/** * ClientModuleSystem — the implementation behind the {@link ClientModuleLoader} * contract. The conceptual contract (lazy CJS model, resolution branch order) is * documented on the public interfaces in `./manifest.ts`; this file owns the * state tables and the load/materialize machinery. */ import { stripClientSuffix } from './manifest.ts' import type { BootManifest, BootModuleRow, ClientBundleRegistration, ClientModuleLoader, ClientModuleRecord, ClientModuleSystemOptions, } from './manifest.ts' /** Default bundle-load hook: same-origin external classic script. */ const defaultLoadBundle = (url: string): Promise => new Promise((resolve, reject) => { const el = document.createElement('script') el.async = true el.src = url el.addEventListener('load', () => { el.remove() resolve() }, { once: true }) el.addEventListener('error', () => { el.remove() reject(new Error(`client-modules: bundle script ${url} failed to load`)) }, { once: true }) document.head.append(el) }) /** Replace the rev query while preserving absolute, protocol-relative, or path-relative form. */ function atRevision(url: string, rev: string): string { if (!/[?&]rev=[^&#]*/.test(url)) { throw new Error(`client-modules: bundle URL ${url} has no revision`) } return url.replace(/([?&]rev=)[^&#]*/, `$1${encodeURIComponent(rev)}`) } /** * Claim and inventory the