@statewalker/cellb 0.8.1 → 0.8.5

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.
@@ -1,4 +1,5 @@
1
1
  import { serialize } from "../v8/serialize.js";
2
+ import { nativeAsyncContext } from "./async-context.js";
2
3
  import { CELLD_SCHEMA } from "./celld-schema.js";
3
4
  /** `EXPORT` of core/handles.ts, by its registered name: importing handles.ts here is a cycle. */
4
5
  const EXPORT = Symbol.for("cellb.export");
@@ -210,18 +211,41 @@ export class DurableObjectStorage extends AsyncKvApi {
210
211
  transactionSync(fn) {
211
212
  return this.sql.transactionSync(fn);
212
213
  }
214
+ /** The last async transaction() queued: each one starts once the one before has settled. */
215
+ #transactions = Promise.resolve();
213
216
  /**
214
217
  * Async transaction spanning awaits: the input gate stays closed (no other
215
218
  * event can interleave writes into the savepoint) and auto-commit is held.
219
+ *
220
+ * Transactions of one object run one after another, as on workerd. The gate alone does not
221
+ * order them: events already past it (Miniflare's D1 object awaits each request's body
222
+ * first) opened their savepoints into each other, and one's rollback undid the other's
223
+ * writes.
224
+ *
225
+ * A transaction() awaited inside another's closure nests, as on workerd, and runs at once on
226
+ * a savepoint of its own. Telling it apart from another event's call needs async context
227
+ * (AsyncLocalStorage on Node, or the engine's AsyncContext); without it, such a call waits
228
+ * for its parent forever: use the `txn` argument there.
216
229
  */
230
+ #txnScope = txnScope();
231
+ #txnDepth = 0;
217
232
  transaction(closure) {
233
+ if (this.#txnScope?.get() === this)
234
+ return this.#transaction(closure);
235
+ const run = () => this.#transaction(closure);
236
+ const result = this.#transactions.then(run, run);
237
+ this.#transactions = result.catch(() => { });
238
+ return result;
239
+ }
240
+ #transaction(closure) {
218
241
  return this.gate.runClosed(async () => {
219
242
  const release = this.sql.hold();
220
- const sp = "_cf_atx";
243
+ const sp = `_cf_atx${++this.#txnDepth}`;
221
244
  this.sql.internalExec(`SAVEPOINT ${sp}`);
222
245
  const txn = new DurableObjectTransaction(this.kv, this.gate);
223
246
  try {
224
- const r = await closure(txn);
247
+ const scope = this.#txnScope;
248
+ const r = await (scope ? scope.run(this, () => closure(txn)) : closure(txn));
225
249
  if (txn.rolledBack)
226
250
  this.#rollbackTo(sp);
227
251
  else
@@ -233,6 +257,7 @@ export class DurableObjectStorage extends AsyncKvApi {
233
257
  throw e;
234
258
  }
235
259
  finally {
260
+ this.#txnDepth--;
236
261
  release();
237
262
  }
238
263
  });
@@ -348,4 +373,18 @@ export class DurableObjectStorage extends AsyncKvApi {
348
373
  this.onAlarmChange(null);
349
374
  }
350
375
  }
376
+ /** An async-context slot marking "inside this storage's transaction", where the platform has one. */
377
+ function txnScope() {
378
+ const hooks = globalThis.process?.getBuiltinModule?.("node:async_hooks");
379
+ if (hooks?.AsyncLocalStorage) {
380
+ const als = new hooks.AsyncLocalStorage();
381
+ return { get: () => als.getStore(), run: (v, fn) => als.run(v, fn) };
382
+ }
383
+ const native = nativeAsyncContext();
384
+ if (native) {
385
+ const v = new native.Variable({ name: "cellb.storage.transaction" });
386
+ return { get: () => v.get(), run: (value, fn) => v.run(value, fn) };
387
+ }
388
+ return undefined;
389
+ }
351
390
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ValueCodec } from \"../ports.js\";\nimport { serialize } from \"../v8/serialize.js\";\nimport { CELLD_SCHEMA } from \"./celld-schema.js\";\nimport type { InputGate } from \"./gates.js\";\nimport type { SqlStorage } from \"./sql-storage.js\";\n\nexport interface ListOptions {\n start?: string;\n startAfter?: string;\n end?: string;\n prefix?: string;\n reverse?: boolean;\n limit?: number;\n}\n\n/** `EXPORT` of core/handles.ts, by its registered name: importing handles.ts here is a cycle. */\nconst EXPORT = Symbol.for(\"cellb.export\");\nconst withoutStoredStubs = (v: unknown): unknown =>\n v && typeof v === \"object\" && (v as Record<symbol, unknown>)[EXPORT]\n ? null\n : Array.isArray(v)\n ? v.map(withoutStoredStubs)\n : v && Object.getPrototypeOf(v) === Object.prototype\n ? Object.fromEntries(Object.entries(v).map(([k, x]) => [k, withoutStoredStubs(x)]))\n : v;\n\n/**\n * Synchronous KV API of SQLite-backed objects (`ctx.storage.kv`), stored as celld stores it:\n * `_cf_KV(scope, k, v)` with the cell's scope and V8-serialized values (celld-schema.ts).\n */\nexport class SyncKvStorage {\n #sql: SqlStorage;\n #codec: ValueCodec;\n #ready = false;\n readonly scope: string;\n /** The name the object was addressed by: recorded as celld's _cf_METADATA.actor_name. */\n actorName: string | undefined;\n\n constructor(sql: SqlStorage, codec: ValueCodec, scope = \"\") {\n this.#sql = sql;\n this.#codec = codec;\n this.scope = scope;\n sql.rolledBack.add(() => {\n this.#ready = false; // the table may have been created inside the rolled-back transaction\n });\n }\n #init(): void {\n if (this.#ready) return;\n for (const ddl of CELLD_SCHEMA) this.#sql.internalExec(ddl);\n if (this.actorName !== undefined)\n this.#sql.internalExec(\n \"INSERT OR IGNORE INTO _cf_METADATA (scope, actor_name) VALUES (?, ?)\",\n [this.scope, this.actorName],\n );\n this.#ready = true;\n }\n get<T = unknown>(key: string): T | undefined {\n this.#init();\n const r = this.#sql.internalExec(\"SELECT v FROM _cf_KV WHERE scope = ? AND k = ?\", [\n this.scope,\n key,\n ]);\n if (!r.rows.length) return undefined;\n return this.#codec.decode(new Uint8Array(r.rows[0][0] as ArrayBuffer)) as T;\n }\n put(key: string, value: unknown): void {\n this.#init();\n // As celld: `undefined` is a storable value; what structured clone refuses is a TypeError.\n // ctx.exports.X({ props }) stubs are left to the codec, which stores them (workerd).\n try {\n structuredClone(withoutStoredStubs(value));\n } catch (e) {\n // Worded as V8 (workerd, celld) words it, by cellb's V8 serializer: SpiderMonkey says\n // \"Function object could not be cloned.\" for V8's \"() => 1 could not be cloned.\".\n try {\n serialize(withoutStoredStubs(value));\n } catch (v8) {\n throw new TypeError((v8 as Error).message);\n }\n // Browsers prefix the engine message (\"Failed to execute 'structuredClone' on …: \").\n throw new TypeError(\n (e as Error).message.replace(/^Failed to execute '[^']+' on '[^']+': /, \"\"),\n );\n }\n this.#sql.internalExec(\"INSERT OR REPLACE INTO _cf_KV (scope, k, v) VALUES (?, ?, ?)\", [\n this.scope,\n key,\n this.#codec.encode(value),\n ]);\n }\n delete(key: string): boolean {\n this.#init();\n return (\n this.#sql.internalExec(\"DELETE FROM _cf_KV WHERE scope = ? AND k = ?\", [this.scope, key])\n .rowsWritten > 0\n );\n }\n /**\n * Only one list() iterator is live at a time, as in workerd: a new call invalidates the\n * previous one, which throws on its next step.\n */\n list<T = unknown>(opts: ListOptions = {}): IterableIterator<[string, T]> {\n const generation = ++this.#listGeneration;\n const live = () => {\n if (generation !== this.#listGeneration)\n throw new Error(\n \"kv.list() iterator was invalidated because a new call to kv.list() was started. \" +\n \"Only one kv.list() iterator can exist at a time.\",\n );\n };\n const rows = this.#rows<T>(opts);\n return (function* () {\n live();\n for (const row of rows) {\n yield row;\n live();\n }\n })();\n }\n #listGeneration = 0;\n *#rows<T>(opts: ListOptions): IterableIterator<[string, T]> {\n this.#init();\n const where: string[] = [\"scope = ?\"];\n const params: unknown[] = [this.scope];\n if (opts.start !== undefined) where.push(\"k >= ?\"), params.push(opts.start);\n if (opts.startAfter !== undefined) where.push(\"k > ?\"), params.push(opts.startAfter);\n if (opts.end !== undefined) where.push(\"k < ?\"), params.push(opts.end);\n if (opts.prefix !== undefined)\n where.push(\"substr(k, 1, ?) = ?\"), params.push(opts.prefix.length, opts.prefix);\n let q = \"SELECT k, v FROM _cf_KV\";\n q += ` WHERE ${where.join(\" AND \")}`;\n q += ` ORDER BY k ${opts.reverse ? \"DESC\" : \"ASC\"}`;\n if (opts.limit !== undefined) (q += \" LIMIT ?\"), params.push(opts.limit);\n for (const [k, v] of this.#sql.internalExec(q, params).rows)\n yield [k as string, this.#codec.decode(new Uint8Array(v as ArrayBuffer)) as T];\n }\n deleteAll(): void {\n this.#init();\n this.#sql.internalExec(\"DELETE FROM _cf_KV WHERE scope = ?\", [this.scope]);\n }\n}\n\n/** Methods shared by `ctx.storage` and the `txn` object of `transaction()`. */\nexport class AsyncKvApi {\n protected kv: SyncKvStorage;\n protected gate: InputGate;\n constructor(kv: SyncKvStorage, gate: InputGate) {\n this.kv = kv;\n this.gate = gate;\n }\n /** Every async storage op closes the input gate until it (and its continuation) completes. */\n protected op<T>(fn: () => T): Promise<T> {\n return this.gate.runClosed(async () => {\n await Promise.resolve();\n return fn();\n });\n }\n get<T = unknown>(key: string): Promise<T | undefined>;\n get<T = unknown>(keys: string[]): Promise<Map<string, T>>;\n get(keyOrKeys: string | string[]): Promise<unknown> {\n return this.op(() => {\n if (!Array.isArray(keyOrKeys)) return this.kv.get(keyOrKeys);\n checkKeys(keyOrKeys);\n const m = new Map<string, unknown>();\n for (const k of [...keyOrKeys].sort()) {\n const v = this.kv.get(k);\n if (v !== undefined) m.set(k, v);\n }\n return m;\n });\n }\n put(key: string, value: unknown): Promise<void>;\n put(entries: Record<string, unknown>): Promise<void>;\n put(keyOrEntries: string | Record<string, unknown>, value?: unknown): Promise<void> {\n return this.op(() => {\n if (typeof keyOrEntries === \"string\") return this.kv.put(keyOrEntries, value);\n const entries = Object.entries(keyOrEntries);\n checkKeys(entries.map(([k]) => k));\n for (const [k, v] of entries) this.kv.put(k, v);\n });\n }\n delete(key: string): Promise<boolean>;\n delete(keys: string[]): Promise<number>;\n delete(keyOrKeys: string | string[]): Promise<boolean | number> {\n return this.op(() => {\n if (!Array.isArray(keyOrKeys)) return this.kv.delete(keyOrKeys);\n checkKeys(keyOrKeys);\n return keyOrKeys.filter((k) => this.kv.delete(k)).length;\n });\n }\n list<T = unknown>(opts?: ListOptions): Promise<Map<string, T>> {\n return this.op(() => new Map(this.kv.list<T>(opts)));\n }\n}\n\n// celld sets no limit on the number of keys of one get/put/delete (storage-details).\nfunction checkKeys(_keys: string[]): void {}\n\nexport class DurableObjectTransaction extends AsyncKvApi {\n rolledBack = false;\n rollback(): void {\n this.rolledBack = true;\n }\n}\n\n/** `ctx.storage` of a SQLite-backed Durable Object. */\nexport class DurableObjectStorage extends AsyncKvApi {\n readonly sql: SqlStorage;\n readonly kv: SyncKvStorage;\n #sync: () => Promise<void>;\n\n constructor(sql: SqlStorage, kv: SyncKvStorage, gate: InputGate, sync: () => Promise<void>) {\n super(kv, gate);\n this.sql = sql;\n sql.rolledBack.add(() => {\n this.#metaReady = false;\n });\n this.kv = kv;\n this.#sync = sync;\n }\n deleteAll(): Promise<void> {\n return this.op(() => {\n this.kv.deleteAll();\n // deleteAll() also deletes the alarm, as on Cloudflare, unless `delete_all_preserves_alarm`.\n if (!this.deleteAllPreservesAlarm) this.clearAlarmSync();\n const tables = this.sql.internalExec(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE '\\\\_cf\\\\_%' ESCAPE '\\\\' AND name NOT LIKE 'sqlite\\\\_%' ESCAPE '\\\\'\",\n ).rows;\n for (const [name] of tables)\n this.sql.internalExec(`DROP TABLE IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`);\n });\n }\n transactionSync<T>(fn: () => T): T {\n return this.sql.transactionSync(fn);\n }\n /**\n * Async transaction spanning awaits: the input gate stays closed (no other\n * event can interleave writes into the savepoint) and auto-commit is held.\n */\n transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T> {\n return this.gate.runClosed(async () => {\n const release = this.sql.hold();\n const sp = \"_cf_atx\";\n this.sql.internalExec(`SAVEPOINT ${sp}`);\n const txn = new DurableObjectTransaction(this.kv, this.gate);\n try {\n const r = await closure(txn);\n if (txn.rolledBack) this.#rollbackTo(sp);\n else this.sql.internalExec(`RELEASE ${sp}`);\n return r;\n } catch (e) {\n this.#rollbackTo(sp);\n throw e;\n } finally {\n release();\n }\n });\n }\n #rollbackTo(sp: string): void {\n this.sql.internalExec(`ROLLBACK TO ${sp}`);\n this.sql.internalExec(`RELEASE ${sp}`);\n for (const f of this.sql.rolledBack) f(); // tables created inside may be gone\n }\n /** Resolves once all writes so far are durable (the output gate barrier). */\n sync(): Promise<void> {\n return this.#sync();\n }\n /** `delete_all_preserves_alarm`: deleteAll() leaves the alarm in place. */\n deleteAllPreservesAlarm = false;\n /** celld's harness hands its storage \"scope\" to engine ops; here it is the storage itself. */\n get _scope(): this {\n return this;\n }\n /** Called whenever the stored alarm changes (the runtime schedules it). */\n onAlarmChange: (at: number | null) => void = () => {};\n\n #metaReady = false;\n #meta(): void {\n if (this.#metaReady) return;\n for (const ddl of CELLD_SCHEMA) this.sql.internalExec(ddl);\n if (this.kv.actorName !== undefined)\n this.sql.internalExec(\n \"INSERT OR IGNORE INTO _cf_METADATA (scope, actor_name) VALUES (?, ?)\",\n [this.kv.scope, this.kv.actorName],\n );\n this.#metaReady = true;\n }\n /**\n * The alarm row as celld keeps it (storage.rs): due time, failure counters, and a random\n * generation that changes with every setAlarm() — so a handler's own change is detected.\n */\n alarmRowSync(): { at: number; retry: number; counted: number; generation: string } | null {\n this.#meta();\n const r = this.sql.internalExec(\n // generation is a 64-bit random(): read as text (beyond JS's safe integers)\n \"SELECT at_ms, retry, counted_retry, CAST(generation AS TEXT) FROM _cf_ALARM WHERE scope = ?\",\n [this.kv.scope],\n ).rows[0];\n return r\n ? { at: Number(r[0]), retry: Number(r[1]), counted: Number(r[2]), generation: String(r[3]) }\n : null;\n }\n /** The alarm being handled: getAlarm() reads null until the handler changes the alarm. */\n #active: { generation: string } | undefined;\n beginAlarm(row: { generation: string }): void {\n this.#active = { generation: row.generation };\n }\n /**\n * After the handler (celld's finish_alarm_handler): unless the handler changed the alarm,\n * success deletes it and failure reschedules it with backoff (2 s << min(retry, 6)) —\n * abandoned after 6 counted failures. Returns the alarm now stored.\n */\n finishAlarm(\n fired: { at: number; generation: string },\n succeeded: boolean,\n now: number,\n ): number | null {\n this.#active = undefined;\n const cur = this.alarmRowSync();\n if (!cur || cur.generation !== fired.generation) return cur?.at ?? null;\n if (succeeded) {\n this.sql.internalExec(\"DELETE FROM _cf_ALARM WHERE scope = ? AND at_ms = ?\", [\n this.kv.scope,\n fired.at,\n ]);\n } else if (cur.counted >= 6) {\n this.sql.internalExec(\"DELETE FROM _cf_ALARM WHERE scope = ?\", [this.kv.scope]);\n } else {\n const at = now + 2_000 * 2 ** Math.min(Math.max(cur.retry, 0), 6);\n this.sql.internalExec(\n \"UPDATE _cf_ALARM SET at_ms = ?, retry = retry + 1, counted_retry = counted_retry + 1 WHERE scope = ?\",\n [at, this.kv.scope],\n );\n }\n const after = this.alarmRowSync()?.at ?? null;\n this.onAlarmChange(after);\n return after;\n }\n /** Synchronous read of the stored alarm (ms since epoch) or null (null while it is handled). */\n alarmSync(): number | null {\n const row = this.alarmRowSync();\n if (row && this.#active && this.#active.generation === row.generation) return null;\n return row ? row.at : null;\n }\n /** One alarm per object, in celld's `_cf_ALARM` (same transaction as the event's writes). */\n getAlarm(_opts?: unknown): Promise<number | null> {\n return this.op(() => this.alarmSync());\n }\n setAlarm(scheduledTime: number | Date, _opts?: unknown): Promise<void> {\n // As celld: the time is coerced to a number and a non-number becomes 0 (due at once).\n const n = scheduledTime instanceof Date ? scheduledTime.getTime() : Number(scheduledTime);\n const at = Number.isNaN(n) ? 0 : n;\n return this.op(() => {\n this.#meta();\n this.sql.internalExec(\n // celld's statement: counters reset, a new random generation\n \"INSERT INTO _cf_ALARM(scope,at_ms,retry,counted_retry,generation) VALUES(?,?,0,0,random()) ON CONFLICT(scope) DO UPDATE SET at_ms=excluded.at_ms, retry=0, counted_retry=0, generation=random()\",\n [this.kv.scope, at],\n );\n this.onAlarmChange(at);\n });\n }\n /** setAlarm() inside a synchronous transaction (celld's harness ops). */\n setAlarmSync(at: number): void {\n this.#meta();\n this.sql.internalExec(\n \"INSERT INTO _cf_ALARM(scope,at_ms,retry,counted_retry,generation) VALUES(?,?,0,0,random()) ON CONFLICT(scope) DO UPDATE SET at_ms=excluded.at_ms, retry=0, counted_retry=0, generation=random()\",\n [this.kv.scope, at],\n );\n this.onAlarmChange(at);\n }\n deleteAlarm(_opts?: unknown): Promise<void> {\n return this.op(() => this.clearAlarmSync());\n }\n clearAlarmSync(): void {\n this.#meta();\n this.sql.internalExec(\"DELETE FROM _cf_ALARM WHERE scope = ?\", [this.kv.scope]);\n this.onAlarmChange(null);\n }\n}\n"]}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ValueCodec } from \"../ports.js\";\nimport { serialize } from \"../v8/serialize.js\";\nimport { nativeAsyncContext } from \"./async-context.js\";\nimport { CELLD_SCHEMA } from \"./celld-schema.js\";\nimport type { InputGate } from \"./gates.js\";\nimport type { SqlStorage } from \"./sql-storage.js\";\n\nexport interface ListOptions {\n start?: string;\n startAfter?: string;\n end?: string;\n prefix?: string;\n reverse?: boolean;\n limit?: number;\n}\n\n/** `EXPORT` of core/handles.ts, by its registered name: importing handles.ts here is a cycle. */\nconst EXPORT = Symbol.for(\"cellb.export\");\nconst withoutStoredStubs = (v: unknown): unknown =>\n v && typeof v === \"object\" && (v as Record<symbol, unknown>)[EXPORT]\n ? null\n : Array.isArray(v)\n ? v.map(withoutStoredStubs)\n : v && Object.getPrototypeOf(v) === Object.prototype\n ? Object.fromEntries(Object.entries(v).map(([k, x]) => [k, withoutStoredStubs(x)]))\n : v;\n\n/**\n * Synchronous KV API of SQLite-backed objects (`ctx.storage.kv`), stored as celld stores it:\n * `_cf_KV(scope, k, v)` with the cell's scope and V8-serialized values (celld-schema.ts).\n */\nexport class SyncKvStorage {\n #sql: SqlStorage;\n #codec: ValueCodec;\n #ready = false;\n readonly scope: string;\n /** The name the object was addressed by: recorded as celld's _cf_METADATA.actor_name. */\n actorName: string | undefined;\n\n constructor(sql: SqlStorage, codec: ValueCodec, scope = \"\") {\n this.#sql = sql;\n this.#codec = codec;\n this.scope = scope;\n sql.rolledBack.add(() => {\n this.#ready = false; // the table may have been created inside the rolled-back transaction\n });\n }\n #init(): void {\n if (this.#ready) return;\n for (const ddl of CELLD_SCHEMA) this.#sql.internalExec(ddl);\n if (this.actorName !== undefined)\n this.#sql.internalExec(\n \"INSERT OR IGNORE INTO _cf_METADATA (scope, actor_name) VALUES (?, ?)\",\n [this.scope, this.actorName],\n );\n this.#ready = true;\n }\n get<T = unknown>(key: string): T | undefined {\n this.#init();\n const r = this.#sql.internalExec(\"SELECT v FROM _cf_KV WHERE scope = ? AND k = ?\", [\n this.scope,\n key,\n ]);\n if (!r.rows.length) return undefined;\n return this.#codec.decode(new Uint8Array(r.rows[0][0] as ArrayBuffer)) as T;\n }\n put(key: string, value: unknown): void {\n this.#init();\n // As celld: `undefined` is a storable value; what structured clone refuses is a TypeError.\n // ctx.exports.X({ props }) stubs are left to the codec, which stores them (workerd).\n try {\n structuredClone(withoutStoredStubs(value));\n } catch (e) {\n // Worded as V8 (workerd, celld) words it, by cellb's V8 serializer: SpiderMonkey says\n // \"Function object could not be cloned.\" for V8's \"() => 1 could not be cloned.\".\n try {\n serialize(withoutStoredStubs(value));\n } catch (v8) {\n throw new TypeError((v8 as Error).message);\n }\n // Browsers prefix the engine message (\"Failed to execute 'structuredClone' on …: \").\n throw new TypeError(\n (e as Error).message.replace(/^Failed to execute '[^']+' on '[^']+': /, \"\"),\n );\n }\n this.#sql.internalExec(\"INSERT OR REPLACE INTO _cf_KV (scope, k, v) VALUES (?, ?, ?)\", [\n this.scope,\n key,\n this.#codec.encode(value),\n ]);\n }\n delete(key: string): boolean {\n this.#init();\n return (\n this.#sql.internalExec(\"DELETE FROM _cf_KV WHERE scope = ? AND k = ?\", [this.scope, key])\n .rowsWritten > 0\n );\n }\n /**\n * Only one list() iterator is live at a time, as in workerd: a new call invalidates the\n * previous one, which throws on its next step.\n */\n list<T = unknown>(opts: ListOptions = {}): IterableIterator<[string, T]> {\n const generation = ++this.#listGeneration;\n const live = () => {\n if (generation !== this.#listGeneration)\n throw new Error(\n \"kv.list() iterator was invalidated because a new call to kv.list() was started. \" +\n \"Only one kv.list() iterator can exist at a time.\",\n );\n };\n const rows = this.#rows<T>(opts);\n return (function* () {\n live();\n for (const row of rows) {\n yield row;\n live();\n }\n })();\n }\n #listGeneration = 0;\n *#rows<T>(opts: ListOptions): IterableIterator<[string, T]> {\n this.#init();\n const where: string[] = [\"scope = ?\"];\n const params: unknown[] = [this.scope];\n if (opts.start !== undefined) where.push(\"k >= ?\"), params.push(opts.start);\n if (opts.startAfter !== undefined) where.push(\"k > ?\"), params.push(opts.startAfter);\n if (opts.end !== undefined) where.push(\"k < ?\"), params.push(opts.end);\n if (opts.prefix !== undefined)\n where.push(\"substr(k, 1, ?) = ?\"), params.push(opts.prefix.length, opts.prefix);\n let q = \"SELECT k, v FROM _cf_KV\";\n q += ` WHERE ${where.join(\" AND \")}`;\n q += ` ORDER BY k ${opts.reverse ? \"DESC\" : \"ASC\"}`;\n if (opts.limit !== undefined) (q += \" LIMIT ?\"), params.push(opts.limit);\n for (const [k, v] of this.#sql.internalExec(q, params).rows)\n yield [k as string, this.#codec.decode(new Uint8Array(v as ArrayBuffer)) as T];\n }\n deleteAll(): void {\n this.#init();\n this.#sql.internalExec(\"DELETE FROM _cf_KV WHERE scope = ?\", [this.scope]);\n }\n}\n\n/** Methods shared by `ctx.storage` and the `txn` object of `transaction()`. */\nexport class AsyncKvApi {\n protected kv: SyncKvStorage;\n protected gate: InputGate;\n constructor(kv: SyncKvStorage, gate: InputGate) {\n this.kv = kv;\n this.gate = gate;\n }\n /** Every async storage op closes the input gate until it (and its continuation) completes. */\n protected op<T>(fn: () => T): Promise<T> {\n return this.gate.runClosed(async () => {\n await Promise.resolve();\n return fn();\n });\n }\n get<T = unknown>(key: string): Promise<T | undefined>;\n get<T = unknown>(keys: string[]): Promise<Map<string, T>>;\n get(keyOrKeys: string | string[]): Promise<unknown> {\n return this.op(() => {\n if (!Array.isArray(keyOrKeys)) return this.kv.get(keyOrKeys);\n checkKeys(keyOrKeys);\n const m = new Map<string, unknown>();\n for (const k of [...keyOrKeys].sort()) {\n const v = this.kv.get(k);\n if (v !== undefined) m.set(k, v);\n }\n return m;\n });\n }\n put(key: string, value: unknown): Promise<void>;\n put(entries: Record<string, unknown>): Promise<void>;\n put(keyOrEntries: string | Record<string, unknown>, value?: unknown): Promise<void> {\n return this.op(() => {\n if (typeof keyOrEntries === \"string\") return this.kv.put(keyOrEntries, value);\n const entries = Object.entries(keyOrEntries);\n checkKeys(entries.map(([k]) => k));\n for (const [k, v] of entries) this.kv.put(k, v);\n });\n }\n delete(key: string): Promise<boolean>;\n delete(keys: string[]): Promise<number>;\n delete(keyOrKeys: string | string[]): Promise<boolean | number> {\n return this.op(() => {\n if (!Array.isArray(keyOrKeys)) return this.kv.delete(keyOrKeys);\n checkKeys(keyOrKeys);\n return keyOrKeys.filter((k) => this.kv.delete(k)).length;\n });\n }\n list<T = unknown>(opts?: ListOptions): Promise<Map<string, T>> {\n return this.op(() => new Map(this.kv.list<T>(opts)));\n }\n}\n\n// celld sets no limit on the number of keys of one get/put/delete (storage-details).\nfunction checkKeys(_keys: string[]): void {}\n\nexport class DurableObjectTransaction extends AsyncKvApi {\n rolledBack = false;\n rollback(): void {\n this.rolledBack = true;\n }\n}\n\n/** `ctx.storage` of a SQLite-backed Durable Object. */\nexport class DurableObjectStorage extends AsyncKvApi {\n readonly sql: SqlStorage;\n readonly kv: SyncKvStorage;\n #sync: () => Promise<void>;\n\n constructor(sql: SqlStorage, kv: SyncKvStorage, gate: InputGate, sync: () => Promise<void>) {\n super(kv, gate);\n this.sql = sql;\n sql.rolledBack.add(() => {\n this.#metaReady = false;\n });\n this.kv = kv;\n this.#sync = sync;\n }\n deleteAll(): Promise<void> {\n return this.op(() => {\n this.kv.deleteAll();\n // deleteAll() also deletes the alarm, as on Cloudflare, unless `delete_all_preserves_alarm`.\n if (!this.deleteAllPreservesAlarm) this.clearAlarmSync();\n const tables = this.sql.internalExec(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE '\\\\_cf\\\\_%' ESCAPE '\\\\' AND name NOT LIKE 'sqlite\\\\_%' ESCAPE '\\\\'\",\n ).rows;\n for (const [name] of tables)\n this.sql.internalExec(`DROP TABLE IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`);\n });\n }\n transactionSync<T>(fn: () => T): T {\n return this.sql.transactionSync(fn);\n }\n /** The last async transaction() queued: each one starts once the one before has settled. */\n #transactions: Promise<unknown> = Promise.resolve();\n /**\n * Async transaction spanning awaits: the input gate stays closed (no other\n * event can interleave writes into the savepoint) and auto-commit is held.\n *\n * Transactions of one object run one after another, as on workerd. The gate alone does not\n * order them: events already past it (Miniflare's D1 object awaits each request's body\n * first) opened their savepoints into each other, and one's rollback undid the other's\n * writes.\n *\n * A transaction() awaited inside another's closure nests, as on workerd, and runs at once on\n * a savepoint of its own. Telling it apart from another event's call needs async context\n * (AsyncLocalStorage on Node, or the engine's AsyncContext); without it, such a call waits\n * for its parent forever: use the `txn` argument there.\n */\n #txnScope = txnScope();\n #txnDepth = 0;\n transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T> {\n if (this.#txnScope?.get() === this) return this.#transaction(closure);\n const run = () => this.#transaction(closure);\n const result = this.#transactions.then(run, run);\n this.#transactions = result.catch(() => {});\n return result;\n }\n #transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T> {\n return this.gate.runClosed(async () => {\n const release = this.sql.hold();\n const sp = `_cf_atx${++this.#txnDepth}`;\n this.sql.internalExec(`SAVEPOINT ${sp}`);\n const txn = new DurableObjectTransaction(this.kv, this.gate);\n try {\n const scope = this.#txnScope;\n const r = await (scope ? scope.run(this, () => closure(txn)) : closure(txn));\n if (txn.rolledBack) this.#rollbackTo(sp);\n else this.sql.internalExec(`RELEASE ${sp}`);\n return r;\n } catch (e) {\n this.#rollbackTo(sp);\n throw e;\n } finally {\n this.#txnDepth--;\n release();\n }\n });\n }\n #rollbackTo(sp: string): void {\n this.sql.internalExec(`ROLLBACK TO ${sp}`);\n this.sql.internalExec(`RELEASE ${sp}`);\n for (const f of this.sql.rolledBack) f(); // tables created inside may be gone\n }\n /** Resolves once all writes so far are durable (the output gate barrier). */\n sync(): Promise<void> {\n return this.#sync();\n }\n /** `delete_all_preserves_alarm`: deleteAll() leaves the alarm in place. */\n deleteAllPreservesAlarm = false;\n /** celld's harness hands its storage \"scope\" to engine ops; here it is the storage itself. */\n get _scope(): this {\n return this;\n }\n /** Called whenever the stored alarm changes (the runtime schedules it). */\n onAlarmChange: (at: number | null) => void = () => {};\n\n #metaReady = false;\n #meta(): void {\n if (this.#metaReady) return;\n for (const ddl of CELLD_SCHEMA) this.sql.internalExec(ddl);\n if (this.kv.actorName !== undefined)\n this.sql.internalExec(\n \"INSERT OR IGNORE INTO _cf_METADATA (scope, actor_name) VALUES (?, ?)\",\n [this.kv.scope, this.kv.actorName],\n );\n this.#metaReady = true;\n }\n /**\n * The alarm row as celld keeps it (storage.rs): due time, failure counters, and a random\n * generation that changes with every setAlarm() — so a handler's own change is detected.\n */\n alarmRowSync(): { at: number; retry: number; counted: number; generation: string } | null {\n this.#meta();\n const r = this.sql.internalExec(\n // generation is a 64-bit random(): read as text (beyond JS's safe integers)\n \"SELECT at_ms, retry, counted_retry, CAST(generation AS TEXT) FROM _cf_ALARM WHERE scope = ?\",\n [this.kv.scope],\n ).rows[0];\n return r\n ? { at: Number(r[0]), retry: Number(r[1]), counted: Number(r[2]), generation: String(r[3]) }\n : null;\n }\n /** The alarm being handled: getAlarm() reads null until the handler changes the alarm. */\n #active: { generation: string } | undefined;\n beginAlarm(row: { generation: string }): void {\n this.#active = { generation: row.generation };\n }\n /**\n * After the handler (celld's finish_alarm_handler): unless the handler changed the alarm,\n * success deletes it and failure reschedules it with backoff (2 s << min(retry, 6)) —\n * abandoned after 6 counted failures. Returns the alarm now stored.\n */\n finishAlarm(\n fired: { at: number; generation: string },\n succeeded: boolean,\n now: number,\n ): number | null {\n this.#active = undefined;\n const cur = this.alarmRowSync();\n if (!cur || cur.generation !== fired.generation) return cur?.at ?? null;\n if (succeeded) {\n this.sql.internalExec(\"DELETE FROM _cf_ALARM WHERE scope = ? AND at_ms = ?\", [\n this.kv.scope,\n fired.at,\n ]);\n } else if (cur.counted >= 6) {\n this.sql.internalExec(\"DELETE FROM _cf_ALARM WHERE scope = ?\", [this.kv.scope]);\n } else {\n const at = now + 2_000 * 2 ** Math.min(Math.max(cur.retry, 0), 6);\n this.sql.internalExec(\n \"UPDATE _cf_ALARM SET at_ms = ?, retry = retry + 1, counted_retry = counted_retry + 1 WHERE scope = ?\",\n [at, this.kv.scope],\n );\n }\n const after = this.alarmRowSync()?.at ?? null;\n this.onAlarmChange(after);\n return after;\n }\n /** Synchronous read of the stored alarm (ms since epoch) or null (null while it is handled). */\n alarmSync(): number | null {\n const row = this.alarmRowSync();\n if (row && this.#active && this.#active.generation === row.generation) return null;\n return row ? row.at : null;\n }\n /** One alarm per object, in celld's `_cf_ALARM` (same transaction as the event's writes). */\n getAlarm(_opts?: unknown): Promise<number | null> {\n return this.op(() => this.alarmSync());\n }\n setAlarm(scheduledTime: number | Date, _opts?: unknown): Promise<void> {\n // As celld: the time is coerced to a number and a non-number becomes 0 (due at once).\n const n = scheduledTime instanceof Date ? scheduledTime.getTime() : Number(scheduledTime);\n const at = Number.isNaN(n) ? 0 : n;\n return this.op(() => {\n this.#meta();\n this.sql.internalExec(\n // celld's statement: counters reset, a new random generation\n \"INSERT INTO _cf_ALARM(scope,at_ms,retry,counted_retry,generation) VALUES(?,?,0,0,random()) ON CONFLICT(scope) DO UPDATE SET at_ms=excluded.at_ms, retry=0, counted_retry=0, generation=random()\",\n [this.kv.scope, at],\n );\n this.onAlarmChange(at);\n });\n }\n /** setAlarm() inside a synchronous transaction (celld's harness ops). */\n setAlarmSync(at: number): void {\n this.#meta();\n this.sql.internalExec(\n \"INSERT INTO _cf_ALARM(scope,at_ms,retry,counted_retry,generation) VALUES(?,?,0,0,random()) ON CONFLICT(scope) DO UPDATE SET at_ms=excluded.at_ms, retry=0, counted_retry=0, generation=random()\",\n [this.kv.scope, at],\n );\n this.onAlarmChange(at);\n }\n deleteAlarm(_opts?: unknown): Promise<void> {\n return this.op(() => this.clearAlarmSync());\n }\n clearAlarmSync(): void {\n this.#meta();\n this.sql.internalExec(\"DELETE FROM _cf_ALARM WHERE scope = ?\", [this.kv.scope]);\n this.onAlarmChange(null);\n }\n}\n\ninterface TxnScope {\n get(): unknown;\n run<R>(value: unknown, fn: () => R): R;\n}\n\n/** An async-context slot marking \"inside this storage's transaction\", where the platform has one. */\nfunction txnScope(): TxnScope | undefined {\n const hooks = (\n globalThis as { process?: { getBuiltinModule?(id: string): unknown } }\n ).process?.getBuiltinModule?.(\"node:async_hooks\") as\n | {\n AsyncLocalStorage?: new () => {\n getStore(): unknown;\n run<R>(store: unknown, fn: () => R): R;\n };\n }\n | undefined;\n if (hooks?.AsyncLocalStorage) {\n const als = new hooks.AsyncLocalStorage();\n return { get: () => als.getStore(), run: (v, fn) => als.run(v, fn) };\n }\n const native = nativeAsyncContext();\n if (native) {\n const v = new native.Variable<unknown>({ name: \"cellb.storage.transaction\" });\n return { get: () => v.get(), run: (value, fn) => v.run(value, fn) };\n }\n return undefined;\n}\n"]}
@@ -18,6 +18,7 @@ Object.assign(globalThis, {
18
18
  });
