reportPlan

tcmts.cli.web.reportPlan · #eddzluxq · term · runs on the server

uses tcmts.cli.style.red, which uses node:util

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import type { AppPlan } from "#codebase/tcmts/cli/placement";
import { dim, red, yellow } from "#codebase/tcmts/cli/style";
import { shortHash } from "#codebase/tcmts/core/hash";

export function reportPlan(cb: Codebase, appName: string, plan: AppPlan) {
  if (plan.errors.length) {
    console.log(red(`\n  ${appName} can't run in the browser yet:`));
    for (const e of plan.errors) console.log(red(`    ${e}`));
    return;
  }
  console.log(`  browser  ${plan.browser.size} definition(s)`);
  const endpoints = [...plan.endpoints]
    .filter((h) => !plan.components.has(h))
    .map((h) => `${cb.displayRef(`#${h}`)} ${dim(shortHash(h))}`);
  const names = (hs: string[]) => hs.map((h) => cb.displayRef(`#${h}`)).join(", ");
  if (plan.components.size) {
    console.log(
      `  server   ${plan.components.size} component(s) rendered on the server, fetched by hash: ${[...plan.components].map((h) => `${cb.displayRef(`#${h}`)} ${dim(shortHash(h))}`).join(", ")}`,
    );
    if (plan.clientRefs.size)
      console.log(
        `  browser  ${names([...plan.clientRefs])} ${dim("rendered in the browser inside server components (sent by hash)")}`,
      );
    // packages' browser components ("use client", or hooks): the browser has them
    const packaged = new Map([...plan.packageRefsOf.values()].flatMap((refs) => [...refs]));
    if (packaged.size)
      console.log(
        `  browser  ${[...packaged.values()].map((e) => `${e.module.slice(4).replace(/@[^@/]*$/, "")}'s ${e.export}`).join(", ")} ${dim("rendered in the browser inside server components (packages' browser components)")}`,
      );
  }
  if (endpoints.length || !plan.components.size) {
    console.log(
      `  server   ${endpoints.length ? `${endpoints.length} function(s) the browser calls by hash: ${endpoints.join(", ")}` : dim("nothing (the app runs entirely in the browser)")}`,
    );
  }
  if (plan.state.server.length)
    console.log(
      `  state    ${names(plan.state.server)} ${dim("on the server, shared by every client")}`,
    );
  if (plan.state.browser.length)
    console.log(
      `  state    ${names(plan.state.browser)} ${dim("in the browser, one copy per tab")}`,
    );
  for (const w of plan.warnings) console.log(yellow(`  warning  ${w}`));
  for (const h of plan.state.both) {
    console.log(
      yellow(
        `  warning  ${cb.displayRef(`#${h}`)} is used by both browser and server code, so the server and each tab have separate copies`,
      ),
    );
  }
}

uses

used by