@statewalker/cellb 0.8.5 → 0.8.6

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.
@@ -278,7 +278,7 @@ export class ObjectHost {
278
278
  let started;
279
279
  this.#active++;
280
280
  try {
281
- started = Promise.resolve(this.#root(() => fn(this.#instance, this.state)));
281
+ started = Promise.resolve(this.#root(() => this.state.storage.runEvent(() => fn(this.#instance, this.state))));
282
282
  }
283
283
  catch (e) {
284
284
  started = Promise.reject(e);
@@ -1 +1 @@
1
- {"version":3,"file":"object-host.js","sourceRoot":"","sources":["../../src/core/object-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\nimport type {\n BackupInfo,\n CellBackup,\n CellDurability,\n Lease,\n OpenCellSql,\n SyncSqlDriver,\n ValueCodec,\n} from \"../ports.js\";\nimport type { AsyncRoot } from \"./async-context.js\";\nimport { CELLD_SCHEMA, LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE, scopeOf } from \"./celld-schema.js\";\nimport { InputGate, OutputGate } from \"./gates.js\";\nimport {\n asyncStub,\n type DurableObjectClass,\n type IsolatedClass,\n isClassHandle,\n} from \"./handles.js\";\nimport { type DurableObjectId, DurableObjectId as DurableObjectIdClass } from \"./id.js\";\nimport { SqlStorage } from \"./sql-storage.js\";\nimport { DurableObjectState } from \"./state.js\";\nimport { DurableObjectStorage, SyncKvStorage } from \"./storage.js\";\n\n/**\n * The request as the object sees it: its signal also aborts when the host closes (the runtime\n * shuts down), as on Cloudflare when the client goes away; a long poll or an SSE stream that\n * waits on it then ends instead of running on into a closed database.\n *\n * The request is not copied: its `signal` becomes a getter that builds the merged signal the\n * first time it is read. Copying a Request and merging two signals cost about 7 µs a request, as\n * much as a small handler's whole turn, and most handlers never read the signal. The request is\n * the caller's own object (`runtime.fetch`) or a stub's fresh copy (a Durable Object's `fetch`);\n * `cf` and the upgrade's `headers` that cellb sets on it stay as they are. A copy the handler\n * makes itself (`new Request(req)`) takes the request's own signal, without the host's.\n */\nexport function closingWith(req: Request, closing: AbortSignal): Request {\n if (closing.aborted) return req;\n const own = signalOf(req);\n let merged: AbortSignal | undefined;\n try {\n Object.defineProperty(req, \"signal\", {\n configurable: true,\n enumerable: false,\n get: () => {\n if (!merged) {\n const before = own();\n merged = before ? AbortSignal.any([before, closing]) : closing;\n }\n return merged;\n },\n });\n return req;\n } catch {\n // A request whose `signal` cannot be redefined: a copy with the merged signal, as before.\n const r = new Request(req, { signal: AbortSignal.any([req.signal, closing]) });\n for (const k of [\"cf\", \"headers\"]) {\n const d = Object.getOwnPropertyDescriptor(req, k);\n if (d) Object.defineProperty(r, k, d);\n }\n return r;\n }\n}\n\n/** Reads `req.signal` as it is now: a getter set by an earlier `closingWith`, or the Request's own. */\nfunction signalOf(req: Request): () => AbortSignal | undefined {\n for (let o: object | null = req; o; o = Object.getPrototypeOf(o)) {\n const d = Object.getOwnPropertyDescriptor(o, \"signal\");\n if (d) return d.get ? () => d.get?.call(req) : () => d.value;\n }\n return () => undefined;\n}\n\n/** The object's host was closed for good: its storage and events fail with this. */\nexport class ObjectClosedError extends Error {\n override name = \"ObjectClosedError\";\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} was closed (its runtime shut down, or it moved or was reset)`);\n }\n}\n\nexport class BrokenObjectError extends Error {\n constructor(cause: unknown, reason = \"its storage failed to commit durably\") {\n const detail = cause instanceof Error ? `: ${cause.message}` : \"\";\n super(`Durable Object reset because ${reason}${detail}`, { cause });\n this.name = \"BrokenObjectError\";\n }\n}\n\n/**\n * One live instance of one Durable Object: its SQLite, gates and dispatcher.\n * Everything that reaches the object (fetch, RPC, later alarms/WebSockets)\n * goes through `deliver()`.\n */\nexport class ObjectHost {\n readonly cellKey: string;\n readonly #gate = new InputGate();\n readonly #out = new OutputGate();\n /** The open database; `#driver` follows it, so it can be closed while idle and reopened. */\n #db!: SyncSqlDriver;\n readonly #driver: SyncSqlDriver = new Proxy({} as SyncSqlDriver, {\n get: (_t, k) => {\n // Closed for good (its runtime or shard shut down): code still running in the object\n // learns why, instead of SQLite's \"DB has been closed\".\n if (this.#closed && k !== \"close\")\n return () => {\n throw new ObjectClosedError(this.cellKey);\n };\n const v = (this.#db as unknown as Record<PropertyKey, unknown>)[k];\n return typeof v === \"function\" ? v.bind(this.#db) : v;\n },\n });\n readonly #sql: SqlStorage;\n #instance: any;\n readonly #backup?: CellBackup;\n #backedUpSeq = 0;\n #saving: Promise<void> | undefined;\n readonly state: DurableObjectState;\n #seq = 0;\n broken = false;\n #brokenCause: unknown;\n\n /** blockConcurrencyWhile() rejected (CF: the object is reset; queued events fail). */\n #breakOn(e: unknown): void {\n this.broken = true;\n this.#brokenCause = e;\n }\n\n constructor(opts: {\n cellKey: string;\n id: DurableObjectId;\n cls: DurableObjectClass;\n env: unknown;\n openSql: OpenCellSql;\n durability: CellDurability;\n codec: ValueCodec;\n waitUntil: (p: Promise<unknown>) => void;\n backup?: CellBackup;\n /** The stored alarm changed (null = cleared). */\n onAlarmChange?: (at: number | null) => void;\n /** `ctx.exports` (loopback handles of the Worker's exports). */\n exports?: Record<string, unknown>;\n /** `ctx.props` of a facet started from a class handle with `{ props }`. */\n props?: unknown;\n /** SQLite extensions to load into every cell database (e.g. \"sqlite_vec\"). */\n sqlExtensions?: string[];\n /** storage.deleteAll() keeps the alarm (`delete_all_preserves_alarm`). */\n deleteAllPreservesAlarm?: boolean;\n /**\n * Ownership: acquire the cell's lease before restoring it. No lease → the cell is owned\n * elsewhere (the host refuses events). The lease epoch fences the cell's log segments;\n * losing the lease breaks the host so it stops serving.\n */\n /** Owner epoch when no lease is taken (facets inherit their root's). */\n epoch?: number;\n /** A facet: on open its rows move to this run's scope, as celld does. */\n facet?: boolean;\n acquire?: Lease[\"tryAcquire\"];\n /** The async context events start in (`asyncRoot()`): not the caller's, as on Cloudflare. */\n asyncRoot?: AsyncRoot;\n }) {\n this.#backup = opts.backup;\n this.cellKey = opts.cellKey;\n this.#epoch = opts.epoch;\n this.#opts = opts;\n this.#open = () => {\n this.#db = opts.openSql(opts.cellKey);\n for (const ext of opts.sqlExtensions ?? []) this.#db.loadExtension(ext);\n };\n this.#open();\n this.#sql = new SqlStorage(\n this.#driver,\n (changes) => {\n if (changes && this.#epoch !== undefined) changes.epoch = this.#epoch;\n // Page-level logs (LTX): the changed pages straight from the page hook when the driver\n // has one; the image only on demand (a generation's first snapshot, or no hook).\n const d = this.#driver;\n const seq = ++this.#seq;\n const pages = opts.durability.capturePages ? d.takeDirtyPages() : undefined;\n const snap = () => d.pageImage?.() ?? d.image?.();\n // The log runs later, after the next event may have opened its transaction, and an\n // image cannot be taken inside one (VACUUM INTO). When the log will surely need it\n // (no page hook) or likely does (this host's first commit), take it now.\n const image = opts.durability.capturePages\n ? !pages || seq === 1\n ? snap()\n : snap\n : undefined;\n const durable = opts.durability.committed(this.cellKey, {\n seq,\n changes,\n image,\n pages,\n epoch: this.#epoch,\n });\n const wake = this.#wakeAfterCommit();\n return this.#out.track(wake ? durable.then(wake) : durable);\n },\n { capture: !!opts.durability.captureChanges },\n );\n // The cell's scope in celld's tables (\"Class:idhex\"), so its database is celld's format.\n const kv = new SyncKvStorage(this.#sql, opts.codec, scopeOf(opts.cellKey));\n if (!opts.facet) kv.actorName = opts.id.name;\n const storage = new DurableObjectStorage(this.#sql, kv, this.#gate, () => this.#barrier());\n if (opts.onAlarmChange) storage.onAlarmChange = opts.onAlarmChange;\n storage.deleteAllPreservesAlarm = !!opts.deleteAllPreservesAlarm;\n const state = new DurableObjectState(opts.id, storage, this.#gate, opts.waitUntil, (e) =>\n this.#breakOn(e),\n );\n this.state = state;\n state.attachDispatcher((fn) => this.deliver(fn));\n // ctx.abort(reason) (workerd, celld): the object resets — a fresh instance on the same\n // database serves the next event; the calling event fails with the reason. Writes the event\n // already made still commit (celld: celld's workflow cell aborts after its delete commit).\n (state as unknown as { abort(reason?: unknown): never }).abort = (reason?: unknown): never => {\n queueMicrotask(() => this.restart());\n throw reason ?? new Error(\"Durable Object reset because its code calls abort()\");\n };\n state.exports = opts.exports ?? {};\n state.props = opts.props;\n state.facets = createFacets(\n { ...opts, epoch: () => this.#epoch },\n (name, cls, env, id, props) => {\n const facet = new ObjectHost({\n ...opts,\n // celld's facet stream: <parent>/facets/<SHA-256(name)[0..16] hex> (engine_api.rs)\n cellKey: `${opts.cellKey}/facets/${facetSegment(name)}`,\n id,\n cls,\n env,\n props,\n onAlarmChange: undefined,\n // A facet is part of its root's cell: no lease of its own, the root's epoch.\n acquire: undefined,\n epoch: this.#epoch,\n facet: true,\n });\n this.#facets.add(facet); // closed with its root\n return facet;\n },\n );\n const root = opts.asyncRoot ?? ((fn) => fn());\n this.#root = root;\n const construct = () => root(() => (this.#instance = new opts.cls(state, opts.env)));\n this.#construct = construct;\n const load = opts.backup?.load;\n const replay = opts.backup?.replay;\n const acquire = opts.acquire;\n if (!load && !replay && !acquire) {\n this.#nameFromMetadata(state);\n construct();\n return;\n }\n // Restore-on-open: events queue behind the closed gate until the image is in.\n void this.#gate\n .runClosed(async () => {\n if (acquire) {\n const lease = await acquire(this.cellKey);\n if (!lease) throw new CellOwnedElsewhereError(this.cellKey);\n this.#epoch = lease.epoch;\n this.#release = lease.release;\n lease.lost.addEventListener(\n \"abort\",\n () => this.#breakOn(new Error(`lease of ${this.cellKey} lost`)),\n {\n once: true,\n },\n );\n }\n // Under a lease (the cell's own, or its root's for a facet) the bucket is the cell's\n // truth: a local file kept from an earlier ownership is older than what other owners\n // wrote since, and may hold commits that never became durable.\n await this.#catchUp(this.#epoch !== undefined);\n if (opts.facet) this.#rescope(scopeOf(opts.cellKey));\n else {\n this.#initWake();\n this.#scheduleRestoredAlarm(opts.onAlarmChange);\n }\n this.#nameFromMetadata(state);\n construct();\n })\n .catch((e) => this.#breakOn(e));\n }\n\n /**\n * Takes an image if the cell changed since the last successful save and hands\n * it to `backup.save`. Taken synchronously between events → a consistent image.\n * Skipped while an async transaction() holds the database or a save is running.\n */\n backupIfDirty(reason: BackupInfo[\"reason\"], now: number): Promise<void> {\n const b = this.#backup;\n if (!b || this.broken || this.#saving || this.#seq === this.#backedUpSeq)\n return this.#saving ?? Promise.resolve();\n if (!this.#driver.image)\n return Promise.reject(new Error(\"SyncSqlDriver has no image(): cannot back up\"));\n if (this.#sql.held) return Promise.resolve(); // mid-transaction: next round\n this.#sql.commit();\n const seq = this.#seq;\n let logSeq = 0;\n try {\n logSeq = Number(this.#driver.exec(LOG_SEQ_READ, []).rows[0]?.[0] ?? 0);\n } catch {\n // no _cf_LOG yet\n }\n const image = this.#driver.image();\n this.#saving = b\n .save(this.cellKey, image, { seq, takenAt: now, reason, logSeq })\n .then(\n () => {\n this.#backedUpSeq = Math.max(this.#backedUpSeq, seq);\n },\n (e) => b.onError?.(this.cellKey, e),\n )\n .finally(() => (this.#saving = undefined));\n return this.#saving;\n }\n\n /**\n * Input gate → handler → commit → output gate (durability) → result.\n *\n * Events are queued and STARTED synchronously by a pump only while the gate\n * is open: the first storage op of a handler closes the gate before the\n * next event can start (checking the gate in an `await` continuation is too\n * late — every queued continuation would see it open).\n */\n deliver<T>(fn: (instance: any, state: DurableObjectState) => T | Promise<T>): Promise<T> {\n if (this.#closed) return Promise.reject(new ObjectClosedError(this.cellKey));\n if (this.broken) return Promise.reject(new BrokenObjectError(undefined));\n return new Promise<T>((resolve, reject) => {\n this.#queue.push(() => {\n if (this.#closed) return reject(new ObjectClosedError(this.cellKey));\n if (this.broken)\n return reject(new BrokenObjectError(this.#brokenCause, \"its initialization failed\"));\n let started: Promise<T>;\n this.#active++;\n try {\n started = Promise.resolve(this.#root(() => fn(this.#instance, this.state)));\n } catch (e) {\n started = Promise.reject(e);\n }\n const done = () => {\n this.#active--;\n this.lastActive = Date.now();\n if (!this.#active && !this.#queue.length) this.#notifyIdle();\n };\n started.then(\n (r) => {\n this.#pinIfStandardWebSocket(r);\n this.#barrier().then(\n () => (done(), resolve(r)),\n (e) => (done(), reject(e)),\n );\n },\n (e) =>\n this.#barrier().then(\n () => (done(), reject(e)),\n (e2) => (done(), reject(e2)),\n ),\n );\n });\n this.#pump();\n });\n }\n\n #queue: (() => void)[] = [];\n #pumpWaiting = false;\n #pump = (): void => {\n this.#pumpWaiting = false;\n while (this.#queue.length && this.#gate.isOpen) {\n // A database closed while idle: reopen it (and catch up) before anything runs.\n if (this.#dbClosed) {\n this.#dbClosed = false;\n void this.#gate\n .runClosed(async () => {\n this.#open();\n // The lease was held throughout: a kept file is current, an empty one is restored.\n await this.#catchUp(false);\n })\n .catch((e) => this.#breakOn(e));\n continue;\n }\n // Waking from hibernation: the constructor runs again before the event (and may\n // close the gate with blockConcurrencyWhile, which the loop then respects).\n if (this.#hibernated) {\n this.#hibernated = false;\n this.#construct?.();\n continue;\n }\n this.#queue.shift()!();\n }\n if (this.#queue.length && !this.#pumpWaiting) {\n this.#pumpWaiting = true;\n this.#gate.onOpen(this.#pump);\n }\n };\n\n async #barrier(): Promise<void> {\n try {\n this.#sql.commit();\n await this.#out.barrier();\n } catch (e) {\n this.broken = true;\n try {\n this.#sql.rollback();\n } catch {}\n throw new BrokenObjectError(e);\n }\n }\n\n /**\n * Settles once no event is in flight or queued (a response body still streaming is not an\n * event: its handler has returned). The runtime waits for it, within a grace period, before\n * it closes the database on shutdown.\n */\n /** No event in flight or queued. */\n get idle(): boolean {\n return !this.#active && !this.#queue.length;\n }\n settled(): Promise<void> {\n if (!this.#active && !this.#queue.length) return Promise.resolve();\n return new Promise((resolve) => this.#idleWaiters.push(resolve));\n }\n #idleWaiters: (() => void)[] = [];\n #notifyIdle(): void {\n const waiters = this.#idleWaiters;\n this.#idleWaiters = [];\n for (const w of waiters) w();\n }\n\n /** Closed for good: storage calls throw ObjectClosedError. */\n #closed = false;\n readonly #closing = new AbortController();\n /** Aborts when the host is shutting down: the signal of the requests it is handed. */\n get closing(): AbortSignal {\n return this.#closing.signal;\n }\n /** The first step of a shutdown: requests in flight see their signal abort. */\n shutdown(): void {\n if (this.#closing.signal.aborted) return;\n this.#closing.abort(new ObjectClosedError(this.cellKey));\n for (const facet of this.#facets) facet.shutdown();\n }\n\n /** Settles once the cell lease is released (a store closed earlier would keep it held). */\n close(): Promise<void> {\n this.shutdown();\n this.#closed = true;\n for (const facet of this.#facets) void facet.close();\n this.#facets.clear();\n if (!this.#dbClosed) this.#db.close();\n // Events still queued fail (each checks #closed first); nothing more runs here.\n for (const queued of this.#queue.splice(0)) queued();\n this.#notifyIdle();\n // Hand the cell over at once instead of letting the lease expire.\n const released = this.#release?.().catch(() => {});\n this.#release = undefined;\n return released ?? Promise.resolve();\n }\n #release: (() => Promise<void>) | undefined;\n /** The hosts of this cell's facets: their databases close with the root's. */\n readonly #facets = new Set<ObjectHost>();\n\n /**\n * Brings the local database to the storage's state: restores the image, then replays the log.\n * Without `rebuild` only an empty database is restored (the local file is the primary copy);\n * with it, a non-empty one is replaced too — dropped first when the storage has no image.\n */\n async #catchUp(rebuild: boolean): Promise<void> {\n const { load, replay } = this.#backup ?? {};\n if (!load && !replay) return;\n const d = this.#driver;\n const empty = Number(d.exec(\"SELECT count(*) FROM sqlite_master\", []).rows[0][0]) === 0;\n if (!empty && !rebuild) return;\n const image = await load?.(this.cellKey);\n if (image) {\n if (!d.restore) throw new Error(\"SyncSqlDriver has no restore(): cannot restore a backup\");\n d.restore(image);\n } else if (!empty) {\n // Indexes and triggers go with their tables; sqlite_* tables cannot be dropped. Foreign\n // keys are off meanwhile, so a parent table can go before its children.\n const objects = d.exec(\n \"SELECT type, name FROM sqlite_master WHERE type IN ('view', 'table') AND name NOT LIKE 'sqlite_%'\",\n [],\n ).rows;\n const fk = Number(d.exec(\"PRAGMA foreign_keys\", []).rows[0][0]);\n d.exec(\"PRAGMA foreign_keys = OFF\", []);\n try {\n for (const [type, name] of objects)\n d.exec(`DROP ${type} IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`, []);\n } finally {\n d.exec(`PRAGMA foreign_keys = ${fk}`, []);\n }\n }\n // Then every logged transaction the image does not contain, in order.\n if (replay) await this.#replayLog(replay);\n }\n\n /** Applies log segments newer than the database's own log sequence (restore path). */\n async #replayLog(replay: NonNullable<CellBackup[\"replay\"]>): Promise<void> {\n const d = this.#driver;\n d.exec(LOG_TABLE, []);\n const row = d.exec(LOG_SEQ_READ, []).rows[0];\n const after = Number(row?.[0] ?? 0);\n for await (const seg of replay(this.cellKey, after)) {\n if (!d.applyChangeset)\n throw new Error(\"SyncSqlDriver cannot apply changesets: cannot replay a log\");\n d.exec(\"BEGIN\", []);\n try {\n for (const ddl of seg.ddl) d.exec(ddl, []);\n d.applyChangeset(seg.changeset);\n for (const [sql, params] of seg.statements) d.exec(sql, params);\n d.exec(LOG_SEQ_WRITE, [seg.logSeq]);\n d.exec(\"COMMIT\", []);\n } catch (e) {\n d.exec(\"ROLLBACK\", []);\n throw e;\n }\n }\n }\n\n #construct?: () => unknown;\n #root: AsyncRoot = (fn) => fn();\n readonly #open: () => void;\n #epoch: number | undefined;\n\n /**\n * celld gives each run of a facet its own scope and moves the facet database's rows to it\n * on open (storage.rs open_embedded); doing the same here reads a facet database celld\n * wrote, whatever scope it used.\n */\n /**\n * celld's alarm publication identity (storage/wake_record.rs initialize): one `_cf_WAKE`\n * row per cell carrying the writer epoch; triggers bump its sequence on every alarm change.\n */\n #initWake(): void {\n if (!this.#epoch || !this.#opts.durability.publishWake) return;\n const scope = scopeOf(this.cellKey);\n for (const ddl of CELLD_SCHEMA) this.#driver.exec(ddl, []);\n this.#driver.exec(\n `INSERT INTO _cf_WAKE(scope,epoch,sequence,at_ms)\n VALUES(?1,?2,0,(SELECT at_ms FROM _cf_ALARM WHERE scope=?1))\n ON CONFLICT(scope) DO UPDATE SET epoch=excluded.epoch WHERE excluded.epoch>_cf_WAKE.epoch`,\n [scope, this.#epoch.toString(16).padStart(16, \"0\")],\n );\n this.#wakeSeq = this.#wakeRow()?.sequence;\n }\n /**\n * A cell restored on open may carry an alarm armed by its previous owner (another node, or\n * celld). This node owns the cell now, so the alarm is its to fire: hand it to the scheduler,\n * which otherwise only hears of alarms set here (or of a later wake-index poll).\n */\n #scheduleRestoredAlarm(onAlarmChange?: (at: number) => void): void {\n let at: unknown;\n try {\n at = this.#driver.exec(\"SELECT at_ms FROM _cf_ALARM WHERE scope = ?\", [scopeOf(this.cellKey)])\n .rows[0]?.[0];\n } catch {\n return; // no alarm table: the cell never had an alarm\n }\n if (at != null) onAlarmChange?.(Number(at));\n }\n #wakeSeq: number | undefined;\n #wakeRow(): { epoch: number; sequence: number; at: number | null } | undefined {\n try {\n const r = this.#driver.exec(\"SELECT epoch, sequence, at_ms FROM _cf_WAKE WHERE scope = ?\", [\n scopeOf(this.cellKey),\n ]).rows[0];\n return r\n ? {\n epoch: Number.parseInt(String(r[0]), 16),\n sequence: Number(r[1]),\n at: r[2] == null ? null : Number(r[2]),\n }\n : undefined;\n } catch {\n return undefined;\n }\n }\n /**\n * After a commit: if it changed the alarm, a publication to run once the commit is durable\n * (celld publishes after replication).\n */\n #wakeAfterCommit(): (() => Promise<void>) | undefined {\n const publish = this.#opts.durability.publishWake;\n if (!publish || this.#opts.facet || !this.#epoch) return undefined;\n const row = this.#wakeRow();\n if (!row || row.sequence === this.#wakeSeq) return undefined;\n this.#wakeSeq = row.sequence;\n return () => publish(this.cellKey, row);\n }\n readonly #opts: { durability: CellDurability; facet?: boolean };\n\n /**\n * celld records the name an object was addressed by (`_cf_METADATA.actor_name`) and gives it\n * back as `ctx.id.name` when the object is woken by id alone (an alarm, a wake entry) —\n * celld's own queue cells rely on it. Both directions here: restore it, and record it.\n */\n #nameFromMetadata(state: { id: DurableObjectId }): void {\n if (this.#opts.facet) return;\n const scope = scopeOf(this.cellKey);\n // Reading only: no DDL or write outside a logged transaction (a changeset log replays\n // only what it captured). The name is recorded with the cell's first storage write.\n if (state.id.name !== undefined) return;\n try {\n const r = this.#driver.exec(\"SELECT actor_name FROM _cf_METADATA WHERE scope = ?\", [scope])\n .rows[0];\n if (r?.[0] != null)\n (state as { id: DurableObjectId }).id = new DurableObjectIdClass(\n state.id.toString(),\n String(r[0]),\n );\n } catch {\n // no _cf_METADATA yet\n }\n }\n\n #rescope(scope: string): void {\n for (const table of [\"_cf_KV\", \"_cf_ALARM\", \"_cf_METADATA\"])\n try {\n this.#driver.exec(`UPDATE ${table} SET scope = ? WHERE scope <> ?`, [scope, scope]);\n } catch {\n // table not created yet\n }\n }\n\n // ---- hibernation ---------------------------------------------------------------------\n #active = 0;\n #hibernated = false;\n #pinned = 0;\n /** Time of the last event's completion (the runtime's idle sweep reads it). */\n lastActive = Date.now();\n\n get hibernated(): boolean {\n return this.#hibernated;\n }\n\n /**\n * A 101 response whose server end was accepted with `accept()` (not acceptWebSocket)\n * holds a standard WebSocket: the object cannot hibernate until that socket closes —\n * as on Cloudflare, only the hibernation API lets an object sleep with open sockets.\n */\n #pinIfStandardWebSocket(r: unknown): void {\n const server = (\n r as { webSocket?: { peer?: { accepted: boolean; hibernatable: boolean } & EventTarget } }\n )?.webSocket?.peer;\n if (!server || server.hibernatable || !server.accepted) return;\n this.#pinned++;\n server.addEventListener(\"close\", () => this.#pinned--, { once: true });\n }\n\n /**\n * Drops the instance when nothing runs: no event in flight or queued, no open async\n * transaction, no standard WebSocket. Storage, alarms and hibernatable sockets stay; the\n * next event constructs the class again. Returns whether it hibernated.\n */\n hibernate(): boolean {\n if (\n this.#hibernated ||\n this.broken ||\n this.#active ||\n this.#queue.length ||\n this.#sql.held ||\n this.#pinned\n )\n return false;\n if (!this.#gate.isOpen) return false;\n this.#sql.commit();\n this.#instance = undefined;\n this.#hibernated = true;\n return true;\n }\n #dbClosed = false;\n /**\n * Closes the database of a hibernated cell (the cell lease stays); the next event reopens it.\n * A cell with changes its backup has not taken yet stays open. Returns whether it closed.\n */\n closeDatabase(): boolean {\n if (!this.#hibernated || this.#dbClosed || this.#queue.length || !this.#gate.isOpen)\n return false;\n if (this.#backup && (this.#saving || this.#seq !== this.#backedUpSeq)) return false;\n this.#db.close();\n this.#dbClosed = true;\n return true;\n }\n /** Replaces the instance with a fresh one on the SAME database (facet abort/delete). */\n restart(): void {\n if (this.#dbClosed) return; // the next event reopens it with a fresh instance\n this.#construct?.();\n }\n}\n\n/**\n * `ctx.facets` (celld docs/services/durable-object-facets.md): named child objects with a\n * SQLite database of their own (`<cellKey>/facets/<name>`), started on first call from a\n * class (or class handle) returned by the callback; the name alone selects the database.\n */\ninterface FacetTarget {\n call(method: string, args: unknown[]): Promise<unknown>;\n fetch(req: Request): Promise<Response>;\n restart(): void | Promise<void>;\n delete(): Promise<void>;\n}\n\nfunction createFacets(\n parent: { id: DurableObjectId; env: unknown; cellKey: string; epoch?: () => number | undefined },\n spawn: (\n name: string,\n cls: DurableObjectClass,\n env: unknown,\n id: DurableObjectId,\n props?: unknown,\n ) => ObjectHost,\n) {\n const running = new Map<string, Promise<FacetTarget>>();\n // abort() stops the stubs handed out so far (their calls throw the reason); a later\n // get() starts the facet again on the same database — as celld does.\n const generation = new Map<string, { n: number; reason?: unknown }>();\n const local = (h: ObjectHost): FacetTarget => ({\n call: (method, args) =>\n h.deliver((obj) => {\n const fn = obj[method];\n if (typeof fn !== \"function\") throw new TypeError(`${method} is not a function`);\n return fn.apply(obj, args);\n }),\n fetch: (req) => h.deliver((obj) => obj.fetch(closingWith(req, h.closing))),\n restart: () => h.restart(),\n delete: async () => {\n await h.deliver((_o, state) => state.storage.deleteAll());\n h.restart();\n },\n });\n /** A class of isolated loaded code: the facet's instance and SQLite live in the isolate. */\n const isolated = (iso: IsolatedClass, cellKey: string, idName?: string): FacetTarget => {\n const attached = iso.attach?.(cellKey, parent.epoch?.(), idName);\n const ready = async () => attached;\n return {\n call: async (method, args) => (await ready(), iso.call(cellKey, method, args)),\n fetch: async (req) => (await ready(), iso.fetch(cellKey, req)),\n restart: async () => (await ready(), iso.restart(cellKey)),\n delete: async () => (await ready(), iso.delete(cellKey)),\n };\n };\n\n const targetOf = (name: string, start?: () => unknown): Promise<FacetTarget> => {\n let p = running.get(name);\n if (!p) {\n if (!start) return Promise.reject(new Error(`Facet \"${name}\" is not running`));\n p = (async () => {\n const info = (await start()) as { class: unknown; id?: unknown };\n let cls: DurableObjectClass;\n let env = parent.env;\n let props: unknown;\n if (isClassHandle(info.class)) {\n const r = await info.class.resolve();\n if (\"isolated\" in r)\n return isolated(\n r.isolated,\n `${parent.cellKey}/facets/${facetSegment(name)}`,\n // The facet's own `ctx.id` (partyserver's `this.name` reads its name).\n info.id instanceof DurableObjectIdClass ? info.id.name : undefined,\n );\n ({ cls, env, props } = r);\n } else cls = info.class as DurableObjectClass;\n const id = info.id instanceof DurableObjectIdClass ? info.id : parent.id;\n return local(spawn(name, cls, env, id, props));\n })();\n p.catch(() => running.delete(name));\n running.set(name, p);\n }\n return p;\n };\n return {\n get(name: string, start: () => unknown) {\n if (new TextEncoder().encode(name).byteLength > 256)\n throw new Error(\"A facet name has a limit of 256 bytes\");\n const gen = generation.get(name)?.n ?? 0;\n const live = () => {\n const g = generation.get(name);\n if (g && g.n !== gen) throw g.reason;\n };\n return asyncStub(\n async (method, args) => (live(), await targetOf(name, start)).call(method, args),\n async (req) => (live(), await targetOf(name, start)).fetch(req),\n );\n },\n abort(name: string, reason?: unknown) {\n const n = (generation.get(name)?.n ?? 0) + 1;\n generation.set(name, { n, reason: reason ?? new Error(`Facet \"${name}\" was aborted`) });\n // The database stays: the next call on a new stub gets a fresh instance over it.\n void running.get(name)?.then((t) => t.restart());\n },\n async delete(name: string) {\n const p = running.get(name);\n generation.set(name, {\n n: (generation.get(name)?.n ?? 0) + 1,\n reason: new Error(`Facet \"${name}\" was deleted`),\n });\n if (p) await (await p).delete();\n },\n };\n}\n\n/** The cell's lease is held by another owner (route the request there, or retry later). */\nexport class CellOwnedElsewhereError extends Error {\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} is owned by another node`);\n this.name = \"CellOwnedElsewhereError\";\n }\n}\n\n/** celld's path segment for a facet name: the first 16 bytes of SHA-256(name), hex. */\nexport function facetSegment(name: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(name)).subarray(0, 16));\n}\n"]}
1
+ {"version":3,"file":"object-host.js","sourceRoot":"","sources":["../../src/core/object-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\nimport type {\n BackupInfo,\n CellBackup,\n CellDurability,\n Lease,\n OpenCellSql,\n SyncSqlDriver,\n ValueCodec,\n} from \"../ports.js\";\nimport type { AsyncRoot } from \"./async-context.js\";\nimport { CELLD_SCHEMA, LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE, scopeOf } from \"./celld-schema.js\";\nimport { InputGate, OutputGate } from \"./gates.js\";\nimport {\n asyncStub,\n type DurableObjectClass,\n type IsolatedClass,\n isClassHandle,\n} from \"./handles.js\";\nimport { type DurableObjectId, DurableObjectId as DurableObjectIdClass } from \"./id.js\";\nimport { SqlStorage } from \"./sql-storage.js\";\nimport { DurableObjectState } from \"./state.js\";\nimport { DurableObjectStorage, SyncKvStorage } from \"./storage.js\";\n\n/**\n * The request as the object sees it: its signal also aborts when the host closes (the runtime\n * shuts down), as on Cloudflare when the client goes away; a long poll or an SSE stream that\n * waits on it then ends instead of running on into a closed database.\n *\n * The request is not copied: its `signal` becomes a getter that builds the merged signal the\n * first time it is read. Copying a Request and merging two signals cost about 7 µs a request, as\n * much as a small handler's whole turn, and most handlers never read the signal. The request is\n * the caller's own object (`runtime.fetch`) or a stub's fresh copy (a Durable Object's `fetch`);\n * `cf` and the upgrade's `headers` that cellb sets on it stay as they are. A copy the handler\n * makes itself (`new Request(req)`) takes the request's own signal, without the host's.\n */\nexport function closingWith(req: Request, closing: AbortSignal): Request {\n if (closing.aborted) return req;\n const own = signalOf(req);\n let merged: AbortSignal | undefined;\n try {\n Object.defineProperty(req, \"signal\", {\n configurable: true,\n enumerable: false,\n get: () => {\n if (!merged) {\n const before = own();\n merged = before ? AbortSignal.any([before, closing]) : closing;\n }\n return merged;\n },\n });\n return req;\n } catch {\n // A request whose `signal` cannot be redefined: a copy with the merged signal, as before.\n const r = new Request(req, { signal: AbortSignal.any([req.signal, closing]) });\n for (const k of [\"cf\", \"headers\"]) {\n const d = Object.getOwnPropertyDescriptor(req, k);\n if (d) Object.defineProperty(r, k, d);\n }\n return r;\n }\n}\n\n/** Reads `req.signal` as it is now: a getter set by an earlier `closingWith`, or the Request's own. */\nfunction signalOf(req: Request): () => AbortSignal | undefined {\n for (let o: object | null = req; o; o = Object.getPrototypeOf(o)) {\n const d = Object.getOwnPropertyDescriptor(o, \"signal\");\n if (d) return d.get ? () => d.get?.call(req) : () => d.value;\n }\n return () => undefined;\n}\n\n/** The object's host was closed for good: its storage and events fail with this. */\nexport class ObjectClosedError extends Error {\n override name = \"ObjectClosedError\";\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} was closed (its runtime shut down, or it moved or was reset)`);\n }\n}\n\nexport class BrokenObjectError extends Error {\n constructor(cause: unknown, reason = \"its storage failed to commit durably\") {\n const detail = cause instanceof Error ? `: ${cause.message}` : \"\";\n super(`Durable Object reset because ${reason}${detail}`, { cause });\n this.name = \"BrokenObjectError\";\n }\n}\n\n/**\n * One live instance of one Durable Object: its SQLite, gates and dispatcher.\n * Everything that reaches the object (fetch, RPC, later alarms/WebSockets)\n * goes through `deliver()`.\n */\nexport class ObjectHost {\n readonly cellKey: string;\n readonly #gate = new InputGate();\n readonly #out = new OutputGate();\n /** The open database; `#driver` follows it, so it can be closed while idle and reopened. */\n #db!: SyncSqlDriver;\n readonly #driver: SyncSqlDriver = new Proxy({} as SyncSqlDriver, {\n get: (_t, k) => {\n // Closed for good (its runtime or shard shut down): code still running in the object\n // learns why, instead of SQLite's \"DB has been closed\".\n if (this.#closed && k !== \"close\")\n return () => {\n throw new ObjectClosedError(this.cellKey);\n };\n const v = (this.#db as unknown as Record<PropertyKey, unknown>)[k];\n return typeof v === \"function\" ? v.bind(this.#db) : v;\n },\n });\n readonly #sql: SqlStorage;\n #instance: any;\n readonly #backup?: CellBackup;\n #backedUpSeq = 0;\n #saving: Promise<void> | undefined;\n readonly state: DurableObjectState;\n #seq = 0;\n broken = false;\n #brokenCause: unknown;\n\n /** blockConcurrencyWhile() rejected (CF: the object is reset; queued events fail). */\n #breakOn(e: unknown): void {\n this.broken = true;\n this.#brokenCause = e;\n }\n\n constructor(opts: {\n cellKey: string;\n id: DurableObjectId;\n cls: DurableObjectClass;\n env: unknown;\n openSql: OpenCellSql;\n durability: CellDurability;\n codec: ValueCodec;\n waitUntil: (p: Promise<unknown>) => void;\n backup?: CellBackup;\n /** The stored alarm changed (null = cleared). */\n onAlarmChange?: (at: number | null) => void;\n /** `ctx.exports` (loopback handles of the Worker's exports). */\n exports?: Record<string, unknown>;\n /** `ctx.props` of a facet started from a class handle with `{ props }`. */\n props?: unknown;\n /** SQLite extensions to load into every cell database (e.g. \"sqlite_vec\"). */\n sqlExtensions?: string[];\n /** storage.deleteAll() keeps the alarm (`delete_all_preserves_alarm`). */\n deleteAllPreservesAlarm?: boolean;\n /**\n * Ownership: acquire the cell's lease before restoring it. No lease → the cell is owned\n * elsewhere (the host refuses events). The lease epoch fences the cell's log segments;\n * losing the lease breaks the host so it stops serving.\n */\n /** Owner epoch when no lease is taken (facets inherit their root's). */\n epoch?: number;\n /** A facet: on open its rows move to this run's scope, as celld does. */\n facet?: boolean;\n acquire?: Lease[\"tryAcquire\"];\n /** The async context events start in (`asyncRoot()`): not the caller's, as on Cloudflare. */\n asyncRoot?: AsyncRoot;\n }) {\n this.#backup = opts.backup;\n this.cellKey = opts.cellKey;\n this.#epoch = opts.epoch;\n this.#opts = opts;\n this.#open = () => {\n this.#db = opts.openSql(opts.cellKey);\n for (const ext of opts.sqlExtensions ?? []) this.#db.loadExtension(ext);\n };\n this.#open();\n this.#sql = new SqlStorage(\n this.#driver,\n (changes) => {\n if (changes && this.#epoch !== undefined) changes.epoch = this.#epoch;\n // Page-level logs (LTX): the changed pages straight from the page hook when the driver\n // has one; the image only on demand (a generation's first snapshot, or no hook).\n const d = this.#driver;\n const seq = ++this.#seq;\n const pages = opts.durability.capturePages ? d.takeDirtyPages() : undefined;\n const snap = () => d.pageImage?.() ?? d.image?.();\n // The log runs later, after the next event may have opened its transaction, and an\n // image cannot be taken inside one (VACUUM INTO). When the log will surely need it\n // (no page hook) or likely does (this host's first commit), take it now.\n const image = opts.durability.capturePages\n ? !pages || seq === 1\n ? snap()\n : snap\n : undefined;\n const durable = opts.durability.committed(this.cellKey, {\n seq,\n changes,\n image,\n pages,\n epoch: this.#epoch,\n });\n const wake = this.#wakeAfterCommit();\n return this.#out.track(wake ? durable.then(wake) : durable);\n },\n { capture: !!opts.durability.captureChanges },\n );\n // The cell's scope in celld's tables (\"Class:idhex\"), so its database is celld's format.\n const kv = new SyncKvStorage(this.#sql, opts.codec, scopeOf(opts.cellKey));\n if (!opts.facet) kv.actorName = opts.id.name;\n const storage = new DurableObjectStorage(this.#sql, kv, this.#gate, () => this.#barrier());\n if (opts.onAlarmChange) storage.onAlarmChange = opts.onAlarmChange;\n storage.deleteAllPreservesAlarm = !!opts.deleteAllPreservesAlarm;\n const state = new DurableObjectState(opts.id, storage, this.#gate, opts.waitUntil, (e) =>\n this.#breakOn(e),\n );\n this.state = state;\n state.attachDispatcher((fn) => this.deliver(fn));\n // ctx.abort(reason) (workerd, celld): the object resets — a fresh instance on the same\n // database serves the next event; the calling event fails with the reason. Writes the event\n // already made still commit (celld: celld's workflow cell aborts after its delete commit).\n (state as unknown as { abort(reason?: unknown): never }).abort = (reason?: unknown): never => {\n queueMicrotask(() => this.restart());\n throw reason ?? new Error(\"Durable Object reset because its code calls abort()\");\n };\n state.exports = opts.exports ?? {};\n state.props = opts.props;\n state.facets = createFacets(\n { ...opts, epoch: () => this.#epoch },\n (name, cls, env, id, props) => {\n const facet = new ObjectHost({\n ...opts,\n // celld's facet stream: <parent>/facets/<SHA-256(name)[0..16] hex> (engine_api.rs)\n cellKey: `${opts.cellKey}/facets/${facetSegment(name)}`,\n id,\n cls,\n env,\n props,\n onAlarmChange: undefined,\n // A facet is part of its root's cell: no lease of its own, the root's epoch.\n acquire: undefined,\n epoch: this.#epoch,\n facet: true,\n });\n this.#facets.add(facet); // closed with its root\n return facet;\n },\n );\n const root = opts.asyncRoot ?? ((fn) => fn());\n this.#root = root;\n const construct = () => root(() => (this.#instance = new opts.cls(state, opts.env)));\n this.#construct = construct;\n const load = opts.backup?.load;\n const replay = opts.backup?.replay;\n const acquire = opts.acquire;\n if (!load && !replay && !acquire) {\n this.#nameFromMetadata(state);\n construct();\n return;\n }\n // Restore-on-open: events queue behind the closed gate until the image is in.\n void this.#gate\n .runClosed(async () => {\n if (acquire) {\n const lease = await acquire(this.cellKey);\n if (!lease) throw new CellOwnedElsewhereError(this.cellKey);\n this.#epoch = lease.epoch;\n this.#release = lease.release;\n lease.lost.addEventListener(\n \"abort\",\n () => this.#breakOn(new Error(`lease of ${this.cellKey} lost`)),\n {\n once: true,\n },\n );\n }\n // Under a lease (the cell's own, or its root's for a facet) the bucket is the cell's\n // truth: a local file kept from an earlier ownership is older than what other owners\n // wrote since, and may hold commits that never became durable.\n await this.#catchUp(this.#epoch !== undefined);\n if (opts.facet) this.#rescope(scopeOf(opts.cellKey));\n else {\n this.#initWake();\n this.#scheduleRestoredAlarm(opts.onAlarmChange);\n }\n this.#nameFromMetadata(state);\n construct();\n })\n .catch((e) => this.#breakOn(e));\n }\n\n /**\n * Takes an image if the cell changed since the last successful save and hands\n * it to `backup.save`. Taken synchronously between events → a consistent image.\n * Skipped while an async transaction() holds the database or a save is running.\n */\n backupIfDirty(reason: BackupInfo[\"reason\"], now: number): Promise<void> {\n const b = this.#backup;\n if (!b || this.broken || this.#saving || this.#seq === this.#backedUpSeq)\n return this.#saving ?? Promise.resolve();\n if (!this.#driver.image)\n return Promise.reject(new Error(\"SyncSqlDriver has no image(): cannot back up\"));\n if (this.#sql.held) return Promise.resolve(); // mid-transaction: next round\n this.#sql.commit();\n const seq = this.#seq;\n let logSeq = 0;\n try {\n logSeq = Number(this.#driver.exec(LOG_SEQ_READ, []).rows[0]?.[0] ?? 0);\n } catch {\n // no _cf_LOG yet\n }\n const image = this.#driver.image();\n this.#saving = b\n .save(this.cellKey, image, { seq, takenAt: now, reason, logSeq })\n .then(\n () => {\n this.#backedUpSeq = Math.max(this.#backedUpSeq, seq);\n },\n (e) => b.onError?.(this.cellKey, e),\n )\n .finally(() => (this.#saving = undefined));\n return this.#saving;\n }\n\n /**\n * Input gate → handler → commit → output gate (durability) → result.\n *\n * Events are queued and STARTED synchronously by a pump only while the gate\n * is open: the first storage op of a handler closes the gate before the\n * next event can start (checking the gate in an `await` continuation is too\n * late — every queued continuation would see it open).\n */\n deliver<T>(fn: (instance: any, state: DurableObjectState) => T | Promise<T>): Promise<T> {\n if (this.#closed) return Promise.reject(new ObjectClosedError(this.cellKey));\n if (this.broken) return Promise.reject(new BrokenObjectError(undefined));\n return new Promise<T>((resolve, reject) => {\n this.#queue.push(() => {\n if (this.#closed) return reject(new ObjectClosedError(this.cellKey));\n if (this.broken)\n return reject(new BrokenObjectError(this.#brokenCause, \"its initialization failed\"));\n let started: Promise<T>;\n this.#active++;\n try {\n started = Promise.resolve(\n this.#root(() => this.state.storage.runEvent(() => fn(this.#instance, this.state))),\n );\n } catch (e) {\n started = Promise.reject(e);\n }\n const done = () => {\n this.#active--;\n this.lastActive = Date.now();\n if (!this.#active && !this.#queue.length) this.#notifyIdle();\n };\n started.then(\n (r) => {\n this.#pinIfStandardWebSocket(r);\n this.#barrier().then(\n () => (done(), resolve(r)),\n (e) => (done(), reject(e)),\n );\n },\n (e) =>\n this.#barrier().then(\n () => (done(), reject(e)),\n (e2) => (done(), reject(e2)),\n ),\n );\n });\n this.#pump();\n });\n }\n\n #queue: (() => void)[] = [];\n #pumpWaiting = false;\n #pump = (): void => {\n this.#pumpWaiting = false;\n while (this.#queue.length && this.#gate.isOpen) {\n // A database closed while idle: reopen it (and catch up) before anything runs.\n if (this.#dbClosed) {\n this.#dbClosed = false;\n void this.#gate\n .runClosed(async () => {\n this.#open();\n // The lease was held throughout: a kept file is current, an empty one is restored.\n await this.#catchUp(false);\n })\n .catch((e) => this.#breakOn(e));\n continue;\n }\n // Waking from hibernation: the constructor runs again before the event (and may\n // close the gate with blockConcurrencyWhile, which the loop then respects).\n if (this.#hibernated) {\n this.#hibernated = false;\n this.#construct?.();\n continue;\n }\n this.#queue.shift()!();\n }\n if (this.#queue.length && !this.#pumpWaiting) {\n this.#pumpWaiting = true;\n this.#gate.onOpen(this.#pump);\n }\n };\n\n async #barrier(): Promise<void> {\n try {\n this.#sql.commit();\n await this.#out.barrier();\n } catch (e) {\n this.broken = true;\n try {\n this.#sql.rollback();\n } catch {}\n throw new BrokenObjectError(e);\n }\n }\n\n /**\n * Settles once no event is in flight or queued (a response body still streaming is not an\n * event: its handler has returned). The runtime waits for it, within a grace period, before\n * it closes the database on shutdown.\n */\n /** No event in flight or queued. */\n get idle(): boolean {\n return !this.#active && !this.#queue.length;\n }\n settled(): Promise<void> {\n if (!this.#active && !this.#queue.length) return Promise.resolve();\n return new Promise((resolve) => this.#idleWaiters.push(resolve));\n }\n #idleWaiters: (() => void)[] = [];\n #notifyIdle(): void {\n const waiters = this.#idleWaiters;\n this.#idleWaiters = [];\n for (const w of waiters) w();\n }\n\n /** Closed for good: storage calls throw ObjectClosedError. */\n #closed = false;\n readonly #closing = new AbortController();\n /** Aborts when the host is shutting down: the signal of the requests it is handed. */\n get closing(): AbortSignal {\n return this.#closing.signal;\n }\n /** The first step of a shutdown: requests in flight see their signal abort. */\n shutdown(): void {\n if (this.#closing.signal.aborted) return;\n this.#closing.abort(new ObjectClosedError(this.cellKey));\n for (const facet of this.#facets) facet.shutdown();\n }\n\n /** Settles once the cell lease is released (a store closed earlier would keep it held). */\n close(): Promise<void> {\n this.shutdown();\n this.#closed = true;\n for (const facet of this.#facets) void facet.close();\n this.#facets.clear();\n if (!this.#dbClosed) this.#db.close();\n // Events still queued fail (each checks #closed first); nothing more runs here.\n for (const queued of this.#queue.splice(0)) queued();\n this.#notifyIdle();\n // Hand the cell over at once instead of letting the lease expire.\n const released = this.#release?.().catch(() => {});\n this.#release = undefined;\n return released ?? Promise.resolve();\n }\n #release: (() => Promise<void>) | undefined;\n /** The hosts of this cell's facets: their databases close with the root's. */\n readonly #facets = new Set<ObjectHost>();\n\n /**\n * Brings the local database to the storage's state: restores the image, then replays the log.\n * Without `rebuild` only an empty database is restored (the local file is the primary copy);\n * with it, a non-empty one is replaced too — dropped first when the storage has no image.\n */\n async #catchUp(rebuild: boolean): Promise<void> {\n const { load, replay } = this.#backup ?? {};\n if (!load && !replay) return;\n const d = this.#driver;\n const empty = Number(d.exec(\"SELECT count(*) FROM sqlite_master\", []).rows[0][0]) === 0;\n if (!empty && !rebuild) return;\n const image = await load?.(this.cellKey);\n if (image) {\n if (!d.restore) throw new Error(\"SyncSqlDriver has no restore(): cannot restore a backup\");\n d.restore(image);\n } else if (!empty) {\n // Indexes and triggers go with their tables; sqlite_* tables cannot be dropped. Foreign\n // keys are off meanwhile, so a parent table can go before its children.\n const objects = d.exec(\n \"SELECT type, name FROM sqlite_master WHERE type IN ('view', 'table') AND name NOT LIKE 'sqlite_%'\",\n [],\n ).rows;\n const fk = Number(d.exec(\"PRAGMA foreign_keys\", []).rows[0][0]);\n d.exec(\"PRAGMA foreign_keys = OFF\", []);\n try {\n for (const [type, name] of objects)\n d.exec(`DROP ${type} IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`, []);\n } finally {\n d.exec(`PRAGMA foreign_keys = ${fk}`, []);\n }\n }\n // Then every logged transaction the image does not contain, in order.\n if (replay) await this.#replayLog(replay);\n }\n\n /** Applies log segments newer than the database's own log sequence (restore path). */\n async #replayLog(replay: NonNullable<CellBackup[\"replay\"]>): Promise<void> {\n const d = this.#driver;\n d.exec(LOG_TABLE, []);\n const row = d.exec(LOG_SEQ_READ, []).rows[0];\n const after = Number(row?.[0] ?? 0);\n for await (const seg of replay(this.cellKey, after)) {\n if (!d.applyChangeset)\n throw new Error(\"SyncSqlDriver cannot apply changesets: cannot replay a log\");\n d.exec(\"BEGIN\", []);\n try {\n for (const ddl of seg.ddl) d.exec(ddl, []);\n d.applyChangeset(seg.changeset);\n for (const [sql, params] of seg.statements) d.exec(sql, params);\n d.exec(LOG_SEQ_WRITE, [seg.logSeq]);\n d.exec(\"COMMIT\", []);\n } catch (e) {\n d.exec(\"ROLLBACK\", []);\n throw e;\n }\n }\n }\n\n #construct?: () => unknown;\n #root: AsyncRoot = (fn) => fn();\n readonly #open: () => void;\n #epoch: number | undefined;\n\n /**\n * celld gives each run of a facet its own scope and moves the facet database's rows to it\n * on open (storage.rs open_embedded); doing the same here reads a facet database celld\n * wrote, whatever scope it used.\n */\n /**\n * celld's alarm publication identity (storage/wake_record.rs initialize): one `_cf_WAKE`\n * row per cell carrying the writer epoch; triggers bump its sequence on every alarm change.\n */\n #initWake(): void {\n if (!this.#epoch || !this.#opts.durability.publishWake) return;\n const scope = scopeOf(this.cellKey);\n for (const ddl of CELLD_SCHEMA) this.#driver.exec(ddl, []);\n this.#driver.exec(\n `INSERT INTO _cf_WAKE(scope,epoch,sequence,at_ms)\n VALUES(?1,?2,0,(SELECT at_ms FROM _cf_ALARM WHERE scope=?1))\n ON CONFLICT(scope) DO UPDATE SET epoch=excluded.epoch WHERE excluded.epoch>_cf_WAKE.epoch`,\n [scope, this.#epoch.toString(16).padStart(16, \"0\")],\n );\n this.#wakeSeq = this.#wakeRow()?.sequence;\n }\n /**\n * A cell restored on open may carry an alarm armed by its previous owner (another node, or\n * celld). This node owns the cell now, so the alarm is its to fire: hand it to the scheduler,\n * which otherwise only hears of alarms set here (or of a later wake-index poll).\n */\n #scheduleRestoredAlarm(onAlarmChange?: (at: number) => void): void {\n let at: unknown;\n try {\n at = this.#driver.exec(\"SELECT at_ms FROM _cf_ALARM WHERE scope = ?\", [scopeOf(this.cellKey)])\n .rows[0]?.[0];\n } catch {\n return; // no alarm table: the cell never had an alarm\n }\n if (at != null) onAlarmChange?.(Number(at));\n }\n #wakeSeq: number | undefined;\n #wakeRow(): { epoch: number; sequence: number; at: number | null } | undefined {\n try {\n const r = this.#driver.exec(\"SELECT epoch, sequence, at_ms FROM _cf_WAKE WHERE scope = ?\", [\n scopeOf(this.cellKey),\n ]).rows[0];\n return r\n ? {\n epoch: Number.parseInt(String(r[0]), 16),\n sequence: Number(r[1]),\n at: r[2] == null ? null : Number(r[2]),\n }\n : undefined;\n } catch {\n return undefined;\n }\n }\n /**\n * After a commit: if it changed the alarm, a publication to run once the commit is durable\n * (celld publishes after replication).\n */\n #wakeAfterCommit(): (() => Promise<void>) | undefined {\n const publish = this.#opts.durability.publishWake;\n if (!publish || this.#opts.facet || !this.#epoch) return undefined;\n const row = this.#wakeRow();\n if (!row || row.sequence === this.#wakeSeq) return undefined;\n this.#wakeSeq = row.sequence;\n return () => publish(this.cellKey, row);\n }\n readonly #opts: { durability: CellDurability; facet?: boolean };\n\n /**\n * celld records the name an object was addressed by (`_cf_METADATA.actor_name`) and gives it\n * back as `ctx.id.name` when the object is woken by id alone (an alarm, a wake entry) —\n * celld's own queue cells rely on it. Both directions here: restore it, and record it.\n */\n #nameFromMetadata(state: { id: DurableObjectId }): void {\n if (this.#opts.facet) return;\n const scope = scopeOf(this.cellKey);\n // Reading only: no DDL or write outside a logged transaction (a changeset log replays\n // only what it captured). The name is recorded with the cell's first storage write.\n if (state.id.name !== undefined) return;\n try {\n const r = this.#driver.exec(\"SELECT actor_name FROM _cf_METADATA WHERE scope = ?\", [scope])\n .rows[0];\n if (r?.[0] != null)\n (state as { id: DurableObjectId }).id = new DurableObjectIdClass(\n state.id.toString(),\n String(r[0]),\n );\n } catch {\n // no _cf_METADATA yet\n }\n }\n\n #rescope(scope: string): void {\n for (const table of [\"_cf_KV\", \"_cf_ALARM\", \"_cf_METADATA\"])\n try {\n this.#driver.exec(`UPDATE ${table} SET scope = ? WHERE scope <> ?`, [scope, scope]);\n } catch {\n // table not created yet\n }\n }\n\n // ---- hibernation ---------------------------------------------------------------------\n #active = 0;\n #hibernated = false;\n #pinned = 0;\n /** Time of the last event's completion (the runtime's idle sweep reads it). */\n lastActive = Date.now();\n\n get hibernated(): boolean {\n return this.#hibernated;\n }\n\n /**\n * A 101 response whose server end was accepted with `accept()` (not acceptWebSocket)\n * holds a standard WebSocket: the object cannot hibernate until that socket closes —\n * as on Cloudflare, only the hibernation API lets an object sleep with open sockets.\n */\n #pinIfStandardWebSocket(r: unknown): void {\n const server = (\n r as { webSocket?: { peer?: { accepted: boolean; hibernatable: boolean } & EventTarget } }\n )?.webSocket?.peer;\n if (!server || server.hibernatable || !server.accepted) return;\n this.#pinned++;\n server.addEventListener(\"close\", () => this.#pinned--, { once: true });\n }\n\n /**\n * Drops the instance when nothing runs: no event in flight or queued, no open async\n * transaction, no standard WebSocket. Storage, alarms and hibernatable sockets stay; the\n * next event constructs the class again. Returns whether it hibernated.\n */\n hibernate(): boolean {\n if (\n this.#hibernated ||\n this.broken ||\n this.#active ||\n this.#queue.length ||\n this.#sql.held ||\n this.#pinned\n )\n return false;\n if (!this.#gate.isOpen) return false;\n this.#sql.commit();\n this.#instance = undefined;\n this.#hibernated = true;\n return true;\n }\n #dbClosed = false;\n /**\n * Closes the database of a hibernated cell (the cell lease stays); the next event reopens it.\n * A cell with changes its backup has not taken yet stays open. Returns whether it closed.\n */\n closeDatabase(): boolean {\n if (!this.#hibernated || this.#dbClosed || this.#queue.length || !this.#gate.isOpen)\n return false;\n if (this.#backup && (this.#saving || this.#seq !== this.#backedUpSeq)) return false;\n this.#db.close();\n this.#dbClosed = true;\n return true;\n }\n /** Replaces the instance with a fresh one on the SAME database (facet abort/delete). */\n restart(): void {\n if (this.#dbClosed) return; // the next event reopens it with a fresh instance\n this.#construct?.();\n }\n}\n\n/**\n * `ctx.facets` (celld docs/services/durable-object-facets.md): named child objects with a\n * SQLite database of their own (`<cellKey>/facets/<name>`), started on first call from a\n * class (or class handle) returned by the callback; the name alone selects the database.\n */\ninterface FacetTarget {\n call(method: string, args: unknown[]): Promise<unknown>;\n fetch(req: Request): Promise<Response>;\n restart(): void | Promise<void>;\n delete(): Promise<void>;\n}\n\nfunction createFacets(\n parent: { id: DurableObjectId; env: unknown; cellKey: string; epoch?: () => number | undefined },\n spawn: (\n name: string,\n cls: DurableObjectClass,\n env: unknown,\n id: DurableObjectId,\n props?: unknown,\n ) => ObjectHost,\n) {\n const running = new Map<string, Promise<FacetTarget>>();\n // abort() stops the stubs handed out so far (their calls throw the reason); a later\n // get() starts the facet again on the same database — as celld does.\n const generation = new Map<string, { n: number; reason?: unknown }>();\n const local = (h: ObjectHost): FacetTarget => ({\n call: (method, args) =>\n h.deliver((obj) => {\n const fn = obj[method];\n if (typeof fn !== \"function\") throw new TypeError(`${method} is not a function`);\n return fn.apply(obj, args);\n }),\n fetch: (req) => h.deliver((obj) => obj.fetch(closingWith(req, h.closing))),\n restart: () => h.restart(),\n delete: async () => {\n await h.deliver((_o, state) => state.storage.deleteAll());\n h.restart();\n },\n });\n /** A class of isolated loaded code: the facet's instance and SQLite live in the isolate. */\n const isolated = (iso: IsolatedClass, cellKey: string, idName?: string): FacetTarget => {\n const attached = iso.attach?.(cellKey, parent.epoch?.(), idName);\n const ready = async () => attached;\n return {\n call: async (method, args) => (await ready(), iso.call(cellKey, method, args)),\n fetch: async (req) => (await ready(), iso.fetch(cellKey, req)),\n restart: async () => (await ready(), iso.restart(cellKey)),\n delete: async () => (await ready(), iso.delete(cellKey)),\n };\n };\n\n const targetOf = (name: string, start?: () => unknown): Promise<FacetTarget> => {\n let p = running.get(name);\n if (!p) {\n if (!start) return Promise.reject(new Error(`Facet \"${name}\" is not running`));\n p = (async () => {\n const info = (await start()) as { class: unknown; id?: unknown };\n let cls: DurableObjectClass;\n let env = parent.env;\n let props: unknown;\n if (isClassHandle(info.class)) {\n const r = await info.class.resolve();\n if (\"isolated\" in r)\n return isolated(\n r.isolated,\n `${parent.cellKey}/facets/${facetSegment(name)}`,\n // The facet's own `ctx.id` (partyserver's `this.name` reads its name).\n info.id instanceof DurableObjectIdClass ? info.id.name : undefined,\n );\n ({ cls, env, props } = r);\n } else cls = info.class as DurableObjectClass;\n const id = info.id instanceof DurableObjectIdClass ? info.id : parent.id;\n return local(spawn(name, cls, env, id, props));\n })();\n p.catch(() => running.delete(name));\n running.set(name, p);\n }\n return p;\n };\n return {\n get(name: string, start: () => unknown) {\n if (new TextEncoder().encode(name).byteLength > 256)\n throw new Error(\"A facet name has a limit of 256 bytes\");\n const gen = generation.get(name)?.n ?? 0;\n const live = () => {\n const g = generation.get(name);\n if (g && g.n !== gen) throw g.reason;\n };\n return asyncStub(\n async (method, args) => (live(), await targetOf(name, start)).call(method, args),\n async (req) => (live(), await targetOf(name, start)).fetch(req),\n );\n },\n abort(name: string, reason?: unknown) {\n const n = (generation.get(name)?.n ?? 0) + 1;\n generation.set(name, { n, reason: reason ?? new Error(`Facet \"${name}\" was aborted`) });\n // The database stays: the next call on a new stub gets a fresh instance over it.\n void running.get(name)?.then((t) => t.restart());\n },\n async delete(name: string) {\n const p = running.get(name);\n generation.set(name, {\n n: (generation.get(name)?.n ?? 0) + 1,\n reason: new Error(`Facet \"${name}\" was deleted`),\n });\n if (p) await (await p).delete();\n },\n };\n}\n\n/** The cell's lease is held by another owner (route the request there, or retry later). */\nexport class CellOwnedElsewhereError extends Error {\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} is owned by another node`);\n this.name = \"CellOwnedElsewhereError\";\n }\n}\n\n/** celld's path segment for a facet name: the first 16 bytes of SHA-256(name), hex. */\nexport function facetSegment(name: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(name)).subarray(0, 16));\n}\n"]}
@@ -14,6 +14,11 @@ export declare class SqlStorageCursor<T = Record<string, unknown>> implements It
14
14
  }
15
15
  export declare class SqlStorage {
16
16
  #private;
17
+ /**
18
+ * Set by `ctx.storage`: true when called from another event while an async `transaction()` is
19
+ * open, where async context tells them apart.
20
+ */
21
+ outsideTransaction?: () => boolean;
17
22
  constructor(driver: SyncSqlDriver, onCommit: (changes?: CommitChanges) => void, opts?: {
18
23
  capture?: boolean;
19
24
  });
@@ -35,6 +40,13 @@ export declare class SqlStorage {
35
40
  statementCount: number;
36
41
  rowsWritten: number;
37
42
  };
43
+ /**
44
+ * A synchronous write made from another event while an async `transaction()` is open lands in
45
+ * that transaction's savepoint, and is undone if it rolls back. On workerd that event would not
46
+ * run until the transaction ends; a synchronous call cannot wait, so this warns, once per
47
+ * object. (Async storage calls wait for the transaction instead.)
48
+ */
49
+ checkWrite(): void;
38
50
  get databaseSize(): number;
39
51
  /** Unguarded path for the runtime's own tables (_cf_KV, _cf_METADATA). */
40
52
  internalExec(query: string, bindings?: unknown[]): SqlResult;
@@ -102,6 +102,8 @@ const DDL = /^\s*(CREATE|ALTER|DROP)\b/i;
102
102
  const ROLLS_BACK = /SQLITE_(IOERR|FULL|NOMEM|BUSY|INTERRUPT|CORRUPT)|disk I\/O error|database or disk is full|out of memory|interrupted/i;
103
103
  /** Statements that may write (a conservative test: WITH … and PRAGMAs count as writes). */
104
104
  const WRITES = /^\s*(INSERT|REPLACE|UPDATE|DELETE|CREATE|ALTER|DROP|WITH|PRAGMA)\b/i;
105
+ /** Statements that surely write, for the warning of `checkWrite()`. */
106
+ const SURE_WRITES = /^\s*(INSERT|REPLACE|UPDATE|DELETE|CREATE|ALTER|DROP)\b/i;
105
107
  const WRITE_TARGET = /^\s*(?:INSERT|REPLACE)(?:\s+OR\s+\w+)?\s+INTO\s+["`[]?([\w$]+)|^\s*UPDATE(?:\s+OR\s+\w+)?\s+["`[]?([\w$]+)|^\s*DELETE\s+FROM\s+["`[]?([\w$]+)/i;
106
108
  export class SqlStorage {
107
109
  #driver;
@@ -113,6 +115,12 @@ export class SqlStorage {
113
115
  #lost;
114
116
  #holds = 0;
115
117
  #depth = 0;
118
+ /**
119
+ * Set by `ctx.storage`: true when called from another event while an async `transaction()` is
120
+ * open, where async context tells them apart.
121
+ */
122
+ outsideTransaction;
123
+ #warnedOutside = false;
116
124
  // Transaction-log capture (only when the durability port asks for it).
117
125
  #capture;
118
126
  #ddl = [];
@@ -171,6 +179,8 @@ export class SqlStorage {
171
179
  // of comments alone, is refused.
172
180
  if (lacksStatement(query))
173
181
  throw new Error("SQL code did not contain a statement.");
182
+ if (SURE_WRITES.test(query))
183
+ this.checkWrite();
174
184
  return new SqlStorageCursor(this.internalExec(query, bindings));
175
185
  }
176
186
  /**
@@ -213,6 +223,18 @@ export class SqlStorage {
213
223
  rowsWritten: this.#totalChanges() - before,
214
224
  };
215
225
  }
226
+ /**
227
+ * A synchronous write made from another event while an async `transaction()` is open lands in
228
+ * that transaction's savepoint, and is undone if it rolls back. On workerd that event would not
229
+ * run until the transaction ends; a synchronous call cannot wait, so this warns, once per
230
+ * object. (Async storage calls wait for the transaction instead.)
231
+ */
232
+ checkWrite() {
233
+ if (this.#warnedOutside || !this.outsideTransaction?.())
234
+ return;
235
+ this.#warnedOutside = true;
236
+ console.warn("cellb: a synchronous storage write from another event while storage.transaction() is open; it is undone if that transaction rolls back (on workerd the event would wait for it)");
237
+ }
216
238
  get databaseSize() {
217
239
  return this.#driver.databaseSize();
218
240
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sql-storage.js","sourceRoot":"","sources":["../../src/core/sql-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommitChanges, SqlResult, SyncSqlDriver } from \"../ports.js\";\nimport { LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE } from \"./celld-schema.js\";\nimport { completeSqlStatements, lacksStatement } from \"./sql-split.js\";\n\nconst FORBIDDEN_TXN = /^\\s*(BEGIN|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\\b/i;\nconst FORBIDDEN_INTERNAL = /\\b_cf_\\w*/i;\n/** Creating or dropping an object with an internal name (any case): celld refuses it outright. */\nconst FORBIDDEN_DDL = /^\\s*(CREATE|DROP)\\b[^(]*?\\b_cf_/i;\n\n/**\n * Runs `fn` after the current macrotask, as workerd commits an implicit transaction after the\n * current turn of its event loop: the writes of every microtask until then share one commit.\n * `setImmediate` on Node; a MessageChannel message in browsers (no timer clamping).\n */\nconst afterTurn: (fn: () => void) => void = (() => {\n const g = globalThis as { setImmediate?: (fn: () => void) => unknown };\n if (typeof g.setImmediate === \"function\") return (fn) => void g.setImmediate!(fn);\n if (typeof MessageChannel === \"function\") {\n const queue: (() => void)[] = [];\n const channel = new MessageChannel();\n channel.port1.onmessage = () => {\n for (const f of queue.splice(0)) f();\n };\n return (fn) => {\n if (queue.push(fn) === 1) channel.port2.postMessage(null);\n };\n }\n return (fn) => void setTimeout(fn, 0);\n})();\n\n/** The SQL text with string literals and comments blanked out (quoted identifiers stay). */\nfunction withoutLiterals(sql: string): string {\n return sql.replace(/'(?:[^']|'')*'|--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g, \" \");\n}\n\n/**\n * Why celld's authorizer refuses a statement at prepare time, or undefined: transaction\n * statements and internal tables. Names inside string literals and comments are values, not\n * tables: `WHERE callback = '_cf_x'` is allowed (the Agents SDK writes one).\n */\nfunction refusal(query: string): string | undefined {\n const code = withoutLiterals(query);\n if (FORBIDDEN_TXN.test(code) || FORBIDDEN_DDL.test(code)) return \"not authorized\";\n const internal = FORBIDDEN_INTERNAL.exec(code);\n if (!internal) return undefined;\n const table = internal[0];\n // celld names the first column of its own internal schema (_cf_KV starts with `scope`).\n return `access to ${table}.${table.toLowerCase() === \"_cf_kv\" ? \"scope\" : \"key\"} is prohibited`;\n}\n\n/** SQLite's own message, without the prefix SQLite WASM adds to it. */\nconst sqliteMessage = (e: unknown) =>\n String((e as Error)?.message ?? e).replace(/^SQLITE_\\w+: sqlite3 result code \\d+: /, \"\");\n\n/** `ctx.storage.sql.exec()` cursor (iterable, one-shot like the CF one). */\nexport class SqlStorageCursor<T = Record<string, unknown>> implements Iterable<T> {\n readonly columnNames: string[];\n readonly rowsRead: number;\n readonly rowsWritten: number;\n #rows: unknown[][];\n #pos = 0;\n constructor(r: SqlResult) {\n this.columnNames = r.columnNames;\n this.#rows = r.rows;\n this.rowsRead = r.rows.length;\n this.rowsWritten = r.rowsWritten;\n }\n next(): IteratorResult<T> {\n // As workerd: the final result has no `value` key ({ done: true }).\n if (this.#pos >= this.#rows.length) return { done: true } as IteratorReturnResult<undefined>;\n return { done: false, value: this.#obj(this.#rows[this.#pos++]) };\n }\n [Symbol.iterator](): Iterator<T> {\n return this;\n }\n toArray(): T[] {\n return [...this];\n }\n one(): T {\n const rest = this.toArray();\n if (rest.length !== 1)\n throw new Error(\n `Expected exactly one result from SQL query, but got ${rest.length === 0 ? \"no\" : \"multiple\"} results`,\n );\n return rest[0];\n }\n *raw(): IterableIterator<unknown[]> {\n while (this.#pos < this.#rows.length) yield this.#rows[this.#pos++];\n }\n #obj(row: unknown[]): T {\n const o: Record<string, unknown> = {};\n for (const [i, c] of this.columnNames.entries()) o[c] = row[i];\n return o as T;\n }\n}\n\n/**\n * `ctx.storage.sql` with SQLite-backed-DO semantics: every write opens an\n * IMPLICIT transaction that commits on the next microtask (i.e. when the\n * handler yields). Sync writes therefore coalesce atomically, and the\n * output gate only has to await durability of the commit.\n */\nconst DDL = /^\\s*(CREATE|ALTER|DROP)\\b/i;\n/** Errors after which SQLite may roll the whole transaction back by itself. */\nconst ROLLS_BACK =\n /SQLITE_(IOERR|FULL|NOMEM|BUSY|INTERRUPT|CORRUPT)|disk I\\/O error|database or disk is full|out of memory|interrupted/i;\n/** Statements that may write (a conservative test: WITH … and PRAGMAs count as writes). */\nconst WRITES = /^\\s*(INSERT|REPLACE|UPDATE|DELETE|CREATE|ALTER|DROP|WITH|PRAGMA)\\b/i;\nconst WRITE_TARGET =\n /^\\s*(?:INSERT|REPLACE)(?:\\s+OR\\s+\\w+)?\\s+INTO\\s+[\"`[]?([\\w$]+)|^\\s*UPDATE(?:\\s+OR\\s+\\w+)?\\s+[\"`[]?([\\w$]+)|^\\s*DELETE\\s+FROM\\s+[\"`[]?([\\w$]+)/i;\n\nexport class SqlStorage {\n #driver: SyncSqlDriver;\n #onCommit: (changes?: CommitChanges) => void;\n #inTxn = false;\n /** The implicit transaction has written (its loss must fail the commit, not pass silently). */\n #wrote = false;\n /** Why SQLite rolled the implicit transaction back by itself (after an I/O error), if it did. */\n #lost: unknown;\n #holds = 0;\n #depth = 0;\n // Transaction-log capture (only when the durability port asks for it).\n readonly #capture: boolean;\n #ddl: string[] = [];\n #statements: [string, unknown[]][] = [];\n readonly #noPk = new Map<string, boolean>();\n #changesAtBegin = 0;\n #schemaAtBegin = 0;\n #schemaVersion(): number {\n return Number(this.#driver.exec(\"PRAGMA schema_version\", []).rows[0]?.[0] ?? 0);\n }\n #totalChanges(): number {\n return Number(this.#driver.exec(\"SELECT total_changes()\", []).rows[0]?.[0] ?? 0);\n }\n\n constructor(\n driver: SyncSqlDriver,\n onCommit: (changes?: CommitChanges) => void,\n opts: { capture?: boolean } = {},\n ) {\n this.#driver = driver;\n this.#onCommit = onCommit;\n this.#capture = !!opts.capture;\n if (this.#capture && !driver.captureStart)\n throw new Error(\"This SyncSqlDriver cannot capture changes: no transaction-log durability\");\n }\n\n /** Records what the changeset cannot carry: schema changes, and writes to PK-less tables. */\n #record(query: string, bindings: unknown[]): void {\n if (!this.#capture) return;\n if (DDL.test(query)) {\n this.#ddl.push(query);\n this.#noPk.clear();\n return;\n }\n if (this.#driver.captureCoversRowidTables !== false) return;\n const m = WRITE_TARGET.exec(query);\n const table = m?.[1] ?? m?.[2] ?? m?.[3];\n if (table && this.#tableHasNoPk(table)) this.#statements.push([query, bindings]);\n }\n\n #tableHasNoPk(table: string): boolean {\n let v = this.#noPk.get(table);\n if (v === undefined) {\n const info = this.#driver.exec(`SELECT count(*) FROM pragma_table_info(?) WHERE pk > 0`, [\n table,\n ]);\n v = Number(info.rows[0]?.[0] ?? 0) === 0;\n this.#noPk.set(table, v);\n }\n return v;\n }\n\n exec<T = Record<string, unknown>>(query: string, ...bindings: unknown[]): SqlStorageCursor<T> {\n // Messages as celld words them (storage-details project).\n const refused = refusal(query);\n if (refused) throw new Error(`SQL error: prepare SQL cursor: ${refused}`);\n if (bindings.length && countParameters(query) !== bindings.length)\n throw new Error(\"SQL error: Wrong number of parameter bindings for SQL query.\");\n // Statement after statement, as workerd and celld prepare them: none at all, or a last one\n // of comments alone, is refused.\n if (lacksStatement(query)) throw new Error(\"SQL code did not contain a statement.\");\n return new SqlStorageCursor<T>(this.internalExec(query, bindings));\n }\n\n /**\n * workerd's `sql.prepare(query)`: a reusable statement, called with bindings.\n * Not in Cloudflare's public docs, but used by Miniflare's simulator objects.\n */\n prepare<T = Record<string, unknown>>(\n query: string,\n ): (...bindings: unknown[]) => SqlStorageCursor<T> {\n return (...bindings) => this.exec<T>(query, ...bindings);\n }\n\n /**\n * workerd's experimental `sql.ingest(text)`, for SQL that arrives in pieces: runs the complete\n * statements at the start of `text` and returns the rest, to be prefixed to the next piece.\n * As celld: errors read `prepare ingested SQL: …` (refused, or not valid SQL) or `step ingested\n * SQL: …` (failed while running); statements before a failing one stay applied; `rowsWritten`\n * includes trigger writes; there is no `rowsRead`.\n */\n ingest(text: string): { remainder: string; statementCount: number; rowsWritten: number } {\n const { statements, remainder } = completeSqlStatements(String(text));\n const before = this.#totalChanges();\n for (const statement of statements) {\n const refused = refusal(statement);\n if (refused) throw new Error(`SQL error: prepare ingested SQL: ${refused}`);\n try {\n this.#driver.exec(`EXPLAIN ${statement}`, []); // prepares it without running it\n } catch (e) {\n throw new Error(`SQL error: prepare ingested SQL: ${sqliteMessage(e)}`);\n }\n try {\n this.internalExec(statement);\n } catch (e) {\n throw new Error(`SQL error: step ingested SQL: ${sqliteMessage(e)}`);\n }\n }\n return {\n remainder,\n statementCount: statements.length,\n rowsWritten: this.#totalChanges() - before,\n };\n }\n\n get databaseSize(): number {\n return this.#driver.databaseSize();\n }\n\n /** Unguarded path for the runtime's own tables (_cf_KV, _cf_METADATA). */\n internalExec(query: string, bindings: unknown[] = []): SqlResult {\n this.#ensureTxn();\n let r: SqlResult;\n try {\n r = this.#driver.exec(query, bindings);\n } catch (e) {\n this.#afterFailure(e);\n throw e;\n }\n if (!this.#wrote && WRITES.test(query)) this.#wrote = true;\n this.#record(query, bindings);\n return r;\n }\n\n /**\n * After a failed statement: SQLite rolls the whole transaction back by itself on some errors\n * (I/O, disk full, out of memory). A read-only transaction lost nothing: the statement's error\n * fails the request, and the next one starts afresh. One that had written lost those writes:\n * its commit fails with the cause (the object resets, as workerd's does).\n */\n #afterFailure(e: unknown): void {\n if (!this.#inTxn) return;\n const open = this.#driver.inTransaction?.();\n if (open === true) return; // only the statement failed\n if (open === undefined) {\n // No way to ask the driver: only errors after which SQLite rolls back are checked, with a\n // statement (one that fails, and is logged by some builds, while the transaction is open).\n if (!ROLLS_BACK.test(String((e as Error)?.message ?? e))) return;\n try {\n this.#driver.exec(\"BEGIN\", []); // succeeds only outside a transaction\n } catch {\n return;\n }\n this.#driver.exec(\"ROLLBACK\", []); // the probe's own transaction\n }\n const wrote = this.#wrote;\n this.#inTxn = false;\n this.#wrote = false;\n this.#driver.discardDirtyPages?.();\n for (const f of this.rolledBack) f();\n if (this.#capture) {\n this.#driver.captureDiscard?.();\n this.#ddl = [];\n this.#statements = [];\n }\n if (wrote) this.#lost = e;\n }\n\n transactionSync<T>(fn: () => T): T {\n this.#ensureTxn();\n const sp = `_cf_sp${++this.#depth}`;\n this.#driver.exec(`SAVEPOINT ${sp}`, []);\n const marks = [this.#ddl.length, this.#statements.length] as const;\n try {\n const r = fn();\n this.#driver.exec(`RELEASE ${sp}`, []);\n return r;\n } catch (e) {\n // SQLite rolled the whole transaction back by itself (#afterFailure): no savepoint left.\n if (!this.#inTxn) throw e;\n this.#driver.exec(`ROLLBACK TO ${sp}`, []);\n for (const f of this.rolledBack) f();\n this.#ddl.length = marks[0];\n this.#statements.length = marks[1];\n this.#driver.exec(`RELEASE ${sp}`, []);\n throw e;\n } finally {\n this.#depth--;\n }\n }\n\n /** Suspends auto-commit (used by the async `transaction()` which spans awaits). */\n hold(): () => void {\n this.#holds++;\n let released = false;\n return () => {\n if (released) return;\n released = true;\n if (--this.#holds === 0) afterTurn(() => this.commit());\n };\n }\n\n /** True while an async transaction() holds auto-commit (no consistent snapshot possible). */\n get held(): boolean {\n return this.#holds > 0;\n }\n\n /** Commits the implicit transaction now (no-op if none, or if held). */\n commit(): void {\n if (this.#lost !== undefined && this.#holds === 0) {\n const cause = this.#lost;\n this.#lost = undefined;\n throw new Error(`the transaction's writes were rolled back after: ${sqliteMessage(cause)}`, {\n cause,\n });\n }\n if (!this.#inTxn || this.#holds > 0) return;\n let changes: CommitChanges | undefined;\n // Read-only transactions produce no log segment (\"IF NOT EXISTS\" DDL that changed\n // nothing included: the schema version tells).\n if (this.#capture && this.#ddl.length && this.#schemaVersion() === this.#schemaAtBegin)\n this.#ddl = [];\n if (this.#capture && (this.#ddl.length || this.#totalChanges() !== this.#changesAtBegin)) {\n // The log sequence number lives in the database, inside the same transaction.\n this.#driver.exec(LOG_TABLE, []);\n const row = this.#driver.exec(LOG_SEQ_READ, []).rows[0];\n const logSeq = Number(row?.[0] ?? 0) + 1;\n this.#driver.exec(LOG_SEQ_WRITE, [logSeq]);\n changes = {\n logSeq,\n ddl: this.#ddl,\n changeset: new Uint8Array(),\n statements: this.#statements,\n };\n }\n this.#inTxn = false;\n this.#wrote = false;\n this.#driver.exec(\"COMMIT\", []);\n if (this.#capture) {\n const changeset = this.#driver.captureTake!();\n if (changes) changes.changeset = changeset;\n this.#ddl = [];\n this.#statements = [];\n }\n this.#onCommit(changes);\n }\n\n /** Called after a rollback (lazily created internal tables may be gone). */\n readonly rolledBack = new Set<() => void>();\n\n rollback(): void {\n this.#lost = undefined;\n if (!this.#inTxn) return;\n this.#inTxn = false;\n this.#wrote = false;\n this.#driver.exec(\"ROLLBACK\", []);\n this.#driver.discardDirtyPages?.(); // pages a rolled-back transaction spilled are not a commit\n for (const f of this.rolledBack) f();\n if (this.#capture) {\n this.#driver.captureDiscard?.();\n this.#ddl = [];\n this.#statements = [];\n }\n }\n\n #ensureTxn(): void {\n if (this.#inTxn) return;\n this.#driver.exec(\"BEGIN\", []);\n if (this.#capture) {\n this.#driver.captureStart!();\n this.#changesAtBegin = this.#totalChanges();\n this.#schemaAtBegin = this.#schemaVersion();\n }\n this.#inTxn = true;\n afterTurn(() => this.commit());\n }\n}\n\n/** Parameters a statement expects: anonymous `?` count, highest `?NNN`, distinct named ones. */\nexport function countParameters(sql: string): number {\n let anon = 0;\n let maxNumbered = 0;\n const named = new Set<string>();\n const re = /'(?:[^']|'')*'|\"(?:[^\"]|\"\")*\"|--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\/|\\?(\\d*)|([:@$][A-Za-z_]\\w*)/g;\n for (let m = re.exec(sql); m; m = re.exec(sql)) {\n if (m[1] !== undefined) {\n if (m[1] === \"\") anon++;\n else maxNumbered = Math.max(maxNumbered, Number(m[1]));\n } else if (m[2]) named.add(m[2]);\n }\n const positional = maxNumbered ? Math.max(maxNumbered, anon) : anon;\n return positional + named.size;\n}\n"]}
1
+ {"version":3,"file":"sql-storage.js","sourceRoot":"","sources":["../../src/core/sql-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommitChanges, SqlResult, SyncSqlDriver } from \"../ports.js\";\nimport { LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE } from \"./celld-schema.js\";\nimport { completeSqlStatements, lacksStatement } from \"./sql-split.js\";\n\nconst FORBIDDEN_TXN = /^\\s*(BEGIN|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\\b/i;\nconst FORBIDDEN_INTERNAL = /\\b_cf_\\w*/i;\n/** Creating or dropping an object with an internal name (any case): celld refuses it outright. */\nconst FORBIDDEN_DDL = /^\\s*(CREATE|DROP)\\b[^(]*?\\b_cf_/i;\n\n/**\n * Runs `fn` after the current macrotask, as workerd commits an implicit transaction after the\n * current turn of its event loop: the writes of every microtask until then share one commit.\n * `setImmediate` on Node; a MessageChannel message in browsers (no timer clamping).\n */\nconst afterTurn: (fn: () => void) => void = (() => {\n const g = globalThis as { setImmediate?: (fn: () => void) => unknown };\n if (typeof g.setImmediate === \"function\") return (fn) => void g.setImmediate!(fn);\n if (typeof MessageChannel === \"function\") {\n const queue: (() => void)[] = [];\n const channel = new MessageChannel();\n channel.port1.onmessage = () => {\n for (const f of queue.splice(0)) f();\n };\n return (fn) => {\n if (queue.push(fn) === 1) channel.port2.postMessage(null);\n };\n }\n return (fn) => void setTimeout(fn, 0);\n})();\n\n/** The SQL text with string literals and comments blanked out (quoted identifiers stay). */\nfunction withoutLiterals(sql: string): string {\n return sql.replace(/'(?:[^']|'')*'|--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g, \" \");\n}\n\n/**\n * Why celld's authorizer refuses a statement at prepare time, or undefined: transaction\n * statements and internal tables. Names inside string literals and comments are values, not\n * tables: `WHERE callback = '_cf_x'` is allowed (the Agents SDK writes one).\n */\nfunction refusal(query: string): string | undefined {\n const code = withoutLiterals(query);\n if (FORBIDDEN_TXN.test(code) || FORBIDDEN_DDL.test(code)) return \"not authorized\";\n const internal = FORBIDDEN_INTERNAL.exec(code);\n if (!internal) return undefined;\n const table = internal[0];\n // celld names the first column of its own internal schema (_cf_KV starts with `scope`).\n return `access to ${table}.${table.toLowerCase() === \"_cf_kv\" ? \"scope\" : \"key\"} is prohibited`;\n}\n\n/** SQLite's own message, without the prefix SQLite WASM adds to it. */\nconst sqliteMessage = (e: unknown) =>\n String((e as Error)?.message ?? e).replace(/^SQLITE_\\w+: sqlite3 result code \\d+: /, \"\");\n\n/** `ctx.storage.sql.exec()` cursor (iterable, one-shot like the CF one). */\nexport class SqlStorageCursor<T = Record<string, unknown>> implements Iterable<T> {\n readonly columnNames: string[];\n readonly rowsRead: number;\n readonly rowsWritten: number;\n #rows: unknown[][];\n #pos = 0;\n constructor(r: SqlResult) {\n this.columnNames = r.columnNames;\n this.#rows = r.rows;\n this.rowsRead = r.rows.length;\n this.rowsWritten = r.rowsWritten;\n }\n next(): IteratorResult<T> {\n // As workerd: the final result has no `value` key ({ done: true }).\n if (this.#pos >= this.#rows.length) return { done: true } as IteratorReturnResult<undefined>;\n return { done: false, value: this.#obj(this.#rows[this.#pos++]) };\n }\n [Symbol.iterator](): Iterator<T> {\n return this;\n }\n toArray(): T[] {\n return [...this];\n }\n one(): T {\n const rest = this.toArray();\n if (rest.length !== 1)\n throw new Error(\n `Expected exactly one result from SQL query, but got ${rest.length === 0 ? \"no\" : \"multiple\"} results`,\n );\n return rest[0];\n }\n *raw(): IterableIterator<unknown[]> {\n while (this.#pos < this.#rows.length) yield this.#rows[this.#pos++];\n }\n #obj(row: unknown[]): T {\n const o: Record<string, unknown> = {};\n for (const [i, c] of this.columnNames.entries()) o[c] = row[i];\n return o as T;\n }\n}\n\n/**\n * `ctx.storage.sql` with SQLite-backed-DO semantics: every write opens an\n * IMPLICIT transaction that commits on the next microtask (i.e. when the\n * handler yields). Sync writes therefore coalesce atomically, and the\n * output gate only has to await durability of the commit.\n */\nconst DDL = /^\\s*(CREATE|ALTER|DROP)\\b/i;\n/** Errors after which SQLite may roll the whole transaction back by itself. */\nconst ROLLS_BACK =\n /SQLITE_(IOERR|FULL|NOMEM|BUSY|INTERRUPT|CORRUPT)|disk I\\/O error|database or disk is full|out of memory|interrupted/i;\n/** Statements that may write (a conservative test: WITH … and PRAGMAs count as writes). */\nconst WRITES = /^\\s*(INSERT|REPLACE|UPDATE|DELETE|CREATE|ALTER|DROP|WITH|PRAGMA)\\b/i;\n/** Statements that surely write, for the warning of `checkWrite()`. */\nconst SURE_WRITES = /^\\s*(INSERT|REPLACE|UPDATE|DELETE|CREATE|ALTER|DROP)\\b/i;\nconst WRITE_TARGET =\n /^\\s*(?:INSERT|REPLACE)(?:\\s+OR\\s+\\w+)?\\s+INTO\\s+[\"`[]?([\\w$]+)|^\\s*UPDATE(?:\\s+OR\\s+\\w+)?\\s+[\"`[]?([\\w$]+)|^\\s*DELETE\\s+FROM\\s+[\"`[]?([\\w$]+)/i;\n\nexport class SqlStorage {\n #driver: SyncSqlDriver;\n #onCommit: (changes?: CommitChanges) => void;\n #inTxn = false;\n /** The implicit transaction has written (its loss must fail the commit, not pass silently). */\n #wrote = false;\n /** Why SQLite rolled the implicit transaction back by itself (after an I/O error), if it did. */\n #lost: unknown;\n #holds = 0;\n #depth = 0;\n /**\n * Set by `ctx.storage`: true when called from another event while an async `transaction()` is\n * open, where async context tells them apart.\n */\n outsideTransaction?: () => boolean;\n #warnedOutside = false;\n // Transaction-log capture (only when the durability port asks for it).\n readonly #capture: boolean;\n #ddl: string[] = [];\n #statements: [string, unknown[]][] = [];\n readonly #noPk = new Map<string, boolean>();\n #changesAtBegin = 0;\n #schemaAtBegin = 0;\n #schemaVersion(): number {\n return Number(this.#driver.exec(\"PRAGMA schema_version\", []).rows[0]?.[0] ?? 0);\n }\n #totalChanges(): number {\n return Number(this.#driver.exec(\"SELECT total_changes()\", []).rows[0]?.[0] ?? 0);\n }\n\n constructor(\n driver: SyncSqlDriver,\n onCommit: (changes?: CommitChanges) => void,\n opts: { capture?: boolean } = {},\n ) {\n this.#driver = driver;\n this.#onCommit = onCommit;\n this.#capture = !!opts.capture;\n if (this.#capture && !driver.captureStart)\n throw new Error(\"This SyncSqlDriver cannot capture changes: no transaction-log durability\");\n }\n\n /** Records what the changeset cannot carry: schema changes, and writes to PK-less tables. */\n #record(query: string, bindings: unknown[]): void {\n if (!this.#capture) return;\n if (DDL.test(query)) {\n this.#ddl.push(query);\n this.#noPk.clear();\n return;\n }\n if (this.#driver.captureCoversRowidTables !== false) return;\n const m = WRITE_TARGET.exec(query);\n const table = m?.[1] ?? m?.[2] ?? m?.[3];\n if (table && this.#tableHasNoPk(table)) this.#statements.push([query, bindings]);\n }\n\n #tableHasNoPk(table: string): boolean {\n let v = this.#noPk.get(table);\n if (v === undefined) {\n const info = this.#driver.exec(`SELECT count(*) FROM pragma_table_info(?) WHERE pk > 0`, [\n table,\n ]);\n v = Number(info.rows[0]?.[0] ?? 0) === 0;\n this.#noPk.set(table, v);\n }\n return v;\n }\n\n exec<T = Record<string, unknown>>(query: string, ...bindings: unknown[]): SqlStorageCursor<T> {\n // Messages as celld words them (storage-details project).\n const refused = refusal(query);\n if (refused) throw new Error(`SQL error: prepare SQL cursor: ${refused}`);\n if (bindings.length && countParameters(query) !== bindings.length)\n throw new Error(\"SQL error: Wrong number of parameter bindings for SQL query.\");\n // Statement after statement, as workerd and celld prepare them: none at all, or a last one\n // of comments alone, is refused.\n if (lacksStatement(query)) throw new Error(\"SQL code did not contain a statement.\");\n if (SURE_WRITES.test(query)) this.checkWrite();\n return new SqlStorageCursor<T>(this.internalExec(query, bindings));\n }\n\n /**\n * workerd's `sql.prepare(query)`: a reusable statement, called with bindings.\n * Not in Cloudflare's public docs, but used by Miniflare's simulator objects.\n */\n prepare<T = Record<string, unknown>>(\n query: string,\n ): (...bindings: unknown[]) => SqlStorageCursor<T> {\n return (...bindings) => this.exec<T>(query, ...bindings);\n }\n\n /**\n * workerd's experimental `sql.ingest(text)`, for SQL that arrives in pieces: runs the complete\n * statements at the start of `text` and returns the rest, to be prefixed to the next piece.\n * As celld: errors read `prepare ingested SQL: …` (refused, or not valid SQL) or `step ingested\n * SQL: …` (failed while running); statements before a failing one stay applied; `rowsWritten`\n * includes trigger writes; there is no `rowsRead`.\n */\n ingest(text: string): { remainder: string; statementCount: number; rowsWritten: number } {\n const { statements, remainder } = completeSqlStatements(String(text));\n const before = this.#totalChanges();\n for (const statement of statements) {\n const refused = refusal(statement);\n if (refused) throw new Error(`SQL error: prepare ingested SQL: ${refused}`);\n try {\n this.#driver.exec(`EXPLAIN ${statement}`, []); // prepares it without running it\n } catch (e) {\n throw new Error(`SQL error: prepare ingested SQL: ${sqliteMessage(e)}`);\n }\n try {\n this.internalExec(statement);\n } catch (e) {\n throw new Error(`SQL error: step ingested SQL: ${sqliteMessage(e)}`);\n }\n }\n return {\n remainder,\n statementCount: statements.length,\n rowsWritten: this.#totalChanges() - before,\n };\n }\n\n /**\n * A synchronous write made from another event while an async `transaction()` is open lands in\n * that transaction's savepoint, and is undone if it rolls back. On workerd that event would not\n * run until the transaction ends; a synchronous call cannot wait, so this warns, once per\n * object. (Async storage calls wait for the transaction instead.)\n */\n checkWrite(): void {\n if (this.#warnedOutside || !this.outsideTransaction?.()) return;\n this.#warnedOutside = true;\n console.warn(\n \"cellb: a synchronous storage write from another event while storage.transaction() is open; it is undone if that transaction rolls back (on workerd the event would wait for it)\",\n );\n }\n\n get databaseSize(): number {\n return this.#driver.databaseSize();\n }\n\n /** Unguarded path for the runtime's own tables (_cf_KV, _cf_METADATA). */\n internalExec(query: string, bindings: unknown[] = []): SqlResult {\n this.#ensureTxn();\n let r: SqlResult;\n try {\n r = this.#driver.exec(query, bindings);\n } catch (e) {\n this.#afterFailure(e);\n throw e;\n }\n if (!this.#wrote && WRITES.test(query)) this.#wrote = true;\n this.#record(query, bindings);\n return r;\n }\n\n /**\n * After a failed statement: SQLite rolls the whole transaction back by itself on some errors\n * (I/O, disk full, out of memory). A read-only transaction lost nothing: the statement's error\n * fails the request, and the next one starts afresh. One that had written lost those writes:\n * its commit fails with the cause (the object resets, as workerd's does).\n */\n #afterFailure(e: unknown): void {\n if (!this.#inTxn) return;\n const open = this.#driver.inTransaction?.();\n if (open === true) return; // only the statement failed\n if (open === undefined) {\n // No way to ask the driver: only errors after which SQLite rolls back are checked, with a\n // statement (one that fails, and is logged by some builds, while the transaction is open).\n if (!ROLLS_BACK.test(String((e as Error)?.message ?? e))) return;\n try {\n this.#driver.exec(\"BEGIN\", []); // succeeds only outside a transaction\n } catch {\n return;\n }\n this.#driver.exec(\"ROLLBACK\", []); // the probe's own transaction\n }\n const wrote = this.#wrote;\n this.#inTxn = false;\n this.#wrote = false;\n this.#driver.discardDirtyPages?.();\n for (const f of this.rolledBack) f();\n if (this.#capture) {\n this.#driver.captureDiscard?.();\n this.#ddl = [];\n this.#statements = [];\n }\n if (wrote) this.#lost = e;\n }\n\n transactionSync<T>(fn: () => T): T {\n this.#ensureTxn();\n const sp = `_cf_sp${++this.#depth}`;\n this.#driver.exec(`SAVEPOINT ${sp}`, []);\n const marks = [this.#ddl.length, this.#statements.length] as const;\n try {\n const r = fn();\n this.#driver.exec(`RELEASE ${sp}`, []);\n return r;\n } catch (e) {\n // SQLite rolled the whole transaction back by itself (#afterFailure): no savepoint left.\n if (!this.#inTxn) throw e;\n this.#driver.exec(`ROLLBACK TO ${sp}`, []);\n for (const f of this.rolledBack) f();\n this.#ddl.length = marks[0];\n this.#statements.length = marks[1];\n this.#driver.exec(`RELEASE ${sp}`, []);\n throw e;\n } finally {\n this.#depth--;\n }\n }\n\n /** Suspends auto-commit (used by the async `transaction()` which spans awaits). */\n hold(): () => void {\n this.#holds++;\n let released = false;\n return () => {\n if (released) return;\n released = true;\n if (--this.#holds === 0) afterTurn(() => this.commit());\n };\n }\n\n /** True while an async transaction() holds auto-commit (no consistent snapshot possible). */\n get held(): boolean {\n return this.#holds > 0;\n }\n\n /** Commits the implicit transaction now (no-op if none, or if held). */\n commit(): void {\n if (this.#lost !== undefined && this.#holds === 0) {\n const cause = this.#lost;\n this.#lost = undefined;\n throw new Error(`the transaction's writes were rolled back after: ${sqliteMessage(cause)}`, {\n cause,\n });\n }\n if (!this.#inTxn || this.#holds > 0) return;\n let changes: CommitChanges | undefined;\n // Read-only transactions produce no log segment (\"IF NOT EXISTS\" DDL that changed\n // nothing included: the schema version tells).\n if (this.#capture && this.#ddl.length && this.#schemaVersion() === this.#schemaAtBegin)\n this.#ddl = [];\n if (this.#capture && (this.#ddl.length || this.#totalChanges() !== this.#changesAtBegin)) {\n // The log sequence number lives in the database, inside the same transaction.\n this.#driver.exec(LOG_TABLE, []);\n const row = this.#driver.exec(LOG_SEQ_READ, []).rows[0];\n const logSeq = Number(row?.[0] ?? 0) + 1;\n this.#driver.exec(LOG_SEQ_WRITE, [logSeq]);\n changes = {\n logSeq,\n ddl: this.#ddl,\n changeset: new Uint8Array(),\n statements: this.#statements,\n };\n }\n this.#inTxn = false;\n this.#wrote = false;\n this.#driver.exec(\"COMMIT\", []);\n if (this.#capture) {\n const changeset = this.#driver.captureTake!();\n if (changes) changes.changeset = changeset;\n this.#ddl = [];\n this.#statements = [];\n }\n this.#onCommit(changes);\n }\n\n /** Called after a rollback (lazily created internal tables may be gone). */\n readonly rolledBack = new Set<() => void>();\n\n rollback(): void {\n this.#lost = undefined;\n if (!this.#inTxn) return;\n this.#inTxn = false;\n this.#wrote = false;\n this.#driver.exec(\"ROLLBACK\", []);\n this.#driver.discardDirtyPages?.(); // pages a rolled-back transaction spilled are not a commit\n for (const f of this.rolledBack) f();\n if (this.#capture) {\n this.#driver.captureDiscard?.();\n this.#ddl = [];\n this.#statements = [];\n }\n }\n\n #ensureTxn(): void {\n if (this.#inTxn) return;\n this.#driver.exec(\"BEGIN\", []);\n if (this.#capture) {\n this.#driver.captureStart!();\n this.#changesAtBegin = this.#totalChanges();\n this.#schemaAtBegin = this.#schemaVersion();\n }\n this.#inTxn = true;\n afterTurn(() => this.commit());\n }\n}\n\n/** Parameters a statement expects: anonymous `?` count, highest `?NNN`, distinct named ones. */\nexport function countParameters(sql: string): number {\n let anon = 0;\n let maxNumbered = 0;\n const named = new Set<string>();\n const re = /'(?:[^']|'')*'|\"(?:[^\"]|\"\")*\"|--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\/|\\?(\\d*)|([:@$][A-Za-z_]\\w*)/g;\n for (let m = re.exec(sql); m; m = re.exec(sql)) {\n if (m[1] !== undefined) {\n if (m[1] === \"\") anon++;\n else maxNumbered = Math.max(maxNumbered, Number(m[1]));\n } else if (m[2]) named.add(m[2]);\n }\n const positional = maxNumbered ? Math.max(maxNumbered, anon) : anon;\n return positional + named.size;\n}\n"]}
@@ -36,6 +36,8 @@ export declare class AsyncKvApi {
36
36
  constructor(kv: SyncKvStorage, gate: InputGate);
37
37
  /** Every async storage op closes the input gate until it (and its continuation) completes. */
38
38
  protected op<T>(fn: () => T): Promise<T>;
39
+ /** An async op that writes (`ctx.storage` holds it back while another event's transaction is open). */
40
+ protected writeOp<T>(fn: () => T): Promise<T>;
39
41
  get<T = unknown>(key: string): Promise<T | undefined>;
40
42
  get<T = unknown>(keys: string[]): Promise<Map<string, T>>;
41
43
  put(key: string, value: unknown): Promise<void>;
@@ -54,6 +56,16 @@ export declare class DurableObjectStorage extends AsyncKvApi {
54
56
  readonly sql: SqlStorage;
55
57
  readonly kv: SyncKvStorage;
56
58
  constructor(sql: SqlStorage, kv: SyncKvStorage, gate: InputGate, sync: () => Promise<void>);
59
+ /**
60
+ * Async writes from another event wait while a transaction() is open, as that event would on
61
+ * workerd: they would otherwise land in its savepoint and be undone if it rolls back. Reads do
62
+ * not wait: an event may await, inside its transaction, a read another event started (a
63
+ * memoized load). Events are told apart by the token `runEvent()` gives each one, which needs
64
+ * async context; without it nothing waits.
65
+ */
66
+ protected writeOp<T>(fn: () => T): Promise<T>;
67
+ /** Runs one event's handler under a token of its own (the object host delivers through it). */
68
+ runEvent<R>(fn: () => R): R;
57
69
  deleteAll(): Promise<void>;
58
70
  transactionSync<T>(fn: () => T): T;
59
71
  transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T>;
@@ -67,6 +67,7 @@ export class SyncKvStorage {
67
67
  // Browsers prefix the engine message ("Failed to execute 'structuredClone' on …: ").
68
68
  throw new TypeError(e.message.replace(/^Failed to execute '[^']+' on '[^']+': /, ""));
69
69
  }
70
+ this.#sql.checkWrite();
70
71
  this.#sql.internalExec("INSERT OR REPLACE INTO _cf_KV (scope, k, v) VALUES (?, ?, ?)", [
71
72
  this.scope,
72
73
  key,
@@ -75,6 +76,7 @@ export class SyncKvStorage {
75
76
  }
76
77
  delete(key) {
77
78
  this.#init();
79
+ this.#sql.checkWrite();
78
80
  return (this.#sql.internalExec("DELETE FROM _cf_KV WHERE scope = ? AND k = ?", [this.scope, key])
79
81
  .rowsWritten > 0);
80
82
  }
@@ -121,6 +123,7 @@ export class SyncKvStorage {
121
123
  }
122
124
  deleteAll() {
123
125
  this.#init();
126
+ this.#sql.checkWrite();
124
127
  this.#sql.internalExec("DELETE FROM _cf_KV WHERE scope = ?", [this.scope]);
125
128
  }
126
129
  }
@@ -139,6 +142,10 @@ export class AsyncKvApi {
139
142
  return fn();
140
143
  });
141
144
  }
145
+ /** An async op that writes (`ctx.storage` holds it back while another event's transaction is open). */
146
+ writeOp(fn) {
147
+ return this.op(fn);
148
+ }
142
149
  get(keyOrKeys) {
143
150
  return this.op(() => {
144
151
  if (!Array.isArray(keyOrKeys))
@@ -154,7 +161,7 @@ export class AsyncKvApi {
154
161
  });
155
162
  }
156
163
  put(keyOrEntries, value) {
157
- return this.op(() => {
164
+ return this.writeOp(() => {
158
165
  if (typeof keyOrEntries === "string")
159
166
  return this.kv.put(keyOrEntries, value);
160
167
  const entries = Object.entries(keyOrEntries);
@@ -164,7 +171,7 @@ export class AsyncKvApi {
164
171
  });
165
172
  }
166
173
  delete(keyOrKeys) {
167
- return this.op(() => {
174
+ return this.writeOp(() => {
168
175
  if (!Array.isArray(keyOrKeys))
169
176
  return this.kv.delete(keyOrKeys);
170
177
  checkKeys(keyOrKeys);
@@ -196,9 +203,48 @@ export class DurableObjectStorage extends AsyncKvApi {
196
203
  });
197
204
  this.kv = kv;
198
205
  this.#sync = sync;
206
+ sql.outsideTransaction = () => this.#otherEvent();
207
+ }
208
+ /**
209
+ * Async writes from another event wait while a transaction() is open, as that event would on
210
+ * workerd: they would otherwise land in its savepoint and be undone if it rolls back. Reads do
211
+ * not wait: an event may await, inside its transaction, a read another event started (a
212
+ * memoized load). Events are told apart by the token `runEvent()` gives each one, which needs
213
+ * async context; without it nothing waits.
214
+ */
215
+ writeOp(fn) {
216
+ return this.gate.runClosed(async () => {
217
+ await Promise.resolve();
218
+ if (this.#waitFor()) {
219
+ // On workerd such a wait cannot end if the transaction awaits this very write: say so.
220
+ const slow = setTimeout(() => console.warn("cellb: a storage write from another event has waited 5 s for an open storage.transaction(); does the transaction await it?"), 5000);
221
+ try {
222
+ for (let done = this.#waitFor(); done; done = this.#waitFor())
223
+ await done;
224
+ }
225
+ finally {
226
+ clearTimeout(slow);
227
+ }
228
+ }
229
+ return fn();
230
+ });
231
+ }
232
+ #events = asyncSlot("cellb.event");
233
+ #txnOwner;
234
+ /** Runs one event's handler under a token of its own (the object host delivers through it). */
235
+ runEvent(fn) {
236
+ return this.#events ? this.#events.run({}, fn) : fn();
237
+ }
238
+ /** The open transaction's end, when a write from the calling event must wait for it. */
239
+ #waitFor() {
240
+ return this.#otherEvent() ? this.#txnDone : undefined;
241
+ }
242
+ /** Called from an event other than the one whose transaction() is open now. */
243
+ #otherEvent() {
244
+ return (this.#txnDepth > 0 && this.#events !== undefined && this.#events.get() !== this.#txnOwner);
199
245
  }
200
246
  deleteAll() {
201
- return this.op(() => {
247
+ return this.writeOp(() => {
202
248
  this.kv.deleteAll();
203
249
  // deleteAll() also deletes the alarm, as on Cloudflare, unless `delete_all_preserves_alarm`.
204
250
  if (!this.deleteAllPreservesAlarm)
@@ -227,10 +273,17 @@ export class DurableObjectStorage extends AsyncKvApi {
227
273
  * (AsyncLocalStorage on Node, or the engine's AsyncContext); without it, such a call waits
228
274
  * for its parent forever: use the `txn` argument there.
229
275
  */
230
- #txnScope = txnScope();
276
+ #txnScope = asyncSlot("cellb.storage.transaction");
231
277
  #txnDepth = 0;
278
+ /** Settles when the transaction open now (the outermost one) ends. */
279
+ #txnDone;
280
+ /** A token per transaction open now; its closure runs with it in `#txnScope`. */
281
+ #openTxns = new Set();
232
282
  transaction(closure) {
233
- if (this.#txnScope?.get() === this)
283
+ // Nested: inside the closure of a transaction still open. (A call its closure left running
284
+ // after returning queues like any other.)
285
+ const parent = this.#txnScope?.get();
286
+ if (parent && this.#openTxns.has(parent))
234
287
  return this.#transaction(closure);
235
288
  const run = () => this.#transaction(closure);
236
289
  const result = this.#transactions.then(run, run);
@@ -240,12 +293,22 @@ export class DurableObjectStorage extends AsyncKvApi {
240
293
  #transaction(closure) {
241
294
  return this.gate.runClosed(async () => {
242
295
  const release = this.sql.hold();
243
- const sp = `_cf_atx${++this.#txnDepth}`;
296
+ let ended;
297
+ if (this.#txnDepth === 0) {
298
+ this.#txnDone = new Promise((r) => (ended = r));
299
+ this.#txnOwner = this.#events?.get();
300
+ }
301
+ const depth = ++this.#txnDepth;
302
+ const sp = `_cf_atx${depth}`;
244
303
  this.sql.internalExec(`SAVEPOINT ${sp}`);
245
304
  const txn = new DurableObjectTransaction(this.kv, this.gate);
305
+ const token = {};
306
+ this.#openTxns.add(token);
246
307
  try {
247
308
  const scope = this.#txnScope;
248
- const r = await (scope ? scope.run(this, () => closure(txn)) : closure(txn));
309
+ const r = await (scope ? scope.run(token, () => closure(txn)) : closure(txn));
310
+ if (this.#txnDepth !== depth)
311
+ console.warn("cellb: a storage.transaction() ended while one nested in it was still running; await nested transactions");
249
312
  if (txn.rolledBack)
250
313
  this.#rollbackTo(sp);
251
314
  else
@@ -257,8 +320,13 @@ export class DurableObjectStorage extends AsyncKvApi {
257
320
  throw e;
258
321
  }
259
322
  finally {
323
+ this.#openTxns.delete(token);
260
324
  this.#txnDepth--;
261
325
  release();
326
+ if (ended) {
327
+ this.#txnDone = undefined;
328
+ ended();
329
+ }
262
330
  }
263
331
  });
264
332
  }
@@ -350,7 +418,7 @@ export class DurableObjectStorage extends AsyncKvApi {
350
418
  // As celld: the time is coerced to a number and a non-number becomes 0 (due at once).
351
419
  const n = scheduledTime instanceof Date ? scheduledTime.getTime() : Number(scheduledTime);
352
420
  const at = Number.isNaN(n) ? 0 : n;
353
- return this.op(() => {
421
+ return this.writeOp(() => {
354
422
  this.#meta();
355
423
  this.sql.internalExec(
356
424
  // celld's statement: counters reset, a new random generation
@@ -365,7 +433,7 @@ export class DurableObjectStorage extends AsyncKvApi {
365
433
  this.onAlarmChange(at);
366
434
  }
367
435
  deleteAlarm(_opts) {
368
- return this.op(() => this.clearAlarmSync());
436
+ return this.writeOp(() => this.clearAlarmSync());
369
437
  }
370
438
  clearAlarmSync() {
371
439
  this.#meta();
@@ -373,8 +441,8 @@ export class DurableObjectStorage extends AsyncKvApi {
373
441
  this.onAlarmChange(null);
374
442
  }
375
443
  }
376
- /** An async-context slot marking "inside this storage's transaction", where the platform has one. */
377
- function txnScope() {
444
+ /** A value that follows async context, where the platform has it (Node, or AsyncContext). */
445
+ function asyncSlot(name) {
378
446
  const hooks = globalThis.process?.getBuiltinModule?.("node:async_hooks");
379
447
  if (hooks?.AsyncLocalStorage) {
380
448
  const als = new hooks.AsyncLocalStorage();
@@ -382,7 +450,7 @@ function txnScope() {
382
450
  }
383
451
  const native = nativeAsyncContext();
384
452
  if (native) {
385
- const v = new native.Variable({ name: "cellb.storage.transaction" });
453
+ const v = new native.Variable({ name });
386
454
  return { get: () => v.get(), run: (value, fn) => v.run(value, fn) };
387
455
  }
388
456
  return undefined;
@@ -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 { 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"]}
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.checkWrite();\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 this.#sql.checkWrite();\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.checkWrite();\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 /** An async op that writes (`ctx.storage` holds it back while another event's transaction is open). */\n protected writeOp<T>(fn: () => T): Promise<T> {\n return this.op(fn);\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.writeOp(() => {\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.writeOp(() => {\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 sql.outsideTransaction = () => this.#otherEvent();\n }\n /**\n * Async writes from another event wait while a transaction() is open, as that event would on\n * workerd: they would otherwise land in its savepoint and be undone if it rolls back. Reads do\n * not wait: an event may await, inside its transaction, a read another event started (a\n * memoized load). Events are told apart by the token `runEvent()` gives each one, which needs\n * async context; without it nothing waits.\n */\n protected override writeOp<T>(fn: () => T): Promise<T> {\n return this.gate.runClosed(async () => {\n await Promise.resolve();\n if (this.#waitFor()) {\n // On workerd such a wait cannot end if the transaction awaits this very write: say so.\n const slow = setTimeout(\n () =>\n console.warn(\n \"cellb: a storage write from another event has waited 5 s for an open storage.transaction(); does the transaction await it?\",\n ),\n 5000,\n );\n try {\n for (let done = this.#waitFor(); done; done = this.#waitFor()) await done;\n } finally {\n clearTimeout(slow);\n }\n }\n return fn();\n });\n }\n #events = asyncSlot(\"cellb.event\");\n #txnOwner: unknown;\n /** Runs one event's handler under a token of its own (the object host delivers through it). */\n runEvent<R>(fn: () => R): R {\n return this.#events ? this.#events.run({}, fn) : fn();\n }\n /** The open transaction's end, when a write from the calling event must wait for it. */\n #waitFor(): Promise<void> | undefined {\n return this.#otherEvent() ? this.#txnDone : undefined;\n }\n /** Called from an event other than the one whose transaction() is open now. */\n #otherEvent(): boolean {\n return (\n this.#txnDepth > 0 && this.#events !== undefined && this.#events.get() !== this.#txnOwner\n );\n }\n deleteAll(): Promise<void> {\n return this.writeOp(() => {\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 = asyncSlot(\"cellb.storage.transaction\");\n #txnDepth = 0;\n /** Settles when the transaction open now (the outermost one) ends. */\n #txnDone: Promise<void> | undefined;\n /** A token per transaction open now; its closure runs with it in `#txnScope`. */\n #openTxns = new Set<object>();\n transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T> {\n // Nested: inside the closure of a transaction still open. (A call its closure left running\n // after returning queues like any other.)\n const parent = this.#txnScope?.get();\n if (parent && this.#openTxns.has(parent as object)) 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 let ended: (() => void) | undefined;\n if (this.#txnDepth === 0) {\n this.#txnDone = new Promise<void>((r) => (ended = r));\n this.#txnOwner = this.#events?.get();\n }\n const depth = ++this.#txnDepth;\n const sp = `_cf_atx${depth}`;\n this.sql.internalExec(`SAVEPOINT ${sp}`);\n const txn = new DurableObjectTransaction(this.kv, this.gate);\n const token = {};\n this.#openTxns.add(token);\n try {\n const scope = this.#txnScope;\n const r = await (scope ? scope.run(token, () => closure(txn)) : closure(txn));\n if (this.#txnDepth !== depth)\n console.warn(\n \"cellb: a storage.transaction() ended while one nested in it was still running; await nested transactions\",\n );\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.#openTxns.delete(token);\n this.#txnDepth--;\n release();\n if (ended) {\n this.#txnDone = undefined;\n ended();\n }\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.writeOp(() => {\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.writeOp(() => 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 AsyncSlot {\n get(): unknown;\n run<R>(value: unknown, fn: () => R): R;\n}\n\n/** A value that follows async context, where the platform has it (Node, or AsyncContext). */\nfunction asyncSlot(name: string): AsyncSlot | 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 });\n return { get: () => v.get(), run: (value, fn) => v.run(value, fn) };\n }\n return undefined;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statewalker/cellb",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "cellb: isomorphic Durable Objects runtime (celld/Cloudflare-compatible surface) for browsers and servers",
5
5
  "type": "module",
6
6
  "license": "MIT",