19
19
  serveIsolate(parentPort, async ({ source }) => import(`data:text/javascript;base64,${Buffer.from(source ?? "").toString("base64")}`),
20
20
  // Facets of the loaded code keep their SQLite here: files under `dataDir` when the host
21
- // gives one, else in memory (lost with the isolate).
22
- { openSql: (load) => nodeSqliteOpener(load?.dataDir) });
21
+ // gives one, else temporary files (lost with the isolate, as in memory). The isolate logs
22
+ // every commit's pages to its host, so they are read from the WAL, not from an image.
23
+ { openSql: (load) => nodeSqliteOpener(load?.dataDir, { pageCapture: true }) });
23
24
  //# sourceMappingURL=node-entry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-entry.js","sourceRoot":"","sources":["../../src/isolate/node-entry.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EACL,YAAY,EACZ,aAAa,EACb,SAAS,EACT,aAAa,EACb,4BAA4B,GAC7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,8FAA8F;AAC9F,qFAAqF;AACrF,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAErE,8FAA8F;AAC9F,gGAAgG;AAChG,yEAAyE;AACzE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE;IACxB,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,aAAa;IACvB,SAAS;IACT,aAAa;IACb,4BAA4B;CAC7B,CAAC,CAAC;AAEH,YAAY,CACV,UAAiC,EACjC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CACnB,MAAM,CAAC,+BAA+B,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACvF,wFAAwF;AACxF,qDAAqD;AACrD,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CACvD,CAAC","sourcesContent":["// A worker thread hosting ONE loaded Worker (an isolate); see src/isolate/protocol.ts.\nimport { parentPort } from \"node:worker_threads\";\nimport { nodeSqliteOpener } from \"../adapters/node-sqlite.js\";\nimport {\n CellsRequest,\n CellsResponse,\n WebSocket,\n WebSocketPair,\n WebSocketRequestResponsePair,\n} from \"../project/workers-globals-module.js\";\nimport { serveIsolate } from \"./isolate.js\";\nimport type { PortLike } from \"./protocol.js\";\n\n// An exception no request awaits (a timer, ctx.abort() from one) is reported, and the isolate\n// lives on, as in a browser Dedicated Worker and workerd; Node would end the thread.\nprocess.on(\"uncaughtException\", (e) => console.error(\"Uncaught\", e));\n\n// This thread is the loaded Worker's realm: its globals are the Workers ones, as in a browser\n// isolate (src/isolate/isolate-worker.ts). A `Response` that takes `{ status: 101, webSocket }`\n// and a `WebSocketPair` are what a Worker that accepts WebSockets needs.\nObject.assign(globalThis, {\n Request: CellsRequest,\n Response: CellsResponse,\n WebSocket,\n WebSocketPair,\n WebSocketRequestResponsePair,\n});\n\nserveIsolate(\n parentPort as unknown as PortLike,\n async ({ source }) =>\n import(`data:text/javascript;base64,${Buffer.from(source ?? \"\").toString(\"base64\")}`),\n // Facets of the loaded code keep their SQLite here: files under `dataDir` when the host\n // gives one, else in memory (lost with the isolate).\n { openSql: (load) => nodeSqliteOpener(load?.dataDir) },\n);\n"]}
