@statewalker/cellb 0.8.7 → 0.8.9
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 +1 -1
- package/dist/adapters/node-sqlite.js +42 -13
- package/dist/adapters/node-sqlite.js.map +1 -1
- package/dist/bindings/cjs-module.d.ts +7 -0
- package/dist/bindings/cjs-module.js +96 -0
- package/dist/bindings/cjs-module.js.map +1 -0
- package/dist/bindings/module-registry.d.ts +33 -0
- package/dist/bindings/module-registry.js +180 -0
- package/dist/bindings/module-registry.js.map +1 -0
- package/dist/bindings/worker-loader.d.ts +23 -5
- package/dist/bindings/worker-loader.js +75 -4
- package/dist/bindings/worker-loader.js.map +1 -1
- package/dist/core/handles.d.ts +21 -1
- package/dist/core/handles.js +49 -3
- package/dist/core/handles.js.map +1 -1
- package/dist/core/namespace.js +4 -1
- package/dist/core/namespace.js.map +1 -1
- package/dist/core/runtime.d.ts +8 -0
- package/dist/core/runtime.js +3 -3
- package/dist/core/runtime.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/isolate/browser.d.ts +1 -1
- package/dist/isolate/browser.js +3 -1
- package/dist/isolate/browser.js.map +1 -1
- package/dist/isolate/host.js +20 -2
- package/dist/isolate/host.js.map +1 -1
- package/dist/isolate/isolate-worker.js +13 -1
- package/dist/isolate/isolate-worker.js.map +1 -1
- package/dist/isolate/isolate.js +11 -0
- package/dist/isolate/isolate.js.map +1 -1
- package/dist/isolate/node-entry.js +33 -0
- package/dist/isolate/node-entry.js.map +1 -1
- package/dist/isolate/protocol.d.ts +1 -0
- package/dist/isolate/protocol.js +228 -13
- package/dist/isolate/protocol.js.map +1 -1
- package/dist/isolate/writable-globals.d.ts +9 -0
- package/dist/isolate/writable-globals.js +45 -0
- package/dist/isolate/writable-globals.js.map +1 -0
- package/dist/node-compat/bundle-files.d.ts +26 -0
- package/dist/node-compat/bundle-files.js +210 -0
- package/dist/node-compat/bundle-files.js.map +1 -0
- package/dist/node-compat/fs.d.ts +13 -1
- package/dist/node-compat/fs.js +54 -15
- package/dist/node-compat/fs.js.map +1 -1
- package/dist/project/browser-modules.d.ts +1 -1
- package/dist/project/browser-modules.js +25 -5
- package/dist/project/browser-modules.js.map +1 -1
- package/dist/project/cloudflare-workers.d.ts +9 -0
- package/dist/project/cloudflare-workers.js +14 -0
- package/dist/project/cloudflare-workers.js.map +1 -1
- package/dist/project/module-rules.js +31 -10
- package/dist/project/module-rules.js.map +1 -1
- package/dist/project/node-project.d.ts +2 -0
- package/dist/project/node-project.js +154 -25
- package/dist/project/node-project.js.map +1 -1
- package/dist/project/site-loader.js +2 -1
- package/dist/project/site-loader.js.map +1 -1
- package/dist/project/uint8array-base64.d.ts +7 -0
- package/dist/project/uint8array-base64.js +96 -0
- package/dist/project/uint8array-base64.js.map +1 -0
- package/dist/project/workers-globals-module.d.ts +1 -0
- package/dist/project/workers-globals-module.js +3 -0
- package/dist/project/workers-globals-module.js.map +1 -1
- package/dist/project/wrangler.js +8 -9
- package/dist/project/wrangler.js.map +1 -1
- package/dist/ws/upgrade.js +18 -1
- package/dist/ws/upgrade.js.map +1 -1
- package/package.json +10 -10
package/dist/core/runtime.d.ts
CHANGED
|
@@ -5,8 +5,16 @@ import { DurableObjectId } from "./id.js";
|
|
|
5
5
|
import { type ObjectEndpoint } from "./namespace.js";
|
|
6
6
|
import { type RejectionHandler } from "./worker-rejections.js";
|
|
7
7
|
export interface WorkerModule {
|
|
8
|
+
/**
|
|
9
|
+
* An object with handlers (`fetch(req, env, ctx)`), or a class (`export default class extends
|
|
10
|
+
* WorkerEntrypoint`): an instance per request, built with `(ctx, env)`, whose `fetch(req)`
|
|
11
|
+
* answers. A class matches through its `prototype`, so `default.fetch` stays readable.
|
|
12
|
+
*/
|
|
8
13
|
default: {
|
|
9
14
|
fetch?(req: Request, env: any, ctx: ExecutionContext): Response | Promise<Response>;
|
|
15
|
+
prototype?: {
|
|
16
|
+
fetch?(req: Request): Response | Promise<Response>;
|
|
17
|
+
};
|
|
10
18
|
};
|
|
11
19
|
[exportName: string]: unknown;
|
|
12
20
|
}
|
package/dist/core/runtime.js
CHANGED
|
@@ -5,7 +5,7 @@ import { takeClientPort } from "../ws/server.js";
|
|
|
5
5
|
import { withUpgrade } from "../ws/upgrade.js";
|
|
6
6
|
import { AlarmScheduler } from "./alarms.js";
|
|
7
7
|
import { asyncRoot } from "./async-context.js";
|
|
8
|
-
import { ctxExports, storedExports } from "./handles.js";
|
|
8
|
+
import { ctxExports, defaultHandler, storedExports } from "./handles.js";
|
|
9
9
|
import { DurableObjectId, namespaceKey } from "./id.js";
|
|
10
10
|
import { DurableObjectNamespace, localEndpoint } from "./namespace.js";
|
|
11
11
|
import { CellOwnedElsewhereError, closingWith, ObjectClosedError, ObjectHost, } from "./object-host.js";
|
|
@@ -354,7 +354,7 @@ export function createCellRuntime(opts) {
|
|
|
354
354
|
await storage.close?.();
|
|
355
355
|
},
|
|
356
356
|
async fetch(req) {
|
|
357
|
-
const handler = opts.worker.default
|
|
357
|
+
const handler = defaultHandler(opts.worker.default, "fetch");
|
|
358
358
|
if (!handler)
|
|
359
359
|
return new Response("Worker has no fetch handler", { status: 500 });
|
|
360
360
|
// A closed runtime serves nothing: its cells are closed, or another runtime's now.
|
|
@@ -371,7 +371,7 @@ export function createCellRuntime(opts) {
|
|
|
371
371
|
if (req.cf === undefined)
|
|
372
372
|
Object.defineProperty(req, "cf", { value: {}, enumerable: true });
|
|
373
373
|
try {
|
|
374
|
-
const r = await rejections(() => handler
|
|
374
|
+
const r = await rejections(() => handler(req, env, ctx));
|
|
375
375
|
// A non-Response is sent as text (celld), not a failure.
|
|
376
376
|
return r instanceof Response ? r : new Response(String(r));
|
|
377
377
|
}
|
package/dist/core/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/core/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type CellDurability,\n type CellStorage,\n type Clock,\n type OpenCellSql,\n systemClock,\n type ValueCodec,\n} from \"../ports.js\";\nimport { httpEndpoint, postVia, type Send } from \"../transport/cells-link.js\";\nimport { v8Codec, v8CodecWith } from \"../v8/codec.js\";\nimport { type CfWebSocket, takeClientPort } from \"../ws/server.js\";\nimport { withUpgrade } from \"../ws/upgrade.js\";\nimport { type AlarmEntry, AlarmScheduler } from \"./alarms.js\";\nimport { type AsyncRoot, asyncRoot } from \"./async-context.js\";\nimport type { ExecutionContext } from \"./durable-object.js\";\nimport { ctxExports, type DurableObjectClass, storedExports } from \"./handles.js\";\nimport { DurableObjectId, namespaceKey } from \"./id.js\";\nimport { DurableObjectNamespace, localEndpoint, type ObjectEndpoint } from \"./namespace.js\";\nimport {\n CellOwnedElsewhereError,\n closingWith,\n ObjectClosedError,\n ObjectHost,\n} from \"./object-host.js\";\nimport { installRequestBody } from \"./request-body.js\";\nimport { type RejectionHandler, rejectionScope, reportToStderr } from \"./worker-rejections.js\";\n\nexport interface WorkerModule {\n default: { fetch?(req: Request, env: any, ctx: ExecutionContext): Response | Promise<Response> };\n [exportName: string]: unknown;\n}\n\nexport interface CellRuntimeOptions {\n /**\n * A promise the Worker's code leaves rejected (Node: the Worker shares the host's process).\n * It is the Worker's, as on workerd and celld: it reaches this handler, not the process's\n * `unhandledRejection` listeners. Default: one line on stderr, outside the Worker's console.\n */\n onUnhandledRejection?: RejectionHandler;\n /** The Worker's module namespace (what wrangler/celld bundle as main module). */\n worker: WorkerModule;\n /** Durable Object bindings: env name → exported class name (wrangler `durable_objects.bindings`). */\n durableObjects?: Record<string, { className: string }>;\n /** Plain vars / other bindings merged into env. */\n vars?: Record<string, unknown>;\n openSql: OpenCellSql;\n /** Durability, backup and ownership of the cells; closed by `close()`, after the runtime. */\n storage?: CellStorage;\n codec?: ValueCodec;\n /**\n * Placement: return a `send` when the cell lives elsewhere (another shard\n * worker, tab or peer); `undefined` means \"host it here\". Default: all local.\n */\n route?: (cellKey: string, id: DurableObjectId) => Send | undefined;\n /** How often to re-read a shared alarm wake index (durability.wakes), in ms. Default 30 s. */\n wakePollMs?: number;\n /** Every object of this runtime is a facet of an outer cell (an isolate's runtime). */\n facets?: boolean;\n /**\n * The `ctx.id` an object sees, when it is not the id that addresses it (a facet given an `id`\n * by `ctx.facets.get`): its storage, cell key and alarms stay the addressing id's.\n */\n ctxIdOf?: (cellKey: string) => DurableObjectId | undefined;\n /** The Worker script's name (wrangler `name`): object ids derive from it, as on celld. */\n scriptName?: string;\n /** Namespace keys overriding the script-scoped default, per class (celld's fleet-wide ones). */\n namespaceKeys?: Record<string, string>;\n /**\n * Routing between nodes (celld's peer routing): when this node cannot own a cell\n * (`CellOwnedElsewhereError`), the call goes to the owner's node over an internal link\n * (`cellsHttpHandler` on the far side). `ownerOf` reads the cell's lease holder.\n */\n peers?: {\n ownerOf(cellKey: string): Promise<string | undefined>;\n link(owner: string): Send;\n /**\n * Talks to an owner directly, for owners that do not speak cellsHttpHandler (a celld node,\n * reached through celld's peer tunnel). Takes precedence over `link` when it returns one.\n */\n endpoint?(\n owner: string,\n cellKey: string,\n name: string | undefined,\n ): Promise<ObjectEndpoint | undefined>;\n };\n /** Hibernate objects idle this long (ms); swept every max(1 s, half of it). Off by default. */\n hibernateAfterMs?: number;\n /**\n * Close the SQLite database of a hibernated object idle this long (ms); the next event reopens\n * it. Swept with `hibernateAfterMs`, so it needs that too. Off by default: the database must\n * come back, so use local SQLite that persists (a directory, an OPFS pool) or storage that\n * restores the cell (a log or a backup).\n */\n closeDatabaseAfterMs?: number;\n /**\n * On `close()`, how long (ms) events still running and `waitUntil` work may take to finish\n * before the databases close under them (they then fail with ObjectClosedError). Default 2000.\n */\n closeGraceMs?: number;\n /** SQLite extensions loaded into every cell database (celld's `sqlite_vec` flag). */\n sqlExtensions?: string[];\n /** `delete_all_preserves_alarm`: storage.deleteAll() keeps the alarm (default: deletes it). */\n deleteAllPreservesAlarm?: boolean;\n /** Timers of the runtime (backups); injectable for tests. */\n clock?: Clock;\n}\n\nexport interface CellRuntime {\n /** Ingress: a (Request) ⇒ Response handler — exactly what webrun-http-browser / node:http mount. */\n fetch(req: Request): Promise<Response>;\n readonly env: Record<string, unknown>;\n /** The Worker's `ctx.exports` (also `exports` of `cloudflare:workers`). */\n readonly exports: Record<string, unknown>;\n /**\n * Runs Worker code the host dispatches itself (a cron trigger's `scheduled()`) as the Worker's\n * event: a promise it leaves rejected goes to `onUnhandledRejection`, not to the process.\n */\n runEvent<R>(fn: () => R): R;\n /** Drops live instances (simulates eviction / hibernation); storage survives if openSql persists it. */\n evictAll(): void;\n /** Settles all waitUntil() promises. */\n drain(): Promise<void>;\n /**\n * Keeps `p` running in the background until `drain()` (what `waitUntil` of\n * `cloudflare:workers` does: on Cloudflare it extends the current event).\n */\n waitUntil(p: Promise<unknown>): void;\n /** Durable Object binding → class name (the namespace key used by idFromName). */\n readonly durableObjectBindings: Readonly<Record<string, string>>;\n /**\n * WebSocket ingress: runs the Worker's fetch with an Upgrade request; on a 101\n * with `webSocket`, returns the client end's MessagePort (to be transferred to\n * the real client, e.g. a page's CellsWebSocket).\n */\n connectWebSocket(\n url: string,\n protocols?: string[],\n headers?: HeadersInit,\n ): Promise<{ port: MessagePort; protocol?: string }>;\n /** Backs up every live cell that changed since its last successful save. */\n backupNow(): Promise<void>;\n /**\n * Hibernates every object idle for at least `idleMs` (default: `hibernateAfterMs`):\n * instances are dropped, storage and hibernatable WebSockets stay. Returns how many slept.\n * Hibernated objects idle for `closeDatabaseAfterMs` also close their database.\n */\n hibernateIdle(idleMs?: number): number;\n /** Replaces one object's instance with a fresh one on the same storage (facet abort). */\n restartObject(cellKey: string): void;\n /** Final backup of changed cells, then stops timers, closes every database and the storage. */\n close(): Promise<void>;\n}\n\nexport function createCellRuntime(opts: CellRuntimeOptions): CellRuntime {\n installRequestBody(); // Firefox: `request.body` for the Worker code (and for the retry below)\n const storage = opts.storage ?? {};\n const { backup, ownership } = storage;\n const durability: CellDurability = storage.durability ?? { committed: () => Promise.resolve() };\n // V8 serialization: storage values in celld's (and workerd's) format.\n const codec = opts.codec ?? v8Codec;\n const hosts = new Map<string, ObjectHost>();\n const background = new Set<Promise<unknown>>();\n // Events start in the context the runtime was made in, not their caller's (Cloudflare).\n // …and in a scope that keeps the Worker's unhandled rejections its own (Node).\n const rejections = rejectionScope(\n opts.onUnhandledRejection ?? reportToStderr(opts.scriptName ?? \"worker\"),\n );\n const root = asyncRoot();\n const eventsRoot: AsyncRoot = (fn) => root(() => rejections(fn));\n const waitUntil = (p: Promise<unknown>) => {\n const t = p.catch(() => {}).finally(() => background.delete(t));\n background.add(t);\n };\n const env: Record<string, unknown> = { ...opts.vars };\n const bindingClasses: Record<string, string> = {};\n const exportsObj = ctxExports(opts.worker, env);\n // Storage values: V8 serialization; ctx.exports stubs are stored too (workerd).\n const storageCodec = opts.codec ?? v8CodecWith(storedExports(exportsObj));\n const clock = opts.clock ?? systemClock;\n // Hosts by class name: the alarm scheduler wakes objects that nobody is calling.\n const hostsByClass = new Map<string, (id: DurableObjectId) => ObjectHost>();\n const alarms = new AlarmScheduler({\n clock,\n openIndex: () => opts.openSql(\"__cellb/alarms\"),\n fire: (e) => fireAlarm(e),\n });\n // One alarm() at a time per object (as on Cloudflare): a re-armed alarm that comes due\n // while the previous handler still runs waits for it.\n const alarmRuns = new Map<string, Promise<void>>();\n const ownedRetries = new Map<string, number>();\n function fireAlarm(e: AlarmEntry): Promise<void> {\n const prev = alarmRuns.get(e.cellKey) ?? Promise.resolve();\n const next = prev.then(() => fireAlarmNow(e));\n alarmRuns.set(e.cellKey, next);\n void next.finally(() => {\n if (alarmRuns.get(e.cellKey) === next) alarmRuns.delete(e.cellKey);\n });\n return next;\n }\n /**\n * celld's alarm lifecycle, in the cell's own storage (so it survives restarts and moves\n * between nodes, celld included): the row stays while its handler runs (getAlarm() reads\n * null meanwhile); success deletes it, failure reschedules it with backoff and counts the\n * failure in the row (`retry`, `counted_retry`) — alarmInfo.retryCount is that count.\n */\n async function fireAlarmNow(e: AlarmEntry): Promise<void> {\n const hostFor = hostsByClass.get(e.className);\n if (!hostFor) return;\n const host = hostFor(new DurableObjectId(e.idHex));\n try {\n await host.deliver(async (obj, state) => {\n // A wake (local timer, or an entry of the shared wake index) is a hint: the stored\n // alarm decides. Gone → nothing to do; moved later → wait for that time.\n const row = state.storage.alarmRowSync();\n if (!row) return;\n if (row.at > clock.now()) {\n alarms.set(e, row.at);\n return;\n }\n state.storage.beginAlarm(row);\n let ok = true;\n try {\n if (typeof obj.alarm === \"function\")\n await obj.alarm({\n retryCount: row.retry,\n isRetry: row.retry > 0,\n scheduledTime: row.at, // alarmInfo.scheduledTime, as in workerd\n });\n } catch {\n ok = false;\n }\n state.storage.finishAlarm(row, ok, clock.now());\n });\n ownedRetries.delete(e.cellKey);\n } catch (err) {\n // Owned by another node (celld or cellb): its owner fires the alarm.\n if (isOwnedElsewhere(err)) {\n hosts.get(e.cellKey)?.close();\n hosts.delete(e.cellKey);\n // A live owner fires it. A stopped one's lease expires within its TTL: look again a\n // few times before leaving it to the next poll of the wake index.\n const n = (ownedRetries.get(e.cellKey) ?? 0) + 1;\n if (n <= 15) {\n ownedRetries.set(e.cellKey, n);\n alarms.set(e, clock.now() + 2_000);\n } else ownedRetries.delete(e.cellKey);\n }\n // Any other failure (broken object, storage error): the row is unchanged; it fires again\n // when the object is next opened or the index is polled.\n }\n }\n\n for (const [binding, { className }] of Object.entries(opts.durableObjects ?? {})) {\n const cls = opts.worker[className] as DurableObjectClass | undefined;\n if (typeof cls !== \"function\")\n throw new Error(`Durable Object class \"${className}\" is not exported by the worker`);\n const hostFor = (id: DurableObjectId): ObjectHost => {\n const cellKey = `${className}/${id.toString()}`;\n // Once close() has closed the cells, none opens again: its storage is closed or handed to\n // the next runtime. Until then (the grace period), work in flight still reaches objects.\n if (cellsClosed) throw new ObjectClosedError(cellKey);\n let h = hosts.get(cellKey);\n if (!h || h.broken) {\n h?.close();\n h = new ObjectHost({\n cellKey,\n id: opts.ctxIdOf?.(cellKey) ?? id,\n cls,\n env,\n openSql: opts.openSql,\n durability,\n codec: storageCodec,\n waitUntil,\n backup,\n onAlarmChange: (at) => alarms.set({ cellKey, className, idHex: id.toString() }, at),\n exports: exportsObj,\n facet: opts.facets,\n asyncRoot: eventsRoot,\n acquire: ownership ? (key) => ownership.tryAcquire(key) : undefined,\n sqlExtensions: opts.sqlExtensions,\n deleteAllPreservesAlarm: opts.deleteAllPreservesAlarm,\n });\n hosts.set(cellKey, h);\n }\n return h;\n };\n hostsByClass.set(className, hostFor);\n const nsKey =\n opts.namespaceKeys?.[className] ?? namespaceKey(opts.scriptName ?? \"worker\", className);\n env[binding] = new DurableObjectNamespace(nsKey, (id) => {\n const remote = opts.route?.(`${className}/${id.toString()}`, id);\n if (remote) return () => httpEndpoint(postVia(remote), codec, binding, className, id);\n const cellKey = `${className}/${id.toString()}`;\n // A cell not open yet waits for room in its store before its first event (OPFS pool).\n const ready = () => (hosts.has(cellKey) ? undefined : opts.openSql.room?.(cellKey));\n const local = localEndpoint(() => hostFor(id), ready);\n const peers = opts.peers;\n if (!peers) return local;\n // Local first; a cell owned by another node is reached through that node.\n const viaOwner = async () => {\n const owner = await peers.ownerOf(cellKey);\n if (!owner) throw new CellOwnedElsewhereError(cellKey);\n const direct = await peers.endpoint?.(owner, cellKey, id.name);\n if (direct) return direct;\n return httpEndpoint(postVia(peers.link(owner)), codec, binding, className, id);\n };\n // The host reports a failed open as a broken object; the cause tells why.\n const elsewhere = (e: unknown): boolean => {\n for (\n let x = e as { name?: string; cause?: unknown } | undefined, i = 0;\n x && i < 5;\n x = x.cause as never, i++\n )\n if (x.name === \"CellOwnedElsewhereError\") return true;\n return false;\n };\n return () => {\n const l = local();\n return {\n get local() {\n return l.local; // not copied: reading it opens the cell\n },\n fetch: async (req: Request) => {\n const spare = req.body ? req.clone() : req;\n try {\n return await l.fetch(req);\n } catch (e) {\n if (!elsewhere(e)) throw e;\n hosts.get(cellKey)?.close();\n hosts.delete(cellKey);\n return (await viaOwner()).fetch(spare);\n }\n },\n call: async (method: string, args: unknown[]) => {\n try {\n return await l.call(method, args);\n } catch (e) {\n if (!elsewhere(e)) throw e;\n hosts.get(cellKey)?.close();\n hosts.delete(cellKey);\n return (await viaOwner()).call(method, args);\n }\n },\n };\n };\n });\n bindingClasses[binding] = className;\n // ctx.exports.<Class> of a class with a namespace is also that namespace, as in workerd\n // (`ctx.exports.MyActor.getByName(\"a\")`); it stays usable as a facet class handle.\n const ns = env[binding] as DurableObjectNamespace;\n const exported = exportsObj[className] as Record<string, unknown> | undefined;\n if (exported && !(\"getByName\" in exported))\n for (const [m, d] of Object.entries(\n Object.getOwnPropertyDescriptors(DurableObjectNamespace.prototype),\n ))\n if (m !== \"constructor\" && typeof d.value === \"function\") exported[m] = d.value.bind(ns);\n }\n\n alarms.restore();\n // Alarms published by any node in a shared wake index (celld's): this node fires them too.\n // An entry is only a hint: firing opens the cell and runs alarm() only if its stored alarm\n // is still due at that time.\n // The index is read at start and then every `wakePollMs` (default 30 s), so alarms of cells\n // whose owner went away are picked up — celld's waker does the same.\n const wakes = storage.durability?.wakes;\n let wakeTimer: unknown;\n let wakesStopped = false;\n if (wakes) {\n const known = new Set(Object.values(bindingClasses));\n const poll = async () => {\n try {\n for (const w of await wakes.call(storage.durability))\n if (known.has(w.className) && !alarmRuns.has(w.cellKey))\n alarms.set(\n { cellKey: w.cellKey, className: w.className, idHex: w.cellKey.split(\"/\")[1] },\n w.at,\n );\n } catch {\n // the index is unavailable for now: next poll\n }\n if (!wakesStopped) wakeTimer = clock.setTimeout(() => void poll(), opts.wakePollMs ?? 30_000);\n };\n void poll();\n }\n // Idle sweep for hibernation (opt-in).\n let hibernationTimer: unknown;\n if (opts.hibernateAfterMs !== undefined) {\n const every = Math.max(1_000, opts.hibernateAfterMs / 2);\n const sweep = () => {\n runtime.hibernateIdle();\n hibernationTimer = clock.setTimeout(sweep, every);\n };\n hibernationTimer = clock.setTimeout(sweep, every);\n }\n const backupAll = (reason: \"interval\" | \"manual\" | \"close\") =>\n Promise.all([...hosts.values()].map((h) => h.backupIfDirty(reason, clock.now()))).then(\n () => {},\n );\n let timer: unknown;\n let closed = false;\n /** Set by close() after its grace period: no cell opens or takes an event any more. */\n let cellsClosed = false;\n /** Aborts when close() starts: the signal of the Worker's requests in flight. */\n const closing = new AbortController();\n const schedule = () => {\n if (!backup || closed) return;\n timer = clock.setTimeout(() => {\n void backupAll(\"interval\").finally(schedule);\n }, backup.intervalMs ?? 30_000);\n };\n schedule();\n\n const runtime: CellRuntime = {\n env,\n exports: exportsObj,\n durableObjectBindings: bindingClasses,\n backupNow: () => backupAll(\"manual\"),\n async connectWebSocket(url, protocols = [], headers) {\n const h = new Headers(headers);\n h.set(\"Upgrade\", \"websocket\");\n if (protocols.length) h.set(\"Sec-WebSocket-Protocol\", protocols.join(\", \"));\n const httpUrl = url.replace(/^ws(s?):/, \"http$1:\");\n const res = (await this.fetch(\n withUpgrade(\n new Request(httpUrl, { headers: h }),\n \"websocket\",\n protocols.length ? { \"Sec-WebSocket-Protocol\": protocols.join(\", \") } : undefined,\n ),\n )) as Response & {\n webSocket?: CfWebSocket | null;\n };\n if (res.status !== 101 || !res.webSocket)\n throw new Error(`WebSocket upgrade refused: HTTP ${res.status}`);\n return {\n port: takeClientPort(res.webSocket),\n protocol: res.headers.get(\"Sec-WebSocket-Protocol\") ?? undefined,\n };\n },\n restartObject(cellKey: string) {\n hosts.get(cellKey)?.restart();\n },\n hibernateIdle(idleMs = opts.hibernateAfterMs ?? 0) {\n const now = Date.now();\n let n = 0;\n const closeMs = opts.closeDatabaseAfterMs;\n for (const h of hosts.values()) {\n const idle = now - h.lastActive;\n if (idle >= idleMs && h.hibernate()) n++;\n if (closeMs !== undefined && idle >= closeMs) h.closeDatabase();\n }\n return n;\n },\n async close() {\n if (hibernationTimer !== undefined) clock.clearTimeout(hibernationTimer);\n closed = true;\n wakesStopped = true;\n if (wakeTimer !== undefined) clock.clearTimeout(wakeTimer);\n alarms.stop();\n clock.clearTimeout(timer);\n timer = undefined;\n // Events in flight (a conversation's last writes, say) and waitUntil work finish first,\n // within the grace period: their writes are then in the final backups too.\n const grace = opts.closeGraceMs ?? 2_000;\n // Requests in flight, the Worker's and its objects', see their signal abort.\n closing.abort(new Error(\"the runtime is closing\"));\n for (const h of hosts.values()) h.shutdown();\n // Work in flight may start more (a queue's delivery calls the consumer, which writes to\n // another object): wait until nothing runs, nor started while waiting, or the grace ends.\n const end = Date.now() + grace;\n for (let left = grace; left > 0; left = end - Date.now()) {\n const cells = hosts.size;\n let t: ReturnType<typeof setTimeout> | undefined;\n const idle = await Promise.race([\n Promise.all([...[...hosts.values()].map((h) => h.settled()), ...[...background]]).then(\n () => true,\n ),\n new Promise<false>((r) => (t = setTimeout(() => r(false), left))),\n ]);\n clearTimeout(t);\n if (!idle) break;\n // One more turn: what finished may have queued more work.\n await new Promise((r) => setTimeout(r, 0));\n if (\n hosts.size === cells &&\n background.size === 0 &&\n [...hosts.values()].every((h) => h.idle)\n )\n break;\n }\n cellsClosed = true;\n await backupAll(\"close\");\n // The releases reach the store before it closes.\n await Promise.all([...hosts.values()].map((h) => h.close()));\n hosts.clear();\n alarms.close(); // every database of the runtime is closed now\n await storage.close?.();\n },\n async fetch(req) {\n const handler = opts.worker.default?.fetch;\n if (!handler) return new Response(\"Worker has no fetch handler\", { status: 500 });\n // A closed runtime serves nothing: its cells are closed, or another runtime's now.\n if (closed) return new Response(\"cellb: the runtime is closed\", { status: 503 });\n // Its signal aborts when the runtime closes: a long poll or an SSE stream ends then.\n req = closingWith(req, closing.signal);\n const ctx = {\n waitUntil,\n passThroughOnException() {},\n exports: exportsObj,\n } as ExecutionContext;\n // celld's ingress: an inbound request has a `cf` object (no edge fields).\n if ((req as { cf?: unknown }).cf === undefined)\n Object.defineProperty(req, \"cf\", { value: {}, enumerable: true });\n try {\n const r = await rejections(() => handler.call(opts.worker.default, req, env, ctx));\n // A non-Response is sent as text (celld), not a failure.\n return r instanceof Response ? r : new Response(String(r));\n } catch (e) {\n const err = e as Error;\n return new Response(\n `Worker failed: rejected: ${err?.name ?? \"Error\"}: ${err?.message ?? String(e)}`,\n {\n status: 500,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n },\n runEvent: (fn) => rejections(fn),\n evictAll() {\n for (const h of hosts.values()) h.close();\n hosts.clear();\n },\n async drain() {\n while (background.size) await Promise.all([...background]);\n },\n waitUntil,\n };\n return runtime;\n}\n\n/** The error (or its cause chain) says another node owns the cell. */\nexport function isOwnedElsewhere(e: unknown): boolean {\n for (\n let x = e as { name?: string; cause?: unknown } | undefined, i = 0;\n x && i < 5;\n x = x.cause as never, i++\n )\n if (x.name === \"CellOwnedElsewhereError\") return true;\n return false;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/core/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type CellDurability,\n type CellStorage,\n type Clock,\n type OpenCellSql,\n systemClock,\n type ValueCodec,\n} from \"../ports.js\";\nimport { httpEndpoint, postVia, type Send } from \"../transport/cells-link.js\";\nimport { v8Codec, v8CodecWith } from \"../v8/codec.js\";\nimport { type CfWebSocket, takeClientPort } from \"../ws/server.js\";\nimport { withUpgrade } from \"../ws/upgrade.js\";\nimport { type AlarmEntry, AlarmScheduler } from \"./alarms.js\";\nimport { type AsyncRoot, asyncRoot } from \"./async-context.js\";\nimport type { ExecutionContext } from \"./durable-object.js\";\nimport { ctxExports, type DurableObjectClass, defaultHandler, storedExports } from \"./handles.js\";\nimport { DurableObjectId, namespaceKey } from \"./id.js\";\nimport { DurableObjectNamespace, localEndpoint, type ObjectEndpoint } from \"./namespace.js\";\nimport {\n CellOwnedElsewhereError,\n closingWith,\n ObjectClosedError,\n ObjectHost,\n} from \"./object-host.js\";\nimport { installRequestBody } from \"./request-body.js\";\nimport { type RejectionHandler, rejectionScope, reportToStderr } from \"./worker-rejections.js\";\n\nexport interface WorkerModule {\n /**\n * An object with handlers (`fetch(req, env, ctx)`), or a class (`export default class extends\n * WorkerEntrypoint`): an instance per request, built with `(ctx, env)`, whose `fetch(req)`\n * answers. A class matches through its `prototype`, so `default.fetch` stays readable.\n */\n default: {\n fetch?(req: Request, env: any, ctx: ExecutionContext): Response | Promise<Response>;\n prototype?: { fetch?(req: Request): Response | Promise<Response> };\n };\n [exportName: string]: unknown;\n}\n\nexport interface CellRuntimeOptions {\n /**\n * A promise the Worker's code leaves rejected (Node: the Worker shares the host's process).\n * It is the Worker's, as on workerd and celld: it reaches this handler, not the process's\n * `unhandledRejection` listeners. Default: one line on stderr, outside the Worker's console.\n */\n onUnhandledRejection?: RejectionHandler;\n /** The Worker's module namespace (what wrangler/celld bundle as main module). */\n worker: WorkerModule;\n /** Durable Object bindings: env name → exported class name (wrangler `durable_objects.bindings`). */\n durableObjects?: Record<string, { className: string }>;\n /** Plain vars / other bindings merged into env. */\n vars?: Record<string, unknown>;\n openSql: OpenCellSql;\n /** Durability, backup and ownership of the cells; closed by `close()`, after the runtime. */\n storage?: CellStorage;\n codec?: ValueCodec;\n /**\n * Placement: return a `send` when the cell lives elsewhere (another shard\n * worker, tab or peer); `undefined` means \"host it here\". Default: all local.\n */\n route?: (cellKey: string, id: DurableObjectId) => Send | undefined;\n /** How often to re-read a shared alarm wake index (durability.wakes), in ms. Default 30 s. */\n wakePollMs?: number;\n /** Every object of this runtime is a facet of an outer cell (an isolate's runtime). */\n facets?: boolean;\n /**\n * The `ctx.id` an object sees, when it is not the id that addresses it (a facet given an `id`\n * by `ctx.facets.get`): its storage, cell key and alarms stay the addressing id's.\n */\n ctxIdOf?: (cellKey: string) => DurableObjectId | undefined;\n /** The Worker script's name (wrangler `name`): object ids derive from it, as on celld. */\n scriptName?: string;\n /** Namespace keys overriding the script-scoped default, per class (celld's fleet-wide ones). */\n namespaceKeys?: Record<string, string>;\n /**\n * Routing between nodes (celld's peer routing): when this node cannot own a cell\n * (`CellOwnedElsewhereError`), the call goes to the owner's node over an internal link\n * (`cellsHttpHandler` on the far side). `ownerOf` reads the cell's lease holder.\n */\n peers?: {\n ownerOf(cellKey: string): Promise<string | undefined>;\n link(owner: string): Send;\n /**\n * Talks to an owner directly, for owners that do not speak cellsHttpHandler (a celld node,\n * reached through celld's peer tunnel). Takes precedence over `link` when it returns one.\n */\n endpoint?(\n owner: string,\n cellKey: string,\n name: string | undefined,\n ): Promise<ObjectEndpoint | undefined>;\n };\n /** Hibernate objects idle this long (ms); swept every max(1 s, half of it). Off by default. */\n hibernateAfterMs?: number;\n /**\n * Close the SQLite database of a hibernated object idle this long (ms); the next event reopens\n * it. Swept with `hibernateAfterMs`, so it needs that too. Off by default: the database must\n * come back, so use local SQLite that persists (a directory, an OPFS pool) or storage that\n * restores the cell (a log or a backup).\n */\n closeDatabaseAfterMs?: number;\n /**\n * On `close()`, how long (ms) events still running and `waitUntil` work may take to finish\n * before the databases close under them (they then fail with ObjectClosedError). Default 2000.\n */\n closeGraceMs?: number;\n /** SQLite extensions loaded into every cell database (celld's `sqlite_vec` flag). */\n sqlExtensions?: string[];\n /** `delete_all_preserves_alarm`: storage.deleteAll() keeps the alarm (default: deletes it). */\n deleteAllPreservesAlarm?: boolean;\n /** Timers of the runtime (backups); injectable for tests. */\n clock?: Clock;\n}\n\nexport interface CellRuntime {\n /** Ingress: a (Request) ⇒ Response handler — exactly what webrun-http-browser / node:http mount. */\n fetch(req: Request): Promise<Response>;\n readonly env: Record<string, unknown>;\n /** The Worker's `ctx.exports` (also `exports` of `cloudflare:workers`). */\n readonly exports: Record<string, unknown>;\n /**\n * Runs Worker code the host dispatches itself (a cron trigger's `scheduled()`) as the Worker's\n * event: a promise it leaves rejected goes to `onUnhandledRejection`, not to the process.\n */\n runEvent<R>(fn: () => R): R;\n /** Drops live instances (simulates eviction / hibernation); storage survives if openSql persists it. */\n evictAll(): void;\n /** Settles all waitUntil() promises. */\n drain(): Promise<void>;\n /**\n * Keeps `p` running in the background until `drain()` (what `waitUntil` of\n * `cloudflare:workers` does: on Cloudflare it extends the current event).\n */\n waitUntil(p: Promise<unknown>): void;\n /** Durable Object binding → class name (the namespace key used by idFromName). */\n readonly durableObjectBindings: Readonly<Record<string, string>>;\n /**\n * WebSocket ingress: runs the Worker's fetch with an Upgrade request; on a 101\n * with `webSocket`, returns the client end's MessagePort (to be transferred to\n * the real client, e.g. a page's CellsWebSocket).\n */\n connectWebSocket(\n url: string,\n protocols?: string[],\n headers?: HeadersInit,\n ): Promise<{ port: MessagePort; protocol?: string }>;\n /** Backs up every live cell that changed since its last successful save. */\n backupNow(): Promise<void>;\n /**\n * Hibernates every object idle for at least `idleMs` (default: `hibernateAfterMs`):\n * instances are dropped, storage and hibernatable WebSockets stay. Returns how many slept.\n * Hibernated objects idle for `closeDatabaseAfterMs` also close their database.\n */\n hibernateIdle(idleMs?: number): number;\n /** Replaces one object's instance with a fresh one on the same storage (facet abort). */\n restartObject(cellKey: string): void;\n /** Final backup of changed cells, then stops timers, closes every database and the storage. */\n close(): Promise<void>;\n}\n\nexport function createCellRuntime(opts: CellRuntimeOptions): CellRuntime {\n installRequestBody(); // Firefox: `request.body` for the Worker code (and for the retry below)\n const storage = opts.storage ?? {};\n const { backup, ownership } = storage;\n const durability: CellDurability = storage.durability ?? { committed: () => Promise.resolve() };\n // V8 serialization: storage values in celld's (and workerd's) format.\n const codec = opts.codec ?? v8Codec;\n const hosts = new Map<string, ObjectHost>();\n const background = new Set<Promise<unknown>>();\n // Events start in the context the runtime was made in, not their caller's (Cloudflare).\n // …and in a scope that keeps the Worker's unhandled rejections its own (Node).\n const rejections = rejectionScope(\n opts.onUnhandledRejection ?? reportToStderr(opts.scriptName ?? \"worker\"),\n );\n const root = asyncRoot();\n const eventsRoot: AsyncRoot = (fn) => root(() => rejections(fn));\n const waitUntil = (p: Promise<unknown>) => {\n const t = p.catch(() => {}).finally(() => background.delete(t));\n background.add(t);\n };\n const env: Record<string, unknown> = { ...opts.vars };\n const bindingClasses: Record<string, string> = {};\n const exportsObj = ctxExports(opts.worker, env);\n // Storage values: V8 serialization; ctx.exports stubs are stored too (workerd).\n const storageCodec = opts.codec ?? v8CodecWith(storedExports(exportsObj));\n const clock = opts.clock ?? systemClock;\n // Hosts by class name: the alarm scheduler wakes objects that nobody is calling.\n const hostsByClass = new Map<string, (id: DurableObjectId) => ObjectHost>();\n const alarms = new AlarmScheduler({\n clock,\n openIndex: () => opts.openSql(\"__cellb/alarms\"),\n fire: (e) => fireAlarm(e),\n });\n // One alarm() at a time per object (as on Cloudflare): a re-armed alarm that comes due\n // while the previous handler still runs waits for it.\n const alarmRuns = new Map<string, Promise<void>>();\n const ownedRetries = new Map<string, number>();\n function fireAlarm(e: AlarmEntry): Promise<void> {\n const prev = alarmRuns.get(e.cellKey) ?? Promise.resolve();\n const next = prev.then(() => fireAlarmNow(e));\n alarmRuns.set(e.cellKey, next);\n void next.finally(() => {\n if (alarmRuns.get(e.cellKey) === next) alarmRuns.delete(e.cellKey);\n });\n return next;\n }\n /**\n * celld's alarm lifecycle, in the cell's own storage (so it survives restarts and moves\n * between nodes, celld included): the row stays while its handler runs (getAlarm() reads\n * null meanwhile); success deletes it, failure reschedules it with backoff and counts the\n * failure in the row (`retry`, `counted_retry`) — alarmInfo.retryCount is that count.\n */\n async function fireAlarmNow(e: AlarmEntry): Promise<void> {\n const hostFor = hostsByClass.get(e.className);\n if (!hostFor) return;\n const host = hostFor(new DurableObjectId(e.idHex));\n try {\n await host.deliver(async (obj, state) => {\n // A wake (local timer, or an entry of the shared wake index) is a hint: the stored\n // alarm decides. Gone → nothing to do; moved later → wait for that time.\n const row = state.storage.alarmRowSync();\n if (!row) return;\n if (row.at > clock.now()) {\n alarms.set(e, row.at);\n return;\n }\n state.storage.beginAlarm(row);\n let ok = true;\n try {\n if (typeof obj.alarm === \"function\")\n await obj.alarm({\n retryCount: row.retry,\n isRetry: row.retry > 0,\n scheduledTime: row.at, // alarmInfo.scheduledTime, as in workerd\n });\n } catch {\n ok = false;\n }\n state.storage.finishAlarm(row, ok, clock.now());\n });\n ownedRetries.delete(e.cellKey);\n } catch (err) {\n // Owned by another node (celld or cellb): its owner fires the alarm.\n if (isOwnedElsewhere(err)) {\n hosts.get(e.cellKey)?.close();\n hosts.delete(e.cellKey);\n // A live owner fires it. A stopped one's lease expires within its TTL: look again a\n // few times before leaving it to the next poll of the wake index.\n const n = (ownedRetries.get(e.cellKey) ?? 0) + 1;\n if (n <= 15) {\n ownedRetries.set(e.cellKey, n);\n alarms.set(e, clock.now() + 2_000);\n } else ownedRetries.delete(e.cellKey);\n }\n // Any other failure (broken object, storage error): the row is unchanged; it fires again\n // when the object is next opened or the index is polled.\n }\n }\n\n for (const [binding, { className }] of Object.entries(opts.durableObjects ?? {})) {\n const cls = opts.worker[className] as DurableObjectClass | undefined;\n if (typeof cls !== \"function\")\n throw new Error(`Durable Object class \"${className}\" is not exported by the worker`);\n const hostFor = (id: DurableObjectId): ObjectHost => {\n const cellKey = `${className}/${id.toString()}`;\n // Once close() has closed the cells, none opens again: its storage is closed or handed to\n // the next runtime. Until then (the grace period), work in flight still reaches objects.\n if (cellsClosed) throw new ObjectClosedError(cellKey);\n let h = hosts.get(cellKey);\n if (!h || h.broken) {\n h?.close();\n h = new ObjectHost({\n cellKey,\n id: opts.ctxIdOf?.(cellKey) ?? id,\n cls,\n env,\n openSql: opts.openSql,\n durability,\n codec: storageCodec,\n waitUntil,\n backup,\n onAlarmChange: (at) => alarms.set({ cellKey, className, idHex: id.toString() }, at),\n exports: exportsObj,\n facet: opts.facets,\n asyncRoot: eventsRoot,\n acquire: ownership ? (key) => ownership.tryAcquire(key) : undefined,\n sqlExtensions: opts.sqlExtensions,\n deleteAllPreservesAlarm: opts.deleteAllPreservesAlarm,\n });\n hosts.set(cellKey, h);\n }\n return h;\n };\n hostsByClass.set(className, hostFor);\n const nsKey =\n opts.namespaceKeys?.[className] ?? namespaceKey(opts.scriptName ?? \"worker\", className);\n env[binding] = new DurableObjectNamespace(nsKey, (id) => {\n const remote = opts.route?.(`${className}/${id.toString()}`, id);\n if (remote) return () => httpEndpoint(postVia(remote), codec, binding, className, id);\n const cellKey = `${className}/${id.toString()}`;\n // A cell not open yet waits for room in its store before its first event (OPFS pool).\n const ready = () => (hosts.has(cellKey) ? undefined : opts.openSql.room?.(cellKey));\n const local = localEndpoint(() => hostFor(id), ready);\n const peers = opts.peers;\n if (!peers) return local;\n // Local first; a cell owned by another node is reached through that node.\n const viaOwner = async () => {\n const owner = await peers.ownerOf(cellKey);\n if (!owner) throw new CellOwnedElsewhereError(cellKey);\n const direct = await peers.endpoint?.(owner, cellKey, id.name);\n if (direct) return direct;\n return httpEndpoint(postVia(peers.link(owner)), codec, binding, className, id);\n };\n // The host reports a failed open as a broken object; the cause tells why.\n const elsewhere = (e: unknown): boolean => {\n for (\n let x = e as { name?: string; cause?: unknown } | undefined, i = 0;\n x && i < 5;\n x = x.cause as never, i++\n )\n if (x.name === \"CellOwnedElsewhereError\") return true;\n return false;\n };\n return () => {\n const l = local();\n return {\n get local() {\n return l.local; // not copied: reading it opens the cell\n },\n fetch: async (req: Request) => {\n const spare = req.body ? req.clone() : req;\n try {\n return await l.fetch(req);\n } catch (e) {\n if (!elsewhere(e)) throw e;\n hosts.get(cellKey)?.close();\n hosts.delete(cellKey);\n return (await viaOwner()).fetch(spare);\n }\n },\n call: async (method: string, args: unknown[]) => {\n try {\n return await l.call(method, args);\n } catch (e) {\n if (!elsewhere(e)) throw e;\n hosts.get(cellKey)?.close();\n hosts.delete(cellKey);\n return (await viaOwner()).call(method, args);\n }\n },\n };\n };\n });\n bindingClasses[binding] = className;\n // ctx.exports.<Class> of a class with a namespace is also that namespace, as in workerd\n // (`ctx.exports.MyActor.getByName(\"a\")`); it stays usable as a facet class handle.\n const ns = env[binding] as DurableObjectNamespace;\n const exported = exportsObj[className] as Record<string, unknown> | undefined;\n if (exported && !(\"getByName\" in exported))\n for (const [m, d] of Object.entries(\n Object.getOwnPropertyDescriptors(DurableObjectNamespace.prototype),\n ))\n if (m !== \"constructor\" && typeof d.value === \"function\") exported[m] = d.value.bind(ns);\n }\n\n alarms.restore();\n // Alarms published by any node in a shared wake index (celld's): this node fires them too.\n // An entry is only a hint: firing opens the cell and runs alarm() only if its stored alarm\n // is still due at that time.\n // The index is read at start and then every `wakePollMs` (default 30 s), so alarms of cells\n // whose owner went away are picked up — celld's waker does the same.\n const wakes = storage.durability?.wakes;\n let wakeTimer: unknown;\n let wakesStopped = false;\n if (wakes) {\n const known = new Set(Object.values(bindingClasses));\n const poll = async () => {\n try {\n for (const w of await wakes.call(storage.durability))\n if (known.has(w.className) && !alarmRuns.has(w.cellKey))\n alarms.set(\n { cellKey: w.cellKey, className: w.className, idHex: w.cellKey.split(\"/\")[1] },\n w.at,\n );\n } catch {\n // the index is unavailable for now: next poll\n }\n if (!wakesStopped) wakeTimer = clock.setTimeout(() => void poll(), opts.wakePollMs ?? 30_000);\n };\n void poll();\n }\n // Idle sweep for hibernation (opt-in).\n let hibernationTimer: unknown;\n if (opts.hibernateAfterMs !== undefined) {\n const every = Math.max(1_000, opts.hibernateAfterMs / 2);\n const sweep = () => {\n runtime.hibernateIdle();\n hibernationTimer = clock.setTimeout(sweep, every);\n };\n hibernationTimer = clock.setTimeout(sweep, every);\n }\n const backupAll = (reason: \"interval\" | \"manual\" | \"close\") =>\n Promise.all([...hosts.values()].map((h) => h.backupIfDirty(reason, clock.now()))).then(\n () => {},\n );\n let timer: unknown;\n let closed = false;\n /** Set by close() after its grace period: no cell opens or takes an event any more. */\n let cellsClosed = false;\n /** Aborts when close() starts: the signal of the Worker's requests in flight. */\n const closing = new AbortController();\n const schedule = () => {\n if (!backup || closed) return;\n timer = clock.setTimeout(() => {\n void backupAll(\"interval\").finally(schedule);\n }, backup.intervalMs ?? 30_000);\n };\n schedule();\n\n const runtime: CellRuntime = {\n env,\n exports: exportsObj,\n durableObjectBindings: bindingClasses,\n backupNow: () => backupAll(\"manual\"),\n async connectWebSocket(url, protocols = [], headers) {\n const h = new Headers(headers);\n h.set(\"Upgrade\", \"websocket\");\n if (protocols.length) h.set(\"Sec-WebSocket-Protocol\", protocols.join(\", \"));\n const httpUrl = url.replace(/^ws(s?):/, \"http$1:\");\n const res = (await this.fetch(\n withUpgrade(\n new Request(httpUrl, { headers: h }),\n \"websocket\",\n protocols.length ? { \"Sec-WebSocket-Protocol\": protocols.join(\", \") } : undefined,\n ),\n )) as Response & {\n webSocket?: CfWebSocket | null;\n };\n if (res.status !== 101 || !res.webSocket)\n throw new Error(`WebSocket upgrade refused: HTTP ${res.status}`);\n return {\n port: takeClientPort(res.webSocket),\n protocol: res.headers.get(\"Sec-WebSocket-Protocol\") ?? undefined,\n };\n },\n restartObject(cellKey: string) {\n hosts.get(cellKey)?.restart();\n },\n hibernateIdle(idleMs = opts.hibernateAfterMs ?? 0) {\n const now = Date.now();\n let n = 0;\n const closeMs = opts.closeDatabaseAfterMs;\n for (const h of hosts.values()) {\n const idle = now - h.lastActive;\n if (idle >= idleMs && h.hibernate()) n++;\n if (closeMs !== undefined && idle >= closeMs) h.closeDatabase();\n }\n return n;\n },\n async close() {\n if (hibernationTimer !== undefined) clock.clearTimeout(hibernationTimer);\n closed = true;\n wakesStopped = true;\n if (wakeTimer !== undefined) clock.clearTimeout(wakeTimer);\n alarms.stop();\n clock.clearTimeout(timer);\n timer = undefined;\n // Events in flight (a conversation's last writes, say) and waitUntil work finish first,\n // within the grace period: their writes are then in the final backups too.\n const grace = opts.closeGraceMs ?? 2_000;\n // Requests in flight, the Worker's and its objects', see their signal abort.\n closing.abort(new Error(\"the runtime is closing\"));\n for (const h of hosts.values()) h.shutdown();\n // Work in flight may start more (a queue's delivery calls the consumer, which writes to\n // another object): wait until nothing runs, nor started while waiting, or the grace ends.\n const end = Date.now() + grace;\n for (let left = grace; left > 0; left = end - Date.now()) {\n const cells = hosts.size;\n let t: ReturnType<typeof setTimeout> | undefined;\n const idle = await Promise.race([\n Promise.all([...[...hosts.values()].map((h) => h.settled()), ...[...background]]).then(\n () => true,\n ),\n new Promise<false>((r) => (t = setTimeout(() => r(false), left))),\n ]);\n clearTimeout(t);\n if (!idle) break;\n // One more turn: what finished may have queued more work.\n await new Promise((r) => setTimeout(r, 0));\n if (\n hosts.size === cells &&\n background.size === 0 &&\n [...hosts.values()].every((h) => h.idle)\n )\n break;\n }\n cellsClosed = true;\n await backupAll(\"close\");\n // The releases reach the store before it closes.\n await Promise.all([...hosts.values()].map((h) => h.close()));\n hosts.clear();\n alarms.close(); // every database of the runtime is closed now\n await storage.close?.();\n },\n async fetch(req) {\n const handler = defaultHandler(opts.worker.default, \"fetch\");\n if (!handler) return new Response(\"Worker has no fetch handler\", { status: 500 });\n // A closed runtime serves nothing: its cells are closed, or another runtime's now.\n if (closed) return new Response(\"cellb: the runtime is closed\", { status: 503 });\n // Its signal aborts when the runtime closes: a long poll or an SSE stream ends then.\n req = closingWith(req, closing.signal);\n const ctx = {\n waitUntil,\n passThroughOnException() {},\n exports: exportsObj,\n } as ExecutionContext;\n // celld's ingress: an inbound request has a `cf` object (no edge fields).\n if ((req as { cf?: unknown }).cf === undefined)\n Object.defineProperty(req, \"cf\", { value: {}, enumerable: true });\n try {\n const r = await rejections(() => handler(req, env, ctx));\n // A non-Response is sent as text (celld), not a failure.\n return r instanceof Response ? r : new Response(String(r));\n } catch (e) {\n const err = e as Error;\n return new Response(\n `Worker failed: rejected: ${err?.name ?? \"Error\"}: ${err?.message ?? String(e)}`,\n {\n status: 500,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n },\n runEvent: (fn) => rejections(fn),\n evictAll() {\n for (const h of hosts.values()) h.close();\n hosts.clear();\n },\n async drain() {\n while (background.size) await Promise.all([...background]);\n },\n waitUntil,\n };\n return runtime;\n}\n\n/** The error (or its cause chain) says another node owns the cell. */\nexport function isOwnedElsewhere(e: unknown): boolean {\n for (\n let x = e as { name?: string; cause?: unknown } | undefined, i = 0;\n x && i < 5;\n x = x.cause as never, i++\n )\n if (x.name === \"CellOwnedElsewhereError\") return true;\n return false;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,3 +22,8 @@ export { type CellsHttpOptions, cellsHttpHandler, type RemoteRuntime, remoteRunt
|
|
|
22
22
|
export { type CellPort, connectRuntime, linkOverPort, serveHandlerOverPort, serveRuntime, } from "./transport/port.js";
|
|
23
23
|
export { type CellsWebSocketClass, createWebSocketClass, type WebSocketConnector, } from "./ws/client.js";
|
|
24
24
|
export { CellsResponse, takeClientPort, WebSocketPair } from "./ws/server.js";
|
|
25
|
+
/**
|
|
26
|
+
* A WebSocket upgrade request a browser can make: `new Request()` there drops `Upgrade` and
|
|
27
|
+
* `Sec-WebSocket-*`, so an embedder that hands a project a socket from a page sets them with this.
|
|
28
|
+
*/
|
|
29
|
+
export { withUpgrade } from "./ws/upgrade.js";
|
package/dist/index.js
CHANGED
|
@@ -22,4 +22,9 @@ export { cellsHttpHandler, remoteRuntime, } from "./transport/cells-http.js";
|
|
|
22
22
|
export { connectRuntime, linkOverPort, serveHandlerOverPort, serveRuntime, } from "./transport/port.js";
|
|
23
23
|
export { createWebSocketClass, } from "./ws/client.js";
|
|
24
24
|
export { CellsResponse, takeClientPort, WebSocketPair } from "./ws/server.js";
|
|
25
|
+
/**
|
|
26
|
+
* A WebSocket upgrade request a browser can make: `new Request()` there drops `Upgrade` and
|
|
27
|
+
* `Sec-WebSocket-*`, so an embedder that hands a project a socket from a page sets them with this.
|
|
28
|
+
*/
|
|
29
|
+
export { withUpgrade } from "./ws/upgrade.js";
|
|
25
30
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAyB,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAA8B,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,OAAO,EAGP,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAA2B,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EAEjB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAkB,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAyB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EACL,sBAAsB,EAEtB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAwB,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACzF,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GAKpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAA0B,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EACL,iBAAiB,EAGjB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,gBAAgB,EAEhB,aAAa,GACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,oBAAoB,GAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export { type FilesApiBackupOptions, filesApiBackup } from \"./adapters/files-backup.js\";\nexport { type ChangeLogOptions, filesApiChangeLog } from \"./adapters/files-changelog.js\";\nexport { type FilesApiLtxLogOptions, filesApiLtxLog } from \"./adapters/files-ltx.js\";\nexport { wasmMemoryOpener } from \"./adapters/wasm-sqlite.js\";\nexport {\n AiError,\n type AiRunOptions,\n type WorkersAiOptions,\n workersAi,\n} from \"./bindings/workers-ai.js\";\nexport { type CelldBucketOptions, celldBucket } from \"./bucket/celld-cells.js\";\nexport {\n filesApiObjectStore,\n memoryObjectStore,\n type ObjectStore,\n PreconditionFailedError,\n} from \"./bucket/object-store.js\";\nexport { type S3Options, s3ObjectStore } from \"./bucket/s3-object-store.js\";\nexport { DurableObject, type ExecutionContext, WorkerEntrypoint } from \"./core/durable-object.js\";\nexport {\n DurableObjectNamespace,\n type DurableObjectStub,\n runInDurableObject,\n} from \"./core/namespace.js\";\nexport {\n BrokenObjectError,\n CellOwnedElsewhereError,\n ObjectClosedError,\n} from \"./core/object-host.js\";\nexport {\n type CellRuntime,\n type CellRuntimeOptions,\n createCellRuntime,\n type WorkerModule,\n} from \"./core/runtime.js\";\nexport { shardOf } from \"./core/shard.js\";\nexport { DurableObjectState } from \"./core/state.js\";\nexport { type FilesRpcOptions, rpcFilesClient, serveFilesApi } from \"./ltx/files-rpc.js\";\nexport * from \"./ports.js\";\nexport { parseJsonc } from \"./project/jsonc.js\";\nexport {\n createProjectRuntime,\n loadProjectBindings,\n type ProjectBindings,\n type ProjectHost,\n type ProjectRuntime,\n type WranglerConfig,\n} from \"./project/wrangler.js\";\nexport { CellRouter, type CellRouterOptions, ShardOwnerLostError } from \"./router/cell-router.js\";\nexport {\n createShardWorker,\n type ShardWorker,\n type ShardWorkerOptions,\n shardRouting,\n} from \"./router/shard-worker.js\";\nexport {\n type CellsHttpOptions,\n cellsHttpHandler,\n type RemoteRuntime,\n remoteRuntime,\n} from \"./transport/cells-http.js\";\nexport {\n type CellPort,\n connectRuntime,\n linkOverPort,\n serveHandlerOverPort,\n serveRuntime,\n} from \"./transport/port.js\";\nexport {\n type CellsWebSocketClass,\n createWebSocketClass,\n type WebSocketConnector,\n} from \"./ws/client.js\";\nexport { CellsResponse, takeClientPort, WebSocketPair } from \"./ws/server.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAyB,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAA8B,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,OAAO,EAGP,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAA2B,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EAEjB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAkB,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAyB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EACL,sBAAsB,EAEtB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAwB,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACzF,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GAKpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAA0B,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EACL,iBAAiB,EAGjB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,gBAAgB,EAEhB,aAAa,GACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,oBAAoB,GAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC9E;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { type FilesApiBackupOptions, filesApiBackup } from \"./adapters/files-backup.js\";\nexport { type ChangeLogOptions, filesApiChangeLog } from \"./adapters/files-changelog.js\";\nexport { type FilesApiLtxLogOptions, filesApiLtxLog } from \"./adapters/files-ltx.js\";\nexport { wasmMemoryOpener } from \"./adapters/wasm-sqlite.js\";\nexport {\n AiError,\n type AiRunOptions,\n type WorkersAiOptions,\n workersAi,\n} from \"./bindings/workers-ai.js\";\nexport { type CelldBucketOptions, celldBucket } from \"./bucket/celld-cells.js\";\nexport {\n filesApiObjectStore,\n memoryObjectStore,\n type ObjectStore,\n PreconditionFailedError,\n} from \"./bucket/object-store.js\";\nexport { type S3Options, s3ObjectStore } from \"./bucket/s3-object-store.js\";\nexport { DurableObject, type ExecutionContext, WorkerEntrypoint } from \"./core/durable-object.js\";\nexport {\n DurableObjectNamespace,\n type DurableObjectStub,\n runInDurableObject,\n} from \"./core/namespace.js\";\nexport {\n BrokenObjectError,\n CellOwnedElsewhereError,\n ObjectClosedError,\n} from \"./core/object-host.js\";\nexport {\n type CellRuntime,\n type CellRuntimeOptions,\n createCellRuntime,\n type WorkerModule,\n} from \"./core/runtime.js\";\nexport { shardOf } from \"./core/shard.js\";\nexport { DurableObjectState } from \"./core/state.js\";\nexport { type FilesRpcOptions, rpcFilesClient, serveFilesApi } from \"./ltx/files-rpc.js\";\nexport * from \"./ports.js\";\nexport { parseJsonc } from \"./project/jsonc.js\";\nexport {\n createProjectRuntime,\n loadProjectBindings,\n type ProjectBindings,\n type ProjectHost,\n type ProjectRuntime,\n type WranglerConfig,\n} from \"./project/wrangler.js\";\nexport { CellRouter, type CellRouterOptions, ShardOwnerLostError } from \"./router/cell-router.js\";\nexport {\n createShardWorker,\n type ShardWorker,\n type ShardWorkerOptions,\n shardRouting,\n} from \"./router/shard-worker.js\";\nexport {\n type CellsHttpOptions,\n cellsHttpHandler,\n type RemoteRuntime,\n remoteRuntime,\n} from \"./transport/cells-http.js\";\nexport {\n type CellPort,\n connectRuntime,\n linkOverPort,\n serveHandlerOverPort,\n serveRuntime,\n} from \"./transport/port.js\";\nexport {\n type CellsWebSocketClass,\n createWebSocketClass,\n type WebSocketConnector,\n} from \"./ws/client.js\";\nexport { CellsResponse, takeClientPort, WebSocketPair } from \"./ws/server.js\";\n/**\n * A WebSocket upgrade request a browser can make: `new Request()` there drops `Upgrade` and\n * `Sec-WebSocket-*`, so an embedder that hands a project a socket from a page sets them with this.\n */\nexport { withUpgrade } from \"./ws/upgrade.js\";\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ModuleLoader } from "../bindings/worker-loader.js";
|
|
2
2
|
import type { CellStorage } from "../ports.js";
|
|
3
3
|
/**
|
|
4
4
|
* Isolated loading in browsers: each loaded Worker runs in its own Dedicated Worker
|
package/dist/isolate/browser.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { compileWasmModules, } from "../bindings/worker-loader.js";
|
|
1
2
|
import { putLoadedModule } from "../project/site-loader.js";
|
|
2
3
|
import { isolatedModuleLoader } from "./host.js";
|
|
3
4
|
/**
|
|
@@ -18,7 +19,8 @@ export function browserIsolatedLoader(opts) {
|
|
|
18
19
|
prepare: async (id, code) => {
|
|
19
20
|
if (!opts.siteBaseUrl)
|
|
20
21
|
return {
|
|
21
|
-
|
|
22
|
+
// Compiled here once: a Dedicated Worker takes a WebAssembly.Module as it is.
|
|
23
|
+
modules: (await compileWasmModules(code)).modules,
|
|
22
24
|
mainModule: code.mainModule,
|
|
23
25
|
storageName: storageName(id),
|
|
24
26
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/isolate/browser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/isolate/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAGnB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGjD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAQrC;IACC,MAAM,WAAW,GAAG,CAAC,EAAU,EAAE,EAAE,CACjC,GAAG,IAAI,CAAC,aAAa,IAAI,SAAS,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACtE,OAAO,oBAAoB,CAAC;QAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,GAAG,EAAE;YACV,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;YAClC,MAAM,CAAC,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC3F,OAAO,EAAE,IAAI,EAAE,CAAwB,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;QAC5E,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,EAAU,EAAE,IAAgB,EAAE,EAAE;YAC9C,IAAI,CAAC,IAAI,CAAC,WAAW;gBACnB,OAAO;oBACL,8EAA8E;oBAC9E,OAAO,EAAE,CAAC,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;oBACjD,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;iBACpB,CAAC;YACb,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC;YACxF,MAAM,GAAG,GAAG,kBAAkB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAChD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrD,MAAM,eAAe,CAAC,GAAG,IAAI,cAAc,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,GAAG,IAAI,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE;gBAChD,SAAS,EAAE,WAAW,EAAE,EAAE;gBAC1B,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;aACpB,CAAC;QACb,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n compileWasmModules,\n type ModuleLoader,\n type WorkerCode,\n} from \"../bindings/worker-loader.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport { putLoadedModule } from \"../project/site-loader.js\";\nimport { isolatedModuleLoader } from \"./host.js\";\nimport type { PortLike } from \"./protocol.js\";\n\n/**\n * Isolated loading in browsers: each loaded Worker runs in its own Dedicated Worker\n * (`isolateScript`, e.g. src/isolate/isolate-worker.ts). With `siteBaseUrl` (the in-browser\n * HTTP server, docs/browser-host.md) its modules are uploaded and imported from URLs; otherwise they\n * travel to the isolate and become Blob-URL modules there.\n */\nexport function browserIsolatedLoader(opts: {\n /** The isolate's script, or a function that starts a Dedicated Worker running it. */\n isolateScript: URL | (() => Worker);\n siteBaseUrl?: string;\n /** Prefix of the OPFS SQLite pool each isolate keeps its facets in (one pool per loaded id). */\n storagePrefix?: string;\n /** The host's storage: facets of loaded code are logged and restored through it. */\n storage?: () => CellStorage | undefined;\n}): ModuleLoader {\n const storageName = (id: string) =>\n `${opts.storagePrefix ?? \"isolate\"}-${id}`.replace(/[^\\w.-]/g, \"_\");\n return isolatedModuleLoader({\n storage: opts.storage,\n spawn: () => {\n const script = opts.isolateScript;\n const w = typeof script === \"function\" ? script() : new Worker(script, { type: \"module\" });\n return { port: w as unknown as PortLike, terminate: () => w.terminate() };\n },\n prepare: async (id: string, code: WorkerCode) => {\n if (!opts.siteBaseUrl)\n return {\n // Compiled here once: a Dedicated Worker takes a WebAssembly.Module as it is.\n modules: (await compileWasmModules(code)).modules,\n mainModule: code.mainModule,\n storageName: storageName(id),\n } as never;\n const base = opts.siteBaseUrl.endsWith(\"/\") ? opts.siteBaseUrl : `${opts.siteBaseUrl}/`;\n const dir = encodeURIComponent(`isolate-${id}`);\n for (const [name, m] of Object.entries(code.modules)) {\n await putLoadedModule(`${base}loaded-src/${dir}/${name}`, m);\n }\n return {\n url: `${base}loaded/${dir}/~/${code.mainModule}`,\n consoleId: `isolate-${id}`,\n storageName: storageName(id),\n } as never;\n },\n });\n}\n"]}
|
package/dist/isolate/host.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { outboundFetch, } from "../bindings/worker-loader.js";
|
|
2
|
-
import { ISOLATED } from "../core/handles.js";
|
|
2
|
+
import { ISOLATED, ON_ABORT } from "../core/handles.js";
|
|
3
3
|
import { hostPort } from "./protocol.js";
|
|
4
4
|
/**
|
|
5
5
|
* Worker Loader whose code runs in a separate realm per loaded Worker (an isolate). Returns
|
|
@@ -22,7 +22,22 @@ export function isolatedModuleLoader(opts) {
|
|
|
22
22
|
terminate: () => isolate.terminate(),
|
|
23
23
|
};
|
|
24
24
|
isolates.add(running);
|
|
25
|
-
const
|
|
25
|
+
const onAbort = [];
|
|
26
|
+
let aborted = false;
|
|
27
|
+
// The loaded code called `abortIsolate()`: calls in flight and later ones reject with
|
|
28
|
+
// workerd's error, the isolate ends, and the loader forgets this module.
|
|
29
|
+
const abort = (m) => {
|
|
30
|
+
if (!isolates.delete(running))
|
|
31
|
+
return;
|
|
32
|
+
aborted = true;
|
|
33
|
+
console.error(`cellb: loaded Worker "${id}" aborted its isolate: ${m.reason}`);
|
|
34
|
+
void close(new Error(`internal error; reference = ${m.reference}`)).finally(() => isolate.terminate());
|
|
35
|
+
for (const f of onAbort.splice(0))
|
|
36
|
+
f();
|
|
37
|
+
};
|
|
38
|
+
const { call, fetch, close } = await hostPort(isolate.port, async (m) => {
|
|
39
|
+
if (m.type === "abort")
|
|
40
|
+
return abort(m);
|
|
26
41
|
if (m.type === "durable") {
|
|
27
42
|
const st = opts.storage?.() ?? {};
|
|
28
43
|
if (m.op === "load")
|
|
@@ -77,6 +92,9 @@ export function isolatedModuleLoader(opts) {
|
|
|
77
92
|
delete: (cellKey) => call({ type: "object", op: "delete", className, cellKey }),
|
|
78
93
|
attach: (cellKey, epoch, idName) => call({ type: "object", op: "attach", className, cellKey, epoch, idName }),
|
|
79
94
|
});
|
|
95
|
+
// Registered after the load: an isolate that ended while its code was evaluated is forgotten
|
|
96
|
+
// at once.
|
|
97
|
+
module[ON_ABORT] = (f) => (aborted ? f() : onAbort.push(f));
|
|
80
98
|
return module;
|
|
81
99
|
};
|
|
82
100
|
return Object.assign(load, {
|
package/dist/isolate/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/isolate/host.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,GAEd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAsB,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAiB,MAAM,eAAe,CAAC;AAExD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAQpC;IACC,2FAA2F;IAC3F,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsD,CAAC;IAC/E,MAAM,IAAI,GAAG,KAAK,EAAE,EAAU,EAAE,IAAgB,EAAE,IAAc,EAAE,EAAE;QAClE,2EAA2E;QAC3E,MAAM,GAAG,GAA4B,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrD,8FAA8F;QAC9F,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5F,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAuD;YAClE,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE;SACrC,CAAC;QACF,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CACpC,OAAO,CAAC,IAAI,EACZ,KAAK,EAAE,CAAC,EAAE,EAAE;YACV,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC;gBAClC,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM;oBAAE,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACzD,IAAI,CAAC,CAAC,EAAE,KAAK,WAAW,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;oBAC1C,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;oBACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;oBACzB,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE;wBACvC,GAAG,IAAI;wBACP,KAAK,EACH,OAAO,KAAK,KAAK,QAAQ;4BACvB,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAyB,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;4BAC9D,CAAC,CAAC,KAAK;qBACZ,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO;YACT,CAAC;YACD,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACrB,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBACvB,OAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;QACH,CAAC,EACD,OAAO,CACR,CAAC;QACF,wFAAwF;QACxF,mEAAmE;QACnE,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAyB;YACjD,IAAI,EAAE,MAAM;YACZ,GAAG,KAAK;YACR,GAAG;YACH,QAAQ;SACT,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAC9B,IAAI,KAAK,CACP,EAAE,EACF;YACE,GAAG,CAAC,EAAE,EAAE,IAAI;gBACV,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,KAAK,QAAQ;oBAAE,OAAO,SAAS,CAAC;gBAClE,sFAAsF;gBACtF,4DAA4D;gBAC5D,IAAI,IAAI,KAAK,OAAO;oBAClB,OAAO,CAAC,GAAY,EAAE,IAAa,EAAE,GAAyB,EAAE,EAAE,CAChE,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC5C,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;oBAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAyB,CAAC;oBAC9C,IAAI,CAAC,GAAG,EAAE,CAAC;oBACX,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5E,CAAC,CAAC;YACJ,CAAC;SACF,CACF,CAAC;QACJ,MAAM,MAAM,GAAqC,MAAM,CAAC,WAAW,CACjE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAChD,CAAC;QACF,6EAA6E;QAC7E,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAiB,EAAiB,EAAE,CAAC,CAAC;YACxD,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC;YAC3D,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAC9B,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YACxE,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;YACjF,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;YAC/E,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CACjC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;SAC5E,CAAC,CAAC;QACH,OAAO,MAAiC,CAAC;IAC3C,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QACzB,KAAK;YACH,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;YAC7B,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjB,yEAAyE;YACzE,OAAO,OAAO,CAAC,GAAG,CAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;gBAC3B,IAAI,KAAgD,CAAC;gBACrD,MAAM,OAAO,CAAC,IAAI,CAAC;oBACjB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;oBAClC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;wBAChB,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;oBAC/B,CAAC,CAAC;iBACH,CAAC,CAAC;gBACH,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,CAAC,CAAC,CACH,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACnB,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n type LogSink,\n type ModuleLoader,\n outboundFetch,\n type WorkerCode,\n} from \"../bindings/worker-loader.js\";\nimport { ISOLATED, type IsolatedClass } from \"../core/handles.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport { hostPort, type PortLike } from \"./protocol.js\";\n\n/**\n * Worker Loader whose code runs in a separate realm per loaded Worker (an isolate). Returns\n * a module facade: each export is an object whose `fetch()` and methods cross the port.\n * Durable Object classes cannot cross (their storage API is synchronous): use an in-realm\n * loader for `getDurableObjectClass` (see `workerLoader(load, { classes })`).\n */\nexport function isolatedModuleLoader(opts: {\n /**\n * The host's storage, so facets of loaded code are logged and restored like the root's\n * own (celld: one stream per facet under the root, the root's epoch).\n */\n storage?: () => CellStorage | undefined;\n spawn(id: string): { port: PortLike; terminate(): void };\n prepare(id: string, code: WorkerCode): Promise<{ source?: string; url?: string }>;\n}): IsolatedModuleLoader {\n // Every isolate this loader started: `close()` ends them (a project runtime's close does).\n const isolates = new Set<{ terminate(): void; goAway?(): Promise<unknown> }>();\n const load = async (id: string, code: WorkerCode, logs?: LogSink) => {\n // The env crosses as any call does: bindings and other stubs by reference.\n const env: Record<string, unknown> = { ...code.env };\n // The loaded code's global fetch(): blocked in the isolate, or sent back here to the Fetcher.\n const fetcher = outboundFetch(code);\n const outbound = code.globalOutbound === null ? \"blocked\" : fetcher ? \"fetcher\" : undefined;\n const where = await opts.prepare(id, code);\n const isolate = opts.spawn(id);\n const running: { terminate(): void; goAway?(): Promise<unknown> } = {\n terminate: () => isolate.terminate(),\n };\n isolates.add(running);\n const { call, fetch } = await hostPort(\n isolate.port,\n async (m) => {\n if (m.type === \"durable\") {\n const st = opts.storage?.() ?? {};\n if (m.op === \"load\") return st.backup?.load?.(m.cellKey);\n if (m.op === \"committed\" && st.durability) {\n const info = m.info;\n const token = info.image;\n await st.durability.committed(m.cellKey, {\n ...info,\n image:\n typeof token === \"number\"\n ? () => call<Uint8Array | undefined>({ type: \"image\", token })\n : token,\n });\n }\n return;\n }\n if (m.type === \"log\") {\n logs?.(m.level, m.args);\n (console as any)[m.level](...m.args);\n }\n },\n fetcher,\n );\n // Before it ends, the isolate tells its sockets' clients it is going away (1001): their\n // frames go straight to the isolate (protocol.ts), so only it can.\n running.goAway = () => call({ type: \"goAway\" });\n const exports = await call<Record<string, string>>({\n type: \"load\",\n ...where,\n env,\n outbound,\n });\n const facade = (name: string) =>\n new Proxy(\n {},\n {\n get(_t, prop) {\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n // Called as a plain-object entrypoint (entrypointStub): `ctx` comes last, after `env`\n // (the isolate has its own); its props cross with the call.\n if (prop === \"fetch\")\n return (req: Request, _env: unknown, ctx?: { props?: unknown }) =>\n fetch({ name, props: ctx?.props }, req);\n return (...args: unknown[]) => {\n const ctx = args.pop() as { props?: unknown };\n args.pop();\n return call({ type: \"call\", name, method: prop, args, props: ctx.props });\n };\n },\n },\n );\n const module: Record<string | symbol, unknown> = Object.fromEntries(\n Object.keys(exports).map((k) => [k, facade(k)]),\n );\n // Durable Object classes of the loaded code run in the isolate too (facets).\n module[ISOLATED] = (className: string): IsolatedClass => ({\n fetch: (cellKey, req) => fetch({ className, cellKey }, req),\n call: (cellKey, method, args) =>\n call({ type: \"object\", op: \"call\", className, cellKey, method, args }),\n restart: (cellKey) => call({ type: \"object\", op: \"restart\", className, cellKey }),\n delete: (cellKey) => call({ type: \"object\", op: \"delete\", className, cellKey }),\n attach: (cellKey, epoch, idName) =>\n call({ type: \"object\", op: \"attach\", className, cellKey, epoch, idName }),\n });\n return module as Record<string, unknown>;\n };\n return Object.assign(load, {\n close(): Promise<void> {\n const ending = [...isolates];\n isolates.clear();\n // Each isolate closes its sockets (1001), within a second; then it ends.\n return Promise.all(\n ending.map(async (isolate) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n isolate.goAway?.().catch(() => {}),\n new Promise((r) => {\n timer = setTimeout(r, 1_000);\n }),\n ]);\n clearTimeout(timer);\n isolate.terminate();\n }),\n ).then(() => {});\n },\n });\n}\n\n/** A Worker Loader's module loader whose isolates end with `close()`. */\nexport type IsolatedModuleLoader = ModuleLoader & { close(): Promise<void> };\n"]}
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/isolate/host.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type LogSink,\n type ModuleLoader,\n outboundFetch,\n type WorkerCode,\n} from \"../bindings/worker-loader.js\";\nimport { ISOLATED, type IsolatedClass, ON_ABORT } from \"../core/handles.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport { hostPort, type PortLike } from \"./protocol.js\";\n\n/**\n * Worker Loader whose code runs in a separate realm per loaded Worker (an isolate). Returns\n * a module facade: each export is an object whose `fetch()` and methods cross the port.\n * Durable Object classes cannot cross (their storage API is synchronous): use an in-realm\n * loader for `getDurableObjectClass` (see `workerLoader(load, { classes })`).\n */\nexport function isolatedModuleLoader(opts: {\n /**\n * The host's storage, so facets of loaded code are logged and restored like the root's\n * own (celld: one stream per facet under the root, the root's epoch).\n */\n storage?: () => CellStorage | undefined;\n spawn(id: string): { port: PortLike; terminate(): void };\n prepare(id: string, code: WorkerCode): Promise<{ source?: string; url?: string }>;\n}): IsolatedModuleLoader {\n // Every isolate this loader started: `close()` ends them (a project runtime's close does).\n const isolates = new Set<{ terminate(): void; goAway?(): Promise<unknown> }>();\n const load = async (id: string, code: WorkerCode, logs?: LogSink) => {\n // The env crosses as any call does: bindings and other stubs by reference.\n const env: Record<string, unknown> = { ...code.env };\n // The loaded code's global fetch(): blocked in the isolate, or sent back here to the Fetcher.\n const fetcher = outboundFetch(code);\n const outbound = code.globalOutbound === null ? \"blocked\" : fetcher ? \"fetcher\" : undefined;\n const where = await opts.prepare(id, code);\n const isolate = opts.spawn(id);\n const running: { terminate(): void; goAway?(): Promise<unknown> } = {\n terminate: () => isolate.terminate(),\n };\n isolates.add(running);\n const onAbort: (() => void)[] = [];\n let aborted = false;\n // The loaded code called `abortIsolate()`: calls in flight and later ones reject with\n // workerd's error, the isolate ends, and the loader forgets this module.\n const abort = (m: { reason: string; reference: string }) => {\n if (!isolates.delete(running)) return;\n aborted = true;\n console.error(`cellb: loaded Worker \"${id}\" aborted its isolate: ${m.reason}`);\n void close(new Error(`internal error; reference = ${m.reference}`)).finally(() =>\n isolate.terminate(),\n );\n for (const f of onAbort.splice(0)) f();\n };\n const { call, fetch, close } = await hostPort(\n isolate.port,\n async (m) => {\n if (m.type === \"abort\") return abort(m);\n if (m.type === \"durable\") {\n const st = opts.storage?.() ?? {};\n if (m.op === \"load\") return st.backup?.load?.(m.cellKey);\n if (m.op === \"committed\" && st.durability) {\n const info = m.info;\n const token = info.image;\n await st.durability.committed(m.cellKey, {\n ...info,\n image:\n typeof token === \"number\"\n ? () => call<Uint8Array | undefined>({ type: \"image\", token })\n : token,\n });\n }\n return;\n }\n if (m.type === \"log\") {\n logs?.(m.level, m.args);\n (console as any)[m.level](...m.args);\n }\n },\n fetcher,\n );\n // Before it ends, the isolate tells its sockets' clients it is going away (1001): their\n // frames go straight to the isolate (protocol.ts), so only it can.\n running.goAway = () => call({ type: \"goAway\" });\n const exports = await call<Record<string, string>>({\n type: \"load\",\n ...where,\n env,\n outbound,\n });\n const facade = (name: string) =>\n new Proxy(\n {},\n {\n get(_t, prop) {\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n // Called as a plain-object entrypoint (entrypointStub): `ctx` comes last, after `env`\n // (the isolate has its own); its props cross with the call.\n if (prop === \"fetch\")\n return (req: Request, _env: unknown, ctx?: { props?: unknown }) =>\n fetch({ name, props: ctx?.props }, req);\n return (...args: unknown[]) => {\n const ctx = args.pop() as { props?: unknown };\n args.pop();\n return call({ type: \"call\", name, method: prop, args, props: ctx.props });\n };\n },\n },\n );\n const module: Record<string | symbol, unknown> = Object.fromEntries(\n Object.keys(exports).map((k) => [k, facade(k)]),\n );\n // Durable Object classes of the loaded code run in the isolate too (facets).\n module[ISOLATED] = (className: string): IsolatedClass => ({\n fetch: (cellKey, req) => fetch({ className, cellKey }, req),\n call: (cellKey, method, args) =>\n call({ type: \"object\", op: \"call\", className, cellKey, method, args }),\n restart: (cellKey) => call({ type: \"object\", op: \"restart\", className, cellKey }),\n delete: (cellKey) => call({ type: \"object\", op: \"delete\", className, cellKey }),\n attach: (cellKey, epoch, idName) =>\n call({ type: \"object\", op: \"attach\", className, cellKey, epoch, idName }),\n });\n // Registered after the load: an isolate that ended while its code was evaluated is forgotten\n // at once.\n module[ON_ABORT] = (f: () => void) => (aborted ? f() : onAbort.push(f));\n return module as Record<string, unknown>;\n };\n return Object.assign(load, {\n close(): Promise<void> {\n const ending = [...isolates];\n isolates.clear();\n // Each isolate closes its sockets (1001), within a second; then it ends.\n return Promise.all(\n ending.map(async (isolate) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n isolate.goAway?.().catch(() => {}),\n new Promise((r) => {\n timer = setTimeout(r, 1_000);\n }),\n ]);\n clearTimeout(timer);\n isolate.terminate();\n }),\n ).then(() => {});\n },\n });\n}\n\n/** A Worker Loader's module loader whose isolates end with `close()`. */\nexport type IsolatedModuleLoader = ModuleLoader & { close(): Promise<void> };\n"]}
|
|
@@ -9,6 +9,15 @@ import { workersHostRegistry } from "../project/site-loader.js";
|
|
|
9
9
|
import { realmWorkerScope } from "../project/worker-scope.js";
|
|
10
10
|
import * as workersGlobals from "../project/workers-globals-module.js";
|
|
11
11
|
import { serveIsolate } from "./isolate.js";
|
|
12
|
+
import { makeGlobalsWritable } from "./writable-globals.js";
|
|
13
|
+
// The channel to the host, from this worker's own methods, taken before the loaded code runs:
|
|
14
|
+
// Worker code may define a global `postMessage` (Kitesurf's window emulation does), and a port
|
|
15
|
+
// that looked `self.postMessage` up on each send would then post into it.
|
|
16
|
+
const hostChannel = {
|
|
17
|
+
postMessage: self.postMessage.bind(self),
|
|
18
|
+
addEventListener: self.addEventListener.bind(self),
|
|
19
|
+
removeEventListener: self.removeEventListener.bind(self),
|
|
20
|
+
};
|
|
12
21
|
globalThis.__cellsWorkersModule = workersModule;
|
|
13
22
|
// The loaded Worker's own `env` and `exports` (serveIsolate binds the realm's scope to them).
|
|
14
23
|
const scope = realmWorkerScope();
|
|
@@ -24,6 +33,9 @@ workersHostRegistry({
|
|
|
24
33
|
Request: workersGlobals.CellsRequest,
|
|
25
34
|
Response: workersGlobals.CellsResponse,
|
|
26
35
|
});
|
|
36
|
+
// workerd lets Worker code assign its globals (Kitesurf's DOM shim sets `navigator` and
|
|
37
|
+
// `location`); this realm's getter-only ones become writable (writable-globals.ts).
|
|
38
|
+
makeGlobalsWritable();
|
|
27
39
|
// This worker is the loaded Worker's realm: its globals are the Workers ones (as on Node,
|
|
28
40
|
// src/isolate/node-entry.ts). Loaded code reads them as free names (partyserver builds its
|
|
29
41
|
// `new WebSocketPair()` and its 101 `Response` that way).
|
|
@@ -36,7 +48,7 @@ Object.assign(globalThis, {
|
|
|
36
48
|
});
|
|
37
49
|
// The global console is left alone (the dev server's client logs here too): loaded modules
|
|
38
50
|
// get a console of their own that reports to the host.
|
|
39
|
-
serveIsolate(
|
|
51
|
+
serveIsolate(hostChannel, async (load, logs) => {
|
|
40
52
|
const own = Object.assign(Object.create(console), {
|
|
41
53
|
log: (...a) => logs("log", a),
|
|
42
54
|
info: (...a) => logs("info", a),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isolate-worker.js","sourceRoot":"","sources":["../../src/isolate/isolate-worker.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,iFAAiF;AAEjF,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACjG,OAAO,KAAK,WAAW,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,aAAa,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,cAAc,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"isolate-worker.js","sourceRoot":"","sources":["../../src/isolate/isolate-worker.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference lib=\"webworker\" />\n// One loaded Worker in its own realm (a Dedicated Worker), served over its port.\n\nimport sqlite3InitModule from \"@sqlite.org/sqlite-wasm\";\nimport { sahpoolOpener } from \"../adapters/wasm-sqlite.js\";\nimport { browserModuleLoader, PROJECT_WORKERS_MODULE_SHIM } from \"../project/browser-modules.js\";\nimport * as emailModule from \"../project/cloudflare-email.js\";\nimport * as workersModule from \"../project/cloudflare-workers.js\";\nimport { workersHostRegistry } from \"../project/site-loader.js\";\nimport { realmWorkerScope } from \"../project/worker-scope.js\";\nimport * as workersGlobals from \"../project/workers-globals-module.js\";\nimport { serveIsolate } from \"./isolate.js\";\nimport type { PortLike } from \"./protocol.js\";\nimport { makeGlobalsWritable } from \"./writable-globals.js\";\n\n// The channel to the host, from this worker's own methods, taken before the loaded code runs:\n// Worker code may define a global `postMessage` (Kitesurf's window emulation does), and a port\n// that looked `self.postMessage` up on each send would then post into it.\nconst hostChannel: PortLike = {\n postMessage: self.postMessage.bind(self) as PortLike[\"postMessage\"],\n addEventListener: self.addEventListener.bind(self) as PortLike[\"addEventListener\"],\n removeEventListener: self.removeEventListener.bind(self) as PortLike[\"removeEventListener\"],\n};\n\n(globalThis as Record<string, unknown>).__cellsWorkersModule = workersModule;\n// The loaded Worker's own `env` and `exports` (serveIsolate binds the realm's scope to them).\nconst scope = realmWorkerScope();\nworkersHostRegistry({\n workersModule: {\n ...workersModule,\n env: scope.env,\n exports: scope.exports,\n waitUntil: scope.waitUntil,\n },\n emailModule,\n ...workersGlobals,\n Request: workersGlobals.CellsRequest,\n Response: workersGlobals.CellsResponse,\n});\n\n// workerd lets Worker code assign its globals (Kitesurf's DOM shim sets `navigator` and\n// `location`); this realm's getter-only ones become writable (writable-globals.ts).\nmakeGlobalsWritable();\n\n// This worker is the loaded Worker's realm: its globals are the Workers ones (as on Node,\n// src/isolate/node-entry.ts). Loaded code reads them as free names (partyserver builds its\n// `new WebSocketPair()` and its 101 `Response` that way).\nObject.assign(globalThis, {\n Request: workersGlobals.CellsRequest,\n Response: workersGlobals.CellsResponse,\n WebSocket: workersGlobals.WebSocket,\n WebSocketPair: workersGlobals.WebSocketPair,\n WebSocketRequestResponsePair: workersGlobals.WebSocketRequestResponsePair,\n});\n\n// The global console is left alone (the dev server's client logs here too): loaded modules\n// get a console of their own that reports to the host.\nserveIsolate(\n hostChannel,\n async (load: any, logs) => {\n const own = Object.assign(Object.create(console), {\n log: (...a: unknown[]) => logs(\"log\", a),\n info: (...a: unknown[]) => logs(\"info\", a),\n warn: (...a: unknown[]) => logs(\"warn\", a),\n error: (...a: unknown[]) => logs(\"error\", a),\n debug: (...a: unknown[]) => logs(\"debug\", a),\n });\n if (load.url) {\n // The site's per-id module server binds `console` to __cellsLoadedConsoles[id].\n const g = globalThis as Record<string, any>;\n g.__cellsLoadedConsoles ??= {};\n g.__cellsLoadedConsoles[load.consoleId] = own;\n return (await import(/* @vite-ignore */ load.url)) as Record<string, unknown>;\n }\n return browserModuleLoader(PROJECT_WORKERS_MODULE_SHIM)(\n \"isolate\",\n { mainModule: load.mainModule, modules: load.modules },\n (level, args) => logs(level, args),\n );\n },\n {\n patchConsole: false,\n // Facets of the loaded code: SQLite on OPFS, one sahpool per loaded Worker.\n openSql: async (load: any) => {\n const sqlite3 = await (sqlite3InitModule as any)({ print() {}, printErr() {} });\n return sahpoolOpener(sqlite3, { name: load?.storageName ?? \"isolate\" });\n },\n },\n);\n"]}
|
package/dist/isolate/isolate.js
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
* The isolate side: loads the Worker code in THIS realm and serves fetch/RPC for the host.
|
|
3
3
|
* `importCode` is realm specific (data: URL of a bundle on Node, a site URL in browsers).
|
|
4
4
|
*/
|
|
5
|
+
import { registerWasmModules } from "../bindings/worker-loader.js";
|
|
5
6
|
import { ctxExports, entrypointStub } from "../core/handles.js";
|
|
6
7
|
import { runInDurableObject } from "../core/namespace.js";
|
|
7
8
|
import { createCellRuntime } from "../core/runtime.js";
|
|
9
|
+
import { ABORT_ISOLATE } from "../project/cloudflare-workers.js";
|
|
8
10
|
import { realmWorkerScope } from "../project/worker-scope.js";
|
|
9
11
|
import { CfWebSocket } from "../ws/server.js";
|
|
10
12
|
import { isolatePort } from "./protocol.js";
|
|
@@ -139,6 +141,8 @@ export function serveIsolate(port, importCode, opts = {}) {
|
|
|
139
141
|
globalThis.fetch = (async () => {
|
|
140
142
|
throw new Error("This worker is not permitted to access the internet via global functions like fetch(). It must use capabilities (such as bindings in 'env') to talk to the outside world.");
|
|
141
143
|
});
|
|
144
|
+
if (m.wasm)
|
|
145
|
+
registerWasmModules(m.wasm); // compiled by the host (Node: wasmModulesOf)
|
|
142
146
|
scope.bind({ env, exports }); // read while the module is evaluated
|
|
143
147
|
module = await importCode(m, sink);
|
|
144
148
|
exports = ctxExports(module, env);
|
|
@@ -179,6 +183,13 @@ export function serveIsolate(port, importCode, opts = {}) {
|
|
|
179
183
|
throw new Error(`unknown isolate message ${m.type}`);
|
|
180
184
|
};
|
|
181
185
|
const { call, outbound } = isolatePort(port, handle, fetchTarget);
|
|
186
|
+
// `abortIsolate()`: the host ends this isolate. The caller sees workerd's error: the call that
|
|
187
|
+
// aborted rejects with it, as do the host's calls in flight (the host closes the port with it).
|
|
188
|
+
globalThis[ABORT_ISOLATE] = (reason) => {
|
|
189
|
+
const reference = crypto.randomUUID().replace(/-/g, "").slice(0, 24);
|
|
190
|
+
void call({ type: "abort", reason: String(reason ?? ""), reference }).catch(() => { });
|
|
191
|
+
throw new Error(`internal error; reference = ${reference}`);
|
|
192
|
+
};
|
|
182
193
|
}
|
|
183
194
|
const safe = (args) => args.map((a) => {
|
|
184
195
|
try {
|