planApp

tcmts.cli.web.planApp · #6sz54aps · term · runs on the server

uses tcmts.loader.materialize, which uses node:path

Resolve the app's name, materialize its closure (and its pwa's), and work out what goes where.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { flightPackage } from "#codebase/tcmts/cli/flight";
import { Placement } from "#codebase/tcmts/cli/placement";
import { hostRefusal } from "#codebase/tcmts/cli/roles";
import { buildKey, pwaOf } from "#codebase/tcmts/cli/web";
import type { AppState } from "#codebase/tcmts/cli/web";
import { materialize } from "#codebase/tcmts/loader";
import { ensureExternals, npmAlias } from "#codebase/tcmts/loader/packages";

export function planApp(cb: Codebase, appName: string): AppState {
  const hash = cb.lookupOne(appName, "value");
  const pwa = pwaOf(cb, appName);
  // the whole closure, server side included, with npm packages
  materialize(pwa ? [hash, pwa] : [hash], cb.source(), cb.lay);
  const placement = new Placement(cb);
  const plan = placement.planApp(hash);
  // (a library it uses that speaks a host protocol this tcm doesn't serve can't run with this tcm's runtime)
  const refused = hostRefusal(
    cb,
    new Set([...plan.browser, ...plan.endpoints, ...plan.components]),
  );
  if (refused) plan.errors.push(refused);
  const app = { hash, key: buildKey(hash, pwa), ...(pwa ? { pwa } : {}), plan };
  const jsx = cb.store.getDef(hash)?.jsx;
  if (!placement.isComponent(hash) || !jsx?.startsWith("npm:react@")) return app;
  // React and React DOM are released together: the same version renders it
  const dom = {
    module: jsx.replace(/^npm:react@/, "npm:react-dom@"),
    subpath: "client",
    export: "createRoot",
  };
  // and Flight, when server components render: their trees are its (installed with React DOM)
  const flight = plan.components.size ? flightPackage(cb, jsx, [dom]) : undefined;
  if (!flight) ensureExternals(cb.lay, [dom]);
  return {
    ...app,
    react: { react: npmAlias(jsx), dom: npmAlias(dom.module), ...(flight ? { flight } : {}) },
  };
}

uses

used by