1
+ {"version":3,"file":"node-entry.js","sourceRoot":"","sources":["../../src/isolate/node-entry.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EACL,YAAY,EACZ,aAAa,EACb,SAAS,EACT,aAAa,EACb,4BAA4B,GAC7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,8FAA8F;AAC9F,qFAAqF;AACrF,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAErE,8FAA8F;AAC9F,gGAAgG;AAChG,yEAAyE;AACzE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE;IACxB,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,aAAa;IACvB,SAAS;IACT,aAAa;IACb,4BAA4B;CAC7B,CAAC,CAAC;AAEH,YAAY,CACV,UAAiC,EACjC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CACnB,MAAM,CAAC,+BAA+B,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACvF,wFAAwF;AACxF,0FAA0F;AAC1F,sFAAsF;AACtF,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,CAC9E,CAAC","sourcesContent":["// A worker thread hosting ONE loaded Worker (an isolate); see src/isolate/protocol.ts.\nimport { parentPort } from \"node:worker_threads\";\nimport { nodeSqliteOpener } from \"../adapters/node-sqlite.js\";\nimport {\n CellsRequest,\n CellsResponse,\n WebSocket,\n WebSocketPair,\n WebSocketRequestResponsePair,\n} from \"../project/workers-globals-module.js\";\nimport { serveIsolate } from \"./isolate.js\";\nimport type { PortLike } from \"./protocol.js\";\n\n// An exception no request awaits (a timer, ctx.abort() from one) is reported, and the isolate\n// lives on, as in a browser Dedicated Worker and workerd; Node would end the thread.\nprocess.on(\"uncaughtException\", (e) => console.error(\"Uncaught\", e));\n\n// This thread is the loaded Worker's realm: its globals are the Workers ones, as in a browser\n// isolate (src/isolate/isolate-worker.ts). A `Response` that takes `{ status: 101, webSocket }`\n// and a `WebSocketPair` are what a Worker that accepts WebSockets needs.\nObject.assign(globalThis, {\n Request: CellsRequest,\n Response: CellsResponse,\n WebSocket,\n WebSocketPair,\n WebSocketRequestResponsePair,\n});\n\nserveIsolate(\n parentPort as unknown as PortLike,\n async ({ source }) =>\n import(`data:text/javascript;base64,${Buffer.from(source ?? \"\").toString(\"base64\")}`),\n // Facets of the loaded code keep their SQLite here: files under `dataDir` when the host\n // gives one, else temporary files (lost with the isolate, as in memory). The isolate logs\n // every commit's pages to its host, so they are read from the WAL, not from an image.\n { openSql: (load) => nodeSqliteOpener(load?.dataDir, { pageCapture: true }) },\n);\n"]}
@@ -88,7 +88,11 @@ function nodeHost(options) {
88
88
  else
89
89
  files = new MemFilesApi();
90
90
  return {
91
- openSql: nodeSqliteOpener(options.data ? resolve(options.data) : undefined),
91
+ // A storage that logs pages (a celld bucket: every commit as LTX) gets them from the WAL
92
+ // (O(changed pages)) instead of an image of the whole database diffed per commit.
93
+ openSql: nodeSqliteOpener(options.data ? resolve(options.data) : undefined, {
94
+ pageCapture: !!options.bucket?.durability?.capturePages,
95
+ }),
92
96
  files,
93
97
  storage: options.bucket,
94
98
  ai: options.ai,
@@ -1 +1 @@
1
- {"version":3,"file":"node-load.js","sourceRoot":"","sources":["../../src/project/node-load.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loadProject` on Node (`@statewalker/cellb/node`): one call that reads a project, built or\n * not, and runs it.\n */\nimport { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { FilesApi } from \"@statewalker/webrun-files\";\nimport { MemFilesApi } from \"@statewalker/webrun-files-mem\";\nimport { NodeFilesApi } from \"@statewalker/webrun-files-node\";\nimport { nodeSqliteOpener } from \"../adapters/node-sqlite.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport {\n BUILD_MANIFEST,\n BUILT_WORKER,\n type BuiltProject,\n filesApiReader,\n isFilesApi,\n type LoadedProject,\n type LoadProjectOptions,\n type ProjectReader,\n type ProjectSource,\n readBuildManifest,\n readBuiltProject,\n urlReader,\n} from \"./built-project.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { loadNodeProject, nodeIsolatedLoader, nodeModuleLoader } from \"./node-project.js\";\nimport { workerScope } from \"./worker-scope.js\";\nimport * as workersGlobals from \"./workers-globals-module.js\";\nimport {\n createProjectRuntime,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n populatesProcessEnv,\n processEnvOf,\n} from \"./wrangler.js\";\n\nexport type NodeLoadProjectOptions = LoadProjectOptions<CellStorage>;\n\n/**\n * Loads a project and runs it in this process.\n *\n * `source`: a folder with `wrangler.json(c)` (its `main` bundled with esbuild, as\n * `loadNodeProject` does), a folder written by `cellb build` (its `worker.js` imported as built),\n * an `http(s):` URL of a built folder, or a FilesApi holding either kind of folder.\n *\n * `options.data`: a directory for the cells' SQLite files and the project's files\n * (`<data>/files`); without it, both are in memory.\n */\nexport async function loadProject(\n source: ProjectSource,\n options: NodeLoadProjectOptions = {},\n): Promise<LoadedProject> {\n const host = nodeHost(options);\n const close = async (runtime: { close(): Promise<void> }, cleanup?: () => void) => {\n await runtime.close();\n cleanup?.();\n };\n // A folder on disk: read where it lies.\n const dir = localDir(source);\n if (dir !== undefined) {\n const reader = fsReader(dir);\n const manifest = await readBuildManifest(reader);\n if (manifest) return runBuilt(await readBuiltProject(reader, manifest), host);\n const { runtime, unsupported, config } = await loadNodeProject(dir, host);\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => close(runtime),\n };\n }\n // A FilesApi: a built folder is read from it; a source folder is copied out for esbuild.\n if (isFilesApi(source)) {\n const reader = filesApiReader(source);\n const manifest = await readBuildManifest(reader);\n if (manifest) return runBuilt(await readBuiltProject(reader, manifest), host);\n const tmp = await copyOut(source);\n try {\n const { runtime, unsupported, config } = await loadNodeProject(tmp, host);\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => close(runtime, () => rmSync(tmp, { recursive: true, force: true })),\n };\n } catch (err) {\n rmSync(tmp, { recursive: true, force: true });\n throw err;\n }\n }\n // A URL of a built folder.\n const url = folderUrl(source);\n const reader = urlReader(url);\n const manifest = await readBuildManifest(reader);\n if (!manifest)\n throw new Error(`${url} has no ${BUILD_MANIFEST}: load a folder written by \\`cellb build\\``);\n return runBuilt(await readBuiltProject(reader, manifest), host);\n}\n\n/** What `options` become on Node: SQLite files and a FilesApi under `data`, or memory. */\nfunction nodeHost(options: NodeLoadProjectOptions): Omit<ProjectHost, \"loadModules\"> {\n let files: FilesApi;\n if (options.data) {\n const data = resolve(options.data);\n mkdirSync(join(data, \"files\"), { recursive: true });\n files = new NodeFilesApi({ rootDir: join(data, \"files\") });\n } else files = new MemFilesApi();\n return {\n openSql: nodeSqliteOpener(options.data ? resolve(options.data) : undefined),\n files,\n storage: options.bucket,\n ai: options.ai,\n };\n}\n\n/**\n * Runs a built project on Node: `worker.js` was bundled for a browser realm, so it reads the\n * Workers globals and `cloudflare:workers` from the globals this sets, as in a browser worker.\n * (One such project per process: the globals are the process's.)\n */\nasync function runBuilt(\n built: BuiltProject,\n host: Omit<ProjectHost, \"loadModules\">,\n): Promise<LoadedProject> {\n const { config } = built;\n const flags = config.compatibility_flags ?? [];\n const scope = workerScope(loadTimeEnv(config, host.ai));\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkersModule = workersClasses;\n g.__cellsProjectScope = scope;\n g.__cellsGlobals = {\n ...workersGlobals,\n Request: workersGlobals.CellsRequest,\n Response: workersGlobals.CellsResponse,\n WebSocketPair: flags.includes(\"websocket_standard_binary_type\")\n ? workersGlobals.StandardWebSocketPair\n : workersGlobals.WebSocketPair,\n };\n if (populatesProcessEnv(config)) {\n const env = processEnvOf(config);\n g.__cellsProcessEnv = env;\n for (const [k, v] of Object.entries(env)) process.env[k] ??= v;\n }\n let module: WorkerModule = { default: {} } as WorkerModule;\n if (built.code !== null) {\n const tmp = mkdtempSync(join(tmpdir(), \"cellb-built-\"));\n const file = join(tmp, BUILT_WORKER.replace(/\\.js$/, \".mjs\"));\n writeFileSync(file, built.code);\n try {\n module = (await import(/* @vite-ignore */ pathToFileURL(file).href)) as WorkerModule;\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n }\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles: built.assets,\n ...host,\n });\n scope.bind(project.runtime);\n const { runtime, unsupported } = project;\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => runtime.close(),\n };\n}\n\n/** The folder a source names on this machine: a path or a `file:` URL. */\nfunction localDir(source: ProjectSource): string | undefined {\n if (typeof source === \"string\") {\n if (/^https?:\\/\\//i.test(source)) return undefined;\n return resolve(source.startsWith(\"file:\") ? fileURLToPath(source) : source);\n }\n if (source instanceof URL && source.protocol === \"file:\") return fileURLToPath(source);\n return undefined;\n}\n\nfunction folderUrl(source: ProjectSource): URL {\n const url = new URL(String(source));\n if (!url.pathname.endsWith(\"/\")) url.pathname += \"/\";\n return url;\n}\n\nfunction fsReader(dir: string): ProjectReader {\n return {\n async bytes(path) {\n const full = join(dir, path);\n return existsSync(full) ? new Uint8Array(readFileSync(full)) : undefined;\n },\n };\n}\n\n/** Copies a FilesApi's files into a temporary folder (esbuild bundles from disk). */\nasync function copyOut(files: FilesApi): Promise<string> {\n const tmp = mkdtempSync(join(tmpdir(), \"cellb-project-\"));\n const reader = filesApiReader(files);\n for (const path of (await reader.list?.(\"/\")) ?? []) {\n const out = join(tmp, path);\n mkdirSync(dirname(out), { recursive: true });\n writeFileSync(out, (await reader.bytes(path)) as Uint8Array);\n }\n return tmp;\n}\n"]}
1
+ {"version":3,"file":"node-load.js","sourceRoot":"","sources":["../../src/project/node-load.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loadProject` on Node (`@statewalker/cellb/node`): one call that reads a project, built or\n * not, and runs it.\n */\nimport { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { FilesApi } from \"@statewalker/webrun-files\";\nimport { MemFilesApi } from \"@statewalker/webrun-files-mem\";\nimport { NodeFilesApi } from \"@statewalker/webrun-files-node\";\nimport { nodeSqliteOpener } from \"../adapters/node-sqlite.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport {\n BUILD_MANIFEST,\n BUILT_WORKER,\n type BuiltProject,\n filesApiReader,\n isFilesApi,\n type LoadedProject,\n type LoadProjectOptions,\n type ProjectReader,\n type ProjectSource,\n readBuildManifest,\n readBuiltProject,\n urlReader,\n} from \"./built-project.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { loadNodeProject, nodeIsolatedLoader, nodeModuleLoader } from \"./node-project.js\";\nimport { workerScope } from \"./worker-scope.js\";\nimport * as workersGlobals from \"./workers-globals-module.js\";\nimport {\n createProjectRuntime,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n populatesProcessEnv,\n processEnvOf,\n} from \"./wrangler.js\";\n\nexport type NodeLoadProjectOptions = LoadProjectOptions<CellStorage>;\n\n/**\n * Loads a project and runs it in this process.\n *\n * `source`: a folder with `wrangler.json(c)` (its `main` bundled with esbuild, as\n * `loadNodeProject` does), a folder written by `cellb build` (its `worker.js` imported as built),\n * an `http(s):` URL of a built folder, or a FilesApi holding either kind of folder.\n *\n * `options.data`: a directory for the cells' SQLite files and the project's files\n * (`<data>/files`); without it, both are in memory.\n */\nexport async function loadProject(\n source: ProjectSource,\n options: NodeLoadProjectOptions = {},\n): Promise<LoadedProject> {\n const host = nodeHost(options);\n const close = async (runtime: { close(): Promise<void> }, cleanup?: () => void) => {\n await runtime.close();\n cleanup?.();\n };\n // A folder on disk: read where it lies.\n const dir = localDir(source);\n if (dir !== undefined) {\n const reader = fsReader(dir);\n const manifest = await readBuildManifest(reader);\n if (manifest) return runBuilt(await readBuiltProject(reader, manifest), host);\n const { runtime, unsupported, config } = await loadNodeProject(dir, host);\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => close(runtime),\n };\n }\n // A FilesApi: a built folder is read from it; a source folder is copied out for esbuild.\n if (isFilesApi(source)) {\n const reader = filesApiReader(source);\n const manifest = await readBuildManifest(reader);\n if (manifest) return runBuilt(await readBuiltProject(reader, manifest), host);\n const tmp = await copyOut(source);\n try {\n const { runtime, unsupported, config } = await loadNodeProject(tmp, host);\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => close(runtime, () => rmSync(tmp, { recursive: true, force: true })),\n };\n } catch (err) {\n rmSync(tmp, { recursive: true, force: true });\n throw err;\n }\n }\n // A URL of a built folder.\n const url = folderUrl(source);\n const reader = urlReader(url);\n const manifest = await readBuildManifest(reader);\n if (!manifest)\n throw new Error(`${url} has no ${BUILD_MANIFEST}: load a folder written by \\`cellb build\\``);\n return runBuilt(await readBuiltProject(reader, manifest), host);\n}\n\n/** What `options` become on Node: SQLite files and a FilesApi under `data`, or memory. */\nfunction nodeHost(options: NodeLoadProjectOptions): Omit<ProjectHost, \"loadModules\"> {\n let files: FilesApi;\n if (options.data) {\n const data = resolve(options.data);\n mkdirSync(join(data, \"files\"), { recursive: true });\n files = new NodeFilesApi({ rootDir: join(data, \"files\") });\n } else files = new MemFilesApi();\n return {\n // A storage that logs pages (a celld bucket: every commit as LTX) gets them from the WAL\n // (O(changed pages)) instead of an image of the whole database diffed per commit.\n openSql: nodeSqliteOpener(options.data ? resolve(options.data) : undefined, {\n pageCapture: !!options.bucket?.durability?.capturePages,\n }),\n files,\n storage: options.bucket,\n ai: options.ai,\n };\n}\n\n/**\n * Runs a built project on Node: `worker.js` was bundled for a browser realm, so it reads the\n * Workers globals and `cloudflare:workers` from the globals this sets, as in a browser worker.\n * (One such project per process: the globals are the process's.)\n */\nasync function runBuilt(\n built: BuiltProject,\n host: Omit<ProjectHost, \"loadModules\">,\n): Promise<LoadedProject> {\n const { config } = built;\n const flags = config.compatibility_flags ?? [];\n const scope = workerScope(loadTimeEnv(config, host.ai));\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkersModule = workersClasses;\n g.__cellsProjectScope = scope;\n g.__cellsGlobals = {\n ...workersGlobals,\n Request: workersGlobals.CellsRequest,\n Response: workersGlobals.CellsResponse,\n WebSocketPair: flags.includes(\"websocket_standard_binary_type\")\n ? workersGlobals.StandardWebSocketPair\n : workersGlobals.WebSocketPair,\n };\n if (populatesProcessEnv(config)) {\n const env = processEnvOf(config);\n g.__cellsProcessEnv = env;\n for (const [k, v] of Object.entries(env)) process.env[k] ??= v;\n }\n let module: WorkerModule = { default: {} } as WorkerModule;\n if (built.code !== null) {\n const tmp = mkdtempSync(join(tmpdir(), \"cellb-built-\"));\n const file = join(tmp, BUILT_WORKER.replace(/\\.js$/, \".mjs\"));\n writeFileSync(file, built.code);\n try {\n module = (await import(/* @vite-ignore */ pathToFileURL(file).href)) as WorkerModule;\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n }\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles: built.assets,\n ...host,\n });\n scope.bind(project.runtime);\n const { runtime, unsupported } = project;\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => runtime.close(),\n };\n}\n\n/** The folder a source names on this machine: a path or a `file:` URL. */\nfunction localDir(source: ProjectSource): string | undefined {\n if (typeof source === \"string\") {\n if (/^https?:\\/\\//i.test(source)) return undefined;\n return resolve(source.startsWith(\"file:\") ? fileURLToPath(source) : source);\n }\n if (source instanceof URL && source.protocol === \"file:\") return fileURLToPath(source);\n return undefined;\n}\n\nfunction folderUrl(source: ProjectSource): URL {\n const url = new URL(String(source));\n if (!url.pathname.endsWith(\"/\")) url.pathname += \"/\";\n return url;\n}\n\nfunction fsReader(dir: string): ProjectReader {\n return {\n async bytes(path) {\n const full = join(dir, path);\n return existsSync(full) ? new Uint8Array(readFileSync(full)) : undefined;\n },\n };\n}\n\n/** Copies a FilesApi's files into a temporary folder (esbuild bundles from disk). */\nasync function copyOut(files: FilesApi): Promise<string> {\n const tmp = mkdtempSync(join(tmpdir(), \"cellb-project-\"));\n const reader = filesApiReader(files);\n for (const path of (await reader.list?.(\"/\")) ?? []) {\n const out = join(tmp, path);\n mkdirSync(dirname(out), { recursive: true });\n writeFileSync(out, (await reader.bytes(path)) as Uint8Array);\n }\n return tmp;\n}\n"]}
@@ -13,7 +13,7 @@ import { parseJsonc } from "./jsonc.js";
13
13
  import { moduleRulesPlugin } from "./module-rules.js";
14
14
  import { ownModule } from "./own-module.js";
15
15
  import { workerScope } from "./worker-scope.js";
16
- import { createProjectRuntime, hasNodeCompat, loadProjectBindings, loadTimeEnv, WRANGLER_FILES, } from "./wrangler.js";
16
+ import { createProjectRuntime, hasNodeCompat, loadProjectBindings, loadTimeEnv, populatesProcessEnv, processEnvOf, WRANGLER_FILES, } from "./wrangler.js";
17
17
  /** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */
18
18
  export function readWranglerConfig(dir) {
19
19
  for (const name of WRANGLER_FILES) {
@@ -216,13 +216,9 @@ export async function loadNodeProject(dir, host) {
216
216
  installHostModuleGlobals(scope);
217
217
  // As the browser host: nodejs_compat fills process.env with the text vars (from compatibility
218
218
  // date 2025-04-01). Node shares its real process with the Worker, so they land there.
219
- if (nodeCompat &&
220
- !flags.includes("nodejs_compat_do_not_populate_process_env") &&
221
- (flags.includes("nodejs_compat_populate_process_env") ||
222
- (config.compatibility_date ?? "") >= "2025-04-01"))
223
- for (const [k, v] of Object.entries(config.vars ?? {}))
224
- if (typeof v === "string")
225
- process.env[k] ??= v;
219
+ if (populatesProcessEnv(config))
220
+ for (const [k, v] of Object.entries(processEnvOf(config)))
221
+ process.env[k] ??= v;
226
222
  const module = config.main
227
223
  ? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {
228
224
  nodeCompat,
@@ -1 +1 @@
1
- {"version":3,"file":"node-project.js","sourceRoot":"","sources":["../../src/project/node-project.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAGL,UAAU,EACV,aAAa,GACd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAmB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAoB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,WAAW,EAGX,cAAc,GAEf,MAAM,eAAe,CAAC;AAEvB,oGAAoG;AACpG,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAmB,CAAC;IAClF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,uFAAuF;AACvF,MAAM,eAAe,GAAG,IAAI,MAAM,CAChC,KAAK,cAAc;KAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;KACrD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;KACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CACjB,CAAC;AAEF;;;;GAIG;AACH,8GAA8G;AAC9G,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAA2E,EAC3E,IAAc,EACd,QAAuB,EACvB,IAAI,GAMA,EAAE;IAEN,0FAA0F;IAC1F,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,UAAqC,CAAC;QAChD,CAAC,CAAC,mBAAmB,KAAK,EAAE,CAAC;QAC5B,CAAC,CAAC,mBAA+C,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IAC5E,CAAC;IACD,mEAAmE;IACnE,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,UAAqC,CAAC;QAChD,CAAC,CAAC,eAAe,KAAK,EAAE,CAAC;QACxB,CAAC,CAAC,eAA2C,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC;IACzE,CAAC;IACD,kEAAkE;IAClE,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,CAAC,GAAG,UAAqC,CAAC;QAChD,CAAC,CAAC,eAAe,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,CAAC,CAAC,eAA0C,CAAC;QAC9D,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC;QAChC,MAAM,IAAI,GACR,CAAC,KAAkD,EAAE,EAAE,CACvD,CAAC,GAAG,IAAe,EAAE,EAAE;YACrB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAClB,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC;QACJ,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACxD,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC;YAChB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAClB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAClB,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC;YACpB,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC;SACrB,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IACvE,8FAA8F;IAC9F,uFAAuF;IACvF,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC7D,aAAa,CACX,aAAa,EACb;QACE,iBAAiB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG;QAC7C,kDAAkD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI;QAC9E,4CAA4C;QAC5C,oDAAoD;QACpD,sDAAsD;KACvD,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACF,MAAM,MAAM,GAAG,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,MAAM,KAAK,CAAC;QACV,WAAW,EAAE;YACX,MAAM,CAAC,CAAC,CAAC,UAAW,KAA0B,CAAC,IAAI,EAAE,CAAC,CAAC,CAAE,KAA0B,CAAC,IAAI;SACzF;QACD,OAAO,EAAE,GAAG;QACZ,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,SAAS;QACnB,2FAA2F;QAC3F,yFAAyF;QACzF,UAAU,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC5C,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC9B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,yFAAyF;QACzF,0FAA0F;QAC1F,2FAA2F;QAC3F,YAAY;QACZ,GAAG,CAAC,IAAI,CAAC,UAAU;YACjB,CAAC,CAAC;gBACE,MAAM,EAAE;oBACN,EAAE,EAAE,8HAA8H;iBACnI;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,EAAE;YACN,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC;YACjD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACrC;QACD,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,eAAe;gBACrB,KAAK,CAAC,CAAC;oBACL,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBAChD,IAAI,EAAE,SAAS;wBACf,SAAS,EAAE,eAAe;qBAC3B,CAAC,CAAC,CAAC;oBACJ,uEAAuE;oBACvE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;wBACpB,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;wBAC7E,6EAA6E;wBAC7E,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC/C,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE;4BACtB,QAAQ,EAAE,IAAI;yBACf,CAAC,CAAC,CAAC;oBACN,CAAC;oBACD,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC/C,IAAI,EAAE,QAAQ;wBACd,SAAS,EAAE,cAAc;qBAC1B,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC3D,QAAQ,EAAE,qCAAqC,CAAC,CAAC,IAAI,CAAC,kBAAkB,GAAG;wBAC3E,MAAM,EAAE,IAAI;qBACb,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC9C,IAAI,EAAE,OAAO;wBACb,SAAS,EAAE,aAAa;qBACzB,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC1D,QAAQ,EAAE,mDAAmD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI;wBAC5F,MAAM,EAAE,IAAI;qBACb,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC5D,QAAQ,EAAE,qDAAqD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI;wBAC7F,MAAM,EAAE,IAAI;qBACb,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,sBAAsB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBACrD,IAAI,EAAE,aAAa;wBACnB,QAAQ,EAAE,IAAI;qBACf,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBACnD,IAAI,EAAE,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;wBACxD,QAAQ,EAAE,IAAI;qBACf,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC3C,IAAI,EAAE,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,wBAAwB,CAAC;wBAC9D,QAAQ,EAAE,IAAI;qBACf,CAAC,CAAC,CAAC;oBACJ,IAAI,CAAC,MAAM;wBAAE,OAAO;oBACpB,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC1C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;wBACrB,SAAS,EAAE,QAAQ;qBACpB,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAC1C,CAAC,CAAC,SAAS,KAAK,QAAQ;wBACtB,CAAC,CAAC;4BACE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;4BAChE,SAAS,EAAE,QAAQ;yBACpB;wBACH,CAAC,CAAC,SAAS,CACd,CAAC;oBACF,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACtD,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;wBACxB,MAAM,EAAE,IAAI;qBACb,CAAC,CAAC,CAAC;gBACN,CAAC;aACF;YACD,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;SAC9B;KACF,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAiB,CAAC;AAChE,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,MAAM,gBAAgB,GAAiB,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IACtE,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACpF,8FAA8F;IAC9F,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,CAAC,MAAM,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrF,KAAK;KACN,CAAC,CAA4B,CAAC;IAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,IAAkF;IAElF,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM;QAChC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,kBAAkB,GAAG,KAAK,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC;IAC5E,qFAAqF;IACrF,kFAAkF;IAClF,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,+FAA+F;IAC/F,2FAA2F;IAC3F,+EAA+E;IAC/E,wBAAwB,CAAC,KAAK,CAAC,CAAC;IAChC,8FAA8F;IAC9F,sFAAsF;IACtF,IACE,UAAU;QACV,CAAC,KAAK,CAAC,QAAQ,CAAC,2CAA2C,CAAC;QAC5D,CAAC,KAAK,CAAC,QAAQ,CAAC,oCAAoC,CAAC;YACnD,CAAC,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC,IAAI,YAAY,CAAC;QAEpD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACpD,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI;QACxB,CAAC,CAAC,MAAM,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;YAC5E,UAAU;YACV,kBAAkB;YAClB,KAAK;YACL,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC;QACJ,CAAC,CAAE,EAAE,OAAO,EAAE,EAAE,EAAmB,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS;QACzC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3D,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE;QACnD,QAAQ,EAAE,MAAM,mBAAmB,CAAC,MAAM,CAAC;QAC3C,WAAW,EAAE,gBAAgB;QAC7B,qDAAqD;QACrD,eAAe,EAAE,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;QACvD,UAAU;QACV,GAAG,IAAI;KACR,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC;AAChC,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,MAAc,EAAE,EAAE;QAC3C,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC7B,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;gBAAE,IAAI,CAAC,IAAI,EAAE,GAAG,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC;;gBAC7D,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,EAAE,IAAI,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAChB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAW,EACX,OAAyC,EACzC,QAAgB;IAEhB,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,EAAE,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,QAAQ,CAC9D,CAAC;IACF,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAG,EAAkC,CAAC,cAAc,IAAI,YAAY,CAAC,CAAC;IAC9F,MAAM,KAAK,GAAuB,UAAU,CAAC,IAAI,CAAC;QAChD,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,iBAAiB,CACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAU,EAChC,KAAK,EACJ,EAAoC,CAAC,gBAAgB,IAAI,eAAe,CAC1E,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,IAAI,YAAyC,CAAC;AAC9C,MAAM,UAAU,kBAAkB,CAAC,OAAuC;IACxE,OAAO,oBAAoB,CAAC;QAC1B,OAAO;QACP,KAAK,EAAE,GAAG,EAAE;YACV,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,oBAAoB,EAAE,EAAE,CAAC,CAAC,CAAC;YACzE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,gDAAgD;YAC9D,OAAO,EAAE,IAAI,EAAE,IAA2B,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACvF,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3B,YAAY,KAAK,iBAAiB,EAAE,CAAC;YACrC,MAAM,YAAY,CAAC;YACnB,MAAM,OAAO,GAA2B,EAAE,CAAC;YAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACpF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC;gBACtB,WAAW,EAAE,CAAC,UAAU,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC1C,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,iBAAiB;wBACvB,KAAK,CAAC,CAAC;4BACL,2EAA2E;4BAC3E,6BAA6B;4BAC7B,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,sBAAsB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;gCACrD,IAAI,EAAE,oBAAoB;gCAC1B,SAAS,EAAE,iBAAiB;6BAC7B,CAAC,CAAC,CAAC;4BACJ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;gCAC9D,QAAQ,EAAE;oCACR,8EAA8E;oCAC9E,iBAAiB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,GAAG;oCACxF,0KAA0K;iCAC3K,CAAC,IAAI,CAAC,IAAI,CAAC;gCACZ,MAAM,EAAE,IAAI;gCACZ,UAAU,EAAE,OAAO,IAAI,CAAC,OAAO;6BAChC,CAAC,CAAC,CAAC;4BACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;gCACnD,IAAI,EAAE,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;6BACzD,CAAC,CAAC,CAAC;4BACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gCAC1C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gCACrB,SAAS,EAAE,QAAQ;6BACpB,CAAC,CAAC,CAAC;4BACJ,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAC1C,CAAC,CAAC,SAAS,KAAK,QAAQ;gCACtB,CAAC,CAAC;oCACE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;oCAChE,SAAS,EAAE,QAAQ;iCACpB;gCACH,CAAC,CAAC,SAAS,CACd,CAAC;4BACF,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gCACtD,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;gCACzB,MAAM,EAAE,IAAI;6BACb,CAAC,CAAC,CAAC;wBACN,CAAC;qBACF;iBACF;aACF,CAAC,CAAC;YACH,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,IAAI,gBAAgB,GAAG,EAAE,CAAC;AAC1B,SAAS,oBAAoB;IAC3B,IAAI,CAAC,gBAAgB;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACtE,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AACD,KAAK,UAAU,iBAAiB;IAC9B,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IACtF,MAAM,KAAK,CAAC;QACV,WAAW,EAAE,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;QACtE,OAAO,EAAE,gBAAgB;QACzB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;KACnB,CAAC,CAAC;IACH,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,wFAAwF;AACxF,SAAS,wBAAwB,CAAC,KAAkB;IAClD,MAAM,CAAC,GAAG,UAAqC,CAAC;IAChD,CAAC,CAAC,mBAAmB,GAAG,KAAK,CAAC;IAC9B,CAAC,CAAC,oBAAoB,KAAK,cAAc,CAAC;IAC1C,uEAAuE;IACvE,CAAC,CAAC,kBAAkB,KAAK,IAAI,KAAK,CAChC,EAAE,EACF,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAC5E,CAAC;AACJ,CAAC;AACD,MAAM,cAAc,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC","sourcesContent":["import {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { Worker as NodeWorker } from \"node:worker_threads\";\nimport { build } from \"esbuild\";\nimport { applyD1Migrations } from \"../bindings/d1-migrations.js\";\nimport {\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport { isolatedModuleLoader } from \"../isolate/host.js\";\nimport type { PortLike } from \"../isolate/protocol.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport { type ModuleRule, moduleRulesPlugin } from \"./module-rules.js\";\nimport { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n hasNodeCompat,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n type ProjectRuntime,\n WRANGLER_FILES,\n type WranglerConfig,\n} from \"./wrangler.js\";\n\n/** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */\nexport function readWranglerConfig(dir: string): WranglerConfig {\n for (const name of WRANGLER_FILES) {\n const p = join(dir, name);\n if (existsSync(p)) return parseJsonc(readFileSync(p, \"utf8\")) as WranglerConfig;\n }\n throw new Error(`no wrangler.jsonc or wrangler.json in ${dir}`);\n}\n\n/** A bare Node.js built-in specifier (\"path\", \"fs/promises\"), not one of a package. */\nconst nodeBuiltinName = new RegExp(\n `^(${builtinModules\n .filter((m) => !m.startsWith(\"_\") && !m.includes(\":\"))\n .map((m) => m.replace(/[/]/g, \"\\\\/\"))\n .join(\"|\")})$`,\n);\n\n/**\n * Node host: bundles `main` with esbuild (as `celld deploy` does) and builds the runtime.\n * `cloudflare:workers` resolves to cellb's module so user classes extend the\n * runtime's own DurableObject / WorkerEntrypoint.\n */\n/** Bundles Worker code (a file, or in-memory modules) with the runtime's module mappings, then imports it. */\nexport async function bundleWorker(\n entry: { path: string } | { modules: Record<string, string>; main: string },\n logs?: LogSink,\n outbound?: typeof fetch,\n opts: {\n nodeCompat?: boolean;\n standardBinaryType?: boolean;\n scope?: WorkerScope;\n /** wrangler `rules` for non-JS imports (the defaults: `.wasm`, `.bin`, `.txt`…, as wrangler). */\n rules?: ModuleRule[];\n } = {},\n): Promise<WorkerModule> {\n // `env` and `exports` of `cloudflare:workers` belong to one Worker: the bundle reads them\n // from its own scope (empty objects for code that has none).\n const scopeKey = opts.scope ? `s${Math.random().toString(36).slice(2)}` : \"\";\n if (opts.scope) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[scopeKey] = opts.scope;\n }\n // Loaded code gets a bundle-local `fetch` (globalOutbound policy)…\n const outboundKey = outbound ? `o${Math.random().toString(36).slice(2)}` : \"\";\n if (outbound) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[outboundKey] = outbound;\n }\n // …and a bundle-local `console` that also feeds its Tail Workers.\n const consoleKey = logs ? `c${Math.random().toString(36).slice(2)}` : \"\";\n if (logs) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const registry = g.__cellsConsoles as Record<string, unknown>;\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n registry[consoleKey] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n }\n const outDir = mkdtempSync(join(tmpdir(), \"cells-worker-\"));\n const out = join(outDir, \"worker.mjs\");\n const cfWorkers = ownModule(import.meta.dirname, \"cloudflare-workers\");\n // This bundle's `cloudflare:workers`: the runtime's classes plus its own `env` and `exports`.\n // A file of its own, kept out of the bundle so it adds no names to the Worker's scope.\n const workersModule = join(outDir, \"cloudflare-workers.mjs\");\n writeFileSync(\n workersModule,\n [\n `export * from ${JSON.stringify(cfWorkers)};`,\n `const scope = globalThis.__cellsWorkerScopes?.[${JSON.stringify(scopeKey)}];`,\n \"export const env = scope ? scope.env : {};\",\n \"export const exports = scope ? scope.exports : {};\",\n \"export const waitUntil = (p) => scope?.waitUntil(p);\",\n ].join(\"\\n\"),\n );\n const memory = \"modules\" in entry ? entry.modules : undefined;\n await build({\n entryPoints: [\n memory ? `memory:${(entry as { main: string }).main}` : (entry as { path: string }).path,\n ],\n outfile: out,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n // As `celld deploy` resolves packages: workerd's conditions, then `module` and `main` (the\n // neutral platform has no main fields, so a package with only `main` would not resolve).\n conditions: [\"workerd\", \"worker\", \"browser\"],\n mainFields: [\"module\", \"main\"],\n target: \"es2022\",\n logLevel: \"silent\",\n // nodejs_compat: CommonJS dependencies `require()` Node's built-ins (mime-types requires\n // node:path), as they may under workerd's nodejs_compat. In an ES module bundle esbuild's\n // require shim needs a `require` in scope: vitest's module runner provides one, plain Node\n // does not.\n ...(opts.nodeCompat\n ? {\n banner: {\n js: 'import { createRequire as __cellbCreateRequire } from \"node:module\";\\nconst require = __cellbCreateRequire(import.meta.url);',\n },\n }\n : {}),\n inject: [\n ownModule(import.meta.dirname, \"workers-globals\"),\n ...(logs ? [\"cellb:console\"] : []),\n ...(outbound ? [\"cellb:fetch\"] : []),\n ],\n plugins: [\n {\n name: \"cells-modules\",\n setup(b) {\n b.onResolve({ filter: /^cellb:console$/ }, () => ({\n path: \"console\",\n namespace: \"cells-console\",\n }));\n // nodejs_compat on a Node host: `node:*` are the real Node.js modules.\n if (opts.nodeCompat) {\n b.onResolve({ filter: /^node:/ }, (a) => ({ path: a.path, external: true }));\n // workerd's nodejs_compat also takes the bare names (\"path\", \"fs/promises\").\n b.onResolve({ filter: nodeBuiltinName }, (a) => ({\n path: `node:${a.path}`,\n external: true,\n }));\n }\n b.onResolve({ filter: /^cellb:compat$/ }, () => ({\n path: \"compat\",\n namespace: \"cells-compat\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-compat\" }, () => ({\n contents: `export const standardBinaryType = ${!!opts.standardBinaryType};`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:fetch$/ }, () => ({\n path: \"fetch\",\n namespace: \"cells-fetch\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fetch\" }, () => ({\n contents: `export const fetch = globalThis.__cellsOutbound[${JSON.stringify(outboundKey)}];`,\n loader: \"js\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-console\" }, () => ({\n contents: `export const console = globalThis.__cellsConsoles[${JSON.stringify(consoleKey)}];`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: workersModule,\n external: true,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n external: true,\n }));\n b.onResolve({ filter: /^cellb:ws$/ }, () => ({\n path: ownModule(import.meta.dirname, \"workers-globals-module\"),\n external: true,\n }));\n if (!memory) return;\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: memory[a.path],\n loader: \"js\",\n }));\n },\n },\n moduleRulesPlugin(opts.rules),\n ],\n });\n return (await import(/* @vite-ignore */ out)) as WorkerModule;\n}\n\n/** Worker Loader on Node: compiles `WorkerCode.modules` with esbuild (as celld compiles loaded code). */\nexport const nodeModuleLoader: ModuleLoader = async (_id, code, logs) => {\n const outbound = outboundFetch(code);\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n // `env` and `exports` of the loaded code's `cloudflare:workers` are its own (WorkerCode.env).\n const env = code.env ?? {};\n const scope = workerScope(env);\n const module = (await bundleWorker({ modules, main: code.mainModule }, logs, outbound, {\n scope,\n })) as Record<string, unknown>;\n scope.bind({ env, exports: ctxExports(module, env) });\n return module;\n};\n\nexport async function loadNodeProject(\n dir: string,\n host: Omit<ProjectHost, \"loadModules\"> & Partial<Pick<ProjectHost, \"loadModules\">>,\n): Promise<ProjectRuntime & { config: WranglerConfig }> {\n const config = readWranglerConfig(dir);\n if (!config.main && !config.assets)\n throw new Error(\"wrangler config has neither `main` nor `assets`\");\n const flags = config.compatibility_flags ?? [];\n const nodeCompat = hasNodeCompat(config);\n const standardBinaryType = flags.includes(\"websocket_standard_binary_type\");\n // The module reads `env` from `cloudflare:workers` while it is evaluated, before the\n // runtime exists: until then the scope holds the configuration's vars (and `ai`).\n const scope = workerScope(loadTimeEnv(config, host.ai));\n // A bundle built elsewhere for cellb (cellbHostModule: webrun-bundler in a browser, say) reads\n // the runtime from globals, as in the browser realm: set them here too, so the same bundle\n // runs on Node. (One such project per process: the globals are the process's.)\n installHostModuleGlobals(scope);\n // As the browser host: nodejs_compat fills process.env with the text vars (from compatibility\n // date 2025-04-01). Node shares its real process with the Worker, so they land there.\n if (\n nodeCompat &&\n !flags.includes(\"nodejs_compat_do_not_populate_process_env\") &&\n (flags.includes(\"nodejs_compat_populate_process_env\") ||\n (config.compatibility_date ?? \"\") >= \"2025-04-01\")\n )\n for (const [k, v] of Object.entries(config.vars ?? {}))\n if (typeof v === \"string\") process.env[k] ??= v;\n const module = config.main\n ? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {\n nodeCompat,\n standardBinaryType,\n scope,\n rules: config.rules,\n })\n : ({ default: {} } as WorkerModule);\n const assetFiles = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : undefined;\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n // own realm, as celld; facets logged like the root's\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles,\n ...host,\n });\n scope.bind(project.runtime);\n return { ...project, config };\n}\n\n/** Reads an assets directory into \"/path\" → bytes (what `celld deploy` uploads). */\nexport function readAssetDirectory(root: string): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n const walk = (dir: string, prefix: string) => {\n for (const name of readdirSync(dir)) {\n const full = join(dir, name);\n if (statSync(full).isDirectory()) walk(full, `${prefix}${name}/`);\n else files.set(`${prefix}${name}`, new Uint8Array(readFileSync(full)));\n }\n };\n walk(root, \"/\");\n return files;\n}\n\n/**\n * `celld d1 migrations apply DATABASE` for a Node-hosted project: reads\n * `migrations_dir` (default \"migrations\") of the `d1_databases` entry and applies what is new.\n */\nexport async function applyNodeD1Migrations(\n dir: string,\n runtime: { env: Record<string, unknown> },\n database: string,\n) {\n const config = readWranglerConfig(dir);\n const d1 = config.d1_databases?.find(\n (d) => d.database_name === database || d.binding === database,\n );\n if (!d1) throw new Error(`no d1_databases entry named ${database}`);\n const mdir = resolve(dir, (d1 as { migrations_dir?: string }).migrations_dir ?? \"migrations\");\n const files: [string, string][] = existsSync(mdir)\n ? readdirSync(mdir).map((f) => [f, readFileSync(join(mdir, f), \"utf8\")])\n : [];\n return applyD1Migrations(\n runtime.env[d1.binding] as never,\n files,\n (d1 as { migrations_table?: string }).migrations_table ?? \"d1_migrations\",\n );\n}\n\n/**\n * Loaded Workers in worker threads (one realm each), like celld's isolates. The code is\n * bundled with esbuild (cloudflare:workers bundled in) and imported in the thread from a\n * data: URL; Durable Object classes for facets still load in this realm.\n */\nlet isolateEntry: Promise<string> | undefined;\nexport function nodeIsolatedLoader(storage?: () => CellStorage | undefined): ModuleLoader {\n return isolatedModuleLoader({\n storage,\n spawn: () => {\n const port = new NodeWorker(new URL(`file://${isolateEntryPathSync()}`));\n port.unref(); // an idle isolate never keeps the process alive\n return { port: port as unknown as PortLike, terminate: () => void port.terminate() };\n },\n prepare: async (_id, code) => {\n isolateEntry ??= buildIsolateEntry();\n await isolateEntry;\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n const out = await build({\n entryPoints: [`memory:${code.mainModule}`],\n write: false,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n logLevel: \"silent\",\n plugins: [\n {\n name: \"isolate-modules\",\n setup(b) {\n // The loaded Worker is its thread's own: `env` and `exports` are the scope\n // serveIsolate keeps for it.\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: \"cloudflare:workers\",\n namespace: \"isolate-workers\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"isolate-workers\" }, () => ({\n contents: [\n // cloudflare-workers.js in the published package (dist/), .ts in the sources.\n `export * from ${JSON.stringify(ownModule(import.meta.dirname, \"cloudflare-workers\"))};`,\n \"export const env = globalThis.__cellsProjectScope.env, exports = globalThis.__cellsProjectScope.exports, waitUntil = (p) => globalThis.__cellsProjectScope.waitUntil(p);\",\n ].join(\"\\n\"),\n loader: \"js\",\n resolveDir: import.meta.dirname,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n }));\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: modules[a.path],\n loader: \"js\",\n }));\n },\n },\n ],\n });\n return { source: out.outputFiles[0].text };\n },\n });\n}\n\nlet isolateEntryFile = \"\";\nfunction isolateEntryPathSync(): string {\n if (!isolateEntryFile) throw new Error(\"isolate entry not built yet\");\n return isolateEntryFile;\n}\nasync function buildIsolateEntry(): Promise<string> {\n isolateEntryFile = join(mkdtempSync(join(tmpdir(), \"cells-isolate-\")), \"isolate.mjs\");\n await build({\n entryPoints: [ownModule(import.meta.dirname, \"../isolate/node-entry\")],\n outfile: isolateEntryFile,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node22\",\n logLevel: \"silent\",\n });\n return isolateEntryFile;\n}\n\n/** The globals `@statewalker/cellb/host-modules` bundles read (see host-modules.ts). */\nfunction installHostModuleGlobals(scope: WorkerScope): void {\n const g = globalThis as Record<string, unknown>;\n g.__cellsProjectScope = scope;\n g.__cellsWorkersModule ??= workersClasses;\n // node:* from Node itself (the browser realm gives cellb's polyfills).\n g.__cellsNodeModules ??= new Proxy(\n {},\n { get: (_t, k) => (typeof k === \"string\" ? requireBuiltin(k) : undefined) },\n );\n}\nconst requireBuiltin = createRequire(import.meta.url);\n"]}
1
+ {"version":3,"file":"node-project.js","sourceRoot":"","sources":["../../src/project/node-project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { Worker as NodeWorker } from \"node:worker_threads\";\nimport { build } from \"esbuild\";\nimport { applyD1Migrations } from \"../bindings/d1-migrations.js\";\nimport {\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport { isolatedModuleLoader } from \"../isolate/host.js\";\nimport type { PortLike } from \"../isolate/protocol.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport { type ModuleRule, moduleRulesPlugin } from \"./module-rules.js\";\nimport { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n hasNodeCompat,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n type ProjectRuntime,\n populatesProcessEnv,\n processEnvOf,\n WRANGLER_FILES,\n type WranglerConfig,\n} from \"./wrangler.js\";\n\n/** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */\nexport function readWranglerConfig(dir: string): WranglerConfig {\n for (const name of WRANGLER_FILES) {\n const p = join(dir, name);\n if (existsSync(p)) return parseJsonc(readFileSync(p, \"utf8\")) as WranglerConfig;\n }\n throw new Error(`no wrangler.jsonc or wrangler.json in ${dir}`);\n}\n\n/** A bare Node.js built-in specifier (\"path\", \"fs/promises\"), not one of a package. */\nconst nodeBuiltinName = new RegExp(\n `^(${builtinModules\n .filter((m) => !m.startsWith(\"_\") && !m.includes(\":\"))\n .map((m) => m.replace(/[/]/g, \"\\\\/\"))\n .join(\"|\")})$`,\n);\n\n/**\n * Node host: bundles `main` with esbuild (as `celld deploy` does) and builds the runtime.\n * `cloudflare:workers` resolves to cellb's module so user classes extend the\n * runtime's own DurableObject / WorkerEntrypoint.\n */\n/** Bundles Worker code (a file, or in-memory modules) with the runtime's module mappings, then imports it. */\nexport async function bundleWorker(\n entry: { path: string } | { modules: Record<string, string>; main: string },\n logs?: LogSink,\n outbound?: typeof fetch,\n opts: {\n nodeCompat?: boolean;\n standardBinaryType?: boolean;\n scope?: WorkerScope;\n /** wrangler `rules` for non-JS imports (the defaults: `.wasm`, `.bin`, `.txt`…, as wrangler). */\n rules?: ModuleRule[];\n } = {},\n): Promise<WorkerModule> {\n // `env` and `exports` of `cloudflare:workers` belong to one Worker: the bundle reads them\n // from its own scope (empty objects for code that has none).\n const scopeKey = opts.scope ? `s${Math.random().toString(36).slice(2)}` : \"\";\n if (opts.scope) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[scopeKey] = opts.scope;\n }\n // Loaded code gets a bundle-local `fetch` (globalOutbound policy)…\n const outboundKey = outbound ? `o${Math.random().toString(36).slice(2)}` : \"\";\n if (outbound) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[outboundKey] = outbound;\n }\n // …and a bundle-local `console` that also feeds its Tail Workers.\n const consoleKey = logs ? `c${Math.random().toString(36).slice(2)}` : \"\";\n if (logs) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const registry = g.__cellsConsoles as Record<string, unknown>;\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n registry[consoleKey] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n }\n const outDir = mkdtempSync(join(tmpdir(), \"cells-worker-\"));\n const out = join(outDir, \"worker.mjs\");\n const cfWorkers = ownModule(import.meta.dirname, \"cloudflare-workers\");\n // This bundle's `cloudflare:workers`: the runtime's classes plus its own `env` and `exports`.\n // A file of its own, kept out of the bundle so it adds no names to the Worker's scope.\n const workersModule = join(outDir, \"cloudflare-workers.mjs\");\n writeFileSync(\n workersModule,\n [\n `export * from ${JSON.stringify(cfWorkers)};`,\n `const scope = globalThis.__cellsWorkerScopes?.[${JSON.stringify(scopeKey)}];`,\n \"export const env = scope ? scope.env : {};\",\n \"export const exports = scope ? scope.exports : {};\",\n \"export const waitUntil = (p) => scope?.waitUntil(p);\",\n ].join(\"\\n\"),\n );\n const memory = \"modules\" in entry ? entry.modules : undefined;\n await build({\n entryPoints: [\n memory ? `memory:${(entry as { main: string }).main}` : (entry as { path: string }).path,\n ],\n outfile: out,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n // As `celld deploy` resolves packages: workerd's conditions, then `module` and `main` (the\n // neutral platform has no main fields, so a package with only `main` would not resolve).\n conditions: [\"workerd\", \"worker\", \"browser\"],\n mainFields: [\"module\", \"main\"],\n target: \"es2022\",\n logLevel: \"silent\",\n // nodejs_compat: CommonJS dependencies `require()` Node's built-ins (mime-types requires\n // node:path), as they may under workerd's nodejs_compat. In an ES module bundle esbuild's\n // require shim needs a `require` in scope: vitest's module runner provides one, plain Node\n // does not.\n ...(opts.nodeCompat\n ? {\n banner: {\n js: 'import { createRequire as __cellbCreateRequire } from \"node:module\";\\nconst require = __cellbCreateRequire(import.meta.url);',\n },\n }\n : {}),\n inject: [\n ownModule(import.meta.dirname, \"workers-globals\"),\n ...(logs ? [\"cellb:console\"] : []),\n ...(outbound ? [\"cellb:fetch\"] : []),\n ],\n plugins: [\n {\n name: \"cells-modules\",\n setup(b) {\n b.onResolve({ filter: /^cellb:console$/ }, () => ({\n path: \"console\",\n namespace: \"cells-console\",\n }));\n // nodejs_compat on a Node host: `node:*` are the real Node.js modules.\n if (opts.nodeCompat) {\n b.onResolve({ filter: /^node:/ }, (a) => ({ path: a.path, external: true }));\n // workerd's nodejs_compat also takes the bare names (\"path\", \"fs/promises\").\n b.onResolve({ filter: nodeBuiltinName }, (a) => ({\n path: `node:${a.path}`,\n external: true,\n }));\n }\n b.onResolve({ filter: /^cellb:compat$/ }, () => ({\n path: \"compat\",\n namespace: \"cells-compat\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-compat\" }, () => ({\n contents: `export const standardBinaryType = ${!!opts.standardBinaryType};`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:fetch$/ }, () => ({\n path: \"fetch\",\n namespace: \"cells-fetch\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fetch\" }, () => ({\n contents: `export const fetch = globalThis.__cellsOutbound[${JSON.stringify(outboundKey)}];`,\n loader: \"js\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-console\" }, () => ({\n contents: `export const console = globalThis.__cellsConsoles[${JSON.stringify(consoleKey)}];`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: workersModule,\n external: true,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n external: true,\n }));\n b.onResolve({ filter: /^cellb:ws$/ }, () => ({\n path: ownModule(import.meta.dirname, \"workers-globals-module\"),\n external: true,\n }));\n if (!memory) return;\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: memory[a.path],\n loader: \"js\",\n }));\n },\n },\n moduleRulesPlugin(opts.rules),\n ],\n });\n return (await import(/* @vite-ignore */ out)) as WorkerModule;\n}\n\n/** Worker Loader on Node: compiles `WorkerCode.modules` with esbuild (as celld compiles loaded code). */\nexport const nodeModuleLoader: ModuleLoader = async (_id, code, logs) => {\n const outbound = outboundFetch(code);\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n // `env` and `exports` of the loaded code's `cloudflare:workers` are its own (WorkerCode.env).\n const env = code.env ?? {};\n const scope = workerScope(env);\n const module = (await bundleWorker({ modules, main: code.mainModule }, logs, outbound, {\n scope,\n })) as Record<string, unknown>;\n scope.bind({ env, exports: ctxExports(module, env) });\n return module;\n};\n\nexport async function loadNodeProject(\n dir: string,\n host: Omit<ProjectHost, \"loadModules\"> & Partial<Pick<ProjectHost, \"loadModules\">>,\n): Promise<ProjectRuntime & { config: WranglerConfig }> {\n const config = readWranglerConfig(dir);\n if (!config.main && !config.assets)\n throw new Error(\"wrangler config has neither `main` nor `assets`\");\n const flags = config.compatibility_flags ?? [];\n const nodeCompat = hasNodeCompat(config);\n const standardBinaryType = flags.includes(\"websocket_standard_binary_type\");\n // The module reads `env` from `cloudflare:workers` while it is evaluated, before the\n // runtime exists: until then the scope holds the configuration's vars (and `ai`).\n const scope = workerScope(loadTimeEnv(config, host.ai));\n // A bundle built elsewhere for cellb (cellbHostModule: webrun-bundler in a browser, say) reads\n // the runtime from globals, as in the browser realm: set them here too, so the same bundle\n // runs on Node. (One such project per process: the globals are the process's.)\n installHostModuleGlobals(scope);\n // As the browser host: nodejs_compat fills process.env with the text vars (from compatibility\n // date 2025-04-01). Node shares its real process with the Worker, so they land there.\n if (populatesProcessEnv(config))\n for (const [k, v] of Object.entries(processEnvOf(config))) process.env[k] ??= v;\n const module = config.main\n ? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {\n nodeCompat,\n standardBinaryType,\n scope,\n rules: config.rules,\n })\n : ({ default: {} } as WorkerModule);\n const assetFiles = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : undefined;\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n // own realm, as celld; facets logged like the root's\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles,\n ...host,\n });\n scope.bind(project.runtime);\n return { ...project, config };\n}\n\n/** Reads an assets directory into \"/path\" → bytes (what `celld deploy` uploads). */\nexport function readAssetDirectory(root: string): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n const walk = (dir: string, prefix: string) => {\n for (const name of readdirSync(dir)) {\n const full = join(dir, name);\n if (statSync(full).isDirectory()) walk(full, `${prefix}${name}/`);\n else files.set(`${prefix}${name}`, new Uint8Array(readFileSync(full)));\n }\n };\n walk(root, \"/\");\n return files;\n}\n\n/**\n * `celld d1 migrations apply DATABASE` for a Node-hosted project: reads\n * `migrations_dir` (default \"migrations\") of the `d1_databases` entry and applies what is new.\n */\nexport async function applyNodeD1Migrations(\n dir: string,\n runtime: { env: Record<string, unknown> },\n database: string,\n) {\n const config = readWranglerConfig(dir);\n const d1 = config.d1_databases?.find(\n (d) => d.database_name === database || d.binding === database,\n );\n if (!d1) throw new Error(`no d1_databases entry named ${database}`);\n const mdir = resolve(dir, (d1 as { migrations_dir?: string }).migrations_dir ?? \"migrations\");\n const files: [string, string][] = existsSync(mdir)\n ? readdirSync(mdir).map((f) => [f, readFileSync(join(mdir, f), \"utf8\")])\n : [];\n return applyD1Migrations(\n runtime.env[d1.binding] as never,\n files,\n (d1 as { migrations_table?: string }).migrations_table ?? \"d1_migrations\",\n );\n}\n\n/**\n * Loaded Workers in worker threads (one realm each), like celld's isolates. The code is\n * bundled with esbuild (cloudflare:workers bundled in) and imported in the thread from a\n * data: URL; Durable Object classes for facets still load in this realm.\n */\nlet isolateEntry: Promise<string> | undefined;\nexport function nodeIsolatedLoader(storage?: () => CellStorage | undefined): ModuleLoader {\n return isolatedModuleLoader({\n storage,\n spawn: () => {\n const port = new NodeWorker(new URL(`file://${isolateEntryPathSync()}`));\n port.unref(); // an idle isolate never keeps the process alive\n return { port: port as unknown as PortLike, terminate: () => void port.terminate() };\n },\n prepare: async (_id, code) => {\n isolateEntry ??= buildIsolateEntry();\n await isolateEntry;\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n const out = await build({\n entryPoints: [`memory:${code.mainModule}`],\n write: false,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n logLevel: \"silent\",\n plugins: [\n {\n name: \"isolate-modules\",\n setup(b) {\n // The loaded Worker is its thread's own: `env` and `exports` are the scope\n // serveIsolate keeps for it.\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: \"cloudflare:workers\",\n namespace: \"isolate-workers\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"isolate-workers\" }, () => ({\n contents: [\n // cloudflare-workers.js in the published package (dist/), .ts in the sources.\n `export * from ${JSON.stringify(ownModule(import.meta.dirname, \"cloudflare-workers\"))};`,\n \"export const env = globalThis.__cellsProjectScope.env, exports = globalThis.__cellsProjectScope.exports, waitUntil = (p) => globalThis.__cellsProjectScope.waitUntil(p);\",\n ].join(\"\\n\"),\n loader: \"js\",\n resolveDir: import.meta.dirname,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n }));\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: modules[a.path],\n loader: \"js\",\n }));\n },\n },\n ],\n });\n return { source: out.outputFiles[0].text };\n },\n });\n}\n\nlet isolateEntryFile = \"\";\nfunction isolateEntryPathSync(): string {\n if (!isolateEntryFile) throw new Error(\"isolate entry not built yet\");\n return isolateEntryFile;\n}\nasync function buildIsolateEntry(): Promise<string> {\n isolateEntryFile = join(mkdtempSync(join(tmpdir(), \"cells-isolate-\")), \"isolate.mjs\");\n await build({\n entryPoints: [ownModule(import.meta.dirname, \"../isolate/node-entry\")],\n outfile: isolateEntryFile,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node22\",\n logLevel: \"silent\",\n });\n return isolateEntryFile;\n}\n\n/** The globals `@statewalker/cellb/host-modules` bundles read (see host-modules.ts). */\nfunction installHostModuleGlobals(scope: WorkerScope): void {\n const g = globalThis as Record<string, unknown>;\n g.__cellsProjectScope = scope;\n g.__cellsWorkersModule ??= workersClasses;\n // node:* from Node itself (the browser realm gives cellb's polyfills).\n g.__cellsNodeModules ??= new Proxy(\n {},\n { get: (_t, k) => (typeof k === \"string\" ? requireBuiltin(k) : undefined) },\n );\n}\nconst requireBuiltin = createRequire(import.meta.url);\n"]}
@@ -1,13 +1,34 @@
1
+ /**
2
+ * `siteCompiler`: a project's sources served by an in-browser HTTP server (`createProjectSite`,
3
+ * hosted in a ServiceWorker by webrun-site-host), for `loadProject(files, { compile })`. Modules
4
+ * are compiled one by one as the browser imports them; nothing is bundled.
5
+ *
6
+ * `loadProject` runs in a Dedicated Worker, which cannot register a ServiceWorker: the site is
7
+ * hosted by a page. `siteHostOverPort` (worker) and `hostSitesForWorker` (page) do that over a
8
+ * MessagePort: the worker serves the site's handler, the page mounts it in its ServiceWorker.
9
+ */
10
+ import { SwHttpAdapter } from "@statewalker/webrun-http-browser";
1
11
  import { HostedSiteBuilder } from "@statewalker/webrun-site-host";
2
12
  import { linkOverPort, serveHandlerOverPort } from "../transport/port.js";
3
13
  import { createProjectSite } from "./site.js";
14
+ /**
15
+ * A `HostedSiteBuilder` whose page side is this package's webrun-http-browser (`SwHttpAdapter`),
16
+ * not the older one webrun-site-host depends on (^0.7). From 0.12.5 it rebuilds a request's url at
17
+ * the page's scheme, so a site hosted on an https page answers; and its version is the one whose
18
+ * ServiceWorker (`sw-worker.js`) hosts serve.
19
+ */
20
+ function newHostedSiteBuilder() {
21
+ return new HostedSiteBuilder({
22
+ adapterFactory: ({ key, serviceWorkerUrl }) => new SwHttpAdapter({ key, serviceWorkerUrl }),
23
+ });
24
+ }
4
25
  /** The default host: a ServiceWorker registered from this realm. */
5
26
  function serviceWorkerHost(serviceWorkerUrl) {
6
27
  return async (handler) => {
7
28
  if (!globalThis.navigator?.serviceWorker)
8
29
  throw new Error("siteCompiler: this realm cannot register a ServiceWorker (a Dedicated Worker cannot): " +
9
30
  "pass `host: siteHostOverPort(port)` and call `hostSitesForWorker(port)` in the page");
10
- const builder = new HostedSiteBuilder().setHandler(handler);
31
+ const builder = newHostedSiteBuilder().setHandler(handler);
11
32
  if (serviceWorkerUrl)
12
33
  builder.setServiceWorkerUrl(serviceWorkerUrl);
13
34
  const site = await builder.build();
@@ -108,7 +129,7 @@ export function hostSitesForWorker(control, options = {}) {
108
129
  // The worker may give up waiting (`timeoutMs`) and ask to stop before the site is up: the
109
130
  // stop then waits on `reply` until the handler below reads it.
110
131
  const link = await linkOverPort(req.link);
111
- const builder = new HostedSiteBuilder().setHandler(link.send);
132
+ const builder = newHostedSiteBuilder().setHandler(link.send);
112
133
  if (options.serviceWorkerUrl)
113
134
  builder.setServiceWorkerUrl(options.serviceWorkerUrl);
114
135
  const site = await builder.build();