// ── What core hands this module, on the client side ──────────────────────── // // The client twin of `server/core.js`, and deliberately much simpler than it. // Every ported page imports its layout, its state components and its hooks from // here, so the boundary is one file and `client/scripts/checkExternals.js` has // one place to look. The normative contract is MODULE_API.md §3.2 and §3.4. // // **Why this is a plain read and the server's is a lazy accessor.** On the // server, `ctx` arrives at `register(ctx)` — after every `require` has already // run — so `server/core.js` has to defer resolution to call time or a router // would capture `undefined` at file scope. There is no such gap here. // `window.__rg` is published by core's own bundle (client/src/modules/shared.js), // and every module chunk is a deferred script the server injects *after* that // bundle's tag, so by the time the first line of this file executes the global // is already there. Reading it once, at module scope, is safe — and it means a // ported component keeps the ordinary `import { PageHeader } from '…'` shape // rather than being wrapped in an accessor that would cost it its identity. // // The absent-global case is handled by `shim/rg.js`, which every shim beside it // also goes through — the shims touch the global before this file does, so a // check here would be unreachable. import { createElement } from 'react' import { createRoot } from 'react-dom/client' import { Link } from 'react-router-dom' import { rg as shared } from './shim/rg.js' const rg = shared() // ── The shared-dependency self-check ─────────────────────────────────────── // // Slice 0 carried this in entry.jsx, back when nothing else imported React and // an unexercised alias was an unproven one. The aliases are thoroughly exercised // now — thirty-five files import React and ten import the router — so what is // left for a runtime check to do is narrower, and worth keeping for exactly that // reason: the two BUILD guards (`assertSharedNotBundled` at resolution time, // `checkExternals.js` on the artifact) both reason about the chunk in isolation, // and neither can see the one failure that only exists once the chunk meets a // core: a `window.__rg` whose React is not the React that rendered the page. // // Identity is the only question worth asking. A second React satisfies every // type check, renders its first element happily, and then throws about an invalid // hook call somewhere unrelated. if (createElement !== rg.react.createElement || createRoot !== rg.reactDom.createRoot || Link !== rg.router.Link) { console.error( '[module-uo] the bindings this chunk imported are not the ones core published — it has bundled ' + 'its own copy of a shared dependency. Check the aliases in vite.config.js (MODULE_API.md §3.6).', ) } // The curated kit (§3.4). Eight members, closed: anything else this module needs // it bundles itself, which is why `components/` next door exists at all. export const { PublicLayout, PageHeader, Loading, ErrorState, EmptyState, useAsync, useAuth, useSite, // Eighth member (MODULE_API 1.6.0): the slot renderer, for the INVERTED // direction — this module declares a place on its own page and CORE fills it. // Shared rather than reimplemented so core's content failing inside our page is // contained by core's own error boundary. Slot, } = rg.ui // The registry, for entry.jsx. Everything else here is read by pages. export const registry = rg.registry // The core API version this module was loaded against. Logged by entry.jsx — // `module.json`'s `coreApi` range is checked by the loader before this file is // ever served, so there is nothing to re-check, only something to report. export const coreApiVersion = rg.version export default rg