@statewalker/cellb 0.8.9 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/dist/adapters/node-sqlite-module.d.ts +6 -0
- package/dist/adapters/node-sqlite-module.js +12 -0
- package/dist/adapters/node-sqlite-module.js.map +1 -1
- package/dist/adapters/node-sqlite.js +3 -3
- package/dist/adapters/node-sqlite.js.map +1 -1
- package/dist/adapters/wasm-sqlite.d.ts +2 -0
- package/dist/adapters/wasm-sqlite.js +15 -0
- package/dist/adapters/wasm-sqlite.js.map +1 -1
- package/dist/bindings/cron.js +9 -2
- package/dist/bindings/cron.js.map +1 -1
- package/dist/bindings/module-registry.d.ts +19 -9
- package/dist/bindings/module-registry.js +42 -30
- package/dist/bindings/module-registry.js.map +1 -1
- package/dist/bucket/sqlite-object-store.js +2 -2
- package/dist/bucket/sqlite-object-store.js.map +1 -1
- package/dist/core/alarms.js +12 -2
- package/dist/core/alarms.js.map +1 -1
- package/dist/isolate/function-imports.d.ts +10 -0
- package/dist/isolate/function-imports.js +93 -0
- package/dist/isolate/function-imports.js.map +1 -0
- package/dist/isolate/isolate-worker.js +5 -1
- package/dist/isolate/isolate-worker.js.map +1 -1
- package/dist/isolate/protocol.js +17 -3
- package/dist/isolate/protocol.js.map +1 -1
- package/dist/project/browser-host.d.ts +2 -0
- package/dist/project/browser-host.js +2 -0
- package/dist/project/browser-host.js.map +1 -1
- package/dist/project/browser-load.js +1 -0
- package/dist/project/browser-load.js.map +1 -1
- package/dist/project/browser-modules.d.ts +7 -1
- package/dist/project/browser-modules.js +5 -1
- package/dist/project/browser-modules.js.map +1 -1
- package/dist/project/browser-tabs.d.ts +1 -1
- package/dist/project/browser-tabs.js.map +1 -1
- package/dist/project/built-project.d.ts +7 -0
- package/dist/project/built-project.js.map +1 -1
- package/dist/project/node-project.js +9 -6
- package/dist/project/node-project.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-tabs.js","sourceRoot":"","sources":["../../src/project/browser-tabs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One project shared by every tab of an origin, its shards balanced over the tabs.\n *\n * ServiceWorker: installProjectRouter(self, { basePath: \"/app/\" })\n * each page: joinProjectShards({ name, shards, spawn, config, code, serviceWorker })\n * shard worker: serveProjectShard({ sqlite3 })\n *\n * Requests to `<basePath><name>/…` reach the project's Worker through the ServiceWorker, whichever\n * tab sent them (with their URL unchanged, unless `stripBase`); a Durable Object call runs in the\n * shard that owns the object, whichever tab holds that shard.\n *\n * Each tab holds a presence lock; every tab computes the same owner for each shard from the tabs\n * present (`shardOwner`: an even split, oldest tabs first), takes the shards it should own (one\n * Web Lock each) and gives up the others. A shard's OPFS pool belongs to the origin, so its cells\n * move with it from tab to tab. A shard given up is drained first (its requests in flight\n * finish, new ones wait for the next owner); a tab that closes runs no code, so the requests in\n * flight in its shards fail (ShardOwnerLostError) and the other tabs take the shards over.\n */\nimport {\n type DispatchFailure,\n type HandlerInfo,\n LinkLostError,\n SwHttpAdapter,\n SwHttpDispatcher,\n type WorkerLink,\n} from \"@statewalker/webrun-http-browser/sw\";\nimport { ShardOwnerLostError } from \"../router/cell-router.js\";\nimport { errorResponse } from \"../transport/cells-http.js\";\nimport { H } from \"../transport/cells-link.js\";\nimport { SW_SOCKET } from \"../ws/sw-connector.js\";\nimport { applyWorkerCookies, withPageCookies } from \"./browser-cookies.js\";\nimport type { BrowserBucket, BrowserProjectOptions } from \"./browser-host.js\";\nimport { INTERNAL_ORIGIN, TAB_INIT, type TabShardInit } from \"./browser-tab-protocol.js\";\n\n/** The ServiceWorker asks a project's tabs to attach their shards again (a host page's wait). */\nconst NEED_LINKS = \"cellb:need-links\";\n/** A page opens a socket (`serviceWorkerConnector`). */\nconst SOCKET = SW_SOCKET;\n\n/**\n * The tab that should run `shard`: the tabs sorted by id (ids start with the time the tab joined),\n * shard i to tab i mod n — every tab runs ⌊shards/n⌋ or ⌈shards/n⌉ shards. A tab joining or\n * leaving moves the shards whose owner index changes; the oldest tabs keep theirs first.\n */\nexport function shardOwner(shard: number, tabs: string[]): string | undefined {\n if (!tabs.length) return undefined;\n const sorted = [...tabs].sort();\n return sorted[shard % sorted.length];\n}\n\nexport interface ProjectTabsOptions {\n /** The project's name in this origin: its URL path, locks and OPFS pools derive from it. */\n name: string;\n shards: number;\n /** Starts the worker of one shard; its script calls `serveProjectShard`. */\n spawn: (shard: number) => Worker;\n config: BrowserProjectOptions[\"config\"];\n code: BrowserProjectOptions[\"code\"];\n assetFiles?: BrowserProjectOptions[\"assetFiles\"];\n /** The OpenAI-compatible endpoint behind the project's `ai` binding. */\n ai?: BrowserProjectOptions[\"ai\"];\n /** Each shard is its own fleet node, `<node>-s<shard>`. */\n bucket?: BrowserBucket;\n /**\n * The active ServiceWorker that runs `installProjectRouter`. This page must be inside its scope\n * and controlled by it (webrun-http-browser's adapter asks the worker to claim the page if it\n * is not, and rejects with a `ServiceWorkerControlError` after 30 s if that fails: after a hard\n * reload, say).\n */\n serviceWorker: () => Promise<ServiceWorker>;\n /** Called whenever the shards this tab runs change. */\n onChange?: (owned: number[]) => void;\n /** How often the tab checks who is present (tabs that crash release their locks silently). */\n checkMs?: number;\n /**\n * A shard handed to another tab first lets its requests in flight finish, for up to this long\n * (default 5 s); new ones wait for the next owner.\n */\n drainMs?: number;\n}\n\nexport interface ProjectTabs {\n /** The shards this tab runs now. */\n owned(): number[];\n /** Ids of the tabs present (this one included). */\n tabs(): Promise<string[]>;\n /** Gives up every shard (closing its runtime first) and leaves. */\n close(): Promise<void>;\n}\n\ninterface Held {\n /** Aborts the wait for the lock, or ends the hold once running. */\n stop: AbortController;\n worker?: Worker;\n running?: Promise<void>;\n}\n\n/** A shard's handler id under the project's key: the router's `route` picks shards by it. */\nconst shardId = (shard: number) => `shard:${shard}`;\n\n/** The page side: this tab takes part in running the project's shards. */\nexport async function joinProjectShards(opts: ProjectTabsOptions): Promise<ProjectTabs> {\n const prefix = `cellb:${opts.name}`;\n const tabId = `${Date.now().toString(36).padStart(9, \"0\")}-${crypto.randomUUID()}`;\n const presenceLock = `${prefix}:tab:${tabId}`;\n let leave!: () => void;\n await new Promise<void>((held) => {\n void navigator.locks.request(presenceLock, () => {\n held();\n return new Promise<void>((r) => (leave = r));\n });\n });\n const channel = new BroadcastChannel(`${prefix}:tabs`);\n const held = new Map<number, Held>();\n const running = new Set<number>();\n let closed = false;\n\n const tabs = async (): Promise<string[]> => {\n const { held: locks = [] } = await navigator.locks.query();\n const ids = locks\n .map((l) => l.name ?? \"\")\n .filter((n) => n.startsWith(`${prefix}:tab:`))\n .map((n) => n.slice(`${prefix}:tab:`.length));\n return ids.includes(tabId) ? ids : [...ids, tabId];\n };\n\n const ask = (w: Worker, data: unknown, ports: MessagePort[] = []) =>\n new Promise<{\n ok: boolean;\n error?: string;\n unsupported?: string[];\n }>((resolve) => {\n const { port1, port2 } = new MessageChannel();\n port1.onmessage = (e) => {\n port1.close();\n resolve(e.data);\n };\n w.postMessage(data, [port2, ...ports]);\n });\n\n // The tab's side of the ServiceWorker's router (webrun-http-browser): it attaches this tab's\n // shard workers under the project's key, and attaches them again whenever the ServiceWorker\n // asks (after a restart). The page itself attaches no handler the router would pick.\n const worker = await opts.serviceWorker();\n // The given worker's registration, not `navigator.serviceWorker.ready` (that is this page's\n // scope's registration, and never settles for a page outside every scope).\n const registration = (await navigator.serviceWorker.getRegistrations()).find((r) =>\n [r.active, r.waiting, r.installing].includes(worker),\n );\n if (!registration)\n throw new Error(`cellb: no registration holds the ServiceWorker ${worker.scriptURL}`);\n const adapter = new SwHttpAdapter({\n key: opts.name,\n registration,\n id: `tab:${tabId}`,\n });\n await adapter.start();\n const links = new Map<number, WorkerLink>();\n\n const changed = () => opts.onChange?.([...running].sort((a, b) => a - b));\n\n /** Waits for the shard's lock, then runs its worker until `stop` is aborted. */\n const take = (shard: number) => {\n const h: Held = { stop: new AbortController() };\n held.set(shard, h);\n h.running = navigator.locks\n .request(`${prefix}:shard:${shard}`, { signal: h.stop.signal }, async () => {\n const w = opts.spawn(shard);\n h.worker = w;\n try {\n const started = await ask(w, {\n type: TAB_INIT,\n name: opts.name,\n shard,\n shards: opts.shards,\n config: opts.config,\n code: opts.code,\n assetFiles: opts.assetFiles,\n ai: opts.ai,\n bucket: opts.bucket && { ...opts.bucket, node: `${opts.bucket.node}-s${shard}` },\n pool: `${opts.name}-shard-${shard}`,\n filesDir: `${opts.name}-files-${shard}`,\n } satisfies TabShardInit);\n if (!started.ok) throw new Error(started.error);\n // What the configuration asks for and this runtime does not provide (a cron trigger\n // without a scheduled() handler, say): said once, not silently ignored.\n if (started.unsupported?.length)\n console.warn(\n `cellb: project ${opts.name} shard ${shard}: unsupported: ${started.unsupported.join(\"; \")}`,\n );\n if (!h.stop.signal.aborted) {\n links.set(\n shard,\n await adapter.attachWorker(w, {\n key: opts.name,\n id: shardId(shard),\n meta: { shard },\n }),\n );\n running.add(shard);\n changed();\n await new Promise<void>((r) =>\n h.stop.signal.aborted ? r() : h.stop.signal.addEventListener(\"abort\", () => r()),\n );\n }\n } finally {\n // A planned hand-over drains the shard's requests in flight first; then the runtime\n // closes (and the pool with it) before the lock goes to the next tab.\n const link = links.get(shard);\n links.delete(shard);\n if (link && running.has(shard))\n await link.drain({ ms: opts.drainMs ?? 5_000 }).catch(() => {});\n running.delete(shard);\n await ask(w, { type: \"cellb:shard-close\" }).catch(() => {});\n w.terminate();\n changed();\n }\n })\n .catch((err) => {\n // Aborted while waiting is expected; a shard that failed to start is reported.\n if (!h.stop.signal.aborted)\n console.error(\n `cellb: ${opts.name} shard ${shard} failed: ${(err as Error)?.message ?? err}`,\n );\n })\n .finally(() => {\n if (held.get(shard) === h) held.delete(shard);\n });\n };\n\n let balancing: Promise<void> | undefined;\n let again = false;\n /** Takes the shards this tab should own and gives up the others. */\n const balance = async () => {\n if (balancing) {\n again = true;\n return balancing;\n }\n balancing = (async () => {\n do {\n again = false;\n if (closed) return;\n const present = await tabs();\n // close() may have run while `tabs()` was answering: take nothing after it.\n if (closed) return;\n for (let shard = 0; shard < opts.shards; shard++) {\n const mine = shardOwner(shard, present) === tabId;\n const h = held.get(shard);\n if (mine && !h) take(shard);\n else if (!mine && h) h.stop.abort();\n }\n } while (again);\n })().finally(() => (balancing = undefined));\n return balancing;\n };\n\n channel.onmessage = () => void balance();\n const timer = setInterval(() => void balance(), opts.checkMs ?? 1000);\n const onSw = (e: MessageEvent) => {\n if (e.data?.type !== NEED_LINKS || (e.data.name && e.data.name !== opts.name)) return;\n void adapter.relink().catch(() => {});\n };\n navigator.serviceWorker.addEventListener(\"message\", onSw);\n channel.postMessage({ joined: tabId });\n await balance();\n\n return {\n owned: () => [...running].sort((a, b) => a - b),\n tabs,\n async close() {\n closed = true;\n clearInterval(timer);\n navigator.serviceWorker.removeEventListener(\"message\", onSw);\n const stopping = [...held.values()];\n for (const h of stopping) h.stop.abort();\n await Promise.all(stopping.map((h) => h.running));\n await adapter.stop().catch(() => {});\n leave();\n channel.postMessage({ left: tabId });\n channel.close();\n },\n };\n}\n\n/**\n * A ServiceWorker's global scope (its `self`), as `installProjectRouter` takes it: typed without\n * TypeScript's WebWorker lib, so that code importing cellb compiles with the DOM lib alone.\n */\nexport interface ServiceWorkerScope {\n readonly location: { readonly origin: string };\n readonly clients: unknown;\n addEventListener(type: string, listener: (event: never) => unknown): void;\n}\n\n/**\n * The ServiceWorker side: webrun-http-browser's dispatcher, with the project as its key and the\n * tabs' shard workers as its handlers. What cellb adds: its urls (`<basePath><name>/`, a root\n * project, `http://cellb.internal/<name>/` for calls between shards), which shard a call goes to,\n * the page's cookies, no control headers from pages, and the host page.\n */\nexport function installProjectRouter(\n scope: ServiceWorkerScope,\n opts: {\n /** Requests to `<basePath><name>/…` go to project `name`. */\n basePath: string;\n /**\n * The Worker sees the request's URL as the page sent it (default), as a Worker on a\n * Cloudflare route does: mount its routes under `<basePath><name>/`. With `stripBase`, it\n * sees `/<rest>` instead — URLs it builds from the request then lack the prefix.\n */\n stripBase?: boolean;\n attachTimeoutMs?: number;\n /**\n * A project served at the origin's root, for apps that build absolute paths (EmDash's\n * `/_emdash/…`, say) and so cannot live under `<basePath><n>/`. Every same-origin request\n * outside `basePath` and outside the `passthrough` path prefixes (the host page's own files)\n * goes to project `name` with its URL unchanged, navigations included.\n *\n * With `hostPage`, a navigation that finds no tab running the project's shards (after\n * `hostWaitMs`, default 2 s, for one to link) is redirected there, with the URL it asked\n * for as `?next=`: the page that starts the project, which a person reopening the site\n * would otherwise never reach, as every path of the origin belongs to the project.\n */\n root?: { name: string; passthrough?: string[]; hostPage?: string; hostWaitMs?: number };\n },\n): { dispatcher: SwHttpDispatcher } {\n const sw = scope as unknown as ServiceWorkerGlobalScope;\n const base = opts.basePath.endsWith(\"/\") ? opts.basePath : `${opts.basePath}/`;\n const internal = new URL(INTERNAL_ORIGIN);\n\n /** Whether `url` goes to the root project (`opts.root`). */\n const atRoot = (url: URL) =>\n !!opts.root &&\n url.origin === sw.location.origin &&\n !url.pathname.startsWith(base) &&\n !(opts.root.passthrough ?? []).some((p) => url.pathname.startsWith(p));\n\n /**\n * `<base><name>/<rest>` → the project's name, the Worker's path `/<rest>`, and `<base><name>` as\n * the URL spells it (`prefix`: what `stripBase` cuts, so a name the URL leaves unescaped, `a@b`,\n * or escapes where it need not, `%61pp`, is cut as written).\n */\n const split = (url: URL): { name: string; path: string; prefix: string } | undefined => {\n if (opts.root && atRoot(url)) return { name: opts.root.name, path: url.pathname, prefix: \"\" };\n if (url.origin !== sw.location.origin || !url.pathname.startsWith(base)) return undefined;\n const rest = url.pathname.slice(base.length);\n const slash = rest.indexOf(\"/\");\n const raw = slash < 0 ? rest : rest.slice(0, slash);\n const name = decodeURIComponent(raw);\n return name\n ? { name, path: slash < 0 ? \"/\" : rest.slice(slash), prefix: `${base}${raw}` }\n : undefined;\n };\n\n const isShard = (h: HandlerInfo) => typeof (h.meta as { shard?: unknown })?.shard === \"number\";\n let rr = 0;\n const dispatcher = new SwHttpDispatcher({\n self: sw,\n handleFetch: false,\n attachTimeoutMs: opts.attachTimeoutMs ?? 15_000,\n key: (url) => {\n // Calls between shards: http://cellb.internal/<name>/.\n if (url.host === internal.host) {\n const name = url.pathname.split(\"/\")[1];\n return name ? decodeURIComponent(name) : undefined;\n }\n return split(url)?.name;\n },\n // A call between shards names its shard (it waits for that one); the rest go to the shard\n // with the fewest requests in flight, round robin among equals. The tabs' pages are handlers\n // of the key too (their adapters'), with nothing to serve: never picked.\n route: (request, _key, handlers) => {\n const shards = handlers.filter(isShard);\n const named = request.headers.get(H.shard);\n if (named !== null)\n return shards.find((h) => (h.meta as { shard: number }).shard === Number(named));\n if (!shards.length) return undefined;\n const start = rr++ % shards.length;\n let best = shards[start];\n for (let i = 1; i < shards.length; i++) {\n const h = shards[(start + i) % shards.length];\n if (h.inflight < best.inflight) best = h;\n }\n return best;\n },\n // A call between shards fails as an error its caller rethrows (postVia); a page's request\n // gets a response it can read.\n failure: (request, failure) => failed(request, failure),\n // Pages may not address objects or shards directly: no control headers on their sockets.\n socketHeaders: (headers, from) =>\n from === \"page\"\n ? headers?.filter(([name]) => !name.toLowerCase().startsWith(\"x-cellb\"))\n : headers,\n });\n dispatcher.start();\n\n const failed = (request: Request, failure: DispatchFailure): Response => {\n const named = request.headers.get(H.shard);\n const what = named !== null ? `cell shard ${named}` : \"the project\";\n const error =\n failure.kind === \"lost\" && failure.error instanceof LinkLostError && named !== null\n ? new ShardOwnerLostError(Number(named))\n : failure.kind === \"timeout\"\n ? new Error(`${what} was not attached in time`)\n : failure.kind === \"gone\"\n ? new Error(`${what} has no tab running it`)\n : (failure.error as Error);\n if (request.headers.get(H.kind) !== null) return errorResponse(error, 503);\n return new Response(`cellb: ${(error as Error)?.message ?? error}`, { status: 503 });\n };\n\n const askForLinks = async (name: string) => {\n const clients = await sw.clients.matchAll({ type: \"window\", includeUncontrolled: true });\n for (const c of clients) c.postMessage({ type: NEED_LINKS, name });\n };\n\n /** Whether a tab runs project `name`'s shards, waiting up to `ms` for one to link. */\n const runningShards = async (name: string, ms: number): Promise<boolean> => {\n await dispatcher.ready;\n const live = () => dispatcher.table.live(name).some(isShard);\n if (live()) return true;\n void askForLinks(name);\n for (const until = Date.now() + ms; Date.now() < until; ) {\n await new Promise((r) => setTimeout(r, 100));\n if (live()) return true;\n }\n return false;\n };\n\n /** Headers for a request the router sends on: no control headers from the page, its base. */\n const routed = (req: Request, prefix: string, root: boolean): Headers => {\n // Headers only: a Request built from `req` would take its body.\n const headers = new Headers(req.headers);\n for (const h of Object.values(H)) if (h !== H.cookie) headers.delete(h);\n if (opts.stripBase && !root) headers.set(H.base, prefix);\n return headers;\n };\n\n /** A request to project `name`, with the page's cookies in and the Worker's out. */\n const serve = async (\n { name, prefix }: { name: string; prefix: string },\n req: Request,\n root: boolean,\n ): Promise<Response> => {\n try {\n // A project no tab has ever served is not the router's: the page's own request goes to the\n // network, as if there were no router (not the copy below, with the page's cookies in a\n // header and a streamed body).\n await dispatcher.ready;\n if (!dispatcher.serves(name)) return await fetch(req);\n const headers = await withPageCookies(\n sw,\n new Request(req.url, { headers: routed(req, prefix, root) }),\n );\n const res = await dispatcher.dispatch(\n new Request(req.url, {\n method: req.method,\n headers,\n body: req.body,\n signal: req.signal,\n duplex: \"half\",\n } as RequestInit),\n );\n return await applyWorkerCookies(sw, res);\n } catch (err) {\n // A response the page can read, instead of a network error with no cause.\n console.error(`cellb: ${req.method} ${new URL(req.url).pathname} failed:`, err);\n return new Response(`cellb: ${(err as Error)?.stack ?? err}`, { status: 502 });\n }\n };\n\n sw.addEventListener(\"fetch\", (e: FetchEvent) => {\n const req = e.request;\n const url = new URL(req.url);\n const root = atRoot(url);\n if (!root && req.mode === \"navigate\") return; // the pages under basePath are the host's\n const project = split(url);\n if (!project) return;\n const hostPage = root && req.mode === \"navigate\" ? opts.root?.hostPage : undefined;\n if (hostPage)\n e.respondWith(\n runningShards(project.name, opts.root?.hostWaitMs ?? 2_000).then((running) =>\n running\n ? serve(project, req, root)\n : Response.redirect(\n `${new URL(hostPage, url.origin).href}?next=${encodeURIComponent(`${url.pathname}${url.search}`)}`,\n 302,\n ),\n ),\n );\n else e.respondWith(serve(project, req, root));\n });\n\n // A page's socket (`serviceWorkerConnector`): routed as a fetch would be, without the page's\n // headers.\n sw.addEventListener(\"message\", (e: ExtendableMessageEvent) => {\n const m = e.data;\n if (m?.type !== SOCKET) return;\n const reply = e.ports[0];\n e.waitUntil(\n (async () => {\n try {\n const url = new URL(m.url);\n const httpUrl = new URL(url);\n if (httpUrl.protocol === \"ws:\") httpUrl.protocol = \"http:\";\n else if (httpUrl.protocol === \"wss:\") httpUrl.protocol = \"https:\";\n const project = split(httpUrl);\n if (!project) throw new Error(`not a project URL: ${m.url}`);\n const headers: [string, string][] = [];\n if (opts.stripBase && !atRoot(httpUrl)) headers.push([H.base, project.prefix]);\n const { port, protocol } = await dispatcher.connectWebSocket(\n `${httpUrl}`,\n m.protocols ?? [],\n headers,\n );\n reply.postMessage({ ok: true, port, protocol }, [port]);\n } catch (err) {\n reply.postMessage({ ok: false, error: String((err as Error)?.message ?? err) });\n }\n })(),\n );\n });\n\n return { dispatcher };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"browser-tabs.js","sourceRoot":"","sources":["../../src/project/browser-tabs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAGL,aAAa,EACb,aAAa,EACb,gBAAgB,GAEjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,CAAC,EAAE,MAAM,4BAA4B,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAqB,MAAM,2BAA2B,CAAC;AAEzF,iGAAiG;AACjG,MAAM,UAAU,GAAG,kBAAkB,CAAC;AACtC,wDAAwD;AACxD,MAAM,MAAM,GAAG,SAAS,CAAC;AAEzB;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,IAAc;IACtD,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAiDD,6FAA6F;AAC7F,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,SAAS,KAAK,EAAE,CAAC;AAEpD,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAwB;IAC9D,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;IACnF,MAAM,YAAY,GAAG,GAAG,MAAM,QAAQ,KAAK,EAAE,CAAC;IAC9C,IAAI,KAAkB,CAAC;IACvB,MAAM,IAAI,OAAO,CAAO,CAAC,IAAI,EAAE,EAAE;QAC/B,KAAK,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,EAAE;YAC9C,IAAI,EAAE,CAAC;YACP,OAAO,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAgB,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,MAAM,IAAI,GAAG,KAAK,IAAuB,EAAE;QACzC,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC3D,MAAM,GAAG,GAAG,KAAK;aACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;aACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC;IAEF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,IAAa,EAAE,KAAK,GAAkB,EAAE,EAAE,EAAE,CAClE,IAAI,OAAO,CAIR,CAAC,OAAO,EAAE,EAAE;QACb,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;QAC9C,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,EAAE;YACtB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC,CAAC;QACF,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEL,6FAA6F;IAC7F,4FAA4F;IAC5F,qFAAqF;IACrF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC1C,4FAA4F;IAC5F,2EAA2E;IAC3E,MAAM,YAAY,GAAG,CAAC,MAAM,SAAS,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACjF,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CACrD,CAAC;IACF,IAAI,CAAC,YAAY;QACf,MAAM,IAAI,KAAK,CAAC,kDAAkD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACxF,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,GAAG,EAAE,IAAI,CAAC,IAAI;QACd,YAAY;QACZ,EAAE,EAAE,OAAO,KAAK,EAAE;KACnB,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE5C,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAE1E,gFAAgF;IAChF,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE;QAC7B,MAAM,CAAC,GAAS,EAAE,IAAI,EAAE,IAAI,eAAe,EAAE,EAAE,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC,CAAC,OAAO,GAAG,SAAS,CAAC,KAAK;aACxB,OAAO,CAAC,GAAG,MAAM,UAAU,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,IAAI,EAAE;YACzE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE;oBAC3B,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,KAAK;oBACL,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,EAAE;oBAChF,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,UAAU,KAAK,EAAE;oBACnC,QAAQ,EAAE,GAAG,IAAI,CAAC,IAAI,UAAU,KAAK,EAAE;iBACjB,CAAC,CAAC;gBAC1B,IAAI,CAAC,OAAO,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAChD,oFAAoF;gBACpF,wEAAwE;gBACxE,IAAI,OAAO,CAAC,WAAW,EAAE,MAAM;oBAC7B,OAAO,CAAC,IAAI,CACV,kBAAkB,IAAI,CAAC,IAAI,UAAU,KAAK,kBAAkB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAC;gBACJ,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC3B,KAAK,CAAC,GAAG,CACP,KAAK,EACL,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE;wBAC5B,GAAG,EAAE,IAAI,CAAC,IAAI;wBACd,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC;wBAClB,IAAI,EAAE,EAAE,KAAK,EAAE;qBAChB,CAAC,CACH,CAAC;oBACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBACnB,OAAO,EAAE,CAAC;oBACV,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAC5B,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CACjF,CAAC;gBACJ,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,oFAAoF;gBACpF,sEAAsE;gBACtE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC9B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;oBAC5B,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACtB,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAC5D,CAAC,CAAC,SAAS,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,+EAA+E;YAC/E,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;gBACxB,OAAO,CAAC,KAAK,CACX,UAAU,IAAI,CAAC,IAAI,UAAU,KAAK,YAAa,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAC/E,CAAC;QACN,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IAEF,IAAI,SAAoC,CAAC;IACzC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,oEAAoE;IACpE,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,GAAG,IAAI,CAAC;YACb,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,SAAS,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,GAAG,CAAC;gBACF,KAAK,GAAG,KAAK,CAAC;gBACd,IAAI,MAAM;oBAAE,OAAO;gBACnB,MAAM,OAAO,GAAG,MAAM,IAAI,EAAE,CAAC;gBAC7B,4EAA4E;gBAC5E,IAAI,MAAM;oBAAE,OAAO;gBACnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;oBACjD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,CAAC;oBAClD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBAC1B,IAAI,IAAI,IAAI,CAAC,CAAC;wBAAE,IAAI,CAAC,KAAK,CAAC,CAAC;yBACvB,IAAI,CAAC,IAAI,IAAI,CAAC;wBAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtC,CAAC;YACH,CAAC,QAAQ,KAAK,EAAE;QAClB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC;QAC5C,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,EAAE,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,CAAC,CAAe,EAAE,EAAE;QAC/B,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO;QACtF,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC;IACF,SAAS,CAAC,aAAa,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACvC,MAAM,OAAO,EAAE,CAAC;IAEhB,OAAO;QACL,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI;QACJ,KAAK,CAAC,KAAK;YACT,MAAM,GAAG,IAAI,CAAC;YACd,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,SAAS,CAAC,aAAa,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC7D,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACpC,KAAK,MAAM,CAAC,IAAI,QAAQ;gBAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACzC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YAClD,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrC,KAAK,EAAE,CAAC;YACR,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACrC,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC;AAcD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAyB,EACzB,IAsBC;IAED,MAAM,EAAE,GAAG,KAA4C,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC;IAC/E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;IAE1C,4DAA4D;IAC5D,MAAM,MAAM,GAAG,CAAC,GAAQ,EAAE,EAAE,CAC1B,CAAC,CAAC,IAAI,CAAC,IAAI;QACX,GAAG,CAAC,MAAM,KAAK,EAAE,CAAC,QAAQ,CAAC,MAAM;QACjC,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;QAC9B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzE;;;;OAIG;IACH,MAAM,KAAK,GAAG,CAAC,GAAQ,EAA8D,EAAE;QACrF,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC9F,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAC1F,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,IAAI;YACT,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,EAAE;YAC9E,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,CAAc,EAAE,EAAE,CAAC,OAAQ,CAAC,CAAC,IAA4B,EAAE,KAAK,KAAK,QAAQ,CAAC;IAC/F,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;QACtC,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,KAAK;QAClB,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,MAAM;QAC/C,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;YACX,uDAAuD;YACvD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxC,OAAO,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACrD,CAAC;YACD,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;QAC1B,CAAC;QACD,0FAA0F;QAC1F,6FAA6F;QAC7F,yEAAyE;QACzE,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,KAAK,KAAK,IAAI;gBAChB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAC,CAAC,IAA0B,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACnF,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAC;YACrC,MAAM,KAAK,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC;YACnC,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC9C,IAAI,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ;oBAAE,IAAI,GAAG,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,0FAA0F;QAC1F,+BAA+B;QAC/B,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;QACvD,yFAAyF;QACzF,aAAa,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAC/B,IAAI,KAAK,MAAM;YACb,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACxE,CAAC,CAAC,OAAO;KACd,CAAC,CAAC;IACH,UAAU,CAAC,KAAK,EAAE,CAAC;IAEnB,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAE,OAAwB,EAAY,EAAE;QACtE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACpE,MAAM,KAAK,GACT,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,KAAK,YAAY,aAAa,IAAI,KAAK,KAAK,IAAI;YACjF,CAAC,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS;gBAC1B,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,2BAA2B,CAAC;gBAC/C,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;oBACvB,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,wBAAwB,CAAC;oBAC5C,CAAC,CAAE,OAAO,CAAC,KAAe,CAAC;QACnC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC3E,OAAO,IAAI,QAAQ,CAAC,UAAW,KAAe,EAAE,OAAO,IAAI,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvF,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;QACzF,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC;IAEF,sFAAsF;IACtF,MAAM,aAAa,GAAG,KAAK,EAAE,IAAY,EAAE,EAAU,EAAoB,EAAE;QACzE,MAAM,UAAU,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACxB,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAI,CAAC;YACzD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC7C,IAAI,IAAI,EAAE;gBAAE,OAAO,IAAI,CAAC;QAC1B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,6FAA6F;IAC7F,MAAM,MAAM,GAAG,CAAC,GAAY,EAAE,MAAc,EAAE,IAAa,EAAW,EAAE;QACtE,gEAAgE;QAChE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM;gBAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxE,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,oFAAoF;IACpF,MAAM,KAAK,GAAG,KAAK,EACjB,EAAE,IAAI,EAAE,MAAM,EAAoC,EAClD,GAAY,EACZ,IAAa,EACM,EAAE;QACrB,IAAI,CAAC;YACH,2FAA2F;YAC3F,wFAAwF;YACxF,+BAA+B;YAC/B,MAAM,UAAU,CAAC,KAAK,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,EAAE,EACF,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAC7D,CAAC;YACF,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,QAAQ,CACnC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,OAAO;gBACP,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM,EAAE,MAAM;aACA,CAAC,CAClB,CAAC;YACF,OAAO,MAAM,kBAAkB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,0EAA0E;YAC1E,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,MAAM,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,UAAU,EAAE,GAAG,CAAC,CAAC;YAChF,OAAO,IAAI,QAAQ,CAAC,UAAW,GAAa,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC,CAAC;IAEF,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAa,EAAE,EAAE;QAC7C,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC;QACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,CAAC,0CAA0C;QACxF,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,QAAQ,GAAG,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QACnF,IAAI,QAAQ;YACV,CAAC,CAAC,WAAW,CACX,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC3E,OAAO;gBACL,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;gBAC3B,CAAC,CAAC,QAAQ,CAAC,QAAQ,CACf,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,SAAS,kBAAkB,CAAC,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAClG,GAAG,CACJ,CACN,CACF,CAAC;;YACC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,6FAA6F;IAC7F,WAAW;IACX,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAyB,EAAE,EAAE;QAC3D,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACjB,IAAI,CAAC,EAAE,IAAI,KAAK,MAAM;YAAE,OAAO;QAC/B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC,CAAC,SAAS,CACT,CAAC,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC7B,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK;oBAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC;qBACtD,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM;oBAAE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBAClE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC/B,IAAI,CAAC,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC7D,MAAM,OAAO,GAAuB,EAAE,CAAC;gBACvC,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;oBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/E,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,UAAU,CAAC,gBAAgB,CAC1D,GAAG,OAAO,EAAE,EACZ,CAAC,CAAC,SAAS,IAAI,EAAE,EACjB,OAAO,CACR,CAAC;gBACF,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;YAClF,CAAC;QACH,CAAC,CAAC,EAAE,CACL,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC","sourcesContent":["/**\n * One project shared by every tab of an origin, its shards balanced over the tabs.\n *\n * ServiceWorker: installProjectRouter(self, { basePath: \"/app/\" })\n * each page: joinProjectShards({ name, shards, spawn, config, code, serviceWorker })\n * shard worker: serveProjectShard({ sqlite3 })\n *\n * Requests to `<basePath><name>/…` reach the project's Worker through the ServiceWorker, whichever\n * tab sent them (with their URL unchanged, unless `stripBase`); a Durable Object call runs in the\n * shard that owns the object, whichever tab holds that shard.\n *\n * Each tab holds a presence lock; every tab computes the same owner for each shard from the tabs\n * present (`shardOwner`: an even split, oldest tabs first), takes the shards it should own (one\n * Web Lock each) and gives up the others. A shard's OPFS pool belongs to the origin, so its cells\n * move with it from tab to tab. A shard given up is drained first (its requests in flight\n * finish, new ones wait for the next owner); a tab that closes runs no code, so the requests in\n * flight in its shards fail (ShardOwnerLostError) and the other tabs take the shards over.\n */\nimport {\n type DispatchFailure,\n type HandlerInfo,\n LinkLostError,\n SwHttpAdapter,\n SwHttpDispatcher,\n type WorkerLink,\n} from \"@statewalker/webrun-http-browser/sw\";\nimport { ShardOwnerLostError } from \"../router/cell-router.js\";\nimport { errorResponse } from \"../transport/cells-http.js\";\nimport { H } from \"../transport/cells-link.js\";\nimport { SW_SOCKET } from \"../ws/sw-connector.js\";\nimport { applyWorkerCookies, withPageCookies } from \"./browser-cookies.js\";\nimport type { BrowserBucket, BrowserProjectOptions } from \"./browser-host.js\";\nimport { INTERNAL_ORIGIN, TAB_INIT, type TabShardInit } from \"./browser-tab-protocol.js\";\n\n/** The ServiceWorker asks a project's tabs to attach their shards again (a host page's wait). */\nconst NEED_LINKS = \"cellb:need-links\";\n/** A page opens a socket (`serviceWorkerConnector`). */\nconst SOCKET = SW_SOCKET;\n\n/**\n * The tab that should run `shard`: the tabs sorted by id (ids start with the time the tab joined),\n * shard i to tab i mod n — every tab runs ⌊shards/n⌋ or ⌈shards/n⌉ shards. A tab joining or\n * leaving moves the shards whose owner index changes; the oldest tabs keep theirs first.\n */\nexport function shardOwner(shard: number, tabs: string[]): string | undefined {\n if (!tabs.length) return undefined;\n const sorted = [...tabs].sort();\n return sorted[shard % sorted.length];\n}\n\nexport interface ProjectTabsOptions {\n /** The project's name in this origin: its URL path, locks and OPFS pools derive from it. */\n name: string;\n shards: number;\n /** Starts the worker of one shard; its script calls `serveProjectShard`. */\n spawn: (shard: number) => Worker;\n config: BrowserProjectOptions[\"config\"];\n code: BrowserProjectOptions[\"code\"];\n assetFiles?: BrowserProjectOptions[\"assetFiles\"];\n /** The OpenAI-compatible endpoint behind the project's `ai` binding. */\n ai?: BrowserProjectOptions[\"ai\"];\n /** Each shard is its own fleet node, `<node>-s<shard>`. */\n bucket?: BrowserBucket;\n /**\n * The active ServiceWorker that runs `installProjectRouter`. This page must be inside its scope\n * and controlled by it (webrun-http-browser's adapter asks the worker to claim the page if it\n * is not, and rejects with a `ServiceWorkerControlError` after 30 s if that fails: after a hard\n * reload, say).\n */\n serviceWorker: () => Promise<ServiceWorker>;\n /** Called whenever the shards this tab runs change. */\n onChange?: (owned: number[]) => void;\n /** How often the tab checks who is present (tabs that crash release their locks silently). */\n checkMs?: number;\n /**\n * A shard handed to another tab first lets its requests in flight finish, for up to this long\n * (default 5 s); new ones wait for the next owner.\n */\n drainMs?: number;\n}\n\nexport interface ProjectTabs {\n /** The shards this tab runs now. */\n owned(): number[];\n /** Ids of the tabs present (this one included). */\n tabs(): Promise<string[]>;\n /** Gives up every shard (closing its runtime first) and leaves. */\n close(): Promise<void>;\n}\n\ninterface Held {\n /** Aborts the wait for the lock, or ends the hold once running. */\n stop: AbortController;\n worker?: Worker;\n running?: Promise<void>;\n}\n\n/** A shard's handler id under the project's key: the router's `route` picks shards by it. */\nconst shardId = (shard: number) => `shard:${shard}`;\n\n/** The page side: this tab takes part in running the project's shards. */\nexport async function joinProjectShards(opts: ProjectTabsOptions): Promise<ProjectTabs> {\n const prefix = `cellb:${opts.name}`;\n const tabId = `${Date.now().toString(36).padStart(9, \"0\")}-${crypto.randomUUID()}`;\n const presenceLock = `${prefix}:tab:${tabId}`;\n let leave!: () => void;\n await new Promise<void>((held) => {\n void navigator.locks.request(presenceLock, () => {\n held();\n return new Promise<void>((r) => (leave = r));\n });\n });\n const channel = new BroadcastChannel(`${prefix}:tabs`);\n const held = new Map<number, Held>();\n const running = new Set<number>();\n let closed = false;\n\n const tabs = async (): Promise<string[]> => {\n const { held: locks = [] } = await navigator.locks.query();\n const ids = locks\n .map((l) => l.name ?? \"\")\n .filter((n) => n.startsWith(`${prefix}:tab:`))\n .map((n) => n.slice(`${prefix}:tab:`.length));\n return ids.includes(tabId) ? ids : [...ids, tabId];\n };\n\n const ask = (w: Worker, data: unknown, ports: MessagePort[] = []) =>\n new Promise<{\n ok: boolean;\n error?: string;\n unsupported?: string[];\n }>((resolve) => {\n const { port1, port2 } = new MessageChannel();\n port1.onmessage = (e) => {\n port1.close();\n resolve(e.data);\n };\n w.postMessage(data, [port2, ...ports]);\n });\n\n // The tab's side of the ServiceWorker's router (webrun-http-browser): it attaches this tab's\n // shard workers under the project's key, and attaches them again whenever the ServiceWorker\n // asks (after a restart). The page itself attaches no handler the router would pick.\n const worker = await opts.serviceWorker();\n // The given worker's registration, not `navigator.serviceWorker.ready` (that is this page's\n // scope's registration, and never settles for a page outside every scope).\n const registration = (await navigator.serviceWorker.getRegistrations()).find((r) =>\n [r.active, r.waiting, r.installing].includes(worker),\n );\n if (!registration)\n throw new Error(`cellb: no registration holds the ServiceWorker ${worker.scriptURL}`);\n const adapter = new SwHttpAdapter({\n key: opts.name,\n registration,\n id: `tab:${tabId}`,\n });\n await adapter.start();\n const links = new Map<number, WorkerLink>();\n\n const changed = () => opts.onChange?.([...running].sort((a, b) => a - b));\n\n /** Waits for the shard's lock, then runs its worker until `stop` is aborted. */\n const take = (shard: number) => {\n const h: Held = { stop: new AbortController() };\n held.set(shard, h);\n h.running = navigator.locks\n .request(`${prefix}:shard:${shard}`, { signal: h.stop.signal }, async () => {\n const w = opts.spawn(shard);\n h.worker = w;\n try {\n const started = await ask(w, {\n type: TAB_INIT,\n name: opts.name,\n shard,\n shards: opts.shards,\n config: opts.config,\n code: opts.code,\n assetFiles: opts.assetFiles,\n ai: opts.ai,\n bucket: opts.bucket && { ...opts.bucket, node: `${opts.bucket.node}-s${shard}` },\n pool: `${opts.name}-shard-${shard}`,\n filesDir: `${opts.name}-files-${shard}`,\n } satisfies TabShardInit);\n if (!started.ok) throw new Error(started.error);\n // What the configuration asks for and this runtime does not provide (a cron trigger\n // without a scheduled() handler, say): said once, not silently ignored.\n if (started.unsupported?.length)\n console.warn(\n `cellb: project ${opts.name} shard ${shard}: unsupported: ${started.unsupported.join(\"; \")}`,\n );\n if (!h.stop.signal.aborted) {\n links.set(\n shard,\n await adapter.attachWorker(w, {\n key: opts.name,\n id: shardId(shard),\n meta: { shard },\n }),\n );\n running.add(shard);\n changed();\n await new Promise<void>((r) =>\n h.stop.signal.aborted ? r() : h.stop.signal.addEventListener(\"abort\", () => r()),\n );\n }\n } finally {\n // A planned hand-over drains the shard's requests in flight first; then the runtime\n // closes (and the pool with it) before the lock goes to the next tab.\n const link = links.get(shard);\n links.delete(shard);\n if (link && running.has(shard))\n await link.drain({ ms: opts.drainMs ?? 5_000 }).catch(() => {});\n running.delete(shard);\n await ask(w, { type: \"cellb:shard-close\" }).catch(() => {});\n w.terminate();\n changed();\n }\n })\n .catch((err) => {\n // Aborted while waiting is expected; a shard that failed to start is reported.\n if (!h.stop.signal.aborted)\n console.error(\n `cellb: ${opts.name} shard ${shard} failed: ${(err as Error)?.message ?? err}`,\n );\n })\n .finally(() => {\n if (held.get(shard) === h) held.delete(shard);\n });\n };\n\n let balancing: Promise<void> | undefined;\n let again = false;\n /** Takes the shards this tab should own and gives up the others. */\n const balance = async () => {\n if (balancing) {\n again = true;\n return balancing;\n }\n balancing = (async () => {\n do {\n again = false;\n if (closed) return;\n const present = await tabs();\n // close() may have run while `tabs()` was answering: take nothing after it.\n if (closed) return;\n for (let shard = 0; shard < opts.shards; shard++) {\n const mine = shardOwner(shard, present) === tabId;\n const h = held.get(shard);\n if (mine && !h) take(shard);\n else if (!mine && h) h.stop.abort();\n }\n } while (again);\n })().finally(() => (balancing = undefined));\n return balancing;\n };\n\n channel.onmessage = () => void balance();\n const timer = setInterval(() => void balance(), opts.checkMs ?? 1000);\n const onSw = (e: MessageEvent) => {\n if (e.data?.type !== NEED_LINKS || (e.data.name && e.data.name !== opts.name)) return;\n void adapter.relink().catch(() => {});\n };\n navigator.serviceWorker.addEventListener(\"message\", onSw);\n channel.postMessage({ joined: tabId });\n await balance();\n\n return {\n owned: () => [...running].sort((a, b) => a - b),\n tabs,\n async close() {\n closed = true;\n clearInterval(timer);\n navigator.serviceWorker.removeEventListener(\"message\", onSw);\n const stopping = [...held.values()];\n for (const h of stopping) h.stop.abort();\n await Promise.all(stopping.map((h) => h.running));\n await adapter.stop().catch(() => {});\n leave();\n channel.postMessage({ left: tabId });\n channel.close();\n },\n };\n}\n\n/**\n * A ServiceWorker's global scope (its `self`), as `installProjectRouter` takes it: typed without\n * TypeScript's WebWorker lib, so that code importing cellb compiles with the DOM lib alone.\n */\nexport interface ServiceWorkerScope {\n readonly location: { readonly origin: string };\n readonly clients: unknown;\n // `Event`, not `never`: a real ServiceWorkerGlobalScope's listener overloads take events, and\n // TypeScript refuses to assign them to a listener of `never`.\n addEventListener(type: string, listener: (event: Event) => unknown): void;\n}\n\n/**\n * The ServiceWorker side: webrun-http-browser's dispatcher, with the project as its key and the\n * tabs' shard workers as its handlers. What cellb adds: its urls (`<basePath><name>/`, a root\n * project, `http://cellb.internal/<name>/` for calls between shards), which shard a call goes to,\n * the page's cookies, no control headers from pages, and the host page.\n */\nexport function installProjectRouter(\n scope: ServiceWorkerScope,\n opts: {\n /** Requests to `<basePath><name>/…` go to project `name`. */\n basePath: string;\n /**\n * The Worker sees the request's URL as the page sent it (default), as a Worker on a\n * Cloudflare route does: mount its routes under `<basePath><name>/`. With `stripBase`, it\n * sees `/<rest>` instead — URLs it builds from the request then lack the prefix.\n */\n stripBase?: boolean;\n attachTimeoutMs?: number;\n /**\n * A project served at the origin's root, for apps that build absolute paths (EmDash's\n * `/_emdash/…`, say) and so cannot live under `<basePath><n>/`. Every same-origin request\n * outside `basePath` and outside the `passthrough` path prefixes (the host page's own files)\n * goes to project `name` with its URL unchanged, navigations included.\n *\n * With `hostPage`, a navigation that finds no tab running the project's shards (after\n * `hostWaitMs`, default 2 s, for one to link) is redirected there, with the URL it asked\n * for as `?next=`: the page that starts the project, which a person reopening the site\n * would otherwise never reach, as every path of the origin belongs to the project.\n */\n root?: { name: string; passthrough?: string[]; hostPage?: string; hostWaitMs?: number };\n },\n): { dispatcher: SwHttpDispatcher } {\n const sw = scope as unknown as ServiceWorkerGlobalScope;\n const base = opts.basePath.endsWith(\"/\") ? opts.basePath : `${opts.basePath}/`;\n const internal = new URL(INTERNAL_ORIGIN);\n\n /** Whether `url` goes to the root project (`opts.root`). */\n const atRoot = (url: URL) =>\n !!opts.root &&\n url.origin === sw.location.origin &&\n !url.pathname.startsWith(base) &&\n !(opts.root.passthrough ?? []).some((p) => url.pathname.startsWith(p));\n\n /**\n * `<base><name>/<rest>` → the project's name, the Worker's path `/<rest>`, and `<base><name>` as\n * the URL spells it (`prefix`: what `stripBase` cuts, so a name the URL leaves unescaped, `a@b`,\n * or escapes where it need not, `%61pp`, is cut as written).\n */\n const split = (url: URL): { name: string; path: string; prefix: string } | undefined => {\n if (opts.root && atRoot(url)) return { name: opts.root.name, path: url.pathname, prefix: \"\" };\n if (url.origin !== sw.location.origin || !url.pathname.startsWith(base)) return undefined;\n const rest = url.pathname.slice(base.length);\n const slash = rest.indexOf(\"/\");\n const raw = slash < 0 ? rest : rest.slice(0, slash);\n const name = decodeURIComponent(raw);\n return name\n ? { name, path: slash < 0 ? \"/\" : rest.slice(slash), prefix: `${base}${raw}` }\n : undefined;\n };\n\n const isShard = (h: HandlerInfo) => typeof (h.meta as { shard?: unknown })?.shard === \"number\";\n let rr = 0;\n const dispatcher = new SwHttpDispatcher({\n self: sw,\n handleFetch: false,\n attachTimeoutMs: opts.attachTimeoutMs ?? 15_000,\n key: (url) => {\n // Calls between shards: http://cellb.internal/<name>/.\n if (url.host === internal.host) {\n const name = url.pathname.split(\"/\")[1];\n return name ? decodeURIComponent(name) : undefined;\n }\n return split(url)?.name;\n },\n // A call between shards names its shard (it waits for that one); the rest go to the shard\n // with the fewest requests in flight, round robin among equals. The tabs' pages are handlers\n // of the key too (their adapters'), with nothing to serve: never picked.\n route: (request, _key, handlers) => {\n const shards = handlers.filter(isShard);\n const named = request.headers.get(H.shard);\n if (named !== null)\n return shards.find((h) => (h.meta as { shard: number }).shard === Number(named));\n if (!shards.length) return undefined;\n const start = rr++ % shards.length;\n let best = shards[start];\n for (let i = 1; i < shards.length; i++) {\n const h = shards[(start + i) % shards.length];\n if (h.inflight < best.inflight) best = h;\n }\n return best;\n },\n // A call between shards fails as an error its caller rethrows (postVia); a page's request\n // gets a response it can read.\n failure: (request, failure) => failed(request, failure),\n // Pages may not address objects or shards directly: no control headers on their sockets.\n socketHeaders: (headers, from) =>\n from === \"page\"\n ? headers?.filter(([name]) => !name.toLowerCase().startsWith(\"x-cellb\"))\n : headers,\n });\n dispatcher.start();\n\n const failed = (request: Request, failure: DispatchFailure): Response => {\n const named = request.headers.get(H.shard);\n const what = named !== null ? `cell shard ${named}` : \"the project\";\n const error =\n failure.kind === \"lost\" && failure.error instanceof LinkLostError && named !== null\n ? new ShardOwnerLostError(Number(named))\n : failure.kind === \"timeout\"\n ? new Error(`${what} was not attached in time`)\n : failure.kind === \"gone\"\n ? new Error(`${what} has no tab running it`)\n : (failure.error as Error);\n if (request.headers.get(H.kind) !== null) return errorResponse(error, 503);\n return new Response(`cellb: ${(error as Error)?.message ?? error}`, { status: 503 });\n };\n\n const askForLinks = async (name: string) => {\n const clients = await sw.clients.matchAll({ type: \"window\", includeUncontrolled: true });\n for (const c of clients) c.postMessage({ type: NEED_LINKS, name });\n };\n\n /** Whether a tab runs project `name`'s shards, waiting up to `ms` for one to link. */\n const runningShards = async (name: string, ms: number): Promise<boolean> => {\n await dispatcher.ready;\n const live = () => dispatcher.table.live(name).some(isShard);\n if (live()) return true;\n void askForLinks(name);\n for (const until = Date.now() + ms; Date.now() < until; ) {\n await new Promise((r) => setTimeout(r, 100));\n if (live()) return true;\n }\n return false;\n };\n\n /** Headers for a request the router sends on: no control headers from the page, its base. */\n const routed = (req: Request, prefix: string, root: boolean): Headers => {\n // Headers only: a Request built from `req` would take its body.\n const headers = new Headers(req.headers);\n for (const h of Object.values(H)) if (h !== H.cookie) headers.delete(h);\n if (opts.stripBase && !root) headers.set(H.base, prefix);\n return headers;\n };\n\n /** A request to project `name`, with the page's cookies in and the Worker's out. */\n const serve = async (\n { name, prefix }: { name: string; prefix: string },\n req: Request,\n root: boolean,\n ): Promise<Response> => {\n try {\n // A project no tab has ever served is not the router's: the page's own request goes to the\n // network, as if there were no router (not the copy below, with the page's cookies in a\n // header and a streamed body).\n await dispatcher.ready;\n if (!dispatcher.serves(name)) return await fetch(req);\n const headers = await withPageCookies(\n sw,\n new Request(req.url, { headers: routed(req, prefix, root) }),\n );\n const res = await dispatcher.dispatch(\n new Request(req.url, {\n method: req.method,\n headers,\n body: req.body,\n signal: req.signal,\n duplex: \"half\",\n } as RequestInit),\n );\n return await applyWorkerCookies(sw, res);\n } catch (err) {\n // A response the page can read, instead of a network error with no cause.\n console.error(`cellb: ${req.method} ${new URL(req.url).pathname} failed:`, err);\n return new Response(`cellb: ${(err as Error)?.stack ?? err}`, { status: 502 });\n }\n };\n\n sw.addEventListener(\"fetch\", (e: FetchEvent) => {\n const req = e.request;\n const url = new URL(req.url);\n const root = atRoot(url);\n if (!root && req.mode === \"navigate\") return; // the pages under basePath are the host's\n const project = split(url);\n if (!project) return;\n const hostPage = root && req.mode === \"navigate\" ? opts.root?.hostPage : undefined;\n if (hostPage)\n e.respondWith(\n runningShards(project.name, opts.root?.hostWaitMs ?? 2_000).then((running) =>\n running\n ? serve(project, req, root)\n : Response.redirect(\n `${new URL(hostPage, url.origin).href}?next=${encodeURIComponent(`${url.pathname}${url.search}`)}`,\n 302,\n ),\n ),\n );\n else e.respondWith(serve(project, req, root));\n });\n\n // A page's socket (`serviceWorkerConnector`): routed as a fetch would be, without the page's\n // headers.\n sw.addEventListener(\"message\", (e: ExtendableMessageEvent) => {\n const m = e.data;\n if (m?.type !== SOCKET) return;\n const reply = e.ports[0];\n e.waitUntil(\n (async () => {\n try {\n const url = new URL(m.url);\n const httpUrl = new URL(url);\n if (httpUrl.protocol === \"ws:\") httpUrl.protocol = \"http:\";\n else if (httpUrl.protocol === \"wss:\") httpUrl.protocol = \"https:\";\n const project = split(httpUrl);\n if (!project) throw new Error(`not a project URL: ${m.url}`);\n const headers: [string, string][] = [];\n if (opts.stripBase && !atRoot(httpUrl)) headers.push([H.base, project.prefix]);\n const { port, protocol } = await dispatcher.connectWebSocket(\n `${httpUrl}`,\n m.protocols ?? [],\n headers,\n );\n reply.postMessage({ ok: true, port, protocol }, [port]);\n } catch (err) {\n reply.postMessage({ ok: false, error: String((err as Error)?.message ?? err) });\n }\n })(),\n );\n });\n\n return { dispatcher };\n}\n"]}
|
|
@@ -70,6 +70,13 @@ export interface LoadedProject {
|
|
|
70
70
|
unsupported: string[];
|
|
71
71
|
/** A request to the project, as its Worker (and assets) answer it. */
|
|
72
72
|
fetch(req: Request): Promise<Response>;
|
|
73
|
+
/**
|
|
74
|
+
* In a browser (an OPFS pool): the cells' databases as `[file name, bytes]`, named as
|
|
75
|
+
* `nodeSqliteOpener(dir)` names them, so that a data directory on Node (`loadProject(dir,
|
|
76
|
+
* { data })`) starts where this browser's cells are. CellB's own databases (`__cellb_*`) are
|
|
77
|
+
* included; R2 objects are not. Empty with a bucket (it holds the cells); not defined on Node.
|
|
78
|
+
*/
|
|
79
|
+
exportCells?(): Promise<[string, Uint8Array][]>;
|
|
73
80
|
close(): Promise<void>;
|
|
74
81
|
}
|
|
75
82
|
/** Reads JSON (or JSONC) at `path`, or undefined when the file is missing. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"built-project.js","sourceRoot":"","sources":["../../src/project/built-project.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The folder `cellb build` writes, and what `loadProject` reads, on both platforms:\n *\n * wrangler.json the project's configuration (`main` → \"worker.js\", `assets.directory` → \"assets\")\n * worker.js `main` bundled for a browser realm (bundleWorkerForBrowser), if there is a `main`\n * assets/… the files of `assets.directory`, as they are\n * cellb.json this manifest: the format, and the asset paths (a static host cannot list a folder)\n *\n * Platform-neutral: it reads through a `ProjectReader` (Node's fs, `fetch` of a URL, a FilesApi).\n */\nimport type { FilesApi } from \"@statewalker/webrun-files\";\nimport type { AssetFiles } from \"../bindings/assets.js\";\nimport type { WorkersAiOptions } from \"../bindings/workers-ai.js\";\nimport type { CellRuntime } from \"../core/runtime.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport type { WranglerConfig } from \"./wrangler.js\";\n\n/** The manifest's file name in a built folder. */\nexport const BUILD_MANIFEST = \"cellb.json\";\n/** The format a built folder declares in its manifest. */\nexport const BUILD_FORMAT = \"cellb-build/1\";\n/** The bundled `main` in a built folder. */\nexport const BUILT_WORKER = \"worker.js\";\n/** The assets directory in a built folder. */\nexport const BUILT_ASSETS = \"assets\";\n\nexport interface BuildManifest {\n format: typeof BUILD_FORMAT;\n /** `worker.js`, or null for a project without `main` (assets only). */\n main: string | null;\n /** The asset files, as paths under `assets/` (\"/index.html\", \"/css/site.css\"). */\n assets: string[];\n}\n\n/** A built project in memory: what `browserProjectRuntime` takes. */\nexport interface BuiltProject {\n config: WranglerConfig;\n /** `main` bundled for a browser realm, or null. */\n code: string | null;\n assets: AssetFiles;\n}\n\n/** Reads the files of a project folder, wherever it lives; `undefined` for a missing file. */\nexport interface ProjectReader {\n bytes(path: string): Promise<Uint8Array | undefined>;\n /** The files under `dir`, as paths relative to it (\"/a/b.html\"); only where the source can list. */\n list?(dir: string): Promise<string[]>;\n}\n\n/** Where `loadProject` finds a project. */\nexport type ProjectSource =\n /** Node: a folder with wrangler.json(c), built or not; browser: the URL of a `cellb build` folder. */\n | string\n | URL\n /** Any FilesApi holding either kind of folder at its root. */\n | FilesApi;\n\n/** Options of `loadProject`, the same on Node and in browsers. */\nexport interface LoadProjectOptions<Bucket = unknown> {\n /**\n * Where cells keep their data. Node: a directory (SQLite files and the project's files under\n * it; default: memory). Browser: an OPFS name, the pool (`<data>`) and the files directory\n * (`<data>-files`) (default: the project's `name`).\n */\n data?: string;\n /** A fleet bucket: a `BrowserBucket` in browsers, a `CellStorage` on Node. */\n bucket?: Bucket;\n /** The OpenAI-compatible endpoint behind the project's `ai` binding (Workers AI). */\n ai?: WorkersAiOptions;\n /** Browser only: an initialized SQLite WASM module (default: loads `@sqlite.org/sqlite-wasm`). */\n sqlite3?: unknown;\n}\n\n/** A running project. */\nexport interface LoadedProject {\n config: WranglerConfig;\n runtime: CellRuntime;\n /** Configuration entries cellb does not run (reported, not silently ignored). */\n unsupported: string[];\n /** A request to the project, as its Worker (and assets) answer it. */\n fetch(req: Request): Promise<Response>;\n close(): Promise<void>;\n}\n\nconst decoder = new TextDecoder();\n\n/** Reads JSON (or JSONC) at `path`, or undefined when the file is missing. */\nexport async function readJson<T>(reader: ProjectReader, path: string): Promise<T | undefined> {\n const bytes = await reader.bytes(path);\n return bytes ? (parseJsonc(decoder.decode(bytes)) as T) : undefined;\n}\n\n/** The manifest of a built folder, or undefined when the folder is not one. */\nexport async function readBuildManifest(reader: ProjectReader): Promise<BuildManifest | undefined> {\n const manifest = await readJson<BuildManifest>(reader, BUILD_MANIFEST);\n if (!manifest) return undefined;\n if (manifest.format !== BUILD_FORMAT)\n throw new Error(`${BUILD_MANIFEST}: unknown format ${JSON.stringify(manifest.format)}`);\n return manifest;\n}\n\n/** Reads a `cellb build` folder: its configuration, its bundled `main` and its assets. */\nexport async function readBuiltProject(\n reader: ProjectReader,\n manifest?: BuildManifest,\n): Promise<BuiltProject> {\n manifest ??= await readBuildManifest(reader);\n if (!manifest) throw new Error(`no ${BUILD_MANIFEST}: not a folder written by \\`cellb build\\``);\n const config = await readJson<WranglerConfig>(reader, \"wrangler.json\");\n if (!config) throw new Error(\"no wrangler.json in the built folder\");\n let code: string | null = null;\n if (manifest.main) {\n const bytes = await reader.bytes(manifest.main);\n if (!bytes) throw new Error(`${manifest.main} is missing from the built folder`);\n code = decoder.decode(bytes);\n }\n const assets: AssetFiles = new Map();\n await Promise.all(\n manifest.assets.map(async (p) => {\n const bytes = await reader.bytes(`${BUILT_ASSETS}${p}`);\n if (!bytes) throw new Error(`${BUILT_ASSETS}${p} is missing from the built folder`);\n assets.set(p, bytes);\n }),\n );\n return { config, code, assets };\n}\n\n/** A reader over a FilesApi, rooted at `root` (\"/\" by default). */\nexport function filesApiReader(files: FilesApi, root = \"/\"): ProjectReader {\n const base = root.endsWith(\"/\") ? root : `${root}/`;\n const at = (p: string) => `${base}${p.replace(/^\\/+/, \"\")}`;\n return {\n async bytes(path) {\n const full = at(path);\n const stats = await files.stats(full);\n if (!stats || stats.kind !== \"file\") return undefined;\n const chunks: Uint8Array[] = [];\n for await (const c of files.read(full)) chunks.push(c);\n return concat(chunks);\n },\n async list(dir) {\n const full = at(dir).replace(/\\/+$/, \"\");\n const out: string[] = [];\n for await (const e of files.list(full, { recursive: true }))\n if (e.kind === \"file\") out.push(e.path.slice(full.length));\n return out;\n },\n };\n}\n\n/** A reader over HTTP: files of the folder at `base` (a URL ending in \"/\"). */\nexport function urlReader(base: URL, fetchFn: typeof fetch = fetch): ProjectReader {\n return {\n async bytes(path) {\n const res = await fetchFn(new URL(path.replace(/^\\/+/, \"\"), base));\n if (res.status === 404) {\n await res.body?.cancel();\n return undefined;\n }\n if (!res.ok) throw new Error(`GET ${new URL(path, base)}: ${res.status} ${res.statusText}`);\n return new Uint8Array(await res.arrayBuffer());\n },\n };\n}\n\n/** Whether `v` is a FilesApi (a source given as files rather than a path or URL). */\nexport function isFilesApi(v: unknown): v is FilesApi {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !(v instanceof URL) &&\n typeof (v as FilesApi).read === \"function\" &&\n typeof (v as FilesApi).list === \"function\" &&\n typeof (v as FilesApi).stats === \"function\"\n );\n}\n\n/** A built project's configuration as `wrangler.json` holds it: `main` and assets renamed. */\nexport function builtConfig(config: WranglerConfig): WranglerConfig {\n const out: WranglerConfig = { ...config };\n if (config.main) out.main = BUILT_WORKER;\n if (config.assets) out.assets = { ...config.assets, directory: BUILT_ASSETS };\n return out;\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n if (chunks.length === 1) return chunks[0];\n const out = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));\n let at = 0;\n for (const c of chunks) {\n out.set(c, at);\n at += c.length;\n }\n return out;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"built-project.js","sourceRoot":"","sources":["../../src/project/built-project.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC,kDAAkD;AAClD,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAC3C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;AAC5C,4CAA4C;AAC5C,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AACxC,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAmErC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,MAAqB,EAAE,IAAY;IACnE,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,CAAC,CAAE,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAqB;IAC3D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAgB,MAAM,EAAE,cAAc,CAAC,CAAC;IACvE,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY;QAClC,MAAM,IAAI,KAAK,CAAC,GAAG,cAAc,oBAAoB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1F,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAqB,EACrB,QAAwB;IAExB,QAAQ,KAAK,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,cAAc,2CAA2C,CAAC,CAAC;IAChG,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAiB,MAAM,EAAE,eAAe,CAAC,CAAC;IACvE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACrE,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,CAAC,IAAI,mCAAmC,CAAC,CAAC;QACjF,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,MAAM,GAAe,IAAI,GAAG,EAAE,CAAC;IACrC,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,GAAG,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACpF,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACvB,CAAC,CAAC,CACH,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,KAAe,EAAE,IAAI,GAAG,GAAG;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;IACpD,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;IAC5D,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,IAAI;YACd,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACtD,MAAM,MAAM,GAAiB,EAAE,CAAC;YAChC,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG;YACZ,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACzC,MAAM,GAAG,GAAa,EAAE,CAAC;YACzB,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;gBACzD,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;oBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7D,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,SAAS,CAAC,IAAS,EAAE,OAAO,GAAiB,KAAK;IAChE,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,IAAI;YACd,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YACnE,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;gBACzB,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;YAC5F,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACjD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAC,CAAU;IACnC,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACV,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC;QACnB,OAAQ,CAAc,CAAC,IAAI,KAAK,UAAU;QAC1C,OAAQ,CAAc,CAAC,IAAI,KAAK,UAAU;QAC1C,OAAQ,CAAc,CAAC,KAAK,KAAK,UAAU,CAC5C,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,WAAW,CAAC,MAAsB;IAChD,MAAM,GAAG,GAAmB,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1C,IAAI,MAAM,CAAC,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC;IACzC,IAAI,MAAM,CAAC,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;IAC9E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,MAAM,CAAC,MAAoB;IAClC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACf,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * The folder `cellb build` writes, and what `loadProject` reads, on both platforms:\n *\n * wrangler.json the project's configuration (`main` → \"worker.js\", `assets.directory` → \"assets\")\n * worker.js `main` bundled for a browser realm (bundleWorkerForBrowser), if there is a `main`\n * assets/… the files of `assets.directory`, as they are\n * cellb.json this manifest: the format, and the asset paths (a static host cannot list a folder)\n *\n * Platform-neutral: it reads through a `ProjectReader` (Node's fs, `fetch` of a URL, a FilesApi).\n */\nimport type { FilesApi } from \"@statewalker/webrun-files\";\nimport type { AssetFiles } from \"../bindings/assets.js\";\nimport type { WorkersAiOptions } from \"../bindings/workers-ai.js\";\nimport type { CellRuntime } from \"../core/runtime.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport type { WranglerConfig } from \"./wrangler.js\";\n\n/** The manifest's file name in a built folder. */\nexport const BUILD_MANIFEST = \"cellb.json\";\n/** The format a built folder declares in its manifest. */\nexport const BUILD_FORMAT = \"cellb-build/1\";\n/** The bundled `main` in a built folder. */\nexport const BUILT_WORKER = \"worker.js\";\n/** The assets directory in a built folder. */\nexport const BUILT_ASSETS = \"assets\";\n\nexport interface BuildManifest {\n format: typeof BUILD_FORMAT;\n /** `worker.js`, or null for a project without `main` (assets only). */\n main: string | null;\n /** The asset files, as paths under `assets/` (\"/index.html\", \"/css/site.css\"). */\n assets: string[];\n}\n\n/** A built project in memory: what `browserProjectRuntime` takes. */\nexport interface BuiltProject {\n config: WranglerConfig;\n /** `main` bundled for a browser realm, or null. */\n code: string | null;\n assets: AssetFiles;\n}\n\n/** Reads the files of a project folder, wherever it lives; `undefined` for a missing file. */\nexport interface ProjectReader {\n bytes(path: string): Promise<Uint8Array | undefined>;\n /** The files under `dir`, as paths relative to it (\"/a/b.html\"); only where the source can list. */\n list?(dir: string): Promise<string[]>;\n}\n\n/** Where `loadProject` finds a project. */\nexport type ProjectSource =\n /** Node: a folder with wrangler.json(c), built or not; browser: the URL of a `cellb build` folder. */\n | string\n | URL\n /** Any FilesApi holding either kind of folder at its root. */\n | FilesApi;\n\n/** Options of `loadProject`, the same on Node and in browsers. */\nexport interface LoadProjectOptions<Bucket = unknown> {\n /**\n * Where cells keep their data. Node: a directory (SQLite files and the project's files under\n * it; default: memory). Browser: an OPFS name, the pool (`<data>`) and the files directory\n * (`<data>-files`) (default: the project's `name`).\n */\n data?: string;\n /** A fleet bucket: a `BrowserBucket` in browsers, a `CellStorage` on Node. */\n bucket?: Bucket;\n /** The OpenAI-compatible endpoint behind the project's `ai` binding (Workers AI). */\n ai?: WorkersAiOptions;\n /** Browser only: an initialized SQLite WASM module (default: loads `@sqlite.org/sqlite-wasm`). */\n sqlite3?: unknown;\n}\n\n/** A running project. */\nexport interface LoadedProject {\n config: WranglerConfig;\n runtime: CellRuntime;\n /** Configuration entries cellb does not run (reported, not silently ignored). */\n unsupported: string[];\n /** A request to the project, as its Worker (and assets) answer it. */\n fetch(req: Request): Promise<Response>;\n /**\n * In a browser (an OPFS pool): the cells' databases as `[file name, bytes]`, named as\n * `nodeSqliteOpener(dir)` names them, so that a data directory on Node (`loadProject(dir,\n * { data })`) starts where this browser's cells are. CellB's own databases (`__cellb_*`) are\n * included; R2 objects are not. Empty with a bucket (it holds the cells); not defined on Node.\n */\n exportCells?(): Promise<[string, Uint8Array][]>;\n close(): Promise<void>;\n}\n\nconst decoder = new TextDecoder();\n\n/** Reads JSON (or JSONC) at `path`, or undefined when the file is missing. */\nexport async function readJson<T>(reader: ProjectReader, path: string): Promise<T | undefined> {\n const bytes = await reader.bytes(path);\n return bytes ? (parseJsonc(decoder.decode(bytes)) as T) : undefined;\n}\n\n/** The manifest of a built folder, or undefined when the folder is not one. */\nexport async function readBuildManifest(reader: ProjectReader): Promise<BuildManifest | undefined> {\n const manifest = await readJson<BuildManifest>(reader, BUILD_MANIFEST);\n if (!manifest) return undefined;\n if (manifest.format !== BUILD_FORMAT)\n throw new Error(`${BUILD_MANIFEST}: unknown format ${JSON.stringify(manifest.format)}`);\n return manifest;\n}\n\n/** Reads a `cellb build` folder: its configuration, its bundled `main` and its assets. */\nexport async function readBuiltProject(\n reader: ProjectReader,\n manifest?: BuildManifest,\n): Promise<BuiltProject> {\n manifest ??= await readBuildManifest(reader);\n if (!manifest) throw new Error(`no ${BUILD_MANIFEST}: not a folder written by \\`cellb build\\``);\n const config = await readJson<WranglerConfig>(reader, \"wrangler.json\");\n if (!config) throw new Error(\"no wrangler.json in the built folder\");\n let code: string | null = null;\n if (manifest.main) {\n const bytes = await reader.bytes(manifest.main);\n if (!bytes) throw new Error(`${manifest.main} is missing from the built folder`);\n code = decoder.decode(bytes);\n }\n const assets: AssetFiles = new Map();\n await Promise.all(\n manifest.assets.map(async (p) => {\n const bytes = await reader.bytes(`${BUILT_ASSETS}${p}`);\n if (!bytes) throw new Error(`${BUILT_ASSETS}${p} is missing from the built folder`);\n assets.set(p, bytes);\n }),\n );\n return { config, code, assets };\n}\n\n/** A reader over a FilesApi, rooted at `root` (\"/\" by default). */\nexport function filesApiReader(files: FilesApi, root = \"/\"): ProjectReader {\n const base = root.endsWith(\"/\") ? root : `${root}/`;\n const at = (p: string) => `${base}${p.replace(/^\\/+/, \"\")}`;\n return {\n async bytes(path) {\n const full = at(path);\n const stats = await files.stats(full);\n if (!stats || stats.kind !== \"file\") return undefined;\n const chunks: Uint8Array[] = [];\n for await (const c of files.read(full)) chunks.push(c);\n return concat(chunks);\n },\n async list(dir) {\n const full = at(dir).replace(/\\/+$/, \"\");\n const out: string[] = [];\n for await (const e of files.list(full, { recursive: true }))\n if (e.kind === \"file\") out.push(e.path.slice(full.length));\n return out;\n },\n };\n}\n\n/** A reader over HTTP: files of the folder at `base` (a URL ending in \"/\"). */\nexport function urlReader(base: URL, fetchFn: typeof fetch = fetch): ProjectReader {\n return {\n async bytes(path) {\n const res = await fetchFn(new URL(path.replace(/^\\/+/, \"\"), base));\n if (res.status === 404) {\n await res.body?.cancel();\n return undefined;\n }\n if (!res.ok) throw new Error(`GET ${new URL(path, base)}: ${res.status} ${res.statusText}`);\n return new Uint8Array(await res.arrayBuffer());\n },\n };\n}\n\n/** Whether `v` is a FilesApi (a source given as files rather than a path or URL). */\nexport function isFilesApi(v: unknown): v is FilesApi {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !(v instanceof URL) &&\n typeof (v as FilesApi).read === \"function\" &&\n typeof (v as FilesApi).list === \"function\" &&\n typeof (v as FilesApi).stats === \"function\"\n );\n}\n\n/** A built project's configuration as `wrangler.json` holds it: `main` and assets renamed. */\nexport function builtConfig(config: WranglerConfig): WranglerConfig {\n const out: WranglerConfig = { ...config };\n if (config.main) out.main = BUILT_WORKER;\n if (config.assets) out.assets = { ...config.assets, directory: BUILT_ASSETS };\n return out;\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n if (chunks.length === 1) return chunks[0];\n const out = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));\n let at = 0;\n for (const c of chunks) {\n out.set(c, at);\n at += c.length;\n }\n return out;\n}\n"]}
|
|
@@ -5,7 +5,7 @@ import { join, resolve } from "node:path";
|
|
|
5
5
|
import { Worker as NodeWorker } from "node:worker_threads";
|
|
6
6
|
import { build } from "esbuild";
|
|
7
7
|
import { applyD1Migrations } from "../bindings/d1-migrations.js";
|
|
8
|
-
import { exportNamesByModule, IMPORT_FROM, prefixModule, RESOLVE_MODULE_NAME_SOURCE,
|
|
8
|
+
import { analyzeModule, exportNamesByModule, IMPORT_FROM, prefixModule, RESOLVE_MODULE_NAME_SOURCE, } from "../bindings/module-registry.js";
|
|
9
9
|
import { compileWasmModules, moduleText, outboundFetch, wasmModulesOf, } from "../bindings/worker-loader.js";
|
|
10
10
|
import { ctxExports } from "../core/handles.js";
|
|
11
11
|
import { isolatedModuleLoader } from "../isolate/host.js";
|
|
@@ -53,15 +53,19 @@ function loadedModuleTexts(code) {
|
|
|
53
53
|
for (const [name, m] of Object.entries(code.modules))
|
|
54
54
|
texts[name] = moduleText(m, name, names);
|
|
55
55
|
const modules = {};
|
|
56
|
+
const exports = new Map();
|
|
56
57
|
for (const [name, text] of Object.entries(texts)) {
|
|
57
|
-
|
|
58
|
+
// One parse per module: the import() calls to route, and the exports the registry lists.
|
|
59
|
+
const analysis = analyzeModule(text, name);
|
|
60
|
+
exports.set(name, analysis?.exports ?? { names: [], stars: [] });
|
|
61
|
+
const routed = analysis?.routed;
|
|
58
62
|
let prelude = routed === undefined ? "" : `import { importFrom as ${IMPORT_FROM} } from "cellb:modules"; `;
|
|
59
63
|
// The main module evaluates the registry, so it is there before any code runs.
|
|
60
64
|
if (name === code.mainModule && !prelude)
|
|
61
65
|
prelude = 'import "cellb:modules"; ';
|
|
62
66
|
modules[name] = prelude ? prefixModule(routed ?? text, prelude) : text;
|
|
63
67
|
}
|
|
64
|
-
return { modules, registry: registrySource(texts, code.mainModule) };
|
|
68
|
+
return { modules, registry: registrySource(Object.keys(texts), exports, code.mainModule) };
|
|
65
69
|
}
|
|
66
70
|
/**
|
|
67
71
|
* What an import of loaded code that names none of its modules becomes: a module that throws when
|
|
@@ -81,9 +85,8 @@ function missingModule(spec, importer) {
|
|
|
81
85
|
* also publishes itself as `globalThis.__cellbLoadedModules`, where an isolate thread's module
|
|
82
86
|
* hooks find it (node-entry.ts: `import()` from code built with `Function`).
|
|
83
87
|
*/
|
|
84
|
-
function registrySource(
|
|
88
|
+
function registrySource(names, exports, main) {
|
|
85
89
|
const q = JSON.stringify;
|
|
86
|
-
const names = Object.keys(texts);
|
|
87
90
|
return [
|
|
88
91
|
`const names = new Set(${q(names)});`,
|
|
89
92
|
`const resolve = ${RESOLVE_MODULE_NAME_SOURCE};`,
|
|
@@ -92,7 +95,7 @@ function registrySource(texts, main) {
|
|
|
92
95
|
" const name = resolve(String(spec), importer, names);",
|
|
93
96
|
" return name === undefined ? import(spec) : table[name]();",
|
|
94
97
|
"};",
|
|
95
|
-
`globalThis.__cellbLoadedModules = { main: ${q(main)}, names, exportNames: ${q(exportNamesByModule(
|
|
98
|
+
`globalThis.__cellbLoadedModules = { main: ${q(main)}, names, exportNames: ${q(exportNamesByModule(exports))}, load: (name) => table[name]() };`,
|
|
96
99
|
].join("\n");
|
|
97
100
|
}
|
|
98
101
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-project.js","sourceRoot":"","sources":["../../src/project/node-project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { Worker as NodeWorker } from \"node:worker_threads\";\nimport { build } from \"esbuild\";\nimport { applyD1Migrations } from \"../bindings/d1-migrations.js\";\nimport {\n exportNamesByModule,\n IMPORT_FROM,\n prefixModule,\n RESOLVE_MODULE_NAME_SOURCE,\n routeDynamicImports,\n} from \"../bindings/module-registry.js\";\nimport {\n compileWasmModules,\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n type WorkerCode,\n wasmModulesOf,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport { isolatedModuleLoader } from \"../isolate/host.js\";\nimport type { PortLike } from \"../isolate/protocol.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport { type ModuleRule, moduleRulesPlugin } from \"./module-rules.js\";\nimport { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n hasNodeCompat,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n type ProjectRuntime,\n populatesProcessEnv,\n processEnvOf,\n WRANGLER_FILES,\n type WranglerConfig,\n} from \"./wrangler.js\";\n\n/** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */\nexport function readWranglerConfig(dir: string): WranglerConfig {\n for (const name of WRANGLER_FILES) {\n const p = join(dir, name);\n if (existsSync(p)) return parseJsonc(readFileSync(p, \"utf8\")) as WranglerConfig;\n }\n throw new Error(`no wrangler.jsonc or wrangler.json in ${dir}`);\n}\n\n/** A bare Node.js built-in specifier (\"path\", \"fs/promises\"), not one of a package. */\nconst nodeBuiltinName = new RegExp(\n `^(${builtinModules\n .filter((m) => !m.startsWith(\"_\") && !m.includes(\":\"))\n .map((m) => m.replace(/[/]/g, \"\\\\/\"))\n .join(\"|\")})$`,\n);\n\n/** Worker code's `node:fs` under nodejs_compat on Node: Node's own, with workerd's `/bundle`. */\nconst FS_OVERLAY = `import * as real from \"node:fs\";\nimport { bundleFs } from \"cellb:bundle-fs\";\nexport * from \"node:fs\";\nconst o = bundleFs(real);\nexport const { existsSync, readFileSync, statSync, lstatSync, readdirSync, accessSync, readFile, stat, lstat, readdir, access, promises } = o;\nexport default { ...real, ...o };`;\n/** Worker code's `node:fs/promises`, the same way. */\nconst FS_PROMISES_OVERLAY = `import * as real from \"node:fs/promises\";\nimport { bundleFsPromises } from \"cellb:bundle-fs\";\nexport * from \"node:fs/promises\";\nconst o = bundleFsPromises(real);\nexport const { readFile, stat, lstat, readdir, access } = o;\nexport default o;`;\n\n/**\n * The modules of loaded code as ES module text, each `import()` the bundler cannot link going to\n * the `cellb:modules` registry instead (module-registry.ts).\n */\nfunction loadedModuleTexts(code: WorkerCode): {\n modules: Record<string, string>;\n registry: string;\n} {\n const texts: Record<string, string> = {};\n const names = new Set(Object.keys(code.modules));\n for (const [name, m] of Object.entries(code.modules)) texts[name] = moduleText(m, name, names);\n const modules: Record<string, string> = {};\n for (const [name, text] of Object.entries(texts)) {\n const routed = routeDynamicImports(text, name);\n let prelude =\n routed === undefined ? \"\" : `import { importFrom as ${IMPORT_FROM} } from \"cellb:modules\"; `;\n // The main module evaluates the registry, so it is there before any code runs.\n if (name === code.mainModule && !prelude) prelude = 'import \"cellb:modules\"; ';\n modules[name] = prelude ? prefixModule(routed ?? text, prelude) : text;\n }\n return { modules, registry: registrySource(texts, code.mainModule) };\n}\n\n/**\n * What an import of loaded code that names none of its modules becomes: a module that throws when\n * it is evaluated, so the failure comes where workerd's would (when the importing module runs), not\n * at build time or when an unrelated module loads. CommonJS, so any named import of it builds.\n */\nfunction missingModule(spec: string, importer: string) {\n const message = `No such module \"${spec}\" (imported from \"${importer}\")`;\n return {\n path: `${importer}\\u0000${spec}`,\n namespace: \"cells-missing\",\n pluginData: `throw new Error(${JSON.stringify(message)});\\nmodule.exports = {};`,\n };\n}\n\n/**\n * The `cellb:modules` registry of a bundle of loaded code: each module, imported on demand. It\n * also publishes itself as `globalThis.__cellbLoadedModules`, where an isolate thread's module\n * hooks find it (node-entry.ts: `import()` from code built with `Function`).\n */\nfunction registrySource(texts: Record<string, string>, main: string): string {\n const q = JSON.stringify;\n const names = Object.keys(texts);\n return [\n `const names = new Set(${q(names)});`,\n `const resolve = ${RESOLVE_MODULE_NAME_SOURCE};`,\n `const table = { ${names.map((n) => `${q(n)}: () => import(${q(`memory:${n}`)})`).join(\", \")} };`,\n \"export const importFrom = (spec, importer) => {\",\n \" const name = resolve(String(spec), importer, names);\",\n \" return name === undefined ? import(spec) : table[name]();\",\n \"};\",\n `globalThis.__cellbLoadedModules = { main: ${q(main)}, names, exportNames: ${q(exportNamesByModule(texts))}, load: (name) => table[name]() };`,\n ].join(\"\\n\");\n}\n\n/**\n * Node host: bundles `main` with esbuild (as `celld deploy` does) and builds the runtime.\n * `cloudflare:workers` resolves to cellb's module so user classes extend the\n * runtime's own DurableObject / WorkerEntrypoint.\n */\n/** Bundles Worker code (a file, or in-memory modules) with the runtime's module mappings, then imports it. */\nexport async function bundleWorker(\n entry:\n | { path: string }\n | {\n modules: Record<string, string>;\n main: string;\n /** The `cellb:modules` registry the modules import (loadedModuleTexts). */\n registry?: string;\n },\n logs?: LogSink,\n outbound?: typeof fetch,\n opts: {\n nodeCompat?: boolean;\n standardBinaryType?: boolean;\n scope?: WorkerScope;\n /** wrangler `rules` for non-JS imports (the defaults: `.wasm`, `.bin`, `.txt`…, as wrangler). */\n rules?: ModuleRule[];\n } = {},\n): Promise<WorkerModule> {\n // `env` and `exports` of `cloudflare:workers` belong to one Worker: the bundle reads them\n // from its own scope (empty objects for code that has none).\n const scopeKey = opts.scope ? `s${Math.random().toString(36).slice(2)}` : \"\";\n if (opts.scope) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[scopeKey] = opts.scope;\n }\n // Loaded code gets a bundle-local `fetch` (globalOutbound policy)…\n const outboundKey = outbound ? `o${Math.random().toString(36).slice(2)}` : \"\";\n if (outbound) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[outboundKey] = outbound;\n }\n // …and a bundle-local `console` that also feeds its Tail Workers.\n const consoleKey = logs ? `c${Math.random().toString(36).slice(2)}` : \"\";\n if (logs) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const registry = g.__cellsConsoles as Record<string, unknown>;\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n registry[consoleKey] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n }\n const outDir = mkdtempSync(join(tmpdir(), \"cells-worker-\"));\n const out = join(outDir, \"worker.mjs\");\n const cfWorkers = ownModule(import.meta.dirname, \"cloudflare-workers\");\n // This bundle's `cloudflare:workers`: the runtime's classes plus its own `env` and `exports`.\n // A file of its own, kept out of the bundle so it adds no names to the Worker's scope.\n const workersModule = join(outDir, \"cloudflare-workers.mjs\");\n writeFileSync(\n workersModule,\n [\n `export * from ${JSON.stringify(cfWorkers)};`,\n `const scope = globalThis.__cellsWorkerScopes?.[${JSON.stringify(scopeKey)}];`,\n \"export const env = scope ? scope.env : {};\",\n \"export const exports = scope ? scope.exports : {};\",\n \"export const waitUntil = (p) => scope?.waitUntil(p);\",\n ].join(\"\\n\"),\n );\n const memory = \"modules\" in entry ? entry.modules : undefined;\n await build({\n entryPoints: [\n memory ? `memory:${(entry as { main: string }).main}` : (entry as { path: string }).path,\n ],\n outfile: out,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n // As `celld deploy` resolves packages: workerd's conditions, then `module` and `main` (the\n // neutral platform has no main fields, so a package with only `main` would not resolve).\n conditions: [\"workerd\", \"worker\", \"browser\"],\n mainFields: [\"module\", \"main\"],\n target: \"es2022\",\n logLevel: \"silent\",\n // nodejs_compat: CommonJS dependencies `require()` Node's built-ins (mime-types requires\n // node:path), as they may under workerd's nodejs_compat. In an ES module bundle esbuild's\n // require shim needs a `require` in scope: vitest's module runner provides one, plain Node\n // does not.\n ...(opts.nodeCompat\n ? {\n banner: {\n js: 'import { createRequire as __cellbCreateRequire } from \"node:module\";\\nconst require = __cellbCreateRequire(import.meta.url);',\n },\n }\n : {}),\n inject: [\n ownModule(import.meta.dirname, \"workers-globals\"),\n ...(logs ? [\"cellb:console\"] : []),\n ...(outbound ? [\"cellb:fetch\"] : []),\n ],\n plugins: [\n {\n name: \"cells-modules\",\n setup(b) {\n b.onResolve({ filter: /^cellb:console$/ }, () => ({\n path: \"console\",\n namespace: \"cells-console\",\n }));\n // nodejs_compat on a Node host: `node:*` are the real Node.js modules, except that\n // `node:fs` also reads workerd's `/bundle` (node-compat/bundle-files.ts).\n if (opts.nodeCompat) {\n b.onResolve({ filter: /^(node:)?fs(\\/promises)?$/ }, (a) => {\n const name = a.path.replace(/^node:/, \"\");\n return a.namespace === \"cells-fs\"\n ? { path: `node:${name}`, external: true }\n : { path: name, namespace: \"cells-fs\" };\n });\n b.onResolve({ filter: /^cellb:bundle-fs$/ }, () => ({\n path: ownModule(join(import.meta.dirname, \"../node-compat\"), \"bundle-files\"),\n external: true,\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fs\" }, (a) => ({\n contents: a.path === \"fs\" ? FS_OVERLAY : FS_PROMISES_OVERLAY,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^node:/ }, (a) => ({ path: a.path, external: true }));\n // workerd's nodejs_compat also takes the bare names (\"path\", \"fs/promises\").\n b.onResolve({ filter: nodeBuiltinName }, (a) => ({\n path: `node:${a.path}`,\n external: true,\n }));\n }\n b.onResolve({ filter: /^cellb:compat$/ }, () => ({\n path: \"compat\",\n namespace: \"cells-compat\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-compat\" }, () => ({\n contents: `export const standardBinaryType = ${!!opts.standardBinaryType};`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:fetch$/ }, () => ({\n path: \"fetch\",\n namespace: \"cells-fetch\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fetch\" }, () => ({\n contents: `export const fetch = globalThis.__cellsOutbound[${JSON.stringify(outboundKey)}];`,\n loader: \"js\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-console\" }, () => ({\n contents: `export const console = globalThis.__cellsConsoles[${JSON.stringify(consoleKey)}];`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: workersModule,\n external: true,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n external: true,\n }));\n b.onResolve({ filter: /^cellb:ws$/ }, () => ({\n path: ownModule(import.meta.dirname, \"workers-globals-module\"),\n external: true,\n }));\n if (!memory) return;\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n const path = new URL(a.path, `file:///${a.importer}`).pathname.slice(1);\n // Not one of the loaded modules: it fails when it runs, as on workerd (missingModule).\n return path in memory\n ? { path, namespace: \"memory\" }\n : missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: memory[a.path],\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:modules$/ }, () => ({\n path: \"modules\",\n namespace: \"cells-modules\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-modules\" }, () => ({\n contents:\n (entry as { registry?: string }).registry ??\n \"export const importFrom = (s) => import(s);\",\n loader: \"js\",\n }));\n // Anything else loaded code imports: a module's whole name (a URL, say), as workerd names\n // modules, or else a module that throws when it is evaluated (missingModule).\n b.onResolve({ filter: /.*/ }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n if (a.path in memory) return { path: a.path, namespace: \"memory\" };\n return missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"cells-missing\" }, (a) => ({\n contents: a.pluginData as string,\n loader: \"js\",\n }));\n },\n },\n moduleRulesPlugin(opts.rules),\n ],\n });\n return (await import(/* @vite-ignore */ out)) as WorkerModule;\n}\n\n/** Worker Loader on Node: compiles `WorkerCode.modules` with esbuild (as celld compiles loaded code). */\nexport const nodeModuleLoader: ModuleLoader = async (_id, loaded, logs) => {\n const code = await compileWasmModules(loaded);\n const outbound = outboundFetch(code);\n const { modules, registry } = loadedModuleTexts(code);\n // `env` and `exports` of the loaded code's `cloudflare:workers` are its own (WorkerCode.env).\n const env = code.env ?? {};\n const scope = workerScope(env);\n const module = (await bundleWorker({ modules, main: code.mainModule, registry }, logs, outbound, {\n scope,\n })) as Record<string, unknown>;\n scope.bind({ env, exports: ctxExports(module, env) });\n return module;\n};\n\nexport async function loadNodeProject(\n dir: string,\n host: Omit<ProjectHost, \"loadModules\"> & Partial<Pick<ProjectHost, \"loadModules\">>,\n): Promise<ProjectRuntime & { config: WranglerConfig }> {\n const config = readWranglerConfig(dir);\n if (!config.main && !config.assets)\n throw new Error(\"wrangler config has neither `main` nor `assets`\");\n const flags = config.compatibility_flags ?? [];\n const nodeCompat = hasNodeCompat(config);\n const standardBinaryType = flags.includes(\"websocket_standard_binary_type\");\n // The module reads `env` from `cloudflare:workers` while it is evaluated, before the\n // runtime exists: until then the scope holds the configuration's vars (and `ai`).\n const scope = workerScope(loadTimeEnv(config, host.ai));\n // A bundle built elsewhere for cellb (cellbHostModule: webrun-bundler in a browser, say) reads\n // the runtime from globals, as in the browser realm: set them here too, so the same bundle\n // runs on Node. (One such project per process: the globals are the process's.)\n installHostModuleGlobals(scope);\n // As the browser host: nodejs_compat fills process.env with the text vars (from compatibility\n // date 2025-04-01). Node shares its real process with the Worker, so they land there.\n if (populatesProcessEnv(config))\n for (const [k, v] of Object.entries(processEnvOf(config))) process.env[k] ??= v;\n const module = config.main\n ? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {\n nodeCompat,\n standardBinaryType,\n scope,\n rules: config.rules,\n })\n : ({ default: {} } as WorkerModule);\n const assetFiles = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : undefined;\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n // own realm, as celld; facets logged like the root's\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles,\n ...host,\n });\n scope.bind(project.runtime);\n return { ...project, config };\n}\n\n/** Reads an assets directory into \"/path\" → bytes (what `celld deploy` uploads). */\nexport function readAssetDirectory(root: string): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n const walk = (dir: string, prefix: string) => {\n for (const name of readdirSync(dir)) {\n const full = join(dir, name);\n if (statSync(full).isDirectory()) walk(full, `${prefix}${name}/`);\n else files.set(`${prefix}${name}`, new Uint8Array(readFileSync(full)));\n }\n };\n walk(root, \"/\");\n return files;\n}\n\n/**\n * `celld d1 migrations apply DATABASE` for a Node-hosted project: reads\n * `migrations_dir` (default \"migrations\") of the `d1_databases` entry and applies what is new.\n */\nexport async function applyNodeD1Migrations(\n dir: string,\n runtime: { env: Record<string, unknown> },\n database: string,\n) {\n const config = readWranglerConfig(dir);\n const d1 = config.d1_databases?.find(\n (d) => d.database_name === database || d.binding === database,\n );\n if (!d1) throw new Error(`no d1_databases entry named ${database}`);\n const mdir = resolve(dir, (d1 as { migrations_dir?: string }).migrations_dir ?? \"migrations\");\n const files: [string, string][] = existsSync(mdir)\n ? readdirSync(mdir).map((f) => [f, readFileSync(join(mdir, f), \"utf8\")])\n : [];\n return applyD1Migrations(\n runtime.env[d1.binding] as never,\n files,\n (d1 as { migrations_table?: string }).migrations_table ?? \"d1_migrations\",\n );\n}\n\n/**\n * Loaded Workers in worker threads (one realm each), like celld's isolates. The code is\n * bundled with esbuild (cloudflare:workers bundled in) and imported in the thread from a\n * data: URL; Durable Object classes for facets still load in this realm.\n */\nlet isolateEntry: Promise<string> | undefined;\nexport function nodeIsolatedLoader(storage?: () => CellStorage | undefined): ModuleLoader {\n return isolatedModuleLoader({\n storage,\n spawn: () => {\n const port = new NodeWorker(new URL(`file://${isolateEntryPathSync()}`));\n port.unref(); // an idle isolate never keeps the process alive\n return { port: port as unknown as PortLike, terminate: () => void port.terminate() };\n },\n prepare: async (_id, loaded) => {\n isolateEntry ??= buildIsolateEntry();\n const [code] = await Promise.all([compileWasmModules(loaded), isolateEntry]);\n const { modules, registry } = loadedModuleTexts(code);\n const out = await build({\n entryPoints: [`memory:${code.mainModule}`],\n write: false,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n logLevel: \"silent\",\n plugins: [\n {\n name: \"isolate-modules\",\n setup(b) {\n // The loaded Worker is its thread's own: `env` and `exports` are the scope\n // serveIsolate keeps for it.\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: \"cloudflare:workers\",\n namespace: \"isolate-workers\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"isolate-workers\" }, () => ({\n contents: [\n // cloudflare-workers.js in the published package (dist/), .ts in the sources.\n `export * from ${JSON.stringify(ownModule(import.meta.dirname, \"cloudflare-workers\"))};`,\n \"export const env = globalThis.__cellsProjectScope.env, exports = globalThis.__cellsProjectScope.exports, waitUntil = (p) => globalThis.__cellsProjectScope.waitUntil(p);\",\n ].join(\"\\n\"),\n loader: \"js\",\n resolveDir: import.meta.dirname,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n }));\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n const path = new URL(a.path, `file:///${a.importer}`).pathname.slice(1);\n // Not one of the loaded modules: it fails when it runs, as on workerd (missingModule).\n return path in modules\n ? { path, namespace: \"memory\" }\n : missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: modules[a.path],\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:modules$/ }, () => ({\n path: \"modules\",\n namespace: \"cells-modules\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-modules\" }, () => ({\n contents: registry,\n loader: \"js\",\n }));\n // Anything else loaded code imports: a module's whole name (a URL, say), as workerd names\n // modules, or else a module that throws when it is evaluated (missingModule).\n b.onResolve({ filter: /.*/ }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n if (a.path in modules) return { path: a.path, namespace: \"memory\" };\n return missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"cells-missing\" }, (a) => ({\n contents: a.pluginData as string,\n loader: \"js\",\n }));\n },\n },\n ],\n });\n // Compiled wasm modules travel beside the source (a worker thread takes them as they are).\n return { source: out.outputFiles[0].text, wasm: wasmModulesOf(code) };\n },\n });\n}\n\nlet isolateEntryFile = \"\";\nfunction isolateEntryPathSync(): string {\n if (!isolateEntryFile) throw new Error(\"isolate entry not built yet\");\n return isolateEntryFile;\n}\nasync function buildIsolateEntry(): Promise<string> {\n isolateEntryFile = join(mkdtempSync(join(tmpdir(), \"cells-isolate-\")), \"isolate.mjs\");\n await build({\n entryPoints: [ownModule(import.meta.dirname, \"../isolate/node-entry\")],\n outfile: isolateEntryFile,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node22\",\n logLevel: \"silent\",\n });\n return isolateEntryFile;\n}\n\n/** The globals `@statewalker/cellb/host-modules` bundles read (see host-modules.ts). */\nfunction installHostModuleGlobals(scope: WorkerScope): void {\n const g = globalThis as Record<string, unknown>;\n g.__cellsProjectScope = scope;\n g.__cellsWorkersModule ??= workersClasses;\n // node:* from Node itself (the browser realm gives cellb's polyfills).\n g.__cellsNodeModules ??= new Proxy(\n {},\n { get: (_t, k) => (typeof k === \"string\" ? requireBuiltin(k) : undefined) },\n );\n}\nconst requireBuiltin = createRequire(import.meta.url);\n"]}
|
|
1
|
+
{"version":3,"file":"node-project.js","sourceRoot":"","sources":["../../src/project/node-project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { Worker as NodeWorker } from \"node:worker_threads\";\nimport { build } from \"esbuild\";\nimport { applyD1Migrations } from \"../bindings/d1-migrations.js\";\nimport {\n analyzeModule,\n exportNamesByModule,\n IMPORT_FROM,\n type ModuleExports,\n prefixModule,\n RESOLVE_MODULE_NAME_SOURCE,\n} from \"../bindings/module-registry.js\";\nimport {\n compileWasmModules,\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n type WorkerCode,\n wasmModulesOf,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport { isolatedModuleLoader } from \"../isolate/host.js\";\nimport type { PortLike } from \"../isolate/protocol.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport { type ModuleRule, moduleRulesPlugin } from \"./module-rules.js\";\nimport { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n hasNodeCompat,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n type ProjectRuntime,\n populatesProcessEnv,\n processEnvOf,\n WRANGLER_FILES,\n type WranglerConfig,\n} from \"./wrangler.js\";\n\n/** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */\nexport function readWranglerConfig(dir: string): WranglerConfig {\n for (const name of WRANGLER_FILES) {\n const p = join(dir, name);\n if (existsSync(p)) return parseJsonc(readFileSync(p, \"utf8\")) as WranglerConfig;\n }\n throw new Error(`no wrangler.jsonc or wrangler.json in ${dir}`);\n}\n\n/** A bare Node.js built-in specifier (\"path\", \"fs/promises\"), not one of a package. */\nconst nodeBuiltinName = new RegExp(\n `^(${builtinModules\n .filter((m) => !m.startsWith(\"_\") && !m.includes(\":\"))\n .map((m) => m.replace(/[/]/g, \"\\\\/\"))\n .join(\"|\")})$`,\n);\n\n/** Worker code's `node:fs` under nodejs_compat on Node: Node's own, with workerd's `/bundle`. */\nconst FS_OVERLAY = `import * as real from \"node:fs\";\nimport { bundleFs } from \"cellb:bundle-fs\";\nexport * from \"node:fs\";\nconst o = bundleFs(real);\nexport const { existsSync, readFileSync, statSync, lstatSync, readdirSync, accessSync, readFile, stat, lstat, readdir, access, promises } = o;\nexport default { ...real, ...o };`;\n/** Worker code's `node:fs/promises`, the same way. */\nconst FS_PROMISES_OVERLAY = `import * as real from \"node:fs/promises\";\nimport { bundleFsPromises } from \"cellb:bundle-fs\";\nexport * from \"node:fs/promises\";\nconst o = bundleFsPromises(real);\nexport const { readFile, stat, lstat, readdir, access } = o;\nexport default o;`;\n\n/**\n * The modules of loaded code as ES module text, each `import()` the bundler cannot link going to\n * the `cellb:modules` registry instead (module-registry.ts).\n */\nfunction loadedModuleTexts(code: WorkerCode): {\n modules: Record<string, string>;\n registry: string;\n} {\n const texts: Record<string, string> = {};\n const names = new Set(Object.keys(code.modules));\n for (const [name, m] of Object.entries(code.modules)) texts[name] = moduleText(m, name, names);\n const modules: Record<string, string> = {};\n const exports = new Map<string, ModuleExports>();\n for (const [name, text] of Object.entries(texts)) {\n // One parse per module: the import() calls to route, and the exports the registry lists.\n const analysis = analyzeModule(text, name);\n exports.set(name, analysis?.exports ?? { names: [], stars: [] });\n const routed = analysis?.routed;\n let prelude =\n routed === undefined ? \"\" : `import { importFrom as ${IMPORT_FROM} } from \"cellb:modules\"; `;\n // The main module evaluates the registry, so it is there before any code runs.\n if (name === code.mainModule && !prelude) prelude = 'import \"cellb:modules\"; ';\n modules[name] = prelude ? prefixModule(routed ?? text, prelude) : text;\n }\n return { modules, registry: registrySource(Object.keys(texts), exports, code.mainModule) };\n}\n\n/**\n * What an import of loaded code that names none of its modules becomes: a module that throws when\n * it is evaluated, so the failure comes where workerd's would (when the importing module runs), not\n * at build time or when an unrelated module loads. CommonJS, so any named import of it builds.\n */\nfunction missingModule(spec: string, importer: string) {\n const message = `No such module \"${spec}\" (imported from \"${importer}\")`;\n return {\n path: `${importer}\\u0000${spec}`,\n namespace: \"cells-missing\",\n pluginData: `throw new Error(${JSON.stringify(message)});\\nmodule.exports = {};`,\n };\n}\n\n/**\n * The `cellb:modules` registry of a bundle of loaded code: each module, imported on demand. It\n * also publishes itself as `globalThis.__cellbLoadedModules`, where an isolate thread's module\n * hooks find it (node-entry.ts: `import()` from code built with `Function`).\n */\nfunction registrySource(\n names: string[],\n exports: Map<string, ModuleExports>,\n main: string,\n): string {\n const q = JSON.stringify;\n return [\n `const names = new Set(${q(names)});`,\n `const resolve = ${RESOLVE_MODULE_NAME_SOURCE};`,\n `const table = { ${names.map((n) => `${q(n)}: () => import(${q(`memory:${n}`)})`).join(\", \")} };`,\n \"export const importFrom = (spec, importer) => {\",\n \" const name = resolve(String(spec), importer, names);\",\n \" return name === undefined ? import(spec) : table[name]();\",\n \"};\",\n `globalThis.__cellbLoadedModules = { main: ${q(main)}, names, exportNames: ${q(exportNamesByModule(exports))}, load: (name) => table[name]() };`,\n ].join(\"\\n\");\n}\n\n/**\n * Node host: bundles `main` with esbuild (as `celld deploy` does) and builds the runtime.\n * `cloudflare:workers` resolves to cellb's module so user classes extend the\n * runtime's own DurableObject / WorkerEntrypoint.\n */\n/** Bundles Worker code (a file, or in-memory modules) with the runtime's module mappings, then imports it. */\nexport async function bundleWorker(\n entry:\n | { path: string }\n | {\n modules: Record<string, string>;\n main: string;\n /** The `cellb:modules` registry the modules import (loadedModuleTexts). */\n registry?: string;\n },\n logs?: LogSink,\n outbound?: typeof fetch,\n opts: {\n nodeCompat?: boolean;\n standardBinaryType?: boolean;\n scope?: WorkerScope;\n /** wrangler `rules` for non-JS imports (the defaults: `.wasm`, `.bin`, `.txt`…, as wrangler). */\n rules?: ModuleRule[];\n } = {},\n): Promise<WorkerModule> {\n // `env` and `exports` of `cloudflare:workers` belong to one Worker: the bundle reads them\n // from its own scope (empty objects for code that has none).\n const scopeKey = opts.scope ? `s${Math.random().toString(36).slice(2)}` : \"\";\n if (opts.scope) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[scopeKey] = opts.scope;\n }\n // Loaded code gets a bundle-local `fetch` (globalOutbound policy)…\n const outboundKey = outbound ? `o${Math.random().toString(36).slice(2)}` : \"\";\n if (outbound) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[outboundKey] = outbound;\n }\n // …and a bundle-local `console` that also feeds its Tail Workers.\n const consoleKey = logs ? `c${Math.random().toString(36).slice(2)}` : \"\";\n if (logs) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const registry = g.__cellsConsoles as Record<string, unknown>;\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n registry[consoleKey] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n }\n const outDir = mkdtempSync(join(tmpdir(), \"cells-worker-\"));\n const out = join(outDir, \"worker.mjs\");\n const cfWorkers = ownModule(import.meta.dirname, \"cloudflare-workers\");\n // This bundle's `cloudflare:workers`: the runtime's classes plus its own `env` and `exports`.\n // A file of its own, kept out of the bundle so it adds no names to the Worker's scope.\n const workersModule = join(outDir, \"cloudflare-workers.mjs\");\n writeFileSync(\n workersModule,\n [\n `export * from ${JSON.stringify(cfWorkers)};`,\n `const scope = globalThis.__cellsWorkerScopes?.[${JSON.stringify(scopeKey)}];`,\n \"export const env = scope ? scope.env : {};\",\n \"export const exports = scope ? scope.exports : {};\",\n \"export const waitUntil = (p) => scope?.waitUntil(p);\",\n ].join(\"\\n\"),\n );\n const memory = \"modules\" in entry ? entry.modules : undefined;\n await build({\n entryPoints: [\n memory ? `memory:${(entry as { main: string }).main}` : (entry as { path: string }).path,\n ],\n outfile: out,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n // As `celld deploy` resolves packages: workerd's conditions, then `module` and `main` (the\n // neutral platform has no main fields, so a package with only `main` would not resolve).\n conditions: [\"workerd\", \"worker\", \"browser\"],\n mainFields: [\"module\", \"main\"],\n target: \"es2022\",\n logLevel: \"silent\",\n // nodejs_compat: CommonJS dependencies `require()` Node's built-ins (mime-types requires\n // node:path), as they may under workerd's nodejs_compat. In an ES module bundle esbuild's\n // require shim needs a `require` in scope: vitest's module runner provides one, plain Node\n // does not.\n ...(opts.nodeCompat\n ? {\n banner: {\n js: 'import { createRequire as __cellbCreateRequire } from \"node:module\";\\nconst require = __cellbCreateRequire(import.meta.url);',\n },\n }\n : {}),\n inject: [\n ownModule(import.meta.dirname, \"workers-globals\"),\n ...(logs ? [\"cellb:console\"] : []),\n ...(outbound ? [\"cellb:fetch\"] : []),\n ],\n plugins: [\n {\n name: \"cells-modules\",\n setup(b) {\n b.onResolve({ filter: /^cellb:console$/ }, () => ({\n path: \"console\",\n namespace: \"cells-console\",\n }));\n // nodejs_compat on a Node host: `node:*` are the real Node.js modules, except that\n // `node:fs` also reads workerd's `/bundle` (node-compat/bundle-files.ts).\n if (opts.nodeCompat) {\n b.onResolve({ filter: /^(node:)?fs(\\/promises)?$/ }, (a) => {\n const name = a.path.replace(/^node:/, \"\");\n return a.namespace === \"cells-fs\"\n ? { path: `node:${name}`, external: true }\n : { path: name, namespace: \"cells-fs\" };\n });\n b.onResolve({ filter: /^cellb:bundle-fs$/ }, () => ({\n path: ownModule(join(import.meta.dirname, \"../node-compat\"), \"bundle-files\"),\n external: true,\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fs\" }, (a) => ({\n contents: a.path === \"fs\" ? FS_OVERLAY : FS_PROMISES_OVERLAY,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^node:/ }, (a) => ({ path: a.path, external: true }));\n // workerd's nodejs_compat also takes the bare names (\"path\", \"fs/promises\").\n b.onResolve({ filter: nodeBuiltinName }, (a) => ({\n path: `node:${a.path}`,\n external: true,\n }));\n }\n b.onResolve({ filter: /^cellb:compat$/ }, () => ({\n path: \"compat\",\n namespace: \"cells-compat\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-compat\" }, () => ({\n contents: `export const standardBinaryType = ${!!opts.standardBinaryType};`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:fetch$/ }, () => ({\n path: \"fetch\",\n namespace: \"cells-fetch\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fetch\" }, () => ({\n contents: `export const fetch = globalThis.__cellsOutbound[${JSON.stringify(outboundKey)}];`,\n loader: \"js\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-console\" }, () => ({\n contents: `export const console = globalThis.__cellsConsoles[${JSON.stringify(consoleKey)}];`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: workersModule,\n external: true,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n external: true,\n }));\n b.onResolve({ filter: /^cellb:ws$/ }, () => ({\n path: ownModule(import.meta.dirname, \"workers-globals-module\"),\n external: true,\n }));\n if (!memory) return;\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n const path = new URL(a.path, `file:///${a.importer}`).pathname.slice(1);\n // Not one of the loaded modules: it fails when it runs, as on workerd (missingModule).\n return path in memory\n ? { path, namespace: \"memory\" }\n : missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: memory[a.path],\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:modules$/ }, () => ({\n path: \"modules\",\n namespace: \"cells-modules\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-modules\" }, () => ({\n contents:\n (entry as { registry?: string }).registry ??\n \"export const importFrom = (s) => import(s);\",\n loader: \"js\",\n }));\n // Anything else loaded code imports: a module's whole name (a URL, say), as workerd names\n // modules, or else a module that throws when it is evaluated (missingModule).\n b.onResolve({ filter: /.*/ }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n if (a.path in memory) return { path: a.path, namespace: \"memory\" };\n return missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"cells-missing\" }, (a) => ({\n contents: a.pluginData as string,\n loader: \"js\",\n }));\n },\n },\n moduleRulesPlugin(opts.rules),\n ],\n });\n return (await import(/* @vite-ignore */ out)) as WorkerModule;\n}\n\n/** Worker Loader on Node: compiles `WorkerCode.modules` with esbuild (as celld compiles loaded code). */\nexport const nodeModuleLoader: ModuleLoader = async (_id, loaded, logs) => {\n const code = await compileWasmModules(loaded);\n const outbound = outboundFetch(code);\n const { modules, registry } = loadedModuleTexts(code);\n // `env` and `exports` of the loaded code's `cloudflare:workers` are its own (WorkerCode.env).\n const env = code.env ?? {};\n const scope = workerScope(env);\n const module = (await bundleWorker({ modules, main: code.mainModule, registry }, logs, outbound, {\n scope,\n })) as Record<string, unknown>;\n scope.bind({ env, exports: ctxExports(module, env) });\n return module;\n};\n\nexport async function loadNodeProject(\n dir: string,\n host: Omit<ProjectHost, \"loadModules\"> & Partial<Pick<ProjectHost, \"loadModules\">>,\n): Promise<ProjectRuntime & { config: WranglerConfig }> {\n const config = readWranglerConfig(dir);\n if (!config.main && !config.assets)\n throw new Error(\"wrangler config has neither `main` nor `assets`\");\n const flags = config.compatibility_flags ?? [];\n const nodeCompat = hasNodeCompat(config);\n const standardBinaryType = flags.includes(\"websocket_standard_binary_type\");\n // The module reads `env` from `cloudflare:workers` while it is evaluated, before the\n // runtime exists: until then the scope holds the configuration's vars (and `ai`).\n const scope = workerScope(loadTimeEnv(config, host.ai));\n // A bundle built elsewhere for cellb (cellbHostModule: webrun-bundler in a browser, say) reads\n // the runtime from globals, as in the browser realm: set them here too, so the same bundle\n // runs on Node. (One such project per process: the globals are the process's.)\n installHostModuleGlobals(scope);\n // As the browser host: nodejs_compat fills process.env with the text vars (from compatibility\n // date 2025-04-01). Node shares its real process with the Worker, so they land there.\n if (populatesProcessEnv(config))\n for (const [k, v] of Object.entries(processEnvOf(config))) process.env[k] ??= v;\n const module = config.main\n ? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {\n nodeCompat,\n standardBinaryType,\n scope,\n rules: config.rules,\n })\n : ({ default: {} } as WorkerModule);\n const assetFiles = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : undefined;\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n // own realm, as celld; facets logged like the root's\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles,\n ...host,\n });\n scope.bind(project.runtime);\n return { ...project, config };\n}\n\n/** Reads an assets directory into \"/path\" → bytes (what `celld deploy` uploads). */\nexport function readAssetDirectory(root: string): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n const walk = (dir: string, prefix: string) => {\n for (const name of readdirSync(dir)) {\n const full = join(dir, name);\n if (statSync(full).isDirectory()) walk(full, `${prefix}${name}/`);\n else files.set(`${prefix}${name}`, new Uint8Array(readFileSync(full)));\n }\n };\n walk(root, \"/\");\n return files;\n}\n\n/**\n * `celld d1 migrations apply DATABASE` for a Node-hosted project: reads\n * `migrations_dir` (default \"migrations\") of the `d1_databases` entry and applies what is new.\n */\nexport async function applyNodeD1Migrations(\n dir: string,\n runtime: { env: Record<string, unknown> },\n database: string,\n) {\n const config = readWranglerConfig(dir);\n const d1 = config.d1_databases?.find(\n (d) => d.database_name === database || d.binding === database,\n );\n if (!d1) throw new Error(`no d1_databases entry named ${database}`);\n const mdir = resolve(dir, (d1 as { migrations_dir?: string }).migrations_dir ?? \"migrations\");\n const files: [string, string][] = existsSync(mdir)\n ? readdirSync(mdir).map((f) => [f, readFileSync(join(mdir, f), \"utf8\")])\n : [];\n return applyD1Migrations(\n runtime.env[d1.binding] as never,\n files,\n (d1 as { migrations_table?: string }).migrations_table ?? \"d1_migrations\",\n );\n}\n\n/**\n * Loaded Workers in worker threads (one realm each), like celld's isolates. The code is\n * bundled with esbuild (cloudflare:workers bundled in) and imported in the thread from a\n * data: URL; Durable Object classes for facets still load in this realm.\n */\nlet isolateEntry: Promise<string> | undefined;\nexport function nodeIsolatedLoader(storage?: () => CellStorage | undefined): ModuleLoader {\n return isolatedModuleLoader({\n storage,\n spawn: () => {\n const port = new NodeWorker(new URL(`file://${isolateEntryPathSync()}`));\n port.unref(); // an idle isolate never keeps the process alive\n return { port: port as unknown as PortLike, terminate: () => void port.terminate() };\n },\n prepare: async (_id, loaded) => {\n isolateEntry ??= buildIsolateEntry();\n const [code] = await Promise.all([compileWasmModules(loaded), isolateEntry]);\n const { modules, registry } = loadedModuleTexts(code);\n const out = await build({\n entryPoints: [`memory:${code.mainModule}`],\n write: false,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n logLevel: \"silent\",\n plugins: [\n {\n name: \"isolate-modules\",\n setup(b) {\n // The loaded Worker is its thread's own: `env` and `exports` are the scope\n // serveIsolate keeps for it.\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: \"cloudflare:workers\",\n namespace: \"isolate-workers\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"isolate-workers\" }, () => ({\n contents: [\n // cloudflare-workers.js in the published package (dist/), .ts in the sources.\n `export * from ${JSON.stringify(ownModule(import.meta.dirname, \"cloudflare-workers\"))};`,\n \"export const env = globalThis.__cellsProjectScope.env, exports = globalThis.__cellsProjectScope.exports, waitUntil = (p) => globalThis.__cellsProjectScope.waitUntil(p);\",\n ].join(\"\\n\"),\n loader: \"js\",\n resolveDir: import.meta.dirname,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n }));\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n const path = new URL(a.path, `file:///${a.importer}`).pathname.slice(1);\n // Not one of the loaded modules: it fails when it runs, as on workerd (missingModule).\n return path in modules\n ? { path, namespace: \"memory\" }\n : missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: modules[a.path],\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:modules$/ }, () => ({\n path: \"modules\",\n namespace: \"cells-modules\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-modules\" }, () => ({\n contents: registry,\n loader: \"js\",\n }));\n // Anything else loaded code imports: a module's whole name (a URL, say), as workerd names\n // modules, or else a module that throws when it is evaluated (missingModule).\n b.onResolve({ filter: /.*/ }, (a) => {\n if (a.namespace !== \"memory\") return undefined;\n if (a.path in modules) return { path: a.path, namespace: \"memory\" };\n return missingModule(a.path, a.importer);\n });\n b.onLoad({ filter: /.*/, namespace: \"cells-missing\" }, (a) => ({\n contents: a.pluginData as string,\n loader: \"js\",\n }));\n },\n },\n ],\n });\n // Compiled wasm modules travel beside the source (a worker thread takes them as they are).\n return { source: out.outputFiles[0].text, wasm: wasmModulesOf(code) };\n },\n });\n}\n\nlet isolateEntryFile = \"\";\nfunction isolateEntryPathSync(): string {\n if (!isolateEntryFile) throw new Error(\"isolate entry not built yet\");\n return isolateEntryFile;\n}\nasync function buildIsolateEntry(): Promise<string> {\n isolateEntryFile = join(mkdtempSync(join(tmpdir(), \"cells-isolate-\")), \"isolate.mjs\");\n await build({\n entryPoints: [ownModule(import.meta.dirname, \"../isolate/node-entry\")],\n outfile: isolateEntryFile,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node22\",\n logLevel: \"silent\",\n });\n return isolateEntryFile;\n}\n\n/** The globals `@statewalker/cellb/host-modules` bundles read (see host-modules.ts). */\nfunction installHostModuleGlobals(scope: WorkerScope): void {\n const g = globalThis as Record<string, unknown>;\n g.__cellsProjectScope = scope;\n g.__cellsWorkersModule ??= workersClasses;\n // node:* from Node itself (the browser realm gives cellb's polyfills).\n g.__cellsNodeModules ??= new Proxy(\n {},\n { get: (_t, k) => (typeof k === \"string\" ? requireBuiltin(k) : undefined) },\n );\n}\nconst requireBuiltin = createRequire(import.meta.url);\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statewalker/cellb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "cellb: isomorphic Durable Objects runtime (celld/Cloudflare-compatible surface) for browsers and servers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"bench:browser": "PW_CHROMIUM=\"${PW_CHROMIUM:-$(node scripts/npm-chromium.mjs)}\" playwright test --config playwright.probes.config.ts --reporter=line bench",
|
|
134
134
|
"test:unit": "vitest run test/",
|
|
135
135
|
"test:e2e": "vitest run e2e/",
|
|
136
|
-
"typecheck": "tsc --noEmit && tsc --noEmit -p e2e-browser/pages/tsconfig.json",
|
|
136
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p e2e-browser/pages/tsconfig.json && tsc --noEmit -p e2e-browser/tsconfig.json",
|
|
137
137
|
"mutate": "node scripts/mutate.mjs",
|
|
138
138
|
"browser:prepare": "mkdir -p e2e-browser/pages/public/vendor && cp node_modules/@statewalker/webrun-http-browser/dist/sw-worker.js e2e-browser/pages/public/vendor/webrun-http-sw-worker.js",
|
|
139
139
|
"browser:dev": "pnpm run browser:prepare && vite e2e-browser/pages --config e2e-browser/pages/vite.config.ts",
|