pluginsForTests

tcmts.cli.web.pluginsForTests · #bpaxsefw · term · runs on the server

uses tcmts.cli.placement.Placement, which uses node:path

Vite plugins for browser tests: like an app's (server code stubbed, called by hash), with the endpoints answered by the test server itself. get sees definitions not stored yet.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { flightPackage, sentByReference, useFlight } from "#codebase/tcmts/cli/flight";
import { Placement } from "#codebase/tcmts/cli/placement";
import type { AppPlan } from "#codebase/tcmts/cli/placement";
import { rpcHandler, tcmPlugin } from "#codebase/tcmts/cli/web";
import type { ComponentPlan, Lookup } from "#codebase/tcmts/cli/web";
import type { DefRecord } from "#codebase/tcmts/core/types";
import type { Plugin } from "vite";

export function pluginsForTests(
  cb: Codebase,
  tests: string[],
  get: (h: string) => DefRecord | undefined,
  members: (c: string) => DefRecord[],
): Plugin[] {
  const placement = new Placement(cb, get);
  const plan: AppPlan = {
    browser: new Set(),
    components: new Set(),
    clientRefs: new Set(),
    refsOf: new Map(),
    packageRefsOf: new Map(),
    packageImports: new Map(),
    endpoints: new Set(),
    serverRefs: new Set(),
    stubbed: new Set(),
    streaming: new Set(),
    errors: [],
    warnings: [],
    state: { server: [], browser: [], both: [] },
  };
  for (const t of tests) {
    const p = placement.planApp(t);
    for (const k of [
      "browser",
      "components",
      "clientRefs",
      "endpoints",
      "serverRefs",
      "stubbed",
      "streaming",
    ] as const)
      for (const h of p[k]) plan[k].add(h);
    for (const [k, v] of p.refsOf) plan.refsOf.set(k, v);
    for (const [k, v] of p.packageRefsOf) plan.packageRefsOf.set(k, v);
    for (const [k, v] of p.packageImports) plan.packageImports.set(k, v);
  }
  const look: Lookup = { get, members };
  // server components render with Flight, beside the React they're written against
  for (const h of plan.components) {
    const jsx = get(h)?.jsx;
    if (jsx?.startsWith("npm:react@")) flightPackage(cb, jsx);
  }
  const sent = sentByReference(plan);
  useFlight(
    cb,
    {
      client: (h) => sent.has(h),
      server: (h) => plan.serverRefs.has(h),
      packageImports: (c) => [...(plan.packageImports.get(c) ?? [])],
    },
    members,
  );
  const components: ComponentPlan = {
    isComponent: (h) => plan.components.has(h),
    isClientRef: (h) => sent.has(h),
  };
  const rpc = rpcHandler(cb, (h) => plan.endpoints.has(h), undefined, undefined, components, look);
  return [
    tcmPlugin(cb, () => plan, look),
    { name: "tcm-rpc", configureServer: (s) => void s.middlewares.use(rpc) },
  ];
}

uses

used by