/** * Client module system: the browser peer of Node's internal ESM loader, built * as a lazy CJS table. The vendored cordis Loader consumes this object * through its `internal` seam (the only call site is `EntryTree.import` → * `internal.import`), which keeps entry governance (fiber lifecycle, inject * waiting, update/refresh) entirely on the vendored side while this package * owns code arrival. * * Lazy CJS model (web2 §0): executing a plugin bundle only REGISTERS its * factory (`window.__ModuleLoader__.load({id, factory})`); every module body * side effect — including CSS injection — lives inside the factory closure * and runs at materialization, not at script execution. Materialization * (factory(require) → export surface) happens on first import/require and is * memoized in {@link ClientModuleLoader.loadCache}; a factory that requires * another registered-but-unmaterialized module materializes it recursively, * so load order needs no external sequencing. * * Resolution branch order (import): seed word → shell instance; memoized * record → surface; static registry (shell-own modules, e.g. app-shell) → * module; registered factory → materialize; graph row → fetch + execute + * materialize; anything else → throw (loud — the runtime mirror of the * build-time bundle purity gate). The synchronous `require` handed to * factories walks the same order minus the fetch branch: fetching is async, * so only already-executed bundles can be required — and cross-plugin value * imports are a build error anyway. * @module @deepseek-ai/dsh-client-modules */ import { ClientModuleLoaderImpl } from './loader.ts' export { ClientModuleLoaderImpl } declare module 'cordis' { interface Context { /** The client module system the web shell provides at boot (contract C5). */ modules: ClientModuleLoader } } /** * One composed client entry pushed by the host (web2 §0 graph row). * `immediately` marks stage-one prefetch; `inject` is informational graph * metadata (the authoritative edges live in each package's dshClient * declaration and reach fibers through entry creation). * * Wire contract, held on both sides: the producing peer lives in * `@deepseek-ai/dsh-host-webserver` (host packages keep zero workspace * dependencies, so neither side imports the other's shape — drift between * the two declarations is a bug against the web2 contract). */ export interface WebBootEntry { /** Entry name == package name (or a shell-owned pseudo id, e.g. app-shell). */ id: string /** * Bundle endpoint, '/plugins//client.js?rev='. Absent only on * shell-owned pseudo rows (app-shell) whose module is statically registered * — a row that is neither fetchable nor static-registered fails loud. */ url?: string /** Bundle content hash (cache-busting consistency anchor); absent with url. */ rev?: string /** Package-name dependency edges, informational (preflight display / HMR diffing). */ inject?: string[] /** Stage-one prefetch mark: fetch + execute (factory registration) during module-face boot. */ immediately?: boolean } /** The composed client entry graph the host injects as `window.__DSH_BOOT__` (dual-held wire contract — see {@link WebBootEntry}). */ export interface WebBootGraph { /** Consistency anchor over the whole graph (content + bundle hashes). */ rev: string /** Composed entries; order carries no semantics (activation order is fiber inject waiting). */ entries: WebBootEntry[] } /** The shape a client bundle hands to `window.__ModuleLoader__.load` (registration handoff, contract C6). */ export interface ClientPluginHandoff { /** Plugin id (package name) — the registration key; must match the graph row being executed. */ id: string /** * Closure factory holding the whole bundle body: receives the synchronous * require bound to the module table and returns the bundle's export * surface. Runs once, at materialization. */ factory: (require: (spec: string) => unknown) => Record } /** Window surface this loader owns (bundle side of the handoff protocol) plus the host-injected graph. */ export interface DshWindow { /** Host-composed entry graph, injected before the shell bundle runs. */ __DSH_BOOT__?: WebBootGraph /** Bundle registration sink; installed once per page by {@link createClientModuleLoader} (contract C6). */ __ModuleLoader__?: { load(handoff: ClientPluginHandoff): void } } /** Per-module bookkeeping in {@link ClientModuleLoader.loadCache} (module-graph seam, flat today). */ export interface ClientModuleRecord { /** Module id (entry name / package name). */ id: string /** The materialized export surface (factory `module.exports`, or the shell module for static registrations). */ surface: unknown /** Owned `