renderFlight
uses node:url
Render server component fn with props as Flight does (useFlight loads both): its tree, streamed as it's
ready (write, text). An error inside it goes to onError, whose answer is the error's digest, what the browser
is told of it in production. Done when all of it is written, or signal aborts.
import type { Codebase } from "#codebase/tcmts/cli/codebase"; import { flightServerFile } from "#codebase/tcmts/cli/flight"; import { Writable } from "node:stream"; import { StringDecoder } from "node:string_decoder"; import { pathToFileURL } from "node:url"; export async function renderFlight( cb: Codebase, fn: (props: never) => unknown, props: unknown, opts: { write(text: string): void; onError(e: unknown): string | undefined; signal: AbortSignal }, ): Promise<void> { const flight = (await import(pathToFileURL(flightServerFile(cb)).href)) as { createElement(type: unknown, props: unknown): unknown; renderToPipeableStream( model: unknown, options: { onError(e: unknown): string | undefined; environmentName: string }, ): { pipe(to: Writable): void; abort(reason?: unknown): void }; }; const text = new StringDecoder("utf8"); await new Promise<void>((done, fail) => { const sink = new Writable({ write(chunk: Buffer, _e, next) { const t = text.write(chunk); if (t) opts.write(t); next(); }, final(next) { const t = text.end(); if (t) opts.write(t); done(); next(); }, }); sink.on("error", fail); const stream = flight.renderToPipeableStream(flight.createElement(fn, props ?? {}), { onError: opts.onError, environmentName: "Server", }); if (opts.signal.aborted) stream.abort(opts.signal.reason); else opts.signal.addEventListener("abort", () => stream.abort(opts.signal.reason), { once: true }); stream.pipe(sink); }); }