renderComponent

tcmts.cli.web.renderComponent · #5tk3czna · term · runs anywhere

Render server component fn with props as Flight's text, passing it to write as it's ready. An error, in the tree or inside a <Suspense> boundary of it, is sent where it happened: what the browser is told of it is describe's, as the error's digest (production hides the rest). Whether anything failed.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { renderFlight } from "#codebase/tcmts/cli/flight";

export async function renderComponent(
  cb: Codebase,
  fn: (...a: unknown[]) => unknown,
  props: unknown,
  describe: (e: unknown) => { name: string; message: string },
  write: (text: string) => void,
  signal: AbortSignal,
): Promise<{ failed: boolean }> {
  let failed = false;
  await renderFlight(cb, fn, props, {
    write,
    signal,
    onError(e) {
      failed = true;
      // (Flight's advice is a directive's, which tcm has no need of)
      if (
        e instanceof Error &&
        e.message.startsWith("Functions cannot be passed directly to Client Components")
      )
        e.message = e.message.replace(
          /^Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server"\./,
          "A function can't be sent from a server component to a browser component: the browser component can import what it needs itself.",
        );
      return JSON.stringify(describe(e));
    },
  });
  return { failed };
}

uses

used by