@mcp-b/do-runtime 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +9 -0
- package/dist/index.js +80 -4
- package/dist/index.js.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/io/io-context.d.ts +39 -0
- package/dist/src/io/worker.d.ts +2 -3
- package/dist/src/server/actor-container.d.ts +4 -4
- package/dist/src/server/actor-namespace.d.ts +3 -0
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#resolve","#reject","#brokenPromise","#gate","#requireGate","#parent","#parentLock","#hooks","#lock","#setBroken","#pastLocksPromise","#brokenState","#setPastLocks","#timer","#timeouts","#nextId","#arm","#cancel","#fire","#tasks","#taskFailed","#actor","#currentInputLocks","#abortPromise","#rejectAbort","#waitUntilTasks","#requireCurrent","#abortException","#addTaskCounter","#waitUntilStatus","#runImpl","#awaitIoImpl","#runCriticalSection","#exit","#channel","#id","#fetcher","#idFactory","#getImpl","#channel","#fetcher","#loopbackClass","#channel","#ctx","#options","#toDynamicWorkerSource","#extractCompatFlags","#rawRows","#rowsWritten","#nextRow","#position","#nextRaw","#ctx","#owner","#getPageSize","#pageSize","#ctx","#owner","#getOne","#getMultiple","#putOne","#putMultiple","#cache","#sql","#kv","#cacheTxn","#rolledBack","#ctx","#facetManager","#parentId","#getFacetManager","#options","#facets","#scope","#requireOwnSlice","#ctx","#subtle","#gated","#crypto","#fetch","#readCurrentExternalEntry","#ctx","#socket","#criticalSection","#deliver","#enqueue","#pump","#db","#tableCreated","#openCursor","#ensureInitialized","#putMultiple","#cancelCurrentCursor","#currentCursor","#rollbackMultiPut","#parent","#rows","#index","#exhaust","#canceled","#db","#tableCreated","#ensureCached","#cache","#setAlarmUncached","#ensureInitialized","#getAlarmUncached","#tasks","#taskFailed","#kv","#metadata","#commitCallback","#hooks","#onWrite","#onCriticalError","#lastConfirmedAlarmDbState","#alarmScheduledNoLaterThan","#deleteAllCommitScheduled","#startImplicitTxn","#alarmLaterIsInFlight","#pendingLaterAlarmTime","#alarmLaterInFlight","#requestScheduledAlarm","#scheduleLaterAlarm","#pendingCommit","#alarmVersion","#inAlarmHandler","#newDeferredAlarmDeleter","#transactionSyncDepth","#maybeDeleteDeferredAlarm","#parent","#committed","#someWriteConfirmed","#dropped","#actorSqlite","#depth","#hasChild","#alarmDirty","#rollbackImpl","#id","#name","#key","#computeMac","#file","#entries","#byKey","#offset","#nextId","#append","#db","#receipts","#deleteSubtree","#active","#run","#clearActive","#pending","#tail","#epochs","#index","#host","#deletions","#queue","#operations","#removeSubtree","#copyInto","#inputGate","#outputGate","#isFacet","#container","#selfId","#depth","#tree","#facets","#parentId","#monitorOnBroken","#forgetIfNeverRuns","#teardown","#actor","#ctx","#durableStorage","#cache","#env","#currentExternalEntry","#withExternalEntry","#alarmTail","#deliverAlarmImpl","#runAlarmHandler"],"sources":["../src/io/io-gate.ts","../src/io/io-context.ts","../src/api/actor.ts","../src/api/export-loopback.ts","../src/api/worker-loader.ts","../src/api/sql.ts","../src/api/sync-kv.ts","../src/api/actor-state.ts","../src/api/http.ts","../src/api/global-scope.ts","../src/api/web-socket.ts","../src/io/actor-cache.ts","../src/util/sqlite-kv.ts","../src/util/sqlite-metadata.ts","../src/io/actor-sqlite.ts","../src/io/worker.ts","../src/server/sha256.ts","../src/server/actor-id-impl.ts","../src/server/facet-tree-index.ts","../src/server/facet-deletion.ts","../src/server/actor-container.ts","../src/transport/rpc-session.ts"],"sourcesContent":["/**\n * ← workerd `src/workerd/io/io-gate.{h,c++}`\n *\n * An I/O gate allows someone to \"lock\" a type of I/O so that other concurrent tasks trying to\n * perform that type of I/O are blocked until the lock is released.\n *\n * I/O gates are used in actors to implement consistency guarantees, allowing in-memory state and\n * storage to be synchronized.\n *\n * Each Actor has two main gates:\n * - Input gate: While locked, blocks all incoming I/O events of any type from being delivered to\n * the actor, other than the specific event or events that hold the lock. This includes\n * blocking responses to subrequests, timer events, input streams, etc. Used when storage\n * operations are outstanding, so that awaiting a storage operation does not risk allowing\n * concurrent events that render the state inconsistent.\n * - Output gate: While locked, blocks all outgoing messages from an actor that would allow the\n * rest of the world to observe the actor's state. Held while writes that have been confirmed\n * to the application are still being flushed to disk. If the flush fails, these messages will\n * never be sent, so that the rest of the world cannot observe a prematurely-confirmed write.\n *\n * Three things kj gives for free and JS does not, resolved the same way at every site:\n *\n * 1. **Destructors.** `~Lock` releases and `~CriticalSection` diagnoses a dropped section as\n * deadlock. Both become explicit: `Lock.release()` and `CriticalSection.drop()`. A `Lock`\n * released twice throws rather than corrupting the refcount.\n * 2. **Cancel-by-drop.** Dropping a `kj::Promise` unwinds its waiter. Every such site takes an\n * `AbortSignal`, the convention `Timer.afterDelay` already set in `io-context.ts`. Aborting a\n * `wait()` rejects it with `CanceledError`; a never-settling promise would be an invisible\n * hang, which is what this repo's fail-closed tenet exists to prevent.\n * 3. **`kj::ForkedPromise` holding an exception with no branches.** JS reports that as an\n * unhandled rejection, so every promise this module stores keeps a no-op `catch` of its own\n * and hands observers a separate view.\n *\n * Error strings are copied verbatim from upstream; users and upstream tests match on them.\n *\n * Not ported: `SpanParent`/`SpanBuilder` tracing, since there is no `trace.h` here and upstream's\n * own tests pass `nullptr` at every call site; and the `~InputGate` assertion that no locks\n * outlive the gate, which guards against dangling references GC makes impossible.\n *\n * Spec: §1.1, §1.2, §1.5, decisions 3, 5 and 13 in\n * docs/decisions.md.\n */\n\n/**\n * Raised when a `wait()` is cancelled through its `AbortSignal`.\n *\n * kj has no equivalent, because a cancelled continuation simply never runs. It is deliberately\n * NOT a gate failure: a cancelled waiter leaves the gate exactly as it found it, so\n * `CriticalSection.wait()` rethrows this one without calling `setBroken()`.\n */\nexport class CanceledError extends Error {\n override readonly name = \"CanceledError\";\n}\n\n/** Mirrors `OutputGate::makeUnfulfilledException()`: one place that spells the exception. */\nfunction makeCanceledError(): CanceledError {\n return new CanceledError(\"input gate wait was canceled\");\n}\n\n/**\n * `addEventListener(\"abort\", ...)` never fires for a signal that has already aborted, so a\n * pre-aborted signal would silently hold its lock forever. Every cancellation site goes through\n * here, and every one of them first rejects a pre-aborted wait before touching gate state, so\n * \"cancelled\" always means \"left the gate exactly as it found it\".\n */\nfunction onAbort(signal: AbortSignal | undefined, run: () => void): void {\n if (signal === undefined) return;\n if (signal.aborted) {\n run();\n return;\n }\n signal.addEventListener(\"abort\", run, { once: true });\n}\n\n/**\n * ← `kj::OneOf<kj::Own<kj::PromiseFulfiller<void>>, kj::Exception> brokenState`.\n *\n * `InputGate` starts in `fulfiller` — it builds its promise in the constructor — while\n * `OutputGate` starts in `none` and only makes one when `onBroken()` is first called.\n */\ntype BrokenState =\n | { readonly kind: \"none\" }\n | { readonly kind: \"fulfiller\"; readonly reject: (exception: unknown) => void }\n | { readonly kind: \"exception\"; readonly exception: unknown };\n\n// =======================================================================================\n// InputGate\n\n/**\n * Hooks that can be used to customize InputGate behavior.\n *\n * Technically, everything implemented here could be accomplished by a class that wraps\n * InputGate, but the part of the code that wants to implement these hooks is far away from the\n * part of the code that calls into the InputGate, and so it was more convenient to give the\n * caller a way to inject behavior into InputGate.\n */\nexport interface InputGateHooks {\n inputGateLocked(): void;\n inputGateReleased(): void;\n inputGateWaiterAdded(): void;\n inputGateWaiterRemoved(): void;\n}\n\n/** ← `InputGate::Hooks::DEFAULT`. */\nexport const DEFAULT_INPUT_GATE_HOOKS: InputGateHooks = {\n inputGateLocked() {},\n inputGateReleased() {},\n inputGateWaiterAdded() {},\n inputGateWaiterRemoved() {},\n};\n\n/** ← `InputGate::Waiter`: a `kj::List` node plus the adapted promise's fulfiller. */\nclass Waiter {\n /** Rewritten by `CriticalSection.succeeded()` when a straggler is reparented. */\n gate: InputGate;\n readonly isChildWaiter: boolean;\n /** ← `link.isLinked()`. */\n linked = true;\n\n readonly #resolve: (lock: Lock) => void;\n readonly #reject: (exception: unknown) => void;\n\n constructor(\n gate: InputGate,\n isChildWaiter: boolean,\n resolve: (lock: Lock) => void,\n reject: (exception: unknown) => void,\n ) {\n this.gate = gate;\n this.isChildWaiter = isChildWaiter;\n this.#resolve = resolve;\n this.#reject = reject;\n\n gate.hooks.inputGateWaiterAdded();\n if (isChildWaiter) {\n gate.waitingChildren.push(this);\n } else {\n gate.waiters.push(this);\n }\n }\n\n unlink(): void {\n if (!this.linked) return;\n this.linked = false;\n const list = this.isChildWaiter ? this.gate.waitingChildren : this.gate.waiters;\n const index = list.indexOf(this);\n if (index < 0) {\n throw new Error(\"InputGate::Waiter is linked but absent from its gate's list\");\n }\n list.splice(index, 1);\n }\n\n fulfill(lock: Lock): void {\n this.unlink();\n this.gate.hooks.inputGateWaiterRemoved();\n this.#resolve(lock);\n }\n\n reject(exception: unknown): void {\n this.unlink();\n this.gate.hooks.inputGateWaiterRemoved();\n this.#reject(exception);\n }\n}\n\n/**\n * An InputGate blocks incoming events from being delivered to an actor while the lock is held.\n *\n * Upstream marks the state below `private` and befriends `Lock` and `CriticalSection`.\n * TypeScript has no friendship, and `protected` would not let `CriticalSection` reach these\n * members on its *parent* gate, which `succeeded()` does. The boundary that actually holds is\n * the package facade in `src/index.ts`, which exports none of these types.\n */\nexport class InputGate {\n readonly hooks: InputGateHooks;\n\n /**\n * How many instances of `Lock` currently exist? When this reaches zero, we'll release some\n * waiters.\n *\n * Upstream also carries a `bool isCriticalSection`, because `CriticalSection` inherits\n * `InputGate` privately and has to `static_cast` back. `instanceof` is the same test with no\n * cast and no field that can disagree with the object it describes.\n */\n lockCount = 0;\n\n readonly waiters: Waiter[] = [];\n\n /**\n * Waiters representing CriticalSections that are ready to start. These take priority over other\n * waiters.\n */\n readonly waitingChildren: Waiter[] = [];\n\n /** A fulfiller for onBroken(), or an exception if already broken. */\n brokenState: BrokenState;\n\n readonly #brokenPromise: Promise<never>;\n\n constructor(hooks: InputGateHooks = DEFAULT_INPUT_GATE_HOOKS) {\n this.hooks = hooks;\n const { promise, reject } = Promise.withResolvers<never>();\n this.#brokenPromise = promise;\n this.brokenState = { kind: \"fulfiller\", reject };\n // kj's ForkedPromise just holds the exception until someone adds a branch.\n void promise.catch(() => {});\n }\n\n /** Wait until there are no `Lock`s, then create a new one and return it. */\n wait(signal?: AbortSignal): Promise<Lock> {\n if (signal?.aborted === true) {\n return Promise.reject(makeCanceledError());\n } else if (this.brokenState.kind === \"exception\") {\n return Promise.reject(this.brokenState.exception);\n } else if (this.lockCount === 0) {\n return Promise.resolve(new Lock(this));\n } else {\n return this.newWaiterPromise(false, signal);\n }\n }\n\n /**\n * Rejects if and when calls to `wait()` become broken due to a failed critical section. The\n * actor should be shut down in this case. This promise never resolves, only rejects.\n */\n onBroken(): Promise<never> {\n if (this.brokenState.kind === \"exception\") {\n return Promise.reject(this.brokenState.exception);\n } else {\n return this.#brokenPromise;\n }\n }\n\n /** ← `kj::newAdaptedPromise<Lock, Waiter>(gate, isChildWaiter, span)`. */\n newWaiterPromise(isChildWaiter: boolean, signal?: AbortSignal): Promise<Lock> {\n const { promise, resolve, reject } = Promise.withResolvers<Lock>();\n const waiter = new Waiter(this, isChildWaiter, resolve, reject);\n onAbort(signal, () => {\n // ← `~Waiter` on the cancellation path. A waiter that already settled is unlinked, and\n // cancelling it is the no-op that dropping a settled promise is.\n if (!waiter.linked) return;\n waiter.reject(makeCanceledError());\n });\n return promise;\n }\n\n releaseLock(): void {\n if (this instanceof CriticalSection && this.state === \"REPARENTED\") {\n // This lock was for a critical section that has already completed, therefore the lock\n // should be considered \"reparented\", and we should forward the release to the parent.\n\n // Ensure any waiters on us have already been reparented.\n if (this.waitingChildren.length !== 0 || this.waiters.length !== 0 || this.lockCount !== 0) {\n throw new Error(\"releasing a lock on a reparented CriticalSection that still holds state\");\n }\n\n this.parentAsInputGate().releaseLock();\n return;\n }\n\n if (this.lockCount === 0) {\n throw new Error(\"InputGate::releaseLock() with no locks outstanding\");\n }\n this.lockCount--;\n\n // Check if any waiters can be released.\n if (this.lockCount === 0) {\n this.hooks.inputGateReleased();\n const child = this.waitingChildren[0];\n if (child !== undefined) {\n child.fulfill(new Lock(this));\n } else {\n const waiter = this.waiters[0];\n if (waiter !== undefined) {\n waiter.fulfill(new Lock(this));\n }\n }\n }\n }\n\n /** Called when a critical section fails. All future waiters will throw this exception. */\n setBroken(exception: unknown): void {\n // `reject()` unlinks the waiter it settles, so walk copies of both lists.\n for (const waiter of [...this.waitingChildren]) waiter.reject(exception);\n for (const waiter of [...this.waiters]) waiter.reject(exception);\n if (this.brokenState.kind === \"fulfiller\") {\n this.brokenState.reject(exception);\n }\n this.brokenState = { kind: \"exception\", exception };\n }\n}\n\n/** ← `InputGate::Lock`. A lock that blocks all new events from being delivered while it exists. */\nexport class Lock {\n /** ← \"Becomes null on move.\" Here it becomes undefined on `release()`. */\n #gate: InputGate | undefined;\n\n constructor(gate: InputGate) {\n this.#gate = gate;\n\n // Upstream keeps a second member, `kj::Own<CriticalSection> cs`, whose job is to hold the\n // section alive for the lock's lifetime. `gate` already points at the same object, and GC\n // does the holding, so here it is a local.\n let gateToLock: InputGate = gate;\n if (gate instanceof CriticalSection && gate.state === \"REPARENTED\") {\n gateToLock = gate.parentAsInputGate();\n }\n\n if (++gateToLock.lockCount === 1) {\n gateToLock.hooks.inputGateLocked();\n }\n }\n\n /** ← `~Lock`. */\n release(): void {\n const gate = this.#gate;\n if (gate === undefined) {\n throw new Error(\"InputGate::Lock was released twice\");\n }\n this.#gate = undefined;\n gate.releaseLock();\n }\n\n /**\n * Increments the lock's refcount, returning a duplicate `Lock`. All `Lock`s must be released\n * before the gate is unlocked.\n */\n addRef(): Lock {\n return new Lock(this.#requireGate());\n }\n\n /**\n * Start a new critical section from this lock. After `wait()` has been called on the returned\n * critical section for the first time, no further Locks will be handed out by\n * InputGate::wait() until the CriticalSection has been dropped.\n *\n * CriticalSections can be nested. If this Lock is itself part of a CriticalSection, the new\n * CriticalSection will be nested within it and the outer CriticalSection's wait() won't\n * produce a Lock again until the inner CriticalSection is dropped.\n */\n startCriticalSection(): CriticalSection {\n return new CriticalSection(this.#requireGate());\n }\n\n /** If this lock was taken in a CriticalSection, return it. */\n getCriticalSection(): CriticalSection | undefined {\n const gate = this.#requireGate();\n return gate instanceof CriticalSection ? gate : undefined;\n }\n\n isFor(otherGate: InputGate): boolean {\n if (otherGate instanceof CriticalSection) {\n throw new Error(\"InputGate::Lock::isFor() takes the root gate, not a CriticalSection\");\n }\n\n let ptr = this.#requireGate();\n while (ptr instanceof CriticalSection) {\n ptr = ptr.parentAsInputGate();\n }\n return ptr === otherGate;\n }\n\n /** ← `operator==`. */\n equals(other: Lock): boolean {\n return this.#requireGate() === other.#requireGate();\n }\n\n #requireGate(): InputGate {\n const gate = this.#gate;\n if (gate === undefined) {\n throw new Error(\"InputGate::Lock was used after release\");\n }\n return gate;\n }\n}\n\n/** ← `InputGate::CriticalSection::State`. */\ntype CriticalSectionState =\n /** wait() hasn't been called. */\n | \"NOT_STARTED\"\n /** wait() has been called once, and that wait hasn't finished yet. */\n | \"INITIAL_WAIT\"\n /** First lock has been obtained, waiting for success() or failed(). */\n | \"RUNNING\"\n /** success() or failed() has been called. */\n | \"REPARENTED\";\n\n/**\n * A CriticalSection is a procedure that must not be interrupted by anything \"external\".\n * While a CriticalSection is running, all events that were not initiated by the\n * CriticalSection itself will be blocked from being delivered.\n *\n * The difference between a Lock and a CriticalSection is that a critical section may succeed\n * or fail. A failed critical section permanently breaks the input gate. Locks, on the other\n * hand, are simply released when dropped.\n *\n * A CriticalSection itself holds a Lock, which blocks the \"parent scope\" from continuing\n * execution until the critical section is done. Meanwhile, the code running inside the critical\n * section obtains nested Locks. These nested locks control concurrency of the operations\n * initiated within the critical section in the same way that input locks normally do at the\n * top-level scope. E.g., if a critical section initiates a storage read and a fetch() at the\n * same time, the fetch() is prevented from returning until after the storage read has returned.\n */\nexport class CriticalSection extends InputGate {\n state: CriticalSectionState = \"NOT_STARTED\";\n\n /**\n * Points to the parent scope, which may be another CriticalSection in the case of nesting.\n * ← `kj::OneOf<InputGate*, kj::Own<CriticalSection>>`; the two arms are one `instanceof` apart.\n */\n readonly #parent: InputGate;\n\n /**\n * A lock in the parent scope. `parentLock` becomes non-null after the first lock is obtained,\n * and becomes null again when succeeded() is called.\n */\n #parentLock: Lock | undefined;\n\n constructor(parent: InputGate) {\n // Upstream's CriticalSection has no base initializer, so it gets `Hooks::DEFAULT` rather than\n // the parent gate's hooks: metrics are counted once, at the root.\n super();\n this.#parent = parent;\n }\n\n /**\n * Wait for a nested lock in order to continue this CriticalSection.\n *\n * The first call to wait() begins the CriticalSection. After that wait completes, until the\n * CriticalSection is done and dropped, no other locks will be allowed on this InputGate, except\n * locks requested by calling wait() on this CriticalSection -- or one of its children.\n *\n * Everything before the first `await` runs in the caller's synchronous slice, which is what\n * lets the NOT_STARTED path take its parent lock before any other event can queue behind it.\n */\n override async wait(signal?: AbortSignal): Promise<Lock> {\n // Before the state machine, not inside it: the NOT_STARTED arm takes a parent lock in its\n // synchronous slice, and a cancelled wait must not leave one behind.\n if (signal?.aborted === true) throw makeCanceledError();\n\n for (;;) {\n switch (this.state) {\n case \"NOT_STARTED\": {\n this.state = \"INITIAL_WAIT\";\n\n const target = this.parentAsInputGate();\n if (target.brokenState.kind === \"exception\") {\n // Oops, we're broken.\n const exception = target.brokenState.exception;\n this.setBroken(exception);\n throw exception;\n }\n\n // Add ourselves to this parent's child waiter list.\n if (target.lockCount === 0) {\n this.state = \"RUNNING\";\n this.#parentLock = new Lock(target);\n continue;\n } else {\n let lock: Lock;\n try {\n lock = await target.newWaiterPromise(true, signal);\n } catch (exception) {\n // kj destroys the coroutine on cancellation, so no catch runs and the state stays\n // INITIAL_WAIT — the case `drop()` calls \"had better have been canceled\".\n if (exception instanceof CanceledError) throw exception;\n this.state = \"RUNNING\";\n this.setBroken(exception);\n throw exception;\n }\n this.state = \"RUNNING\";\n this.#parentLock = lock;\n continue;\n }\n }\n case \"INITIAL_WAIT\":\n // To avoid the need for a ForkedPromise, we assume wait() is called once initially to\n // get things started. This is the case in practice because any further tasks would be\n // started only after some code runs under the initial lock.\n throw new Error(\"CriticalSection::wait() should be called once initially\");\n case \"RUNNING\":\n // CriticalSection is active, so defer to InputGate implementation.\n return await super.wait(signal);\n case \"REPARENTED\":\n // Once the CriticalSection has declared itself done, then any straggler tasks it\n // initiated are adopted by the parent. Upstream needs a KJ_SWITCH_ONEOF here so as not\n // to bypass a parent CriticalSection's own override of wait(); JS is always virtual.\n return await this.#parent.wait(signal);\n }\n }\n }\n\n /**\n * Call when the critical section has completed successfully. If this is not called before the\n * CriticalSection is dropped, then failed() is called implicitly.\n *\n * Returns the input lock that was held on the parent critical section. This can be used to\n * continue execution in the parent before any other input arrives.\n */\n succeeded(): Lock {\n if (this.state !== \"RUNNING\") {\n throw new Error(\"CriticalSection::succeeded() requires a running critical section\");\n }\n\n // Once the CriticalSection has declared itself done, then any straggler tasks it initiated are\n // adopted by the parent. Appending preserves FIFO order against the parent's own waiters.\n const parentGate = this.parentAsInputGate();\n for (const waiter of this.waitingChildren) waiter.gate = parentGate;\n parentGate.waitingChildren.push(...this.waitingChildren);\n this.waitingChildren.length = 0;\n for (const waiter of this.waiters) waiter.gate = parentGate;\n parentGate.waiters.push(...this.waiters);\n this.waiters.length = 0;\n parentGate.lockCount += this.lockCount;\n this.lockCount = 0;\n\n this.state = \"REPARENTED\";\n const result = this.#parentLock;\n if (result === undefined) {\n throw new Error(\"CriticalSection::succeeded() with no parent lock\");\n }\n this.#parentLock = undefined;\n return result;\n }\n\n /**\n * Call to indicate the CriticalSection has failed with the given exception. This immediately\n * breaks the InputGate.\n */\n failed(exception: unknown): void {\n if (this.brokenState.kind === \"exception\") {\n // Already failed I guess.\n return;\n }\n\n this.setBroken(exception);\n if (this.#parent instanceof CriticalSection) {\n this.#parent.failed(exception);\n } else {\n this.#parent.setBroken(exception);\n }\n }\n\n /** ← `~CriticalSection`. */\n drop(): void {\n switch (this.state) {\n case \"NOT_STARTED\":\n // Oh well.\n break;\n case \"INITIAL_WAIT\":\n // The initial wait() had better have been canceled... but we have no way to tell here.\n break;\n case \"RUNNING\":\n this.failed(\n new Error(\n \"jsg.Error: A critical section within this Durable Object awaited a Promise that \" +\n \"apparently will never complete. This could happen in particular if a critical \" +\n \"section awaits a task that was initiated outside of the critical section. Since \" +\n \"a critical section blocks all other tasks from completing, this leads to \" +\n \"deadlock.\",\n ),\n );\n break;\n case \"REPARENTED\":\n // Common case.\n break;\n }\n\n // `parentLock` is a `kj::Maybe<Lock>` MEMBER (`io-gate.h:234`), so the destructor body above\n // is followed by its destruction, which hands the parent lock back. After the switch, not\n // inside it: `failed()` must see the lock count upstream would show it.\n //\n // Only RUNNING can still hold one, and not even always — see `wait()`'s catch arm, which\n // sets RUNNING for a section broken during its initial wait without ever acquiring a lock.\n // NOT_STARTED and INITIAL_WAIT never assign it, and REPARENTED gave it away in\n // `succeeded()`. Clearing first, as `succeeded()` does, makes a second drop a no-op rather\n // than a \"released twice\" throw.\n const parentLock = this.#parentLock;\n if (parentLock !== undefined) {\n this.#parentLock = undefined;\n parentLock.release();\n }\n }\n\n /** Return a reference for the parent scope, skipping any reparented CriticalSections */\n parentAsInputGate(): InputGate {\n // Upstream walks a `ptr` starting at `this` and reads `ptr->parent` each turn; walking the\n // parent link itself visits the same chain without aliasing `this`.\n let parent = this.#parent;\n for (;;) {\n if (!(parent instanceof CriticalSection)) return parent;\n if (parent.state !== \"REPARENTED\") return parent;\n // Keep looping...\n parent = parent.#parent;\n }\n }\n}\n\n// =======================================================================================\n// makeReentryCallback\n\n/**\n * ← the gate half of `IoContext::makeReentryCallback()` (`io-context.h:1507`), which is\n * `ctx.run(func, cs)` with the critical section captured here rather than looked up later.\n *\n * Upstream, on why the critical section travels with the callback at all:\n *\n * > \"What if the call was made within blockConcurrencyWhile()? The callback will be blocked until\n * > the critical section ends, which could lead to deadlock if the critical section code is\n * > waiting on it? ... The callback is allowed to run within the critical section\n * > (blockConcurrencyWhile()) from which it was called.\"\n *\n * `criticalSection` must come from the capturing lock's `getCriticalSection()`, at the moment of\n * capture. It cannot be recovered from gate state on invocation: a *new* external event that\n * inherited the running section would skip the queue, and `blockConcurrencyWhile` would silently\n * block nothing (Part 4).\n *\n * The lock covers the callback's synchronous slice and is released when the callback returns\n * control — decision 1, and the reason a callback that awaits something does not wedge the gate.\n * A callback needing the lock across an await takes `lock.addRef()`, which is upstream's\n * `awaitIoWithInputLock` in the one shape io-gate can express (§1.2).\n *\n * The returned function can be called multiple times.\n */\nexport function makeReentryCallback<Args extends unknown[], Result>(\n gate: InputGate,\n criticalSection: CriticalSection | undefined,\n func: (lock: Lock, ...args: Args) => Result | PromiseLike<Result>,\n): (...args: Args) => Promise<Result> {\n return async (...args: Args): Promise<Result> => {\n const lock = await (criticalSection === undefined ? gate.wait() : criticalSection.wait());\n\n let result: Result | PromiseLike<Result>;\n try {\n result = func(lock, ...args);\n } finally {\n lock.release();\n }\n return await result;\n };\n}\n\n// =======================================================================================\n// OutputGate\n\n/**\n * Hooks that can be used to customize OutputGate behavior. See `InputGateHooks` for why these\n * are injected rather than wrapped.\n */\nexport interface OutputGateHooks {\n /**\n * Optionally make a promise which should be raced with the lock promise to implement a\n * timeout. The returned promise should be something that throws an exception after some\n * timeout has expired.\n */\n makeTimeoutPromise(): Promise<never>;\n\n outputGateLocked(): void;\n outputGateReleased(): void;\n outputGateWaiterAdded(): void;\n outputGateWaiterRemoved(): void;\n}\n\n/** ← `OutputGate::Hooks::DEFAULT`. */\nexport const DEFAULT_OUTPUT_GATE_HOOKS: OutputGateHooks = {\n /** ← `kj::NEVER_DONE`. */\n makeTimeoutPromise: () => new Promise<never>(() => {}),\n outputGateLocked() {},\n outputGateReleased() {},\n outputGateWaiterAdded() {},\n outputGateWaiterRemoved() {},\n};\n\n/** ← `kj::Own<kj::PromiseFulfiller<void>>`, the one link `lockWhile` holds in the chain. */\ninterface VoidFulfiller {\n isWaiting(): boolean;\n fulfill(): void;\n reject(exception: unknown): void;\n}\n\n/** ← `OutputGate::makeUnfulfilledException()`. */\nfunction makeUnfulfilledException(): Error {\n return new Error(\"output lock was canceled before completion\");\n}\n\n/**\n * An OutputGate blocks outgoing messages from an Actor until writes which they might depend on\n * are confirmed.\n *\n * A promise chain, not a counter (§1.1): each `lockWhile` joins a new link onto the chain and\n * re-forks it, so a `wait()` is bound to exactly the locks outstanding when it was taken and is\n * unaffected by any later `lockWhile`.\n */\nexport class OutputGate {\n readonly #hooks: OutputGateHooks;\n #pastLocksPromise: Promise<void> = Promise.resolve();\n /** A fulfiller for onBroken(), or an exception if already broken. */\n #brokenState: BrokenState = { kind: \"none\" };\n\n constructor(hooks: OutputGateHooks = DEFAULT_OUTPUT_GATE_HOOKS) {\n this.#hooks = hooks;\n }\n\n /**\n * Block all future `wait()` calls until `promise` completes. Returns a wrapper around\n * `promise`. If `promise` rejects, the exception will propagate to all future `wait()`s. If the\n * returned promise is canceled before completion, all future `wait()`s will also throw.\n */\n lockWhile<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n const fulfiller = this.#lock();\n const raced = Promise.race([promise, this.#hooks.makeTimeoutPromise()]);\n\n this.#hooks.outputGateLocked();\n\n return new Promise<T>((resolve, reject) => {\n // ← the `kj::defer(rejectIfCanceled)` arm that runs when the coroutine is destroyed.\n // Upstream leaves the dropped promise unobservable; here the caller still holds it, and a\n // promise that never settles is a hang nobody can see, so it takes the same exception.\n onAbort(signal, () => {\n // The guard comes first, as it does in `Waiter`. Upstream can call the hook before its\n // own check because `kj::defer` runs once ever, on whichever path exits the scope; an\n // abort listener can fire after the lock already settled, so the invariant to preserve\n // is \"exactly one release per lockWhile\", not upstream's statement order.\n if (!fulfiller.isWaiting()) return;\n this.#hooks.outputGateReleased();\n const exception = makeUnfulfilledException();\n this.#setBroken(exception);\n fulfiller.reject(exception);\n reject(exception);\n });\n\n void raced.then(\n (value) => {\n // kj would have destroyed this frame on cancellation; there is nothing left to settle.\n if (!fulfiller.isWaiting()) return;\n fulfiller.fulfill();\n this.#hooks.outputGateReleased();\n resolve(value);\n },\n (exception: unknown) => {\n if (!fulfiller.isWaiting()) return;\n this.#setBroken(exception);\n fulfiller.reject(exception);\n this.#hooks.outputGateReleased();\n reject(exception);\n },\n );\n });\n }\n\n /**\n * Wait until all preceding locks are released. The wait will not be affected by any future\n * call to `lockWhile()`.\n */\n wait(): Promise<void> {\n this.#hooks.outputGateWaiterAdded();\n return this.#pastLocksPromise.then(\n () => {\n this.#hooks.outputGateWaiterRemoved();\n },\n (exception: unknown) => {\n this.#hooks.outputGateWaiterRemoved();\n throw exception;\n },\n );\n }\n\n /**\n * Rejects if and when calls to `wait()` become broken due to a failed lockWhile(). The actor\n * should be shut down in this case. This promise never resolves, only rejects.\n *\n * This method can only be called once.\n */\n onBroken(): Promise<never> {\n if (this.#brokenState.kind === \"fulfiller\") {\n throw new Error(\"onBroken() can only be called once\");\n }\n\n if (this.#brokenState.kind === \"exception\") {\n return Promise.reject(this.#brokenState.exception);\n } else {\n const { promise, reject } = Promise.withResolvers<never>();\n this.#brokenState = { kind: \"fulfiller\", reject };\n void promise.catch(() => {});\n return promise;\n }\n }\n\n isBroken(): boolean {\n return this.#brokenState.kind === \"exception\";\n }\n\n #lock(): VoidFulfiller {\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n\n // ← `kj::joinPromises`, which waits for EVERY branch and only then propagates the first\n // exception. `Promise.all` is fail-fast, which \"OutputGate exception\" explicitly forbids: a\n // later lock failing must not release an earlier `wait()`.\n this.#setPastLocks(\n Promise.allSettled([this.#pastLocksPromise, promise]).then((results) => {\n for (const result of results) {\n if (result.status === \"rejected\") throw result.reason;\n }\n }),\n );\n\n let waiting = true;\n return {\n isWaiting: () => waiting,\n fulfill: () => {\n waiting = false;\n resolve();\n },\n reject: (exception) => {\n waiting = false;\n reject(exception);\n },\n };\n }\n\n #setPastLocks(promise: Promise<void>): void {\n this.#pastLocksPromise = promise;\n // kj's ForkedPromise holds a rejection with no branches attached; JS calls that unhandled.\n void promise.catch(() => {});\n }\n\n #setBroken(exception: unknown): void {\n // We assume the exception is already propagated into `pastLocksPromise`, so all we need to do\n // is handle onBroken().\n if (this.#brokenState.kind === \"fulfiller\") {\n this.#brokenState.reject(exception);\n }\n this.#brokenState = { kind: \"exception\", exception };\n }\n}\n","/**\n * ← workerd `src/workerd/io/io-context.{h,c++}`\n *\n * IoContext: the one door, plus the two await forms.\n *\n * This is the file with no true upstream correspondence for its *enforcement*.\n * Workerd acquires the input gate at isolate entry, so acquisition is\n * structural. We have no isolate hook, so a lock is taken at our own dispatch\n * boundary instead. See \"The enforcement point is the one thing we cannot port\"\n * in the design record.\n *\n * What this file does, stated before anything about how it got here:\n *\n * 1. `#currentInputLocks` is a STACK of the locks held by the slices that are\n * running. It is upstream's single `kj::Maybe<InputGate::Lock>\n * currentInputLock` member (`io-context.h:993`) with the `Maybe` widened,\n * and a \"frame\" is an entry in it. A frame carries nothing else: the only\n * two things ever read from one are the lock (`getInputLock`) and the\n * critical section that lock belongs to (`getCriticalSection`), and the\n * lock answers both.\n * 2. A lock is released, and leaves the stack, at the END OF THE MICROTASK\n * CHECKPOINT of the slice holding it — not when that slice's synchronous\n * body returns. That is upstream's own boundary, not a relaxation of it:\n * `runImpl`'s inner `KJ_DEFER` calls `js.runMicrotasks()`\n * (`io-context.c++:1262`) and `runInContextScope`'s outer one then clears\n * `currentInputLock` (`:1214`), inner scope first, so the whole checkpoint\n * drains under the lock. `currentInputLock` holds the `Lock` by value, so\n * clearing it is the release. `atCheckpointEnd` below is that point.\n * 3. NEITHER await form releases anything at the moment of the await.\n * `awaitIo` reads `getCriticalSection()` and `awaitIoWithInputLock` takes\n * an `addRef`; both then return a promise and let the slice end normally.\n * So an invocation that calls `awaitIo` keeps the gate until its own\n * checkpoint-end exit and the gate opens there — which is still before any\n * real I/O can complete, so \"a bare timer releases the input gate\" holds.\n * Upstream is the same: `getCriticalSection()` (`io-context.c++:362`) does\n * not touch `currentInputLock`, and `:1214` is the only place that clears\n * it. The difference between the two forms is entirely on the far side —\n * `awaitIo` re-enters through `run(func, criticalSection)` and queues for a\n * fresh lock, `awaitIoWithInputLock` re-enters holding the ref it took.\n * 4. Removal from the stack is by identity, not by popping, because entries do\n * overlap — three deep in the unit tests. One invocation can have several\n * held awaits outstanding (`Promise.all` over two storage reads), and a\n * section's last body slice overlaps the slice that resolves it.\n *\n * Two mechanics were validated against real workerd before this scaffolding\n * landed, and both are easy to get wrong:\n *\n * 1. The ambient \"which lock am I under\" must be a STACK of invocation frames,\n * not a single slot, so that `current` always names the running invocation.\n * The prototype that found this stated it as \"`awaitIo` splices its frame\n * out and re-pushes the SAME frame on resume\". That is not what happens\n * here and the difference is worth knowing: nothing splices at the point of\n * the await, because a lock already leaves the stack when its slice ends,\n * which is the same event that releases it (`#exit` does both). A\n * resumption then pushes a fresh lock. The prototype needed the splice\n * because its door held one lock for a whole invocation; the identity that\n * has to survive an await here is the critical section, and that is\n * captured at the call rather than looked up later.\n * 2. That ambient is safe here for a reason that does NOT generalise to the\n * §2.3 ambient-field hazard: the gate guarantees pushes and pops nest\n * properly in time, because only one holder chain is inside at once.\n * `_cf_currentSubAgentBridge` has no such guarantee, which is why it is a\n * live bug and this is not.\n *\n * Consequence: no async context is required. Do not add a dependency on\n * decision 8 here without re-running the conformance gate suite first.\n *\n * The invariant a future simplifier has to re-check: a single slot would pass\n * every test in `io-context.test.ts`, and that was established by trying it,\n * not by argument. `current()` is only read from inside a slice, every slice\n * pushes its own lock last, and no second slice can begin while an earlier\n * frame is still waiting for its checkpoint-end exit — that frame is holding\n * the gate. So the top of a stack and the last write to a slot always agree.\n * The stack is still what is here, because a slot would be holding a stale\n * value at every one of the overlaps in (4), and that is unobservable for\n * exactly as long as the invariant holds. Tightening (2) back to the end of the\n * synchronous body breaks it immediately, which is the regime the mechanic was\n * found in.\n *\n * Spec: §1.2, §1.3, §1.5, §1.6, §1.7.1, §1.9, decisions 1, 2, 4 and 13 in\n * docs/decisions.md.\n *\n * `TimeoutManager` is the only part of this file a consumer's own code reaches\n * directly: every host-provided async primitive a\n * Durable Object can await has to route through here, or the continuation after\n * it resumes with an empty invocation stack. `TimeoutManager` below is the\n * timer half; `api/global-scope.ts` and `api/web-socket.ts` are the rest.\n *\n * Not ported, because the substrate has no equivalent to port onto: isolate and\n * async locks (`Worker::Lock`, `jsg::Lock`, `takeAsyncLock`) and everything\n * that exists to enter or leave an isolate — which is precisely the thing this\n * file substitutes for; the limit enforcer and `afterLimitTimeout` (the\n * deadline takes the `Timer` port instead); trace spans, already a recorded\n * divergence documented in §1.12; subrequest channels and HTTP, which are\n * `api/http.ts`'s gating over the substrate's own `fetch`;\n * `IoOwn`/`IoPtr`/`DeleteQueue`, which guard cross-context dereferences that GC\n * makes impossible; hang detection and `registerPendingEvent`, which need the\n * isolate's own idea of pending work; and the thread-local\n * `IoContext::current()` static, whose lock-resolving half the invocation stack\n * replaces — its *identity* half is `currentSlice` below, narrowed to the\n * synchronous slice, with one consumer and no resolver. `EventOutcome` and\n * `RequestObserver` are metrics types with no port, so `waitUntilStatus()`\n * returns the first exception instead.\n */\n\nimport {\n CriticalSection,\n type InputGate,\n Lock,\n type OutputGate,\n} from \"./io-gate\";\n\n/**\n * ← `kj::Timer`, threaded into IoContext upstream.\n *\n * A port with one production implementation would be an invented seam; this\n * one has two (real clock in browser and workerd) plus a fake the conformance\n * suite cannot exist without — the 30-second critical-section deadline and the\n * alarm retry ladder are not assertable on wall-clock time in CI.\n */\nexport interface Timer {\n now(): number;\n /** `kj::Timer::afterDelay`. The signal replaces kj's cancel-by-drop. */\n afterDelay(ms: number, signal?: AbortSignal): Promise<void>;\n}\n\n/**\n * ← the `Worker::Actor` surface reached through an `IoContext`:\n * `a.getInputGate()`, `a.getOutputGate()` and `a.shutdownActorCache()` from\n * `io-context.{h,c++}` itself, plus `assertCanSetAlarm()`, which\n * `api/actor-state.c++:486` reaches through\n * `IoContext::current().getActorOrThrow()`.\n *\n * `Worker::Actor` lives in `io/worker.h`, the same Bazel target as this file, so\n * naming the members its consumers use is upstream's own layering rather than a\n * new seam. Every context here is an actor context — there is no non-actor\n * request in a Durable Object runtime — so upstream's\n * `kj::Maybe<Worker::Actor&>` and every branch that tests it collapse to this\n * being required, and `getActorOrThrow()` cannot actually throw.\n */\nexport interface Actor {\n getInputGate(): InputGate;\n getOutputGate(): OutputGate;\n /** Abort abandons scheduled writes rather than flushing them (§1.6). */\n shutdownActorCache(reason: unknown): void;\n /**\n * ← `Worker::Actor::assertCanSetAlarm()` (`io/worker.c++:4090`). Every branch\n * of it reads the actor's class-instance lifecycle, which `server/` owns, so\n * `api/actor-state.ts`'s obligation is to call it and the container's is to\n * answer it.\n */\n assertCanSetAlarm(): void;\n}\n\n/** ← `static constexpr int64_t max = 3153600000000; // Milliseconds in 100 years`. */\nconst MAX_TIMEOUT_MS = 3_153_600_000_000;\n\n/** ← `afterLimitTimeout(30 * kj::SECONDS)` in `IoContext::blockConcurrencyWhile`. */\nexport const BLOCK_CONCURRENCY_WHILE_TIMEOUT_MS = 30_000;\n\n/** Copied verbatim: users and upstream tests match on it. */\nexport const BLOCK_CONCURRENCY_WHILE_TIMEOUT_MESSAGE =\n \"A call to blockConcurrencyWhile() in a Durable Object waited for too long. \" +\n \"The call was canceled and the Durable Object was reset.\";\n\n/** ← `jsg::annotateBroken(msg, \"broken.inputGateBroken\")`. */\nconst INPUT_GATE_BROKEN_PREFIX = \"broken.inputGateBroken; \";\n\n/**\n * THE check every storage entry point in `api/` makes before touching the\n * database, and the only place this package throws for a missing input lock.\n *\n * Upstream never faces the question. `IoContext::current()` is a thread-local\n * read with a `KJ_REQUIRE` behind it, and it cannot fail for a storage call\n * because isolate entry is the only way into an actor and it always took a\n * lock. We have no isolate hook (see this file's header), so a continuation\n * that resumed from a raw `setTimeout`, a raw `fetch`, or any other promise the\n * runtime does not own comes back with an empty invocation stack, and its next\n * storage call reaches `ActorSqlite` — which is synchronous, touches no gate,\n * and would happily serve it outside any transaction boundary.\n *\n * So this throws, matching the assert. It is deliberately ONE function called\n * from every entry point rather than a check written at each of them: the\n * policy is a design decision that belongs to the design record, and when it\n * changes it has to change in one place rather than across a surface the\n * vendored consumer reaches from hundreds of call sites. There is no lenient\n * mode, no flag, and no implicit acquire — a lost invocation is loud, and a\n * lost transaction boundary is not.\n */\nexport function requireInputLock(ctx: IoContext, op: string): void {\n if (ctx.hasCurrent()) return;\n throw new Error(`${op}: no input lock available in this context`);\n}\n\n/**\n * The end of the microtask checkpoint — the moment `runImpl`'s `KJ_DEFER` fires.\n *\n * Upstream drains the whole checkpoint INSIDE the isolate run: the defer calls\n * `js.runMicrotasks()` and only the outer defer in `runInContextScope` then\n * clears `currentInputLock`. So a continuation that awaits nothing but\n * already-resolved promises stays under the same lock, and a continuation that\n * waits on real I/O does not. In JS the only observable end of a microtask drain\n * is the next macrotask, so that is where a lock leaves the invocation stack.\n *\n * Measured, because the obvious alternatives are wrong in ways nothing catches:\n * releasing synchronously when the invoked function returns, or on the next\n * microtask, both hand the lock back BEFORE the code awaiting the I/O resumes as\n * soon as one promise sits between the two — one `async` wrapper, a `.then`, a\n * `Promise.all` — and `actor-state.ts` is exactly such a wrapper. The gate would\n * then open in the middle of a storage await with no test failing, which is the\n * silent loss of atomicity §1.7.1 names.\n *\n * `MessageChannel` and not `setTimeout`, decided by benchmark rather than by\n * argument, because the two are three orders of magnitude apart on the shapes\n * that wait for a release. A chain of these schedules each hand-off from inside\n * the previous one's callback, so a `setTimeout` chain's nesting level climbs\n * past five and stays there, where browsers clamp it to 4ms. Median per hand-off\n * over 50 chained hops:\n *\n * | | setTimeout | MessageChannel |\n * | node | 1.273 ms | 0.018 ms |\n * | chromium page | 4.96 ms | 0.024 ms |\n * | chromium Worker | 5.542 ms | 0.022 ms |\n *\n * Only two shapes pay it: an `awaitIo` chain, which has to re-acquire the lock\n * its slice gave up, and a queue of events waiting on the holder. A chain of\n * held storage awaits does not — the lock passes from `addRef` to `addRef` and\n * the release is off the critical path. So 50 sequential facet RPCs cost 277ms\n * of pure clamp in a Worker under `setTimeout` and 1.1ms under this.\n *\n * One channel per BATCH, and a batch is an explicit array: `atCheckpointEnd`\n * pushes onto `pendingCheckpointEnds` and only the push that finds it empty opens\n * a channel. Ordering then comes from the array, which the language guarantees,\n * rather than from delivery order across separate channels, which no\n * specification does. That mattered because the storage engine below depends on\n * a commit scheduled inside a slice running before the release scheduled at the\n * end of that slice; separate channels do deliver in post order in Node,\n * measured across 200 of them including one scheduled from inside another's\n * callback, but a browser that chose otherwise would open the gate onto a\n * transaction a previous event left open, and nothing would say so.\n *\n * A callback scheduled DURING a drain lands in the next batch, which is the\n * semantics to want: one hand-off is one checkpoint end, and a slice that begins\n * inside this drain gets its own. The drain runs every callback even if one\n * throws, and rethrows the first exception afterwards, because abandoning the\n * rest of a batch is how a gate wedges with nothing to see.\n *\n * A long-lived shared port was rejected for the reason it always is: it has to be\n * closed on abort and `unref`'d so it cannot hold a test runner's event loop\n * open, and an `unref`'d port can drop a release at exit — a wedged gate. A\n * channel that lives for exactly one message cannot. Batching gets most of what\n * a shared port was worth anyway: a slice that schedules a commit and a release\n * now allocates one channel where it used to allocate two.\n *\n * **Exported because `kj::evalLater()` is this same point.** `ActorSqlite` opens\n * its implicit transaction on the first write and commits it \"on the next turn of\n * the event loop\" (`actor-sqlite.c++:352-357`); upstream's next turn is after the\n * isolate run, which is after `js.runMicrotasks()`, which is after\n * `currentInputLock` is cleared. Upstream's two boundaries are one boundary, and\n * they stay one here only if the commit rides the same primitive as the release.\n * Two consequences the storage engine depends on, both properties of this\n * function rather than of `ActorSqlite`:\n *\n * 1. **Everything that holds the input lock across an await is a microtask\n * chain.** `awaitIoWithInputLock` resumes through `#awaitIoImpl`'s `.then`\n * into `run(func, lock)`, which never waits on the gate. So a whole run of\n * held storage awaits finishes before the next hand-off and its writes are\n * one transaction (§1.7.1 row 1).\n * 2. **Everything that releases it needs at least one hand-off.** `awaitIo`\n * resumes through `gate.wait()`, which cannot resolve until `#exit` runs\n * here. So a timer or outbound await puts the commit between the two writes\n * (§1.7.1 row 2).\n *\n */\nexport function atCheckpointEnd(run: () => void): void {\n pendingCheckpointEnds.push(run);\n if (pendingCheckpointEnds.length > 1) return;\n\n const channel = new MessageChannel();\n // Assigning `onmessage` starts the port; `addEventListener` would need `start()`.\n channel.port1.onmessage = () => {\n channel.port1.close();\n channel.port2.close();\n // A snapshot, so a callback scheduled by one of these belongs to the next batch — and, since\n // the queue is empty while the batch runs, that push opens the next channel by itself.\n const batch = pendingCheckpointEnds.splice(0);\n let failure: { readonly exception: unknown } | undefined;\n for (const callback of batch) {\n try {\n callback();\n } catch (exception) {\n failure ??= { exception };\n }\n }\n if (failure !== undefined) throw failure.exception;\n };\n channel.port2.postMessage(0);\n}\n\n/** The current batch. Its order is the hand-off order every consumer below relies on. */\nconst pendingCheckpointEnds: (() => void)[] = [];\n\n// =======================================================================================\n// `IoContext::current()`, narrowed to what JS can express\n\n/**\n * ← `static thread_local IoContext* threadLocalRequest` (`io-context.c++:25`).\n *\n * **This is NOT an async context and must not become one.** It is set on entry\n * to a slice's SYNCHRONOUS body and restored the instant that body returns —\n * which for an `async` function is its first `await`. It propagates through\n * exactly nothing. The package's \"no async context is required\" property\n * (README, Part 4 mechanic 1) is undisturbed: nothing resolves a lock through\n * this, and deleting it would change no gate behaviour.\n *\n * Upstream's scope is wider and cannot be matched. `runInContextScope` saves the\n * previous context, installs itself, and restores at the end of the isolate run\n * — which drains the whole microtask checkpoint synchronously, so upstream's\n * `current()` covers a slice's continuations too. JS cannot drain a checkpoint\n * synchronously, so covering continuations here would mean holding the value\n * until `atCheckpointEnd`, and by then a SECOND actor's body can have run and\n * left. That is not a hazard upstream has: two actors' slices genuinely overlap\n * in this window (§1.10 gives every facet its own gates, so nothing serialises\n * a parent against its child), and the value would be wrong with nothing to say\n * so.\n *\n * So the port keeps only the half that is exact, and the one consumer is a\n * tripwire that refuses on mismatch and stays quiet on `undefined` — never a\n * resolver. See `requireOwnSlice` in `api/global-scope.ts`.\n */\nlet currentSlice: IoContext | undefined;\n\n/** ← `IoContext::tryCurrent()` (`io-context.c++:1416-1422`), over the narrowed scope above. */\nexport function tryCurrentSlice(): IoContext | undefined {\n return currentSlice;\n}\n\n/**\n * ← the `SuppressIoContextScope` constructor's `threadLocalRequest = this` half\n * (`io-context.c++:1208`), as a function rather than an assignment in `#runImpl`.\n *\n * A function because `currentSlice = this` reads to a linter as a `this` alias — the\n * ES5 `var self = this` habit — when it is the opposite: publishing the running\n * context to a module scope, which is exactly what the C++ does to a thread local.\n */\nfunction enterSlice(context: IoContext | undefined): void {\n currentSlice = context;\n}\n\n/** ← `kj::OneOf<T, kj::Exception>`, the result of `promiseForExceptionOrT()`. */\ntype Outcome<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly exception: unknown };\n\n/** ← `promiseForExceptionOrT()`: merge the rejection into the value so it survives the hop. */\nfunction promiseForExceptionOrT<T>(promise: Promise<T>): Promise<Outcome<T>> {\n return promise.then(\n (value): Outcome<T> => ({ ok: true, value }),\n (exception: unknown): Outcome<T> => ({ ok: false, exception }),\n );\n}\n\n/** ← `IdentityFunc<T>`. */\nfunction identity<T>(value: T): T {\n return value;\n}\n\n/**\n * ← the `if (!msg.startsWith(\"broken.\"))` guard in `blockConcurrencyWhile`'s error\n * handler. Upstream rewrites the exception's description in place, so this does\n * too. `jsg`'s exception tunnelling — the `jsg.Error:` / `remote.` prefixes\n * `annotateBroken()` also produces — has no port here, so only the brokenness tag\n * it exists to carry survives.\n */\nfunction annotateInputGateBroken(exception: unknown): void {\n if (!(exception instanceof Error)) return;\n if (exception.message.startsWith(\"broken.\") || exception.message.startsWith(\"remote.broken.\")) {\n return;\n }\n exception.message = INPUT_GATE_BROKEN_PREFIX + exception.message;\n}\n\n/**\n * ← `jsg::isExceptionFromInputGateBroken` (`jsg/exception.c++:168-172`):\n * \"annotateBroken() produces 'broken.inputGateBroken; {message}', optionally\n * prefixed with 'remote.' when crossing RPC boundaries. Strip the remote prefix\n * first, then check the tag.\"\n *\n * Its writer is `annotateInputGateBroken` directly above, which is why the two\n * live together rather than the reader moving to its consumer: `jsg/` has no\n * module here, and a prefix known in two places is a prefix that drifts.\n */\nexport function isExceptionFromInputGateBroken(exception: unknown): boolean {\n if (!(exception instanceof Error)) return false;\n let description = exception.message;\n // \"there are cases where we return a tunneled error through multiple workers, so let's be\n // paranoid and allow for multiple 'remote.' prefixes\" (`jsg/exception.c++:52-57`).\n while (description.startsWith(REMOTE_EXCEPTION_PREFIX)) {\n description = description.slice(REMOTE_EXCEPTION_PREFIX.length);\n }\n return description.startsWith(INPUT_GATE_BROKEN_PREFIX);\n}\n\n/** ← `ERROR_REMOTE_PREFIX` (`jsg/exception.h`). */\nconst REMOTE_EXCEPTION_PREFIX = \"remote.\";\n\n/**\n * ← `jsg::EXCEPTION_IS_USER_ERROR` (`jsg/exception.h:160`), a\n * `kj::Exception::DetailTypeId` attached to an arbitrary exception rather than a\n * type of exception.\n *\n * A symbol-keyed property is the closest JS has: it rides any thrown object,\n * survives a rethrow, and cannot collide with anything an application writes.\n * `Symbol.for` rather than `Symbol()` so the detail is still legible after the\n * exception crosses a realm — the mistake decision 18 records capnweb making.\n */\nexport const EXCEPTION_IS_USER_ERROR = Symbol.for(\"workerd.exceptionIsUserError\");\n\n/** ← `error.setDetail(jsg::EXCEPTION_IS_USER_ERROR, kj::heapArray<byte>(0))`. */\nexport function setUserErrorDetail(exception: unknown): void {\n if (typeof exception !== \"object\" || exception === null) return;\n Object.defineProperty(exception, EXCEPTION_IS_USER_ERROR, {\n value: true,\n enumerable: false,\n configurable: true,\n });\n}\n\n/** ← `e.getDetail(jsg::EXCEPTION_IS_USER_ERROR) != kj::none`. */\nexport function hasUserErrorDetail(exception: unknown): boolean {\n if (typeof exception !== \"object\" || exception === null) return false;\n return (exception as Record<symbol, unknown>)[EXCEPTION_IS_USER_ERROR] === true;\n}\n\n// =======================================================================================\n// Timers\n\n/**\n * ← `TimeoutManager::TimeoutParameters` (`io/io-timers.h:71-80`).\n *\n * `callback` is nullable for upstream's stated reason: \"This is a maybe to allow\n * cancel to clear it and free the reference when it is no longer needed.\"\n */\ntype TimeoutParameters = {\n readonly repeat: boolean;\n readonly msDelay: number;\n callback: (() => void) | undefined;\n};\n\n/** ← `IoContext::TimeoutManagerImpl::TimeoutState` (`io-context.c++:133-148`). */\ntype TimeoutState = {\n readonly params: TimeoutParameters;\n isCanceled: boolean;\n /**\n * ← `kj::Maybe<kj::Promise<void>> maybePromise`, whose presence upstream reads\n * as \"this timeout is armed\". kj cancels by dropping the promise; there is no\n * drop here, so the signal that aborts the underlying `Timer.afterDelay` is\n * carried beside it — the same substitution Section 1 made for every kj\n * cancel-by-drop.\n */\n armed: AbortController | undefined;\n};\n\n/**\n * ← `IoContext::TimeoutManagerImpl` (`io-context.c++:40-140`, `:742-880`).\n *\n * **The one mechanic worth reading twice: a timer is NOT `awaitIo`.** Upstream\n * says why in a comment on the very line (`io-context.c++:756-758`): \"the manual\n * use of run() here (including carrying over the critical section) is kind of\n * ugly, but using awaitIo() doesn't work here because we need the ability to\n * cancel the timer, so we don't want to addTask() it, which awaitIo() does\n * implicitly.\" So the shape is `cs = ctx.getCriticalSection()` captured at the\n * call, then `ctx.run(callback, cs)` when it fires. The captured section is what\n * makes a timer armed inside `blockConcurrencyWhile` run INSIDE that section\n * rather than queueing on the root gate behind it.\n *\n * **Substrate divergence: one `Timer.afterDelay` per timeout, where upstream\n * keeps a sorted `timeoutTimes` map and a single `timerTask` for the nearest.**\n * That structure exists because `kj::TimerChannel::atTime` supports one pending\n * wait, so upstream has to multiplex; `Timer.afterDelay` takes as many\n * concurrent waits as are asked for. The observable properties it produced —\n * timers fire in deadline order, ties broken by arming order — are the ones both\n * lane timers already have, since both are `setTimeout` underneath. Nothing else\n * in `resetTimerTask` is observable, so nothing else is ported.\n *\n * Not ported: `TimeoutId::Generator` and its cross-`ServiceWorkerGlobalScope`\n * assertion (`io-context.c++:52-60`), which exists to catch an IoContext being\n * current for a different V8 context — a confusion with no shape here, since a\n * timeout id is minted by the manager that owns it; `registerPendingEvent`,\n * which needs the isolate's own idea of pending work; and `getNextTimeout`,\n * whose only caller is the limit enforcer.\n */\nclass TimeoutManager {\n readonly #timer: Timer;\n readonly #timeouts = new Map<number, TimeoutState>();\n #nextId = 1;\n\n constructor(timer: Timer) {\n this.#timer = timer;\n }\n\n /** ← `TimeoutManagerImpl::setTimeout` (`io-context.c++:51-67`). */\n setTimeout(ctx: IoContext, params: TimeoutParameters): number {\n const id = this.#nextId++;\n const state: TimeoutState = { params, isCanceled: false, armed: undefined };\n this.#timeouts.set(id, state);\n this.#arm(ctx, id, state);\n return id;\n }\n\n /** ← `TimeoutManagerImpl::clearTimeout` (`io-context.c++:874-883`). */\n clearTimeout(id: number): void {\n const state = this.#timeouts.get(id);\n // \"We can't find this timeout, thus we act as if it was already canceled.\"\n if (state === undefined) return;\n this.#cancel(id, state);\n }\n\n /** ← `TimeoutManagerImpl::getTimeoutCount` (`io-context.c++:71-73`). */\n getTimeoutCount(): number {\n return this.#timeouts.size;\n }\n\n /** ← `TimeoutManagerImpl::cancelAll` (`io-context.c++:83-87`). */\n cancelAll(): void {\n for (const [id, state] of [...this.#timeouts]) this.#cancel(id, state);\n }\n\n /** ← `TimeoutState::cancel` — clear the flag, drop the callback reference, disarm. */\n #cancel(id: number, state: TimeoutState): void {\n state.isCanceled = true;\n state.params.callback = undefined;\n state.armed?.abort();\n state.armed = undefined;\n this.#timeouts.delete(id);\n }\n\n /** ← `TimeoutManagerImpl::setTimeoutImpl` (`io-context.c++:742-853`). */\n #arm(ctx: IoContext, id: number, state: TimeoutState): void {\n // Captured HERE, at the arming call, exactly as upstream captures it into the `.then` lambda.\n // Reading it when the timer fires would give a new external event the running section and\n // `blockConcurrencyWhile` would silently block nothing (Part 4, mechanic 2).\n const criticalSection = ctx.getCriticalSection();\n const wake = new AbortController();\n state.armed = wake;\n\n const fired = this.#timer.afterDelay(state.params.msDelay, wake.signal).then(\n async () => {\n if (state.isCanceled) return;\n state.armed = undefined;\n await this.#fire(ctx, id, state, criticalSection);\n },\n (exception: unknown) => {\n // kj cancels by dropping the promise, which cannot report anything; Section 1 records\n // that the substitution turns every cancel-by-drop into an `AbortSignal` whose waiter\n // rejects with `CanceledError`. A wake THIS manager aborted is that cancellation and not\n // a failure. Anything else is the timer port's and is reported, so a substrate that\n // fails to keep time cannot look like a timer nobody armed.\n if (!state.isCanceled) throw exception;\n },\n );\n\n // ← `context.addWaitUntil(kj::mv(paf.promise))` (`io-context.c++:845-851`): \"Add a wait-until\n // task which resolves when this timer completes. This ensures that `IncomingRequest::drain()`\n // waits until all timers finish.\"\n //\n // Divergence, and it is the fail-closed direction. Upstream additionally swallows the chain's\n // rejection outright (`[](kj::Exception&&) {}`, `io-context.c++:817`) because a JS throw from\n // the callback has already reached the isolate's uncaught-exception path. There is no such path\n // here, so a swallow would lose it entirely; routing the rejection through the waitUntil set\n // records it in `waitUntilStatus()` — the context's existing failure channel — instead of\n // inventing a second one.\n ctx.addWaitUntil(fired);\n }\n\n /** ← the body of the `.then` at `io-context.c++:759-816`, which is one `context.run`. */\n async #fire(\n ctx: IoContext,\n id: number,\n state: TimeoutState,\n criticalSection: CriticalSection | undefined,\n ): Promise<void> {\n await ctx.run(() => {\n // \"We've been canceled before running. Nothing more to do.\"\n if (state.isCanceled) return;\n const callback = state.params.callback;\n if (callback === undefined) return;\n\n // ← \"First, move our timeout promise to the task set so it's safe to call clearInterval()\n // inside the user's callback.\" A non-repeating timeout is done with its entry either way; a\n // repeating one keeps it so `clearInterval` inside the callback still finds it.\n if (!state.params.repeat) {\n state.params.callback = undefined;\n this.#timeouts.delete(id);\n }\n\n // ← the `KJ_DEFER(unwindDetector.catchExceptionsIfUnwinding(...))`: \"The user's callback\n // might throw, but we need to at least attempt to reschedule interval callbacks even if\n // they throw.\"\n try {\n callback();\n } finally {\n if (state.params.repeat && !state.isCanceled) this.#arm(ctx, id, state);\n }\n }, criticalSection);\n }\n}\n\n/**\n * A set of background promises, with the one behaviour `kj::TaskSet` adds over an\n * array: a failing task reports to `taskFailed` instead of becoming an unhandled\n * rejection, and the set can be waited on until empty.\n */\nclass TaskSet {\n readonly #tasks = new Set<Promise<void>>();\n readonly #taskFailed: (exception: unknown) => void;\n\n constructor(taskFailed: (exception: unknown) => void) {\n this.#taskFailed = taskFailed;\n }\n\n add(promise: Promise<void>): void {\n const task = promise.then(\n () => {\n this.#tasks.delete(task);\n },\n (exception: unknown) => {\n this.#tasks.delete(task);\n this.#taskFailed(exception);\n },\n );\n this.#tasks.add(task);\n }\n\n /** ← `kj::TaskSet::onEmpty()`. Re-checks, since a task can add another. */\n async onEmpty(): Promise<void> {\n while (this.#tasks.size > 0) {\n await Promise.all([...this.#tasks]);\n }\n }\n}\n\n// =======================================================================================\n// IoContext\n\nexport class IoContext {\n readonly #actor: Actor;\n readonly #timer: Timer;\n\n /**\n * ← `kj::Maybe<InputGate::Lock> currentInputLock`, made a stack.\n *\n * The top entry is the lock of the slice that is running right now. Entries are\n * removed by identity rather than popped, so `#exit` never depends on the order\n * the overlapping slices happen to leave in.\n */\n readonly #currentInputLocks: Lock[] = [];\n\n #abortException: { readonly exception: unknown } | undefined;\n readonly #abortPromise: Promise<never>;\n readonly #rejectAbort: (exception: unknown) => void;\n\n /**\n * Two sets, as upstream: `abortWhen()` always uses `tasks` so that a monitor\n * which never completes cannot hold up a drain, while `addTask()` in an actor\n * is a waitUntil task.\n */\n readonly #tasks: TaskSet;\n readonly #waitUntilTasks: TaskSet;\n #addTaskCounter = 0;\n #waitUntilStatus: { readonly exception: unknown } | undefined;\n\n /** ← `kj::Own<TimeoutManager> timeoutManager` (`io-context.h:1043`). */\n readonly #timeouts: TimeoutManager;\n\n constructor(actor: Actor, timer: Timer) {\n this.#actor = actor;\n this.#timer = timer;\n this.#timeouts = new TimeoutManager(timer);\n\n const { promise, reject } = Promise.withResolvers<never>();\n this.#abortPromise = promise;\n this.#rejectAbort = reject;\n // kj's ForkedPromise just holds the exception until someone adds a branch.\n void promise.catch(() => {});\n\n this.#tasks = new TaskSet((exception) => this.#taskFailed(exception));\n this.#waitUntilTasks = new TaskSet((exception) => this.#taskFailed(exception));\n\n // Arrange to complain if the input gate is broken, which indicates a critical section\n // failed and the actor can no longer be used.\n this.abortWhen(actor.getInputGate().onBroken());\n\n // Also complain if the output gate is broken, which indicates a critical storage failure\n // that means we cannot continue execution.\n this.abortWhen(actor.getOutputGate().onBroken());\n }\n\n // -----------------------------------------------------------------\n // The ambient lock\n\n /**\n * Get the current input lock. Throws an exception if no input lock is held (e.g. because\n * this is not an actor request).\n *\n * ← `KJ_ASSERT_NONNULL(currentInputLock, ...).addRef()`. The `addRef` IS the §1.2\n * distinction: it is the only way to hold the gate past the end of this slice.\n */\n getInputLock(): Lock {\n return this.#requireCurrent().addRef();\n }\n\n /** Get the current CriticalSection, if there is one, or returns null if not. */\n getCriticalSection(): CriticalSection | undefined {\n return this.#currentInputLocks.at(-1)?.getCriticalSection();\n }\n\n /** Is a gated slice running? The question `IoContext::hasCurrent()` answers upstream. */\n hasCurrent(): boolean {\n return this.#currentInputLocks.length > 0;\n }\n\n /**\n * ← `IoContext::isCurrent()` (`io-context.c++:1428-1430`), over the narrowed\n * scope `currentSlice` documents: true only while a synchronous body of THIS\n * context is on the JS stack.\n *\n * Distinct from `hasCurrent()` above, which asks whether this context holds a\n * lock at all — true throughout an outstanding held await, and true for a\n * parent whose slice is awaiting a facet while the facet's body runs. This one\n * is the question a shared global has to answer: is the code calling me this\n * actor's?\n */\n isCurrentSlice(): boolean {\n return currentSlice === this;\n }\n\n /**\n * ← `IoContext::getActorOrThrow()`. Upstream's throws when the request is not\n * an actor request; there is no such request here, so it is a plain accessor.\n */\n getActorOrThrow(): Actor {\n return this.#actor;\n }\n\n /** ← `IoContext::now()` (`io-context.h:703`), which reads the same timer. */\n now(): number {\n return this.#timer.now();\n }\n\n // -----------------------------------------------------------------\n // Timers\n\n /**\n * ← `IoContext::setTimeoutImpl` (`io-context.c++:885-899`), clamp included.\n *\n * The generator parameter is gone with `TimeoutId::Generator` — see\n * `TimeoutManager`'s header — so the signature is upstream's minus that one\n * argument.\n */\n setTimeoutImpl(repeat: boolean, callback: () => void, msDelay: number): number {\n // \"Clamp the range on timers to [0, 3153600000000] (inclusive). The specs do not indicate a\n // clear maximum range for setTimeout/setInterval so the limit here is fairly arbitrary. 100\n // years max should be plenty safe.\"\n const delay =\n msDelay <= 0 || Number.isNaN(msDelay)\n ? 0\n : msDelay >= MAX_TIMEOUT_MS\n ? MAX_TIMEOUT_MS\n : Math.trunc(msDelay);\n return this.#timeouts.setTimeout(this, { repeat, msDelay: delay, callback });\n }\n\n /** ← `IoContext::clearTimeoutImpl` (`io-context.c++:901-903`). */\n clearTimeoutImpl(id: number): void {\n this.#timeouts.clearTimeout(id);\n }\n\n /** ← `IoContext::getTimeoutCount` (`io-context.c++:905-907`). */\n getTimeoutCount(): number {\n return this.#timeouts.getTimeoutCount();\n }\n\n // -----------------------------------------------------------------\n // The output gate\n\n /**\n * Wait until all outstanding output locks have been unlocked. Does not wait for future\n * output locks, even if they are created before past locks are unlocked.\n */\n waitForOutputLocks(): Promise<void> {\n return this.#actor.getOutputGate().wait();\n }\n\n /**\n * Check if the output gate is currently broken. This indicates that there was a problem\n * with committing storage writes.\n */\n isOutputGateBroken(): boolean {\n return this.#actor.getOutputGate().isBroken();\n }\n\n /** Lock output until the given promise completes. */\n lockOutputWhile<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n return this.#actor.getOutputGate().lockWhile(promise, signal);\n }\n\n // -----------------------------------------------------------------\n // Abort\n\n /**\n * Rejects if and when the context should be aborted, e.g. because a gate broke. This\n * promise never resolves, only rejects.\n */\n onAbort(): Promise<never> {\n return this.#abortPromise;\n }\n\n /** Force context abort now. */\n abort(exception: unknown): void {\n if (this.#abortException !== undefined) {\n return;\n }\n this.#abortException = { exception };\n\n // Stop the ActorCache from flushing any scheduled write operations to prevent any\n // unnecessary or unintentional async work.\n this.#actor.shutdownActorCache(exception);\n\n // ← `timeoutManager->cancelAll()` in `~IoContext_IncomingRequest`, plus the\n // `context.abortException == kj::none` guard that stops `setTimeoutImpl` rescheduling into an\n // aborted context (`io-context.c++:832`). Upstream reaches both through destruction; with no\n // destructors, abort is the one event that stands for it. Without this a pending timer wakes\n // into `run()`, which refuses an aborted context, and the refusal lands in `waitUntilStatus()`\n // as a failure nobody caused.\n this.#timeouts.cancelAll();\n\n this.#rejectAbort(exception);\n }\n\n /**\n * Await the given promise and, if it throws, call `abort()` with the exception. The promise\n * given here should just be a monitoring promise, it should not represent any sort of\n * background work beyond monitoring.\n */\n abortWhen(promise: Promise<unknown>): void {\n if (this.#abortException === undefined) {\n this.#tasks.add(\n promise.then(\n () => {},\n (exception: unknown) => {\n this.abort(exception);\n },\n ),\n );\n }\n }\n\n // -----------------------------------------------------------------\n // Task scheduling\n\n /**\n * Arrange for the given promise to execute as part of this request.\n *\n * \"In Actors, we treat all tasks as wait-until tasks, because it's perfectly legit to start\n * a task under one request and then expect some other request to handle it later.\" Every\n * context here is an actor context, so that branch is the only branch.\n */\n addTask(promise: Promise<void>): void {\n ++this.#addTaskCounter;\n this.addWaitUntil(promise);\n }\n\n /**\n * Indicates that the script has requested that it stay active until the given promise\n * resolves. `drainWaitUntil()` waits until all such promises have completed. Touches\n * neither gate (§1.9).\n */\n addWaitUntil(promise: Promise<void>): void {\n this.#waitUntilTasks.add(promise);\n }\n\n /** Returns the number of times addTask() has been called (even if the tasks have completed). */\n taskCount(): number {\n return this.#addTaskCounter;\n }\n\n /**\n * The first exception a background task failed with, if any.\n *\n * ← `waitUntilStatus()`, which returns an `EventOutcome` derived from the exception by\n * `RequestObserver`. There is no observer here, so the exception itself is the status —\n * and keeping it is what stops a failed background task from being swallowed, since\n * upstream's other half of `taskFailed()` is a log this package has no port for.\n */\n waitUntilStatus(): unknown {\n return this.#waitUntilStatus?.exception;\n }\n\n /**\n * ← `IncomingRequest::drain()`, actor branch. \"For actors, all promises are canceled on\n * actor shutdown, not on a fixed timeout, because work doesn't necessarily happen on a\n * per-request basis in actors.\"\n */\n async drainWaitUntil(): Promise<void> {\n await Promise.race([this.#waitUntilTasks.onEmpty(), this.#abortPromise.catch(() => {})]);\n }\n\n // -----------------------------------------------------------------\n // Entry\n\n /**\n * Run the given callback within this context, holding an input lock.\n *\n * ← the two `IoContext::run()` overloads: given a CriticalSection it waits on that, given\n * an already-held Lock it runs under it, and given neither it takes a fresh lock from the\n * gate. The third case is what a new external event does, and it is the reason inheritance\n * cannot be read from gate state — see `makeReentryCallback`.\n */\n async run<T>(\n func: (lock: Lock) => T | PromiseLike<T>,\n ilOrCs?: Lock | CriticalSection,\n ): Promise<T> {\n // Before we try running anything, let's make sure our IoContext hasn't been aborted. If it\n // has been aborted, there's likely not an active request so later operations will fail\n // anyway.\n const aborted = this.#abortException;\n if (aborted !== undefined) {\n throw aborted.exception;\n }\n\n let lock: Lock;\n if (ilOrCs === undefined) {\n lock = await this.#actor.getInputGate().wait();\n } else if (ilOrCs instanceof CriticalSection) {\n lock = await ilOrCs.wait();\n } else {\n lock = ilOrCs;\n }\n\n return await this.#runImpl(func, lock);\n }\n\n /**\n * Make a function which, when called, re-enters this IoContext to run some code.\n *\n * Upstream, on why the critical section travels with the callback at all:\n *\n * > \"What if the call was made within blockConcurrencyWhile()? The callback will be blocked\n * > until the critical section ends, which could lead to deadlock if the critical section\n * > code is waiting on it? ... The callback is allowed to run within the critical section\n * > (blockConcurrencyWhile()) from which it was called.\"\n *\n * The section is read here, at the point of capture, and never on invocation: a new\n * external event that inherited the running section would skip the queue and\n * `blockConcurrencyWhile` would silently block nothing (Part 4, mechanic 2).\n *\n * The returned function can be called multiple times.\n *\n * It does not route through `io-gate.ts`'s `makeReentryCallback`, which is the same idea\n * expressed at the gate. Upstream's `IoContext::makeReentryCallback` is literally\n * `ctx.run(func, cs)`, and going through the gate helper instead would take a lock this\n * file then has to make current a second time. The gate copy stays: it is the shape a\n * consumer holding only a gate needs, and Section 1's tests cover it.\n */\n makeReentryCallback<Args extends unknown[], Result>(\n func: (lock: Lock, ...args: Args) => Result | PromiseLike<Result>,\n ): (...args: Args) => Promise<Result> {\n // A reentry callback is meant for *re-*entry, so should only be created while already\n // inside the IoContext. Initial entry should just use run().\n this.#requireCurrent();\n const criticalSection = this.getCriticalSection();\n\n return async (...args: Args): Promise<Result> => {\n const call = this.run((lock) => func(lock, ...args), criticalSection);\n\n // ← the `addTask()` + `registerPendingEvent()` pair, which keeps the context live while\n // a callback is outstanding. Upstream scopes that to the callback's lifetime via a\n // destructor; with no destructors the closest live analogue is the in-flight call, which\n // is what should stop `drainWaitUntil()` reporting idle. The outcome is swallowed here\n // only because the caller already receives it.\n this.addTask(\n call.then(\n () => {},\n () => {},\n ),\n );\n\n return await call;\n };\n }\n\n // -----------------------------------------------------------------\n // The two await forms\n\n /**\n * Waits for some background I/O to complete, then executes `func` on the result.\n *\n * The input lock is NOT held across the wait: the resumption re-enters through\n * `run(func, criticalSection)` and takes a fresh lock, so it queues behind whatever\n * arrived in the meantime. This is what makes a Durable Object awaiting another Durable\n * Object fully re-entrant (§1.3).\n *\n * `func` is a parameter rather than something the caller chains, for upstream's reason:\n * chaining \"required returning to the KJ event loop between running func() and running\n * whatever JavaScript code was waiting on it\". Here the equivalent cost is a promise hop\n * outside the lock.\n */\n awaitIo<T>(promise: Promise<T>): Promise<T>;\n awaitIo<T, R>(promise: Promise<T>, func: (value: T) => R | PromiseLike<R>): Promise<R>;\n awaitIo<T, R>(\n promise: Promise<T>,\n func: (value: T) => R | PromiseLike<R> = identity as (value: T) => R,\n ): Promise<R> {\n return this.#awaitIoImpl(promise, this.getCriticalSection(), func);\n }\n\n /**\n * Waits for the given I/O while holding the input lock, so that all other I/O is blocked\n * from completing in the meantime (unless it is also holding the same input lock).\n *\n * This is the whole of §1.2's asymmetry, and per §1.7.1 it is also the implicit-transaction\n * boundary: the four async storage calls take this form, everything else takes `awaitIo`.\n * Calling it outside a gated slice throws rather than inventing a lock — a lost invocation\n * is loud, a lost transaction boundary is not.\n */\n awaitIoWithInputLock<T>(promise: Promise<T>): Promise<T>;\n awaitIoWithInputLock<T, R>(\n promise: Promise<T>,\n func: (value: T) => R | PromiseLike<R>,\n ): Promise<R>;\n awaitIoWithInputLock<T, R>(\n promise: Promise<T>,\n func: (value: T) => R | PromiseLike<R> = identity as (value: T) => R,\n ): Promise<R> {\n let inputLock: Lock;\n try {\n // The exception is unchanged; only its shape is. A method that returns a promise and\n // sometimes throws synchronously instead escapes the caller's `.catch`, and this is the\n // one call every storage method makes.\n inputLock = this.getInputLock();\n } catch (exception) {\n return Promise.reject(exception);\n }\n return this.#awaitIoImpl(promise, inputLock, func);\n }\n\n // -----------------------------------------------------------------\n // blockConcurrencyWhile\n\n /**\n * Runs `callback` within its own critical section, returning its final result. If\n * `callback` throws, the input lock will break, resetting the actor.\n *\n * Three behaviours live here rather than in `io-gate.ts`, which has no timer, and rather\n * than in `api/actor-state.ts`, whose own `blockConcurrencyWhile` is a one-line forward:\n * the 30-second deadline, the brokenness annotation, and the fact that on failure the\n * returned promise is never settled at all.\n */\n blockConcurrencyWhile<T>(callback: (lock: Lock) => T | PromiseLike<T>): Promise<T> {\n const lock = this.getInputLock();\n const criticalSection = lock.startCriticalSection();\n const { promise: result, resolve } = Promise.withResolvers<T>();\n\n this.addTask(\n (async () => {\n try {\n const value = await this.#runCriticalSection(criticalSection, callback);\n\n // Hand the parent lock back and resolve under it, so the caller's continuation runs\n // before any other input arrives.\n await this.#runImpl(() => {\n resolve(value);\n }, criticalSection.succeeded());\n } catch (exception) {\n // Annotate as broken for periodic metrics. If we already set up a brokenness reason,\n // we shouldn't override it.\n annotateInputGateBroken(exception);\n\n // Note that on failure, no further InputLocks will be obtainable and the actor will\n // shut down, so don't worry about holding a lock until we get back to application\n // code -- we won't! In fact, we don't even bother calling resolver.reject() because\n // it's meaningless at this point.\n criticalSection.failed(exception);\n\n throw exception;\n } finally {\n // ← `~CriticalSection`. A no-op after `succeeded()`; on the failure path it is what\n // hands the parent lock back, since `failed()` does not.\n criticalSection.drop();\n }\n })(),\n );\n\n // ← the destruction of `auto lock` at the end of the upstream scope. Everything above is\n // synchronous, so the end of the setup is the end of the scope.\n lock.release();\n\n return result;\n }\n\n // -----------------------------------------------------------------\n\n /**\n * ← `runImpl()` + `runInContextScope()`: check the lock belongs to this actor, make it the\n * current one, run, and let `KJ_DEFER` clear it.\n *\n * The defer fires after the microtask checkpoint, not when `func` returns — see\n * `atCheckpointEnd`. Everything else about the scope is isolate machinery with no port.\n */\n async #runImpl<T>(func: (lock: Lock) => T | PromiseLike<T>, lock: Lock): Promise<T> {\n if (!lock.isFor(this.#actor.getInputGate())) {\n throw new Error(\"IoContext::runImpl() was given a lock belonging to another actor\");\n }\n\n this.#currentInputLocks.push(lock);\n let result: T | PromiseLike<T>;\n // ← `SuppressIoContextScope previousRequest; threadLocalRequest = this;` (`io-context.c++:1208`)\n // and its restoring destructor. Scoped to the synchronous body only — see `currentSlice`.\n const previousSlice = currentSlice;\n enterSlice(this);\n try {\n result = func(lock);\n } finally {\n enterSlice(previousSlice);\n atCheckpointEnd(() => {\n this.#exit(lock);\n });\n }\n return await result;\n }\n\n /**\n * ← `requireCurrent()`. Upstream asks whether this IoContext is the thread's current one;\n * with no thread-local there is only one question left, and it is the one every caller of\n * `requireCurrent()` actually depends on: is a gated slice running?\n */\n #requireCurrent(): Lock {\n const lock = this.#currentInputLocks.at(-1);\n if (lock === undefined) {\n throw new Error(\"no input lock available in this context\");\n }\n return lock;\n }\n\n /** ← the far side of `runInContextScope`'s `KJ_DEFER`. */\n #exit(lock: Lock): void {\n const at = this.#currentInputLocks.lastIndexOf(lock);\n if (at < 0) {\n throw new Error(\"IoContext invocation stack lost a lock it was holding\");\n }\n this.#currentInputLocks.splice(at, 1);\n lock.release();\n }\n\n /**\n * ← `awaitIoImpl()`.\n *\n * The KJ-side rejection is merged into the value so a single continuation handles both, the\n * continuation re-enters through `run(func, ilOrCs)`, and the whole thing rides `addTask()`.\n * When `ilOrCs` is a Lock this is `awaitIoWithInputLock` and the gate never opened; when it\n * is a CriticalSection or nothing this is `awaitIo` and the resumption queues for a fresh\n * lock like any other event.\n */\n #awaitIoImpl<T, R>(\n promise: Promise<T>,\n ilOrCs: Lock | CriticalSection | undefined,\n func: (value: T) => R | PromiseLike<R>,\n ): Promise<R> {\n const { promise: result, resolve, reject } = Promise.withResolvers<R>();\n\n this.addTask(\n promiseForExceptionOrT(promise).then(async (outcome) => {\n try {\n await this.run((): void => {\n if (outcome.ok) {\n // `func` runs under the lock, which is the guarantee that makes it a parameter.\n try {\n resolve(func(outcome.value));\n } catch (exception) {\n reject(exception);\n }\n } else {\n reject(outcome.exception);\n }\n }, ilOrCs);\n } catch (exception) {\n // `run()` refuses to re-enter an aborted context, and both of its throws happen\n // before the lock reaches the invocation stack. Upstream would destroy the whole\n // continuation here, releasing the held lock with it; with no destructors it has to\n // be handed back by name. `result` is deliberately left unsettled, as upstream\n // leaves it: the actor is being torn down and `onAbort()` is what reports that.\n if (ilOrCs instanceof Lock) ilOrCs.release();\n throw exception;\n }\n }),\n );\n\n return result;\n }\n\n /**\n * ← the first `.then()` of `blockConcurrencyWhile`: start the section, run the callback\n * under its first nested lock, and race the deadline.\n */\n async #runCriticalSection<T>(\n criticalSection: CriticalSection,\n callback: (lock: Lock) => T | PromiseLike<T>,\n ): Promise<T> {\n const inputLock = await criticalSection.wait();\n\n return await this.#runImpl((lock) => {\n // Remember that this can throw synchronously, and it's important that we catch such\n // throws and call cs->failed().\n const running = callback(lock);\n\n // Arrange to time out if the critical section runs more than 30 seconds, so that objects\n // won't be hung forever if they have a critical section that deadlocks.\n const deadline = new AbortController();\n const timeout = this.#timer\n .afterDelay(BLOCK_CONCURRENCY_WHILE_TIMEOUT_MS, deadline.signal)\n .then((): never => {\n throw new Error(BLOCK_CONCURRENCY_WHILE_TIMEOUT_MESSAGE);\n });\n\n // ← `exclusiveJoin`. The loser cannot be cancelled — a recorded divergence — but the\n // timer half of it can, which is what the signal is for: a section that finishes must\n // not leave a live 30-second timer behind.\n return Promise.race([Promise.resolve(running), timeout]).finally(() => {\n deadline.abort();\n });\n }, inputLock);\n }\n\n /** ← `IoContext::taskFailed()`, minus the logging half, which has no port. */\n #taskFailed(exception: unknown): void {\n if (this.#waitUntilStatus === undefined) {\n this.#waitUntilStatus = { exception };\n }\n }\n}\n","/**\n * ← workerd `src/workerd/api/actor.{h,c++}`\n *\n * Upstream's own opening comment is the best summary of why this file is named\n * what it is: \"'Actors' are the internal name for Durable Objects, because they\n * implement a sort of actor model. We ended up not calling the product 'Actors'\n * publicly because we found that people who were familiar with actor-model\n * programming were more confused than helped by it.\"\n *\n * Five classes and three outgoing factories. The five are here:\n * `ColoLocalActorNamespace` (`actor.h:25`), `DurableObjectId` (`:42`),\n * `DurableObject` (`:87`), `DurableObjectNamespace` (`:142`) and\n * `DurableObjectClass` (`:367`). The three factories — `GlobalActorOutgoingFactory`\n * (`:293`), `LocalActorOutgoingFactory` (`:331`) and `ReplicaActorOutgoingFactory`\n * (`:352`) — are **not**, and their absence is the whole of this file's seam:\n * every one of them is a bag of addressing data plus a lazily-created actor\n * channel, and `newSingleUseClient` returns a `WorkerInterface`, which is capnp\n * dispatch with no port. `ActorChannelFactory` and `ColoLocalActorChannelFactory`\n * below are the shape they plug into, holding exactly the fields the two\n * reachable factories' constructors capture.\n * `ActorRetryRequestMetadata` stays on that same omitted transport seam:\n * upstream passes it from an outgoing factory to `ActorChannel`, while the\n * host-provided `Fetcher` here already owns retry policy and exposes no metadata.\n *\n * **`ColoLocalActorNamespace` is ported, not treated as a substrate boundary**,\n * and the reason is worth stating because the opposite call is easy to defend\n * badly. It is the pre-SQLite, non-durable actor namespace, and this host cannot\n * host one — there is no storage-less actor kind here, and `createActorContainer`\n * requires a `SqlDatabaseProvider`. But *hosting* is not in this file. What is in\n * this file is the JS-facing half: one argument check and one outgoing-stub\n * request, which has precisely the same substrate needs as\n * `DurableObjectNamespace.get()`, which nobody proposes cutting. The boundary, if\n * there is one, sits in `server/` at the point something has to place an\n * ephemeral actor — so there is nothing here to cut, and cutting it would be the\n * feature subset the package README forbids.\n *\n * It is also not idle, though an earlier revision of this comment gave the wrong\n * reason. It claimed `ctx.exports` surfaces a storage-less actor class as a\n * `LoopbackColoLocalActorNamespace`; upstream's own comment\n * (`api/export-loopback.h:111-115`) says that case is a\n * `LoopbackDurableObjectClass`. `LoopbackColoLocalActorNamespace` is \"for\n * colo-local (ephemeral) actor namespaces\" (`:191`) and is built from a\n * *configured* binding, `Global::LoopbackEphemeralActorNamespace`\n * (`server/workerd-api.c++:666-670`) — reachable through configuration rather\n * than through a bare export. The conclusion stands; the path to it is that one.\n *\n * Two things are absent because there is nothing to resolve them against:\n *\n * - **The numbered-channel arm of every binding.** Each of upstream's\n * `kj::OneOf<uint, IoOwn<...>>` keeps only its object arm. Upstream resolves a\n * binding to a `uint` at configuration time; here a binding is a property of\n * the `env` object the consumer supplies, and there is no channel table for a\n * number to index. The object arm is upstream's own alternative, offered on\n * `DurableObjectNamespace` for the case where one \"is constructed dynamically\n * within an execution context, rather than being a long-lived binding\" — which\n * is every binding here.\n * - **Compatibility flags.** `getEnableVersionApi`, `getReplicaRouting`,\n * `getDurableObjectGetExisting` and `getDurableObjectFetchRequiresSchemeAuthority`\n * are read four times in `actor.c++`. A runtime with no deployed history takes\n * the current behaviour, which is the same judgment `deleteAll()`'s\n * `deleteAllDeletesAlarm` row already records. The one that is not a flag\n * decision is `enableReplicaRouting`, which is `false` because replication is a\n * named substrate boundary in `io/actor-cache.ts`.\n *\n * `serialize`/`deserialize` on `DurableObjectClass` are a boundary of their own:\n * they are built on `jsg::Serializer`, `Frankenvalue`, capnp `rpc::JsValue::External`\n * and channel tokens, none of which has a port. Both throw one named message.\n *\n * Spec: §1.10, §1.11 in docs/decisions.md.\n */\n\nimport type { ActorGetMode, ActorId, ActorIdFactory, ActorRoutingMode, ActorVersion } from \"../io/actor-id\";\nimport type { ActorClassChannel } from \"../io/io-channels\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← the `[1, 2048]` bound in `ColoLocalActorNamespace::get`.\n *\n * Upstream compares `actorId.size()`, which for a `kj::String` is **bytes**, so\n * this is measured in UTF-8 bytes rather than in UTF-16 code units. That costs\n * one `TextEncoder` pass and buys an exact match on a bound a caller can hit.\n */\nexport const MAX_COLO_LOCAL_ACTOR_ID_BYTES = 2048;\n\n/**\n * Upstream never faces this: JSG unwraps a `jsg::Ref<DurableObjectId>` parameter\n * and throws a `TypeError` before the method body runs, so `getInner()` cannot be\n * reached on something that is not one. Here the parameter type is\n * workers-types' structural `DurableObjectId` interface, which any object with a\n * `toString` and an `equals` satisfies — so the unwrap has to be written, and it\n * fails closed rather than guessing at the string form.\n */\nexport const FOREIGN_ACTOR_ID_MESSAGE =\n \"This DurableObjectId was not created by this runtime, so its underlying actor id cannot be \" +\n \"read. Ids must come from newUniqueId(), idFromName() or idFromString() on a \" +\n \"DurableObjectNamespace.\";\n\n/** Substrate boundary: `jsg::Serializer`, `Frankenvalue` and channel tokens have no port. */\nexport const ACTOR_CLASS_SERIALIZATION_UNIMPLEMENTED_MESSAGE =\n \"DurableObjectClass cannot be serialized in this runtime: upstream writes a channel token \" +\n \"through jsg::Serializer and Frankenvalue, and neither the token nor the serializer has an \" +\n \"equivalent here.\";\n\n/**\n * Replication is a named substrate boundary (`io/actor-cache.ts`), so no request\n * this file builds asks for replica routing. Upstream reads\n * `FeatureFlags::get(js).getReplicaRouting()` here.\n */\nconst ENABLE_REPLICA_ROUTING = false;\n\n// =======================================================================================\n// The outgoing seam — the shape the three factories plug into\n\n/**\n * ← what `GlobalActorOutgoingFactory`'s constructor captures (`actor.h:297-303`),\n * one field per constructor parameter minus the channel number.\n */\nexport type GlobalActorRequest = {\n readonly id: ActorId;\n readonly locationHint: string | undefined;\n readonly mode: ActorGetMode;\n readonly enableReplicaRouting: boolean;\n readonly routingMode: ActorRoutingMode;\n readonly version: ActorVersion | undefined;\n};\n\n/**\n * ← `DurableObjectNamespace::ActorChannelFactory` (`actor.h:147-157`) composed\n * with `IoChannelFactory::getGlobalActor`, which is what its one implementation\n * forwards to.\n *\n * The composition is not a shortcut. Upstream's `getGlobalActor` returns an\n * `ActorChannel`, and the only thing done with one is `startRequest(...)` →\n * `WorkerInterface`, which the `Fetcher` then drives. `WorkerInterface` has no\n * port and `Fetcher` construction is `api/http.{h,c++}`'s, which is not ported,\n * so the channel and the stub it produces are one object here — the same collapse\n * `io/worker.ts`'s `FacetManager.getFacet` and `server/actor-container.ts`'s\n * `FacetHandle.stub` already make.\n *\n * Section 7 implements this. The laziness upstream's factory has — \"Lazily\n * initialize actorChannel\" — belongs to the implementation, not to the interface,\n * because upstream's own laziness is per-`newSingleUseClient` and there is no\n * per-request client here to be lazy about.\n */\nexport interface ActorChannelFactory {\n getGlobalActor(request: GlobalActorRequest): Fetcher;\n}\n\n/** ← what `LocalActorOutgoingFactory`'s constructor captures (`actor.h:333-335`). */\nexport type ColoLocalActorRequest = {\n readonly actorId: string;\n};\n\n/**\n * ← `IoChannelFactory::getColoLocalActor`, reached through\n * `LocalActorOutgoingFactory`.\n *\n * Upstream gives `ColoLocalActorNamespace` only the numbered-channel arm, because\n * an ephemeral namespace is always a configured binding there. With no channel\n * table the factory arm is the only one available, so this is the same\n * substitution upstream itself offers `DurableObjectNamespace` — applied to the\n * one constructor that did not already have it.\n */\nexport interface ColoLocalActorChannelFactory {\n getColoLocalActor(request: ColoLocalActorRequest): Fetcher;\n}\n\n// =======================================================================================\n// ColoLocalActorNamespace\n\n/**\n * ← `ColoLocalActorNamespace` (`actor.h:25-37`). \"A capability to an ephemeral\n * Actor namespace.\"\n */\nexport class ColoLocalActorNamespace implements globalThis.ColoLocalActorNamespace {\n readonly #channel: ColoLocalActorChannelFactory;\n\n constructor(channel: ColoLocalActorChannelFactory) {\n this.#channel = channel;\n }\n\n /** ← `ColoLocalActorNamespace::get` (`actor.c++:116-129`). */\n get(actorId: string): Fetcher {\n const bytes = utf8Length(actorId);\n if (!(bytes > 0 && bytes <= MAX_COLO_LOCAL_ACTOR_ID_BYTES)) {\n throw new TypeError(\n `Actor ID length must be in the range [1, ${MAX_COLO_LOCAL_ACTOR_ID_BYTES}].`,\n );\n }\n return this.#channel.getColoLocalActor({ actorId });\n }\n}\n\nconst textEncoder = new TextEncoder();\n\n/** `kj::String::size()` is bytes; `String.prototype.length` is UTF-16 code units. */\nfunction utf8Length(value: string): number {\n return textEncoder.encode(value).length;\n}\n\n// =======================================================================================\n// DurableObjectId\n\n/**\n * ← `DurableObjectId` (`actor.h:42-84`). \"DurableObjectId type seen by\n * JavaScript.\"\n *\n * `name` and `jurisdiction` are read from the inner id **once, at construction**,\n * where upstream's are `JSG_READONLY_INSTANCE_PROPERTY`s that re-read it on every\n * access. That is not a preference: `@cloudflare/workers-types` declares both\n * `readonly name?: string`, and under `exactOptionalPropertyTypes` a getter\n * returning `string | undefined` does not satisfy an optional `string`. An own\n * property assigned only when the value exists does, and it is what keeps this\n * class assignable to the interface with no cast (§2.4). The one behaviour lost\n * is `ActorIdImpl::clearName()` (`server/actor-id-impl.h`) taking effect on an\n * already-wrapped id — a `server/`-internal that runs before the id reaches JS.\n */\nexport class DurableObjectId implements globalThis.DurableObjectId {\n readonly #id: ActorId;\n readonly name?: string;\n readonly jurisdiction?: string;\n\n constructor(id: ActorId) {\n this.#id = id;\n const name = id.getName();\n if (name !== undefined) this.name = name;\n const jurisdiction = id.getJurisdiction();\n if (jurisdiction !== undefined) this.jurisdiction = jurisdiction;\n }\n\n /** ← `getInner()`. Not JS-visible upstream either; the outgoing factories take it. */\n getInner(): ActorId {\n return this.#id;\n }\n\n /** \"Converts to a string which can be passed back to the constructor to reproduce the same ID.\" */\n toString(): string {\n return this.#id.toString();\n }\n\n equals(other: globalThis.DurableObjectId): boolean {\n return this.#id.equals(innerIdOf(other));\n }\n}\n\n/** The unwrap JSG performs for a `jsg::Ref<DurableObjectId>` parameter. */\nfunction requireDurableObjectId(id: globalThis.DurableObjectId): DurableObjectId {\n if (id instanceof DurableObjectId) return id;\n throw new TypeError(FOREIGN_ACTOR_ID_MESSAGE);\n}\n\nfunction innerIdOf(id: globalThis.DurableObjectId): ActorId {\n return requireDurableObjectId(id).getInner();\n}\n\n// =======================================================================================\n// The DurableObject stub\n\n/**\n * ← `DurableObject` (`actor.h:87-139`). \"Stub object used to send messages to a\n * remote durable object.\"\n *\n * Upstream's carries its whole behaviour by `JSG_INHERIT(Fetcher)` and adds\n * exactly two readonly properties. So does this: the `Fetcher` is the transport's\n * and everything except `id` and `name` belongs to it. `asDurableObjectStub`\n * below is where the inheritance goes.\n */\nexport class DurableObject {\n readonly #id: DurableObjectId;\n readonly #fetcher: Fetcher;\n\n constructor(id: DurableObjectId, fetcher: Fetcher) {\n this.#id = id;\n this.#fetcher = fetcher;\n }\n\n /** ← `JSG_READONLY_INSTANCE_PROPERTY(id, getId)`. */\n getId(): DurableObjectId {\n return this.#id;\n }\n\n /** ← `JSG_READONLY_INSTANCE_PROPERTY(name, getName)`. */\n getName(): string | undefined {\n return this.#id.name;\n }\n\n /** The `Fetcher` upstream inherits from rather than holds. */\n getFetcher(): Fetcher {\n return this.#fetcher;\n }\n}\n\n/**\n * ← `js.alloc<DurableObject>(...)` plus `JSG_INHERIT(Fetcher)` plus the\n * `JSG_TS_OVERRIDE` that renames the resource type to `DurableObjectStub`.\n *\n * The named assertion is the same one `io/worker.ts`'s `asFacetStub` makes and\n * for the same reason: `DurableObjectStub<T>` is `Fetcher<T, …> & { id, name }`,\n * and `Fetcher<T>` for an unresolved `T` is `Rpc.Provider<T, …>`, a conditional\n * type TypeScript defers until `T` is known — where `T` is the caller's claim\n * about a class it named, which no value can confirm. Upstream is in the same\n * position and answers it the same way, with the parameter living only inside a\n * `JSG_TS_OVERRIDE`.\n *\n * The `Proxy` is what JSG inheritance costs in JS. Two properties have to answer\n * from the id and every other property — `fetch`, `connect`, and every RPC method\n * name, which are the whole point of a stub — has to reach the transport with\n * `this` still bound to it. Bound methods are memoised so `stub.foo === stub.foo`,\n * which upstream gets for free by there being one object rather than two.\n */\nexport function asDurableObjectStub<T extends Rpc.DurableObjectBranded | undefined>(\n object: DurableObject,\n): DurableObjectStub<T> {\n const fetcher = object.getFetcher();\n const bound = new Map<string | symbol, unknown>();\n\n const stub = new Proxy(fetcher, {\n get(target, property): unknown {\n if (property === \"id\") return object.getId();\n if (property === \"name\") return object.getName();\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const value: unknown = Reflect.get(target, property, target);\n if (typeof value !== \"function\") return value;\n const method: unknown = value.bind(target);\n bound.set(property, method);\n return method;\n },\n\n has(target, property): boolean {\n if (property === \"id\" || property === \"name\") return true;\n return Reflect.has(target, property);\n },\n\n ownKeys(target): ArrayLike<string | symbol> {\n const keys = Reflect.ownKeys(target).filter((key) => key !== \"id\" && key !== \"name\");\n return [\"id\", \"name\", ...keys];\n },\n\n getOwnPropertyDescriptor(target, property): PropertyDescriptor | undefined {\n if (property === \"id\" || property === \"name\") {\n return {\n value: property === \"id\" ? object.getId() : object.getName(),\n writable: false,\n enumerable: true,\n // Configurable, because the target does not have these keys and a Proxy may not\n // report a non-configurable descriptor for a property its target lacks.\n configurable: true,\n };\n }\n return Reflect.getOwnPropertyDescriptor(target, property);\n },\n });\n\n return stub as DurableObjectStub<T>;\n}\n\n// =======================================================================================\n// DurableObjectNamespace\n\n/** ← `DurableObjectNamespace::NewUniqueIdOptions` (`actor.h:166-177`). */\nexport type NewUniqueIdOptions = {\n /** \"Restricts the new unique ID to a set of colos within a jurisdiction.\" */\n readonly jurisdiction?: string | null;\n};\n\n/** ← `DurableObjectNamespace::GetDurableObjectOptions` (`actor.h:193-234`). */\nexport type GetDurableObjectOptions = {\n readonly locationHint?: string;\n /**\n * \"`routingMode` may be be of interest to applications using Durable Objects\n * replicas. It can be one of the following options: none: the default,\n * indicates we will pick for the application. 'primary-only': guarantees we\n * route directly to the primary (skip any replicas).\"\n */\n readonly routingMode?: string;\n readonly version?: { readonly cohort?: string };\n};\n\n/**\n * ← `DurableObjectNamespace` (`actor.h:142-291`). \"Global durable object class\n * binding type.\"\n */\nexport class DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined>\n implements globalThis.DurableObjectNamespace<T>\n{\n readonly #channel: ActorChannelFactory;\n readonly #idFactory: ActorIdFactory;\n\n constructor(channel: ActorChannelFactory, idFactory: ActorIdFactory) {\n this.#channel = channel;\n this.#idFactory = idFactory;\n }\n\n /**\n * \"Create a new unique ID for a durable object that will be allocated nearby\n * the calling colo.\"\n */\n newUniqueId(options?: NewUniqueIdOptions): DurableObjectId {\n return new DurableObjectId(this.#idFactory.newUniqueId(options?.jurisdiction ?? undefined));\n }\n\n /**\n * \"Create a name-derived ID. Passing in the same `name` (to the same class)\n * will always produce the same ID.\"\n */\n idFromName(name: string): DurableObjectId {\n return new DurableObjectId(this.#idFactory.idFromName(name));\n }\n\n /**\n * \"Create a DurableObjectId from the stringified form of the ID (as produced by\n * calling `toString()` on a durable object ID). Throws if the ID is not a\n * 64-digit hex number, or if the ID was not originally created for this class.\"\n */\n idFromString(id: string): DurableObjectId {\n return new DurableObjectId(this.#idFactory.idFromString(id));\n }\n\n /** \"Gets a durable object by ID or creates it if it doesn't already exist.\" */\n get(id: globalThis.DurableObjectId, options?: GetDurableObjectOptions): DurableObjectStub<T> {\n return this.#getImpl(\"GET_OR_CREATE\", id, options);\n }\n\n /**\n * \"Gets a durable object by name or creates it if it doesn't already exist.\n * Short for `idFromName()` followed by `get()`.\"\n */\n getByName(name: string, options?: GetDurableObjectOptions): DurableObjectStub<T> {\n return this.#getImpl(\"GET_OR_CREATE\", this.idFromName(name), options);\n }\n\n /**\n * \"Experimental. Gets a durable object by ID if it already exists. Currently,\n * gated for use by cloudflare only.\"\n *\n * Upstream exposes it only when the `durableObjectGetExisting` compat flag is\n * on, and `@cloudflare/workers-types` 4.20260702.1 does not declare it. It is\n * exposed unconditionally here, which is the current-behaviour reading every\n * other compat flag in this file gets.\n */\n getExisting(\n id: globalThis.DurableObjectId,\n options?: GetDurableObjectOptions,\n ): DurableObjectStub<T> {\n return this.#getImpl(\"GET_EXISTING\", id, options);\n }\n\n /**\n * \"Creates a subnamespace with the jurisdiction hardcoded.\"\n *\n * The argument is optional because upstream's is a\n * `jsg::Optional<kj::Maybe<kj::String>>`, so both \"omitted\" and \"null\" mean the\n * same thing — `cloneWithJurisdiction(kj::none)`, a subnamespace with none.\n */\n jurisdiction(jurisdiction?: string | null): DurableObjectNamespace<T> {\n return new DurableObjectNamespace<T>(\n this.#channel,\n this.#idFactory.cloneWithJurisdiction(jurisdiction ?? undefined),\n );\n }\n\n /** ← `DurableObjectNamespace::getImpl` (`actor.c++:167-213`). */\n #getImpl(\n mode: ActorGetMode,\n id: globalThis.DurableObjectId,\n options: GetDurableObjectOptions | undefined,\n ): DurableObjectStub<T> {\n const durableObjectId = requireDurableObjectId(id);\n const inner = durableObjectId.getInner();\n if (!this.#idFactory.matchesJurisdiction(inner)) {\n throw new TypeError(\n \"get called on jurisdictional subnamespace with an ID from a different jurisdiction\",\n );\n }\n\n let routingMode: ActorRoutingMode = \"DEFAULT\";\n const requestedRoutingMode = options?.routingMode;\n if (requestedRoutingMode !== undefined) {\n if (requestedRoutingMode !== \"primary-only\") {\n throw new RangeError(`unknown routingMode: ${requestedRoutingMode}`);\n }\n routingMode = \"PRIMARY_ONLY\";\n }\n\n const fetcher = this.#channel.getGlobalActor({\n id: inner,\n locationHint: options?.locationHint,\n mode,\n enableReplicaRouting: ENABLE_REPLICA_ROUTING,\n routingMode,\n version: actorVersionOf(options?.version),\n });\n\n // The id handed to the stub is the one the caller passed, as upstream's `id.addRef()` is.\n return asDurableObjectStub<T>(new DurableObject(durableObjectId, fetcher));\n }\n}\n\n/**\n * ← `version = ActorVersion{.cohort = kj::mv(v.cohort)}` (`actor.c++:186-190`),\n * behind `FeatureFlags::get(js).getEnableVersionApi()` which this file reads as\n * on. A version with no cohort is still a version, which is why the empty object\n * is not collapsed to `undefined`.\n */\nfunction actorVersionOf(version: { readonly cohort?: string } | undefined): ActorVersion | undefined {\n if (version === undefined) return undefined;\n return version.cohort === undefined ? {} : { cohort: version.cohort };\n}\n\n// =======================================================================================\n// DurableObjectClass\n\n/**\n * ← `DurableObjectClass` (`actor.h:367-393`). \"DurableObjectClass represents a\n * binding to a Durable Object class that can be used as a facet. The only use of\n * this type is to pass to `ctx.facets.get()`.\"\n *\n * `getChannel()` takes no `IoContext` because the parameter existed to resolve the\n * numbered-channel arm, and there is no numbered-channel arm here.\n */\nexport class DurableObjectClass<_T extends Rpc.DurableObjectBranded | undefined = undefined>\n implements globalThis.DurableObjectClass<_T>\n{\n readonly #channel: ActorClassChannel;\n\n constructor(channel: ActorClassChannel) {\n this.#channel = channel;\n }\n\n /** ← `DurableObjectClass::getChannel` (`actor.c++:232-242`). */\n getChannel(): ActorClassChannel {\n return this.#channel;\n }\n\n /**\n * ← `DurableObjectClass::serialize` (`actor.c++:244-306`). Substrate boundary.\n *\n * `requireAllowsTransfer()` runs first, exactly as upstream's does, so a class\n * that refuses transfer reports that rather than the boundary — the refusal is\n * the more specific answer and it is the one upstream would give too.\n */\n serialize(): never {\n this.#channel.requireAllowsTransfer();\n throw new Error(ACTOR_CLASS_SERIALIZATION_UNIMPLEMENTED_MESSAGE);\n }\n\n /** ← `DurableObjectClass::deserialize` (`actor.c++:308-359`). Substrate boundary. */\n static deserialize(): never {\n throw new Error(ACTOR_CLASS_SERIALIZATION_UNIMPLEMENTED_MESSAGE);\n }\n}\n","/**\n * ← workerd `src/workerd/api/export-loopback.{h,c++}`\n *\n * The four types `ctx.exports` is made of. Upstream's own comment on the first\n * says what they all are: \"the type of a property of `ctx.exports` which points\n * back at a … entrypoint of this Worker\", specialized by *invoking* it.\n *\n * - `LoopbackServiceStub` (`export-loopback.h:18`) — a stateless entrypoint. A\n * `Fetcher` with empty props, callable to get one with props.\n * - `LoopbackDurableObjectClass` (`:116`) — an actor class with **no storage\n * configured**. A `DurableObjectClass`, callable to get a specialized one.\n * - `LoopbackDurableObjectNamespace` (`:155`) — an actor class **with** storage:\n * \"we want a binding that behaves *both* like a LoopbackDurableObjectClass\n * *and* like a DurableObjectNamespace binding.\"\n * - `LoopbackColoLocalActorNamespace` (`:192`) — the same, for a colo-local\n * (ephemeral) namespace binding.\n *\n * The third is why this file blocks `server/`. The vendored consumer reads\n * `ctx.exports[className]` and needs one value to answer both `idFromName`\n * (`vendor/agents/packages/agents/src/index.ts:10829`, `:10855`) and\n * `ctx.facets.get`'s class check (`:10857`) — namespace-shaped and class-shaped\n * at once, which is exactly what `LoopbackDurableObjectNamespace` is for.\n * Upstream's own `api/tests/worker-loader-test.js:449-450` pins the same pair.\n *\n * **`JSG_CALLABLE` becomes a `Proxy` with an `apply` trap.** A JS value can only\n * be invoked if it is a function, and a class instance is not one; the private\n * fields these classes inherit mean the callable cannot simply be a function\n * whose prototype is the instance, because an inherited method would then run\n * with `this` set to the function. So each class keeps its behaviour and an\n * `asLoopback…` function produces the JS-visible value — the same split, for the\n * same reason, that `asDurableObjectStub` already makes for `JSG_INHERIT`.\n * `getPrototypeOf` is what keeps `instanceof` answering, which is how\n * `DurableObjectFacets.get` discriminates the three arms of its class switch.\n *\n * **Two `IoChannelFactory` methods are declared here rather than in\n * `io/io-channels.ts`.** `getSubrequestChannel` and `getActorClass` are what\n * `export-loopback.c++` reaches for, and both take a channel *number* upstream —\n * which this package does not have (`io/io-channels.ts`'s header: there is no\n * numbered channel table). So each collapses into a factory taking an object\n * request, exactly as `api/actor.ts` already does for `IoChannelFactory`'s\n * `getGlobalActor` and `getColoLocalActor`, and each is declared beside its one\n * consumer for the same reason `ActorChannelFactory` is. Section 7 fills them.\n *\n * **Non-serializability survives, and Section 7b is where it is enforced.**\n * Upstream is explicit that `LoopbackServiceStub` is \"intentionally NOT\n * serializable, unlike its parent class Fetcher\", and\n * `api/tests/worker-loader-test.js:104` asserts the message;\n * `LoopbackDurableObjectClass` likewise declares no `JSG_SERIALIZABLE` where\n * `DurableObjectClass` (`actor.h:389`) does, and neither namespace type declares\n * one either — `JSG_INHERIT` does not carry serializability, which is what the\n * test's own comment says it is checking.\n *\n * An earlier revision of this paragraph said the refusal did not survive, and\n * named `src/transport/` as the layer that would have to make it. Both halves\n * were wrong about *where*: the test reaches the refusal through\n * `worker.getEntrypoint(name, {props})`, and `WorkerStub::getEntrypoint`'s first\n * act is `Frankenvalue::fromJs`, which runs `jsg::Serializer` inside\n * `api/worker-loader.c++`. So `api/worker-loader.ts`'s `requireSerializableProps`\n * refuses all four of these in `props` and in `env`, with upstream's message and\n * a `DataCloneError`. `DurableObjectClass.serialize` remains a separate named\n * substrate boundary that throws for every class, loopback or not.\n *\n * The version half of `LoopbackServiceStub` is present and `Options`, the\n * flag-off form, is not: `FeatureFlags::getEnableVersionApi()` is read as on\n * here, the same current-behaviour reading `api/actor.ts` gives the four\n * compatibility flags it meets. That makes this a superset of\n * `@cloudflare/workers-types` 4.20260702.1, which generated the flag-off\n * signature — the same relationship `DurableObjectNamespace.getExisting` has.\n *\n * Spec: §1.10, §1.11, decisions 14 and 16 in\n * docs/decisions.md.\n */\n\nimport type { ActorIdFactory } from \"../io/actor-id\";\nimport type { ActorClassChannel } from \"../io/io-channels\";\nimport {\n ColoLocalActorNamespace,\n DurableObjectClass,\n DurableObjectNamespace,\n type ActorChannelFactory,\n type ColoLocalActorChannelFactory,\n} from \"./actor\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← what JSG's struct unwrapper does with a value that is not an object\n * (`jsg/struct.h:246`). Undefined and null are **not** in that set: a struct\n * whose every field is optional — which both option structs here are — unwraps\n * from either as an empty struct (`jsg/struct.h:236-243`), so `ctx.exports.Foo()`\n * is upstream's own empty-options call and not an error.\n */\nexport const LOOPBACK_OPTIONS_NOT_AN_OBJECT_MESSAGE =\n \"A ctx.exports binding is invoked with an options object: pass { props }, or nothing at all.\";\n\n/** ← what JSG does unwrapping a `jsg::JsRef<jsg::JsObject>` from a non-object. */\nexport const LOOPBACK_PROPS_NOT_AN_OBJECT_MESSAGE =\n \"`props` must be an object. Upstream unwraps it as a jsg::JsObject, which refuses anything else.\";\n\n// =======================================================================================\n// The outgoing seam — the two IoChannelFactory methods this file reaches\n\n/** ← `IoChannelFactory::VersionRequest` (`io/io-channels.h:123-131`). */\nexport type VersionRequest = {\n /** \"Request a version within the given cohort.\" */\n readonly cohort: string | undefined;\n};\n\n/**\n * ← the two arguments `IoChannelFactory::getSubrequestChannel` takes besides the\n * channel number (`io/io-channels.h:243-245`). Upstream: \"`props` and\n * `versionRequest` can only be specified if this is a loopback channel (i.e.\n * from ctx.exports).\"\n */\nexport type SubrequestChannelRequest = {\n /** ← `kj::Maybe<Frankenvalue> props`. */\n readonly props: unknown;\n readonly version: VersionRequest | undefined;\n};\n\n/**\n * ← `IoChannelFactory::getSubrequestChannel` composed with the `Fetcher` upstream\n * builds over the `SubrequestChannel` it returns.\n *\n * The composition is `api/actor.ts`'s: a `SubrequestChannel` is only ever driven\n * through `startRequest()` → `WorkerInterface`, which has no port, while the\n * JS-visible product is a `Fetcher` — so the channel and the stub it produces are\n * one object here.\n */\nexport interface SubrequestChannelFactory {\n getSubrequestChannel(request: SubrequestChannelRequest): Fetcher;\n}\n\n/** ← the `props` argument of `IoChannelFactory::getActorClass` (`io/io-channels.h:315`). */\nexport type ActorClassRequest = {\n readonly props: unknown;\n};\n\n/** ← `IoChannelFactory::getActorClass`, which returns the token `io/io-channels.ts` ports. */\nexport interface ActorClassChannelFactory {\n getActorClass(request: ActorClassRequest): ActorClassChannel;\n}\n\n// =======================================================================================\n// The option structs\n\n/** ← `LoopbackServiceStub::OptionsWithVersion::Version` (`export-loopback.h:32-36`). */\nexport type LoopbackServiceStubVersion = {\n /** `jsg::Optional<kj::Maybe<kj::String>>`: omitted and null are the same request. */\n readonly cohort?: string | null;\n};\n\n/** ← `LoopbackServiceStub::OptionsWithVersion` (`export-loopback.h:31-42`). */\nexport type LoopbackServiceStubOptions = {\n readonly props?: unknown;\n readonly version?: LoopbackServiceStubVersion;\n};\n\n/** ← `LoopbackDurableObjectClass::Options` (`export-loopback.h:120-124`). */\nexport type LoopbackDurableObjectClassOptions = {\n readonly props?: unknown;\n};\n\n// =======================================================================================\n// LoopbackServiceStub\n\n/**\n * ← `LoopbackServiceStub` (`export-loopback.h:18-109`).\n *\n * Upstream is a `Fetcher` on the loopback channel and holds the channel number a\n * second time so `callImpl` can re-specialize it. Here the `Fetcher` is the\n * transport's — `api/http.{h,c++}` is not ported — so the unspecialized stub is\n * what the factory returns for a request with no props and no version, and the\n * factory is the thing held twice over.\n */\nexport class LoopbackServiceStub {\n readonly #channel: SubrequestChannelFactory;\n readonly #fetcher: Fetcher;\n\n constructor(channel: SubrequestChannelFactory) {\n this.#channel = channel;\n this.#fetcher = channel.getSubrequestChannel({ props: undefined, version: undefined });\n }\n\n /** The `Fetcher` upstream inherits from rather than holds, as `DurableObject`'s is. */\n getFetcher(): Fetcher {\n return this.#fetcher;\n }\n\n /**\n * ← `LoopbackServiceStub::callImpl` (`export-loopback.c++:11-29`) reached\n * through `callWithVersion` (`export-loopback.h:53-55`), which is the callable\n * when `enableVersionApi` is on. \"Create a specialized Fetcher which can be\n * passed over RPC.\"\n */\n callWithVersion(options: LoopbackServiceStubOptions): Fetcher {\n return this.#channel.getSubrequestChannel({\n props: requireProps(options.props),\n version: versionRequestOf(options.version),\n });\n }\n}\n\n/**\n * ← `js.alloc<LoopbackServiceStub>(…)` plus `JSG_CALLABLE(callWithVersion)`.\n *\n * The declared type is a superset of `@cloudflare/workers-types`' by exactly the\n * `version` field, for the reason in this module's header.\n */\nexport type LoopbackServiceStubValue<\n T extends Rpc.WorkerEntrypointBranded | undefined = undefined,\n> = Fetcher<T> & ((options?: LoopbackServiceStubOptions) => Fetcher<T>);\n\nexport function asLoopbackServiceStub<\n T extends Rpc.WorkerEntrypointBranded | undefined = undefined,\n>(stub: LoopbackServiceStub): LoopbackServiceStubValue<T> {\n return asCallable({\n properties: stub.getFetcher(),\n prototype: LoopbackServiceStub.prototype,\n call: (options) => stub.callWithVersion(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// LoopbackDurableObjectClass\n\n/**\n * ← `LoopbackDurableObjectClass` (`export-loopback.h:116-148`). \"Similar to\n * LoopbackServiceStub, but for actor classes … this is used for actor classes\n * that do *not* have any storage configured. If you simply export a class\n * extending `DurableObject` but you don't configure storage for it, it shows up\n * in `ctx.exports` as this type. This can be used to create a Durable Object\n * facet.\"\n *\n * Upstream's base `DurableObjectClass` holds the channel *number*, and\n * `getChannel(ioctx)` resolves it lazily. There is no numbered arm here, so the\n * unspecialized channel is requested once, in the constructor — which is the same\n * value `getActorClass(channel)` with default props would have produced.\n */\nexport class LoopbackDurableObjectClass<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> extends DurableObjectClass<T> {\n readonly #channel: ActorClassChannelFactory;\n\n constructor(channel: ActorClassChannelFactory) {\n super(channel.getActorClass({ props: undefined }));\n this.#channel = channel;\n }\n\n /**\n * ← `LoopbackDurableObjectClass::call` (`export-loopback.c++:31-40`). \"Create a\n * specialized DurableObjectClass which can be passed over RPC.\"\n *\n * The result is a plain `DurableObjectClass`, as `js.alloc<DurableObjectClass>`\n * is: specializing a loopback class does not produce another loopback class.\n */\n call(options: LoopbackDurableObjectClassOptions): DurableObjectClass<T> {\n return new DurableObjectClass<T>(\n this.#channel.getActorClass({ props: requireProps(options.props) }),\n );\n }\n}\n\n/** ← `js.alloc<LoopbackDurableObjectClass>(…)` plus `JSG_CALLABLE(call)`. */\nexport type LoopbackDurableObjectClassValue<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> = DurableObjectClass<T> &\n ((options?: LoopbackDurableObjectClassOptions) => DurableObjectClass<T>);\n\nexport function asLoopbackDurableObjectClass<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n>(actorClass: LoopbackDurableObjectClass<T>): LoopbackDurableObjectClassValue<T> {\n return asCallable({\n properties: actorClass,\n prototype: Object.getPrototypeOf(actorClass),\n call: (options) => actorClass.call(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// LoopbackDurableObjectNamespace\n\n/**\n * ← `LoopbackDurableObjectNamespace` (`export-loopback.h:155-189`).\n *\n * Upstream: \"used when the class has storage configured. In this case, we want a\n * binding that behaves *both* like a LoopbackDurableObjectClass *and* like a\n * DurableObjectNamespace binding. Easy enough, we'll inherit\n * DurableObjectNamespace, but also make the binding invokable as a function like\n * LoopbackDurableObjectClass.\"\n */\nexport class LoopbackDurableObjectNamespace<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> extends DurableObjectNamespace<T> {\n readonly #loopbackClass: LoopbackDurableObjectClass<T>;\n\n constructor(\n channel: ActorChannelFactory,\n idFactory: ActorIdFactory,\n loopbackClass: LoopbackDurableObjectClass<T>,\n ) {\n super(channel, idFactory);\n this.#loopbackClass = loopbackClass;\n }\n\n /** ← `getClass()`. \"getClass() accessor for use from C++ only.\" */\n getClass(): LoopbackDurableObjectClass<T> {\n return this.#loopbackClass;\n }\n\n /** ← `call`. \"Invoking the binding creates a specialization of the class -- not the namespace.\" */\n call(options: LoopbackDurableObjectClassOptions): DurableObjectClass<T> {\n return this.#loopbackClass.call(options);\n }\n}\n\n/**\n * ← `js.alloc<LoopbackDurableObjectNamespace>(…)` plus `JSG_CALLABLE(call)`.\n *\n * This is the type of a `ctx.exports` entry for a Durable Object class with\n * storage, and the reason it is stated in terms of this package's classes rather\n * than `@cloudflare/workers-types`' `LoopbackDurableObjectNamespace` is that the\n * pinned interface is `interface LoopbackDurableObjectNamespace extends\n * DurableObjectNamespace {}` — no call signature, because that resource type\n * carries no `JSG_TS_OVERRIDE` to generate one from. `Cloudflare.Exports`\n * describes the same value correctly, as `LoopbackDurableObjectClass<T> &\n * DurableObjectNamespace<T>`, and `PinnedLoopbackTypes` below checks against\n * that rather than against the interface.\n *\n * `call` is omitted because `JSG_CALLABLE` registers it as the object's call\n * behaviour rather than as a property: on the value, `.call` is\n * `Function.prototype.call`, which is what `asCallable`'s `get` trap answers.\n */\nexport type LoopbackDurableObjectNamespaceValue<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> = Omit<LoopbackDurableObjectNamespace<T>, \"call\"> &\n ((options?: LoopbackDurableObjectClassOptions) => DurableObjectClass<T>);\n\nexport function asLoopbackDurableObjectNamespace<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n>(namespace: LoopbackDurableObjectNamespace<T>): LoopbackDurableObjectNamespaceValue<T> {\n return asCallable({\n properties: namespace,\n prototype: Object.getPrototypeOf(namespace),\n call: (options) => namespace.call(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// LoopbackColoLocalActorNamespace\n\n/**\n * ← `LoopbackColoLocalActorNamespace` (`export-loopback.h:192-220`). \"Like\n * LoopbackDurableObjectNamespace, but for colo-local (ephemeral) actor\n * namespaces.\"\n */\nexport class LoopbackColoLocalActorNamespace extends ColoLocalActorNamespace {\n readonly #loopbackClass: LoopbackDurableObjectClass;\n\n constructor(channel: ColoLocalActorChannelFactory, loopbackClass: LoopbackDurableObjectClass) {\n super(channel);\n this.#loopbackClass = loopbackClass;\n }\n\n /** ← `getClass()`. \"getClass() accessor for use from C++ only.\" */\n getClass(): LoopbackDurableObjectClass {\n return this.#loopbackClass;\n }\n\n /** ← `call`. \"Invoking the binding creates a specialization of the class -- not the namespace.\" */\n call(options: LoopbackDurableObjectClassOptions): DurableObjectClass {\n return this.#loopbackClass.call(options);\n }\n}\n\n/**\n * ← `js.alloc<LoopbackColoLocalActorNamespace>(…)` plus `JSG_CALLABLE(call)`,\n * with `call` omitted for the reason given on the durable namespace above.\n */\nexport type LoopbackColoLocalActorNamespaceValue = Omit<LoopbackColoLocalActorNamespace, \"call\"> &\n ((options?: LoopbackDurableObjectClassOptions) => DurableObjectClass);\n\nexport function asLoopbackColoLocalActorNamespace(\n namespace: LoopbackColoLocalActorNamespace,\n): LoopbackColoLocalActorNamespaceValue {\n return asCallable({\n properties: namespace,\n prototype: Object.getPrototypeOf(namespace),\n call: (options) => namespace.call(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// The pinned-types check\n\n/** `Value` must be assignable to `Declared`; declaring the constraint is the check. */\ntype Assignable<Value extends Declared, Declared> = Value;\n\n/**\n * Checked rather than claimed: every value this module produces satisfies the\n * shape `@cloudflare/workers-types` 4.20260702.1 declares for it. The last two\n * are checked against `Cloudflare.Exports`' own description of a `ctx.exports`\n * entry — `LoopbackForExport<T>` intersected with the namespace — because the\n * two named interfaces there are call-signature-less, per the note above.\n */\nexport type PinnedLoopbackTypes = [\n Assignable<LoopbackServiceStubValue, globalThis.LoopbackServiceStub>,\n Assignable<LoopbackDurableObjectClassValue, globalThis.LoopbackDurableObjectClass>,\n Assignable<\n LoopbackDurableObjectNamespaceValue,\n globalThis.LoopbackDurableObjectClass & globalThis.DurableObjectNamespace\n >,\n Assignable<\n LoopbackColoLocalActorNamespaceValue,\n globalThis.LoopbackDurableObjectClass & globalThis.ColoLocalActorNamespace\n >,\n];\n\n// =======================================================================================\n// The mechanics JSG supplies\n\n/**\n * ← `JSG_CALLABLE`, which makes a JSG resource object invocable while leaving\n * every other property answering from the resource type.\n *\n * `properties` is where reads land, with `this` bound to it so a method reaching\n * a private field still finds one — the same binding, memoised the same way,\n * that `asDurableObjectStub` performs for `JSG_INHERIT`. `prototype` is what\n * `instanceof` sees, and it is separate from `properties` because\n * `LoopbackServiceStub` is one object with two halves: upstream's identity is the\n * resource type while its behaviour is the inherited `Fetcher`'s.\n *\n * The target is an arrow function rather than a plain one because a plain\n * function has a non-configurable own `prototype` property, which a Proxy may not\n * hide from `ownKeys`.\n *\n * This is the one assertion the four producers above need, made once here. It is\n * `asDurableObjectStub`'s, for `asDurableObjectStub`'s reason: the declared value\n * is a `Fetcher<T>` or a `DurableObjectClass<T>` intersected with a call\n * signature, and `T` is the caller's claim about a class it named, which no value\n * can confirm. Upstream states the same shapes the same way, in a\n * `JSG_TS_OVERRIDE` that no C++ value is checked against either.\n */\nconst INVOCATION_METHODS = new Set<string | symbol>([\"call\", \"apply\", \"bind\"]);\n\nfunction asCallable<Value>(facade: {\n readonly properties: object;\n readonly prototype: object | null;\n readonly call: (options: unknown) => unknown;\n}): Value {\n const bound = new Map<string | symbol, unknown>();\n const target = (): never => {\n throw new Error(\"unreachable: the apply trap answers every invocation\");\n };\n\n return new Proxy(target, {\n apply(_target, _thisArg, args: readonly unknown[]): unknown {\n return facade.call(args[0]);\n },\n\n get(target, property, receiver): unknown {\n // `call`, `apply` and `bind` belong to the callable rather than to the property source.\n // Upstream's object is a function and answers all three from `Function.prototype`, and\n // `call` is also the C++ method name `JSG_CALLABLE` registers — which is the object's call\n // behaviour there and not a JS property, so it must not become one here. Answering from\n // the target keeps `foo.call(thisArg, options)` meaning `foo(options)`, as it does upstream.\n if (INVOCATION_METHODS.has(property)) return Reflect.get(target, property, receiver);\n\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const value: unknown = Reflect.get(facade.properties, property, facade.properties);\n if (typeof value !== \"function\") return value;\n const method: unknown = value.bind(facade.properties);\n bound.set(property, method);\n return method;\n },\n\n has(_target, property): boolean {\n return Reflect.has(facade.properties, property);\n },\n\n ownKeys(): ArrayLike<string | symbol> {\n return Reflect.ownKeys(facade.properties);\n },\n\n getOwnPropertyDescriptor(_target, property): PropertyDescriptor | undefined {\n const descriptor = Reflect.getOwnPropertyDescriptor(facade.properties, property);\n if (descriptor === undefined) return undefined;\n // Configurable, because the target does not have this key and a Proxy may not report a\n // non-configurable descriptor for a property its target lacks.\n return { ...descriptor, configurable: true };\n },\n\n getPrototypeOf(): object | null {\n return facade.prototype;\n },\n }) as Value;\n}\n\n/**\n * ← JSG's struct unwrapper (`jsg/struct.h:236-246`), for the two option structs\n * here: every field of both is optional, so undefined and null yield an empty\n * struct and anything that is not an object is a `TypeError`. V8's `IsObject()`\n * is true for functions, which is why one is not refused here either.\n *\n * `cohort` is not checked, because upstream does not check it: JSG's `kj::String`\n * unwrapper calls `ToString` on whatever it is given (`jsg/value.h:501-506`), so\n * refusing a non-string here would refuse what workerd coerces. That is the same\n * reading `api/actor.ts`'s `actorVersionOf` already takes of the same field.\n */\nfunction requireOptions<Options extends object>(options: unknown): Options {\n if (\n options !== undefined &&\n options !== null &&\n typeof options !== \"object\" &&\n typeof options !== \"function\"\n ) {\n throw new TypeError(LOOPBACK_OPTIONS_NOT_AN_OBJECT_MESSAGE);\n }\n return (options ?? {}) as Options;\n}\n\n/** ← `jsg::Optional<jsg::JsRef<jsg::JsObject>> props` — present means an object. */\nfunction requireProps(props: unknown): unknown {\n if (props === undefined) return undefined;\n if (props === null || (typeof props !== \"object\" && typeof props !== \"function\")) {\n throw new TypeError(LOOPBACK_PROPS_NOT_AN_OBJECT_MESSAGE);\n }\n return props;\n}\n\n/** ← `.cohort = kj::mv(version.cohort).orDefault(kj::none)` (`export-loopback.c++:19-23`). */\nfunction versionRequestOf(\n version: LoopbackServiceStubVersion | undefined,\n): VersionRequest | undefined {\n if (version === undefined) return undefined;\n return { cohort: version.cohort ?? undefined };\n}\n","/**\n * ← workerd `src/workerd/api/worker-loader.{h,c++}`\n *\n * The Worker Loader binding: `get(name, getCode)` and `load(code)`, the\n * `WorkerStub` they return, and the two ways a dynamic Worker is reached —\n * `getEntrypoint()` for a `Fetcher` and `getDurableObjectClass()` for a\n * `DurableObjectClass`, which is the single bridge between dynamic Workers and\n * facets. Per §1.11 Code Mode is two features composed: a dynamic Worker for\n * execution and a facet for durable state, because \"Dynamically-loaded isolates\n * can't directly have storage\" (`server/server.c++:4209`).\n *\n * **The scaffolding this file replaces was a hypothesis, and the C++ wants a\n * different shape.** It declared `IsolateHost.execute({executionId, code,\n * namespaces}, onToolCall)` plus `cancel(executionId)`, with a\n * `SandboxNamespaceDescriptor` of `{provider, name}` and a `SandboxToolDispatch`\n * of `(provider, name, args, toolCallId)`. Not one of those words appears in\n * `worker-loader.{h,c++}` or in `io-channels.h`: providers, tool calls and\n * execution ids are the *consumer's* concepts, and this package may not know\n * about Rook, Think or agents. What upstream actually declares is\n * `IoChannelFactory::loadIsolate(channel, name, fetchSource) ->\n * WorkerStubChannel` (`io/io-channels.h:339-343`), with `getEntrypoint` and\n * `getActorClass` on the channel — a Worker-shaped seam, not an\n * execution-shaped one. The scaffolding had transcribed\n * `OffscreenCodemodeExecutor`, which is decision 15's *subject*, not its result.\n * `ActorPorts.isolates` went with it: a Worker Loader is a binding a host puts in\n * `env`, exactly as `DurableObjectNamespace` and `ctx.exports` already are, not a\n * port the container needs — upstream's own is `Global::WorkerLoader{channel}`\n * compiled into the bindings (`server/workerd-api.c++:748`).\n *\n * **`get()` does not cache; the namespace behind it does.** `WorkerLoader::get`\n * calls `loadIsolate` unconditionally and mints a fresh `WorkerStub` every call\n * (`worker-loader.c++:63-83`). The find-or-create by name lives one layer down, in\n * `Server::WorkerLoaderNamespace::loadIsolate` (`server.c++:4243-4281`), together\n * with the rule that a **null or absent name mints a fresh isolate every time** —\n * which upstream's own `isolateUniqueness` test pins at\n * `api/tests/worker-loader-test.js:527-541`. So what this layer owns is which name\n * reaches the seam: `load(code)` is documented as \"Shortcut for `get(null, () =>\n * code)`\" and both it and `get(null)` pass none.\n *\n * **What `load()` owns that `get()` does not is *when* the code is validated.**\n * `load()` builds the whole `DynamicWorkerSource` synchronously before it returns\n * (`worker-loader.c++:88`), so a malformed module list throws out of `load()`;\n * `get()` defers everything into the callback, so the same mistake surfaces at the\n * first request on the stub, which is what upstream's tests assert\n * (`worker-loader-test.js:812`, `:829`, `:856`). That eager capture is also a\n * memory-safety fix: `data` and `wasm` bytes are copied out of the caller's buffer\n * at that moment, because a resizable `ArrayBuffer` can be shrunk to zero\n * afterwards (`worker-loader.c++:225-232`, `:242-245`, and\n * `api/tests/worker-loader-rab-test.js`).\n *\n * **`globalOutbound: null` is the default posture, per decision 15, and what it\n * enforces here is one hop further out than on workerd.** Upstream substitutes a\n * `NullGlobalOutboundChannel` whose `startRequest` throws\n * (`server.c++:4306-4331`), so ambient `fetch` inside the loaded Worker fails from\n * inside the isolate. This layer's whole job is the same one upstream's is:\n * collapse the three JS states — omitted, `null`, a `Fetcher` — into the two the\n * source carries, where absent means blocked and omitted means the caller's own\n * outbound. Enforcement belongs to whatever `loadIsolate` returns, because that is\n * the thing with an isolate to deny.\n *\n * **The one thing this file refuses that upstream refuses elsewhere.**\n * `Frankenvalue::fromJs` serializes `props` and `env` inside these methods, and a\n * `ctx.exports` binding that has not been invoked declares no `JSG_SERIALIZABLE`,\n * so it is refused there with a `DataCloneError` — pinned at\n * `api/tests/worker-loader-test.js:104`. `api/export-loopback.ts`'s header records\n * that refusal as not surviving; it survives here, because this is the layer\n * upstream refuses at. See `requireSerializableProps` below.\n *\n * **There are no source or `env` size caps, and an earlier statement of this\n * section's spec said there were** — \"64 MiB of module source, 1 MiB of `env`\n * (`worker-loader.c++:15-21`)\". Those lines are `WorkerStub::getEntrypoint`'s\n * props-and-limits prologue, and no cap of either size exists anywhere in the\n * open-source runtime: the complete list of refusals in the load path is the ten\n * `JSG_REQUIRE`/`JSG_FAIL_REQUIRE` sites this file ports, and none of them\n * measures a length. Those are Cloudflare's documented *production* limits, which\n * workerd does not reproduce — the same class of thing as `ResourceLimits`, and\n * recorded on it. Nothing here counts bytes.\n *\n * Spec: §1.11, decisions 15 and 16 in\n * docs/decisions.md.\n */\n\nimport type {\n CompatibilityDateValidation,\n CompatibilityFlagsRequest,\n DynamicWorkerSource,\n EntrypointRequest,\n ResourceLimits,\n WorkerStubChannel,\n} from \"../io/io-channels\";\nimport type { IoContext } from \"../io/io-context\";\nimport { requireInputLock } from \"../io/io-context\";\nimport type { Module as SourceModule, ModuleContent, WorkerSource } from \"../io/worker-source\";\nimport { DurableObjectClass } from \"./actor\";\nimport {\n LoopbackColoLocalActorNamespace,\n LoopbackDurableObjectClass,\n LoopbackDurableObjectNamespace,\n LoopbackServiceStub,\n} from \"./export-loopback\";\n\n// =======================================================================================\n// Messages\n\n/** ← `JSG_REQUIRE(code.modules.fields.size() > 0, …)` (`worker-loader.c++:175-176`). */\nexport const NO_MODULES_MESSAGE = \"Dynamic Worker code must contain at least one module.\";\n\nconst MODULE_NAME_PREFIX =\n \"Module name must end with '.js' or '.py' (or the content must be an object \" +\n \"indicating the type explicitly). Got: \";\n\n/** ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:204-206`. */\nexport function moduleNameMessage(name: string): string {\n return `${MODULE_NAME_PREFIX}${name}`;\n}\n\n/**\n * ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:197-201`, the `.ts` / `.tsx` / `.jsx`\n * arm. Upstream's is the message above plus the bundler suggestion.\n */\nexport function typeScriptModuleNameMessage(name: string): string {\n return (\n `${MODULE_NAME_PREFIX}${name}. If you're trying to load TypeScript, bundle it first with ` +\n \"'@cloudflare/worker-bundler' and pass the generated JavaScript modules.\"\n );\n}\n\n/** ← `JSG_REQUIRE(fieldCount == 1, …)` (`worker-loader.c++:212-215`). */\nexport function moduleFieldCountMessage(name: string, fieldCount: number): string {\n return (\n \"Each module must contain exactly one of 'js', 'cjs', 'text', 'data', 'json', 'py', or \" +\n `'wasm'. Module '${name}' contained ${fieldCount} properties.`\n );\n}\n\n/** ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:261-262`. */\nexport function jsModuleInPythonWorkerMessage(name: string): string {\n return `Module \"${name}\" is a JS module, but the main module is a Python module.`;\n}\n\n/** ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:266-267`. */\nexport function pythonModuleInJsWorkerMessage(name: string): string {\n return `Module \"${name}\" is a Python module, but the main module isn't a Python module.`;\n}\n\n/** ← `JSG_REQUIRE` at `worker-loader.c++:152-154`. Upstream's carries no closing period. */\nexport const STREAMING_TAILS_EXPERIMENTAL_MESSAGE =\n \"Streaming tail workers are experimental. You must pass the option \" +\n \"'allowExperimental: true' to the worker loader to use them\";\n\n/**\n * ← `JSG_REQUIRE_NONNULL(weakIoctx->tryGet(), Error, …)` (`worker-loader.c++:73-74`),\n * the guard the AUTOVULN-CLOUDFLARE-WORKERD-256 fix added.\n *\n * **The precondition differs and the failure mode nearly did too.** Upstream's\n * `IoContext` is per REQUEST, so a stub can outlive the context that made it and\n * the raw `&ioctx` capture was a use-after-free; the WeakRef turns that into this\n * message. Ours is per CONTAINER and outlives every stub it made, so the\n * destroyed case cannot happen — what remains reachable is an **aborted** actor,\n * and for that `IoContext::awaitIo` deliberately leaves its promise unsettled\n * (\"`result` is deliberately left unsettled, as upstream leaves it\",\n * `io/io-context.ts`). Upstream can afford that because `runAlarm`'s caller and\n * everything else in a torn-down request is being destroyed anyway; a dynamic\n * worker load cannot, because `WorkerStubChannel`'s contract is that a failed\n * load makes every request on the stub **fail** — a load that never settles makes\n * every request on the stub hang instead, which is the failure this repository's\n * own divergence 149 exists to prevent (\"a JS promise has to settle, and one that\n * never does is a hang nobody can see\"). So the abort is observed explicitly and\n * answered with upstream's own message.\n */\nexport const DEAD_LOAD_CONTEXT_MESSAGE =\n \"The request which initiated this dynamic worker load has already completed.\";\n\n/** ← `JSG_REQUIRE(!allowExperimental, …)` (`worker-loader.c++:282-284`). */\nexport const ALLOW_EXPERIMENTAL_MESSAGE =\n \"'allowExperimental' is only allowed when the calling worker has the 'experimental' \" +\n \"compat flag set.\";\n\n/**\n * ← `Serializer::throwDataCloneErrorForObject` (`jsg/ser.c++:175-183`), whose type\n * name is `obj->GetConstructorName()` — the JSG resource type's name, which is the\n * class name here. Pinned for `LoopbackServiceStub` at\n * `api/tests/worker-loader-test.js:104`.\n */\nexport function notSerializableMessage(typeName: string): string {\n return `Could not serialize object of type \"${typeName}\". This type does not support serialization.`;\n}\n\n/** Not something `jsg::asBytes()` would accept for a `kj::Array<const byte>` body. */\nexport const NOT_BYTES_MESSAGE =\n \"A module's 'data' or 'wasm' body must be an ArrayBuffer or a view over one.\";\n\n// =======================================================================================\n// The outgoing seam — the two IoChannelFactory methods this file reaches\n\n/**\n * ← the two arguments `IoChannelFactory::loadIsolate` takes besides the channel\n * number (`io/io-channels.h:339-343`). Upstream: \"Use a dynamic Worker loader\n * binding to obtain an Worker by name. If name is null, or if the named Worker\n * doesn't already exist, the callback will be called to fetch the source code from\n * which the Worker should be created.\"\n *\n * Upstream's own note on the callback, at `worker-loader.c++:90-94`, is the\n * contract an implementation has to honour: \"the callback we pass to\n * `loadIsolate()` technically may be called any number of times. Yes, even though\n * we aren't providing an ID. The runtime can actually evict the isolate while a\n * stub still exists, as long as there is no active request on the stub, and then\n * recreate the isolate on the next request.\"\n */\nexport type LoadIsolateRequest = {\n /**\n * ← `kj::Maybe<kj::String> name`. Absent means the isolate is not cached and a\n * fresh one is minted per call (`server.c++:4264-4281`).\n */\n readonly name: string | undefined;\n /** ← `kj::Function<kj::Promise<DynamicWorkerSource>()> fetchSource`. */\n fetchSource(): Promise<DynamicWorkerSource>;\n};\n\n/**\n * ← `IoChannelFactory`'s two dynamic-worker methods, collapsed the way\n * `api/actor.ts` and `api/export-loopback.ts` already collapse theirs: both take a\n * channel *number* upstream and there is no numbered channel table here, so each\n * becomes a factory method taking an object request. Declared beside its one\n * consumer for the same reason `ActorChannelFactory` is.\n *\n * This is the whole substrate seam of §1.11. A host implements it three ways — the\n * offscreen document in the browser, an in-realm module evaluation under Node, and\n * the real `worker_loaders` binding on workerd — and nothing above it has to know\n * which.\n */\nexport interface IsolateChannelFactory {\n /** ← `IoChannelFactory::loadIsolate`. Returns before the Worker has loaded. */\n loadIsolate(request: LoadIsolateRequest): WorkerStubChannel;\n\n /**\n * ← `getSubrequestChannel(IoContext::NULL_CLIENT_CHANNEL)`\n * (`worker-loader.c++:137-138`, `io/io-context.h:753`) — the calling worker's own\n * global outbound, which a loaded Worker inherits when `globalOutbound` is\n * omitted. Upstream reaches it by channel number 0; with no channel table it is a\n * method on the one factory that needs it.\n *\n * Upstream deliberately does not call `requireAllowsTransfer()` on this one: \"if\n * it was the global outbound of the parent, it must be OK to be the global\n * outbound of the child.\"\n */\n getNullClientChannel(): Fetcher;\n}\n\n// =======================================================================================\n// The JS-facing structs\n\n/**\n * ← `WorkerLoader::Module` (`worker-loader.h:62-78`). \"Exactly one must be filled\n * in.\"\n *\n * `data` and `wasm` are `ArrayBuffer | ArrayBufferView` where\n * `@cloudflare/workers-types` declares `ArrayBuffer`, because upstream unwraps\n * them with `jsg::asBytes()`, which accepts either — and upstream's own tests pass\n * a `Uint8Array` to both (`worker-loader-test.js:585`, `:645`). A superset of the\n * pinned types, the same relationship `DurableObjectNamespace.getExisting` has.\n *\n * `serializedJson` is absent: upstream's own comment calls it a HACK for owning\n * the string `Worker::Script::Source` only borrows, and a JS string is owned.\n */\nexport type Module = {\n /** ES module. */\n readonly js?: string;\n /** Common JS module. */\n readonly cjs?: string;\n /** \"text blob, imports as a string\" */\n readonly text?: string;\n /** \"byte blob, imports as ArrayBuffer\" */\n readonly data?: ArrayBuffer | ArrayBufferView;\n /** \"arbitrary JS value, will be serialized to JSON and then parsed again when imported\" */\n readonly json?: unknown;\n /** Python module. */\n readonly py?: string;\n /** \"compiled WASM module\" */\n readonly wasm?: ArrayBuffer | ArrayBufferView;\n};\n\n/** ← `WorkerLoader::WorkerCode` (`worker-loader.h:80-120`). */\nexport type WorkerCode = {\n readonly compatibilityDate: string;\n readonly compatibilityFlags?: readonly string[];\n readonly allowExperimental?: boolean;\n readonly limits?: ResourceLimits;\n readonly mainModule: string;\n /**\n * \"Modules are specified as an object mapping names to content. If the content is\n * just a string, an ES module is assumed. If it's an object, the type of module\n * is determined based on which property is set.\"\n */\n readonly modules: Record<string, Module | string>;\n /** \"Any RPC-serializable value!\" */\n readonly env?: unknown;\n /**\n * \"`Fetcher` (e.g. service binding) representing the loaded worker's global\n * outbound. If omitted, inherit the current worker's global outbound. If `null`,\n * block the global outbound (all requests throw errors).\"\n */\n readonly globalOutbound?: Fetcher | null;\n /** \"Specify tail workers.\" */\n readonly tails?: readonly Fetcher[];\n readonly streamingTails?: readonly Fetcher[];\n};\n\n/** ← `WorkerStub::EntrypointOptions` (`worker-loader.h:22-27`). */\nexport type EntrypointOptions = {\n readonly props?: unknown;\n readonly limits?: ResourceLimits;\n};\n\n// =======================================================================================\n// WorkerStub\n\n/**\n * ← `WorkerStub` (`worker-loader.h:15-50`). \"JS stub pointing to a remote Worker\n * loaded using WorkerLoader. This is not a stub for a specific entrypoint, but\n * instead the entire Worker, allowing the caller to call any entrypoint (and\n * specify arbitrary props).\"\n */\nexport class WorkerStub implements globalThis.WorkerStub {\n readonly #channel: WorkerStubChannel;\n\n constructor(channel: WorkerStubChannel) {\n this.#channel = channel;\n }\n\n /** ← `WorkerStub::getEntrypoint` (`worker-loader.c++:13-36`). */\n getEntrypoint<T extends Rpc.WorkerEntrypointBranded | undefined = undefined>(\n name?: string | null,\n options?: EntrypointOptions,\n ): Fetcher<T> {\n return asEntrypointStub<T>(this.#channel.getEntrypoint(entrypointRequestOf(name, options)));\n }\n\n /**\n * ← `WorkerStub::getDurableObjectClass` (`worker-loader.c++:38-61`).\n *\n * **This is the bridge into facets and it is a real connection, not a named\n * boundary.** The `ActorClassChannel` the channel answers with is the same token\n * `DurableObjectClass.getChannel()` hands to `FacetStartInfo.actorClass`, which\n * `FacetManager.getFacet` hands to `FacetHost.start` — so a class obtained here\n * goes straight into `ctx.facets.get(name, () => ({ class }))` with nothing in\n * between, which is exactly the shape upstream's `FacetTestActor` uses\n * (`worker-loader-test.js:421-433`).\n */\n getDurableObjectClass<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name?: string | null,\n options?: EntrypointOptions,\n ): DurableObjectClass<T> {\n return new DurableObjectClass<T>(this.#channel.getActorClass(entrypointRequestOf(name, options)));\n }\n}\n\n/**\n * The one assertion `getEntrypoint` needs, and it is `asFacetStub`'s\n * (`io/worker.ts`) for `asFacetStub`'s reason: `Fetcher<T>` for an unresolved `T`\n * is a conditional type over the caller's claim about an entrypoint it named, and\n * no value can confirm that claim. Upstream states the same shape the same way, in\n * a `JSG_TS_OVERRIDE` (`worker-loader.h:40-45`) that no C++ value is checked\n * against either. What IS checked is the half that carries behaviour — `fetch` and\n * `connect` — because the argument is a `Fetcher` before it is widened.\n */\nfunction asEntrypointStub<T extends Rpc.WorkerEntrypointBranded | undefined>(\n stub: Fetcher,\n): Fetcher<T> {\n return stub as Fetcher<T>;\n}\n\n/**\n * ← the identical prologue of both `WorkerStub` methods (`worker-loader.c++:16-32`\n * and `:41-57`).\n *\n * `\"default\"` collapses to no name, which is upstream's own line\n * (`if (n2 != \"default\"_kj)`) and is why `getEntrypoint(\"default\")` and\n * `getEntrypoint()` reach the same entrypoint.\n */\nfunction entrypointRequestOf(\n name: string | null | undefined,\n options: EntrypointOptions | undefined,\n): EntrypointRequest {\n return {\n name: entrypointNameOf(name),\n props: requireSerializableProps(options?.props, \"props\"),\n limits: options?.limits,\n };\n}\n\nfunction entrypointNameOf(name: string | null | undefined): string | undefined {\n // ← `jsg::Optional<kj::Maybe<kj::String>>`: absent and null are the same request. Anything\n // else reaches JSG's `kj::String` unwrapper, which calls ToString (`jsg/value.h:501-506`) —\n // the same reading `api/export-loopback.ts` gives `version.cohort`.\n if (name === undefined || name === null) return undefined;\n const text = String(name);\n return text === \"default\" ? undefined : text;\n}\n\n// =======================================================================================\n// WorkerLoader\n\n/**\n * The two constructor inputs upstream's `WorkerLoader` resolves from ambients this\n * package does not have.\n */\nexport type WorkerLoaderOptions = {\n /**\n * ← `WorkerLoader`'s second constructor parameter (`worker-loader.h:58`), whose\n * comment is \"`compatDateValidation` will differ between workerd vs.\n * production\". It is carried onto the `DynamicWorkerSource` rather than consumed\n * here, because the compilation it feeds is a substrate boundary — see\n * `CompatibilityFlagsRequest` in `io/io-channels.ts`.\n */\n readonly compatDateValidation: CompatibilityDateValidation;\n\n /**\n * ← `FeatureFlags::get(js).getWorkerdExperimental()` (`worker-loader.c++:281`) —\n * the *calling* worker's `experimental` compatibility flag, which gates\n * `allowExperimental` on the loaded one.\n *\n * Every other compatibility flag this package meets was answered by \"a runtime\n * with no deployed history takes the current behaviour\" (`api/actor.ts`, and the\n * README row for `deleteAllDeletesAlarm`). That reading does not work here:\n * `experimental` has no default-on date and never turns on by itself, so taking\n * the current behaviour would hard-code `false`, make `allowExperimental: true`\n * always throw, and put `streamingTails` out of reach — the feature subset the\n * README's second paragraph forbids. So the bit moves from an ambient to an\n * explicit input, which is what this package does with every ambient.\n * `compileCompatibilityFlags`'s own parameter for the same bit is named\n * `allowExperimentalFeatures`.\n */\n readonly allowExperimentalFeatures: boolean;\n};\n\n/**\n * ← `WorkerLoader` (`worker-loader.h:52-150`). \"JS interface for worker loader\n * binding.\"\n *\n * Takes an `IoContext` where upstream reads `IoContext::current()`, which is the\n * substitution every class in `api/` makes (`DurableObjectFacets`,\n * `DurableObjectStorageOperations`); and an `IsolateChannelFactory` where upstream\n * holds a channel number, which is the substitution every outgoing seam in `api/`\n * makes.\n */\nexport class WorkerLoader implements globalThis.WorkerLoader {\n readonly #ctx: IoContext;\n readonly #channel: IsolateChannelFactory;\n readonly #options: WorkerLoaderOptions;\n\n constructor(ctx: IoContext, channel: IsolateChannelFactory, options: WorkerLoaderOptions) {\n this.#ctx = ctx;\n this.#channel = channel;\n this.#options = options;\n }\n\n /**\n * ← `WorkerLoader::get` (`worker-loader.c++:63-83`).\n *\n * Nothing is validated here: the code callback is deferred whole into the reentry\n * callback, so every refusal `toDynamicWorkerSource` can make surfaces at the\n * first request on the returned stub instead. That is upstream's own behaviour\n * and its tests depend on it.\n */\n get(name: string | null | undefined, getCode: () => WorkerCode | Promise<WorkerCode>): WorkerStub {\n const ctx = this.#ctx;\n\n // ← `ioctx.makeReentryCallback(…)` (`worker-loader.c++:67`), and it is decision 13 for the\n // same reason the facet startup callback is: a Worker loaded from inside\n // blockConcurrencyWhile() would otherwise queue behind the section waiting for it.\n const reenterAndGetCode = ctx.makeReentryCallback(\n async (): Promise<DynamicWorkerSource> =>\n // ← the inner `getCode(js).then(js, …)` (`:70-76`). A jsg promise continuation re-enters\n // the isolate, so the source is built holding a fresh input lock rather than in whatever\n // context the code promise happened to resolve in; `awaitIo` is that re-entry, and it is\n // what keeps `toDynamicWorkerSource` gated (divergence 147).\n await Promise.race([\n ctx.awaitIo(Promise.resolve(getCode()), (code) => this.#toDynamicWorkerSource(code)),\n // ← `JSG_REQUIRE_NONNULL(weakIoctx->tryGet(), …)` (`:73-74`). `awaitIo`'s own answer to\n // an aborted context is to leave its promise unsettled, which would wedge every request\n // on the stub — see `DEAD_LOAD_CONTEXT_MESSAGE`. `onAbort()` only ever rejects.\n ctx.onAbort().catch((): never => {\n throw new Error(DEAD_LOAD_CONTEXT_MESSAGE);\n }),\n ]),\n );\n\n return new WorkerStub(\n this.#channel.loadIsolate({ name: loadNameOf(name), fetchSource: reenterAndGetCode }),\n );\n }\n\n /**\n * ← `WorkerLoader::load` (`worker-loader.c++:85-107`). \"Shortcut for `get(null,\n * () => code)`.\"\n *\n * A shortcut with two consequences upstream states outright. The source is built\n * **now**, synchronously, so every refusal below throws from this call rather\n * than from the first request; and `name` is `kj::none`, so the isolate is not\n * cached and a fresh Worker is minted per call.\n *\n * Upstream's clone-per-invocation is absent because a JS source object is\n * immutable and shared safely — see `io/worker-source.ts`'s header. The\n * atomic-refcount wrapper it needs for that (\"it may ultimately destroy the\n * `ownContent` in another thread ... Ugh!\") goes with it.\n */\n load(code: WorkerCode): WorkerStub {\n // ← `auto& ioctx = IoContext::current();` (`:86`), which asserts. `get()` does not need the\n // line because `makeReentryCallback` makes the same assertion for it.\n requireInputLock(this.#ctx, \"load()\");\n\n const source = this.#toDynamicWorkerSource(code);\n return new WorkerStub(\n this.#channel.loadIsolate({ name: undefined, fetchSource: async () => source }),\n );\n }\n\n /** ← `WorkerLoader::toDynamicWorkerSource` (`worker-loader.c++:109-172`). */\n #toDynamicWorkerSource(code: WorkerCode): DynamicWorkerSource {\n const source = extractSource(code);\n const compatibilityFlags = this.#extractCompatFlags(code);\n\n // ← `Frankenvalue::fromJs(js, codeEnv.getHandle(js))` (`:117-120`).\n const env = requireSerializableProps(code.env, \"env\");\n\n // ← `:122-139`. Three JS states collapse to two: `null` leaves the source's outbound absent,\n // which is what blocks it, and an omitted one inherits the caller's.\n let globalOutbound: Fetcher | undefined;\n if (code.globalOutbound !== undefined) {\n if (code.globalOutbound !== null) {\n globalOutbound = requireTransferableChannel(code.globalOutbound);\n } else {\n // \"Application passed `null` to disable internet access. Leave `globalOutbound` as\n // `kj::none`.\"\n }\n } else {\n // \"Inherit the calling worker's global outbound channel.\" No transferrability check, per\n // upstream: the parent's outbound is by definition allowed to be the child's.\n globalOutbound = this.#channel.getNullClientChannel();\n }\n\n // ← `:141-148`.\n const tails = (code.tails ?? []).map(requireTransferableChannel);\n\n // ← `:150-161`.\n const streamingTailsInput = code.streamingTails;\n let streamingTails: readonly Fetcher[] = [];\n if (streamingTailsInput !== undefined) {\n if ((code.allowExperimental ?? false) !== true) {\n throw new Error(STREAMING_TAILS_EXPERIMENTAL_MESSAGE);\n }\n streamingTails = streamingTailsInput.map(requireTransferableChannel);\n }\n\n return {\n source,\n compatibilityFlags,\n limits: code.limits,\n env,\n globalOutbound,\n tails,\n streamingTails,\n };\n }\n\n /**\n * ← `WorkerLoader::extractCompatFlags` (`worker-loader.c++:278-306`), first half\n * only.\n *\n * The second half compiles the date and flags into a `CompatibilityFlags::Reader`\n * by walking that schema's capnp annotations, and reports\n * `errorReporter.errors.front()`. There is no `compatibility-date.capnp` here and\n * no schema reflection to walk one with, so the inputs travel on the\n * `DynamicWorkerSource` to the layer that has an isolate to configure. See\n * `CompatibilityFlagsRequest` in `io/io-channels.ts`.\n */\n #extractCompatFlags(code: WorkerCode): CompatibilityFlagsRequest {\n const allowExperimental = code.allowExperimental ?? false;\n if (!this.#options.allowExperimentalFeatures) {\n if (allowExperimental) throw new Error(ALLOW_EXPERIMENTAL_MESSAGE);\n }\n\n return {\n compatibilityDate: code.compatibilityDate,\n compatibilityFlags: code.compatibilityFlags ?? [],\n allowExperimental,\n dateValidation: this.#options.compatDateValidation,\n };\n }\n}\n\n/**\n * ← `kj::Maybe<kj::String> name` on `WorkerLoader::get`. Absent and null are the\n * same request, and both mint a fresh isolate — `worker-loader-test.js:527-541`\n * checks `get(null)` and two `get(undefined)`s all get their own module scope.\n *\n * Unlike the entrypoint name, `\"default\"` is not special here: it names an\n * isolate, not an export.\n */\nfunction loadNameOf(name: string | null | undefined): string | undefined {\n return name === undefined || name === null ? undefined : String(name);\n}\n\n// =======================================================================================\n// extractSource\n\n/**\n * ← `WorkerLoader::extractSource` (`worker-loader.c++:174-276`).\n *\n * Iteration order is the object's own key order, which is `jsg::Dict`'s: both the\n * fieldCount and mixed-language refusals name the FIRST offending module in that\n * order, and upstream's `noMixedJsPythonModules` pair depends on it\n * (`worker-loader-test.js:803-835`).\n */\nfunction extractSource(code: WorkerCode): WorkerSource {\n const entries = Object.entries(code.modules);\n if (entries.length === 0) throw new TypeError(NO_MODULES_MESSAGE);\n\n const modules: SourceModule[] = entries.map(([name, value]) => ({\n name,\n content: moduleContentOf(name, value),\n }));\n\n // ← `:255`. Whether the Worker is Python is decided by the MAIN module's name alone.\n const isPython = code.mainModule.endsWith(\".py\");\n\n // ← `:257-269`. \"Disallow Python modules when the main module is a JS module, and vice versa.\"\n for (const module of modules) {\n const isJsModule =\n module.content.type === \"esModule\" || module.content.type === \"commonJsModule\";\n if (isPython && isJsModule) {\n throw new TypeError(jsModuleInPythonWorkerMessage(module.name));\n }\n const isPythonModule = module.content.type === \"pythonModule\";\n if (!isPython && isPythonModule) {\n throw new TypeError(pythonModuleInJsWorkerMessage(module.name));\n }\n }\n\n return { variant: { type: \"modulesSource\", mainModule: code.mainModule, modules, isPython } };\n}\n\n/** ← the `KJ_SWITCH_ONEOF(entry.value)` at `worker-loader.c++:179-251`. */\nfunction moduleContentOf(name: string, value: Module | string): ModuleContent {\n if (typeof value === \"string\") return stringModuleContentOf(name, value);\n return objectModuleContentOf(name, value);\n}\n\n/** ← the `kj::String` arm (`:180-207`): the name alone decides the type. */\nfunction stringModuleContentOf(name: string, body: string): ModuleContent {\n if (name.endsWith(\".py\")) return { type: \"pythonModule\", body };\n if (name.endsWith(\".js\")) return { type: \"esModule\", body };\n if (name.endsWith(\".ts\") || name.endsWith(\".tsx\") || name.endsWith(\".jsx\")) {\n throw new TypeError(typeScriptModuleNameMessage(name));\n }\n throw new TypeError(moduleNameMessage(name));\n}\n\n/** The seven fields of `WorkerLoader::Module`, in upstream's `JSG_STRUCT` order. */\nconst MODULE_FIELDS = [\"js\", \"cjs\", \"text\", \"data\", \"json\", \"py\", \"wasm\"] as const;\n\n/** ← the `Module` arm (`:208-250`). */\nfunction objectModuleContentOf(name: string, module: Module): ModuleContent {\n // ← the seven `!= kj::none` sums at `:209-211`. `jsg::Optional` reads undefined as absent, so a\n // field explicitly set to undefined does not count — which is what makes a `{...spread}` of a\n // partially-filled module behave the same way in both runtimes.\n const fieldCount = MODULE_FIELDS.filter((field) => module[field] !== undefined).length;\n if (fieldCount !== 1) throw new TypeError(moduleFieldCountMessage(name, fieldCount));\n\n if (module.js !== undefined) return { type: \"esModule\", body: module.js };\n if (module.cjs !== undefined) return { type: \"commonJsModule\", body: module.cjs };\n if (module.text !== undefined) return { type: \"textModule\", body: module.text };\n // ← `:225-232`. \"The kj::Array<const byte> produced by jsg::asBytes() points into a V8\n // BackingStore. If the user passed a *resizable* ArrayBuffer they can call resize(0) (or\n // transfer/detach) after load() returns but before the child isolate is compiled\n // asynchronously, leaving us with a (ptr,len) into PROT_NONE pages. Copy now so the bytes\n // survive until compileDataGlobal().\"\n if (module.data !== undefined) return { type: \"dataModule\", body: copyBytes(module.data) };\n if (module.json !== undefined) {\n // ← `js.serializeJson(kj::mv(json))` (`:234-235`). Upstream then clears the field because it\n // moved out of a V8Ref; nothing is moved here. `JSON.stringify` answers undefined for a value\n // it cannot represent at the root — a function or a symbol — where V8's JSON serializer\n // throws; the string is what a module body has to be, so the undefined is made one.\n return { type: \"jsonModule\", body: JSON.stringify(module.json) ?? \"undefined\" };\n }\n if (module.py !== undefined) return { type: \"pythonModule\", body: module.py };\n if (module.wasm !== undefined) return { type: \"wasmModule\", body: copyBytes(module.wasm) };\n\n // ← `KJ_UNREACHABLE` (`:247`): fieldCount === 1 has already found one of the seven.\n throw new Error(\"unreachable: exactly one module field is set\");\n}\n\n/**\n * ← `jsg::asBytes()` followed by `kj::heapArray<const kj::byte>(data.asPtr())`\n * (`worker-loader.c++:231`, `:244`). The copy is the whole point — see the caller.\n */\nfunction copyBytes(value: ArrayBuffer | ArrayBufferView): Uint8Array {\n if (value instanceof ArrayBuffer) return new Uint8Array(value.slice(0));\n if (ArrayBuffer.isView(value)) {\n return new Uint8Array(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));\n }\n throw new TypeError(NOT_BYTES_MESSAGE);\n}\n\n// =======================================================================================\n// What may cross into a dynamic Worker\n\n/**\n * ← `Fetcher::getSubrequestChannel(ioctx)` followed by\n * `channel->requireAllowsTransfer()` (`worker-loader.c++:125-126`, `:144-145`,\n * `:157-158`).\n *\n * **The check has nothing to call, and that is a recorded divergence rather than\n * an omission.** Upstream's `SubrequestChannel` carries `requireAllowsTransfer()`;\n * here a `SubrequestChannel` and the `Fetcher` built over it are one object\n * (`io/io-channels.ts`'s header, and the same collapse `api/actor.ts` and\n * `api/export-loopback.ts` already made), and a `Fetcher` is\n * `@cloudflare/workers-types`' interface with no such member. The one refusal it\n * produces in the open-source runtime is `throwDynamicEntrypointTransferError`\n * (`server.c++:167-173`), raised by `WorkerService::requireAllowsTransfer` when\n * `isDynamic` — an isolate-host fact here, exactly as it is a `server/` fact there.\n *\n * Kept as a named function rather than inlined so the three call sites read as\n * upstream's do, and so there is one place to put the check if a `Fetcher` seam\n * ever grows one.\n */\nfunction requireTransferableChannel(fetcher: Fetcher): Fetcher {\n return fetcher;\n}\n\n/**\n * ← `Frankenvalue::fromJs(js, …)`, whose serializer refuses any object whose JSG\n * resource type declares no `JSG_SERIALIZABLE` (`jsg/ser.c++:175-183`).\n *\n * Four types reachable from this package are in that set, and all four for one\n * reason: `JSG_INHERIT` does not carry serializability. Upstream says so twice — in\n * `export-loopback.h:57-58` (\"Note that `LoopbackServiceStub` is intentionally NOT\n * serializable, unlike its parent class Fetcher\") and in the test that pins it,\n * whose comment reads \"it's more testing LoopbackServiceStub and that\n * serializability is not inherited\" (`worker-loader-test.js:91-92`). None of\n * `LoopbackServiceStub`, `LoopbackDurableObjectClass`,\n * `LoopbackDurableObjectNamespace` or `LoopbackColoLocalActorNamespace` declares\n * `JSG_SERIALIZABLE`; every one of them *invoked* produces something that does — a\n * `Fetcher` or a plain `DurableObjectClass` — which is exactly the distinction\n * `worker-loader-test.js:62-107` measures, accepting the invoked form in `props`\n * and refusing the bare binding.\n *\n * **This discharges the obligation the README left open on Section 7.** That row\n * says the refusal would have to come from `src/transport/` if a `Fetcher` ever\n * became serializable; the layer upstream refuses at is this one, because\n * `Frankenvalue::fromJs` runs inside `getEntrypoint`, `getDurableObjectClass` and\n * `toDynamicWorkerSource`. Putting it here makes it reachable today rather than\n * conditional on a transport change that has not happened, and it depends on no\n * transport fact — so `api/` still imports no transport library.\n *\n * The walk descends into plain objects and arrays only. Everything else is a host\n * object: either one the substrate knows how to carry (a `Fetcher`, a\n * `DurableObjectClass`, an `RpcTarget`) or one of the four above. Walking a host\n * object's own keys would drive proxy traps — a stub's `get` mints an RPC import —\n * which is a cost upstream's serializer never pays, because it asks the type rather\n * than the value.\n */\nfunction requireSerializableProps(root: unknown, field: string): unknown {\n // A cycle would otherwise walk forever; upstream's serializer handles one natively.\n const seen = new Set<object>();\n\n const visit = (value: unknown, path: string): void => {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) return;\n const subject = value as object;\n\n const refused = notSerializableType(subject);\n if (refused !== undefined) {\n throw new DOMException(`${notSerializableMessage(refused)} At ${path}.`, \"DataCloneError\");\n }\n\n if (seen.has(subject)) return;\n seen.add(subject);\n\n if (Array.isArray(subject)) {\n subject.forEach((entry, index) => {\n visit(entry, `${path}[${index}]`);\n });\n return;\n }\n\n // Plain objects only — see the note above on why a host object is not descended into.\n const prototype: unknown = Object.getPrototypeOf(subject);\n if (prototype !== Object.prototype && prototype !== null) return;\n for (const [name, entry] of Object.entries(subject)) visit(entry, `${path}.${name}`);\n };\n\n visit(root, `<${field}>`);\n return root;\n}\n\n/**\n * The four `ctx.exports` binding types, named by the class whose name\n * `GetConstructorName()` would report.\n *\n * The four are mutually exclusive — each extends a different base\n * (`api/export-loopback.ts`) — so the order is presentational. What the order does\n * NOT do is reach a base class: `DurableObjectClass`, `DurableObjectNamespace`,\n * `ColoLocalActorNamespace` and `Fetcher` are all serializable upstream\n * (`actor.h:389`), and it is exactly `JSG_INHERIT`'s failure to carry\n * serializability that makes the four subclasses refuse where their bases accept.\n */\nfunction notSerializableType(value: object): string | undefined {\n if (value instanceof LoopbackServiceStub) return \"LoopbackServiceStub\";\n if (value instanceof LoopbackDurableObjectNamespace) return \"LoopbackDurableObjectNamespace\";\n if (value instanceof LoopbackColoLocalActorNamespace) return \"LoopbackColoLocalActorNamespace\";\n if (value instanceof LoopbackDurableObjectClass) return \"LoopbackDurableObjectClass\";\n return undefined;\n}\n\n// =======================================================================================\n// The pinned-types check\n\n/** `Value` must be assignable to `Declared`; declaring the constraint is the check. */\ntype Assignable<Value extends Declared, Declared> = Value;\n\n/**\n * §2.4's no-cast rule: these reach a consumer as `env` bindings typed by\n * `@cloudflare/workers-types`, so the type system checks the surface rather than a\n * cast doing it. The three struct rows point the other way, because a struct is an\n * argument: what has to hold is that every code a consumer can write against the\n * pinned type is one this file accepts. `Module` is a strict superset by the two\n * byte fields, for the reason its own comment gives.\n */\nexport type PinnedWorkerLoaderTypes = [\n Assignable<WorkerLoader, globalThis.WorkerLoader>,\n Assignable<WorkerStub, globalThis.WorkerStub>,\n Assignable<globalThis.WorkerLoaderWorkerCode, WorkerCode>,\n Assignable<globalThis.WorkerLoaderModule, Module>,\n Assignable<globalThis.WorkerStubEntrypointOptions, EntrypointOptions>,\n];\n","/**\n * ← workerd `src/workerd/api/sql.{h,c++}`\n *\n * `SqlStorage` and its two nested types. ~330 call sites depend on this — it is\n * the real storage layer, not KV.\n *\n * Four things about the translation, in descending order of how much they cost:\n *\n * 1. **The cursor is materialised, not live.** Upstream's `Cursor` owns a\n * running `SqliteDatabase::Query` and pulls one row at a time; the backend\n * seam this package chose (`SqlDatabase.exec` → `SqlResult`) has already\n * collected every row before a cursor exists. Everything downstream of that\n * follows: there is no statement cache, so `CachedStatement`, the 1 MiB LRU\n * and `reusedCachedQueryForTest` are absent with it; there is no live\n * statement to cancel, so `Cursor::canceled` and `selfRef` — both already\n * dead upstream, written but never assigned — have nothing to guard; and\n * `endQuery`'s job of returning a statement to the cache is nothing here, so\n * the counters it saves off are simply the counters. What is kept is every\n * observable: the position is shared across `next`/`toArray`/`one`/`raw`,\n * and a drained cursor keeps yielding done.\n * 2. **`Cursor` and `Statement` must be constructible with no arguments**, or\n * `SqlStorage` cannot satisfy workers-types without a cast: the interface\n * types them `typeof SqlStorageCursor` / `typeof SqlStorageStatement`, and\n * both are `abstract` there, so their construct signatures take none.\n * Upstream's are unconstructible from JS for the same reason they are\n * `abstract` in the types — JSG nested types have no JS constructor — so the\n * faithful shape is a constructor that refuses. `sql.Cursor` exists for\n * `instanceof`, which is all upstream exposes it for.\n * 3. **The regulator is ported whole; what is missing is the authorizer that\n * calls it.** All three callbacks are here and none of them needed the\n * authorizer to compute anything — `isAllowedName` is a prefix test,\n * `isAllowedTrigger` is `return true`, `allowTransactions` throws. What the\n * authorizer supplied was the *identifiers*, not the decisions. With no\n * authorizer the statement text is the only source, so `exec` tokenizes it\n * and runs `isAllowedName` over every identifier-shaped token. That is\n * deliberately STRICTER than upstream — see `SQL_RESERVED_PREFIX_MESSAGE`.\n * 4. **`ingest` stays at upstream's SQLite seam.** `SqliteDatabase.ingest()`\n * executes every complete statement and returns the partial tail, using the\n * same compiled boundaries and regulator as `exec`.\n *\n * Spec: §1.4, §2.4 in docs/decisions.md.\n */\n\nimport { requireInputLock } from \"../io/io-context\";\nimport type { IoContext } from \"../io/io-context\";\nimport type { SqlIngestResult, SqliteDatabase, SqlValue } from \"../util/sqlite\";\n\n/**\n * ← `SqlStorage::BindingValue`. JSG converts these public JavaScript values\n * to workerd's `Maybe<OneOf<Array<byte>, String, double>>` before C++ sees them;\n * `toSqlBindingValue()` is that conversion for this no-isolate runtime.\n */\nexport type BindingValue =\n | ArrayBuffer\n | ArrayBufferView\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/** ← the `SqlStorageValue` `JSG_TS_DEFINE` on `Cursor`. */\nexport type SqlRow = Record<string, SqlStorageValue>;\n\n/** ← `SqlStorage::IngestResult`. */\nexport type SqlStorageIngestResult = SqlIngestResult;\n\n/**\n * ← `SqlStorageRegulator::allowTransactions()`, copied verbatim. Users match on\n * it and it is the one regulator callback our substrate can still answer.\n */\nexport const SQL_TRANSACTION_REFUSED_MESSAGE =\n \"To execute a transaction, please use the state.storage.transaction() or \" +\n \"state.storage.transactionSync() APIs instead of the SQL BEGIN TRANSACTION or SAVEPOINT \" +\n \"statements. The JavaScript API is safer because it will automatically roll back on \" +\n \"exceptions, and because it interacts correctly with Durable Objects' automatic atomic \" +\n \"write coalescing.\";\n\n/** See translation 2 in the header: the class is exposed for `instanceof` only. */\nexport const CURSOR_NOT_CONSTRUCTIBLE_MESSAGE =\n \"Illegal invocation: SqlStorage.Cursor cannot be constructed directly. Use sql.exec().\";\n\n/** Same, for the prepared-statement compatibility shim. */\nexport const STATEMENT_NOT_CONSTRUCTIBLE_MESSAGE =\n \"Illegal invocation: SqlStorage.Statement cannot be constructed directly. Use sql.prepare().\";\n\n/**\n * ← SQLite's own denial text, with the reason appended.\n *\n * There is no upstream string to copy here: `SqlStorageRegulator::onError` just\n * rethrows whatever SQLite produced, and SQLite produces `not authorized` for an\n * authorizer denial (`access to X.Y is prohibited` for the column-read case,\n * which needs a resolved identifier we do not have). The prefix is kept so that\n * anything matching upstream still matches; the rest is here because a bare\n * `not authorized` is not debuggable.\n */\nexport const SQL_RESERVED_PREFIX_MESSAGE =\n \"not authorized: a SQL statement may not name the reserved _cf_ prefix, which is where this \" +\n \"Durable Object keeps its own KV and metadata tables.\";\n\n/**\n * ← the five transaction-control forms `sqlite3_stmt_readonly()` reports\n * read-only and the authorizer reports as `SQLITE_TRANSACTION` /\n * `SQLITE_SAVEPOINT`. The same set `util/sqlite.ts` classifies, read here from\n * the leading keyword because the untrusted path has to refuse them before the\n * trusted one applies them.\n */\nconst TRANSACTION_CONTROL = /^\\s*(?:BEGIN|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\\b/i;\n\n/** Cheap pre-test, so the tokenizer below runs only on a statement that could fail it. */\nconst RESERVED_PREFIX_HINT = /_cf_/i;\n\n/** A SQL identifier. Double-quoted and bracketed forms are still identifiers, so only the\n * delimiters are stripped and the word inside is scanned like any other. */\nconst IDENTIFIER = /[A-Za-z_][A-Za-z0-9_$]*/g;\n\n/**\n * Everything in a statement an identifier cannot come from: single-quoted string\n * literals (SQLite escapes an embedded quote by doubling it), `--` line comments,\n * and `/* *\\/` block comments. Replaced with a space before tokenizing, so what is\n * left is code.\n *\n * Backtick-quoted names are NOT here: MySQL-compatible quoting produces an\n * identifier, exactly as the double-quoted form does.\n */\nconst NOT_CODE = /'(?:[^']|'')*'|--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g;\n\n/**\n * ← `SqlStorageRegulator` (`sql.h:15-22`, `sql.c++:143-173`), whole.\n *\n * Upstream reaches these through the SQLite authorizer while a statement is\n * being compiled. `exec` calls them from the statement text instead, which is\n * the same translation Section 3 made for the write classifier and for\n * transaction state.\n */\nexport const SqlStorageRegulator = {\n /**\n * Upstream's body is `return !name.startsWith(\"_cf_\")`, with an autogate that\n * makes the comparison case-insensitive and logs a warning until it lands. The\n * case-insensitive form is taken here: it is the direction upstream is moving,\n * and there is no logger for the warning half.\n */\n isAllowedName(name: string): boolean {\n return name.length < 4 || name.slice(0, 4).toLowerCase() !== \"_cf_\";\n },\n\n /** Upstream's body is `return true`. */\n isAllowedTrigger(_name: string): boolean {\n return true;\n },\n\n /** Upstream's body is a `JSG_FAIL_REQUIRE` with this message. */\n allowTransactions(): never {\n throw new Error(SQL_TRANSACTION_REFUSED_MESSAGE);\n },\n\n /** \"Bill for queries executed from JavaScript.\" Nothing reads it — `SqliteObserver` has no port. */\n shouldAddQueryStats(): boolean {\n return true;\n },\n};\n\n/**\n * The text-level stand-in for the authorizer's `isAllowedName` calls — see\n * `SQL_RESERVED_PREFIX_MESSAGE` and the README row.\n *\n * Upstream refuses a *resolved identifier* that starts with `_cf_`, because it\n * reaches `isAllowedName` through the SQLite authorizer while the statement is\n * being compiled. There is no authorizer here, so this tokenizes the statement\n * text instead, over everything that is not a string literal or a comment —\n * which is the same set of characters an identifier can come from.\n *\n * **The literals were once refused too, and that was wrong.** The first draft\n * scanned the whole statement on the reasoning that no legitimate consumer\n * statement contains the token, so being stricter than upstream was the safe\n * direction. A retained conformance case uses `_cf_keepAliveHeartbeat` as a\n * bound value: real workerd accepts it, so this parser must distinguish data\n * from identifiers. `conformance/suite/sql.spec.ts` pins the rule: refused as a\n * table name and as a quoted identifier, allowed as data.\n *\n * A name that merely CONTAINS the token — `my_cf_thing` — stays allowed, because\n * `isAllowedName` tests a prefix.\n */\nfunction requireAllowedNames(query: string): void {\n if (!RESERVED_PREFIX_HINT.test(query)) return;\n const code = query.replace(NOT_CODE, \" \");\n for (const [token] of code.matchAll(IDENTIFIER)) {\n if (!SqlStorageRegulator.isAllowedName(token)) throw new Error(SQL_RESERVED_PREFIX_MESSAGE);\n }\n}\n\n/** Refuse transaction control against one SQLite-decided statement boundary. */\nfunction refuseTransactionControl(statement: string): void {\n const code = statement.replace(NOT_CODE, \" \");\n if (TRANSACTION_CONTROL.test(code)) SqlStorageRegulator.allowTransactions();\n}\n\n/**\n * ← the `jsg::Ref<DurableObjectStorage>` `SqlStorage` holds, narrowed to the one\n * member it reaches through (`SqlStorage::getDb`). `DurableObjectStorage`\n * satisfies it; narrowing is what keeps this file free of a value-level import\n * cycle, which upstream tolerates because C++ headers do not have one.\n */\nexport interface SqlStorageOwner {\n /** ← `DurableObjectStorage::getSqliteDb`. Throws if not SQLite-backed. */\n getSqliteDb(): SqliteDatabase;\n}\n\n/** The rows a cursor walks, plus the counters that outlive them. */\ntype CursorState = {\n readonly columnNames: string[];\n readonly rawRows: readonly (readonly SqlStorageValue[])[];\n readonly rowsWritten: number;\n};\n\n/**\n * ← `SqlStorage::Cursor`.\n *\n * `rowsRead` is the one counter that is not upstream's. Upstream reads\n * `Query::getRowsRead()`, a billing counter sourced from libsql's\n * `STMTSTATUS_ROWS_READ` that counts index rows and that neither backend\n * exposes — the same absence the README already records for `SqlResult`. The\n * interface requires a number, so this returns the rows the cursor has yielded,\n * which is what today's browser host returns and what its tests assert. It\n * undercounts any query that scans more rows than it returns.\n */\nexport class Cursor<T extends SqlRow = SqlRow> implements SqlStorageCursor<T> {\n readonly columnNames: string[];\n readonly #rawRows: readonly (readonly SqlStorageValue[])[];\n readonly #rowsWritten: number;\n #position = 0;\n\n constructor(state?: CursorState) {\n if (state === undefined) throw new Error(CURSOR_NOT_CONSTRUCTIBLE_MESSAGE);\n this.columnNames = state.columnNames;\n this.#rawRows = state.rawRows;\n this.#rowsWritten = state.rowsWritten;\n }\n\n /** ← `Cursor::next`, whose `RowIterator::Next` is this exact shape. */\n next(): { done?: false; value: T } | { done: true; value?: never } {\n const row = this.#nextRow();\n if (row === undefined) return { done: true };\n return { done: false, value: row };\n }\n\n /** ← `Cursor::toArray`, which drains from the current position. */\n toArray(): T[] {\n const rows: T[] = [];\n for (;;) {\n const row = this.#nextRow();\n if (row === undefined) return rows;\n rows.push(row);\n }\n }\n\n /** ← `Cursor::one`. Both messages are upstream's, verbatim. */\n one(): T {\n const row = this.#nextRow();\n if (row === undefined) {\n throw new Error(\"Expected exactly one result from SQL query, but got no results.\");\n }\n if (this.#position < this.#rawRows.length) {\n // Upstream drops the query here before throwing, so the statement cannot be reused.\n this.#position = this.#rawRows.length;\n throw new Error(\"Expected exactly one result from SQL query, but got multiple results.\");\n }\n return row;\n }\n\n /** ← `Cursor::raw`, which shares this cursor's position rather than restarting. */\n raw<U extends SqlStorageValue[]>(): IterableIterator<U> {\n const iterator: IterableIterator<U> = {\n [Symbol.iterator](): IterableIterator<U> {\n return iterator;\n },\n next: (): IteratorResult<U> => {\n const raw = this.#nextRaw();\n if (raw === undefined) return { done: true, value: undefined };\n const values: SqlStorageValue[] = [...raw];\n return { done: false, value: asRawRow<U>(values) };\n },\n };\n return iterator;\n }\n\n /** ← `JSG_ITERABLE(rows)`. */\n [Symbol.iterator](): IterableIterator<T> {\n const iterator: IterableIterator<T> = {\n [Symbol.iterator](): IterableIterator<T> {\n return iterator;\n },\n next: (): IteratorResult<T> => {\n const row = this.#nextRow();\n if (row === undefined) return { done: true, value: undefined };\n return { done: false, value: row };\n },\n };\n return iterator;\n }\n\n get rowsRead(): number {\n return this.#position;\n }\n\n /** ← `Cursor::getRowsWritten`, which is `SqlResult.rowsWritten` here. */\n get rowsWritten(): number {\n return this.#rowsWritten;\n }\n\n #nextRaw(): readonly SqlStorageValue[] | undefined {\n const raw = this.#rawRows[this.#position];\n if (raw === undefined) return undefined;\n this.#position += 1;\n return raw;\n }\n\n /** ← `Cursor::rowIteratorNext`: zip the column names onto the row. */\n #nextRow(): T | undefined {\n const raw = this.#nextRaw();\n if (raw === undefined) return undefined;\n const row: SqlRow = {};\n this.columnNames.forEach((name, index) => {\n row[name] = raw[index] ?? null;\n });\n return asRow<T>(row);\n }\n}\n\n/**\n * ← `SqlStorage::Statement`, which upstream describes as \"supported only for\n * backwards compatibility ... it is actually just a wrapper around `exec()`\".\n * `JSG_CALLABLE(run)` makes the object itself callable, so `prepare()` returns a\n * function wearing this prototype rather than an object with a `run` method.\n */\nexport class Statement {\n constructor() {\n throw new Error(STATEMENT_NOT_CONSTRUCTIBLE_MESSAGE);\n }\n}\n\n/** What `prepare()` hands back: `Statement::run`, reachable by calling it. */\nexport interface PreparedStatement {\n <T extends SqlRow = SqlRow>(...bindings: BindingValue[]): Cursor<T>;\n}\n\nexport class SqlStorage implements globalThis.SqlStorage {\n readonly #ctx: IoContext;\n readonly #owner: SqlStorageOwner;\n /** ← `kj::Maybe<uint> pageSize`, memoized for the same reason. */\n #pageSize: number | undefined;\n\n constructor(ctx: IoContext, owner: SqlStorageOwner) {\n this.#ctx = ctx;\n this.#owner = owner;\n }\n\n /** ← `JSG_NESTED_TYPE(Cursor)`. Exposed so `instanceof` works, as upstream's is. */\n readonly Cursor = Cursor;\n /** ← `JSG_NESTED_TYPE(Statement)`. */\n readonly Statement = Statement;\n\n exec<T extends SqlRow = SqlRow>(query: string, ...bindings: BindingValue[]): Cursor<T> {\n requireInputLock(this.#ctx, \"sql.exec()\");\n const db = this.#owner.getSqliteDb();\n const sqlBindings = bindings.map(toSqlBindingValue);\n\n // Name checks stay a preflight because the backend cannot return a compiled\n // statement for a missing reserved table. This text-level check is the\n // deliberately stricter authorizer substitute documented above.\n requireAllowedNames(query);\n\n // The backend supplies the same statement boundary SQLite compiled. That is\n // load-bearing for CREATE TRIGGER, whose body legitimately contains semicolons.\n const result = db.run({ regulate: refuseTransactionControl }, query, ...sqlBindings);\n return new Cursor<T>({\n columnNames: [...result.columnNames],\n rawRows: result.rawRows.map((row) => row.map(toSqlStorageValue)),\n rowsWritten: result.rowsWritten,\n });\n }\n\n /**\n * ← `SqlStorage::getDatabaseSize`.\n *\n * Upstream's second query is `PRAGMA page_size;`, which `sqlite3_stmt_readonly()`\n * reports read-only. With no such call the text is the only source and §1.7.1's\n * rule is write-unless-provably-a-read, so a bare `PRAGMA` would open a\n * transaction and take an output-gate lock to answer a size question. The\n * `pragma_page_size` table-valued function is the same value read through the\n * `SELECT` upstream already uses for the page count.\n */\n get databaseSize(): number {\n requireInputLock(this.#ctx, \"sql.databaseSize\");\n const db = this.#owner.getSqliteDb();\n const pages = db.run(\n \"select (select * from pragma_page_count) - (select * from pragma_freelist_count);\",\n );\n return readNumber(pages, \"page count\") * this.#getPageSize(db);\n }\n\n /** ← `SqlStorage::prepare`. Experimental and deprecated upstream; `exec` caches for you. */\n prepare(query: string): PreparedStatement {\n requireInputLock(this.#ctx, \"sql.prepare()\");\n const run = <T extends SqlRow = SqlRow>(...bindings: BindingValue[]): Cursor<T> =>\n this.exec<T>(query, ...bindings);\n Object.setPrototypeOf(run, Statement.prototype);\n return run;\n }\n\n /** ← `SqlStorage::ingest`. */\n ingest(query: string): SqlStorageIngestResult {\n requireInputLock(this.#ctx, \"sql.ingest()\");\n requireAllowedNames(query);\n return this.#owner.getSqliteDb().ingest(query, refuseTransactionControl);\n }\n\n /** ← `SqlStorage::setMaxPageCountForTest`, which is what its name says. */\n setMaxPageCountForTest(count: number): void {\n requireInputLock(this.#ctx, \"sql.setMaxPageCountForTest()\");\n this.#owner.getSqliteDb().run(`PRAGMA max_page_count = ${count}`);\n }\n\n /** ← `SqlStorage::getPageSize`. */\n #getPageSize(db: SqliteDatabase): number {\n const cached = this.#pageSize;\n if (cached !== undefined) return cached;\n const size = readNumber(db.run(\"select * from pragma_page_size;\"), \"page size\");\n this.#pageSize = size;\n return size;\n }\n}\n\nfunction readNumber(result: { readonly rawRows: readonly (readonly unknown[])[] }, what: string): number {\n const value = result.rawRows[0]?.[0];\n if (typeof value === \"number\") return value;\n if (typeof value === \"bigint\") return Number(value);\n throw new Error(`Expected a number for the database's ${what}.`);\n}\n\n/** ← JSG's conversion from JavaScript arguments to `SqlStorage::BindingValue`. */\nfunction toSqlBindingValue(value: unknown): SqlValue {\n if (value === null || value === undefined) return null;\n if (typeof value === \"string\" || typeof value === \"number\") return value;\n if (typeof value === \"boolean\") return String(value);\n if (typeof value === \"bigint\") {\n throw new TypeError(\"Cannot convert a BigInt value to a number\");\n }\n if (value instanceof ArrayBuffer) return copyBytes(new Uint8Array(value));\n if (ArrayBuffer.isView(value)) {\n return copyBytes(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n }\n throw new TypeError(`Cannot convert ${Object.prototype.toString.call(value)} to a SQL value`);\n}\n\nfunction copyBytes(bytes: Uint8Array): Uint8Array {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy;\n}\n\n/**\n * ← `SqlStorage::wrapSqlValue` plus the `Query::getValue` switch above it.\n *\n * Upstream's int64 arm carries its own comment: \"int64 will become BigInt, but\n * most applications won't want all their integers to be BigInt. We will coerce\n * to a double here.\" That coercion is kept rather than refused, because it is\n * the documented behaviour of `sql.exec` and a caller storing an id larger than\n * 2^53 has already lost on workerd.\n */\nfunction toSqlStorageValue(value: unknown): SqlStorageValue {\n if (value === null || value === undefined) return null;\n if (typeof value === \"string\" || typeof value === \"number\") return value;\n if (typeof value === \"bigint\") return Number(value);\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value instanceof Uint8Array) {\n const copy = new ArrayBuffer(value.byteLength);\n new Uint8Array(copy).set(value);\n return copy;\n }\n throw new Error(`SQL returned a ${typeof value}, which is not a SqlStorageValue.`);\n}\n\n/**\n * The two narrowings a generic row type needs. `T` is the caller's claim about\n * the shape of a row SQLite produced at runtime, so no check can confirm it and\n * upstream does not try — its `Cursor<T>` is the same claim written in a\n * `JSG_TS_OVERRIDE`. Confined to these two functions so the claim is one place\n * rather than sprinkled through the cursor.\n */\nfunction asRow<T extends SqlRow>(row: SqlRow): T {\n return row as T;\n}\n\nfunction asRawRow<U extends SqlStorageValue[]>(values: SqlStorageValue[]): U {\n return values as U;\n}\n","/**\n * ← workerd `src/workerd/api/sync-kv.{h,c++}`\n *\n * \"Synchronous KV storage. Available as ctx.storage.kv on SQLite-backed DOs.\"\n *\n * This module is not in Section 5's brief and exists because\n * `DurableObjectStorage` cannot satisfy workers-types without it: the interface\n * declares `kv: SyncKvStorage` unconditionally, and §2.4's rule is that the\n * surface is verified by the type system rather than by a cast. It is also a\n * genuine part of the contract — a whole KV surface that skips the promise\n * wrapper, over the same `SqliteKv` `DurableObjectStorage` writes through, with\n * the same codec.\n *\n * Two things upstream has that are absent, both already absent below this file:\n * the trace spans every method opens, and the billing counters. What is kept is\n * the whole of the behaviour, including the one error that is neither of those:\n * a `list()` iterator invalidated by a second `list()` says so rather than\n * silently ending, which is `SqliteKv::ListCursor::wasCanceled()`.\n *\n * Spec: §2.4 in docs/decisions.md.\n */\n\nimport type { IoContext } from \"../io/io-context\";\nimport { requireInputLock } from \"../io/io-context\";\nimport type { SqliteKv, SqliteKvListCursor } from \"../util/sqlite-kv\";\nimport { compileListOptions, deserializeValue, serializeValue } from \"./actor-state\";\n\n/**\n * ← the `jsg::Ref<DurableObjectStorage>` `SyncKvStorage` holds, narrowed to the\n * one member it reaches through (`SyncKvStorage::getSqliteKv`).\n */\nexport interface SyncKvStorageOwner {\n getSqliteKv(): SqliteKv;\n}\n\n/** ← `SyncKvStorage::ListOptions`, which is `ListOptions` minus the two gate flags. */\nexport type SyncKvListOptions = {\n start?: string;\n startAfter?: string;\n end?: string;\n prefix?: string;\n reverse?: boolean;\n limit?: number;\n};\n\nexport class SyncKvStorage implements globalThis.SyncKvStorage {\n readonly #ctx: IoContext;\n readonly #owner: SyncKvStorageOwner;\n\n constructor(ctx: IoContext, owner: SyncKvStorageOwner) {\n this.#ctx = ctx;\n this.#owner = owner;\n }\n\n get<T = unknown>(key: string): T | undefined {\n requireInputLock(this.#ctx, \"kv.get()\");\n const value = this.#owner.getSqliteKv().get(key);\n if (value === undefined) return undefined;\n return deserializeValue(key, value) as T;\n }\n\n /**\n * ← `SyncKvStorage::list`, which reuses `compileListOptions` — \"This is public\n * so that SyncKvStorage can reuse it.\"\n */\n list<T = unknown>(options?: SyncKvListOptions): Iterable<[string, T]> {\n requireInputLock(this.#ctx, \"kv.list()\");\n const compiled = compileListOptions(options);\n if (compiled === undefined) {\n // Key range is empty. Upstream allocates a cursor over a null query for exactly this.\n return { [Symbol.iterator]: () => emptyIterator<T>() };\n }\n\n const cursor = this.#owner\n .getSqliteKv()\n .list(compiled.start, compiled.end, compiled.limit, compiled.reverse ? \"REVERSE\" : \"FORWARD\");\n return { [Symbol.iterator]: () => listIterator<T>(cursor) };\n }\n\n put<T>(key: string, value: T): void {\n requireInputLock(this.#ctx, \"kv.put()\");\n this.#owner.getSqliteKv().put(key, serializeValue(key, value));\n }\n\n delete(key: string): boolean {\n requireInputLock(this.#ctx, \"kv.delete()\");\n return this.#owner.getSqliteKv().delete(key);\n }\n}\n\n/** ← `SyncKvStorage::listNext`, whose cancellation branch is the reason it is not a plain loop. */\nfunction listIterator<T>(cursor: SqliteKvListCursor): IterableIterator<[string, T]> {\n const iterator: IterableIterator<[string, T]> = {\n [Symbol.iterator]: () => iterator,\n next: (): IteratorResult<[string, T]> => {\n const pair = cursor.next();\n if (pair !== undefined) {\n return { done: false, value: [pair.key, deserializeValue(pair.key, pair.value) as T] };\n }\n if (cursor.wasCanceled()) {\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 return { done: true, value: undefined };\n },\n };\n return iterator;\n}\n\nfunction emptyIterator<T>(): IterableIterator<[string, T]> {\n const iterator: IterableIterator<[string, T]> = {\n [Symbol.iterator]: () => iterator,\n next: (): IteratorResult<[string, T]> => ({ done: true, value: undefined }),\n };\n return iterator;\n}\n","/**\n * ← workerd `src/workerd/api/actor-state.{h,c++}`\n *\n * The JS-facing storage objects: `DurableObjectStorageOperations` and its two\n * subclasses, `DurableObjectFacets`, and `DurableObjectState`. Everything below\n * this file is reached through one of them.\n *\n * **`DurableObjectStorage` satisfies workers-types with no cast (§2.4).** That\n * was checked rather than asserted, and two shapes here exist only because it\n * has to: `sql.Cursor` and `sql.Statement` must be constructible with no\n * arguments (see `sql.ts`), and `storage.kv` is required, which is why\n * `api/sync-kv.ts` exists at all. The narrowings that remain are all one thing —\n * `get<T>` returns the caller's claim about the shape of a value SQLite handed\n * back as bytes, which no check can confirm and which upstream states the same\n * way, as a `jsg::JsRef<jsg::JsValue>` behind a `JSG_TS_OVERRIDE`'d\n * `Promise<T>`. There is no `as unknown as` anywhere in this layer.\n *\n * **Every throw is synchronous, including from the promise-returning methods.**\n * That is upstream's: a `JSG_REQUIRE` inside a method returning `jsg::Promise`\n * throws into the isolate before the promise exists, so `put(k, undefined)`\n * throws rather than rejecting. The same goes for a value that will not decode,\n * because §1.4 makes the SQLite path take `transformCacheResult`'s value arm and\n * run the decoder synchronously.\n *\n * **What the input gate does and does not do here.** Every entry point calls\n * `requireInputLock` — see its comment in `io/io-context.ts`, which is the one\n * place this package decides what an empty invocation stack means. Nothing else\n * takes a lock: a read returns a value, a write returns a resolved promise, and\n * `atCheckpointEnd` is what keeps the whole chain inside one transaction\n * (§1.7.1). The two exceptions are upstream's own — `sync()` and the bookmark\n * pair release the gate via `awaitIo`, and `transaction()` takes a critical\n * section.\n *\n * **Decision 2's branch has one reachable site**, and it is not where upstream's\n * is. `transformCacheResult` branches on `allowConcurrency` because upstream's\n * `ActorCacheOps` returns `kj::OneOf<T, kj::Promise<T>>`; §1.4 measures that the\n * SQLite arm is always the immediate one, so Section 4 collapsed the `OneOf` and\n * the branch has nothing to select between. `transformMaybeBackpressure` keeps\n * it, because `DeleteAllResults.backpressure` is still a promise in\n * `io/actor-cache.ts`. Both helpers are kept under upstream's names so the\n * question \"where did `allowConcurrency` go\" is answered by reading them.\n *\n * Not ported, because the substrate has no equivalent: Hibernatable WebSockets,\n * which is the whole reason `DurableObjectState`'s eight WebSocket methods are\n * named throwing stubs; V8's private wire bytes, replaced by a browser-safe\n * structured-clone encoding with the same public value semantics; the billing\n * counters\n * (`billingUnits`, `ActorObserver`, `updateStorageWriteUnit`) and the trace\n * spans, both already absent throughout; `enableSql`, a workerd namespace option\n * that exists to simulate a non-SQLite Durable Object; and `ReplicaActorOutgoingFactory`,\n * whose replication half is a named boundary in `io/actor-cache.ts`.\n *\n * Spec: §1.4, §1.5, §1.10, §2.4, §2.5, decisions 2, 4 and 14 in\n * docs/decisions.md.\n */\n\nimport {\n deserialize as deserializeStructuredClone,\n serialize as serializeStructuredClone,\n} from \"@ungap/structured-clone\";\nimport type {\n ActorCacheInterface,\n ActorCacheOps,\n ActorCacheTransaction,\n GetResultList,\n ReadOptions,\n WriteOptions,\n} from \"../io/actor-cache\";\nimport type { IoContext } from \"../io/io-context\";\nimport { requireInputLock, setUserErrorDetail } from \"../io/io-context\";\nimport type { FacetManager, FacetStartInfo } from \"../io/worker\";\nimport type { SqliteKv } from \"../util/sqlite-kv\";\nimport type { SqliteDatabase } from \"../util/sqlite\";\nimport { DurableObjectClass } from \"./actor\";\nimport { LoopbackColoLocalActorNamespace, LoopbackDurableObjectNamespace } from \"./export-loopback\";\nimport type { ActorScopeBindings } from \"./global-scope\";\nimport { SqlStorage } from \"./sql\";\nimport { SyncKvStorage } from \"./sync-kv\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← `MAX_FACET_NAME_LENGTH` / `MAX_FACET_TREE_DEPTH`\n * (`actor-state.c++:943,947`), in the anonymous namespace beside the facet code\n * that enforces them. The scaffolding had them in `server/`, which is neither\n * where upstream puts them nor where they are checked.\n */\nexport const FACET_NAME_MAX_LENGTH = 256;\n/** Root is at depth 0, so the deepest allowed facet is at depth 3. */\nexport const FACET_TREE_MAX_DEPTH = 4;\n\n/**\n * The substrate boundary named in the package README: Hibernatable WebSockets\n * exist so the platform can evict an actor while keeping its sockets open, and\n * Chrome exposes no equivalent lifecycle. Under this repo's fail-closed tenet\n * the throw IS the specified behaviour, which is why §2.5 orders the four\n * silent no-op stubs beside it replaced.\n */\nexport const HIBERNATION_UNIMPLEMENTED_MESSAGE =\n \"Hibernatable WebSockets are not available in this runtime: they exist so the platform can \" +\n \"evict a Durable Object while keeping its sockets open, and there is no equivalent lifecycle \" +\n \"to be faithful to.\";\n\n/**\n * ← what falls off the end of `DurableObjectFacets::get`'s class switch\n * (`actor-state.c++:1029-1043`).\n *\n * Upstream accepts three things as `FacetStartupOptions.class`: a bare\n * `DurableObjectClass`, a `LoopbackDurableObjectNamespace`, or a\n * `LoopbackColoLocalActorNamespace`, unwrapping the last two through\n * `getClass()`. All three are ported — the loopback pair by\n * `api/export-loopback.ts` — and `KJ_UNREACHABLE` is the fourth case there\n * because JSG has already refused anything else while unwrapping the\n * `kj::OneOf`. The check has to be written here because\n * `@cloudflare/workers-types` declares `interface DurableObjectClass<_T> {}`,\n * which every object satisfies, so nothing refuses it before the method body.\n */\nexport const FACET_CLASS_UNSUPPORTED_MESSAGE =\n \"facets.get() was given a class this runtime cannot resolve. `class` must be a \" +\n \"DurableObjectClass, a LoopbackDurableObjectNamespace or a LoopbackColoLocalActorNamespace — \" +\n \"which is what a ctx.exports entry for a Durable Object class is.\";\n\n/** ← `DurableObjectStorageOperations::OpName`. Named only where an error quotes them. */\nconst OP_GET = \"get()\";\nconst OP_GET_ALARM = \"getAlarm()\";\nconst OP_LIST = \"list()\";\nconst OP_PUT = \"put()\";\nconst OP_PUT_ALARM = \"setAlarm()\";\nconst OP_DELETE = \"delete()\";\nconst OP_DELETE_ALARM = \"deleteAlarm()\";\nconst OP_ROLLBACK = \"rollback()\";\n\n/** The key immediately after `k` in byte order is `k` plus this. */\nconst NULL_CHARACTER = \"\\u0000\";\n/** ← the `0xff` upstream strips from the tail of a prefix, in UTF-16 code units. */\nconst MAX_CODE_UNIT = 0xffff;\n\n// =======================================================================================\n// The value codec\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n/** A byte JSON could never begin with, `DO`, and the local codec version. */\nconst VALUE_CODEC_HEADER = new Uint8Array([0, 0x44, 0x4f, 1]);\n\n/**\n * ← `serializeV8Value`. The wire bytes differ because V8's serializer is not\n * available in browsers; the public structured-clone value semantics do not.\n * The short header keeps the new representation unambiguous while old JSON rows\n * remain readable.\n */\nexport function serializeValue(_key: string, value: unknown): Uint8Array {\n const body = textEncoder.encode(JSON.stringify(serializeStructuredClone(value)));\n const encoded = new Uint8Array(VALUE_CODEC_HEADER.byteLength + body.byteLength);\n encoded.set(VALUE_CODEC_HEADER);\n encoded.set(body, VALUE_CODEC_HEADER.byteLength);\n return encoded;\n}\n\n/**\n * ← `deserializeV8Value`.\n *\n * Upstream logs \"the key (to help find the data in the database if it hasn't\n * been deleted), the length of the value, and the first three bytes of the value\n * (which is just the v8-internal version header and the tag that indicates the\n * type of the value, but not its contents)\". Our four-byte header carries only\n * a marker and version for the same reason.\n */\nexport function deserializeValue(key: string, buffer: Uint8Array): unknown {\n if (buffer.byteLength === 0) {\n throw new Error(`unexpectedly empty value buffer; key = ${key}`);\n }\n try {\n const structured = VALUE_CODEC_HEADER.every((byte, index) => buffer[index] === byte);\n const bytes = structured ? buffer.subarray(VALUE_CODEC_HEADER.byteLength) : buffer;\n const parsed = JSON.parse(textDecoder.decode(bytes)) as unknown;\n return structured\n ? deserializeStructuredClone(parsed as ReturnType<typeof serializeStructuredClone>)\n : parsed;\n } catch (exception) {\n throw new Error(\n \"actor storage deserialization failed: failed to deserialize stored value; \" +\n `key = ${key}; size = ${buffer.byteLength}`,\n { cause: exception },\n );\n }\n}\n\n/** ← `deserializeMaybeV8Value`. */\nfunction deserializeMaybeValue(key: string, buffer: Uint8Array | undefined): unknown {\n return buffer === undefined ? undefined : deserializeValue(key, buffer);\n}\n\n// =======================================================================================\n// The option transforms\n\n/**\n * ← `transformCacheResult` and `transformCacheResultWithCacheStatus`\n * (`actor-state.c++:49-101`), with the arm that cannot happen removed.\n *\n * Upstream's body is a two-arm switch on `kj::OneOf<T, kj::Promise<T>>`, and the\n * `allowConcurrency` branch lives in the promise arm. §1.4 measures that a\n * SQLite-backed actor returns the immediate arm at every call site, so Section 4\n * collapsed the `OneOf` to `T` and there is no promise left to await — and\n * therefore no gate decision to make. The name is kept so a reader comparing the\n * two files finds the answer here rather than inferring an omission. The\n * `WithCacheStatus` variant differs only in a `cached` flag feeding billing\n * counters that have no port, so the two collapse to one function.\n */\nfunction transformCacheResult<T, R>(value: T, func: (value: T) => R): Promise<R> {\n return Promise.resolve(func(value));\n}\n\n/**\n * ← `transformMaybeBackpressure` (`actor-state.c++:103-119`). THIS is decision\n * 2's live site: `DeleteAllResults.backpressure` is still `Promise<void> |\n * undefined`, so the branch has something to select between.\n *\n * Upstream's own note, kept because it is the reason the flag is threaded here\n * at all: \"In practice `allowConcurrency` will have no effect on a backpressure\n * promise since backpressure blocks everything anyway, but we pass the option\n * through for consistency in case of future changes.\"\n */\nfunction transformMaybeBackpressure(\n ctx: IoContext,\n options: { readonly allowConcurrency?: boolean },\n maybeBackpressure: Promise<void> | undefined,\n): Promise<void> {\n if (maybeBackpressure === undefined) return Promise.resolve();\n if (options.allowConcurrency === true) return ctx.awaitIo(maybeBackpressure);\n return ctx.awaitIoWithInputLock(maybeBackpressure, () => {});\n}\n\n// =======================================================================================\n// compileListOptions\n\n/** ← `DurableObjectStorageOperations::CompiledListOptions`. */\nexport type CompiledListOptions = {\n readonly start: string;\n readonly end: string | undefined;\n readonly reverse: boolean;\n readonly limit: number | undefined;\n};\n\n/**\n * ← `DurableObjectStorageOperations::compileListOptions`\n * (`actor-state.c++:314-417`). Returns undefined if the list operation would\n * provably return no results. Public because `SyncKvStorage` reuses it, exactly\n * as upstream's comment says it must.\n *\n * Two translations. `startAfter` gains ONE null character where upstream's\n * `kj::String` gains two, because the second of upstream's is the terminator and\n * a JS string has none. And every comparison here is on UTF-16 code units where\n * upstream's is on UTF-8 bytes, while the range the database actually applies is\n * SQLite's `BINARY` collation over UTF-8 — the two orders agree for every key\n * outside the astral planes, and a key that mixes astral characters with a\n * prefix can land on the wrong side of a clamp this function computes.\n */\nexport function compileListOptions(\n options: DurableObjectListOptions | undefined,\n): CompiledListOptions | undefined {\n let start = \"\";\n let end: string | undefined;\n let reverse = false;\n let limit: number | undefined;\n\n if (options !== undefined) {\n if (options.start !== undefined) {\n if (options.startAfter !== undefined) {\n throw new TypeError(\"list() cannot be called with both start and startAfter values.\");\n }\n start = options.start;\n }\n if (options.startAfter !== undefined) {\n // Convert an exclusive startAfter into an inclusive start key, so the implementation below\n // does not have to handle both. ONE null character, not upstream's two: the second of\n // upstream's is `kj::String`'s terminator, and a JS string has none.\n start = options.startAfter + NULL_CHARACTER;\n }\n if (options.end !== undefined) end = options.end;\n if (options.reverse !== undefined) reverse = options.reverse;\n if (options.limit !== undefined) {\n if (!(options.limit > 0)) throw new TypeError(\"List limit must be positive.\");\n limit = options.limit;\n }\n\n const prefix = options.prefix;\n if (prefix !== undefined && prefix.length > 0) {\n // Let's clamp `start` and `end` to include only keys with the given prefix.\n if (start < prefix) {\n // `start` is before `prefix`, so listing should actually start at `prefix`.\n start = prefix;\n } else if (start.startsWith(prefix)) {\n // `start` is within the prefix, so need not be modified.\n } else {\n // `start` comes after the last value with the prefix, so there's no overlap.\n return undefined;\n }\n\n const keyAfterPrefix = firstKeyAfterPrefix(prefix);\n if (keyAfterPrefix === undefined) {\n // The prefix is a run of maximal code units, so it includes the entire key space through\n // the last possible key. Hence there is no end — but an end specified earlier still holds.\n } else if (end === undefined) {\n // We didn't have any end set, so use the end of the prefix range.\n end = keyAfterPrefix;\n } else if (end <= prefix) {\n // No keys could possibly match both the end and the prefix.\n return undefined;\n } else if (end.startsWith(prefix)) {\n // `end` is within the prefix, so need not be modified.\n } else {\n // `end` comes after all keys with the prefix, so stop at the end of the prefix.\n end = keyAfterPrefix;\n }\n }\n }\n\n if (end !== undefined && end <= start) {\n // Key range is empty.\n return undefined;\n }\n\n return { start, end, reverse, limit };\n}\n\n/**\n * ← the `keyAfterPrefix` vector: strip maximal trailing units, then increment.\n *\n * Returns undefined when the prefix is nothing but maximal units, which is\n * upstream's \"the prefix is a string of some number of 0xff bytes, so includes\n * the entire key space up through the last possible key\".\n */\nfunction firstKeyAfterPrefix(prefix: string): string | undefined {\n let head = prefix;\n while (head.length > 0 && head.charCodeAt(head.length - 1) === MAX_CODE_UNIT) {\n head = head.slice(0, -1);\n }\n if (head.length === 0) return undefined;\n return head.slice(0, -1) + String.fromCharCode(head.charCodeAt(head.length - 1) + 1);\n}\n\n// =======================================================================================\n// DurableObjectStorageOperations\n\n/**\n * ← `DurableObjectStorageOperations`. \"Common implementation of\n * DurableObjectStorage and DurableObjectTransaction. This class is designed to\n * be used as a mixin.\"\n */\nexport abstract class DurableObjectStorageOperations {\n protected readonly ctx: IoContext;\n\n constructor(ctx: IoContext) {\n this.ctx = ctx;\n }\n\n protected abstract getCache(op: string): ActorCacheOps;\n\n /** Whether to skip caching and allow concurrency on all operations. */\n protected useDirectIo(): boolean {\n return false;\n }\n\n /**\n * ← `configureOptions`. Both subclasses answer `useDirectIo()` false, so this\n * is the identity today; it is upstream's hook and the only place the two\n * flags are forced on.\n */\n protected configureOptions<T extends { allowConcurrency?: boolean; noCache?: boolean }>(\n options: T,\n ): T {\n if (!this.useDirectIo()) return options;\n return { ...options, allowConcurrency: true, noCache: true };\n }\n\n get<T = unknown>(key: string, options?: DurableObjectGetOptions): Promise<T | undefined>;\n get<T = unknown>(keys: string[], options?: DurableObjectGetOptions): Promise<Map<string, T>>;\n get<T = unknown>(\n keyOrKeys: string | string[],\n maybeOptions?: DurableObjectGetOptions,\n ): Promise<T | undefined> | Promise<Map<string, T>> {\n requireInputLock(this.ctx, OP_GET);\n const options = this.configureOptions({ ...maybeOptions });\n if (typeof keyOrKeys === \"string\") return this.#getOne<T>(keyOrKeys, options);\n return this.#getMultiple<T>(keyOrKeys, options);\n }\n\n getAlarm(maybeOptions?: DurableObjectGetAlarmOptions): Promise<number | null> {\n requireInputLock(this.ctx, OP_GET_ALARM);\n // Even if we do not have an alarm handler, we might once have had one. It's fine to return\n // whatever a previous alarm setting or a falsy result.\n const options = this.configureOptions({ ...maybeOptions, noCache: false });\n return transformCacheResult(this.getCache(OP_GET_ALARM).getAlarm(options), (date) => date);\n }\n\n list<T = unknown>(maybeOptions?: DurableObjectListOptions): Promise<Map<string, T>> {\n requireInputLock(this.ctx, OP_LIST);\n const compiled = compileListOptions(maybeOptions);\n if (compiled === undefined) return Promise.resolve(new Map<string, T>());\n\n const options = this.configureOptions({ ...maybeOptions });\n const cache = this.getCache(OP_LIST);\n const result = compiled.reverse\n ? cache.listReverse(compiled.start, compiled.end, compiled.limit, options)\n : cache.list(compiled.start, compiled.end, compiled.limit, options);\n return transformCacheResult(result, (rows) => listResultsToMap<T>(rows));\n }\n\n put<T>(key: string, value: T, options?: DurableObjectPutOptions): Promise<void>;\n put<T>(entries: Record<string, T>, options?: DurableObjectPutOptions): Promise<void>;\n put<T>(\n keyOrEntries: string | Record<string, T>,\n valueOrOptions?: T | DurableObjectPutOptions,\n maybeOptions?: DurableObjectPutOptions,\n ): Promise<void> {\n requireInputLock(this.ctx, OP_PUT);\n // The second parameter carries a value in one overload and the options bag in the other, and\n // which it is follows from the first — so the two narrowings below are the discrimination\n // upstream does with `optionsTypeHandler.tryUnwrap`, made by testing the parameter that\n // actually decides rather than the one that is ambiguous.\n if (typeof keyOrEntries === \"string\") {\n if (valueOrOptions === undefined) {\n throw new TypeError(\"put() called with undefined value.\");\n }\n return this.#putOne(\n keyOrEntries,\n valueOrOptions as T,\n this.configureOptions({ ...maybeOptions }),\n );\n }\n return this.#putMultiple(\n keyOrEntries,\n this.configureOptions({ ...(valueOrOptions as DurableObjectPutOptions | undefined) }),\n );\n }\n\n delete(key: string, options?: DurableObjectPutOptions): Promise<boolean>;\n delete(keys: string[], options?: DurableObjectPutOptions): Promise<number>;\n delete(\n keyOrKeys: string | string[],\n maybeOptions?: DurableObjectPutOptions,\n ): Promise<boolean> | Promise<number> {\n requireInputLock(this.ctx, OP_DELETE);\n const options = this.configureOptions({ ...maybeOptions });\n if (typeof keyOrKeys === \"string\") {\n return transformCacheResult(\n this.getCache(OP_DELETE).delete(keyOrKeys, options),\n (deleted) => deleted,\n );\n }\n return transformCacheResult(\n this.getCache(OP_DELETE).deleteMultiple(keyOrKeys, options),\n (count) => count,\n );\n }\n\n setAlarm(scheduledTime: number | Date, maybeOptions?: DurableObjectSetAlarmOptions): Promise<void> {\n requireInputLock(this.ctx, OP_PUT_ALARM);\n const when = scheduledTime instanceof Date ? scheduledTime.getTime() : scheduledTime;\n if (!(when > 0)) {\n throw new TypeError(\"setAlarm() cannot be called with an alarm time <= 0\");\n }\n\n // \"This doesn't check if we have an alarm handler per say. It checks if we have an initialized\n // (post-ctor) JS durable object with an alarm handler.\"\n this.ctx.getActorOrThrow().assertCanSetAlarm();\n\n const options = this.configureOptions({ ...maybeOptions, noCache: false });\n\n // \"We fudge times set in the past to Date.now() to ensure that any one user can't DDOS the\n // alarm polling system by putting dates far in the past and therefore getting sorted earlier by\n // the index. This also ensures uniqueness of alarm times (which is required for correctness).\"\n this.getCache(OP_PUT_ALARM).setAlarm(Math.max(when, this.ctx.now()), options);\n return Promise.resolve();\n }\n\n deleteAlarm(maybeOptions?: DurableObjectSetAlarmOptions): Promise<void> {\n requireInputLock(this.ctx, OP_DELETE_ALARM);\n // Even if we do not have an alarm handler, we might once have had one. It's fine to remove that\n // alarm or noop on the absence of one.\n const options = this.configureOptions({ ...maybeOptions, noCache: false });\n this.getCache(OP_DELETE_ALARM).setAlarm(null, options);\n return Promise.resolve();\n }\n\n #getOne<T>(key: string, options: ReadOptions): Promise<T | undefined> {\n const value = this.getCache(OP_GET).get(key, options);\n return transformCacheResult(value, (bytes) => deserializeMaybeValue(key, bytes) as T | undefined);\n }\n\n #getMultiple<T>(keys: string[], options: ReadOptions): Promise<Map<string, T>> {\n const result = this.getCache(OP_GET).getMultiple(keys, options);\n return transformCacheResult(result, (rows) => listResultsToMap<T>(rows));\n }\n\n #putOne<T>(key: string, value: T, options: WriteOptions): Promise<void> {\n this.getCache(OP_PUT).put(key, serializeValue(key, value), options);\n return Promise.resolve();\n }\n\n #putMultiple<T>(entries: Record<string, T>, options: WriteOptions): Promise<void> {\n const pairs: { key: string; value: Uint8Array }[] = [];\n for (const [key, value] of Object.entries(entries)) {\n // \"We silently drop fields with value=undefined in putMultiple. There aren't many good\n // options here, as deleting an undefined field is confusing, throwing could break otherwise\n // working code, and a stray undefined here or there is probably closer to what the user\n // desires.\"\n if (value === undefined) continue;\n pairs.push({ key, value: serializeValue(key, value) });\n }\n this.getCache(OP_PUT).putMultiple(pairs, options);\n return Promise.resolve();\n }\n}\n\n/** ← `listResultsToMap` and `getMultipleResultsToMap`, minus the billing halves. */\nfunction listResultsToMap<T>(rows: GetResultList): Map<string, T> {\n const map = new Map<string, T>();\n for (const entry of rows) {\n map.set(entry.key, deserializeValue(entry.key, entry.value) as T);\n }\n return map;\n}\n\n// =======================================================================================\n// DurableObjectStorage\n\n/**\n * The engine `DurableObjectStorage` drives.\n *\n * Upstream holds an `ActorCacheInterface` and reaches `getSqliteDatabase()` /\n * `getSqliteKv()` through it, both `kj::Maybe`s that are non-null exactly when\n * the actor is SQLite-backed — which here it always is. `transactionSync` is the\n * third member and is one layer lower than upstream's for the reason\n * `io/actor-sqlite.ts` records: the savepoint depth counter and `notifyWrite`\n * both live there, so this file's is a one-line forward the way\n * `blockConcurrencyWhile` already is.\n */\nexport type StorageCache = ActorCacheInterface & {\n getSqliteDatabase(): SqliteDatabase;\n getSqliteKv(): SqliteKv;\n transactionSync<T>(callback: () => T): T;\n};\n\nexport class DurableObjectStorage\n extends DurableObjectStorageOperations\n implements globalThis.DurableObjectStorage\n{\n readonly #cache: StorageCache;\n #sql: SqlStorage | undefined;\n #kv: SyncKvStorage | undefined;\n\n constructor(ctx: IoContext, cache: StorageCache) {\n super(ctx);\n this.#cache = cache;\n }\n\n /** ← `DurableObjectStorage::getActorCacheInterface`, which `DurableObjectState::abort` needs. */\n getActorCacheInterface(): StorageCache {\n return this.#cache;\n }\n\n /** ← `DurableObjectStorage::getSqliteDb`. Always SQLite-backed here; see the header. */\n getSqliteDb(): SqliteDatabase {\n return this.#cache.getSqliteDatabase();\n }\n\n /** ← `DurableObjectStorage::getSqliteKv`. */\n getSqliteKv(): SqliteKv {\n return this.#cache.getSqliteKv();\n }\n\n protected override getCache(): ActorCacheOps {\n return this.#cache;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(sql, getSql)`. */\n get sql(): SqlStorage {\n this.#sql ??= new SqlStorage(this.ctx, this);\n return this.#sql;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(kv, getKv)`. */\n get kv(): SyncKvStorage {\n this.#kv ??= new SyncKvStorage(this.ctx, this);\n return this.#kv;\n }\n\n /**\n * ← `DurableObjectStorage::deleteAll`.\n *\n * `deleteAlarm` is upstream's `FeatureFlags::get(js).getDeleteAllDeletesAlarm()`,\n * a compatibility flag that exists so Workers published before it keep the old\n * behaviour. A runtime with no deployed history takes the current behaviour.\n */\n deleteAll(maybeOptions?: DurableObjectPutOptions): Promise<void> {\n requireInputLock(this.ctx, \"deleteAll()\");\n const options = this.configureOptions({ ...maybeOptions });\n const result = this.#cache.deleteAll(options, { deleteAlarm: true });\n return transformMaybeBackpressure(this.ctx, options, result.backpressure);\n }\n\n /**\n * ← `DurableObjectStorage::transaction`.\n *\n * The critical section is load bearing and upstream says why: \"the call to\n * `startTransaction()` is when the SQLite-backed implementation will actually\n * invoke `BEGIN TRANSACTION`, so it's important that we're inside the\n * blockConcurrencyWhile block before that point so we don't accidentally catch\n * some other asynchronous event in our transaction.\"\n *\n * The exception is packed into the result rather than thrown out of the\n * section, and then rethrown outside it. Upstream's reason: \"We don't actually\n * want to reset the object, we only want to roll back the transaction and\n * propagate the exception.\" A throw out of a critical section permanently\n * breaks the input gate (§1.5), so a failing transaction callback would\n * destroy the actor.\n */\n transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T> {\n requireInputLock(this.ctx, \"transaction()\");\n type TxnResult =\n | { readonly isError: false; readonly value: T }\n | { readonly isError: true; readonly exception: unknown };\n\n return this.ctx\n .blockConcurrencyWhile(async (): Promise<TxnResult> => {\n const txn = new DurableObjectTransaction(this.ctx, this.#cache.startTransaction());\n try {\n const value = await closure(txn);\n txn.maybeCommit();\n return { isError: false, value };\n } catch (exception) {\n txn.maybeRollback();\n return { isError: true, exception };\n }\n })\n .then((result) => {\n if (result.isError) throw result.exception;\n return result.value;\n });\n }\n\n /** ← `DurableObjectStorage::transactionSync`, a forward for the reason above. */\n transactionSync<T>(callback: () => T): T {\n requireInputLock(this.ctx, \"transactionSync()\");\n return this.#cache.transactionSync(callback);\n }\n\n /**\n * ← `DurableObjectStorage::sync`.\n *\n * Upstream's `awaitIo` rather than `awaitIoWithInputLock`, which is the one\n * storage method that deliberately opens the gate: \"we're merely checking if\n * we have any pending or in-flight operations, and providing a promise that\n * resolves when they succeed.\"\n */\n sync(): Promise<void> {\n requireInputLock(this.ctx, \"sync()\");\n return this.ctx.awaitIo(this.#cache.onNoPendingFlush());\n }\n\n /**\n * Real, not a boundary: `ActorSqlite`'s is \"an ersatz implementation that's\n * good enough for local dev with D1's Session API\", built on the metadata\n * table's local-development bookmark. Anything above this package that\n * surfaces it to an application should know it is a counter and not a\n * recovery point — as it is on workerd.\n */\n getCurrentBookmark(): Promise<string> {\n requireInputLock(this.ctx, \"getCurrentBookmark()\");\n return this.ctx.awaitIo(this.#cache.getCurrentBookmark());\n }\n\n waitForBookmark(bookmark: string): Promise<void> {\n requireInputLock(this.ctx, \"waitForBookmark()\");\n return this.ctx.awaitIo(this.#cache.waitForBookmark(bookmark));\n }\n\n /** Substrate boundary: point-in-time recovery. Upstream reaches the cache directly, as this does. */\n getBookmarkForTime(timestamp: number | Date): Promise<string> {\n return this.#cache.getBookmarkForTime(\n timestamp instanceof Date ? timestamp.getTime() : timestamp,\n );\n }\n\n /** Substrate boundary: point-in-time recovery. */\n onNextSessionRestoreBookmark(bookmark: string): Promise<string> {\n return this.#cache.onNextSessionRestoreBookmark(bookmark);\n }\n\n /** Substrate boundary: replication. */\n ensureReplicas(): void {\n this.#cache.ensureReplicas();\n }\n\n /** Substrate boundary: replication. */\n disableReplicas(): void {\n this.#cache.disableReplicas();\n }\n\n /**\n * ← `DurableObjectStorage::getPrimary` / `isReplica`. `maybePrimary` is set\n * only by the replica constructor, and nothing constructs a replica here, so\n * these answer upstream's own non-replica case rather than a stubbed one.\n */\n getPrimary(): undefined {\n return undefined;\n }\n\n isReplica(): boolean {\n return false;\n }\n}\n\n// =======================================================================================\n// DurableObjectTransaction\n\nexport class DurableObjectTransaction\n extends DurableObjectStorageOperations\n implements globalThis.DurableObjectTransaction\n{\n /** Becomes undefined when committed or rolled back. */\n #cacheTxn: ActorCacheTransaction | undefined;\n #rolledBack = false;\n\n constructor(ctx: IoContext, cacheTxn: ActorCacheTransaction) {\n super(ctx);\n this.#cacheTxn = cacheTxn;\n }\n\n protected override getCache(op: string): ActorCacheOps {\n if (this.#rolledBack) throw new Error(`Cannot ${op} on rolled back transaction`);\n const txn = this.#cacheTxn;\n if (txn === undefined) {\n throw new Error(\n `Cannot call ${op} on transaction that has already committed: ` +\n \"did you move `txn` outside of the closure?\",\n );\n }\n return txn;\n }\n\n /** Called from JS. */\n rollback(): void {\n if (this.#rolledBack) return; // allow multiple calls to rollback()\n this.getCache(OP_ROLLBACK); // just for the checks\n const txn = this.#cacheTxn;\n if (txn !== undefined) {\n txn.rollback();\n // ← the `IoContext::addWaitUntil(prom.attach(mv(cacheTxn)))`, whose attach is the\n // destruction Section 1 turned into an explicit drop.\n txn.drop();\n this.#cacheTxn = undefined;\n }\n this.#rolledBack = true;\n }\n\n /** Just throws an exception saying this isn't supported. */\n deleteAll(): never {\n throw new Error(\"Cannot call deleteAll() within a transaction\");\n }\n\n /**\n * Called from the runtime, not JS, after the transaction callback has\n * completed. Does nothing if the transaction is already committed or rolled\n * back. Synchronous, because `ActorCacheTransaction::commit` is (§1.4).\n */\n maybeCommit(): void {\n const txn = this.#cacheTxn;\n if (txn === undefined) return;\n this.#cacheTxn = undefined;\n txn.commit();\n txn.drop();\n }\n\n /** Same, for the failure path. Upstream's drops the transaction, whose destructor rolls back. */\n maybeRollback(): void {\n const txn = this.#cacheTxn;\n this.#cacheTxn = undefined;\n this.#rolledBack = true;\n txn?.drop();\n }\n}\n\n// =======================================================================================\n// DurableObjectFacets\n\n/**\n * ← `requireValidFacetName` (`actor-state.c++:949-952`).\n *\n * The comparison is `name.size()` on a `kj::StringPtr`, which is **UTF-8 bytes**,\n * so it is measured in bytes here too — the same `TextEncoder` pass, for the same\n * reason, that `ColoLocalActorNamespace.get`'s `[1, 2048]` bound already costs.\n * Comparing `name.length` accepts a 256-character non-ASCII name that upstream\n * refuses, which is a bound a caller can hit.\n */\nfunction requireValidFacetName(name: string): void {\n if (textEncoder.encode(name).length > FACET_NAME_MAX_LENGTH) {\n throw new TypeError(`Facet name is too long (max ${FACET_NAME_MAX_LENGTH} characters).`);\n }\n}\n\n/**\n * ← the `KJ_SWITCH_ONEOF(options.$class)` lambda (`actor-state.c++:1029-1043`).\n *\n * Three arms, and the order matters for the same reason it does upstream: a\n * `LoopbackDurableObjectClass` *is* a `DurableObjectClass`, so it takes the bare\n * arm here exactly as JSG's `kj::OneOf` unwraps it into the first alternative.\n * The two loopback namespaces are not classes and carry one, which `getClass()`\n * hands back.\n *\n * A `ctx.exports` entry is the callable façade `api/export-loopback.ts` produces\n * rather than the instance itself, and every check below is an `instanceof` that\n * the façade's `getPrototypeOf` answers — which is why that trap exists.\n */\nfunction requireFacetClass(actorClass: unknown): DurableObjectClass {\n if (actorClass instanceof DurableObjectClass) return actorClass;\n if (actorClass instanceof LoopbackDurableObjectNamespace) return actorClass.getClass();\n if (actorClass instanceof LoopbackColoLocalActorNamespace) return actorClass.getClass();\n throw new TypeError(FACET_CLASS_UNSUPPORTED_MESSAGE);\n}\n\n/**\n * ← `DurableObjectFacets`.\n *\n * **`clone` is the fourth method, and the vendored C++ snapshot does not have\n * it.** The design record cites `actor-state.h:431-497` and\n * `server.c++:721-749`; neither line range contains it, `DurableObjectFacets`\n * there exposes exactly `get`, `abort` and `delete`, and\n * `Worker::Actor::FacetManager` has exactly `getDepth`, `getFacet`, `abortFacet`\n * and `deleteFacet`. It is real all the same: `@cloudflare/workers-types`\n * 4.20260702.1 — a month newer than the snapshot — declares\n * `clone(src: string, dst: string): void` on `DurableObjectFacets`. So the\n * signature comes from the types and the semantics from §1.10 (abort dst, delete\n * dst storage, recursive copy of the src subtree), and the orchestration is\n * `server/`'s `cloneFacet`. There is nothing upstream to check the body against,\n * which makes it the one method here with no reference — worth knowing when it\n * is wrong.\n */\nexport class DurableObjectFacets implements globalThis.DurableObjectFacets {\n readonly #ctx: IoContext;\n readonly #facetManager: FacetManager | undefined;\n readonly #parentId: string;\n\n constructor(ctx: IoContext, facetManager: FacetManager | undefined, parentId: string) {\n this.#ctx = ctx;\n this.#facetManager = facetManager;\n this.#parentId = parentId;\n }\n\n /**\n * Get a facet by name, starting it if it isn't already running.\n * `getStartupOptions` is invoked only if the facet wasn't already running.\n *\n * Returns a `Fetcher` instead of a `DurableObject` because the returned stub\n * does not have the `id` or `name` methods that a DO stub normally has.\n */\n get<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name: string,\n getStartupOptions: () => FacetStartupOptions<T> | Promise<FacetStartupOptions<T>>,\n ): Fetcher<T> {\n requireValidFacetName(name);\n const facetManager = this.#getFacetManager();\n\n if (facetManager.getDepth() + 1 >= FACET_TREE_MAX_DEPTH) {\n throw new Error(\n \"Facet nesting depth limit exceeded. The maximum depth including the root Durable \" +\n `Object is ${FACET_TREE_MAX_DEPTH}.`,\n );\n }\n\n // Where upstream reads `IoContext::current()`, which is after both checks above.\n requireInputLock(this.#ctx, \"facets.get()\");\n\n // ← `ioCtx.makeReentryCallback(...)` (`actor-state.c++:1011`), which is decision 13: without\n // it a facet started from inside blockConcurrencyWhile() would queue behind the section that\n // is waiting for it.\n const getStartInfo = this.#ctx.makeReentryCallback(async (): Promise<FacetStartInfo> => {\n const options = await getStartupOptions();\n const id = options.id;\n return {\n // ← `actorClass.getChannel(ioCtx)` (`actor-state.c++:1045`).\n actorClass: requireFacetClass(options.class).getChannel(),\n // Child inherits parent ID.\n id: id === undefined ? this.#parentId : typeof id === \"string\" ? id : id.toString(),\n };\n });\n\n return facetManager.getFacet<T>(name, getStartInfo);\n }\n\n abort(name: string, reason: unknown): void {\n requireValidFacetName(name);\n this.#getFacetManager().abortFacet(name, reason);\n }\n\n delete(name: string): void {\n requireValidFacetName(name);\n this.#getFacetManager().deleteFacet(name);\n }\n\n clone(src: string, dst: string): void {\n requireValidFacetName(src);\n requireValidFacetName(dst);\n this.#getFacetManager().cloneFacet(src, dst);\n }\n\n #getFacetManager(): FacetManager {\n const facetManager = this.#facetManager;\n if (facetManager === undefined) {\n throw new Error(\"This Durable Object does not support creating facets.\");\n }\n return facetManager;\n }\n}\n\n// =======================================================================================\n// DurableObjectState\n\nexport type DurableObjectStateOptions = {\n id: DurableObjectId;\n /** The `ctx.exports` class registry. */\n exports: Record<string, unknown>;\n props: unknown;\n storage?: DurableObjectStorage;\n /** Absent for an actor whose host offers no facets, as upstream's `kj::Maybe` is. */\n facets?: FacetManager;\n /** ← `ActorVersion`, a deployment cohort with nothing to read it here. */\n version?: { cohort?: string };\n /**\n * This actor's `ServiceWorkerGlobalScope` half — the container's own\n * `globals`. Required, unlike `storage` and `facets`: a host that offers no\n * storage is a real posture upstream has, but an actor with no gated timers\n * is not, and the failure of a missing one is an ungated timer that WORKS\n * until a continuation after it touches storage. See\n * `DurableObjectState.globals`.\n */\n globals: ActorScopeBindings;\n};\n\n/** The type passed as the first parameter to a Durable Object class's constructor. */\nexport class DurableObjectState implements globalThis.DurableObjectState {\n readonly #ctx: IoContext;\n readonly #options: DurableObjectStateOptions;\n #facets: DurableObjectFacets | undefined;\n\n constructor(ctx: IoContext, options: DurableObjectStateOptions) {\n this.#ctx = ctx;\n this.#options = options;\n }\n\n get id(): DurableObjectId {\n return this.#options.id;\n }\n\n get props(): unknown {\n return this.#options.props;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(exports, getExports)`, behind `enableCtxExports` upstream. */\n get exports(): Record<string, unknown> {\n return this.#options.exports;\n }\n\n get version(): { cohort?: string } | undefined {\n return this.#options.version;\n }\n\n /**\n * NO upstream correspondence, because upstream needs none: a\n * `ServiceWorkerGlobalScope` IS the isolate's global object there, so an\n * actor's class reaches its gated `setTimeout` by writing `setTimeout`.\n *\n * Here one realm hosts several actors, so the names on `globalThis` can only\n * be bound to one of them and a continuation cannot be asked which one it\n * belongs to. `ctx` is the one reference every Durable Object class already\n * holds and that already means exactly one actor — the constructor was handed\n * it — so it is where the scope goes. An actor's method writes\n * `this.ctx.globals.setTimeout(…)`; a free function it calls takes the scope\n * as a parameter.\n *\n * `installActorScope` still exists and is still what a host uses for a\n * dynamically-loaded Worker source, which has no `ctx` to reach through and\n * its own module scope to destructure into. The two are the same object.\n */\n get globals(): ActorScopeBindings {\n return this.#options.globals;\n }\n\n get storage(): DurableObjectStorage {\n const storage = this.#options.storage;\n if (storage === undefined) {\n throw new Error(\"This Durable Object does not have storage.\");\n }\n return storage;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(facets, getFacets)`. */\n get facets(): DurableObjectFacets {\n this.#facets ??= new DurableObjectFacets(\n this.#ctx,\n this.#options.facets,\n this.#options.id.toString(),\n );\n return this.#facets;\n }\n\n waitUntil(promise: Promise<unknown>): void {\n this.#ctx.addWaitUntil(promise.then(() => {}));\n }\n\n /**\n * ← `DurableObjectState::blockConcurrencyWhile` (`actor-state.c++:1128-1131`),\n * which is a one-line forward and nothing else. The 30-second deadline, the\n * brokenness annotation and the never-settled promise on failure all live in\n * `IoContext::blockConcurrencyWhile`, which Section 2 already implements.\n *\n * Its precondition comes with it: `IoContext::blockConcurrencyWhile` calls\n * `getInputLock()`, which asserts, so this is reachable only from inside a\n * gated slice.\n */\n blockConcurrencyWhile<T>(callback: () => Promise<T>): Promise<T> {\n return this.#ctx.blockConcurrencyWhile(() => callback());\n }\n\n /**\n * ← `DurableObjectState::abort`. Reset the object, including breaking the\n * output gate and canceling any writes that haven't been committed yet.\n *\n * `js.terminateExecutionNow()` has no port — there is no isolate to terminate —\n * so the caller's own slice keeps running to its next await, where `IoContext`\n * refuses to re-enter.\n */\n abort(reason?: string): void {\n const description =\n reason === undefined\n ? \"broken.outputGateBroken; jsg.Error: Application called abort() to reset Durable Object.\"\n : `broken.outputGateBroken; jsg.Error: ${reason}`;\n const error = new Error(description);\n // ← `error.setDetail(jsg::EXCEPTION_IS_USER_ERROR, ...)` (`actor-state.c++:1143`). It is what\n // tells `isAlarmFailureUserError` that this reset was the application's doing, so an alarm\n // handler that aborts is retried a bounded number of times rather than forever.\n setUserErrorDetail(error);\n\n // \"Make sure we _synchronously_ break storage so that there's no chance our promise fulfilling\n // will race against the output gate, possibly allowing writes to complete before being\n // canceled.\"\n this.#options.storage?.getActorCacheInterface().shutdown(error);\n\n this.#ctx.abort(error);\n }\n\n /** ← `DurableObjectState::getPrimaryStub`. Non-null only for a replica; see the storage note. */\n get primaryStub(): undefined {\n return this.#options.storage?.getPrimary();\n }\n\n /** Substrate boundary: replication. */\n configureReadReplication(options: { mode: string }): Promise<void> {\n const storage = this.#options.storage;\n if (storage === undefined) {\n throw new TypeError(\"This actor does not support read replication.\");\n }\n if (storage.isReplica()) {\n throw new Error(\"Replica Durable Objects cannot call configureReadReplication().\");\n }\n if (options.mode !== \"auto\" && options.mode !== \"disabled\") {\n throw new TypeError(\n `configureReadReplication() called with unknown mode setting: ${options.mode}.`,\n );\n }\n return this.#ctx.awaitIo(\n storage.getActorCacheInterface().configureReadReplication(options.mode === \"auto\"),\n );\n }\n\n // -----------------------------------------------------------------\n // Hibernatable WebSockets — the substrate boundary. §2.5 orders the silent\n // no-op stubs replaced with throws, so all eight throw the same named message.\n\n acceptWebSocket(_ws: WebSocket, _tags?: string[]): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getWebSockets(_tag?: string): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n setWebSocketAutoResponse(_maybeReqResp?: WebSocketRequestResponsePair): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getWebSocketAutoResponse(): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getWebSocketAutoResponseTimestamp(_ws: WebSocket): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n setHibernatableWebSocketEventTimeout(_timeoutMs?: number): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getHibernatableWebSocketEventTimeout(): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getTags(_ws: WebSocket): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n}\n","/**\n * ← workerd `src/workerd/api/http.{h,c++}` — the gating, and nothing else.\n *\n * `http.c++` is 2,400 lines of `Request`, `Response`, `Headers`, `Body`,\n * `Fetcher` and the redirect machine. None of it is ported: the substrate ships\n * all of it, to the same specification, and re-implementing WHATWG Fetch over\n * `fetch` would be the feature-subset failure the porting philosophy describes,\n * with a much larger surface than the eighty lines it saves.\n *\n * What the substrate's copy cannot have is the half that is not in the spec at\n * all: **every asynchronous step of a fetch is an io-context operation**, so on\n * workerd the code after `await res.json()` resumes holding an input lock the\n * same way the code after `await fetch(…)` does. §1.3 is the whole of it —\n * `api/http.c++` contains ten `awaitIo(` calls and zero\n * `awaitIoWithInputLock`, so an outbound request releases the input gate and its\n * continuation re-takes one.\n *\n * A `Response` is where that matters and where it is easiest to miss. `fetch`\n * itself is one `awaitIo` in `api/global-scope.ts`, which is obvious; the body\n * is a SECOND await, arbitrarily later, and a raw `Response` would resolve it\n * from a promise this package does not own. The continuation would come back\n * with an empty invocation stack and the next `ctx.storage` call would throw —\n * divergence 147, arriving from a line that looks like it only parses JSON.\n *\n * Upstream reaches the same place by construction rather than by wrapping: a\n * `Response`'s body is an `IoOwn<ReadableStream>`, and `IoOwn` is precisely \"a\n * thing that may only be touched from inside its IoContext\"\n * (`io-context.h`'s `IoOwn`/`IoPtr`/`DeleteQueue` block). There is no such\n * ownership here — GC makes a cross-context dereference impossible in the way\n * that block guards against, which is why the package does not port it — so the\n * property it produced has to be produced by the wrapper below.\n *\n * Spec: §1.3 and decision 1 in\n * docs/decisions.md.\n */\n\n/**\n * The `Body` mixin's consuming methods (`http.h`'s `Body` resource type). Each\n * one reads the whole stream, so each one is an await that has to resume gated.\n *\n * `formData` is included even though nothing in this package's consumer calls\n * it: a subset here is a hole with no error, which is the one direction this\n * layer may not be wrong in.\n */\nconst BODY_CONSUMERS = [\"arrayBuffer\", \"blob\", \"bytes\", \"formData\", \"json\", \"text\"] as const;\n\ntype IoAwaiter = {\n awaitIo<T>(promise: Promise<T>): Promise<T>;\n};\n\n/**\n * Wrap a `Request` or `Response` so every asynchronous step of reading it\n * resumes inside a gated slice.\n *\n * A `Proxy` rather than a subclass, for a reason that is the substrate's rather\n * than a preference: `Response`'s internals are exotic, `new Response(res.body)`\n * would lose `status`, `url`, `redirected` and the header casing, and a class\n * that delegated every member by hand would silently stop covering whatever the\n * platform adds next. The trap covers what has to be covered and forwards the\n * rest to the real object, bound to it, so a member this file has never heard of\n * behaves exactly as the substrate's does.\n *\n * `clone()` is wrapped too. It returns a second body owner over a tee of the\n * same stream, and an unwrapped one would be the same hole one call further out.\n */\nfunction gateBody<T extends Request | Response>(ctx: IoAwaiter, value: T): T {\n const bound = new Map<string | symbol, unknown>();\n\n return new Proxy(value, {\n get(subject, property): unknown {\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n\n if (property === \"body\") {\n const body = subject.body;\n if (body === null) return null;\n const gated = gateReadableStream(ctx, body);\n bound.set(property, gated);\n return gated;\n }\n\n if (property === \"clone\") {\n const clone = (): T => gateBody(ctx, subject.clone() as T);\n bound.set(property, clone);\n return clone;\n }\n\n if ((BODY_CONSUMERS as readonly (string | symbol)[]).includes(property)) {\n const consume = (...args: unknown[]): Promise<unknown> =>\n ctx.awaitIo(\n (subject[property as (typeof BODY_CONSUMERS)[number]] as (...a: unknown[]) => Promise<unknown>).apply(\n subject,\n args,\n ),\n );\n bound.set(property, consume);\n return consume;\n }\n\n // `headers`, `status`, `ok` and friends are accessors on the prototype that read internal\n // slots, so they have to be read with the real object as the receiver rather than the proxy.\n // A method reached this way is bound for the same reason.\n const value: unknown = Reflect.get(subject, property, subject);\n if (typeof value === \"function\") {\n const method = (value as (...a: unknown[]) => unknown).bind(subject);\n bound.set(property, method);\n return method;\n }\n return value;\n },\n });\n}\n\n/** Wrap a host-provided request so consuming or streaming its body resumes gated. */\nexport function gateRequestBody(ctx: IoAwaiter, request: Request): Request {\n return gateBody(ctx, request);\n}\n\n/** Wrap an outbound response so consuming or streaming its body resumes gated. */\nexport function gateResponseBody(ctx: IoAwaiter, response: Response): Response {\n return gateBody(ctx, response);\n}\n\n/**\n * ← the same property one layer down: a body read through `getReader()` is a\n * sequence of awaits, so each `read()` is one.\n *\n * Only the default reader is covered. A BYOB reader is refused rather than\n * passed through ungated — see `BYOB_READER_UNGATABLE_MESSAGE`.\n */\nexport const BYOB_READER_UNGATABLE_MESSAGE =\n \"getReader({ mode: 'byob' }): a BYOB reader cannot be gated by this runtime, because \" +\n \"`ReadableStream.getReader` is the only seam it has and a byte stream's `read(view)` \" +\n \"returns the caller's own buffer. Read the body through `arrayBuffer()` or a default reader.\";\n\n// Instrument the native object itself. Chromium's `Response` constructor does not recognise a\n// `Proxy` around a `ReadableStream` as `BodyInit`; it stringifies the proxy instead.\nexport function gateReadableStream<T>(ctx: IoAwaiter, stream: ReadableStream<T>): ReadableStream<T> {\n const getReader = stream.getReader.bind(stream);\n const tee = stream.tee.bind(stream);\n\n Object.defineProperties(stream, {\n getReader: {\n configurable: true,\n writable: true,\n value(options?: { mode?: string }): unknown {\n // Fail closed. A byte reader whose `read(view)` this layer cannot intercept would hand\n // its continuation back ungated, which is the exact failure this module exists to\n // prevent, and it would do it silently.\n if (options?.mode === \"byob\") throw new Error(BYOB_READER_UNGATABLE_MESSAGE);\n return gateReader(ctx, getReader());\n },\n },\n // `tee()` splits into two streams; both are bodies and both get the same treatment.\n tee: {\n configurable: true,\n writable: true,\n value(): [ReadableStream<T>, ReadableStream<T>] {\n const [a, b] = tee();\n return [gateReadableStream(ctx, a), gateReadableStream(ctx, b)];\n },\n },\n });\n\n return stream;\n}\n\nfunction gateReader<T>(\n ctx: IoAwaiter,\n reader: ReadableStreamDefaultReader<T>,\n): ReadableStreamDefaultReader<T> {\n return new Proxy(reader, {\n get(subject, property): unknown {\n if (property === \"read\") {\n return (): Promise<ReadableStreamReadResult<T>> => ctx.awaitIo(subject.read());\n }\n const value: unknown = Reflect.get(subject, property, subject);\n return typeof value === \"function\"\n ? (value as (...a: unknown[]) => unknown).bind(subject)\n : value;\n },\n });\n}\n","/**\n * ← workerd `src/workerd/api/global-scope.{h,c++}` — the alarm half, and the\n * async-primitive half `ServiceWorkerGlobalScope` exposes to an application.\n *\n * The event surface (`fetch`/`scheduled`/`trace`/`queue` handlers) still has no\n * port: that belongs to layers this package does not have. What is here is the\n * other thing that class is, and the thing a Durable Object actually reaches —\n * `JSG_METHOD(setTimeout)`, `clearTimeout`, `setInterval`, `clearInterval`,\n * `JSG_METHOD(fetch)`, and `JSG_LAZY_INSTANCE_PROPERTY(scheduler, getScheduler)`\n * (`global-scope.h:776-808`). `Scheduler` itself is `api/basics.h:781-797`; it\n * is one class with one method and it lives beside its only exposure rather than\n * in a `api/basics.ts` that would hold nothing else, since everything else in\n * that file — `Event`, `EventTarget`, `AbortController`, `AbortSignal` — the\n * substrate already provides.\n *\n * **Why this file gained a half.** Workerd's globals hold no context: each one\n * reads `IoContext::current()` at call time (`global-scope.c++:944`, `:961`,\n * `:989`, `:1160`), because acquisition is structural and every entry into the\n * isolate has already taken the lock. There is no isolate hook here, so a\n * continuation that resumes from a promise the runtime does not own comes back\n * with an empty invocation stack and its next `ctx.storage` call throws `no\n * input lock available in this context`. Every host-provided async primitive\n * therefore has to gate itself, and this is where they do.\n *\n * The three primitives take three different mechanisms, and flattening them into\n * \"wrap it in awaitIo\" would be wrong three ways:\n *\n * - **Timers** capture the critical section at the ARMING call and re-enter\n * through `ctx.run(callback, cs)` when they fire. Not `awaitIo`, deliberately\n * — see `TimeoutManager` in `io/io-context.ts` for upstream's own reason.\n * - **`fetch`** is `awaitIo` (`http.c++` has ten of them and zero\n * `awaitIoWithInputLock`), preceded by an output-gate wait so nothing departs\n * ahead of the writes it might reveal (`http.c++:1488`). §1.3.\n * - **WebSocket** is neither: `api/web-socket.ts`, because a socket is a long\n * stream of events rather than one result.\n *\n * **The context is held, not looked up, and that is the whole of the\n * enforcement substitution.** One scope per actor. See `requireOwnSlice` for\n * what happens when a facet reaches a scope that is not its own.\n *\n * Spec: §1.2, §1.3, §1.8 and decisions 1 and 16 in\n * docs/decisions.md.\n */\n\nimport {\n hasUserErrorDetail,\n isExceptionFromInputGateBroken,\n tryCurrentSlice,\n type IoContext,\n} from \"../io/io-context\";\nimport { gateResponseBody } from \"./http\";\n\n/**\n * ← `AlarmInvocationInfo` (`api/global-scope.h:386-412`): \"a jsg::Object used to\n * pass alarm invocation info to an alarm handler.\"\n *\n * `scheduledTime` is already milliseconds here where upstream converts a\n * `kj::Date` to them at construction (`global-scope.h:390`), which is the same\n * unit `@cloudflare/workers-types` declares and the same one `setAlarm` takes.\n */\nexport class AlarmInvocationInfo implements globalThis.AlarmInvocationInfo {\n readonly scheduledTime: number;\n readonly retryCount: number;\n\n constructor(scheduledTime: number, retry: number) {\n this.scheduledTime = scheduledTime;\n this.retryCount = retry;\n }\n\n get isRetry(): boolean {\n return this.retryCount > 0;\n }\n}\n\n/**\n * ← `isAlarmFailureUserError` (`api/global-scope.c++:501-515`), whose own\n * comment lists the three arms: \"Returns true if an alarm failure should count\n * against the user's retry limit. A failure is user-generated if any of: the\n * exception was explicitly tagged with EXCEPTION_IS_USER_ERROR at construction\n * time (e.g. state.abort(), exceededCpu, exceededMemory, overload queue); the\n * exception originated from user code throwing inside blockConcurrencyWhile,\n * which breaks the input gate as a secondary side-effect; the exception is a\n * plain jsg.* error without broken.* or jsg-internal.* prefixes, meaning the\n * user's handler threw directly.\"\n *\n * The first two arms port exactly: this package writes both markers itself —\n * `DurableObjectState.abort()` sets the detail, and `IoContext` annotates a\n * broken input gate with upstream's own prefix.\n *\n * **The third arm has no input here, and its default is inverted deliberately.**\n * Upstream reads it off jsg's exception tunnelling: a `jsg.Error:` prefix that\n * is neither `jsg-internal.` nor a Durable Object reset means the user's handler\n * threw. There is no tunnelling in this runtime — an `Error` out of a handler\n * carries no provenance at all — so a plain exception is reported here as NOT a\n * user error, where upstream would report it as one.\n *\n * That inversion is narrower than it sounds, and it is the safe direction. The\n * caller is\n * `shouldRetryCountsAgainstLimits = !isOutputGateBroken() || isUserGeneratedError`\n * (`global-scope.c++:624`), so for an intact actor a handler failure counts\n * whatever this answers; the only case the two readings disagree on is a handler\n * failure that arrives together with a broken output gate. Upstream counts that\n * and eventually abandons the alarm. This does not, so the alarm outlives the\n * actor's reset and is retried after the restart — which is what\n * `!tunneled.isDurableObjectReset` (`:514`) is reaching for on the arm above it\n * and what the product ranking asks for outright. A default of \"user error\"\n * would abandon exactly the alarms that most need keeping.\n */\nexport function isAlarmFailureUserError(exception: unknown): boolean {\n if (hasUserErrorDetail(exception)) return true;\n if (isExceptionFromInputGateBroken(exception)) return true;\n return false;\n}\n\n// =======================================================================================\n// The async primitives an application reaches\n\n/** ← `Scheduler::WaitOptions` (`api/basics.h:775-778`). */\nexport type SchedulerWaitOptions = { signal?: AbortSignal };\n\n/**\n * ← `Scheduler` (`api/basics.h:781-797`), whose own comment is: \"The scheduler\n * class is an emerging web platform standard API that is meant to be global and\n * provides task scheduling APIs. We currently only implement a subset of the API\n * that is being defined.\"\n *\n * `wait` is \"essentially an awaitable alternative to setTimeout()\", and upstream\n * implements it as exactly that — `setTimeoutInternal` onto the same timeout\n * manager (`basics.c++:1007`), which is why it inherits the gating rather than\n * having any of its own.\n */\nexport class Scheduler {\n readonly #scope: ActorGlobalScope;\n\n constructor(scope: ActorGlobalScope) {\n this.#scope = scope;\n }\n\n /** ← `Scheduler::wait` (`basics.c++:989-1020`). */\n wait(delay: number, options?: SchedulerWaitOptions): Promise<void> {\n // ← the pre-check: an already-aborted signal rejects without arming anything.\n if (options?.signal?.aborted === true) {\n return Promise.reject(abortReasonOf(options.signal));\n }\n\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n let id: number;\n try {\n id = this.#scope.setTimeout(() => {\n resolve();\n }, delay);\n } catch (exception) {\n // The exception is unchanged; only its shape is. A method that returns a promise and\n // sometimes throws synchronously instead escapes the caller's `.catch` — the same reason\n // `IoContext.awaitIoWithInputLock` reshapes `getInputLock()`'s throw. The one thing that\n // can throw here is the foreign-slice refusal, and it must reach a caller that only wrote\n // `await scheduler.wait(…).catch(…)`.\n return Promise.reject(exception);\n }\n\n // ← the `signal` branch below `paf`: aborting clears the timeout and rejects.\n options?.signal?.addEventListener(\"abort\", () => {\n this.#scope.clearTimeout(id);\n reject(abortReasonOf(options.signal));\n });\n\n return promise;\n }\n\n /**\n * NO upstream correspondence: `scheduler.yield()` is the Prioritized Task\n * Scheduling API's, which workerd does not implement — `Scheduler` above has\n * exactly one `JSG_METHOD`. It is here because Chrome ships a `scheduler`\n * global in workers that DOES have `yield` and no `wait`, so a scope that\n * replaced Chrome's and dropped `yield` would break page-shaped code that a\n * Durable Object never runs but a shared worker global might. A zero-delay\n * gated timer is the closest honest reading and it keeps the lock property.\n */\n yield(): Promise<void> {\n return this.wait(0);\n }\n}\n\n/**\n * ← `SubtleCrypto` (`api/crypto.h`), whose every method is a `jsg::Promise`\n * built inside the isolate's `IoContext` — so on workerd a continuation after\n * `await crypto.subtle.digest(...)` holds the input lock, and nothing has to say\n * so.\n *\n * Here `globalThis.crypto` is the PLATFORM's, and its promise is one this\n * package does not own. The vendored `agents` package hashes inside a method\n * that then writes, so an ungated `digest` made every routine mutation throw at\n * its own `setState` — three frames below the await that lost the lock, with\n * nothing naming the cause. `conformance/suite/gates.spec.ts` is the row that\n * settles it against workerd.\n *\n * `getRandomValues` and `randomUUID` are NOT gated and are forwarded as they\n * are: both are synchronous, so there is no continuation to lose a lock.\n */\nclass GatedSubtleCrypto {\n readonly #requireOwnSlice: (op: string) => void;\n readonly #ctx: IoContext;\n readonly #subtle: SubtleCrypto;\n\n constructor(requireOwnSlice: (op: string) => void, ctx: IoContext, subtle: SubtleCrypto) {\n this.#requireOwnSlice = requireOwnSlice;\n this.#ctx = ctx;\n this.#subtle = subtle;\n }\n\n /**\n * Every asynchronous `SubtleCrypto` method, forwarded through `awaitIo`.\n *\n * Written as one generic hop rather than twelve near-identical methods,\n * because the shape is identical for all of them — the arguments are opaque to\n * this layer and the only thing added is the gate. `requireOwnSlice` runs\n * first for the reason `fetch` runs it: a facet that reached a parent's global\n * would resume under the wrong actor's gate.\n */\n #gated<K extends AsyncSubtleMethod>(method: K): SubtleCrypto[K] {\n const forward = (...args: unknown[]): Promise<unknown> => {\n try {\n this.#requireOwnSlice(`crypto.subtle.${method}`);\n } catch (exception) {\n // Reshaped rather than thrown, for `Scheduler.wait`'s reason: this returns a promise,\n // so a synchronous throw would escape the caller's `.catch`.\n return Promise.reject(exception);\n }\n const call = this.#subtle[method] as (...rest: unknown[]) => Promise<unknown>;\n return this.#ctx.awaitIo(call.apply(this.#subtle, args));\n };\n return forward as SubtleCrypto[K];\n }\n\n readonly decrypt = this.#gated(\"decrypt\");\n readonly deriveBits = this.#gated(\"deriveBits\");\n readonly deriveKey = this.#gated(\"deriveKey\");\n readonly digest = this.#gated(\"digest\");\n readonly encrypt = this.#gated(\"encrypt\");\n readonly exportKey = this.#gated(\"exportKey\");\n readonly generateKey = this.#gated(\"generateKey\");\n readonly importKey = this.#gated(\"importKey\");\n readonly sign = this.#gated(\"sign\");\n readonly unwrapKey = this.#gated(\"unwrapKey\");\n readonly verify = this.#gated(\"verify\");\n readonly wrapKey = this.#gated(\"wrapKey\");\n}\n\n/** Every `SubtleCrypto` member that returns a promise. */\ntype AsyncSubtleMethod = {\n [K in keyof SubtleCrypto]: SubtleCrypto[K] extends (...args: never[]) => Promise<unknown>\n ? K\n : never;\n}[keyof SubtleCrypto];\n\n/**\n * ← `ServiceWorkerGlobalScope`'s `crypto`. The synchronous members are the\n * platform's own; `subtle` is the gated one above.\n */\nclass GatedCrypto {\n readonly subtle: SubtleCrypto;\n readonly #crypto: Crypto;\n\n constructor(requireOwnSlice: (op: string) => void, ctx: IoContext, crypto: Crypto) {\n this.#crypto = crypto;\n this.subtle = new GatedSubtleCrypto(\n requireOwnSlice,\n ctx,\n crypto.subtle,\n ) as unknown as SubtleCrypto;\n }\n\n getRandomValues<T extends ArrayBufferView | null>(array: T): T {\n return this.#crypto.getRandomValues(array as never) as T;\n }\n\n randomUUID(): `${string}-${string}-${string}-${string}-${string}` {\n return this.#crypto.randomUUID();\n }\n}\n\n/** ← `s->getReason(js)`, which is what `Scheduler::wait` rejects with. */\nfunction abortReasonOf(signal: AbortSignal | undefined): unknown {\n return signal?.reason ?? new DOMException(\"The operation was aborted.\", \"AbortError\");\n}\n\n/** What the host supplies beneath `ServiceWorkerGlobalScope::fetch`. */\nexport type FetchPort = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type ActorGlobalScopeOptions = {\n /** Opaque identity of the external entry whose synchronous body is running. */\n readonly currentExternalEntry?: (() => object | undefined) | undefined;\n /**\n * The `Crypto` the gated one delegates to. Defaults to the realm's own, which\n * is what a host wants: unlike `fetch`, there is no per-actor outbound to\n * route this through — `SubtleCrypto` is pure computation, and the only thing\n * the actor's scope adds is the gate around its promise.\n */\n readonly crypto?: Crypto | undefined;\n /**\n * ← the global outbound `Fetcher` `ServiceWorkerGlobalScope::fetch` resolves\n * (`global-scope.c++:1160`). Absent means this actor has no ambient outbound,\n * which is upstream's `globalOutbound: null` posture (§1.11) — `fetch` then\n * refuses by name rather than reaching a `fetch` this package does not own.\n */\n readonly fetch?: FetchPort | undefined;\n};\n\n/** Thrown where `globalOutbound` is absent. Asserted rather than skipped, so it cannot drift. */\nexport const NO_GLOBAL_OUTBOUND_MESSAGE =\n \"fetch(): this actor has no global outbound, so an ambient fetch cannot be gated.\";\n\n/**\n * The message a scope answers with when it is reached from another actor's\n * slice. Exported because the failure it names is the one thing about this layer\n * that cannot be found by reading the calling code — see `requireOwnSlice`.\n */\nexport const FOREIGN_SLICE_MESSAGE =\n \"was reached from a different actor's slice. A facet that reads a global \" +\n \"instead of its own binding gets its parent's scope, and its continuation would resume \" +\n \"under the wrong actor's input gate.\";\n\n/**\n * ← `ServiceWorkerGlobalScope`, the async-primitive half. One per actor.\n *\n * A consumer installs this into whatever scope its actor's code reads —\n * `globalThis` for a class in the worker's own module graph, a module-scoped\n * binding for a class that arrived as a dynamically-loaded Worker source, which\n * is upstream's own arrangement (a dynamic Worker has its own global scope bound\n * to its own context, §1.11).\n */\nexport class ActorGlobalScope {\n readonly #ctx: IoContext;\n readonly #fetch: FetchPort | undefined;\n readonly #readCurrentExternalEntry: (() => object | undefined) | undefined;\n readonly scheduler: Scheduler;\n readonly crypto: GatedCrypto;\n\n constructor(ctx: IoContext, options: ActorGlobalScopeOptions = {}) {\n this.#ctx = ctx;\n this.#fetch = options.fetch;\n this.#readCurrentExternalEntry = options.currentExternalEntry;\n this.scheduler = new Scheduler(this);\n this.crypto = new GatedCrypto(\n (op) => {\n this.#requireOwnSlice(op);\n },\n ctx,\n // `platformCrypto`, captured at import, and NOT `globalThis.crypto` read here: a\n // host installs its scope before it builds the container, so reading the global now\n // would find the installed binding and recurse into itself on the first digest.\n options.crypto ?? platformCrypto,\n );\n }\n\n /** Opaque identity available only during an external entry's synchronous body. */\n get currentExternalEntry(): object | undefined {\n return this.#readCurrentExternalEntry?.();\n }\n\n /** Re-enter this actor after a host promise settles. */\n awaitIo<T>(promise: Promise<T>): Promise<T> {\n return this.#ctx.awaitIo(promise);\n }\n\n /**\n * The tripwire, and the reason this class can be bound rather than ambient.\n *\n * A scope is reached lexically, so a facet source that writes\n * `globalThis.scheduler.wait(…)` instead of the `scheduler` its own module\n * scope binds gets its PARENT's scope. Upstream cannot have this: a dynamic\n * Worker is a separate isolate with a separate global object, so the wrong\n * scope is not nameable. Here there is one realm, and the design record says\n * of it: \"nothing can detect it.\"\n *\n * This detects the case that occurs, and refuses. `IoContext.isCurrentSlice()`\n * is true only while a synchronous body of that context is on the JS stack,\n * and a facet's body calling a foreign global IS such a moment — the facet\n * entered through `entry()`/`run()`, and its body runs to its first `await`\n * with the ambient set. So the mismatch is certain, and the refusal names the\n * actor rather than surfacing three layers away as `no input lock available in\n * this context` from a storage call that had nothing to do with it.\n *\n * **What it does not catch, stated rather than implied.** A call made from a\n * CONTINUATION — after the calling body's first `await` — finds no ambient at\n * all, because `currentSlice` is restored when the body returns and JS cannot\n * drain a microtask checkpoint synchronously the way `runInContextScope` does.\n * The check then passes and the bound context is used, which is the status quo\n * behaviour and no worse than it. Widening the ambient to cover continuations\n * is not available: two actors' slices genuinely overlap in that window (§1.10\n * gives a facet its own gates, so nothing serialises it against its parent),\n * so a wider ambient would be WRONG rather than merely absent, and wrong with\n * nothing to say so. A tripwire that is silent when it cannot tell is worth\n * more than one that guesses.\n */\n #requireOwnSlice(op: string): void {\n const running = tryCurrentSlice();\n if (running === undefined || running === this.#ctx) return;\n throw new Error(`${op}: this actor's global scope ${FOREIGN_SLICE_MESSAGE}`);\n }\n\n /** ← `ServiceWorkerGlobalScope::setTimeout` (`global-scope.c++:944-950`). */\n setTimeout(callback: (...args: never[]) => void, msDelay = 0, ...args: unknown[]): number {\n this.#requireOwnSlice(\"setTimeout\");\n return this.#ctx.setTimeoutImpl(false, () => callback(...(args as never[])), msDelay);\n }\n\n /** ← `ServiceWorkerGlobalScope::clearTimeout` (`global-scope.c++:967-975`). */\n clearTimeout(id?: number | null): void {\n // ← `KJ_IF_SOME(id, timeoutId)`: a missing or non-numeric id is not an error, it is a no-op.\n if (typeof id !== \"number\") return;\n this.#ctx.clearTimeoutImpl(id);\n }\n\n /** ← `ServiceWorkerGlobalScope::setInterval` (`global-scope.c++:959-965`). */\n setInterval(callback: (...args: never[]) => void, msDelay = 0, ...args: unknown[]): number {\n this.#requireOwnSlice(\"setInterval\");\n return this.#ctx.setTimeoutImpl(true, () => callback(...(args as never[])), msDelay);\n }\n\n /** ← `ServiceWorkerGlobalScope::clearInterval`, which is `clearTimeout`'s own body. */\n clearInterval(id?: number | null): void {\n this.clearTimeout(id);\n }\n\n /**\n * ← `ServiceWorkerGlobalScope::fetch` (`global-scope.h:703-705`) reaching\n * `fetchImpl` (`http.c++:1740-1760`).\n *\n * Two gates, in upstream's order. The OUTPUT gate first, because an outbound\n * request is exactly the observation §1.1 exists to hold back — \"blocks all\n * outgoing messages from an actor that would allow the rest of the world to\n * observe the actor's state\" — and `fetchImpl` waits on it before the request\n * departs (`http.c++:1488`, `:1759`). The INPUT gate is released for the\n * duration and re-taken on resumption, which is `awaitIo` and which is what\n * makes an actor awaiting the network stay re-entrant (§1.3).\n */\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n try {\n // Reshaped rather than thrown, for the reason `Scheduler.wait` gives above: this returns a\n // promise, so a synchronous throw would escape the caller's `.catch`.\n this.#requireOwnSlice(\"fetch\");\n } catch (exception) {\n return Promise.reject(exception);\n }\n const outbound = this.#fetch;\n if (outbound === undefined) return Promise.reject(new Error(NO_GLOBAL_OUTBOUND_MESSAGE));\n\n const ctx = this.#ctx;\n return ctx.awaitIo(\n (async (): Promise<Response> => {\n await ctx.waitForOutputLocks();\n return await outbound(input, init);\n })(),\n // A `Response` is a promise for its body as much as it is a value: `await res.json()`\n // resumes from a promise this package would not own, so the body is gated too.\n (response) => gateResponseBody(ctx, response),\n );\n }\n}\n\n// =======================================================================================\n// Installing a scope\n\n/**\n * The bound form of `ActorGlobalScope`, which is what a scope object actually\n * holds. Bound, because these are read as free variables — `setTimeout(…)`, not\n * `scope.setTimeout(…)` — so a method that needed its receiver would break the\n * moment it was destructured, which is exactly how a dynamically-loaded Worker\n * source receives them.\n */\nexport type ActorScopeBindings = {\n readonly awaitIo: <T>(promise: Promise<T>) => Promise<T>;\n readonly scheduler: {\n wait(delay: number, options?: SchedulerWaitOptions): Promise<void>;\n yield(): Promise<void>;\n };\n readonly setTimeout: (\n callback: (...args: never[]) => void,\n msDelay?: number,\n ...args: unknown[]\n ) => number;\n readonly clearTimeout: (id?: number | null) => void;\n readonly setInterval: (\n callback: (...args: never[]) => void,\n msDelay?: number,\n ...args: unknown[]\n ) => number;\n readonly clearInterval: (id?: number | null) => void;\n readonly fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n readonly crypto: Crypto;\n readonly currentExternalEntry?: object | undefined;\n};\n\n/**\n * The capabilities an actor's code reads, bound to one scope.\n *\n * `resolve` is a thunk because the owner may change across root respawns, or a\n * shared realm may select the actor whose synchronous slice is running. It is\n * consulted only when an operation begins; it does not propagate identity\n * across a promise continuation. Actor-owned code should retain its explicit\n * scope instead. A single-actor host simply writes `() => scope`.\n */\nexport function actorScopeBindings(resolve: () => ActorGlobalScope): ActorScopeBindings {\n return {\n awaitIo: (promise) => resolve().awaitIo(promise),\n scheduler: {\n wait: (delay, options) => resolve().scheduler.wait(delay, options),\n yield: () => resolve().scheduler.yield(),\n },\n setTimeout: (callback, msDelay, ...args) => resolve().setTimeout(callback, msDelay, ...args),\n clearTimeout: (id) => {\n resolve().clearTimeout(id);\n },\n setInterval: (callback, msDelay, ...args) => resolve().setInterval(callback, msDelay, ...args),\n clearInterval: (id) => {\n resolve().clearInterval(id);\n },\n fetch: (input, init) => resolve().fetch(input, init),\n crypto: scopeCrypto(resolve),\n get currentExternalEntry(): object | undefined {\n return resolve().currentExternalEntry;\n },\n };\n}\n\n/**\n * `crypto`, bound the way every other name here is bound: nothing resolves until\n * an operation actually runs.\n *\n * That laziness is required rather than tidy, and both lanes proved it. A facet's\n * module destructures its seven names at module scope, which is BEFORE its container\n * exists — so a `crypto` that resolved on read threw at import. And on the root\n * path `globalThis.crypto` is read by things that are not the actor at all: capnweb,\n * the sqlite driver, the test runner. So the binding is a pair of plain objects\n * whose methods resolve, and reading `crypto` or `crypto.subtle` resolves nothing.\n *\n * The synchronous members go to the PLATFORM's `crypto` rather than through the\n * scope, because gating buys nothing for a call with no continuation — and because\n * they are exactly the ones a non-actor caller reaches for.\n */\nfunction scopeCrypto(resolve: () => ActorGlobalScope): Crypto {\n const subtle: Record<string, unknown> = {};\n for (const method of ASYNC_SUBTLE_METHODS) {\n subtle[method] = (...args: unknown[]): Promise<unknown> => {\n const target = resolve().crypto.subtle;\n const call = target[method] as (...rest: unknown[]) => Promise<unknown>;\n return Reflect.apply(call, target, args);\n };\n }\n return {\n subtle: subtle as unknown as SubtleCrypto,\n getRandomValues: <T extends ArrayBufferView | null>(array: T): T =>\n platformCrypto.getRandomValues(array as never) as T,\n randomUUID: () => platformCrypto.randomUUID(),\n } as unknown as Crypto;\n}\n\n/** Captured at import, before any host installs a scope over it. */\nconst platformCrypto = globalThis.crypto;\n\n/** ← every `SubtleCrypto` member that returns a promise, as a value the binding can iterate. */\nconst ASYNC_SUBTLE_METHODS = [\n \"decrypt\",\n \"deriveBits\",\n \"deriveKey\",\n \"digest\",\n \"encrypt\",\n \"exportKey\",\n \"generateKey\",\n \"importKey\",\n \"sign\",\n \"unwrapKey\",\n \"verify\",\n \"wrapKey\",\n] as const satisfies readonly AsyncSubtleMethod[];\n\n/**\n * Write the web-platform bindings onto a scope object — `globalThis` for a class in the worker's\n * own module graph, a plain object a dynamically-loaded source destructures for\n * one that is not.\n *\n * **A host should call this rather than assigning the names itself**, and the\n * reason is the failure it prevents: a host that installs five of the six leaves\n * one primitive ungated, and an ungated primitive that WORKS is invisible until\n * a continuation after it touches storage — possibly never, on the path that\n * matters. The set is the package's, so it can grow without every host growing\n * with it.\n *\n * **It ASSIGNS, and that is not incidental.** Chrome ships a `scheduler` global\n * in dedicated workers — the Prioritized Task Scheduling API, `postTask` and\n * `yield`, no `wait` — so a host writing `??=` silently keeps Chrome's and every\n * timer await fails somewhere else entirely with `scheduler.wait is not a\n * function`. Measured on the browser conformance lane, and the extension meets\n * the same global at cutover.\n *\n * **What a host must do first:** capture whatever raw timers its own substrate\n * needs. Everything BELOW the runtime — a `Timer` port, a transport's own\n * retries — has to keep the platform's, or arming a timeout goes through a\n * timeout. That is not hypothetical: pointing the node lane at these primitives\n * without capturing first produced `RangeError: Maximum call stack size\n * exceeded` on the first row.\n */\nexport function installActorScope(target: object, resolve: () => ActorGlobalScope): void {\n const bindings = actorScopeBindings(resolve);\n // Descriptors, not values: `crypto` is a getter, and reading it here would resolve the scope\n // at install time — which is before the container exists on the facet path, where the whole\n // arrangement is a late binding.\n for (const [name, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(bindings))) {\n // These are explicit actor capabilities, not web-platform globals.\n if (name === \"awaitIo\" || name === \"currentExternalEntry\") continue;\n Object.defineProperty(target, name, { ...descriptor, configurable: true });\n }\n}\n","/**\n * ← workerd `src/workerd/api/web-socket.{h,c++}` — the gating, and nothing else.\n *\n * A socket is the one primitive that is neither of the other two, and §1.8 says\n * why in three lines: incoming frames \"each take a fresh input lock via\n * `context.run(...)`\", the read loop \"captures the critical section at\n * `accept()` time\", and outbound messages \"each carry their own output-gate\n * promise captured at `send()` time\". Upstream states the first outright, on the\n * line that does it (`web-socket.c++:1056-1059`):\n *\n * > \"Re-enter the context with context.run(). This is arguably a bit unusual\n * > compared to other I/O which is delivered by return from context.awaitIo(),\n * > but the difference here is that we have a long stream of events over time.\n * > It makes sense to use context.run() each time a new event arrives.\"\n *\n * So a socket cannot be `awaitIo`: there is no single result to resume from.\n * `accept()` starts a loop, and the loop is the gate's caller.\n *\n * **What is ported and what is not.** The frame protocol, the hibernation\n * states, auto-response, `WebSocketPair` and the byte accounting are all\n * absent — the substrate ships a `WebSocket`, and hibernation is a recorded\n * substrate boundary with no Chrome lifecycle to be faithful to. What is here is\n * `WebSocket::Accepted`: the three gate properties above, over whatever socket\n * the host hands in. That is the same division `api/http.ts` makes and for the\n * same reason.\n *\n * **The accept contract, and the hole it leaves.** After `acceptWebSocket`, the\n * gated view owns the raw socket's events. A consumer that keeps a reference to\n * the raw socket and registers a listener on it directly gets that listener\n * called ungated, and nothing here can prevent it — upstream cannot be reached\n * that way because `accept()` moves the `kj::WebSocket` into `Accepted` and the\n * JS object never had it. The refusal below covers the case that is detectable\n * (accepting the same socket twice); the rest is the accept contract, stated.\n *\n * Spec: §1.1, §1.8 and decision 5 in\n * docs/decisions.md.\n */\n\nimport type { IoContext } from \"../io/io-context\";\nimport type { CriticalSection } from \"../io/io-gate\";\n\n/**\n * The socket beneath. Deliberately structural and minimal: a real `WebSocket`,\n * the extension's `WebSocketFacade` over capnweb, and a test double all satisfy\n * it, and none of them is a type this package should name.\n */\nexport interface RawWebSocket {\n addEventListener(type: string, listener: (event: Event) => void): void;\n send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void;\n close(code?: number, reason?: string): void;\n}\n\n/** ← the `JSG_REQUIRE(!native.state.is<Accepted>(), ...)` at the head of `accept()`. */\nexport const ALREADY_ACCEPTED_MESSAGE =\n \"acceptWebSocket(): this socket has already been accepted by an actor. A socket's frames are \" +\n \"delivered by exactly one read loop, and a second accept would deliver them under two gates.\";\n\n/** Sockets this runtime has accepted, so the refusal above is answerable. */\nconst accepted = new WeakSet<RawWebSocket>();\n\n/** The four events a `WebSocket` dispatches, which `readLoop` and its `.then` cover upstream. */\nconst SOCKET_EVENTS = [\"open\", \"message\", \"close\", \"error\"] as const;\ntype SocketEvent = (typeof SOCKET_EVENTS)[number];\n\n/**\n * ← `WebSocket::Accepted` (`web-socket.h:~300-360`), reached through\n * `accept()` → `internalAccept(js, IoContext::current().getCriticalSection())`\n * → `startReadLoop` (`web-socket.c++:133`, `:426`, `:429-433`, `:507`).\n *\n * An `EventTarget`, so a consumer registers listeners the way it would on a real\n * socket — but on THIS object rather than on the raw one, because this is what\n * runs them inside a gated slice.\n */\nexport class AcceptedWebSocket extends EventTarget {\n readonly #ctx: IoContext;\n readonly #socket: RawWebSocket;\n /**\n * ← `readLoop`'s `cs` parameter, captured at accept and replayed for every\n * frame via `mapAddRef(cs)` (`web-socket.c++:1110`). A socket accepted inside\n * `blockConcurrencyWhile` therefore delivers its messages inside that critical\n * section — §1.8's second bullet, and the reason this is captured here rather\n * than read when a frame arrives.\n */\n readonly #criticalSection: CriticalSection | undefined;\n\n /**\n * ← `OutgoingMessagesMap outgoingMessages` plus `ensurePumping`\n * (`web-socket.h:582-590`, `web-socket.c++:948-975`), as a chain.\n *\n * The table is insertion-ordered and the pump awaits each entry's own\n * `outputLock` before sending it, so messages leave in order and message N\n * waits only for the writes outstanding when IT was enqueued. A promise chain\n * is the same two properties with nothing to schedule.\n */\n #pump: Promise<void> = Promise.resolve();\n\n onopen: ((event: Event) => void) | null = null;\n onmessage: ((event: MessageEvent) => void) | null = null;\n onclose: ((event: CloseEvent) => void) | null = null;\n onerror: ((event: Event) => void) | null = null;\n\n constructor(ctx: IoContext, socket: RawWebSocket) {\n super();\n this.#ctx = ctx;\n this.#socket = socket;\n this.#criticalSection = ctx.getCriticalSection();\n\n // ← `startReadLoop`. One listener per event type on the raw socket, forever; each delivery is\n // one gated run. Upstream's loop is a coroutine over `ws.receive()`, which is the same shape\n // an event listener already is here.\n for (const type of SOCKET_EVENTS) {\n socket.addEventListener(type, (event: Event) => {\n this.#deliver(type, event);\n });\n }\n }\n\n /**\n * ← `co_await context.run([...](auto& wLock) { dispatchEventImpl(...) }, mapAddRef(cs))`\n * (`web-socket.c++:1065-1110`).\n *\n * The run rides `addWaitUntil`, as upstream's read loop does (\"We put the read\n * loop in a `waitUntil`, since there would otherwise be a race condition\n * between delivering the final close message and the request being canceled\",\n * `web-socket.c++:537-541`). That is also what stops a listener's throw\n * becoming an unhandled rejection: it lands in `waitUntilStatus()`.\n */\n #deliver(type: SocketEvent, event: Event): void {\n this.#ctx.addWaitUntil(\n this.#ctx.run(() => {\n // One rebuilt event for both forms: handing the handler the raw one would give it a\n // different `target` from the listener beside it, for the same frame.\n const delivered = cloneEventFor(type, event);\n this.dispatchEvent(delivered);\n // Consumers use both forms — a client library sets handlers, a server library listens —\n // so both are called, exactly as `WebSocketFacade` does for the same reason.\n const handler = this[`on${type}`] as ((event: Event) => void) | null;\n handler?.(delivered);\n }, this.#criticalSection),\n );\n }\n\n /**\n * ← `WebSocket::send` (`web-socket.c++:~640`), which inserts a\n * `GatedMessage{IoContext::current().waitForOutputLocksIfNecessary(), …}`.\n *\n * Synchronous, as upstream's is: the wait is the pump's, not the caller's. The\n * output gate is what \"blocks all outgoing messages from an actor that would\n * allow the rest of the world to observe the actor's state\" (§1.1), and a\n * socket frame is exactly such a message.\n *\n * `waitForOutputLocksIfNecessary()` collapses to `waitForOutputLocks()` here\n * for the reason the whole file collapses `kj::Maybe<Worker::Actor&>`: its\n * body is `actor.map(…)` (`io-context.c++:383-386`) and every context in this\n * runtime is an actor context.\n */\n send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void {\n this.#enqueue(() => {\n this.#socket.send(data);\n });\n }\n\n /** ← `WebSocket::close`, which enqueues a `Close` through the same gate. */\n close(code?: number, reason?: string): void {\n this.#enqueue(() => {\n this.#socket.close(code, reason);\n });\n }\n\n #enqueue(write: () => void): void {\n // Captured HERE, at the call, so message N waits for the writes outstanding when it was\n // enqueued and not for whatever is outstanding when the pump reaches it.\n const outputLock = this.#ctx.waitForOutputLocks();\n this.#pump = this.#pump.then(async () => {\n await outputLock;\n write();\n });\n // The chain is the actor's work, so a broken output gate reports where every other background\n // failure reports rather than as an unhandled rejection.\n this.#ctx.addWaitUntil(this.#pump);\n }\n}\n\n/**\n * ← `accept()` / `state.acceptWebSocket()`, as the one verb.\n *\n * Named for what upstream names it, because the critical-section capture is a\n * property of accepting rather than of constructing: \"a socket accepted inside a\n * `blockConcurrencyWhile` delivers its messages inside that critical section\"\n * (§1.8).\n */\nexport function acceptWebSocket(ctx: IoContext, socket: RawWebSocket): AcceptedWebSocket {\n if (accepted.has(socket)) throw new Error(ALREADY_ACCEPTED_MESSAGE);\n accepted.add(socket);\n return new AcceptedWebSocket(ctx, socket);\n}\n\n/**\n * An `Event` may be dispatched by exactly one target at a time, so the raw\n * socket's event object cannot be re-dispatched: `dispatchEvent` on an event\n * that is already dispatched throws `InvalidStateError`, and one that has\n * finished carries the raw socket as its `target`. Rebuilding it is what makes\n * `event.target` the accepted socket, which is what a listener expects.\n */\nfunction cloneEventFor(type: SocketEvent, event: Event): Event {\n if (type === \"message\") {\n const source = event as MessageEvent;\n return new MessageEvent(\"message\", {\n data: source.data,\n origin: source.origin,\n lastEventId: source.lastEventId,\n });\n }\n if (type === \"close\") {\n const source = event as CloseEvent;\n return new CloseEvent(\"close\", {\n code: source.code,\n reason: source.reason,\n wasClean: source.wasClean,\n });\n }\n return new Event(type);\n}\n","/**\n * ← workerd `src/workerd/io/actor-cache.h` — INTERFACE ONLY.\n *\n * The `actor-cache.c++` LRU implementation is ABSENT rather than skipped: it\n * caches a remote storage service that none of our substrates have. Upstream\n * does not use it in SQLite mode either — `ActorSqlite` is the sole\n * `ActorCacheInterface` implementation there, and the same is true here.\n *\n * The two behaviours decision 5 names live in `io/actor-sqlite.ts`, which is\n * where workerd's SQLite path exhibits them: `allowUnconfirmed` skips the\n * output-gate lock but STILL breaks the gate on error, and a batch started as\n * unconfirmed is retroactively upgraded when a must-confirm write joins it.\n *\n * Ordering guarantee, upstream's words (`actor-cache.h:334-340`): writes are\n * never committed out-of-order, by brute force — one transaction commits all\n * dirty keys at once.\n *\n * This file carries only what `ActorSqlite` genuinely implements. Everything in\n * `ActorCacheInterface` that exists solely for the LRU — `evictStale`'s\n * backpressure, the RPC storage client, the shared LRU and its hooks — is\n * absent with it.\n *\n * The one shape that is ours rather than upstream's: **every read and write is\n * synchronous.** Upstream returns `kj::OneOf<T, kj::Promise<T>>` so a cache miss\n * can go to the network; §1.4 measures that a SQLite-backed actor never does,\n * and the SQLite arm of every one of those `OneOf`s is the immediate value. A\n * `OneOf` with one reachable arm is a promise nobody can observe, and keeping it\n * would make `api/actor-state.ts` unwrap something that is never a promise.\n * `onNoPendingFlush` and `abandonAlarm` stay asynchronous because upstream's\n * SQLite arm is genuinely asynchronous there.\n *\n * Spec: §1.7, decisions 2 and 5.\n */\n\n/** ← `ActorCacheOps::Key`. \"Keys are text for now.\" */\nexport type Key = string;\n\n/** ← `ActorCacheOps::Value`. Values are raw bytes; the value encoding is `api/`'s. */\nexport type Value = Uint8Array;\n\n/** ← `ActorCacheOps::KeyValuePair`. */\nexport type KeyValuePair = {\n readonly key: Key;\n readonly value: Value;\n};\n\n/**\n * ← `ActorCacheOps::GetResultList`, which upstream makes a class so it can\n * iterate pointers into the cache's own storage. Ours has already copied.\n */\nexport type GetResultList = readonly KeyValuePair[];\n\n/**\n * The option bags. Per §1.2 `allowConcurrency` is precisely the input-gate\n * opt-out: it selects `awaitIo` over `awaitIoWithInputLock`, which per §1.7.1\n * also ends the implicit transaction.\n *\n * Nothing passes any of these today — not upstream, not this repo, not the\n * vendored tests. They are built anyway; building half of the\n * `awaitIoWithInputLock` branch is the feature-subset failure the porting\n * philosophy rejects. The conformance suite exercises them deliberately.\n *\n * Placement note: upstream's `ActorCacheReadOptions` holds only `noCache`, and\n * `allowConcurrency` is read one layer up, in `DurableObjectStorageOperations`\n * (`actor-state.c++:68-79`) — `ActorCacheOps` never sees it. Part 4's table puts\n * decision 2 in this file, so it is declared here and consumed by `api/`;\n * `ActorSqlite` itself reads neither `allowConcurrency` nor `noCache`, exactly\n * as upstream's does not.\n */\nexport type ReadOptions = {\n /** Release the input gate across the await. Ends the implicit transaction. */\n allowConcurrency?: boolean;\n /** Do not retain the value in cache. */\n noCache?: boolean;\n};\n\nexport type WriteOptions = ReadOptions & {\n /** Skip the output-gate lock. Never skips break-on-error. */\n allowUnconfirmed?: boolean;\n};\n\n/** ← `DeleteAllOptions`. */\nexport type DeleteAllOptions = {\n /**\n * When true, deleteAll() will also delete any scheduled alarm. The alarm\n * deletion is guaranteed to take effect only after the deleteAll() itself\n * succeeds, so that we never end up in a state where the alarm is deleted but\n * KV data remains.\n */\n deleteAlarm?: boolean;\n};\n\n/**\n * ← `ActorCacheInterface::DeleteAllResults`.\n *\n * Upstream splits these \"so client code that doesn't need the count doesn't have\n * to wait for it just to account for backpressure\". Both arms are immediate for\n * SQLite: `backpressure` is always `kj::none` and `count` is a ready promise.\n */\nexport type DeleteAllResults = {\n readonly backpressure: Promise<void> | undefined;\n readonly count: number;\n};\n\n/**\n * ← `ActorCacheInterface::CancelAlarmHandler`. Alarm should be canceled without\n * retry, because alarm state has changed such that the requested alarm time is\n * no longer valid.\n */\nexport type CancelAlarmHandler = {\n /** Caller should wait for this promise to complete before canceling. */\n readonly waitBeforeCancel: Promise<void>;\n};\n\n/**\n * ← the `kj::Own<void>` that `RunAlarmHandler` carries, whose disposer runs\n * `maybeDeleteDeferredAlarm()`. Section 1's rule applies: a kj destructor\n * becomes an explicit call, so the caller attaches `drop()` to the promise\n * representing the handler's execution rather than a scope exit.\n */\nexport interface DeferredAlarmDeleter {\n drop(): void;\n}\n\n/** ← `ActorCacheInterface::RunAlarmHandler`. Alarm should be run. */\nexport type RunAlarmHandler = {\n readonly deferredDelete: DeferredAlarmDeleter;\n};\n\n/** ← `kj::OneOf<CancelAlarmHandler, RunAlarmHandler>`. */\nexport type ArmAlarmResult =\n | { readonly kind: \"cancel\"; readonly cancel: CancelAlarmHandler }\n | { readonly kind: \"run\"; readonly run: RunAlarmHandler };\n\n/** ← `ActorCache::SHUTDOWN_ERROR_MESSAGE`, which `ActorSqlite::shutdown` reuses. */\nexport const SHUTDOWN_ERROR_MESSAGE =\n \"broken.ignored; jsg.Error: Durable Object storage is no longer accessible.\";\n\n/**\n * ← the message every unimplemented `ActorCacheInterface` PITR method throws.\n * `ActorSqlite` overrides two of the four; the other two keep this.\n */\nexport const PITR_UNIMPLEMENTED_MESSAGE =\n \"This Durable Object's storage back-end does not implement point-in-time recovery.\";\n\n/** ← the message the three replication methods throw. */\nexport const REPLICATION_UNIMPLEMENTED_MESSAGE =\n \"This Durable Object's storage back-end does not support replication.\";\n\n/**\n * Common interface between the storage engine and a transaction on it.\n *\n * ← `ActorCacheOps`. Upstream's `list`/`listReverse` split exists because the\n * two directions \"require a subtly different implementation of pretty much the\n * entire algorithm\" in the cache; both are kept, because both are separate\n * entry points a caller reaches.\n */\nexport interface ActorCacheOps {\n get(key: Key, options: ReadOptions): Value | undefined;\n getMultiple(keys: readonly Key[], options: ReadOptions): GetResultList;\n getAlarm(options: ReadOptions): number | null;\n list(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions,\n ): GetResultList;\n listReverse(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions,\n ): GetResultList;\n\n put(key: Key, value: Value, options: WriteOptions): void;\n putMultiple(pairs: readonly KeyValuePair[], options: WriteOptions): void;\n /** Returns whether the key was present. */\n delete(key: Key, options: WriteOptions): boolean;\n /** Returns how many of the keys were present. */\n deleteMultiple(keys: readonly Key[], options: WriteOptions): number;\n setAlarm(newAlarmTime: number | null, options: WriteOptions): void;\n}\n\n/**\n * ← `ActorCacheInterface::Transaction`.\n *\n * \"If commit() is not called before the Transaction is destroyed, nothing is\n * written.\" JS has no destruction, so `drop()` is that moment and exactly one of\n * `commit()`/`rollback()`+`drop()` has to run — the same contract Section 1\n * established for `Lock` and `CriticalSection`.\n */\nexport interface ActorCacheTransaction extends ActorCacheOps {\n /**\n * Write all changes to the underlying storage.\n *\n * \"This will NOT detect conflicts, it will always just write blindly, because\n * conflicts inherently cannot happen.\"\n */\n commit(): void;\n rollback(): void;\n /** ← `~ExplicitTxn`: roll back if not committed, then leave the txn stack. */\n drop(): void;\n}\n\n/**\n * Abstract interface that upstream implements twice, and that this package\n * implements once — `ActorSqlite` is the sole implementation, exactly as on\n * workerd-with-SQLite.\n */\nexport interface ActorCacheInterface extends ActorCacheOps {\n startTransaction(): ActorCacheTransaction;\n deleteAll(options: WriteOptions, deleteAllOptions?: DeleteAllOptions): DeleteAllResults;\n /**\n * \"Call each time the isolate lock is taken to evict stale entries.\" There is\n * no cache to evict from and never any backpressure to apply.\n */\n evictStale(now: number): undefined;\n shutdown(exception?: unknown): void;\n\n armAlarmHandler(scheduledTime: number, currentTime: number): ArmAlarmResult;\n cancelDeferredAlarmDeletion(): void;\n abandonAlarm(scheduledTime: number): Promise<number | null>;\n\n /** Implements `sync()`. */\n onNoPendingFlush(): Promise<void>;\n\n getCurrentBookmark(): Promise<string>;\n getBookmarkForTime(timestamp: number): Promise<string>;\n onNextSessionRestoreBookmark(bookmark: string): Promise<string>;\n waitForBookmark(bookmark: string): Promise<void>;\n\n ensureReplicas(): void;\n disableReplicas(): void;\n configureReadReplication(enabled: boolean): Promise<void>;\n}\n","/**\n * ← workerd `src/workerd/util/sqlite-kv.{h,c++}`\n *\n * KV storage on top of SQLite, for Durable Object storage.\n *\n * The table is named `_cf_KV`. The naming is designed so that if the\n * application is allowed to perform direct SQL queries, we can block it from\n * accessing any table prefixed with `_cf_`.\n *\n * This layer is bytes in, bytes out, exactly as upstream is. The structured\n * value encoding happens above it, in `api/actor-state.ts`, which is where\n * upstream V8-serializes.\n *\n * Three translations, each of them forced:\n *\n * - `get`'s callback exists upstream to avoid copying bytes out of a live\n * sqlite row. Our backends have already materialised the row by the time we\n * see it, so there is no copy to avoid and the value is returned.\n * - `delete_` is spelled `delete` — the C++ name carries a trailing underscore\n * only because `delete` is a keyword there.\n * - Upstream's `Uninitialized` / `Initialized` pair exists solely to hold\n * thirteen `SqliteDatabase::Statement`s. Prepared statements are not part of\n * our backend seam (each `exec` prepares), so the pair collapses into the\n * `tableCreated` flag it already sits beside. The statements survive as\n * `STMT` below: same names, same order, SQL copied verbatim, so the\n * correspondence a reader needs is intact.\n *\n * Not ported: `SqliteKvRegulator`. Its remaining job is `shouldAddQueryStats`,\n * which is row-count billing; neither backend exposes those counters.\n *\n * Spec: §2.4 in docs/decisions.md.\n */\n\nimport {\n getBlob,\n getInt64,\n getText,\n hasCurrentSqliteTable,\n type ResetListener,\n type SqliteDatabase,\n} from \"./sqlite\";\n\nexport type KeyPtr = string;\nexport type ValuePtr = Uint8Array;\n\n/** ← `SqliteKv::Order`. */\nexport type Order = \"FORWARD\" | \"REVERSE\";\n\n/** ← `SqliteKv::WriteOptions`. */\nexport type WriteOptions = {\n allowUnconfirmed?: boolean;\n};\n\n/** ← `SqliteKv::ListCursor::KeyValuePair`, and the shape `put(pairs)` iterates. */\nexport type KeyValuePair = {\n key: KeyPtr;\n value: ValuePtr;\n};\n\n/** ← the `Initialized` statement bundle, verbatim. */\nconst STMT = {\n get: `\n SELECT value FROM _cf_KV WHERE key = ?\n `,\n put: `\n INSERT INTO _cf_KV VALUES(?, ?)\n ON CONFLICT DO UPDATE SET value = excluded.value\n `,\n delete: `\n DELETE FROM _cf_KV WHERE key = ?\n `,\n list: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key\n `,\n listEnd: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key\n `,\n listLimit: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key\n LIMIT ?\n `,\n listEndLimit: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key\n LIMIT ?\n `,\n listReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key DESC\n `,\n listEndReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key DESC\n `,\n listLimitReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key DESC\n LIMIT ?\n `,\n listEndLimitReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key DESC\n LIMIT ?\n `,\n countKeys: `\n SELECT count(*) FROM _cf_KV\n `,\n multiPutSavepoint: `\n SAVEPOINT _cf_put_multiple_savepoint\n `,\n multiPutRelease: `\n RELEASE _cf_put_multiple_savepoint\n `,\n} as const;\n\nconst CREATE_TABLE = `\n CREATE TABLE IF NOT EXISTS _cf_KV (\n key TEXT PRIMARY KEY,\n value BLOB\n ) WITHOUT ROWID\n `;\n\nexport class SqliteKv implements ResetListener {\n readonly #db: SqliteDatabase;\n\n /**\n * Has the `_cf_KV` table been created? Separate from the statement bundle\n * upstream, since it has to be repeated after a reset.\n */\n #tableCreated = false;\n\n #currentCursor: SqliteKvListCursor | null = null;\n\n constructor(db: SqliteDatabase) {\n this.#db = db;\n this.#tableCreated = hasCurrentSqliteTable(db, \"_cf_KV\", CREATE_TABLE);\n db.addResetListener(this);\n }\n\n /**\n * Search for a match for the given key. Returns the value if found, undefined\n * if not.\n */\n get(key: KeyPtr): ValuePtr | undefined {\n // \"No table, so no value\" is answered from `#tableCreated` without a\n // statement, which is the one path a latched critical error would not\n // otherwise stop.\n this.#db.assertUsable();\n if (!this.#tableCreated) return undefined;\n\n const row = this.#db.run(STMT.get, key).rawRows[0];\n if (row === undefined) return undefined;\n return getBlob(row, 0);\n }\n\n /**\n * Search for all known keys and values in a range. `end` and `limit` can be\n * undefined to request no constraint be enforced.\n *\n * With a callback, calls it for each row seen and returns the count. Without\n * one, returns a cursor which can be iterated one at a time.\n */\n list(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n ): SqliteKvListCursor;\n list(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n callback: (key: KeyPtr, value: ValuePtr) => void,\n ): number;\n list(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n callback?: (key: KeyPtr, value: ValuePtr) => void,\n ): SqliteKvListCursor | number {\n const cursor = this.#openCursor(begin, end, limit, order);\n return callback === undefined ? cursor : cursor.forEach(callback);\n }\n\n /** Store a value into the table, or atomically store multiple values. */\n put(key: KeyPtr, value: ValuePtr, options?: WriteOptions): void;\n put(pairs: Iterable<KeyValuePair>, options: WriteOptions): void;\n put(\n keyOrPairs: KeyPtr | Iterable<KeyValuePair>,\n valueOrOptions?: ValuePtr | WriteOptions,\n maybeOptions?: WriteOptions,\n ): void {\n // The two overloads share a parameter position, and narrowing it by test\n // rather than by cast is what keeps a caller who mixes them up from writing\n // an options object into the table as a value.\n if (typeof keyOrPairs === \"string\") {\n if (!(valueOrOptions instanceof Uint8Array)) {\n throw new Error(\"put(key, value) takes a Uint8Array value.\");\n }\n const allowUnconfirmed = maybeOptions?.allowUnconfirmed ?? false;\n this.#ensureInitialized(allowUnconfirmed);\n this.#db.run({ allowUnconfirmed }, STMT.put, keyOrPairs, valueOrOptions);\n return;\n }\n if (valueOrOptions instanceof Uint8Array) {\n throw new Error(\"put(pairs, options) takes an options object.\");\n }\n this.#putMultiple(keyOrPairs, valueOrOptions ?? {});\n }\n\n /** Delete the key and return whether it was matched. */\n delete(key: KeyPtr, options: WriteOptions = {}): boolean {\n const allowUnconfirmed = options.allowUnconfirmed ?? false;\n this.#ensureInitialized(allowUnconfirmed);\n return this.#db.run({ allowUnconfirmed }, STMT.delete, key).rowsWritten > 0;\n }\n\n deleteAll(): number {\n // Upstream's TODO(perf) applies verbatim: apps almost certainly don't care\n // about the return value, but historically we returned the count of keys\n // deleted, so now we're stuck counting the table size for no good reason.\n let count = 0;\n if (this.#tableCreated) {\n const row = this.#db.run(STMT.countKeys).rawRows[0];\n if (row === undefined) throw new Error(\"count(*) returned no row.\");\n count = getInt64(row, 0);\n }\n this.#db.reset();\n return count;\n }\n\n /** ResetListener interface: we'll need to recreate the table on the next operation. */\n beforeSqliteReset(): void {\n this.#tableCreated = false;\n // Upstream's cursors are ResetListeners of their own and throw\n // \"query canceled because reset()\" afterwards. Ours hold a materialised\n // array that a reset cannot invalidate, so cancelling is what keeps a\n // cursor from outliving the data it was reading.\n this.#cancelCurrentCursor();\n }\n\n #openCursor(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n ): SqliteKvListCursor {\n // Same cache-served early return as `get`.\n this.#db.assertUsable();\n if (!this.#tableCreated) return new SqliteKvListCursor(null, null);\n\n const [sql, params] = selectListStatement(begin, end, limit, order);\n this.#cancelCurrentCursor();\n const cursor = new SqliteKvListCursor(this, this.#db.run(sql, ...params).rawRows);\n this.#currentCursor = cursor;\n return cursor;\n }\n\n /** Called by a cursor that has run out of rows, mirroring `~ListCursor::State`. */\n releaseCursor(cursor: SqliteKvListCursor): void {\n if (this.#currentCursor === cursor) this.#currentCursor = null;\n }\n\n #cancelCurrentCursor(): void {\n const cursor = this.#currentCursor;\n if (cursor !== null) {\n cursor.cancel();\n this.#currentCursor = null;\n }\n }\n\n #putMultiple(pairs: Iterable<KeyValuePair>, options: WriteOptions): void {\n const allowUnconfirmed = options.allowUnconfirmed ?? false;\n this.#ensureInitialized(allowUnconfirmed);\n this.#db.run({ allowUnconfirmed }, STMT.multiPutSavepoint);\n\n try {\n for (const pair of pairs) {\n this.put(pair.key, pair.value, { allowUnconfirmed });\n }\n } catch (error) {\n // If any of the puts throw, roll the savepoint back and re-throw the\n // exception from the put that failed.\n this.#rollbackMultiPut(allowUnconfirmed, error);\n throw error;\n }\n this.#db.run({ allowUnconfirmed }, STMT.multiPutRelease);\n }\n\n /**\n * Upstream logs and swallows a failure here, on the grounds that it should be\n * rare. This repo has no logger and a storage layer that swallows an error\n * corrupts data silently, so a failed rollback is raised instead — carrying\n * the put failure as its cause, since that is the one the caller came for.\n * The normal path is unchanged: a rollback that succeeds re-throws the\n * original untouched.\n */\n #rollbackMultiPut(allowUnconfirmed: boolean, cause: unknown): void {\n try {\n // This should be rare, so we don't keep a statement for it.\n this.#db.run({ allowUnconfirmed }, \"ROLLBACK TO _cf_put_multiple_savepoint\");\n this.#db.run({ allowUnconfirmed }, STMT.multiPutRelease);\n } catch (rollbackError) {\n throw new Error(`Rolling back a multi-put failed: ${String(rollbackError)}`, { cause });\n }\n }\n\n /**\n * Make sure the KV table is created. Not called until the first write —\n * upstream's `ensureInitialized`, minus the statement bundle.\n */\n #ensureInitialized(allowUnconfirmed: boolean): void {\n if (this.#tableCreated) return;\n\n this.#db.run({ allowUnconfirmed }, CREATE_TABLE);\n this.#tableCreated = true;\n\n // If we're in a transaction and it gets rolled back, we better mark that\n // the table is actually not created anymore.\n this.#db.onRollback(() => {\n this.#tableCreated = false;\n });\n }\n}\n\n/**\n * ← `SqliteKv::ListCursor`.\n *\n * Upstream's iterates a live sqlite statement, which is why only one may be\n * open at a time and why a new `list()` cancels the previous cursor. Our rows\n * arrive materialised, so nothing forces that constraint — it is kept because\n * `wasCanceled()` is part of the contract above this layer, and a cursor whose\n * cancellation depended on the substrate would make the browser and Node lanes\n * disagree. What we do lose is streaming: an unbounded `list()` reads the whole\n * range into memory, where upstream reads a row at a time.\n */\nexport class SqliteKvListCursor {\n readonly #parent: SqliteKv | null;\n #rows: readonly (readonly unknown[])[] | null;\n #index = 0;\n #canceled = false;\n\n constructor(parent: SqliteKv | null, rows: readonly (readonly unknown[])[] | null) {\n this.#parent = parent;\n this.#rows = rows;\n }\n\n next(): KeyValuePair | undefined {\n const rows = this.#rows;\n if (rows === null) return undefined;\n\n const row = rows[this.#index];\n if (row === undefined) {\n this.#exhaust();\n return undefined;\n }\n this.#index += 1;\n return { key: getText(row, 0), value: getBlob(row, 1) };\n }\n\n forEach(callback: (key: KeyPtr, value: ValuePtr) => void): number {\n let count = 0;\n for (;;) {\n const pair = this.next();\n if (pair === undefined) return count;\n callback(pair.key, pair.value);\n count += 1;\n }\n }\n\n /**\n * If true, the cursor was canceled due to a new list() operation starting.\n * Only one list() is allowed at a time.\n */\n wasCanceled(): boolean {\n return this.#canceled;\n }\n\n /** Called by `SqliteKv` only. */\n cancel(): void {\n this.#rows = null;\n this.#canceled = true;\n }\n\n #exhaust(): void {\n this.#rows = null;\n this.#parent?.releaseCursor(this);\n }\n}\n\n/** ← the eight-way branch in `SqliteKv::list`, in the same order. */\nfunction selectListStatement(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n): [sql: string, params: (string | number)[]] {\n if (order === \"FORWARD\") {\n if (end !== undefined) {\n if (limit !== undefined) return [STMT.listEndLimit, [begin, end, limit]];\n return [STMT.listEnd, [begin, end]];\n }\n if (limit !== undefined) return [STMT.listLimit, [begin, limit]];\n return [STMT.list, [begin]];\n }\n if (end !== undefined) {\n if (limit !== undefined) return [STMT.listEndLimitReverse, [begin, end, limit]];\n return [STMT.listEndReverse, [begin, end]];\n }\n if (limit !== undefined) return [STMT.listLimitReverse, [begin, limit]];\n return [STMT.listReverse, [begin]];\n}\n","/**\n * ← workerd `src/workerd/util/sqlite-metadata.{h,c++}`\n *\n * A simple metadata kv storage and cache on top of SQLite. Currently used to\n * store:\n *\n * - Durable Object alarm times (hardcoded as key = 1);\n * - a local development bookmark used to simulate the getCurrentBookmark API\n * used by D1 (hardcoded as key = 2), not used in production.\n *\n * The table is named `_cf_METADATA`. The naming is designed so that if the\n * application is allowed to perform direct SQL queries, we can block it from\n * accessing any table prefixed with `_cf_`.\n *\n * Times are milliseconds, not nanoseconds. Upstream stores\n * `(t - UNIX_EPOCH) / kj::NANOSECONDS` as an int64. A JS number runs out of\n * integer precision 104 days into the epoch at nanosecond scale, so storing\n * what upstream stores would silently round every alarm. Milliseconds are also\n * what every caller above this already uses.\n *\n * The local-development bookmark IS ported, which the package's bookmark\n * substrate boundary might seem to rule out. It does not: that boundary is\n * `getCurrentBookmark` / `getBookmarkForTime` / `onNextSessionRestoreBookmark`,\n * which need point-in-time recovery from the storage engine. Key 2 is an\n * integer in a row, and D1 uses it locally precisely because it needs nothing.\n *\n * Spec: §1.8, §2.6 in docs/decisions.md.\n */\n\nimport {\n getInt64,\n hasCurrentSqliteTable,\n isNull,\n type ResetListener,\n type SqliteDatabase,\n} from \"./sqlite\";\n\n/** ← the `Initialized` statement bundle. */\nconst STMT = {\n getAlarm: `\n SELECT value FROM _cf_METADATA WHERE key = 1\n `,\n setAlarm: `\n INSERT INTO _cf_METADATA VALUES(1, ?)\n ON CONFLICT DO UPDATE SET value = excluded.value\n `,\n getLocalDevelopmentBookmark: `\n SELECT value FROM _cf_METADATA WHERE key = 2\n `,\n setLocalDevelopmentBookmark: `\n INSERT INTO _cf_METADATA VALUES(2, ?)\n ON CONFLICT DO UPDATE SET value = excluded.value\n `,\n} as const;\n\nconst CREATE_TABLE = `\n CREATE TABLE IF NOT EXISTS _cf_METADATA (\n key INTEGER PRIMARY KEY,\n value BLOB\n )\n `;\n\n/** ← `SqliteMetadata::Cache`. */\ntype Cache = {\n alarmTime: number | null;\n};\n\nexport class SqliteMetadata implements ResetListener {\n readonly #db: SqliteDatabase;\n #tableCreated: boolean;\n #cache: Cache | undefined;\n\n constructor(db: SqliteDatabase) {\n this.#db = db;\n this.#tableCreated = hasCurrentSqliteTable(db, \"_cf_METADATA\", CREATE_TABLE);\n if (this.#tableCreated) {\n const unexpected = db.run(\"SELECT key FROM _cf_METADATA WHERE key NOT IN (1, 2) LIMIT 1\")\n .rawRows[0];\n if (unexpected !== undefined) {\n throw new Error(\n `Incompatible @mcp-b/do-runtime storage data: _cf_METADATA contains unsupported key ${getInt64(unexpected, 0)}.`,\n );\n }\n }\n db.addResetListener(this);\n }\n\n /** Return currently set alarm time, or null. */\n getAlarm(): number | null {\n return this.#ensureCached().alarmTime;\n }\n\n /**\n * Sets current alarm time, or null. Returns true if the value changed, false\n * if it was already set to the same value.\n */\n setAlarm(currentTime: number | null, allowUnconfirmed: boolean): boolean {\n const cached = this.#cache;\n if (cached !== undefined && cached.alarmTime === currentTime) {\n return false;\n }\n this.#setAlarmUncached(currentTime, allowUnconfirmed);\n this.#db.onRollback(() => {\n this.#cache = cached;\n });\n this.#cache = { alarmTime: currentTime };\n return true;\n }\n\n /** Return the current local development bookmark, or null if none has been set. */\n getLocalDevelopmentBookmark(): number | null {\n this.#ensureInitialized(false);\n const row = this.#db.run(STMT.getLocalDevelopmentBookmark).rawRows[0];\n if (row === undefined || isNull(row, 0)) return null;\n\n const bookmark = getInt64(row, 0);\n if (bookmark < 0) throw new Error(`Local development bookmark is negative: ${bookmark}.`);\n return bookmark;\n }\n\n /** Set the current ersatz bookmark. */\n setLocalDevelopmentBookmark(bookmark: number): void {\n // Upstream's `uint64_t` parameter plus its `KJ_REQUIRE(bookmark <= maxValue)`, expressed in\n // the range a JS number can actually carry without rounding.\n if (!Number.isSafeInteger(bookmark) || bookmark < 0) {\n throw new Error(\n `Local development bookmark is not a non-negative safe integer: ${bookmark}.`,\n );\n }\n this.#ensureInitialized(false);\n this.#db.run(STMT.setLocalDevelopmentBookmark, bookmark);\n }\n\n /** ResetListener interface: we'll need to recreate the table on the next operation. */\n beforeSqliteReset(): void {\n this.#tableCreated = false;\n this.#cache = undefined;\n }\n\n #ensureCached(): Cache {\n // The only read in this class that can be answered without a statement, so\n // the only one a latched critical error would not already stop — and the\n // one whose answer SQLite may have rolled back underneath.\n this.#db.assertUsable();\n const cached = this.#cache;\n if (cached !== undefined) return cached;\n\n const populated: Cache = {\n alarmTime: this.#getAlarmUncached(),\n };\n this.#cache = populated;\n return populated;\n }\n\n #getAlarmUncached(): number | null {\n if (!this.#tableCreated) return null;\n\n const row = this.#db.run(STMT.getAlarm).rawRows[0];\n if (row === undefined || isNull(row, 0)) return null;\n return getInt64(row, 0);\n }\n\n #setAlarmUncached(currentTime: number | null, allowUnconfirmed: boolean): void {\n this.#ensureInitialized(allowUnconfirmed);\n // Our getter code also allows representing an empty alarm value as a\n // missing row or table, but a null-value row seems efficient and simple.\n this.#db.run({ allowUnconfirmed }, STMT.setAlarm, currentTime);\n }\n\n /**\n * Make sure the metadata table is created. Not called until the first write —\n * except by the bookmark getter, which is upstream's shape too.\n */\n #ensureInitialized(allowUnconfirmed: boolean): void {\n if (this.#tableCreated) return;\n\n this.#db.run({ allowUnconfirmed }, CREATE_TABLE);\n this.#tableCreated = true;\n this.#db.onRollback(() => {\n this.#tableCreated = false;\n });\n }\n}\n","/**\n * ← workerd `src/workerd/io/actor-sqlite.{h,c++}`\n *\n * The storage engine. Owns:\n * - implicit transactions, bounded by GATE RELEASE rather than by an\n * event-loop turn (§1.7.1 — measured; a storage await does not end the\n * transaction, a timer or outbound await does);\n * - `onWrite` taking the output-gate lock at the first must-confirm write,\n * one lock per flush batch;\n * - `transactionSync` as SAVEPOINT/RELEASE/ROLLBACK TO with a depth counter,\n * plus the async-callback guard today's version lacks;\n * - alarm arm/consume/deferred-deletion, and `deleteAll`.\n *\n * Sole `ActorCacheInterface` implementation, exactly as on workerd-with-SQLite.\n *\n * The single most important constraint in the whole port lives here: the\n * transaction boundary and the gate boundary are the same line. Implement them\n * as one mechanism. Release at every await — the naive reading of §1.2 — and\n * every multi-statement write silently loses atomicity, with nothing failing\n * until a crash lands between two statements that were meant to be one.\n *\n * **How that one line is drawn here, since it is the question the design record\n * left open.** Upstream needs no gate hook: `startImplicitTxn` wraps the commit\n * in `kj::evalLater`, which runs it on the next turn of the KJ event loop, and\n * the next KJ turn is by construction after the isolate run — which is after\n * `js.runMicrotasks()`, which is after `KJ_DEFER` clears `currentInputLock`.\n * \"Next turn\" and \"gate release\" are one boundary upstream, so `ActorSqlite`\n * hangs the commit on the cheaper of the two. They are one boundary here for the\n * same reason, provided the commit rides `atCheckpointEnd` — the primitive\n * `io-context.ts` releases on. Its comment carries the proof; the short form is\n * that holding the lock across an await is a pure microtask chain and releasing\n * it always costs a hand-off, so no write can cross a hand-off inside one\n * transaction and no two events can share one. `IoContext` therefore grows no\n * per-invocation exit notification, and the root gate's `inputGateReleased` hook\n * is *not* the right edge: it fires when `lockCount` hits zero, which never\n * happens inside a critical section, so decision 4's fifteen boot phases would\n * become a single transaction nobody chose.\n *\n * `onWrite` and `onCriticalError` are `SqliteDatabase`'s, in `util/sqlite.ts`,\n * exactly as upstream has them, and the constructor binds itself to both the way\n * `ActorSqlite`'s does. What is ours is only the substitute for the question\n * upstream answers with `sqlite3_stmt_readonly()` — see `isWrite` there.\n *\n * Not ported, because the substrate has no equivalent to port onto: `SpanParent`\n * tracing, already a Section 1 divergence, so every `traceSpan` parameter and\n * `currentCommitSpan` with it; `debugAlarmSync` and every `LOG_*`, which are a\n * logger this package does not have; and `TxnCommitRegulator::onError`, which\n * re-reports `SQLITE_CONSTRAINT` during commit as a user-visible error — error\n * codes do not cross the backend seam, the same reason Section 3 dropped\n * `SqliteKvRegulator::onError`.\n *\n * Spec: §1.4, §1.7, §1.7.1, §1.8, §2.4, §2.6, decisions 2, 5, 6 and 7 in\n * docs/decisions.md.\n */\n\nimport type {\n ActorCacheInterface,\n ActorCacheTransaction,\n ArmAlarmResult,\n DeferredAlarmDeleter,\n DeleteAllOptions,\n DeleteAllResults,\n GetResultList,\n Key,\n KeyValuePair,\n ReadOptions,\n Value,\n WriteOptions,\n} from \"./actor-cache\";\nimport {\n PITR_UNIMPLEMENTED_MESSAGE,\n REPLICATION_UNIMPLEMENTED_MESSAGE,\n SHUTDOWN_ERROR_MESSAGE,\n} from \"./actor-cache\";\nimport { atCheckpointEnd } from \"./io-context\";\nimport type { OutputGate } from \"./io-gate\";\nimport { SqliteKv } from \"../util/sqlite-kv\";\nimport { SqliteMetadata } from \"../util/sqlite-metadata\";\nimport { type SqliteCriticalError, SqliteDatabase } from \"../util/sqlite\";\n\n/**\n * The alarm port — one outbound method, matching upstream's seam exactly.\n *\n * Everything else about alarms is runtime-internal: arm/consume semantics here,\n * retry ladder and serialised delivery in `server/alarm-scheduler.ts`. Delivery\n * comes back IN through `ActorContainer.deliverAlarm`, not through this port.\n */\nexport interface AlarmOutlet {\n /**\n * Must be durable before the returned promise resolves.\n *\n * `priorTask` is upstream's second parameter and is load bearing rather than\n * decorative: \"any work we must wait on prior to scheduling the new request,\n * as of this writing, this would be the alarmLaterInFlight promise, which\n * tracks any in-flight request to move the alarm 'later' than is currently\n * set.\" An implementation that ignores it can send a move-earlier request\n * concurrently with a move-later one and lose the ordering invariant that the\n * scheduled alarm is always at or before the persisted one.\n *\n * May throw synchronously; `ActorSqlite` relies on it, because a scheduling\n * failure has to reach the caller before the local database commits.\n */\n scheduleRun(newAlarmTime: number | null, priorTask: Promise<void>): Promise<void>;\n}\n\n/** ← `ActorSqlite::Hooks::DEFAULT`, whose `scheduleRun` refuses. */\nexport const DEFAULT_ALARM_OUTLET: AlarmOutlet = {\n scheduleRun(): Promise<void> {\n throw new Error(\"alarms are not yet implemented for SQLite-backed Durable Objects\");\n },\n};\n\n// =======================================================================================\n// The anonymous namespace at the top of actor-sqlite.c++\n\n/** Returns true if a given (set or unset) alarm will fire earlier than another. */\nfunction willFireEarlier(alarm1: number | null, alarm2: number | null): boolean {\n // Intuitively, an unset alarm is effectively indistinguishable from an alarm set at infinity.\n return (alarm1 ?? Infinity) < (alarm2 ?? Infinity);\n}\n\n/**\n * Set options.allowUnconfirmed to false and log a reason why.\n *\n * Upstream mutates the caller's bag and logs; there is no logger here and the\n * bag belongs to the caller, so the disabled copy is returned instead.\n */\nfunction disableAllowUnconfirmed(options: WriteOptions, _reason: string): WriteOptions {\n return { ...options, allowUnconfirmed: false };\n}\n\n/**\n * ← `kj::evalLater`, which is where upstream's implicit transaction commits.\n *\n * See `atCheckpointEnd` in `io-context.ts` for why that primitive and not\n * `queueMicrotask`, `setTimeout`, or a hook on the input gate.\n */\nfunction evalLater<T>(func: () => Promise<T>): Promise<T> {\n const { promise, resolve, reject } = Promise.withResolvers<T>();\n atCheckpointEnd(() => {\n func().then(resolve, reject);\n });\n return promise;\n}\n\n/**\n * ← `kj::TaskSet` plus its `ErrorHandler`. `ActorSqlite` owns one of its own,\n * separate from `IoContext`'s, exactly as upstream does.\n */\nclass TaskSet {\n readonly #tasks = new Set<Promise<void>>();\n readonly #taskFailed: (exception: unknown) => void;\n\n constructor(taskFailed: (exception: unknown) => void) {\n this.#taskFailed = taskFailed;\n }\n\n add(promise: Promise<void>): void {\n const task = promise.then(\n () => {\n this.#tasks.delete(task);\n },\n (exception: unknown) => {\n this.#tasks.delete(task);\n this.#taskFailed(exception);\n },\n );\n this.#tasks.add(task);\n }\n}\n\n// =======================================================================================\n// ActorSqlite\n\n/** ← `kj::OneOf<NoTxn, ImplicitTxn*, ExplicitTxn*>`. */\ntype CurrentTxn =\n | { readonly kind: \"none\" }\n | { readonly kind: \"implicit\"; readonly txn: ImplicitTxn }\n | { readonly kind: \"explicit\"; readonly txn: ExplicitTxn };\n\nconst NO_TXN: CurrentTxn = { kind: \"none\" };\n\n/** ← `ActorSqlite::PrecommitAlarmState`. */\ntype PrecommitAlarmState = {\n /** Promise for the completion of precommit alarm scheduling */\n schedulingPromise?: Promise<void>;\n};\n\n/**\n * An implementation of ActorCacheOps that is backed by SqliteKv.\n *\n * Constructing one arranges to honor the output gate, that is, any writes to the\n * database which occur without any `await`s in between will automatically be\n * combined into a single atomic write. This is accomplished using transactions.\n * In addition to ensuring atomicity, this tends to improve performance, as\n * SQLite is able to coalesce writes across statements that modify the same page.\n *\n * `commitCallback` will be invoked after committing a transaction. The output\n * gate will block on the returned promise. This can be used e.g. when the\n * database needs to be replicated to other machines before being considered\n * durable.\n *\n * Members upstream marks `private` and reaches through `ImplicitTxn` and\n * `ExplicitTxn`, which are nested classes with implicit friendship, are ordinary\n * members here for the reason `io-gate.ts` gives: TypeScript has no friendship,\n * and the boundary that actually holds is the package facade in `src/index.ts`.\n */\nexport class ActorSqlite implements ActorCacheInterface {\n /** Upstream-private; reached by the two transaction classes. */\n readonly db: SqliteDatabase;\n /** Upstream-private; reached by the two transaction classes. */\n readonly outputGate: OutputGate;\n /** Upstream-private; reached by the two transaction classes. */\n readonly commitTasks: TaskSet;\n readonly #kv: SqliteKv;\n readonly #metadata: SqliteMetadata;\n\n readonly #commitCallback: () => Promise<void>;\n readonly #hooks: AlarmOutlet;\n\n /** Upstream-private; the transaction classes read it to skip their rollback. */\n broken: unknown | undefined;\n\n /**\n * When set to `none`, there is no transaction outstanding.\n *\n * When set to an `ImplicitTxn`, an implicit transaction is currently open,\n * owned by `commitTasks`. If there is a need to commit this early, e.g. to\n * start an explicit transaction, that can be done through this reference.\n *\n * When set to an `ExplicitTxn`, an explicit transaction is currently open, so\n * no implicit transactions should be used in the meantime.\n */\n currentTxn: CurrentTxn = NO_TXN;\n\n /** If true, then a commit is scheduled as a result of deleteAll() having been called. */\n #deleteAllCommitScheduled = false;\n\n /**\n * State for tracking completion of all commits (both confirmed and\n * unconfirmed) for implementing sync() in onNoPendingFlush.\n *\n * Upstream-private; `ExplicitTxn::commit` replaces it.\n */\n lastCommit: Promise<void> = Promise.resolve();\n\n /**\n * We need to track some additional alarm state to guarantee at-least-once\n * alarm delivery: within an alarm handler, we want the observable alarm state\n * to look like the running alarm was deleted at the start of the handler (when\n * armAlarmHandler() is called), but we don't actually want to persist that\n * deletion until after the handler has successfully completed.\n *\n * Upstream-private; `ExplicitTxn::commit` clears it when the txn was alarm-dirty.\n */\n haveDeferredDelete = false;\n\n /** Some state only used for tracking calling invariants. */\n #inAlarmHandler = false;\n\n /** The alarm state for which we last received confirmation that the db was durably stored. */\n #lastConfirmedAlarmDbState: number | null;\n\n /**\n * The latest time we'd expect a scheduled alarm to fire, given the current set\n * of in-flight scheduling requests, without yet knowing if any of them\n * succeeded or failed. We use this value to maintain the invariant that the\n * scheduled alarm is always equal to or earlier than the alarm value in the\n * persisted database state.\n */\n #alarmScheduledNoLaterThan: number | null;\n\n /** A promise for an in-progress alarm notification update and database commit. */\n #pendingCommit: Promise<void> | undefined;\n\n /**\n * Promise for the currently in-flight \"move alarm later\" operation, if any.\n * Used to serialize move-earlier operations against any pending move-later\n * operation.\n */\n #alarmLaterInFlight: Promise<void> = Promise.resolve();\n\n /** True when a \"move alarm later\" request is currently in-flight via scheduleLaterAlarm(). */\n #alarmLaterIsInFlight = false;\n\n /**\n * When a \"move alarm later\" request is already in-flight and we need to\n * schedule another one, we store the desired alarm time here. When the\n * in-flight request completes, it checks this variable and starts a new\n * request if needed. `undefined` means there is no pending time at all; null\n * means \"clear the alarm\".\n */\n #pendingLaterAlarmTime: number | null | undefined;\n\n /**\n * Version counter that increments on every alarm change. Used to detect if\n * another commit modified the alarm while we were async, allowing us to skip\n * redundant post-commit alarm syncs. This provides automatic coalescing of\n * rapid alarm changes.\n */\n #alarmVersion = 0;\n\n /** ← `DurableObjectStorage::transactionSyncDepth`; see `transactionSync`. */\n #transactionSyncDepth = 0;\n\n constructor(\n db: SqliteDatabase,\n outputGate: OutputGate,\n commitCallback: () => Promise<void>,\n hooks: AlarmOutlet = DEFAULT_ALARM_OUTLET,\n ) {\n this.db = db;\n this.outputGate = outputGate;\n this.#commitCallback = commitCallback;\n this.#hooks = hooks;\n this.#kv = new SqliteKv(db);\n this.#metadata = new SqliteMetadata(db);\n this.commitTasks = new TaskSet((exception) => {\n this.#taskFailed(exception);\n });\n\n db.onWrite((allowUnconfirmed) => {\n this.#onWrite(allowUnconfirmed);\n });\n db.onCriticalError((exception) => {\n this.#onCriticalError(exception);\n });\n this.#lastConfirmedAlarmDbState = this.#metadata.getAlarm();\n\n // Because we preserve an invariant that scheduled alarms are always at or earlier than\n // persisted db alarm state, it should be OK to populate our idea of the latest scheduled alarm\n // using the current db alarm state. At worst, it may perform one unnecessary scheduling\n // request in cases where a previous alarm-state-altering transaction failed.\n this.#alarmScheduledNoLaterThan = this.#metadata.getAlarm();\n }\n\n isCommitScheduled(): boolean {\n return this.currentTxn.kind !== \"none\" || this.#deleteAllCommitScheduled;\n }\n\n getSqliteDatabase(): SqliteDatabase {\n return this.db;\n }\n\n getSqliteKv(): SqliteKv {\n this.requireNotBroken();\n return this.#kv;\n }\n\n // -----------------------------------------------------------------\n // Transaction plumbing\n\n #onCriticalError(exception: SqliteCriticalError): void {\n // If we have already experienced a terminal exception, no need to replace it\n if (this.broken === undefined) {\n const broken = new Error(`broken.outputGateBroken; ${exception.message}`, {\n cause: exception,\n });\n this.broken = broken;\n\n // Also ensure output gate is explicitly broken.\n this.commitTasks.add(this.outputGate.lockWhile(Promise.reject(broken)));\n }\n }\n\n #startImplicitTxn(): void {\n const txn = new ImplicitTxn(this);\n\n // We implement the magic of accumulating all of the writes between JavaScript awaits in one\n // transaction by wrapping the commit function with evalLater, which runs the function on the\n // next turn of the event loop.\n const commitPromise = evalLater(async (): Promise<void> => {\n try {\n // Don't commit if shutdown() has been called.\n this.requireNotBroken();\n\n // Start the schedule request before commit(), for correctness in workerd.\n const precommitAlarmState = this.startPrecommitAlarmScheduling();\n\n try {\n txn.commit();\n } catch (exception) {\n // HACK: If we became broken during `COMMIT TRANSACTION` then throw the broken exception\n // instead of whatever SQLite threw.\n this.requireNotBroken();\n\n // No, we're not broken, so propagate the exception as-is.\n throw exception;\n }\n\n // The callback is only expected to commit writes up until this point. Any new writes that\n // occur while the callback is in progress are NOT included, therefore require a new commit\n // to be scheduled. So, we should drop `txn` to cause `currentTxn` to become NoTxn now,\n // rather than after the callback.\n txn.drop();\n\n await this.commitImpl(precommitAlarmState);\n } finally {\n // ← the coroutine frame's destruction, which rolls the transaction back on any path that\n // did not reach the drop above.\n txn.drop();\n }\n }).catch(async (exception: unknown): Promise<void> => {\n // Unconditionally break the output gate if commit threw an error, no matter whether the\n // commit was confirmed or unconfirmed.\n await this.outputGate.lockWhile(Promise.reject(exception));\n });\n\n this.commitTasks.add(commitPromise);\n\n // Commits must be executed in order, so we only have to track the most recent commit promise.\n this.lastCommit = commitPromise;\n }\n\n #onWrite(allowUnconfirmed: boolean): void {\n this.requireNotBroken();\n if (this.currentTxn.kind === \"none\") {\n this.#startImplicitTxn();\n }\n\n // Update the status of the current transaction.\n const current = this.currentTxn;\n switch (current.kind) {\n case \"none\":\n throw new Error(\"we must have a transaction at this point\");\n case \"implicit\":\n if (!current.txn.isSomeWriteConfirmed() && !allowUnconfirmed) {\n // This is adding a must-confirm write to the transaction, so we must ensure the\n // outputGate locks for remainder of this transaction.\n current.txn.setSomeWriteConfirmed(true);\n this.commitTasks.add(this.outputGate.lockWhile(this.lastCommit));\n }\n break;\n case \"explicit\":\n if (!current.txn.isSomeWriteConfirmed() && !allowUnconfirmed) {\n // ExplicitTxns don't have a pending commit and don't lock the output gate during the\n // transaction, so there's nothing to do here.\n current.txn.setSomeWriteConfirmed(true);\n }\n break;\n }\n }\n\n // -----------------------------------------------------------------\n // Alarm scheduling\n\n /**\n * Issues a request to the alarm scheduler for the given time, returning a\n * promise that resolves when the request is confirmed.\n *\n * Not an `async` function, because it is important for correctness that a\n * synchronously thrown exception in scheduleRun() can escape synchronously to\n * the caller.\n */\n #requestScheduledAlarm(requestedTime: number | null, priorTask: Promise<void>): Promise<void> {\n const movingAlarmLater = willFireEarlier(this.#alarmScheduledNoLaterThan, requestedTime);\n if (movingAlarmLater) {\n // Since we are setting the alarm to be later, we can update alarmScheduledNoLaterThan\n // immediately and still preserve the invariant that the scheduled alarm time is equal to or\n // earlier than the persisted db alarm value.\n this.#alarmScheduledNoLaterThan = requestedTime;\n }\n\n return this.#hooks.scheduleRun(requestedTime, priorTask).then(() => {\n if (!movingAlarmLater) {\n this.#alarmScheduledNoLaterThan = requestedTime;\n }\n });\n }\n\n /**\n * Schedules a \"move alarm later\" operation. If no move-later is currently\n * in-flight, starts one immediately. If one is already in-flight, stores the\n * desired time in `pendingLaterAlarmTime` so it will be picked up when the\n * current in-flight operation completes.\n */\n #scheduleLaterAlarm(newAlarmTime: number | null): void {\n if (this.#alarmLaterIsInFlight) {\n // There's already a move-later request in-flight. Just store the desired time; the in-flight\n // request's completion handler will pick it up and start a new request. This overwrites any\n // previously pending time, which is fine -- only the latest value matters.\n this.#pendingLaterAlarmTime = newAlarmTime;\n return;\n }\n\n this.#alarmLaterIsInFlight = true;\n this.#alarmLaterInFlight = this.#requestScheduledAlarm(\n newAlarmTime,\n this.#alarmLaterInFlight,\n ).catch(() => {\n // If an exception occurs when scheduling the alarm later, it's OK -- the alarm will\n // eventually fire at the earlier time, and the rescheduling will be retried.\n // We catch here to prevent the chain from breaking on errors.\n });\n\n this.commitTasks.add(\n this.#alarmLaterInFlight\n .then(() => {\n this.#alarmLaterIsInFlight = false;\n const nextTime = this.#pendingLaterAlarmTime;\n if (nextTime !== undefined) {\n this.#pendingLaterAlarmTime = undefined;\n this.#scheduleLaterAlarm(nextTime);\n }\n })\n .catch(() => {\n // Move-later alarm failures are non-fatal; catch here to prevent taskFailed() from\n // breaking the output gate.\n }),\n );\n }\n\n /**\n * To be called just before committing the local sqlite db, to synchronously\n * start any necessary alarm scheduling.\n *\n * Upstream-private; `ExplicitTxn::commit` calls it for the root transaction.\n */\n startPrecommitAlarmScheduling(): PrecommitAlarmState {\n const state: PrecommitAlarmState = {};\n if (\n this.#pendingCommit === undefined &&\n willFireEarlier(this.#metadata.getAlarm(), this.#alarmScheduledNoLaterThan)\n ) {\n // We must wait on the `alarmLaterInFlight` promise here, otherwise, if there is an in-flight\n // \"move later\" alarm task and it fails, our \"move earlier\" alarm might interleave, succeed,\n // and be followed by a retry of the in-flight \"move later\" alarm.\n //\n // Clear any pending move-later alarm time. Since we are about to move the alarm earlier, any\n // coalesced later time is now obsolete. This also prevents the scheduleLaterAlarm completion\n // handler from starting a concurrent scheduleRun when it drains pendingLaterAlarmTime after\n // the current in-flight request resolves.\n this.#pendingLaterAlarmTime = undefined;\n state.schedulingPromise = this.#requestScheduledAlarm(\n this.#metadata.getAlarm(),\n this.#alarmLaterInFlight,\n );\n }\n return state;\n }\n\n /**\n * Performs the rest of the asynchronous commit, to be waited on after\n * committing the local sqlite db. Should be called in the same turn of the\n * event loop as startPrecommitAlarmScheduling() and passed the state that it\n * returned.\n *\n * Upstream-private; `ExplicitTxn::commit` calls it for the root transaction.\n */\n async commitImpl(precommitAlarmState: PrecommitAlarmState): Promise<void> {\n // We assume that exceptions thrown during commit will propagate to the caller, such that they\n // will ensure cancelDeferredAlarmDeletion() is called, if necessary.\n\n const pending = this.#pendingCommit;\n if (pending !== undefined) {\n // If an earlier commitImpl() invocation is already in the process of updating precommit\n // alarms but has not yet made the commitCallback() call, it should be OK to wait on it to\n // perform the precommit alarm update and db commit for this invocation, too.\n await pending;\n return;\n }\n\n // There are no pending commits in-flight, so we set up a promise that other callers can wait\n // on, to perform the alarm scheduling and database persistence work for all of them. If an\n // exception is thrown below, it is propagated to the other waiters before it is rethrown, which\n // is what upstream gets from the fulfiller's destructor noticing the stack unwinding.\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n this.#pendingCommit = promise;\n void promise.catch(() => {});\n\n try {\n // Wait for the first precommit alarm scheduling request to complete, if any. This was set up\n // in startPrecommitAlarmScheduling() and is essentially the first iteration of the below\n // loop, but needed to be initiated synchronously before the local database commit to ensure\n // correctness in workerd.\n if (precommitAlarmState.schedulingPromise !== undefined) {\n await precommitAlarmState.schedulingPromise;\n }\n\n // While the local db state requires an earlier alarm than is known might be scheduled, issue\n // an alarm update request for the earlier time and wait for it to complete. This helps ensure\n // that the successfully scheduled alarm time is always earlier or equal to the alarm state in\n // the successfully persisted db.\n //\n // Note that we do not pass alarmLaterInFlight here: we already waited for it above, and\n // `pendingCommit` was set before yielding, so no one could have started another \"move-later\"\n // alarm until we finish.\n while (willFireEarlier(this.#metadata.getAlarm(), this.#alarmScheduledNoLaterThan)) {\n await this.#requestScheduledAlarm(this.#metadata.getAlarm(), Promise.resolve());\n }\n\n // Issue the commitCallback() request to persist the db state, then synchronously clear the\n // pending commit so that the next commitImpl() invocation starts its own set of precommit\n // alarm updates and db commit.\n const alarmStateForCommit = this.#metadata.getAlarm();\n\n // Capture the alarm version before going async to detect concurrent alarm changes. If the\n // alarmVersion changes while we are in-flight, we should skip attempting any move-later alarm\n // update.\n const alarmVersionBeforeAsync = this.#alarmVersion;\n\n const commitCallbackPromise = this.#commitCallback();\n this.#pendingCommit = undefined;\n\n // Wait for the db to persist.\n await commitCallbackPromise;\n this.#lastConfirmedAlarmDbState = alarmStateForCommit;\n\n // Notify any merged commitImpl() requests that the db persistence completed.\n resolve();\n\n // If another commit modified the alarm while we were async, skip post-commit alarm sync.\n //\n // 1. The other commit will handle its own alarm sync\n // 2. Post-commit syncs are inherently optional (the alarm will self-correct)\n // 3. This coalesces redundant alarm updates for better performance\n // 4. This avoids race conditions where a later commit moved the alarm earlier, requiring a\n // pre-commit alarm update, and this update may have already been made before we get here.\n if (this.#alarmVersion === alarmVersionBeforeAsync) {\n // No intervening alarm changes, it is safe to schedule a move-later alarm update if needed.\n if (willFireEarlier(this.#alarmScheduledNoLaterThan, alarmStateForCommit)) {\n this.#scheduleLaterAlarm(alarmStateForCommit);\n }\n }\n } catch (exception) {\n // Upstream leaves `pendingCommit` holding the now-rejected forked promise rather than\n // clearing it: a merged commit still has to see the failure, and by this point the output\n // gate is breaking anyway.\n reject(exception);\n throw exception;\n }\n }\n\n #taskFailed(exception: unknown): void {\n // The output gate should already have been broken since it wraps all commit tasks that can\n // throw. So, we don't have to report anything here, the exception will already propagate\n // elsewhere. We should block further operations, though.\n if (this.broken === undefined) {\n this.broken = exception;\n }\n }\n\n /** Upstream-private; the transaction classes call it before touching the db. */\n requireNotBroken(): void {\n if (this.broken !== undefined) {\n throw this.broken;\n }\n }\n\n /** Called when the deferred alarm deleter is dropped, to delete the alarm if not reset or cancelled during the handler. */\n #maybeDeleteDeferredAlarm(): void {\n // Upstream warns when this runs outside a handler (\"pretty sure this can't happen\"); there is\n // no logger, and the state update below is what the warning accompanies rather than guards.\n this.#inAlarmHandler = false;\n\n if (this.haveDeferredDelete) {\n // If we have reached this point, the client is destroying its DeferredAlarmDeleter at the end\n // of an alarm handler run, and deletion hasn't been cancelled, indicating that the handler\n // returned success.\n //\n // If the output gate has somehow broken in the interim, attempting to write the deletion here\n // will cause the drop to throw, which the caller probably isn't expecting. So we'll skip the\n // deletion attempt, and let the caller detect the gate brokenness through other means.\n if (this.broken === undefined) {\n // The safe thing to do is to require confirmation.\n if (this.#metadata.setAlarm(null, false)) {\n this.#alarmVersion += 1;\n }\n }\n this.haveDeferredDelete = false;\n }\n }\n\n // =======================================================================================\n // ActorCacheInterface implementation\n\n get(key: Key, _options: ReadOptions = {}): Value | undefined {\n this.requireNotBroken();\n return this.#kv.get(key);\n }\n\n getMultiple(keys: readonly Key[], _options: ReadOptions = {}): GetResultList {\n this.requireNotBroken();\n\n const results: KeyValuePair[] = [];\n for (const key of keys) {\n const value = this.#kv.get(key);\n if (value !== undefined) results.push({ key, value });\n }\n results.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));\n return results;\n }\n\n getAlarm(_options: ReadOptions = {}): number | null {\n this.requireNotBroken();\n\n let transactionAlarmDirty = false;\n if (this.currentTxn.kind === \"explicit\") {\n transactionAlarmDirty = this.currentTxn.txn.getAlarmDirty();\n }\n\n if (this.haveDeferredDelete && !transactionAlarmDirty) {\n // If an alarm handler is currently running, and a new alarm time has not been set yet, we\n // need to return that there is no alarm.\n return null;\n }\n return this.#metadata.getAlarm();\n }\n\n list(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n _options: ReadOptions = {},\n ): GetResultList {\n this.requireNotBroken();\n\n const results: KeyValuePair[] = [];\n this.#kv.list(begin, end, limit, \"FORWARD\", (key, value) => {\n results.push({ key, value });\n });\n\n // Already guaranteed sorted.\n return results;\n }\n\n listReverse(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n _options: ReadOptions = {},\n ): GetResultList {\n this.requireNotBroken();\n\n const results: KeyValuePair[] = [];\n this.#kv.list(begin, end, limit, \"REVERSE\", (key, value) => {\n results.push({ key, value });\n });\n\n // Already guaranteed sorted (reversed).\n return results;\n }\n\n put(key: Key, value: Value, options: WriteOptions = {}): void {\n this.requireNotBroken();\n this.#kv.put(key, value, { allowUnconfirmed: options.allowUnconfirmed ?? false });\n }\n\n putMultiple(pairs: readonly KeyValuePair[], options: WriteOptions = {}): void {\n this.requireNotBroken();\n if (this.currentTxn.kind === \"none\") {\n // If we are not in a transaction, start an ImplicitTxn since that's what would happen on the\n // first write anyway. `SqliteKv::put(pairs)` opens with a SAVEPOINT, which is not a write, so\n // without this the savepoint would stand alone instead of nesting inside the transaction.\n this.#startImplicitTxn();\n }\n if (this.currentTxn.kind === \"none\") {\n throw new Error(\"we must have a transaction at this point\");\n }\n\n this.#kv.put(pairs, { allowUnconfirmed: options.allowUnconfirmed ?? false });\n }\n\n delete(key: Key, options: WriteOptions = {}): boolean {\n this.requireNotBroken();\n return this.#kv.delete(key, { allowUnconfirmed: options.allowUnconfirmed ?? false });\n }\n\n deleteMultiple(keys: readonly Key[], options: WriteOptions = {}): number {\n this.requireNotBroken();\n\n let count = 0;\n for (const key of keys) {\n if (this.#kv.delete(key, { allowUnconfirmed: options.allowUnconfirmed ?? false })) count += 1;\n }\n return count;\n }\n\n setAlarm(newAlarmTime: number | null, options: WriteOptions = {}): void {\n this.requireNotBroken();\n\n // Only increment version counter if the alarm value actually changed. This is important because\n // if the value didn't change, no SQLite write occurs, so no implicit transaction is started,\n // and we don't want to invalidate in-flight commits without a replacement commit.\n if (this.#metadata.setAlarm(newAlarmTime, options.allowUnconfirmed ?? false)) {\n this.#alarmVersion += 1;\n }\n\n if (this.currentTxn.kind === \"explicit\") {\n this.currentTxn.txn.setAlarmDirty();\n } else {\n this.haveDeferredDelete = false;\n }\n }\n\n startTransaction(): ActorCacheTransaction {\n this.requireNotBroken();\n return new ExplicitTxn(this);\n }\n\n deleteAll(options: WriteOptions = {}, deleteAllOptions: DeleteAllOptions = {}): DeleteAllResults {\n this.requireNotBroken();\n const effectiveOptions = disableAllowUnconfirmed(options, \"deleteAll is not supported\");\n\n // kv.deleteAll() clears the database, so save and possibly restore the alarm state.\n const localAlarmState = this.#metadata.getAlarm();\n\n // deleteAll() cannot be part of a transaction because it deletes the database altogether. So,\n // we have to close our transactions or fail.\n const current = this.currentTxn;\n switch (current.kind) {\n case \"none\":\n // good\n break;\n case \"implicit\":\n // Whatever the implicit transaction did, it's about to be blown away anyway. Roll it back\n // so we don't waste time flushing these writes anywhere.\n current.txn.rollback();\n this.currentTxn = NO_TXN;\n break;\n case \"explicit\":\n // Keep in mind:\n //\n // ctx.storage.transaction(txn => {\n // txn.deleteAll(); // calls the transaction's deleteAll()\n // ctx.storage.deleteAll(); // calls this method\n // });\n //\n // Directly calling `ctx.storage` inside a transaction (as opposed to using the `txn`\n // object) should still be treated as part of the transaction, and so should throw the\n // same thing.\n throw new Error(\"Cannot call deleteAll() within a transaction\");\n }\n\n if (!this.#deleteAllCommitScheduled) {\n // Make sure a commit callback is queued for the deleteAll().\n this.commitTasks.add(\n this.outputGate.lockWhile(\n evalLater(async (): Promise<void> => {\n // Don't commit if shutdown() has been called.\n this.requireNotBroken();\n\n this.#deleteAllCommitScheduled = false;\n if (this.currentTxn.kind === \"implicit\") {\n // An implicit transaction is already scheduled, so we'll count on it to perform a\n // commit when it's done. This is particularly important for the case where\n // deleteAll() was called while an alarm is outstanding; resetting the alarm state\n // (below) starts an implicit transaction. We don't want to commit the deletion\n // without that transaction.\n return;\n }\n // Use commitImpl() rather than commitCallback() so that alarm scheduling is handled.\n // This is important when deleteAll() deletes an alarm: commitImpl() detects that\n // getAlarm() moved to null and notifies the scheduler via requestScheduledAlarm(null).\n const precommitAlarmState = this.startPrecommitAlarmScheduling();\n await this.commitImpl(precommitAlarmState);\n }),\n ),\n );\n this.#deleteAllCommitScheduled = true;\n }\n\n const count = this.#kv.deleteAll();\n\n // Reset alarm state, if necessary. If no alarm is set, leave the metadata table uninitialized.\n if (localAlarmState !== null) {\n if (deleteAllOptions.deleteAlarm === true) {\n // The reset already removed the alarm metadata. Bump the version so an in-flight commit\n // cannot perform stale post-commit scheduling, and let this commit sync the cancellation.\n this.#alarmVersion += 1;\n this.haveDeferredDelete = false;\n } else if (\n this.#metadata.setAlarm(localAlarmState, effectiveOptions.allowUnconfirmed ?? false)\n ) {\n this.#alarmVersion += 1;\n }\n }\n\n return { backpressure: undefined, count };\n }\n\n evictStale(_now: number): undefined {\n // This implementation never needs to apply backpressure.\n return undefined;\n }\n\n shutdown(exception?: unknown): void {\n if (this.broken === undefined) {\n // Any scheduled flushes will fail once the commit is invoked and notices that `broken` has a\n // value. Any in-flight flushes will continue to run in the background. Remember that these\n // in-flight flushes may or may not be awaited by the worker, but they still hold the output\n // lock as long as `allowUnconfirmed` wasn't used.\n this.broken = exception ?? new Error(SHUTDOWN_ERROR_MESSAGE);\n\n // We explicitly do not schedule a flush to break the output gate. This means that if a\n // request is ongoing after the actor cache is shutting down, the output gate is only broken\n // if they had to send a flush after shutdown, either from a scheduled flush or a retry after\n // failure.\n } else {\n // We've already experienced a terminal exception either from shutdown or OOM, there should\n // already be a flush scheduled that will break the output gate.\n }\n }\n\n armAlarmHandler(scheduledTime: number, currentTime: number): ArmAlarmResult {\n if (this.#inAlarmHandler) {\n throw new Error(\"armAlarmHandler() called while an alarm handler is already running\");\n }\n\n // Upstream warns when `haveDeferredDelete` is already set here (\"unlikely to happen, unless\n // caller is starting new alarm handler before previous alarm handler cleanup has completed\").\n\n const localAlarmState = this.#metadata.getAlarm();\n if (localAlarmState !== scheduledTime) {\n if (localAlarmState === this.#lastConfirmedAlarmDbState) {\n // If the local alarm time is already in the past, just run the handler now. This avoids\n // blocking alarm execution on the alarm manager sync when storage is overloaded. The alarm\n // will either delete itself on success or reschedule on failure.\n if (willFireEarlier(localAlarmState, currentTime)) {\n this.haveDeferredDelete = true;\n this.#inAlarmHandler = true;\n return { kind: \"run\", run: { deferredDelete: this.#newDeferredAlarmDeleter() } };\n }\n\n // If there's a clean db time that differs from the requested handler's scheduled time, this\n // run should be canceled.\n if (willFireEarlier(scheduledTime, localAlarmState)) {\n // If the handler's scheduled time is earlier than the clean scheduled time, we may be\n // recovering from a failed db commit or scheduling request, so we need to request that\n // the alarm be rescheduled for the current db time, and tell the caller to wait for\n // successful rescheduling before cancelling the current handler invocation.\n //\n // Since we're requesting to move the alarm time to later, we need to update the\n // alarmLaterInFlight promise. One branch feeds alarmLaterInFlight with error catching so\n // the chain remains usable, and the other is the returned promise, which propagates\n // errors to the caller. We update alarmLaterInFlight here rather than using\n // scheduleLaterAlarm(), because we need that separate un-caught branch.\n const schedulingPromise = this.#requestScheduledAlarm(\n localAlarmState,\n this.#alarmLaterInFlight,\n );\n // Clear any stale pending time so that when the existing completion handler fires it does\n // not start a redundant scheduleLaterAlarm for the same time that armAlarmHandler is\n // already scheduling.\n this.#pendingLaterAlarmTime = undefined;\n this.#alarmLaterInFlight = schedulingPromise.catch(() => {\n // If an exception occurs when scheduling the alarm later, it's OK -- the alarm will\n // eventually fire at the earlier time, and the rescheduling will be retried.\n });\n return { kind: \"cancel\", cancel: { waitBeforeCancel: schedulingPromise } };\n }\n\n // We have a clean local alarm time that is earlier than the handler's scheduled time, which\n // suggests that either the alarm manager is working with stale data or that the local alarm\n // time has somehow gotten out of sync with the scheduled alarm time.\n //\n // We pass a ready promise because being in this branch (SQLite is ahead of the alarm\n // manager) means there's no recent move-later operation to wait for.\n return {\n kind: \"cancel\",\n cancel: {\n waitBeforeCancel: this.#requestScheduledAlarm(localAlarmState, Promise.resolve()),\n },\n };\n }\n // There's an alarm write that hasn't been set yet pending for a time different than ours --\n // we won't cancel the alarm because it hasn't been confirmed, but we shouldn't delete the\n // pending write.\n this.haveDeferredDelete = false;\n } else {\n this.haveDeferredDelete = true;\n }\n this.#inAlarmHandler = true;\n\n return { kind: \"run\", run: { deferredDelete: this.#newDeferredAlarmDeleter() } };\n }\n\n cancelDeferredAlarmDeletion(): void {\n // Upstream warns when this runs outside a handler (\"pretty sure this can't happen\").\n this.haveDeferredDelete = false;\n }\n\n async abandonAlarm(scheduledTime: number): Promise<number | null> {\n // Called when the alarm scheduler has given up retrying an alarm after too many counted\n // failures. Clear the alarm from SQLite so getAlarm() returns null instead of a stale time.\n // Only clear if SQLite currently has the exact alarm being abandoned and we're not mid-handler.\n // The time check guards against the race where the user set a new alarm (which always has a\n // time >= now() > scheduledTime due to past-time clamping in setAlarm) before this call\n // arrived.\n if (this.#inAlarmHandler) {\n // Shouldn't happen -- the scheduler shouldn't call abandonAlarm while a handler is running.\n return null;\n }\n const storedTime = this.#metadata.getAlarm();\n if (storedTime !== null) {\n if (storedTime === scheduledTime) {\n this.setAlarm(null, {});\n return null;\n }\n // The user set a different alarm. Return it so the scheduler can re-register.\n return storedTime;\n }\n return null;\n }\n\n /**\n * This implements sync().\n *\n * sync() should wait for ALL writes (both confirmed and unconfirmed) that are\n * outstanding at the time sync() is called. We use lastCommit which keeps track\n * of the most recent commit to be formed. We join with the outputGate because\n * there are a lot of edge cases where we break the output gate and it's easiest\n * to catch all of those instances here rather than updating everything to also\n * break lastCommit.\n */\n async onNoPendingFlush(): Promise<void> {\n // ← `kj::joinPromisesFailFast`, which `Promise.all` already is.\n await Promise.all([this.lastCommit, this.outputGate.wait()]);\n }\n\n /**\n * This is an ersatz implementation that's good enough for local dev with D1's\n * Session API.\n *\n * The returned bookmark satisfies the properties that D1 cares about:\n *\n * * Later bookmarks sort after earlier bookmarks. We implement this by\n * incrementing the bookmark whenever getCurrentBookmark() is called.\n *\n * * Bookmarks from the current session sort after bookmarks from previous\n * sessions. We implement this by saving an ersatz bookmark in the metadata\n * table.\n *\n * This is NOT the point-in-time-recovery bookmark API, which is a substrate\n * boundary: it needs nothing the substrate lacks, which is exactly why Section\n * 3 ported `getLocalDevelopmentBookmark`/`setLocalDevelopmentBookmark`.\n */\n async getCurrentBookmark(): Promise<string> {\n this.requireNotBroken();\n let bookmark = 0;\n const stored = this.#metadata.getLocalDevelopmentBookmark();\n if (stored !== null) {\n bookmark = stored + 1;\n }\n this.#metadata.setLocalDevelopmentBookmark(bookmark);\n\n const paddedHex = (value: number): string => value.toString(16).padStart(8, \"0\");\n\n // Turn the bookmark into a format matching what Cloudflare's production returns.\n const uint32Max = 0xffff_ffff;\n return [\n paddedHex(Math.floor(bookmark / uint32Max)),\n paddedHex(bookmark % uint32Max),\n paddedHex(0),\n \"0\".repeat(32),\n ].join(\"-\");\n }\n\n async waitForBookmark(_bookmark: string): Promise<void> {\n // This is an ersatz implementation that's good enough for local dev with D1's Session API.\n this.requireNotBroken();\n }\n\n async getBookmarkForTime(_timestamp: number): Promise<string> {\n throw new Error(PITR_UNIMPLEMENTED_MESSAGE);\n }\n\n async onNextSessionRestoreBookmark(_bookmark: string): Promise<string> {\n throw new Error(PITR_UNIMPLEMENTED_MESSAGE);\n }\n\n ensureReplicas(): void {\n throw new Error(REPLICATION_UNIMPLEMENTED_MESSAGE);\n }\n\n disableReplicas(): void {\n throw new Error(REPLICATION_UNIMPLEMENTED_MESSAGE);\n }\n\n async configureReadReplication(_enabled: boolean): Promise<void> {\n throw new Error(REPLICATION_UNIMPLEMENTED_MESSAGE);\n }\n\n // =======================================================================================\n // transactionSync\n\n /**\n * ← `DurableObjectStorage::transactionSync` (`actor-state.c++:713-753`).\n *\n * One layer lower than upstream, which is where `util/sqlite.ts` already\n * records it belongs: the savepoint depth counter and `notifyWrite` both live\n * here, and `api/actor-state.ts`'s `transactionSync` becomes a one-line forward\n * the way `blockConcurrencyWhile` already is.\n *\n * The nesting guard §2.4 asks for is upstream's own and is the depth-named\n * savepoint: a second `BEGIN IMMEDIATE` is a SQLite error, a nested SAVEPOINT\n * is not, which is why this issues savepoints and lets the implicit transaction\n * underneath be the only `BEGIN`.\n *\n * The async-callback guard is ours and has no upstream twin, because upstream's\n * `jsg::Function<jsg::JsRef<jsg::JsValue>()>` callback cannot be awaited at\n * all: it returns a value, and a JS function that returns a promise simply has\n * its promise ignored. Here the same mistake is silent and corrupting — the\n * RELEASE fires at the first await and everything after it lands outside the\n * transaction — so a thenable result is refused and the savepoint rolled back.\n * Work the callback already started is not cancellable and keeps running; the\n * throw is what stops it being mistaken for transactional.\n */\n transactionSync<T>(callback: () => T): T {\n // SAVEPOINT is a readonly statement, but we need to trigger an outer TRANSACTION.\n this.db.notifyWrite();\n\n const depth = this.#transactionSyncDepth++;\n try {\n this.db.run(`SAVEPOINT _cf_sync_savepoint_${depth}`);\n try {\n const result = callback();\n\n if (isThenable(result)) {\n throw new Error(\n \"transactionSync() callback returned a promise. The transaction commits when the \" +\n \"callback returns, so everything after its first await would land outside it.\",\n );\n }\n\n // If a critical error forced an automatic rollback, we throw an exception to convey failure\n // to the caller of transactionSync(), even if the callback did not throw.\n if (this.db.observedCriticalError() !== undefined) {\n throw new Error(\"Cannot commit transaction due to an earlier SQL critical error\");\n }\n\n this.db.run(`RELEASE _cf_sync_savepoint_${depth}`);\n return result;\n } catch (exception) {\n // If a critical error forced an automatic rollback, we skip the rollback and release\n // attempt, because savepoints should already be released.\n if (this.db.observedCriticalError() === undefined) {\n this.db.run(`ROLLBACK TO _cf_sync_savepoint_${depth}`);\n this.db.run(`RELEASE _cf_sync_savepoint_${depth}`);\n }\n throw exception;\n }\n } finally {\n this.#transactionSyncDepth -= 1;\n }\n }\n\n #newDeferredAlarmDeleter(): DeferredAlarmDeleter {\n let dropped = false;\n return {\n drop: (): void => {\n if (dropped) throw new Error(\"the deferred alarm deleter was dropped twice\");\n dropped = true;\n this.#maybeDeleteDeferredAlarm();\n },\n };\n }\n}\n\nfunction isThenable(value: unknown): boolean {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) return false;\n return typeof (value as { then?: unknown }).then === \"function\";\n}\n\n// =======================================================================================\n// ImplicitTxn\n\n/** ← `ActorSqlite::ImplicitTxn`. */\nclass ImplicitTxn {\n readonly #parent: ActorSqlite;\n #committed = false;\n #dropped = false;\n\n /** True if any of the writes in this commit are confirmed writes. */\n #someWriteConfirmed = false;\n\n constructor(parent: ActorSqlite) {\n if (parent.currentTxn.kind !== \"none\") {\n throw new Error(\"an implicit transaction requires that no transaction is open\");\n }\n this.#parent = parent;\n parent.db.run(\"BEGIN TRANSACTION\");\n parent.currentTxn = { kind: \"implicit\", txn: this };\n }\n\n commit(): void {\n // Ignore redundant commit()s.\n if (!this.#committed) {\n this.#parent.db.run(\"COMMIT TRANSACTION\");\n this.#committed = true;\n }\n }\n\n rollback(): void {\n // As of this writing, rollback() is only called when the database is about to be reset.\n if (!this.#committed) {\n this.#parent.db.run(\"ROLLBACK TRANSACTION\");\n this.#committed = true;\n }\n }\n\n setSomeWriteConfirmed(someWriteConfirmed: boolean): void {\n this.#someWriteConfirmed = someWriteConfirmed;\n }\n\n isSomeWriteConfirmed(): boolean {\n return this.#someWriteConfirmed;\n }\n\n /** ← `~ImplicitTxn`. Idempotent, because the commit path drops before and after the callback. */\n drop(): void {\n if (this.#dropped) return;\n this.#dropped = true;\n\n const current = this.#parent.currentTxn;\n if (current.kind === \"implicit\" && current.txn === this) {\n this.#parent.currentTxn = NO_TXN;\n }\n if (!this.#committed && this.#parent.broken === undefined) {\n // Failed to commit, so roll back.\n //\n // This should only happen in cases of catastrophic error.\n this.#parent.db.run(\"ROLLBACK TRANSACTION\");\n }\n }\n}\n\n// =======================================================================================\n// ExplicitTxn\n\n/** ← `ActorSqlite::ExplicitTxn`. */\nclass ExplicitTxn implements ActorCacheTransaction {\n readonly #actorSqlite: ActorSqlite;\n readonly #parent: ExplicitTxn | undefined;\n readonly #depth: number;\n #hasChild = false;\n #committed = false;\n #dropped = false;\n #alarmDirty = false;\n /** True if any of the writes in this commit are confirmed writes. */\n #someWriteConfirmed = false;\n\n constructor(actorSqlite: ActorSqlite) {\n this.#actorSqlite = actorSqlite;\n\n const current = actorSqlite.currentTxn;\n if (current.kind === \"implicit\") {\n // An implicit transaction is open, commit it now because it would be weird if writes\n // performed before the explicit transaction started were postponed until the transaction\n // completes. Note that this isn't violating any atomicity guarantees because the transaction\n // API is async, and atomicity is only guaranteed over synchronous code.\n current.txn.commit();\n this.#parent = undefined;\n this.#depth = 0;\n } else if (current.kind === \"explicit\") {\n const exp = current.txn;\n if (exp.#hasChild) {\n throw new Error(\n \"critical section should have blocked creation of more than one child at a time\",\n );\n }\n this.#parent = exp;\n exp.#hasChild = true;\n this.#depth = exp.#depth + 1;\n this.#alarmDirty = exp.#alarmDirty;\n this.#someWriteConfirmed = exp.#someWriteConfirmed;\n } else {\n this.#parent = undefined;\n this.#depth = 0;\n }\n actorSqlite.currentTxn = { kind: \"explicit\", txn: this };\n\n // To support nested transactions, we assign each savepoint a name based on its nesting depth.\n actorSqlite.db.run(`SAVEPOINT _cf_savepoint_${this.#depth}`);\n }\n\n getAlarmDirty(): boolean {\n return this.#alarmDirty;\n }\n\n setAlarmDirty(): void {\n this.#alarmDirty = true;\n }\n\n setSomeWriteConfirmed(someWriteConfirmed: boolean): void {\n this.#someWriteConfirmed = someWriteConfirmed;\n }\n\n isSomeWriteConfirmed(): boolean {\n return this.#someWriteConfirmed;\n }\n\n commit(): void {\n const actor = this.#actorSqlite;\n actor.requireNotBroken();\n if (this.#hasChild) {\n throw new Error(\n \"critical sections should have prevented committing transaction while nested txn is \" +\n \"outstanding\",\n );\n }\n\n // Start the schedule request before root transaction commit(), for correctness in workerd.\n const precommitAlarmState =\n this.#parent === undefined ? actor.startPrecommitAlarmScheduling() : undefined;\n\n actor.db.run(`RELEASE _cf_savepoint_${this.#depth}`);\n this.#committed = true;\n\n const parent = this.#parent;\n if (parent !== undefined) {\n if (this.#alarmDirty) parent.#alarmDirty = true;\n if (this.#someWriteConfirmed) parent.#someWriteConfirmed = true;\n // No backpressure for SQLite.\n return;\n }\n\n if (this.#alarmDirty) {\n actor.haveDeferredDelete = false;\n }\n\n // We committed the root transaction, so it's time to signal any replication layer and lock the\n // output gate in the meantime.\n //\n // Unlike ImplicitTxn, which locks the output gate at the start of the first write that requires\n // confirmation, ExplicitTxn only locks when we're going to confirm the commit.\n if (precommitAlarmState === undefined) {\n throw new Error(\"a root transaction committed without precommit alarm state\");\n }\n let commitPromise = actor.commitImpl(precommitAlarmState).catch(\n async (exception: unknown): Promise<void> => {\n // Unconditionally break the output gate if commit threw an error, no matter whether the\n // commit was confirmed or unconfirmed.\n await actor.outputGate.lockWhile(Promise.reject(exception));\n },\n );\n if (this.#someWriteConfirmed) {\n commitPromise = actor.outputGate.lockWhile(commitPromise);\n }\n actor.commitTasks.add(commitPromise);\n actor.lastCommit = commitPromise;\n }\n\n rollback(): void {\n this.#actorSqlite.requireNotBroken();\n if (this.#hasChild) {\n throw new Error(\n \"Cannot roll back an outer transaction while a nested transaction is still running.\",\n );\n }\n if (!this.#committed) {\n this.#rollbackImpl();\n this.#committed = true;\n }\n }\n\n /** ← `~ExplicitTxn`. */\n drop(): void {\n if (this.#dropped) return;\n this.#dropped = true;\n\n let rollbackFailure: { readonly exception: unknown } | undefined;\n if (!this.#committed && this.#actorSqlite.broken === undefined) {\n // Assume rollback if not committed.\n try {\n this.#rollbackImpl();\n } catch (exception) {\n rollbackFailure = { exception };\n }\n }\n\n // ← the `KJ_DEFER([&]() noexcept {...})`: \"We'd better crash if any of this state update fails,\n // otherwise dangling pointers.\" It runs after the rollback no matter what. A JS `finally` that\n // throws would swallow the rollback's own exception, so the rollback's is held and rethrown\n // below instead; if the state update itself throws, that one wins, which is the same ordering\n // upstream's `noexcept` produces.\n if (this.#hasChild) {\n throw new Error(\"an explicit transaction was dropped while a nested one was outstanding\");\n }\n const current = this.#actorSqlite.currentTxn;\n if (current.kind !== \"explicit\" || current.txn !== this) {\n throw new Error(\"an explicit transaction was dropped out of order\");\n }\n const parent = this.#parent;\n if (parent !== undefined) {\n parent.#hasChild = false;\n this.#actorSqlite.currentTxn = { kind: \"explicit\", txn: parent };\n } else {\n this.#actorSqlite.currentTxn = NO_TXN;\n }\n\n if (rollbackFailure !== undefined) throw rollbackFailure.exception;\n }\n\n #rollbackImpl(): void {\n this.#actorSqlite.db.run(`ROLLBACK TO _cf_savepoint_${this.#depth}`);\n this.#actorSqlite.db.run(`RELEASE _cf_savepoint_${this.#depth}`);\n const parent = this.#parent;\n if (parent !== undefined) {\n this.#alarmDirty = parent.#alarmDirty;\n this.#someWriteConfirmed = parent.#someWriteConfirmed;\n } else {\n this.#alarmDirty = false;\n this.#someWriteConfirmed = false;\n }\n }\n\n // Implements ActorCacheOps. These all forward to the ActorSqlite instance.\n\n get(key: Key, options: ReadOptions = {}): Value | undefined {\n return this.#actorSqlite.get(key, options);\n }\n getMultiple(keys: readonly Key[], options: ReadOptions = {}): GetResultList {\n return this.#actorSqlite.getMultiple(keys, options);\n }\n getAlarm(options: ReadOptions = {}): number | null {\n return this.#actorSqlite.getAlarm(options);\n }\n list(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions = {},\n ): GetResultList {\n return this.#actorSqlite.list(begin, end, limit, options);\n }\n listReverse(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions = {},\n ): GetResultList {\n return this.#actorSqlite.listReverse(begin, end, limit, options);\n }\n put(key: Key, value: Value, options: WriteOptions = {}): void {\n this.#actorSqlite.put(key, value, options);\n }\n putMultiple(pairs: readonly KeyValuePair[], options: WriteOptions = {}): void {\n this.#actorSqlite.putMultiple(pairs, options);\n }\n delete(key: Key, options: WriteOptions = {}): boolean {\n return this.#actorSqlite.delete(key, options);\n }\n deleteMultiple(keys: readonly Key[], options: WriteOptions = {}): number {\n return this.#actorSqlite.deleteMultiple(keys, options);\n }\n setAlarm(newAlarmTime: number | null, options: WriteOptions = {}): void {\n this.#actorSqlite.setAlarm(newAlarmTime, options);\n }\n}\n","/**\n * ← workerd `src/workerd/io/worker.h` — `Worker::Actor::FacetManager` only\n * (`io/worker.h:901`).\n *\n * This file exists to settle a layering question the scaffolding got backwards.\n * The facet surface `api/actor-state.ts` consumes was declared in\n * `server/actor-container.ts`, which would give `api/` → `server/` a dependency\n * upstream does not have: `api/actor-state.c++` includes from `api/`, `io/` and\n * `jsg/` and from `server/` never, and the manager it reaches for is a nested\n * class of `Worker::Actor` in `io/worker.h`. Per the README's rule for a\n * legitimate upstream include crossing a wall, the reference widens to match\n * upstream rather than the files being reshuffled to avoid it.\n *\n * `FacetManager` is not the same interface as `server/actor-container.ts`'s\n * `FacetHost`, and conflating them is what produced the inverted dependency.\n * `FacetHost` is the substrate PLACEMENT port — where a facet runs, the callable\n * stub across that placement, and physical storage deletion — and it has no\n * upstream twin, because workerd's facets are in-process. `FacetManager` is the\n * package-owned layer above it that owns naming, ids, the limits, receipts and\n * `clone()` orchestration, and it is the only facet thing `api/` may see.\n * `server/` implements it on top of `FacetHost`.\n *\n * The rest of `worker.h` — `Worker`, `Worker::Isolate`, `Worker::Lock`,\n * `Worker::Actor` itself — is isolate machinery with no port. The three\n * `Worker::Actor` members `io/io-context.ts` reaches for are declared there, as\n * that file's own comment explains; `assertCanSetAlarm()` joins them because\n * `api/actor-state.c++` reaches for it through\n * `IoContext::current().getActorOrThrow()`.\n *\n * Spec: §1.10, decision 14 in docs/decisions.md.\n */\n\nimport type { ActorClassChannel } from \"./io-channels\";\n\n/**\n * ← `Worker::Actor::FacetManager::StartInfo`.\n *\n * `actorClass` is upstream's own type — a resolved\n * `IoChannelFactory::ActorClassChannel`, which `io/io-channels.ts` ports and\n * `DurableObjectClass.getChannel()` produces. An earlier revision typed it as\n * `DurableObjectClass`, the `@cloudflare/workers-types` interface, which is\n * declared `interface DurableObjectClass<_T> {}` and therefore accepts any\n * object at all: it was `unknown` with a name, and it left `server/` with\n * nothing to resolve a class against. Upstream resolves it one step earlier —\n * `DurableObjectFacets::get` calls `actorClass.getChannel(ioCtx)` inside the\n * reentry callback (`actor-state.c++:1044`) — so `api/actor-state.ts` now does\n * the same and this field carries the resolved channel.\n *\n * `id` is upstream's `Worker::Actor::Id` as the string form of a\n * `DurableObjectId`, which is all a `DurableObjectId` is once it leaves this\n * package, since ids never cross the host boundary.\n */\nexport type FacetStartInfo = {\n readonly actorClass: ActorClassChannel;\n /** `ctx.id` for the child. Defaults to the parent's, as upstream's does. */\n readonly id: string;\n};\n\n/**\n * ← `Worker::Actor::FacetManager` (`io/worker.h:901-931`).\n *\n * Upstream's comment on the last three: \"These methods are C++ equivalents of\n * the JavaScript ctx.facets API.\"\n *\n * `cloneFacet` is the fourth, and it is not in the vendored C++ snapshot — see\n * the note on `DurableObjectFacets.clone` in `api/actor-state.ts`.\n */\nexport interface FacetManager {\n /** Returns the nesting depth of this facet. Root = 0, direct child of root = 1, etc. */\n getDepth(): number;\n\n getFacet<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name: string,\n getStartInfo: () => Promise<FacetStartInfo>,\n ): Fetcher<T>;\n\n abortFacet(name: string, reason: unknown): void;\n\n deleteFacet(name: string): void;\n\n /** Aborts `dst`, deletes its storage, then copies the whole `src` subtree onto it. */\n cloneFacet(src: string, dst: string): void;\n}\n\n/**\n * The one type assertion the facet surface needs, in one named place so an\n * implementation does not have to reinvent it.\n *\n * `Fetcher<T>` for an unresolved `T` is `Rpc.Provider<T, …> & { fetch, connect }`\n * — a conditional type TypeScript defers until `T` is known, and `T` is the\n * caller's claim about the shape of a class it named. No value can confirm that\n * claim, so no value can be checked against it. Upstream is in exactly the same\n * position and answers it the same way: `DurableObjectFacets::get` returns a\n * plain `jsg::Ref<Fetcher>` and the type parameter exists only inside a\n * `JSG_TS_OVERRIDE`. What IS checked is the half that carries behaviour —\n * `fetch` and `connect` — because the argument is a `Fetcher` before it is\n * widened.\n */\nexport function asFacetStub<T extends Rpc.DurableObjectBranded | undefined>(\n stub: Fetcher,\n): Fetcher<T> {\n return stub as Fetcher<T>;\n}\n","/**\n * ← workerd `NO upstream correspondence`\n *\n * The substrate replacement for the two includes `server/actor-id-impl.{h,c++}`\n * makes — `<openssl/sha.h>` and `<openssl/hmac.h>` — and nothing else. Only\n * `actor-id-impl.ts` consumes it, which is why it sits here rather than in\n * `util/`: `src/util/` corresponds 1:1 to `src/workerd/util/`, and workerd has no\n * digest there. `server/facet-deletion.ts` sets the precedent for a file in this\n * directory with no upstream twin.\n *\n * **Why this exists at all.** Every method on `ActorIdFactory` is synchronous\n * (`io/actor-id.h:66-71`), and the browser exposes no synchronous digest:\n * `crypto.subtle.digest` returns a promise, and `node:crypto` is one lane only.\n * So the algorithm is written out. It is a **substrate** divergence in decision\n * 16's sense and not a semantic one — the bytes are the bytes FIPS 180-4 and RFC\n * 2104 specify, which is exactly what BoringSSL computes, so an id minted here is\n * the same 64 hex digits workerd mints from the same unique key. That equality is\n * the whole reason for writing the real digest rather than a cheaper keyed\n * function the reduced threat model would have tolerated: it keeps workerd\n * available as an oracle for ids, where an invented construction would have made\n * every future id question original research.\n *\n * No dependency was added. Nothing in the workspace ships a synchronous SHA-256,\n * and the catalog's `crypto-browserify` is a CommonJS bundler shim for the\n * extension that would not typecheck under this package's `WebWorker`-only lib.\n */\n\n/** ← `SHA256_DIGEST_LENGTH`. */\nexport const SHA256_DIGEST_LENGTH = 32;\n\n/** SHA-256's block size, and therefore HMAC's — RFC 2104's `B`. */\nconst BLOCK_LENGTH = 64;\n\n/** FIPS 180-4 §4.2.2: the first 32 bits of the cube roots of the first 64 primes. */\n// prettier-ignore\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\n/** FIPS 180-4 §5.3.3: the first 32 bits of the square roots of the first 8 primes. */\n// prettier-ignore\nconst INITIAL_HASH = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/**\n * `noUncheckedIndexedAccess` types every element read as possibly undefined.\n * Every index below is in range by construction, and this package does not\n * substitute a value for one that should not be missing.\n */\nfunction at(array: Uint8Array | Uint32Array, index: number): number {\n const value = array[index];\n if (value === undefined) throw new Error(`sha256: index ${index} is outside its array`);\n return value;\n}\n\nfunction rotr(value: number, bits: number): number {\n return ((value >>> bits) | (value << (32 - bits))) >>> 0;\n}\n\n/** ← `SHA256(data, length, out)`. FIPS 180-4 §6.2. */\nexport function sha256(message: Uint8Array): Uint8Array {\n // §5.1.1: append 0x80, then zeroes, then the 64-bit big-endian bit length,\n // padding to a whole number of blocks. The +9 is that one byte plus the eight\n // the length occupies, which is why a 56-byte message needs a second block.\n const paddedLength = (Math.ceil((message.length + 9) / BLOCK_LENGTH) | 0) * BLOCK_LENGTH;\n const padded = new Uint8Array(paddedLength);\n padded.set(message);\n padded[message.length] = 0x80;\n const view = new DataView(padded.buffer);\n // A BigInt because a bit count above 2^53 is not exactly representable as a\n // number, and a message that large is a caller's business rather than ours.\n view.setBigUint64(paddedLength - 8, BigInt(message.length) * 8n, false);\n\n const hash = INITIAL_HASH.slice();\n const w = new Uint32Array(64);\n\n for (let block = 0; block < paddedLength; block += BLOCK_LENGTH) {\n // §6.2.2 step 1: the message schedule.\n for (let i = 0; i < 16; i++) w[i] = view.getUint32(block + i * 4, false);\n for (let i = 16; i < 64; i++) {\n const w15 = at(w, i - 15);\n const w2 = at(w, i - 2);\n const s0 = (rotr(w15, 7) ^ rotr(w15, 18) ^ (w15 >>> 3)) >>> 0;\n const s1 = (rotr(w2, 17) ^ rotr(w2, 19) ^ (w2 >>> 10)) >>> 0;\n w[i] = (at(w, i - 16) + s0 + at(w, i - 7) + s1) >>> 0;\n }\n\n // §6.2.2 step 2.\n let a = at(hash, 0);\n let b = at(hash, 1);\n let c = at(hash, 2);\n let d = at(hash, 3);\n let e = at(hash, 4);\n let f = at(hash, 5);\n let g = at(hash, 6);\n let h = at(hash, 7);\n\n // §6.2.2 step 3.\n for (let i = 0; i < 64; i++) {\n const sigma1 = (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) >>> 0;\n const choice = ((e & f) ^ (~e & g)) >>> 0;\n const temp1 = (h + sigma1 + choice + at(K, i) + at(w, i)) >>> 0;\n const sigma0 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) >>> 0;\n const majority = ((a & b) ^ (a & c) ^ (b & c)) >>> 0;\n const temp2 = (sigma0 + majority) >>> 0;\n\n h = g;\n g = f;\n f = e;\n e = (d + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n\n // §6.2.2 step 4.\n hash[0] = (at(hash, 0) + a) >>> 0;\n hash[1] = (at(hash, 1) + b) >>> 0;\n hash[2] = (at(hash, 2) + c) >>> 0;\n hash[3] = (at(hash, 3) + d) >>> 0;\n hash[4] = (at(hash, 4) + e) >>> 0;\n hash[5] = (at(hash, 5) + f) >>> 0;\n hash[6] = (at(hash, 6) + g) >>> 0;\n hash[7] = (at(hash, 7) + h) >>> 0;\n }\n\n const digest = new Uint8Array(SHA256_DIGEST_LENGTH);\n const digestView = new DataView(digest.buffer);\n for (let i = 0; i < 8; i++) digestView.setUint32(i * 4, at(hash, i), false);\n return digest;\n}\n\n/**\n * ← `HMAC(EVP_sha256(), key, keyLength, data, dataLength, out, &outLength)`.\n * RFC 2104.\n *\n * Upstream's comment on why a MAC is used for something that is not\n * authentication: \"We're using HMAC as a keyed hash here, not actually for\n * authentication, but it works\" (`actor-id-impl.c++:74-75`).\n */\nexport function hmacSha256(key: Uint8Array, message: Uint8Array): Uint8Array {\n // RFC 2104 §2: a key longer than one block is replaced by its own digest, and\n // a shorter one is zero-padded. Exactly one block is used as it stands, which\n // is why the comparison is `>` and not `>=`.\n const block = new Uint8Array(BLOCK_LENGTH);\n block.set(key.length > BLOCK_LENGTH ? sha256(key) : key);\n\n const inner = new Uint8Array(BLOCK_LENGTH + message.length);\n const outer = new Uint8Array(BLOCK_LENGTH + SHA256_DIGEST_LENGTH);\n for (let i = 0; i < BLOCK_LENGTH; i++) {\n inner[i] = at(block, i) ^ 0x36;\n outer[i] = at(block, i) ^ 0x5c;\n }\n inner.set(message, BLOCK_LENGTH);\n outer.set(sha256(inner), BLOCK_LENGTH);\n return sha256(outer);\n}\n","/**\n * ← workerd `src/workerd/server/actor-id-impl.{h,c++}`\n *\n * The implementation behind `io/actor-id.ts`'s two interfaces, which that file's\n * header names as Section 6's problem: \"upstream's is a keyed SHA-256\n * construction … a faithful port of it needs a synchronous digest, which the\n * browser does not expose.\"\n *\n * **What upstream computes.** The factory's key is `SHA256(uniqueKey)`, where\n * `uniqueKey` is the namespace's configured string (`workerd-api.c++:675`).\n * An id is 32 bytes in two halves: a 16-byte base and the first 16 bytes of\n * `HMAC-SHA256(key, base)` — `computeMac` (`actor-id-impl.c++:115-125`), which\n * writes a full 32-byte HMAC into a 48-byte working buffer of which only the\n * first 32 bytes ever become the id. `idFromName` derives the base from\n * `HMAC-SHA256(key, name)` (`:71-83`); `newUniqueId` draws it from the entropy\n * source (`:48-69`); `idFromString` takes it from the supplied hex and refuses\n * the string unless the MAC it recomputes matches the half that came with it\n * (`:85-100`). `toString` is `kj::encodeHex` of the 32 bytes.\n *\n * **The digest is written out; the bytes are unchanged.** Every method on\n * `ActorIdFactory` is synchronous (`io/actor-id.h:66-71`) and no browser API\n * offers a synchronous digest, so `server/sha256.ts` supplies SHA-256 and\n * HMAC-SHA-256 in place of BoringSSL. It computes what FIPS 180-4 and RFC 2104\n * specify, so this is decision 16's **substrate** divergence and not a semantic\n * one: `idFromName` here produces the identical 64 hex digits workerd produces\n * from the same unique key, which keeps workerd usable as an oracle for ids.\n *\n * That equality is why the construction is ported whole rather than narrowed.\n * The reduced threat model would have tolerated much less — ids never cross the\n * host boundary, there is no colo, no jurisdiction routing and no second worker\n * re-deriving an id from the same key, so nothing here forges an id — but only\n * two of the contract's properties are cheap to satisfy any other way. The other\n * two are not: `idFromName` must be **stable forever**, because the id names the\n * actor's storage and a name that hashed differently after a restart loses its\n * data; and `idFromString` must **refuse a string this namespace did not mint**,\n * which is a decision only the keyed MAC half can make. A narrower construction\n * would have satisfied both and cost the oracle, turning every future question\n * about an id into original research on a bespoke artifact — the failure the\n * \"Porting philosophy\" section describes.\n *\n * **`isPredictableModeForTest()` is absent** (`actor-id-impl.c++:59-62`). It is a\n * `util/thread-scopes.h` process-global test hack with no port here, it makes\n * `newUniqueId` return a counter, and `actor-id-impl-test.c++` does not use it.\n * Its body is also wrong upstream: `kj::arrayPtr(id).slice(counter)` slices by\n * the counter's *value*, which is a no-op for every counter it can legitimately\n * reach and out of bounds once the counter passes the buffer's 48 bytes.\n *\n * Spec: §1.10 in docs/decisions.md.\n */\n\nimport type { ActorId, ActorIdFactory } from \"../io/actor-id\";\nimport { hmacSha256, sha256, SHA256_DIGEST_LENGTH } from \"./sha256\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← `JSG_REQUIRE(jurisdiction == kj::none, Error, …)` (`actor-id-impl.c++:50-51`,\n * `:108`).\n *\n * Verbatim, \"in workerd\" and all: the conformance suite runs one assertion\n * against both runtimes, so a reworded message would be a difference where there\n * is none.\n */\nexport const JURISDICTION_UNIMPLEMENTED_MESSAGE =\n \"Jurisdiction restrictions are not implemented in workerd.\";\n\n/** ← the first `JSG_REQUIRE` in `idFromString` (`actor-id-impl.c++:87-89`). */\nexport const INVALID_ACTOR_ID_MESSAGE = \"Invalid Durable Object ID: must be 64 hex digits\";\n\n/** ← the second `JSG_REQUIRE` in `idFromString` (`actor-id-impl.c++:96-97`). */\nexport const WRONG_NAMESPACE_ACTOR_ID_MESSAGE =\n \"Durable Object ID is not valid for this namespace.\";\n\n/**\n * Upstream `kj::downcast`s the argument of `equals` (`actor-id-impl.c++:33`),\n * which asserts in a debug build and is undefined in a release one. There is one\n * `ActorId` implementation here, so a correct caller cannot reach this; it fails\n * closed rather than comparing something meaningless.\n */\nexport const FOREIGN_ACTOR_ID_MESSAGE =\n \"This actor id was not created by this runtime, so it cannot be compared with one that was.\";\n\n/** ← `ActorIdFactoryImpl::BASE_LENGTH` — `SHA256_DIGEST_LENGTH / 2` (`actor-id-impl.h:44`). */\nconst BASE_LENGTH = SHA256_DIGEST_LENGTH / 2;\n\n/**\n * The working buffer `newUniqueId`, `idFromName` and `idFromString` all build.\n * Upstream's comment (`actor-id-impl.c++:53-56`): \"We want to randomly-generate\n * the first 16 bytes, then HMAC those to produce the latter 16 bytes. But the\n * HMAC will produce 32 bytes, so we're only taking a prefix of it. We'll allocate\n * a single array big enough to output the HMAC as a suffix, which will then get\n * truncated.\"\n */\nconst WORKING_LENGTH = BASE_LENGTH + SHA256_DIGEST_LENGTH;\n\n/** What `kj::decodeHex` accepts, at the length the first `JSG_REQUIRE` demands. */\nconst ACTOR_ID_PATTERN = /^[0-9a-fA-F]{64}$/;\n\nconst encoder = new TextEncoder();\n\n// =======================================================================================\n// ActorIdImpl\n\n/** ← `ActorIdFactoryImpl::ActorIdImpl` (`actor-id-impl.h:13-30`). */\nexport class ActorIdImpl implements ActorId {\n readonly #id: Uint8Array;\n #name: string | undefined;\n\n /**\n * ← the constructor (`actor-id-impl.c++:14-18`). Its parameter is declared\n * `const kj::byte idParam[SHA256_DIGEST_LENGTH]` and its body `memcpy`s\n * exactly `sizeof(id)` bytes, so a caller may hand over the longer working\n * buffer and only its first 32 bytes become the id. The copy is upstream's\n * too — a later write to the caller's buffer is not seen here.\n */\n constructor(id: Uint8Array, name: string | undefined) {\n if (id.length < SHA256_DIGEST_LENGTH) {\n throw new Error(`an actor id is ${SHA256_DIGEST_LENGTH} bytes, and this buffer holds ${id.length}`);\n }\n this.#id = id.slice(0, SHA256_DIGEST_LENGTH);\n this.#name = name;\n }\n\n /** ← `toString()` — `kj::encodeHex`, which is lowercase (`actor-id-impl.c++:20-22`). */\n toString(): string {\n let out = \"\";\n for (const byte of this.#id) out += byte.toString(16).padStart(2, \"0\");\n return out;\n }\n\n /** ← `getName()` (`actor-id-impl.c++:24-26`). */\n getName(): string | undefined {\n return this.#name;\n }\n\n /** ← `getJurisdiction()`, which is unconditionally none (`actor-id-impl.c++:28-30`). */\n getJurisdiction(): string | undefined {\n return undefined;\n }\n\n /**\n * ← `equals()` (`actor-id-impl.c++:32-34`). The id bytes only — the name is\n * deliberately not part of identity, which is what upstream's own table\n * asserts by giving two equal ids different names.\n */\n equals(other: ActorId): boolean {\n if (!(other instanceof ActorIdImpl)) throw new Error(FOREIGN_ACTOR_ID_MESSAGE);\n const mine = this.#id;\n const theirs = other.#id;\n for (let i = 0; i < SHA256_DIGEST_LENGTH; i++) {\n if (mine[i] !== theirs[i]) return false;\n }\n return true;\n }\n\n /** ← `clearName()` (`actor-id-impl.h:23-25`). Not JS-visible; `server/` calls it. */\n clearName(): void {\n this.#name = undefined;\n }\n}\n\n// =======================================================================================\n// ActorIdFactoryImpl\n\n/** ← `ActorIdFactoryImpl` (`actor-id-impl.h:8-46`). */\nexport class ActorIdFactoryImpl implements ActorIdFactory {\n readonly #key: Uint8Array;\n\n /**\n * ← both constructors (`actor-id-impl.c++:40-46`). C++ overloads on the\n * parameter type; one constructor branching on it is the same two behaviours.\n * The string form is the namespace's configured `uniqueKey`\n * (`workerd-api.c++:675`, `:680`); the byte form exists for\n * `cloneWithJurisdiction`, which passes the already-derived key.\n */\n constructor(uniqueKey: string | Uint8Array) {\n if (typeof uniqueKey === \"string\") {\n this.#key = sha256(encoder.encode(uniqueKey));\n return;\n }\n if (uniqueKey.length !== SHA256_DIGEST_LENGTH) {\n throw new Error(`an actor id factory key is ${SHA256_DIGEST_LENGTH} bytes`);\n }\n this.#key = uniqueKey.slice();\n }\n\n /** ← `newUniqueId()` (`actor-id-impl.c++:48-69`). */\n newUniqueId(jurisdiction: string | undefined): ActorId {\n if (jurisdiction !== undefined) throw new Error(JURISDICTION_UNIMPLEMENTED_MESSAGE);\n\n const id = new Uint8Array(WORKING_LENGTH);\n // ← `getEntropy(kj::arrayPtr(id, BASE_LENGTH))` (`util/entropy.h`): \"Fills\n // `output` with cryptographically-random bytes.\"\n crypto.getRandomValues(id.subarray(0, BASE_LENGTH));\n this.#computeMac(id);\n return new ActorIdImpl(id, undefined);\n }\n\n /** ← `idFromName()` (`actor-id-impl.c++:71-83`). */\n idFromName(name: string): ActorId {\n const id = new Uint8Array(WORKING_LENGTH);\n\n // Compute the first half of the ID by HMACing the name itself. We're using HMAC as a keyed\n // hash here, not actually for authentication, but it works.\n id.set(hmacSha256(this.#key, encoder.encode(name)));\n\n this.#computeMac(id);\n return new ActorIdImpl(id, name);\n }\n\n /** ← `idFromString()` (`actor-id-impl.c++:85-100`). */\n idFromString(str: string): ActorId {\n // Upstream's three conditions — 64 characters, `kj::decodeHex` reported no\n // errors, 32 bytes out — are one test here, because a 64-character match on\n // this pattern decodes to 32 bytes and cannot report an error.\n if (!ACTOR_ID_PATTERN.test(str)) throw new TypeError(INVALID_ACTOR_ID_MESSAGE);\n const decoded = new Uint8Array(SHA256_DIGEST_LENGTH);\n for (let i = 0; i < SHA256_DIGEST_LENGTH; i++) {\n decoded[i] = Number.parseInt(str.slice(i * 2, i * 2 + 2), 16);\n }\n\n const id = new Uint8Array(WORKING_LENGTH);\n id.set(decoded.subarray(0, BASE_LENGTH));\n this.#computeMac(id);\n\n // Verify that the computed mac matches the input.\n for (let i = 0; i < SHA256_DIGEST_LENGTH - BASE_LENGTH; i++) {\n if (id[BASE_LENGTH + i] !== decoded[BASE_LENGTH + i]) {\n throw new TypeError(WRONG_NAMESPACE_ACTOR_ID_MESSAGE);\n }\n }\n\n return new ActorIdImpl(id, undefined);\n }\n\n /** ← `cloneWithJurisdiction()` (`actor-id-impl.c++:102-109`). */\n cloneWithJurisdiction(maybeJurisdiction: string | undefined): ActorIdFactory {\n if (maybeJurisdiction === undefined) return new ActorIdFactoryImpl(this.#key);\n throw new Error(JURISDICTION_UNIMPLEMENTED_MESSAGE);\n }\n\n /** ← `matchesJurisdiction()`, which is unconditionally true (`actor-id-impl.c++:111-113`). */\n matchesJurisdiction(_id: ActorId): boolean {\n return true;\n }\n\n /**\n * ← `computeMac()` (`actor-id-impl.c++:115-125`). \"Given that the first\n * `BASE_LENGTH` bytes of `id` are filled in, compute the second half of the ID\n * by HMACing the first half. The id must be in a buffer large enough to store\n * the first half of the ID plus a full HMAC, even though only a prefix of the\n * HMAC becomes part of the final ID.\"\n */\n #computeMac(id: Uint8Array): void {\n id.set(hmacSha256(this.#key, id.subarray(0, BASE_LENGTH)), BASE_LENGTH);\n }\n}\n","/**\n * ← workerd `src/workerd/server/facet-tree-index.{h,c++}`\n *\n * Upstream's own summary: \"Implements an index, stored on disk, which maps\n * leaves of a tree to small integers in a stable way.\" One facet — id zero — is\n * the root; every other facet has a parent and a name, names are unique among\n * siblings but not globally, and each (parent, name) pair is assigned the next\n * sequential id the first time it is seen. Deleting a facet does not release its\n * id: recreating the same name under the same parent gets the same id back,\n * which is what decision 14 means by \"stable ids across delete-and-recreate.\"\n *\n * The whole index is held in memory, loaded at construction, because upstream\n * assumes \"the total number of facets created for a single Durable Object over\n * its entire lifetime will never be very large\" (`facet-tree-index.h:19-22`).\n * That is what makes the file append-only, and the append-only format is what\n * makes a torn tail safe to discard: an entry written but not synced cannot have\n * been relied on, so a nonsensical entry ends the read and the remainder is\n * truncated away.\n *\n * **The one seam: `kj::File` becomes `IndexFile`.** Upstream takes a\n * `kj::Own<const kj::File>` and calls exactly four members on it —\n * `readAllBytes`, `write`, `truncate` and `datasync`. There is no `kj/filesystem`\n * port and no reason to build one for four methods, so those four become an\n * interface and `server/` supplies it. Every method is synchronous because every\n * method upstream is, and because `facets.get` is synchronous all the way down;\n * both substrates can answer that (`FileSystemSyncAccessHandle` in a worker,\n * `node:fs`'s sync family), which is the same shape the storage backends already\n * take.\n *\n * **A name is its UTF-8 bytes, not its JS string.** Upstream's names are\n * `kj::String`s, so the on-disk bytes *are* the identity and the ordering.\n * `TextEncoder` is not injective on JS strings — every lone surrogate encodes to\n * U+FFFD — so keying this index by the JS string would let two distinct names\n * collide on disk and share one facet's storage file after a reload. Entries are\n * therefore identified and ordered by their encoded bytes, and `forEachChild`\n * reports the round-tripped name, which is what a reload would report. That also\n * makes the ordering exact: upstream's `kj::TreeSet` orders by `kj::String`'s\n * byte comparison, where JS `<` would order by UTF-16 code unit and disagree for\n * any name mixing astral characters with U+E000..U+FFFF.\n *\n * **The scaffolding recorded a divergence here that is wrong, and it is not\n * kept.** That header said workerd keeps one index per root actor while \"our tree\n * spans workers, so each parent indexes its direct children.\" Upstream's index\n * already *is* keyed by (parent, name) — `getId(parent, name)`,\n * `forEachChild(parentId, …)` — so a per-parent index changes nothing about what\n * is indexed and only changes what an id *means*: upstream's ids are sequential\n * across the whole tree, and they name storage files in one flat namespace,\n * `<actor-id>.<facetId>.sqlite` (`server.c++:2737-2743`). Per-parent counters\n * would mint id 1 under every parent and collide those files. Nor does the\n * premise hold: the index is owned by the root *container*, not by an actor's\n * worker (`server.c++:2680-2681`, `:2697`), and `FacetHost` already speaks a flat\n * `FacetId = number` with a precomputed subtree — which only a whole-tree index\n * can produce. Ported as upstream has it.\n *\n * Spec: §1.10, decision 14 in docs/decisions.md.\n */\n\n/**\n * ← the `kj::File` members `FacetTreeIndex` calls, and nothing else.\n *\n * `datasync()` is not decoration: the format's recovery story is that an entry\n * which was written but never synced was never relied upon, so a substrate that\n * drops it turns a torn tail from \"discard and reassign\" into \"two facets, one\n * id\".\n */\nexport interface IndexFile {\n /** ← `kj::File::readAllBytes()`. Called once, at construction. */\n readAllBytes(): Uint8Array;\n /** ← `kj::File::write(offset, data)`. Extends the file when it writes past the end. */\n write(offset: number, data: Uint8Array): void;\n /** ← `kj::File::truncate(size)`. Only ever shrinks, to drop a corrupted tail. */\n truncate(size: number): void;\n /** ← `kj::File::datasync()`. */\n datasync(): void;\n}\n\n/**\n * ← `FacetTreeIndex::MAGIC_NUMBER` (`facet-tree-index.h:116`). Upstream writes it\n * \"in host byte order (which is little-endian on all supported platforms)\", so\n * every integer in the format is read and written little-endian here.\n */\nconst MAGIC_NUMBER = 0xc4cd_ce5b_c5b0_ef57n;\n\n/** The magic number's width, which is also the offset of the first entry. */\nconst MAGIC_LENGTH = 8;\n\n/** ← `FacetTreeIndex::MAX_ID` — `static_cast<uint16_t>(kj::maxValue)`. */\nconst MAX_ID = 0xffff;\n\n/** ← `sizeof(FacetTreeIndex::EntryHeader)`: two `uint16_t`s, parent id then name length. */\nconst ENTRY_HEADER_LENGTH = 4;\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * A byte sequence as one code unit per byte, which makes it both a byte-exact\n * `Map` key and a byte-lexicographic sort key: JS compares strings by UTF-16 code\n * unit, and over 0..255 that is byte order, with a common prefix sorting first\n * exactly as `memcmp` leaves it.\n */\nfunction byteString(bytes: Uint8Array): string {\n let out = \"\";\n // Chunked because String.fromCharCode is variadic and a name may be 65535\n // bytes long, which is more arguments than a call is guaranteed to accept.\n for (let i = 0; i < bytes.length; i += 4096) {\n out += String.fromCharCode(...bytes.subarray(i, i + 4096));\n }\n return out;\n}\n\n/** ← `FacetTreeIndex::Entry`, plus the encoded form upstream gets for free from `kj::String`. */\ntype Entry = {\n readonly parent: number;\n /** The decoded name, which is what a reload of this file would produce. */\n readonly name: string;\n /** Byte identity and sort key — see the header on why the JS string is neither. */\n readonly nameKey: string;\n};\n\n/** ← `FacetTreeIndex` (`facet-tree-index.h:50-123`). */\nexport class FacetTreeIndex {\n readonly #file: IndexFile;\n\n /**\n * ← `FacetTreeIndex::offset`. \"Offset at which to write the next entry.\n * Typically points to the end of the file (except when a corrupted tail was\n * detected).\"\n */\n #offset = 0;\n\n /**\n * ← `kj::TreeSet<Entry> entries`, split into the two things that set was doing\n * at once. The array is upstream's insertion order — \"there's no need to store\n * the ID of each entry since they are strictly ordered with no erasures\", so\n * index + 1 is the id — and the map is the (parent, name) lookup the tree\n * ordering provided. Sorting moves to `forEachChild`, which is the only reader\n * that wants it.\n */\n readonly #entries: Entry[] = [];\n readonly #byKey = new Map<string, number>();\n\n /**\n * ← the constructor (`facet-tree-index.c++:11-86`). \"Construct the index,\n * reading the given file to populate the initial index, and then arranging to\n * append new entries to the file as needed.\"\n */\n constructor(file: IndexFile) {\n this.#file = file;\n\n // Read the file to populate the initial index\n const fileBytes = file.readAllBytes();\n\n // Check if the magic number is present.\n //\n // If the file size is less than or equal to the magic number size itself, it's possible that a\n // previous session suffered a failure while writing the magic number. In that case we can assume\n // nothing was ever written to the index, so we just rewrite it and start over.\n if (fileBytes.length <= MAGIC_LENGTH) {\n // New file, initialize with magic number.\n const magic = new Uint8Array(MAGIC_LENGTH);\n new DataView(magic.buffer).setBigUint64(0, MAGIC_NUMBER, true);\n file.write(0, magic);\n file.datasync();\n this.#offset = MAGIC_LENGTH;\n return;\n }\n\n const view = new DataView(fileBytes.buffer, fileBytes.byteOffset, fileBytes.byteLength);\n\n // On the other hand, because we datasync() immediately after writing the magic number, we can\n // assume that if _more_ bytes are written than just the magic number, then a failure did _not_\n // occurr during the writing of the magic number, and therefore, if it contains the wrong bytes,\n // the file must be in a format we don't recognize.\n if (view.getBigUint64(0, true) !== MAGIC_NUMBER) {\n throw new Error(\"unknown magic number on facet tree index\");\n }\n this.#offset = MAGIC_LENGTH;\n\n // Read entries\n while (this.#offset + ENTRY_HEADER_LENGTH <= fileBytes.length) {\n if (this.#nextId() > MAX_ID) throw new Error(\"Maximum number of facets exceeded\");\n\n const parentId = view.getUint16(this.#offset, true);\n const nameLength = view.getUint16(this.#offset + 2, true);\n\n // Validation checks\n if (nameLength === 0) {\n // Empty name is invalid.\n break;\n }\n\n if (this.#offset + ENTRY_HEADER_LENGTH + nameLength > fileBytes.length) {\n // Name extends beyond file bounds, invalid.\n break;\n }\n\n if (parentId >= this.#nextId()) {\n // Invalid parent ID (parent must already exist).\n break;\n }\n\n // Extract the name\n const nameBytes = fileBytes.subarray(\n this.#offset + ENTRY_HEADER_LENGTH,\n this.#offset + ENTRY_HEADER_LENGTH + nameLength,\n );\n const nameKey = byteString(nameBytes);\n\n if (this.#byKey.has(`${parentId}:${nameKey}`)) {\n // Duplicate entry is invalid.\n break;\n }\n this.#append({ parent: parentId, name: decoder.decode(nameBytes), nameKey });\n\n // Entry was valid and processed successfully, now we can update the offset\n this.#offset += ENTRY_HEADER_LENGTH + nameLength;\n }\n\n if (this.#offset < fileBytes.length) {\n // It appears we stopped at a corrupted entry. We assume such corruption can only be the result\n // of a power failure in the middle of writing an entry during a past session. Any entry which\n // was written but not synced can be presumed to have never been used, so we can simply\n // truncate it from the file.\n file.truncate(this.#offset);\n }\n }\n\n /** ← `FacetTreeIndex::getId`. \"Gets the ID for the given facet, assigning it if needed.\" */\n getId(parent: number, name: string): number {\n const nameBytes = encoder.encode(name);\n if (nameBytes.length === 0) throw new Error(\"Facet name cannot be empty\");\n if (nameBytes.length > MAX_ID) throw new Error(\"Facet name too long\");\n if (parent > this.#entries.length) throw new Error(\"Invalid parent ID\");\n\n const nameKey = byteString(nameBytes);\n const key = `${parent}:${nameKey}`;\n\n // Use findOrCreate to either find an existing entry or create a new one\n const found = this.#byKey.get(key);\n if (found !== undefined) return found + 1;\n\n // New entry, need to assign a new ID and append to file\n if (this.#nextId() > MAX_ID) throw new Error(\"Maximum number of facets exceeded\");\n\n // Prepare entry data\n const entrySize = ENTRY_HEADER_LENGTH + nameBytes.length;\n const entryData = new Uint8Array(entrySize);\n const header = new DataView(entryData.buffer);\n header.setUint16(0, parent, true);\n header.setUint16(2, nameBytes.length, true);\n entryData.set(nameBytes, ENTRY_HEADER_LENGTH);\n\n this.#file.write(this.#offset, entryData);\n\n // We don't want to return an entry that might disappear after a power failure, so sync it\n // now.\n this.#file.datasync();\n\n this.#offset += entrySize;\n\n // Calculate the ID based on the entry's position in the set\n // Root facet (ID 0) isn't in the entries set, so add 1 to the index\n return this.#append({ parent, name: decoder.decode(nameBytes), nameKey }) + 1;\n }\n\n /**\n * ← `FacetTreeIndex::forEachChild`. \"For each child of the given parent ID,\n * call the callback.\"\n *\n * Upstream walks a `kj::TreeSet` range, so children arrive ordered by name\n * rather than by id; the sort here is that ordering, over the same bytes.\n */\n forEachChild(parentId: number, callback: (childId: number, name: string) => void): void {\n const children: { id: number; entry: Entry }[] = [];\n this.#entries.forEach((entry, index) => {\n if (entry.parent === parentId) children.push({ id: index + 1, entry });\n });\n children.sort((a, b) => (a.entry.nameKey < b.entry.nameKey ? -1 : 1));\n for (const child of children) callback(child.id, child.entry.name);\n }\n\n /** ← `FacetTreeIndex::nextId`. \"Off-by-one due to root not being in the set.\" */\n #nextId(): number {\n return this.#entries.length + 1;\n }\n\n /** Adds one entry in insertion order and returns its index, which is its id minus one. */\n #append(entry: Entry): number {\n const index = this.#entries.length;\n this.#entries.push(entry);\n this.#byKey.set(`${entry.parent}:${entry.nameKey}`, index);\n return index;\n }\n}\n","/**\n * ← workerd `NO upstream correspondence`\n *\n * Generation-fenced deletion receipts, serialized subtree deletion, reference\n * epochs. Keyed by facet id, never by an app address.\n *\n * **Why there is no upstream twin.** `ActorContainer::deleteFacet`\n * (`server.c++:2642-2655`) aborts the child and then calls\n * `directory->remove(...)` — synchronous, in-process, on a real filesystem. It\n * cannot be interrupted between \"the app asked\" and \"the bytes are gone\", so it\n * needs no record that it was asked. Here the same call is\n * `FacetHost.deleteStorage`, which is asynchronous because it is the HOST's and a\n * host's storage removal is not required to be prompt: OPFS removal is\n * asynchronous in general, and the extension's supervisor crosses a worker to do\n * it. `ctx.facets.delete()` is synchronous and `void` regardless — so the app's\n * request outlives the process that has to carry it out. §2.7 records the browser\n * host's answer to that, generation-fenced receipts, as \"a genuine improvement\n * over workerd, which has no equivalent because its facets are in-process\". This\n * is that answer, moved down into the runtime and re-keyed.\n *\n * In-process facets do not remove this gap. What upstream gets from them is that\n * `kj::Directory::remove` is a synchronous call it can finish before returning.\n * The seam here is `Promise<void>` whoever implements it, so the gap between \"the\n * app asked\" and \"the bytes are gone\" is still real and still spans a possible\n * teardown. The two conformance lanes happen to close that gap promptly — one\n * through `rmSync`, one through the SAH pool's `unlink` — and the receipt is what\n * makes a host that cannot, such as the extension's supervisor, survivable.\n *\n * **What changed in the move, and it is the whole of the change.** The\n * extension's version (`offscreen/worker/host/facet-deletion.ts`) is keyed by an\n * `AgentWorkerAddress` — a root name plus a path of `{className, name}` steps —\n * and derives \"is this address inside that subtree\" by comparing path prefixes.\n * Here the key is a `FacetId`, the small integer `server/facet-tree-index.ts`\n * assigns, and ancestry is not derivable from it: id 7 says nothing about who its\n * parent is. So every operation that needs a subtree is *given* one, computed\n * from the index by the caller that already holds it, and this file has no\n * opinion about tree shape at all. That is a smaller module, not a larger one:\n * three of the extension's helpers — `isAgentAddressInTree`,\n * `isAgentStorageKeyInTree`, `isAgentStorageEntryInTree` — exist only to answer\n * the ancestry question from a string, and none of them has anything to do here.\n *\n * Storage is the facet-tree database rather than the actor's own, and that is\n * load bearing: `SqliteKv::deleteAll()` calls `db.reset()`\n * (`util/sqlite-kv.ts`), which replaces the actor's database file wholesale. A\n * receipt recorded there would be destroyed by the very `deleteAll()` whose\n * cascade it exists to make recoverable. It sits beside the tree index for the\n * same reason the index does — both are facts about the tree rather than about\n * any one actor's contents.\n *\n * Spec: §2.7, decision 14 in docs/decisions.md.\n */\n\nimport { hasCurrentSqliteTable, type SqlDatabase } from \"../util/sqlite\";\nimport type { FacetId } from \"./actor-container\";\n\n/** The table the receipts live in, beside the tree index. */\nconst RECEIPTS_TABLE = \"_cf_FACET_DELETIONS\";\nconst CREATE_RECEIPTS_TABLE = `CREATE TABLE IF NOT EXISTS ${RECEIPTS_TABLE} (\n facet_id INTEGER PRIMARY KEY,\n generation INTEGER NOT NULL\n)`;\n\n/**\n * One recorded intent to delete a facet's storage.\n *\n * `generation` is the fence. A receipt is cleared only if the row still carries\n * the generation this receipt was issued with, so a delete that was requested\n * again while the first deletion was in flight cannot have its second request\n * erased by the first request's completion.\n */\nexport type FacetDeletionReceipt = {\n readonly id: FacetId;\n readonly generation: number;\n};\n\n/**\n * Parent-owned durable receipts for the synchronous `ctx.facets.delete()`\n * boundary. The doomed child never owns its own deletion decision — it may not\n * be running, and if it is, it is the thing being destroyed.\n */\nexport class FacetDeletionReceiptStore {\n readonly #db: SqlDatabase;\n\n constructor(db: SqlDatabase) {\n this.#db = db;\n hasCurrentSqliteTable(db, RECEIPTS_TABLE, CREATE_RECEIPTS_TABLE);\n this.#db.exec(CREATE_RECEIPTS_TABLE, []);\n }\n\n /** Bumps the generation for `id` and returns the receipt naming it. */\n record(id: FacetId): FacetDeletionReceipt {\n requireFacetId(id);\n // One statement, so it is one implicit SQLite transaction and is durable when it returns —\n // which is what lets `ctx.facets.delete()` stay synchronous and still be recoverable. The\n // extension's version wrapped the read and the write in `transactionSync`; a single upsert\n // that computes the next generation from the row it is replacing needs no transaction at all.\n const rows = this.#db.exec(\n `INSERT INTO ${RECEIPTS_TABLE} (facet_id, generation)\n VALUES (?, 1)\n ON CONFLICT(facet_id) DO UPDATE SET generation = generation + 1\n RETURNING generation`,\n [id],\n ).rawRows;\n const generation = rows[0]?.[0];\n if (typeof generation !== \"number\" || !Number.isSafeInteger(generation) || generation <= 0) {\n throw new Error(`recording a facet deletion receipt for ${id} produced no generation`);\n }\n return { id, generation };\n }\n\n read(id: FacetId): FacetDeletionReceipt | undefined {\n requireFacetId(id);\n const rows = this.#db.exec(`SELECT generation FROM ${RECEIPTS_TABLE} WHERE facet_id = ?`, [\n id,\n ]).rawRows;\n const row = rows[0];\n if (row === undefined) return undefined;\n return { id, generation: requireGeneration(id, row[0]) };\n }\n\n /**\n * Every outstanding receipt, oldest facet first, for boot-time replay.\n *\n * The `ORDER BY` cannot be shown to matter and is kept anyway: `facet_id` is\n * an `INTEGER PRIMARY KEY`, which is the rowid, so both backends scan the\n * table in that order with or without it. Removing it survives the whole\n * suite — a mutant that no test can kill, because killing it needs a SQLite\n * that returns rows out of rowid order, and nothing this package can reach\n * does. Relying on the scan order rather than saying so is the kind of thing\n * that is right until a schema change makes it silently wrong.\n */\n list(): FacetDeletionReceipt[] {\n return this.#db\n .exec(`SELECT facet_id, generation FROM ${RECEIPTS_TABLE} ORDER BY facet_id`, [])\n .rawRows.map((row) => {\n const id = row[0];\n if (typeof id !== \"number\" || !Number.isSafeInteger(id) || id <= 0) {\n throw new Error(`facet deletion receipt has an invalid facet id: ${String(id)}`);\n }\n return { id, generation: requireGeneration(id, row[1]) };\n });\n }\n\n /**\n * Clears the receipt if and only if it is still the one that was issued.\n * Returns false when a newer request has superseded it, which is the whole\n * point of the generation.\n */\n clear(receipt: FacetDeletionReceipt): boolean {\n return (\n this.#db.exec(`DELETE FROM ${RECEIPTS_TABLE} WHERE facet_id = ? AND generation = ?`, [\n receipt.id,\n receipt.generation,\n ]).rowsWritten > 0\n );\n }\n}\n\nfunction requireFacetId(id: FacetId): void {\n if (!Number.isSafeInteger(id) || id <= 0) {\n throw new Error(`a facet deletion receipt names a facet, and ${id} is not one`);\n }\n}\n\nfunction requireGeneration(id: FacetId, value: unknown): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n throw new Error(`facet deletion receipt for ${id} has an invalid generation`);\n }\n return value;\n}\n\n/**\n * Replays and generation-fences one parent's durable child-deletion receipts.\n *\n * Recording is synchronous — that is the boundary `ctx.facets.delete()` has to\n * hold — and only the physical deletion crosses an async boundary. A second\n * delete of the same facet while the first is in flight records a newer\n * generation and queues behind it rather than racing it, so a facet cannot be\n * half-deleted by two overlapping attempts.\n */\nexport class FacetDeletionController {\n readonly #receipts: FacetDeletionReceiptStore;\n readonly #deleteSubtree: (receipt: FacetDeletionReceipt) => Promise<void>;\n readonly #active = new Map<FacetId, { generation: number; promise: Promise<void> }>();\n\n constructor(\n receipts: FacetDeletionReceiptStore,\n deleteSubtree: (receipt: FacetDeletionReceipt) => Promise<void>,\n ) {\n this.#receipts = receipts;\n this.#deleteSubtree = deleteSubtree;\n }\n\n /**\n * Record the intent durably now, then carry it out after the caller's actor\n * ordering has settled. The record is synchronous even when the barrier is\n * still pending.\n */\n delete(id: FacetId, waitBeforeDelete: Promise<unknown> = Promise.resolve()): Promise<void> {\n return this.#run(this.#receipts.record(id), waitBeforeDelete);\n }\n\n /** Carry out whatever is still recorded for `id`, until nothing is. */\n async flush(id: FacetId): Promise<void> {\n for (;;) {\n const receipt = this.#receipts.read(id);\n if (receipt === undefined) return;\n await this.#run(receipt);\n }\n }\n\n /** ← boot. Every receipt a previous session left behind is carried out before the actor runs. */\n async recoverAll(): Promise<void> {\n await Promise.all(this.#receipts.list().map((receipt) => this.flush(receipt.id)));\n }\n\n #run(\n receipt: FacetDeletionReceipt,\n waitBeforeDelete: Promise<unknown> = Promise.resolve(),\n ): Promise<void> {\n const active = this.#active.get(receipt.id);\n // An in-flight attempt at this generation or newer already covers this request.\n if (active !== undefined && active.generation >= receipt.generation) return active.promise;\n\n // A failed predecessor must not stop the successor; it has its own receipt and its own\n // caller to report to.\n const previous = active?.promise.catch(() => undefined) ?? Promise.resolve();\n const ready = Promise.all([previous, waitBeforeDelete.catch(() => undefined)]);\n const promise = ready.then(async () => {\n await this.#deleteSubtree(receipt);\n this.#receipts.clear(receipt);\n });\n const entry = { generation: receipt.generation, promise };\n this.#active.set(receipt.id, entry);\n void promise.then(\n () => this.#clearActive(receipt.id, entry),\n () => this.#clearActive(receipt.id, entry),\n );\n return promise;\n }\n\n #clearActive(id: FacetId, entry: { generation: number; promise: Promise<void> }): void {\n if (this.#active.get(id) === entry) this.#active.delete(id);\n }\n}\n\n/**\n * Serializes physical subtree deletion while retaining subtree-aware waits.\n *\n * Two deletions that overlap in the tree must not run at once: the inner one\n * would be removing files the outer one is walking. Serializing every deletion\n * is the simplest thing that is correct, and deletion is not on any hot path.\n * `waitFor` is the other half — anything about to *use* a facet has to wait for\n * a pending deletion that covers it, and the ids each pending operation covers\n * are recorded rather than derived, because a facet id does not encode its\n * ancestry.\n */\nexport class SerializedSubtreeDeletionQueue {\n readonly #pending = new Map<Promise<void>, ReadonlySet<FacetId>>();\n #tail: Promise<void> = Promise.resolve();\n\n /** Runs `operation` after every operation already queued, covering `ids`. */\n run(ids: Iterable<FacetId>, operation: () => Promise<void>): Promise<void> {\n const covered = new Set(ids);\n // The tail swallows failures so one failed deletion does not cancel every later one; the\n // returned promise still carries the failure to its own caller.\n const promise = this.#tail.then(operation);\n this.#tail = promise.catch(() => undefined);\n this.#pending.set(promise, covered);\n void this.#tail.then(() => {\n this.#pending.delete(promise);\n });\n return promise;\n }\n\n /** Resolves once no queued deletion covers `id`. Failures are not the waiter's to report. */\n async waitFor(id: FacetId): Promise<void> {\n const barriers: Promise<unknown>[] = [];\n for (const [promise, covered] of this.#pending) {\n if (covered.has(id)) barriers.push(promise.catch(() => undefined));\n }\n await Promise.all(barriers);\n }\n}\n\n/**\n * Epochs make every capability captured before an ancestor abort or delete\n * stale.\n *\n * The hazard this closes has no workerd equivalent for the same reason the\n * receipts do not: upstream's `abortFacet` erases the map entry and the stub\n * that was handed out is refcounted against a container that is now broken, so\n * a later call on it fails by itself. Here the stub is a value that outlives the\n * placement, so something has to be able to say \"the thing you are holding was\n * torn down\". Invalidation is by explicit subtree because a `FacetId` does not\n * encode ancestry.\n */\nexport class FacetReferenceEpochs {\n readonly #epochs = new Map<FacetId, number>();\n\n /** The epoch to remember alongside a capability. */\n capture(id: FacetId): number {\n const epoch = this.#epochs.get(id) ?? 0;\n this.#epochs.set(id, epoch);\n return epoch;\n }\n\n /** Bumps `root` and every id in `subtree`, so captures older than this call stop matching. */\n invalidate(root: FacetId, subtree: Iterable<FacetId> = []): void {\n const ids = new Set<FacetId>([root, ...subtree]);\n for (const id of ids) this.#epochs.set(id, (this.#epochs.get(id) ?? 0) + 1);\n }\n\n isCurrent(id: FacetId, epoch: number): boolean {\n return (this.#epochs.get(id) ?? 0) === epoch;\n }\n}\n","/**\n * ← workerd `src/workerd/server/server.c++` — `ActorNamespace::ActorContainer`\n * (`:2383-2968`), which is at once the supervisor's per-actor record, its\n * `Worker::Actor::FacetManager`, and the code that builds the storage engine.\n *\n * Composes the gates, the context, the storage engine and the facet tree into\n * one actor. Constructs the Durable Object class under workerd's boot\n * semantics, and on break aborts facets, abandons scheduled writes, refuses\n * re-entry, and surfaces `onBroken`.\n *\n * **The three line ranges this file was handed are all in the wrong class, and\n * the right ones are above.** `server.c++:1199-1214`, `:1225-1237` and\n * `:1293-1297` are all inside `Server::DiskDirectoryService` (`:1058`) — the\n * directory-listing branch of a static-file handler, its entry-type switch, and\n * a `sendError(501, \"Not Implemented\")`. None of them has anything to do with\n * actors. The three things they were offered for are real, and are at\n * `:2864-2877` (alarm hooks installed only `if (parent == kj::none)`, with\n * `// TODO(someday): Support alarms in facets, somehow.`), `:2885-2897`\n * (`afterReset`, where `deleteAll()`'s cascade to descendant facet storage\n * lives) and `:2603-2620` / `:2953-2956` (`getFacetContainer` and\n * `actorClass->newActor`, the two halves of facet actor construction). Every\n * citation in this file was checked line by line against\n * `e8f1e125bd48f048a3e82c48d37e5e3902fffbd6`, which is the tree Section 6a's\n * citations were taken from and agree with.\n *\n * **Ordering, because it is the part that cannot be read off upstream.**\n * Upstream builds the actor lazily inside `getActor()`, so `ctx.storage` does\n * not exist until the first request arrives and nothing can observe the gap.\n * Here `ActorContainer.state` is a plain property that promises a\n * `DurableObjectState` answering `.storage`, and the database behind it opens\n * asynchronously (`SqlDatabaseProvider.open`, Section 3's seam). Something has to\n * give, and the honest one is the factory: `createActorContainer` returns a\n * promise, and everything it returns is fully built. The alternative — a `state`\n * property that throws until `start()` — is a worse lie, because it makes the\n * one declared field of the public interface conditional on a call the type\n * system cannot see.\n *\n * Spec: §1.6, §1.10, decisions 6 and 14 in\n * docs/decisions.md.\n */\n\nimport { DurableObjectState, DurableObjectStorage } from \"../api/actor-state\";\nimport { DurableObjectId } from \"../api/actor\";\nimport { RpcTarget } from \"../api/cloudflare-workers\";\nimport type { FetchPort } from \"../api/global-scope\";\nimport {\n ActorGlobalScope,\n AlarmInvocationInfo,\n actorScopeBindings,\n isAlarmFailureUserError,\n} from \"../api/global-scope\";\nimport type { AcceptedWebSocket, RawWebSocket } from \"../api/web-socket\";\nimport { acceptWebSocket } from \"../api/web-socket\";\nimport type { IsolateChannelFactory, WorkerLoaderOptions } from \"../api/worker-loader\";\nimport { WorkerLoader } from \"../api/worker-loader\";\nimport type { AlarmOutlet } from \"../io/actor-sqlite\";\nimport { ActorSqlite, DEFAULT_ALARM_OUTLET } from \"../io/actor-sqlite\";\nimport type { AlarmResult } from \"./alarm-scheduler\";\nimport type { Actor, Timer } from \"../io/io-context\";\nimport { IoContext } from \"../io/io-context\";\nimport { InputGate, OutputGate } from \"../io/io-gate\";\nimport type { FacetManager, FacetStartInfo } from \"../io/worker\";\nimport { asFacetStub } from \"../io/worker\";\nimport type { SqlDatabase, SqlDatabaseProvider } from \"../util/sqlite\";\nimport { hasCurrentSqliteTable, SqliteDatabase } from \"../util/sqlite\";\nimport { ActorIdFactoryImpl } from \"./actor-id-impl\";\nimport type { IndexFile } from \"./facet-tree-index\";\nimport { FacetTreeIndex } from \"./facet-tree-index\";\nimport type { FacetDeletionReceipt } from \"./facet-deletion\";\nimport {\n FacetDeletionController,\n FacetDeletionReceiptStore,\n FacetReferenceEpochs,\n SerializedSubtreeDeletionQueue,\n} from \"./facet-deletion\";\n\nexport type FacetId = number;\n\nexport type FacetStartRequest = {\n id: FacetId;\n /** The `facets.get` name, `class\\0name` form preserved. */\n name: string;\n /** Resolved against `ctx.exports` by `api/actor-state.ts`. */\n className: string;\n /** This facet's depth. The container enforces <= 4 including the root. */\n depth: number;\n /**\n * The `ctx.id` the child was told to take, present only when the startup\n * options supplied one. Absent means the child inherits the parent's, which\n * is upstream's `ioCtx.getActorOrThrow().cloneId()` (`actor-state.c++:1026`).\n *\n * The scaffolding called this \"the DurableObjectId name\". It is not\n * necessarily a name: `FacetStartupOptions.id` is `DurableObjectId | string`\n * (`actor-state.h:453`), so this carries a 64-hex id string whenever the app\n * passed a `DurableObjectId`, and whatever the app chose whenever it passed a\n * string. The host decides what to do with it, exactly as upstream's\n * `Worker::Actor::Id` leaves that to the supervisor.\n */\n routedId?: string;\n};\n\nexport interface FacetHandle {\n /**\n * The placement's outcome, resolving to what `facets.get` will call —\n * Fetcher-shaped per §1.10: no id, no name.\n *\n * `start` is synchronous because `facets.get` is, but placing an actor is not: a database\n * has to open and a constructor has to run. Upstream has exactly this shape and\n * does not have to say so — `getFacetContainer` hands `ActorChannelImpl` a\n * `kj::Promise<ClassAndId>` (`server.c++:2603-2620`) and the channel is\n * returned before it resolves, so a failure to construct reaches the caller at\n * the first call on the stub. Measured on workerd 1.20260722.1: a facet whose\n * constructor throws returns a stub from `facets.get()`, rejects the first call\n * with the constructor's own message, and leaves the parent untouched.\n *\n * Keeping the placement promise here makes construction failures observable at\n * the first call and leaves `asFacetTransport` as the sole deferral layer.\n */\n stub: Promise<object>;\n /**\n * Rejects when a RUNNING facet breaks — the signal upstream gets from\n * `actor.onBroken()` and monitors in `monitorOnBroken`\n * (`server.c++:2767-2800`).\n *\n * **A break travels DOWN and never up, so nothing here reaches the parent.**\n * `ActorContainer::abort` (`:2565-2589`) and `monitorOnBroken` each loop\n * `for (auto& facet: facets)` and abort the container's OWN children; a broken\n * child takes itself and its subtree, and nothing above it notices.\n * `conformance/suite/facets.spec.ts` guards this against workerd: the parent and\n * its other facets remain live.\n *\n * `FacetManagerImpl` consumes this signal for `monitorOnBroken`'s two local\n * effects: tell the host to tear down the broken placement (which aborts its\n * descendants), and erase it from the PARENT's facet map (`:2777-2780`,\n * `:2794-2798`). That frees the name for a fresh placement without changing\n * the parent or its siblings.\n *\n * **A placement that never completed does not belong here** — it is a start\n * that failed, not a break, and it travels through `stub`. Measured on\n * workerd: a facet whose construction fails does not break its parent, and the\n * next `facets.get` runs the startup callback again.\n */\n broken: Promise<never>;\n}\n\n/**\n * The facet port. Substrate is only placement, the callable stub across that\n * placement, and physical storage deletion for children a parent cannot open.\n *\n * NOT substrate, and therefore not in this interface: naming, ids, the\n * depth/name/count limits, deletion receipts and epochs, and `clone()`\n * orchestration. Those are package-owned. In particular there is no\n * addressing-strategy port: once\n * the package speaks facet ids, the app-address mapping is the browser\n * adapter's private business and needs no interface at all.\n *\n * This is NOT the interface `api/actor-state.ts` consumes. That one is\n * `io/worker.ts`'s `FacetManager`, upstream's own `Worker::Actor::FacetManager`,\n * which this file implements on top of this port — see that file's header for\n * why the two were conflated and why the fix was to widen rather than reshuffle.\n * The `clone()` orchestration named above is `cloneFacet`'s body, and the\n * limits named above are enforced by `DurableObjectFacets` where upstream\n * enforces them.\n *\n * One host serves a whole actor tree, as upstream's `ActorNamespace` does: every\n * `FacetId` it is handed is an id in the root's index, so a facet's own host\n * must be able to place and remove any of its descendants.\n */\nexport interface FacetHost {\n /**\n * Synchronous, like `facets.get` itself — but the placement it begins is not,\n * and `FacetHandle.stub` is where that is declared. A host reports a placement\n * it could not finish by rejecting that promise, and reports nothing about it\n * on `broken`: see `FacetHandle`.\n *\n * A synchronous throw is still legal and still means the same thing — the\n * facet cannot be started — and `getFacet` turns it into the same rejected\n * stub. What is no longer possible is a host that fails asynchronously and has\n * nowhere to say so.\n */\n start(request: FacetStartRequest): FacetHandle;\n /**\n * Kills the instance; storage survives (measured on workerd).\n *\n * **Never called while a placement for `id` is in flight**, and never before\n * that placement's `stub` has settled. The container orders the two against\n * each other, so a host needs no queue of its own and is never handed an abort\n * for a facet it is still placing — which it could only no-op, its placement\n * map having no entry for the id yet.\n *\n * It may still be called for an id that never ran: a placement that failed, or\n * one refused before `start` was reached. Upstream's is too — `abortFacet`\n * finds the container whether or not its `kj::Promise<ClassAndId>` ever\n * resolved (`server.c++:2635-2640`) — so a host that has nothing to kill\n * should return, not throw.\n */\n abort(id: FacetId, reason?: string): void;\n /**\n * Physical removal, descendants included. `subtree` is the descendants alone,\n * deepest first — upstream removes children before the parent\n * (`server.c++:2754-2759`) — and `id` is the facet itself.\n */\n deleteStorage(id: FacetId, subtree: readonly FacetId[]): Promise<void>;\n /**\n * Physical copy of one facet's storage onto another, for `cloneFacet`. The\n * recursive walk of the source subtree is this file's; copying one database\n * is the substrate's, the same split `deleteStorage` already makes.\n */\n copyStorage(src: FacetId, dst: FacetId): Promise<void>;\n}\n\n/**\n * The `FacetHost` for a host that places no facets — the shape of every first\n * integration, provided so hosts stop re-typing it. `start` refuses by name.\n * `abort` returns, per its contract above: a host with nothing to kill returns.\n * The storage operations refuse, because a call to either proves a facet once\n * existed — which this host could not have placed.\n */\nexport const noFacets: FacetHost = {\n start(): FacetHandle {\n throw new Error(\"this host places no facets\");\n },\n abort(): void {},\n deleteStorage(): Promise<void> {\n return Promise.reject(new Error(\"this host places no facets\"));\n },\n copyStorage(): Promise<void> {\n return Promise.reject(new Error(\"this host places no facets\"));\n },\n};\n\n/**\n * The four ports. Each one is a seam workerd itself takes as a constructor\n * input; a port that would exist only because our code is currently shaped\n * badly is an invented seam and was rejected. Rejected, for the record:\n * a transport port (one implementation per substrate, forever), a logger port\n * (fail closed — errors throw, breakage surfaces on `onBroken`), a value-codec\n * port (giving lanes different codecs would make the Node lane lie about the\n * browser), and an addressing-strategy port (unnecessary once the package\n * speaks facet ids).\n *\n * A fifth, `isolates?: IsolateHost`, was here from the scaffolding and Section 7b\n * removed it. A Worker Loader is a **binding**, not a port: upstream builds it\n * from `Global::WorkerLoader{channel}` alongside every other binding\n * (`server/workerd-api.c++:748`) and it reaches an application through `env`,\n * exactly as `DurableObjectNamespace` and `ctx.exports` already do here. A host\n * constructs `WorkerLoader` over its own `IsolateChannelFactory` and puts it in\n * `env`; the container never sees one. See `api/worker-loader.ts`'s header.\n */\nexport type ActorPorts = {\n sql: SqlDatabaseProvider;\n /**\n * Root containers only — facets have no alarm slot (§1.10).\n *\n * `AlarmScheduler.hooks(actorId)` is the implementation to put here: upstream\n * builds one `AlarmScheduler` per namespace and gives each actor a\n * three-line `ActorSqliteHooks` adapter over it (`server.c++:2325-2350`,\n * `:3199-3219`), which is the same composition.\n */\n alarms: AlarmOutlet;\n facets: FacetHost;\n timer: Timer;\n /**\n * ← the global outbound `Fetcher` a Worker's `fetch` resolves\n * (`api/global-scope.c++:1160`), which `container.globals.fetch` gates.\n *\n * Optional, and absence is upstream's `globalOutbound: null` posture rather\n * than a missing port: a Worker configured that way has no ambient `fetch` at\n * all, which is how Code Mode forces every I/O through connectors (§1.11).\n * `fetch` then refuses by name instead of reaching a `fetch` this package does\n * not own — an ungated one that works is the failure this layer exists to\n * prevent.\n */\n fetch?: FetchPort;\n};\n\n/**\n * The whole-tree facet state, which belongs to the root container and is shared\n * by every container in one actor tree.\n *\n * Upstream keeps the same thing in the same place — \"FacetTreeIndex for this\n * actor. Only initialized on the root\" (`server.c++:2680-2681`), reached from a\n * facet by `root.ensureFacetTreeIndex()` (`:2697`) — and can do so with a plain\n * reference because every facet of an actor is an object in one process. None of\n * these methods can cross a worker boundary: `facets.get()` is synchronous all\n * the way down, so `getId` has to answer without yielding. A facet in another\n * worker cannot be handed this object and therefore cannot have facets of its\n * own. Every host here\n * now places in the parent's realm and passes the root's object straight through.\n *\n * It is an interface rather than a plain reference anyway, because a facet\n * container is constructed on its own and the root's index is the one piece of\n * state it cannot build for itself: ids are sequential across the whole tree. A\n * host that does not supply one gets a facet that cannot have facets of its own\n * and says so, rather than a per-parent counter that would collide the storage.\n */\nexport interface FacetTree {\n /** ← `FacetTreeIndex::getId`. Assigns on first sight, stable thereafter. */\n getId(parent: FacetId, name: string): FacetId;\n /** ← `FacetTreeIndex::forEachChild`, collected. Ordered by the child's UTF-8 name. */\n children(parent: FacetId): readonly { readonly id: FacetId; readonly name: string }[];\n /** ← `deleteDescendantStorage`'s recursion, as a list: descendants only, deepest first. */\n descendants(id: FacetId): FacetId[];\n /**\n * Records the intent durably now, then removes `id` and its descendants after\n * the current parent and descendant operations represented by `waitBeforeDelete`.\n */\n deleteSubtree(id: FacetId, waitBeforeDelete: Promise<unknown>): Promise<void>;\n /** Copies the whole `src` subtree onto `dst`, minting `dst`'s children as it goes. */\n copySubtree(src: FacetId, dst: FacetId): Promise<void>;\n /** Runs one placement or abort after every earlier operation on the same stable facet id. */\n runOperation(id: FacetId, operation: () => Promise<void>): void;\n /** Snapshots the current operation tail for `id` and every indexed descendant. */\n subtreeOperationBarrier(id: FacetId): Promise<void>;\n /**\n * Resolves once no queued deletion still covers `id`, which is what makes a\n * facet re-created under a name that is still being deleted safe to start.\n */\n settled(id: FacetId): Promise<void>;\n /** Every capability captured before an ancestor abort or delete goes stale here. */\n readonly epochs: FacetReferenceEpochs;\n /** ← boot. Carries out every deletion a previous session recorded and did not finish. */\n recoverDeletions(): Promise<void>;\n}\n\n/**\n * ← `IoContext::awaitIo`, as the one primitive a host needs in order to build a\n * platform async primitive of its own.\n */\nexport type ActorContainerOptions = {\n /** The DurableObjectId name. */\n id: string;\n /**\n * The namespace's unique key, upstream's `uniqueKey` configuration field\n * (`server.c++:2919`, read from `config::Worker::DurableObjectNamespace::Durable`).\n * `ActorIdFactoryImpl` derives its factory key as `SHA256(uniqueKey)` and an\n * id as 16 bytes of base plus 16 bytes of `HMAC-SHA256(key, base)`.\n *\n * **The host must keep this stable forever.** `ctx.id` is\n * `idFromName(options.id)` under this key, and the id names the actor's\n * storage, so a key that changes across a restart changes every id and every\n * actor loses its data. There is no default and it is not optional, because a\n * default is exactly the shape that would let a host acquire this obligation\n * without noticing it. This package cannot check the property for itself —\n * nothing it can observe distinguishes \"a new key\" from \"a new actor\" — so\n * this comment is the whole of the enforcement.\n */\n uniqueKey: string;\n /** The `ctx.exports` class registry. Keys are the consumer's concern. */\n exports: Record<string, unknown>;\n env: unknown;\n ports: ActorPorts;\n /** Present when this container hosts a facet rather than a root. */\n facet?: {\n /** Root is 0, a direct child of the root is 1. `getDepth()` answers with it. */\n depth: number;\n /** This facet's own id, the one its parent allocated from the tree index. */\n id: FacetId;\n /** The root-owned tree this facet and every descendant share. */\n tree: FacetTree;\n };\n};\n\n/** The local entry proxy: data properties stay local; every method becomes one async event. */\nexport type ActorEntry<T extends object> = {\n [K in keyof T]: T[K] extends (...args: infer Args) => infer Result\n ? (...args: Args) => Promise<Awaited<Result>>\n : T[K];\n};\n\nexport interface ActorContainer {\n /** Implements the workers-types interface. No `as unknown as` cast (§2.4). */\n readonly state: DurableObjectState;\n\n /**\n * The actor tree this container belongs to, which a root builds for itself and\n * a facet is handed.\n *\n * It is on the interface because the host is the only thing that can carry it\n * from a parent to a child: `FacetHost.start` builds the nested container, and\n * a facet that may have facets of its own needs the root's index rather than\n * one of its own (see `FacetTree`). Upstream needs no equivalent because a\n * facet reaches `root.ensureFacetTreeIndex()` through a plain reference\n * (`server.c++:2697`), and every facet of an actor is an object in one process.\n *\n */\n readonly facetTree: FacetTree;\n\n /**\n * Whether this container owns the synchronous actor slice on the JS stack.\n * This is the narrow identity check a host loopback needs to call the raw\n * instance instead of queueing behind the lock it already holds. It resolves\n * no container and carries no state into continuations.\n */\n isCurrentSlice(): boolean;\n\n /**\n * Whether this actor's input lock is on the current invocation stack.\n *\n * ← `IoContext::hasCurrent()`. Wider than `isCurrentSlice()`: a slice ends\n * when its synchronous body returns, but the lock it took drains the whole\n * microtask checkpoint (§1.2), so actor code chained one promise past a gated\n * resumption is lock-holding without being slice-current. That window is\n * where a host stub still has a caller to identify: an outbound call made\n * there must resume through the caller's `awaitIo`, or the code after it\n * comes back with no input lock and its next storage call throws. A host\n * that resolves callers with `isCurrentSlice()` alone routes exactly those\n * calls ungated, which is how the loss stays invisible until three layers\n * later.\n */\n hasCurrent(): boolean;\n\n /**\n * Construct the instance under workerd's boot semantics: the input gate is\n * held for the constructor's synchronous slice, and boot-time\n * deletion-receipt replay precedes it.\n */\n start<T extends object>(construct: (ctx: DurableObjectState, env: unknown) => T): Promise<T>;\n\n /**\n * THE door for RPC targets. A proxy whose every method invocation is one\n * gated event. This single wrapper is what replaces the serialised tail,\n * all three dispatch tables, and the 33 hand-written exemptions.\n *\n * EVERY call queues, including one made while this actor is holding its own\n * lock across an await. That is §1.2's whole content and the suite pins it: a\n * second event posted while a storage await holds the gate must not interleave,\n * and a door that reused the held lock could not tell that event apart from a\n * call the actor made to itself. Telling them apart needs to know WHO is\n * calling, which is a host's question rather than a container's — see the\n * extension host's `loopbackStub`, where an actor reaching its own\n * `DurableObjectNamespace` binding skips this door entirely because the lock it\n * would take is the one it is already holding.\n */\n entry<T extends object>(target: T): ActorEntry<T>;\n\n /**\n * The door for events that are not method calls — one WebSocket frame, one\n * host-originated callback. Upstream: `IoContext::run`.\n */\n run<T>(event: () => T | PromiseLike<T>): Promise<T>;\n\n /**\n * ← `IoContext::awaitIo`. The form a HOST-PROVIDED async primitive must take,\n * and the only gate primitive this package makes public.\n *\n * Every platform async thing an application can await — `scheduler.wait`, a\n * `fetch`, a WebSocket round trip — is an io-context primitive upstream, which\n * is why \"resuming from an await re-enters the isolate with a fresh input\n * lock\" needs saying nowhere in workerd: there is no other kind of await.\n * There is here. A raw `setTimeout` resolves a promise the runtime does not\n * own, the application's continuation resumes with an empty invocation stack,\n * and its next `ctx.storage` call throws `no input lock available in this\n * context` — the README's divergence 147. Wrapping the promise in this makes\n * the continuation resume inside a gated slice, which is what upstream's does.\n *\n * It releases the input gate for the duration, per §1.3, so the actor stays\n * re-entrant while it waits. The holding form,\n * `IoContext::awaitIoWithInputLock`, is deliberately NOT public: that one is\n * the transaction boundary of §1.7.1, it belongs to the four async storage\n * calls, and a host holding it by hand is the serialised tail growing back.\n */\n awaitIo<T>(promise: Promise<T>): Promise<T>;\n\n /**\n * ← `ServiceWorkerGlobalScope`, the async-primitive half: this actor's\n * `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval`, `fetch` and\n * `scheduler` (`api/global-scope.ts`).\n *\n * **This is what \"own the primitives in the worker global\" means, and the\n * ownership is the point.** `awaitIo` above is the primitive a host needs to\n * build one of these; this is the set already built, so a host installs rather\n * than reimplements the surface.\n *\n * **One scope per actor, installed lexically, and never resolved from an\n * ambient.** Upstream's globals read `IoContext::current()` because acquisition\n * is structural there; this one holds its context. A host puts it where its\n * actor's code reads it — `globalThis` for a class in the worker's own module\n * graph, a module-scoped binding for a class that arrived as a\n * dynamically-loaded Worker source, which is upstream's own arrangement (§1.11:\n * a dynamic Worker has its own global scope bound to its own context). What\n * happens when a facet reaches past its binding to a parent's scope is\n * `ActorGlobalScope`'s `requireOwnSlice`.\n */\n readonly globals: ActorGlobalScope;\n\n /**\n * ← `WebSocket::accept()` / `state.acceptWebSocket()`\n * (`api/web-socket.c++:133`, `:426`), whose gating is `api/web-socket.ts`.\n *\n * Separate from `globals` because accepting is an act rather than a binding:\n * the critical section is captured at THIS call, so a socket accepted inside\n * `blockConcurrencyWhile` delivers its frames inside that section (§1.8).\n */\n acceptWebSocket(socket: RawWebSocket): AcceptedWebSocket;\n\n /**\n * ← `WorkerInterface::runAlarm(scheduledTime, retryCount)`\n * (`io/worker-interface.h:107`), which is what `AlarmScheduler` calls and what\n * `ServiceWorkerGlobalScope::runAlarm` answers. Strictly serialised (§1.8).\n *\n * It reports rather than throws, because the two bits the scheduler's ladder\n * turns on — retry, and whether the retry counts against the limit — are not\n * derivable from \"the promise rejected\".\n *\n * `retryCount` reaches the handler as `AlarmInvocationInfo`. It is the\n * scheduler's `countedRetry` for this alarm, so the container takes it as an\n * argument exactly as upstream's `runAlarm` does.\n */\n deliverAlarm(scheduledTime: number, retryCount: number): Promise<AlarmResult>;\n\n /**\n * ← `WorkerInterface::abandonAlarm` (`io/worker-interface.h:114`), forwarded to\n * `ActorSqlite::abandonAlarm` (`io/actor-sqlite.c++:1039-1060`).\n *\n * Called when the scheduler has given up retrying, so the actor clears its own\n * alarm state and `getAlarm()` stops reporting a time that will never fire.\n * Answers the actor's stored alarm time when it differs from `scheduledTime` —\n * meaning the application set a different one — and null when the alarm was\n * cleared or there was none.\n */\n abandonAlarm(scheduledTime: number): Promise<number | null>;\n\n /**\n * Output-gate wait for outbound sends that do not ride an `entry()` reply.\n * A broadcast path calls this before each frame (decision 5).\n */\n waitOutputLocks(): Promise<void>;\n\n /** For the host's idle check — today's `drainWaitUntil`. */\n drainWaitUntil(): Promise<void>;\n\n /**\n * ← `WorkerdApi::compileGlobals`'s `Global::WorkerLoader` arm\n * (`server/workerd-api.c++:748-752`), which is the step that turns a configured\n * loader channel into the JS binding an application finds in `env`.\n *\n * **The one binding the runtime has to construct, and the reason is the\n * context.** Upstream's `WorkerLoader` holds a channel number and a\n * validation mode and nothing else, because `get()` and `load()` read\n * `IoContext::current()` when they are called. This package deliberately has no\n * ambient of any kind, so the context is a constructor input — and it must be\n * *this* container's, since `makeReentryCallback` inherits the critical section\n * a `blockConcurrencyWhile` is holding (decision 13). `IoContext` is not\n * exported, on purpose (see `src/index.ts`'s header), so this method is how a\n * host gets a loader bound to the right one.\n *\n * The host still owns the name: assign the result onto the `env` object it\n * passed in, which is what upstream's binding compilation does one layer down.\n * A container whose host never calls this simply has no loader binding, exactly\n * as a Worker with no `workerLoader` in its config does.\n */\n workerLoader(channel: IsolateChannelFactory, options: WorkerLoaderOptions): WorkerLoader;\n\n /**\n * Rejects when either gate breaks, or when a facet the parent did not abort\n * breaks (decisions 6 and 14). The host consumes this: terminate the worker,\n * respawn on the next event.\n */\n readonly onBroken: Promise<never>;\n\n /** The programmatic `ctx.abort()` path. */\n abort(reason?: unknown): void;\n}\n\n// =======================================================================================\n// Constants\n\n/** ← the database `ports.sql` opens for the actor's own KV and SQL. */\nconst ACTOR_DATABASE_NAME = \"root\";\n\n/**\n * ← `<actor-id>.facets` (`server.c++:2711-2714`), as a database rather than a\n * file.\n *\n * Upstream opens a second file beside the actor's SQLite database and calls four\n * `kj::File` members on it. There is no `kj/filesystem` port and the browser\n * cannot give a supervisor a synchronous file handle at all — OPFS sync access\n * handles are worker-only, measured — so the bytes live in a second database\n * from the same provider, which the actor's own worker already has open.\n *\n * A **second** database rather than a table in the actor's own, and the reason is\n * not tidiness. `SqliteKv::deleteAll()` calls `db.reset()`, which replaces the\n * actor's database file wholesale; upstream's index survives that because it is a\n * separate file, and decision 14's \"stable ids across delete-and-recreate\"\n * depends on it surviving. An index inside the actor's database would also be\n * written inside whatever transaction happens to be open — the implicit one, or a\n * `transactionSync` savepoint — so a rolled-back transaction would take an id\n * assignment with it while the facet holding that id kept running. Upstream's\n * index write is `datasync`'d immediately and is in no transaction at all, and a\n * separate connection is what reproduces that.\n */\nconst FACET_DATABASE_NAME = \"facets\";\n\n/** ← the storage the tree index's bytes live in. One row, holding the whole file. */\nconst INDEX_TABLE = \"_cf_FACET_INDEX\";\nconst CREATE_INDEX_TABLE = `CREATE TABLE IF NOT EXISTS ${INDEX_TABLE} (\n k INTEGER PRIMARY KEY CHECK (k = 0),\n bytes BLOB NOT NULL\n)`;\n\n/** ← `JSG_KJ_EXCEPTION(FAILED, Error, \"Facet was deleted.\")` (`server.c++:2644`). */\nconst FACET_DELETED_MESSAGE = \"Facet was deleted.\";\n\n/**\n * A facet has no alarm slot, and this is where that becomes visible.\n *\n * `server.c++:2864-2877` installs alarm hooks only `if (parent == kj::none)` and\n * gives a facet `ActorSqlite::Hooks::getDefaultHooks()`, whose `scheduleRun`\n * throws — so on workerd a `setAlarm()` inside a facet appears to succeed and\n * then breaks the whole actor asynchronously, which is open bug\n * https://github.com/cloudflare/workerd/issues/6810. This runtime refuses at the\n * call instead, as recorded in §2.7. A deliberate semantic\n * divergence: the observable behaviour is a synchronous throw naming the facet\n * where workerd's is a destroyed actor three turns later.\n */\nexport const FACET_ALARM_UNIMPLEMENTED_MESSAGE =\n \"A facet has no alarm slot. Alarm hooks are installed only on a root Durable Object, so a \" +\n \"facet cannot schedule one: record the wake on the root and route the work back down.\";\n\n// =======================================================================================\n// The tree index, over a database\n\n/**\n * ← the `kj::File` `FacetTreeIndex` is constructed over, backed by one BLOB.\n *\n * `datasync()` is a no-op and that is a property of the substrate rather than a\n * shortcut: nothing else ever opens a transaction on this connection, so every\n * statement below is its own implicit SQLite transaction and is durable by the\n * time `exec` returns. The read-modify-write is O(file) per append, which is\n * what upstream's own bound makes affordable — the format is four bytes plus a\n * name per facet and there can be at most 65,535 facets over an actor's whole\n * lifetime (`facet-tree-index.h:19-22`).\n */\nexport function newDatabaseIndexFile(db: SqlDatabase): IndexFile {\n hasCurrentSqliteTable(db, INDEX_TABLE, CREATE_INDEX_TABLE);\n db.exec(CREATE_INDEX_TABLE, []);\n\n const read = (): Uint8Array => {\n const value = db.exec(`SELECT bytes FROM ${INDEX_TABLE} WHERE k = 0`, []).rawRows[0]?.[0];\n if (value === undefined) return new Uint8Array(0);\n if (value instanceof Uint8Array) return value;\n throw new Error(\"the facet tree index row is not a BLOB\");\n };\n\n const store = (bytes: Uint8Array): void => {\n db.exec(\n `INSERT INTO ${INDEX_TABLE} (k, bytes) VALUES (0, ?)\n ON CONFLICT(k) DO UPDATE SET bytes = excluded.bytes`,\n [bytes],\n );\n };\n\n return {\n readAllBytes: read,\n\n write(offset: number, data: Uint8Array): void {\n const current = read();\n // kj's file grows on a write past the end and zero-fills the gap.\n const size = Math.max(current.length, offset + data.length);\n const next = new Uint8Array(size);\n next.set(current, 0);\n next.set(data, offset);\n store(next);\n },\n\n truncate(size: number): void {\n const current = read();\n if (size === current.length) return;\n const next = new Uint8Array(size);\n next.set(current.subarray(0, Math.min(size, current.length)), 0);\n store(next);\n },\n\n datasync(): void {\n // See the note above: one statement is one transaction on this connection.\n },\n };\n}\n\n// =======================================================================================\n// ActorTree\n\n/**\n * The root container's copy of everything that is true of the tree rather than\n * of one actor: the index, the deletion receipts, the serialization of physical\n * deletion, and the reference epochs.\n */\nclass ActorTree implements FacetTree {\n readonly #index: FacetTreeIndex;\n readonly #host: FacetHost;\n readonly #deletions: FacetDeletionController;\n readonly #queue = new SerializedSubtreeDeletionQueue();\n /**\n * One operation tail per stable facet id, shared by every manager in the\n * tree. A parent deletion must see a descendant manager's placement before\n * asking the host to unlink that descendant's storage.\n */\n readonly #operations = new Map<FacetId, Promise<void>>();\n readonly epochs = new FacetReferenceEpochs();\n\n constructor(db: SqlDatabase, host: FacetHost) {\n this.#index = new FacetTreeIndex(newDatabaseIndexFile(db));\n this.#host = host;\n this.#deletions = new FacetDeletionController(new FacetDeletionReceiptStore(db), (receipt) =>\n this.#removeSubtree(receipt),\n );\n }\n\n getId(parent: FacetId, name: string): FacetId {\n return this.#index.getId(parent, name);\n }\n\n children(parent: FacetId): readonly { readonly id: FacetId; readonly name: string }[] {\n const found: { id: FacetId; name: string }[] = [];\n this.#index.forEachChild(parent, (id, name) => {\n found.push({ id, name });\n });\n return found;\n }\n\n /**\n * ← `deleteDescendantStorage` (`server.c++:2754-2759`), flattened. Upstream\n * recurses into a child before removing it, so the deepest storage goes first;\n * this list is in that order and the caller removes `id` itself afterwards.\n */\n descendants(id: FacetId): FacetId[] {\n const out: FacetId[] = [];\n for (const child of this.children(id)) {\n out.push(...this.descendants(child.id));\n out.push(child.id);\n }\n return out;\n }\n\n deleteSubtree(id: FacetId, waitBeforeDelete: Promise<unknown>): Promise<void> {\n return this.#deletions.delete(id, waitBeforeDelete);\n }\n\n async copySubtree(src: FacetId, dst: FacetId): Promise<void> {\n // A copy touches every id in both subtrees, so it queues behind — and blocks — any deletion\n // that overlaps either one. Nothing else may be walking these files while it runs.\n const touched = [src, dst, ...this.descendants(src), ...this.descendants(dst)];\n await this.#queue.run(touched, () => this.#copyInto(src, dst));\n }\n\n runOperation(id: FacetId, operation: () => Promise<void>): void {\n const pending = this.#operations.get(id);\n // Both outcomes chained: an abort is not conditional on the placement before it succeeding.\n const done = pending === undefined ? operation() : pending.then(operation, operation);\n this.#operations.set(id, done);\n void done.finally(() => {\n if (this.#operations.get(id) === done) this.#operations.delete(id);\n });\n }\n\n async subtreeOperationBarrier(id: FacetId): Promise<void> {\n const pending = new Set<Promise<void>>();\n for (const target of [id, ...this.descendants(id)]) {\n const operation = this.#operations.get(target);\n if (operation !== undefined) pending.add(operation);\n }\n await Promise.all([...pending].map((operation) => operation.catch(() => undefined)));\n }\n\n recoverDeletions(): Promise<void> {\n return this.#deletions.recoverAll();\n }\n\n /** Waits out any deletion covering `id`, which is what makes a re-created facet safe to start. */\n settled(id: FacetId): Promise<void> {\n return this.#queue.waitFor(id);\n }\n\n #removeSubtree(receipt: FacetDeletionReceipt): Promise<void> {\n const subtree = this.descendants(receipt.id);\n return this.#queue.run([receipt.id, ...subtree], () =>\n this.#host.deleteStorage(receipt.id, subtree),\n );\n }\n\n async #copyInto(src: FacetId, dst: FacetId): Promise<void> {\n await this.#host.copyStorage(src, dst);\n for (const child of this.children(src)) {\n await this.#copyInto(child.id, this.getId(dst, child.name));\n }\n }\n}\n\n// =======================================================================================\n// The Actor\n\n/** ← `Worker::Actor::Impl::classInstance` (`io/worker.c++:4091-4115`). */\ntype ClassInstance =\n | { readonly kind: \"before-ctor\" }\n | { readonly kind: \"initializing\" }\n | { readonly kind: \"running\"; readonly instance: object }\n | { readonly kind: \"failed\"; readonly exception: unknown };\n\n/**\n * ← `Worker::Actor`, restricted to the four members `io/io-context.ts` names.\n *\n * The gates are constructed here because upstream constructs them here:\n * `Worker::Actor::Impl` owns its own `InputGate` and `OutputGate`\n * (`worker.c++:3784`), and that is per-facet rather than shared with the parent,\n * which is the whole mechanism behind §1.10's parent↔child re-entrancy.\n */\nclass ActorImpl implements Actor {\n readonly #inputGate = new InputGate();\n readonly #outputGate = new OutputGate();\n readonly #isFacet: boolean;\n\n /** Assigned after construction; `storage` is a WXT auto-import in extension bundles. */\n actorStorage: ActorSqlite | undefined;\n\n classInstance: ClassInstance = { kind: \"before-ctor\" };\n\n constructor(isFacet: boolean) {\n this.#isFacet = isFacet;\n }\n\n getInputGate(): InputGate {\n return this.#inputGate;\n }\n\n getOutputGate(): OutputGate {\n return this.#outputGate;\n }\n\n /** ← `Worker::Actor::shutdownActorCache`. Abandons scheduled writes rather than flushing (§1.6). */\n shutdownActorCache(reason: unknown): void {\n this.actorStorage?.shutdown(reason);\n }\n\n /**\n * ← `Worker::Actor::assertCanSetAlarm()` (`io/worker.c++:4090-4116`), one arm\n * per state of its `classInstance` switch.\n *\n * `NoClass` has no arm because this runtime has no class-less actor: every\n * container is built around a constructor. The facet refusal at the top is the\n * divergence `FACET_ALARM_UNIMPLEMENTED_MESSAGE` documents; everything below\n * it is upstream's, message for message.\n */\n assertCanSetAlarm(): void {\n if (this.#isFacet) throw new Error(FACET_ALARM_UNIMPLEMENTED_MESSAGE);\n\n switch (this.classInstance.kind) {\n case \"before-ctor\":\n throw new Error(\"setAlarm() invoked before Durable Object ctor\");\n case \"initializing\":\n // We don't explicitly know if we have an alarm handler or not, so just let it happen.\n // We'll handle it when we go to run the alarm.\n return;\n case \"running\":\n if (!hasAlarmHandler(this.classInstance.instance)) {\n throw new TypeError(\n \"Your Durable Object class must have an alarm() handler in order to call setAlarm()\",\n );\n }\n return;\n case \"failed\":\n // We've failed in the ctor, might as well just throw that exception for now.\n throw this.classInstance.exception;\n }\n }\n}\n\nfunction hasAlarmHandler(instance: object): boolean {\n return typeof (instance as { alarm?: unknown }).alarm === \"function\";\n}\n\n// =======================================================================================\n// FacetManagerImpl\n\n/** One name in the parent's facet map. ← the `ActorMap facets` entry (`server.c++:2686`). */\ntype FacetEntry = {\n readonly id: FacetId;\n readonly started: Promise<FacetHandle>;\n handle: FacetHandle | undefined;\n};\n\n/** For awaiting a promise's settlement without adopting its outcome. */\nconst noop = (): void => {};\n\n/**\n * ← `ActorContainer`'s `Worker::Actor::FacetManager` half (`server.c++:2622-2654`).\n *\n * Upstream's `getFacet` hands the child container a `kj::Promise<ClassAndId>` and\n * returns an `ActorChannelImpl` immediately, so the stub exists before the\n * startup callback has run. `FacetHost.start` is synchronous and wants a resolved\n * request, so the deferral moves here: the stub returned is a proxy that awaits\n * the start and then forwards. Same observable shape — `facets.get()` returns\n * synchronously, and the first call on the result waits for the class.\n *\n * A broken facet is monitored without escalating the break. Upstream\n * `monitorOnBroken` (`server.c++:2767-2800`) aborts that container's own\n * children and erases it from its parent's map; it does not abort the parent.\n * Here the host owns the child container, so `#monitorOnBroken` asks the host to\n * tear it down and removes only the matching entry. `#forgetIfNeverRuns` is the\n * separate path for a placement that never became a running facet.\n */\nclass FacetManagerImpl implements FacetManager {\n readonly #container: ActorContainerImpl;\n readonly #host: FacetHost;\n readonly #selfId: FacetId;\n readonly #depth: number;\n readonly #tree: FacetTree;\n readonly #facets = new Map<string, FacetEntry>();\n\n constructor(\n container: ActorContainerImpl,\n host: FacetHost,\n selfId: FacetId,\n depth: number,\n tree: FacetTree,\n ) {\n this.#container = container;\n this.#host = host;\n this.#selfId = selfId;\n this.#depth = depth;\n this.#tree = tree;\n }\n\n /** ← `getDepth()` (`server.c++:2622-2627`). */\n getDepth(): number {\n return this.#depth;\n }\n\n /** ← `getFacet()` (`server.c++:2629-2633`) plus `getFacetContainer()` (`:2603-2620`). */\n getFacet<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name: string,\n getStartInfo: () => Promise<FacetStartInfo>,\n ): Fetcher<T> {\n const existing = this.#facets.get(name);\n if (existing !== undefined) {\n return asFacetStub<T>(asFacetTransport(existing, this.#container));\n }\n\n const tree = this.#tree;\n const id = tree.getId(this.#selfId, name);\n const epoch = tree.epochs.capture(id);\n const depth = this.#depth + 1;\n\n // The entry has to exist before the placement runs, so that it can write the handle back onto\n // it; a resolver pair is what lets `started` stay a plain `Promise<FacetHandle>` rather than\n // becoming optional for the one turn it takes to fill in.\n const { promise, resolve, reject } = Promise.withResolvers<FacetHandle>();\n const entry: FacetEntry = { id, handle: undefined, started: promise };\n\n const place = async (): Promise<void> => {\n let handle: FacetHandle;\n try {\n const info = await getStartInfo();\n // A facet re-created under a name that is still being deleted must not open its database\n // while the old one is being removed. Nothing above this layer can see the difference,\n // which is exactly why it has to be waited for here.\n await tree.settled(id);\n if (!tree.epochs.isCurrent(id, epoch)) {\n throw new Error(`Facet \"${name}\" was torn down before it finished starting.`);\n }\n handle = this.#host.start({\n id,\n name,\n className: info.actorClass.className,\n depth,\n ...(info.id === this.#parentId() ? {} : { routedId: info.id }),\n });\n entry.handle = handle;\n this.#monitorOnBroken(name, entry, handle);\n } catch (exception) {\n // Everything up to a usable handle, so a failure reaches `started` and nothing else. The\n // queue must not be the one to carry it: an id whose placement failed is idle, not broken.\n reject(exception);\n return;\n }\n resolve(handle);\n // `started` settles where it always did — the moment the host accepted the placement — and\n // the id stays busy PAST it, until the placement itself has landed. `start` returning is not\n // the facet running, and an abort\n // delivered inside it reaches a host that has nothing yet to abort.\n await handle.stub.then(noop, noop);\n };\n\n // Attached before the placement runs, and it is the whole of this entry's failure handling —\n // see its own comment.\n this.#forgetIfNeverRuns(name, entry);\n tree.runOperation(id, place);\n this.#facets.set(name, entry);\n return asFacetStub<T>(asFacetTransport(entry, this.#container));\n }\n\n /**\n * ← the fact that a facet which failed to start is **not running**, and\n * `getFacet` \"runs the startup callback only when the facet is not already\n * running\" (§1.10, workerd PR #4431) therefore runs it again.\n *\n * Measured on workerd 1.20260722.1 rather than inferred: a name whose first\n * `facets.get` supplied a class that throws in its constructor accepts a\n * working class on the very next `facets.get`, with no `abort()` in between,\n * and the facet then counts its own storage from 1. A map entry kept after a\n * failed placement would answer every later get with the same dead handle, so\n * the name would be poisoned for the life of the actor.\n *\n * Both failures count, because both leave the same nothing behind: a `start`\n * that rejected before the host was called at all (a startup callback that\n * threw, or a tear-down that invalidated the reference epoch), and a placement\n * the host accepted and could not finish.\n *\n * It is also the handler that keeps either from being reported as an unhandled\n * rejection when nobody ever calls the stub — the same thing `IoContext` does\n * for its abort promise — without hiding it from a real caller, which reaches\n * it through `asFacetTransport`.\n */\n #forgetIfNeverRuns(name: string, entry: FacetEntry): void {\n void entry.started\n .then(async (handle) => {\n await handle.stub;\n })\n .catch(() => {\n // Only if this entry is still the one under that name: a tear-down removes it first, and\n // a later `getFacet` may already have put a fresh entry in its place.\n if (this.#facets.get(name) === entry) this.#facets.delete(name);\n });\n }\n\n /**\n * ← `monitorOnBroken` (`server.c++:2767-2800`): tear down the broken container\n * (and therefore its own descendants), then free its name in the parent's map.\n * The identity check keeps a late rejection from touching a replacement that\n * already occupies the stable facet id.\n */\n #monitorOnBroken(name: string, entry: FacetEntry, handle: FacetHandle): void {\n void handle.broken.catch((reason: unknown) => {\n if (this.#facets.get(name) !== entry) return;\n this.#facets.delete(name);\n this.#teardown(entry, describeReason(reason));\n });\n }\n\n /** ← `abortFacet()` (`server.c++:2635-2640`). */\n abortFacet(name: string, reason: unknown): void {\n const entry = this.#facets.get(name);\n if (entry === undefined) return;\n this.#facets.delete(name);\n this.#teardown(entry, describeReason(reason));\n }\n\n /**\n * ← `deleteFacet()` (`server.c++:2642-2655`): abort any running facet, then\n * delete the underlying storage, descendants first.\n *\n * Upstream's second half is a synchronous `directory->remove`. Ours is a\n * durable receipt plus an asynchronous removal, which is what\n * `server/facet-deletion.ts` exists for — the record is synchronous, so the\n * `void` return still means \"this will happen\", and a session that dies\n * between the two replays it at boot.\n */\n deleteFacet(name: string): void {\n const tree = this.#tree;\n this.abortFacet(name, new Error(FACET_DELETED_MESSAGE));\n\n // Note that upstream skips this entirely when the index has never been written, on the grounds\n // that \"if there's no facet index then there couldn't possibly be any child storage\". `getId`\n // assigns on first sight, so asking for a name that was never created costs one index entry\n // and then deletes nothing — which is also what makes the id stable if it is created later.\n const id = tree.getId(this.#selfId, name);\n tree.epochs.invalidate(id, tree.descendants(id));\n this.#container.trackFacetTeardown(tree.deleteSubtree(id, tree.subtreeOperationBarrier(id)));\n }\n\n /**\n * ← `DurableObjectFacets::clone`, which has **no body anywhere in workerd** —\n * `Worker::Actor::FacetManager` (`io/worker.h:901-931`) declares four members\n * and none of them is a clone, while `@cloudflare/workers-types` 4.20260702.1\n * declares `clone(src, dst)`. So the semantics come from §1.10's own prose:\n * abort `dst`, delete its storage, recursively copy the `src` subtree onto it.\n *\n * Two things that prose does not settle, assumed here and flagged rather than\n * hidden. It does not say whether `src` must exist — this treats a `src` that\n * was never created as an empty subtree, because `getId` assigns on sight and\n * there is nothing to distinguish \"never created\" from \"created and empty\".\n * And it does not say whether `dst`'s own children survive: this deletes\n * `dst`'s whole subtree before copying, because \"delete dst storage\" followed\n * by a recursive copy leaves no reading in which a child of the old `dst`\n * should still be there.\n */\n cloneFacet(src: string, dst: string): void {\n const tree = this.#tree;\n this.abortFacet(dst, new Error(FACET_DELETED_MESSAGE));\n\n const srcId = tree.getId(this.#selfId, src);\n const dstId = tree.getId(this.#selfId, dst);\n if (srcId === dstId) throw new TypeError(\"facets.clone() cannot clone a facet onto itself.\");\n\n tree.epochs.invalidate(dstId, tree.descendants(dstId));\n this.#container.trackFacetTeardown(\n tree\n .deleteSubtree(dstId, tree.subtreeOperationBarrier(dstId))\n .then(() => tree.copySubtree(srcId, dstId)),\n );\n }\n\n /** ← `monitorOnBroken`'s `for (auto& facet: facets) facet.value->abort(...)` (`server.c++:2777-2780`). */\n abortAll(reason: unknown): void {\n const description = describeReason(reason);\n for (const [name, entry] of this.#facets) {\n this.#facets.delete(name);\n this.#teardown(entry, description);\n }\n }\n\n /** ← `afterReset`'s `deleteDescendantStorage(dir, selfId)` (`server.c++:2885-2897`). */\n deleteAllDescendants(): void {\n const tree = this.#tree;\n this.abortAll(new Error(FACET_DELETED_MESSAGE));\n for (const child of tree.children(this.#selfId)) {\n tree.epochs.invalidate(child.id, tree.descendants(child.id));\n this.#container.trackFacetTeardown(\n tree.deleteSubtree(child.id, tree.subtreeOperationBarrier(child.id)),\n );\n }\n }\n\n /**\n * ← `ActorContainer::abort` (`server.c++:2565-2589`) as `abortFacet` reaches it\n * (`:2635-2640`), which is synchronous AND effective the instant it runs.\n *\n * Ours can only be effective once the host has finished placing, so the abort\n * goes to the back of the id's queue when one is in flight and straight\n * through when the id is idle. `abortFacet` stays `void` either way — the\n * queueing is invisible above this line, which is the point: `ctx.facets`'s\n * synchronous shape is upstream's and is not negotiable (`:2635`).\n *\n * Nothing here has to record that this break was the parent's own doing: a\n * facet breaking never reaches its parent, so the parent's own tear-down and a\n * facet dying by itself are the same event as far as the parent is concerned.\n */\n #teardown(entry: FacetEntry, description: string): void {\n this.#tree.runOperation(entry.id, async () => {\n this.#host.abort(entry.id, description);\n });\n }\n\n #parentId(): string {\n return this.#container.state.id.toString();\n }\n}\n\nfunction describeReason(reason: unknown): string {\n if (typeof reason === \"string\") return reason;\n if (reason instanceof Error) return reason.message;\n return String(reason);\n}\n\n/** Well-known members a stub proxy must answer as absent rather than as a method. */\nconst NON_METHOD_PROPERTIES: ReadonlySet<string | symbol> = new Set<string | symbol>([\n \"then\",\n \"catch\",\n \"finally\",\n Symbol.toPrimitive,\n Symbol.toStringTag,\n Symbol.iterator,\n Symbol.asyncIterator,\n]);\n\n/**\n * The point where the host's placement stub becomes the `Fetcher` the facet API\n * promises, plus the deferral upstream gets from `ActorChannelImpl` holding a\n * promise.\n *\n * The assertion is `asFacetStub`'s, one layer lower. `FacetHost.start` returns\n * `stub: Promise<object>` because a host mints the handle synchronously and the\n * placement it stands for is not finished yet, so the declared type is the widest\n * thing every host can actually satisfy, and `Promise<Fetcher>` is not it.\n *\n * **This function is the only deferral.** `FacetHandle.stub` carries the\n * placement promise and the proxy below waits for it before forwarding.\n *\n * **The assertion here is a separate one and would survive a narrower\n * `FacetHandle.stub`.** What is not describable is the `Fetcher` *this* function\n * returns: it is a `get`-trap `Proxy` that supplies `fetch`, `connect` and every\n * RPC method name at call time, and TypeScript types a `Proxy` as its target.\n * Typing the target `Fetcher` would only move the assertion to\n * `Object.create(null) as Fetcher`. So this stays where it is, for the reason the\n * two `asFacetStub`-shaped assertions beside it stay: the surface is supplied\n * dynamically, not that the value beneath is unknown.\n */\nfunction asFacetTransport(entry: FacetEntry, owner: ActorContainerImpl): Fetcher {\n const bound = new Map<string | symbol, unknown>();\n\n const stub = new Proxy(Object.create(null) as object, {\n get(_target, property): unknown {\n // A proxy that answered `then` with a function would make itself a thenable, and\n // `await facets.get(...)` would hang waiting for it to call back.\n if (NON_METHOD_PROPERTIES.has(property)) return undefined;\n\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n\n // ← `awaitIo`, which is what makes an outbound RPC BOTH release the input gate and resume\n // holding one (§1.3). Without it the caller's continuation comes back with an empty\n // invocation stack — divergence 147 — and its next `ctx.storage` or `ctx.facets` call\n // throws. Upstream never faces the question because every promise JS can await originates\n // in an io-context primitive, and a facet stub is one of them.\n const method = (...args: unknown[]): Promise<unknown> => {\n // Capture re-entry now, while the caller's slice (and any surrounding\n // critical section) is current. Waiting for output locks first can move\n // this work onto a later microtask with no current input lock.\n const callArgs = args.map((arg) =>\n arg instanceof RpcTarget ? owner.bindReentryTarget(arg) : arg,\n );\n return owner.awaitIo(\n owner.waitOutputLocks().then(async (): Promise<unknown> => {\n const handle = entry.handle ?? (await entry.started);\n // The placement, which may still be in flight and may have failed. A failure arrives\n // here and nowhere else — it is what upstream's `kj::Promise<ClassAndId>` failing\n // does, and it is what workerd was measured to do (§1.10).\n const target = (await handle.stub) as Record<string | symbol, unknown>;\n const fn = target[property];\n if (typeof fn !== \"function\") {\n throw new TypeError(`This facet stub has no method ${String(property)}.`);\n }\n // A Cap'n Web method stub is a callable Proxy. Reading its `.apply`\n // would serialize a remote property lookup (`method.apply`) instead\n // of invoking the local call trap, so use the intrinsic directly.\n return await Reflect.apply(fn as (...rest: unknown[]) => unknown, target, callArgs);\n }),\n );\n };\n bound.set(property, method);\n return method;\n },\n });\n\n return stub as Fetcher;\n}\n\n// =======================================================================================\n// ActorContainerImpl\n\nclass ActorContainerImpl implements ActorContainer {\n readonly #actor: ActorImpl;\n readonly #ctx: IoContext;\n #currentExternalEntry: object | undefined;\n readonly #durableStorage: DurableObjectStorage;\n readonly #cache: ActorSqlite;\n readonly #facets: FacetManagerImpl;\n readonly #tree: ActorTree | undefined;\n readonly #env: unknown;\n readonly state: DurableObjectState;\n readonly facetTree: FacetTree;\n readonly globals: ActorGlobalScope;\n\n /** ← §1.8's \"delivery is strictly serialized\", measured. One at a time, in order. */\n #alarmTail: Promise<unknown> = Promise.resolve();\n\n constructor(\n options: ActorContainerOptions,\n db: SqliteDatabase,\n tree: ActorTree | undefined,\n facetTree: FacetTree,\n ) {\n const facet = options.facet;\n this.#actor = new ActorImpl(facet !== undefined);\n this.#ctx = new IoContext(this.#actor, options.ports.timer);\n this.#env = options.env;\n this.#tree = tree;\n\n this.#cache = new ActorSqlite(\n db,\n this.#actor.getOutputGate(),\n // ← `[](SpanParent) -> kj::Promise<void> { return kj::READY_NOW; }` (`server.c++:2900`).\n // Upstream's commit callback exists for a replication layer workerd's local storage has none\n // of; the local commit is already durable when `COMMIT TRANSACTION` returns.\n async () => {},\n // ← `if (parent == kj::none) ... else getDefaultHooks()` (`server.c++:2864-2877`). A facet\n // takes upstream's default hooks, whose `scheduleRun` throws.\n //\n // Nothing can reach them, because `assertCanSetAlarm` refuses first — so giving a facet a\n // live outlet here changes nothing observable and survives the whole suite. It is upstream's\n // own line and it stays: the refusal above it is a divergence, and if the divergence is ever\n // withdrawn this is what workerd's behaviour falls back to.\n facet === undefined ? options.ports.alarms : DEFAULT_ALARM_OUTLET,\n );\n this.#actor.actorStorage = this.#cache;\n\n this.#durableStorage = new DurableObjectStorage(this.#ctx, this.#cache);\n this.globals = new ActorGlobalScope(this.#ctx, {\n fetch: options.ports.fetch,\n currentExternalEntry: () => this.#currentExternalEntry,\n });\n this.facetTree = facetTree;\n this.#facets = new FacetManagerImpl(\n this,\n options.ports.facets,\n facet?.id ?? 0,\n facet?.depth ?? 0,\n this.facetTree,\n );\n\n // ← the `afterReset` hook (`server.c++:2885-2897`): \"reset() is used when the app called\n // deleteAll(), in which case we also want to delete all child facets.\" Ours is\n // `beforeSqliteReset`, which is the listener Section 3 ported, and the difference does not\n // matter — the descendants live in other databases entirely.\n db.addResetListener({\n beforeSqliteReset: () => {\n this.#facets.deleteAllDescendants();\n },\n });\n\n const idFactory = new ActorIdFactoryImpl(options.uniqueKey);\n this.state = new DurableObjectState(this.#ctx, {\n id: new DurableObjectId(idFactory.idFromName(options.id)),\n exports: options.exports,\n props: undefined,\n storage: this.#durableStorage,\n facets: this.#facets,\n // The same object `container.globals` is, so a class that reaches through\n // `ctx` and a dynamically-loaded source that destructured the seven names\n // are gated by one scope rather than two that could drift.\n globals: actorScopeBindings(() => this.globals),\n });\n }\n\n get onBroken(): Promise<never> {\n // ← `IoContext`'s two `abortWhen` calls, which are already wired to both gates\n // (`io-context.c++:206-215`). A facet of this actor breaking is NOT one of the ways in: a\n // break travels down, so what reaches here is this container's own failure.\n return this.#ctx.onAbort();\n }\n\n isCurrentSlice(): boolean {\n return this.#ctx.isCurrentSlice();\n }\n\n hasCurrent(): boolean {\n return this.#ctx.hasCurrent();\n }\n\n /**\n * ← `ActorContainer::start` (`server.c++:2854-2957`) as far as the class\n * instance, plus decision 4's boot semantics.\n *\n * Deletion-receipt replay precedes the constructor because a facet the previous\n * session was told to delete must not be reachable from `onStart`. Upstream has\n * no equivalent step for the reason `server/facet-deletion.ts`'s header gives.\n */\n async start<T extends object>(\n construct: (ctx: DurableObjectState, env: unknown) => T,\n ): Promise<T> {\n await this.#tree?.recoverDeletions();\n\n this.#actor.classInstance = { kind: \"initializing\" };\n try {\n // The input gate is held for the constructor's synchronous slice and the microtask\n // checkpoint that drains after it, which is upstream's own boundary (§1.2).\n const instance = await this.#ctx.run(() => construct(this.state, this.#env));\n this.#actor.classInstance = { kind: \"running\", instance };\n return instance;\n } catch (exception) {\n this.#actor.classInstance = { kind: \"failed\", exception };\n throw exception;\n }\n }\n\n entry<T extends object>(target: T): ActorEntry<T> {\n const bound = new Map<string | symbol, unknown>();\n\n return new Proxy(target, {\n get: (subject, property): unknown => {\n // The receiver is the target rather than the proxy, so a getter on the class does not\n // re-enter this trap for every field it touches.\n const value: unknown = Reflect.get(subject, property, subject);\n if (typeof value !== \"function\") return value;\n\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const gated = async (...args: unknown[]): Promise<unknown> => {\n const result = await this.#ctx.run(() =>\n this.#withExternalEntry(() =>\n (value as (...rest: unknown[]) => unknown).apply(subject, args),\n ),\n );\n // ← the reply being piped through `waitForOutputLocks()`. This is §1.1's whole point:\n // a method that returns without awaiting its own write still must not answer before\n // that write is durable.\n await this.#ctx.waitForOutputLocks();\n return result;\n };\n bound.set(property, gated);\n return gated;\n },\n }) as ActorEntry<T>;\n }\n\n /**\n * Bind an exported Workers RPC callback to the actor slice that created it.\n *\n * A facet call is bidirectional: the caller can pass an `RpcTarget` and the\n * callee can invoke it before returning. That invocation is re-entry into the\n * caller, not an unscoped JavaScript callback. Capturing one generic re-entry\n * function here preserves a surrounding critical section and keeps method\n * discovery lazy for Cap'n Web's property-path dispatch.\n */\n bindReentryTarget<T extends object>(target: T): T {\n const invoke = this.#ctx.makeReentryCallback(\n async (_lock, property: string | symbol, args: unknown[]): Promise<unknown> => {\n const value: unknown = Reflect.get(target, property, target);\n if (typeof value !== \"function\") {\n throw new TypeError(`This RPC callback has no method ${String(property)}.`);\n }\n const result = await Reflect.apply(value as (...rest: unknown[]) => unknown, target, args);\n await this.#ctx.waitForOutputLocks();\n return result;\n },\n );\n const bound = new Map<string | symbol, unknown>();\n return new Proxy(target, {\n get(subject, property): unknown {\n const value: unknown = Reflect.get(subject, property, subject);\n if (typeof value !== \"function\") return value;\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const callback = (...args: unknown[]): Promise<unknown> => invoke(property, args);\n bound.set(property, callback);\n return callback;\n },\n });\n }\n\n run<T>(event: () => T | PromiseLike<T>): Promise<T> {\n return this.#ctx.run(() => this.#withExternalEntry(event));\n }\n\n #withExternalEntry<T>(body: () => T): T {\n const previous = this.#currentExternalEntry;\n this.#currentExternalEntry = {};\n try {\n return body();\n } finally {\n this.#currentExternalEntry = previous;\n }\n }\n\n // An arrow property rather than a method, because `asFacetTransport` is handed it as a value\n // and the facet stub's whole job is to be called with `this` bound elsewhere.\n awaitIo = <T>(promise: Promise<T>): Promise<T> => this.#ctx.awaitIo(promise);\n\n acceptWebSocket(socket: RawWebSocket): AcceptedWebSocket {\n return acceptWebSocket(this.#ctx, socket);\n }\n\n /**\n * ← the alarm run in `Worker::Actor`: arm, run the handler under a fresh\n * top-level lock, wait for the output locks, then let the deferred deleter\n * drop.\n *\n * \"Alarms enter with no lock and no critical section, so an alarm queues behind\n * any held lock and takes a fresh top-level lock\" (§1.8) — which is exactly\n * `ctx.run(func)` with no third argument. The retry ladder and the watchdog are\n * `server/alarm-scheduler.ts`'s; what is here is one delivery, and the\n * serialization of one delivery against the next, which is the property\n * `_cf_executingScheduleRowId` upstream depends on.\n */\n deliverAlarm(scheduledTime: number, retryCount: number): Promise<AlarmResult> {\n const delivery = this.#alarmTail.then(\n () => this.#deliverAlarmImpl(scheduledTime, retryCount),\n () => this.#deliverAlarmImpl(scheduledTime, retryCount),\n );\n this.#alarmTail = delivery.catch(() => undefined);\n return delivery;\n }\n\n abandonAlarm(scheduledTime: number): Promise<number | null> {\n return this.#cache.abandonAlarm(scheduledTime);\n }\n\n waitOutputLocks(): Promise<void> {\n return this.#ctx.waitForOutputLocks();\n }\n\n drainWaitUntil(): Promise<void> {\n return this.#ctx.drainWaitUntil();\n }\n\n /** ← `WorkerdApi::compileGlobals`'s `Global::WorkerLoader` arm. */\n workerLoader(channel: IsolateChannelFactory, options: WorkerLoaderOptions): WorkerLoader {\n return new WorkerLoader(this.#ctx, channel, options);\n }\n\n /**\n * ← `DurableObjectState::abort`, which is what the programmatic path is\n * upstream too. Everything §1.6 asks for is already downstream of it: the cache\n * is shut down synchronously so no scheduled write can still land,\n * `IoContext::abort` refuses re-entry, and `onBroken` is the abort promise.\n * Aborting the facets is this layer's own addition, and it is\n * `monitorOnBroken`'s first act (`server.c++:2777-2780`).\n */\n abort(reason?: unknown): void {\n this.#facets.abortAll(reason ?? new Error(\"Parent Durable Object was aborted.\"));\n this.state.abort(reason === undefined ? undefined : describeReason(reason));\n }\n\n /**\n * A physical deletion or copy outlives the synchronous call that asked for it,\n * so it rides `addWaitUntil`: `drainWaitUntil()` then reports the actor busy\n * until it finishes, and a failure lands in `waitUntilStatus()` instead of\n * becoming an unhandled rejection nobody sees.\n */\n trackFacetTeardown(work: Promise<void>): void {\n this.#ctx.addWaitUntil(work);\n }\n\n /**\n * ← `ServiceWorkerGlobalScope::runAlarm` (`api/global-scope.c++:518-691`),\n * whose every step is a member of this class: `armAlarmHandler` and its two\n * arms, the handler under a fresh top-level lock, `waitForOutputLocks`, and the\n * deferred deleter dropping last.\n *\n * Two of its steps have nothing to port onto and are absent rather than\n * skipped: the 15-minute walltime `timeoutPromise` (`:558-586`) needs\n * `afterLimitTimeout` and a limit enforcer, neither of which this package has,\n * and every `LOG_NOSENTRY` around the classification is a log with nothing to\n * write to. What survives is the decision those logs describe.\n */\n async #deliverAlarmImpl(scheduledTime: number, retryCount: number): Promise<AlarmResult> {\n const armed = this.#cache.armAlarmHandler(scheduledTime, this.#ctx.now());\n if (armed.kind === \"cancel\") {\n // ← `CancelAlarmHandler` (`global-scope.c++:684-688`). Not a failure: SQLite has moved past\n // this alarm and has asked the scheduler to re-register the time it does hold.\n await armed.cancel.waitBeforeCancel;\n return { outcome: \"canceled\", retry: false, retryCountsAgainstLimit: true };\n }\n\n try {\n const instance = this.#actor.classInstance;\n if (instance.kind === \"running\" && !hasAlarmHandler(instance.instance)) {\n // ← \"Attempted to run a scheduled alarm without a handler, did you remember to export an\n // alarm() function?\" (`global-scope.c++:543-549`). Upstream logs the warning once and\n // reports SCRIPT_NOT_FOUND, which does NOT retry — so the deferred deleter still drops and\n // the alarm is cleared rather than redelivered to a class that can never answer it.\n return { outcome: \"script-not-found\", retry: false, retryCountsAgainstLimit: true };\n }\n\n let result: AlarmResult;\n try {\n await this.#ctx.run(() => this.#runAlarmHandler(scheduledTime, retryCount));\n result = { outcome: \"ok\", retry: false, retryCountsAgainstLimit: true };\n } catch (exception) {\n // ← the `.catch_` (`global-scope.c++:593-641`). \"We assume that exceptions thrown during\n // commit will propagate to the caller, such that they will ensure\n // cancelDeferredAlarmDeletion() is called\": a handler that failed must not have its alarm\n // deleted, or the retry the scheduler is about to make has nothing to run.\n this.#cache.cancelDeferredAlarmDeletion();\n result = {\n outcome: \"exception\",\n retry: true,\n retryCountsAgainstLimit: true,\n errorDescription: describeReason(exception),\n };\n }\n\n try {\n // ← `context.waitForOutputLocks()` (`global-scope.c++:645`), which is where a write the\n // handler did not await gets its chance to fail.\n await this.#ctx.waitForOutputLocks();\n } catch (exception) {\n // ← the output-lock error branch (`:647-681`), whose\n // `shouldRetryCountsAgainstLimits` is `isUserGeneratedError` alone: a gate that broke\n // after the handler ran is a reset, and a reset must not spend the alarm's retry budget.\n //\n // Divergence: upstream does NOT cancel the deferred deletion here, because its deleter is\n // owned by the `catch_` lambda and fires at the end of the chain either way. Cancelling is\n // the side that keeps the alarm — a deletion written through a gate that has just broken\n // cannot commit, so the only thing at stake is whether a gate that recovers loses it.\n this.#cache.cancelDeferredAlarmDeletion();\n result = {\n outcome: \"exception\",\n retry: true,\n retryCountsAgainstLimit: isAlarmFailureUserError(exception),\n errorDescription: describeReason(exception),\n };\n }\n return result;\n } finally {\n armed.run.deferredDelete.drop();\n }\n }\n\n #runAlarmHandler(scheduledTime: number, retryCount: number): unknown {\n const instance = this.#actor.classInstance;\n if (instance.kind !== \"running\") {\n throw new Error(\"An alarm was delivered to a Durable Object that has not been constructed.\");\n }\n if (!hasAlarmHandler(instance.instance)) {\n throw new TypeError(\"Your Durable Object class must have an alarm() handler.\");\n }\n // ← `alarm(lock, js.alloc<AlarmInvocationInfo>(scheduledTime, retryCount))` (`:588`).\n return (instance.instance as { alarm: (info: AlarmInvocationInfo) => unknown }).alarm(\n new AlarmInvocationInfo(scheduledTime, retryCount),\n );\n }\n}\n\n// =======================================================================================\n// createActorContainer\n\n/**\n * Builds one actor: the two gates, the `IoContext` over them, the storage engine\n * over the actor's database, the facet tree, the id factory, and the `api/`\n * classes on top.\n *\n * Asynchronous because `SqlDatabaseProvider.open` is — see this file's header for\n * why that surfaces here rather than being hidden behind a lazily-opening\n * `state`.\n */\nexport async function createActorContainer(\n options: ActorContainerOptions,\n): Promise<ActorContainer> {\n const db = new SqliteDatabase(await options.ports.sql.open(ACTOR_DATABASE_NAME));\n\n // ← `ensureFacetTreeIndex()`'s `KJ_REQUIRE(parent == kj::none, \"only 'root' may\n // ensureFacetTreeIndex()\")` (`server.c++:2704`). A facet is handed the root's rather than\n // opening one, which is also why this is the only `open` a facet container makes.\n if (options.facet !== undefined) {\n return new ActorContainerImpl(options, db, undefined, options.facet.tree);\n }\n const tree = new ActorTree(\n await options.ports.sql.open(FACET_DATABASE_NAME),\n options.ports.facets,\n );\n return new ActorContainerImpl(options, db, tree, tree);\n}\n","/**\n * ← workerd `NO upstream correspondence (capnweb adaptation)`\n *\n * The one door onto a capnweb session, so that decision 18's identity graft\n * cannot be skipped by establishing one some other way.\n *\n * The `RpcTarget` identity graft lives here because the guarantee belongs to\n * the call that establishes a session, not to whichever sibling module happened\n * to run a side effect first. It is re-applied for every session and is\n * idempotent.\n *\n * **What this deliberately is not.** It is not a transport abstraction and takes\n * no options capnweb does not: a lane or a host that needs\n * `newWebSocketRpcSession` instead should call `reconcileRpcTargetIdentity()`\n * itself and say so, rather than growing this into a second capnweb API. The\n * `MessagePort` form is the only one this substrate uses — the extension's\n * offscreen↔worker hop and the browser lane's page↔actor and page↔alarms hops are\n * all `newMessagePortRpcSession` — and a port carries structured clone, which is\n * what makes capnweb's `structuredClonable` encoding level available.\n *\n * Spec: decision 18 in docs/decisions.md.\n */\n\nimport {\n newMessagePortRpcSession,\n RpcTarget as TransportRpcTarget,\n type RpcStub,\n} from \"capnweb\";\nimport { RpcTarget } from \"../api/cloudflare-workers\";\n\n/** Make the declared Workers RpcTarget recognizable to capnweb by reference. */\nexport function reconcileRpcTargetIdentity(): void {\n if ((RpcTarget as unknown) === (TransportRpcTarget as unknown)) return;\n if (\n Object.prototype.isPrototypeOf.call(\n TransportRpcTarget.prototype,\n RpcTarget.prototype,\n )\n ) {\n return;\n }\n const existing: unknown = Object.getPrototypeOf(RpcTarget.prototype);\n if (existing !== Object.prototype) {\n throw new Error(\n \"The cloudflare:workers RpcTarget already inherits from something other than Object, so \" +\n \"the capnweb identity cannot be reconciled without discarding that link.\",\n );\n }\n Object.setPrototypeOf(RpcTarget.prototype, TransportRpcTarget.prototype);\n}\n\n/**\n * Establish a capnweb session over a `MessagePort`, with the `RpcTarget`\n * identity reconciled first.\n *\n * `localMain` is what the peer reaches; the returned stub is what the peer\n * exposed. Both ends call this — a session is symmetric — and either side may\n * omit its main when it exports nothing.\n */\nexport function newRpcSession<T = unknown>(port: MessagePort, localMain?: unknown): RpcStub<T> {\n reconcileRpcTargetIdentity();\n // Through `unknown`, because capnweb's own return type is `RpcStub<Stubify<...>>` and asking a\n // checker to compare that against `RpcStub<T>` structurally is what makes it recurse until it\n // gives up (TS2589, and two TS2321s behind it). The narrowing is the point of the signature —\n // the caller names the peer's main — and it is unchecked either way.\n return newMessagePortRpcSession(port, localMain) as unknown as RpcStub<T>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#resolve","#reject","#brokenPromise","#gate","#requireGate","#parent","#parentLock","#hooks","#lock","#setBroken","#pastLocksPromise","#brokenState","#setPastLocks","#timer","#timeouts","#nextId","#arm","#cancel","#fire","#tasks","#taskFailed","#actor","#currentInputLocks","#abortPromise","#rejectAbort","#waitUntilTasks","#requireCurrent","#lastGateUse","#abortException","#addTaskCounter","#waitUntilStatus","#runImpl","#awaitIoImpl","#runCriticalSection","#exit","#channel","#id","#fetcher","#idFactory","#getImpl","#channel","#fetcher","#loopbackClass","#channel","#ctx","#options","#toDynamicWorkerSource","#extractCompatFlags","#rawRows","#rowsWritten","#nextRow","#position","#nextRaw","#ctx","#owner","#getPageSize","#pageSize","#ctx","#owner","#getOne","#getMultiple","#putOne","#putMultiple","#cache","#sql","#kv","#cacheTxn","#rolledBack","#ctx","#facetManager","#parentId","#getFacetManager","#options","#facets","#scope","#requireOwnSlice","#ctx","#subtle","#gated","#crypto","#fetch","#readCurrentExternalEntry","#ctx","#socket","#criticalSection","#deliver","#enqueue","#pump","#db","#tableCreated","#openCursor","#ensureInitialized","#putMultiple","#cancelCurrentCursor","#currentCursor","#rollbackMultiPut","#parent","#rows","#index","#exhaust","#canceled","#db","#tableCreated","#ensureCached","#cache","#setAlarmUncached","#ensureInitialized","#getAlarmUncached","#tasks","#taskFailed","#kv","#metadata","#commitCallback","#hooks","#onWrite","#onCriticalError","#lastConfirmedAlarmDbState","#alarmScheduledNoLaterThan","#deleteAllCommitScheduled","#startImplicitTxn","#alarmLaterIsInFlight","#pendingLaterAlarmTime","#alarmLaterInFlight","#requestScheduledAlarm","#scheduleLaterAlarm","#pendingCommit","#alarmVersion","#inAlarmHandler","#newDeferredAlarmDeleter","#transactionSyncDepth","#maybeDeleteDeferredAlarm","#parent","#committed","#someWriteConfirmed","#dropped","#actorSqlite","#depth","#hasChild","#alarmDirty","#rollbackImpl","#id","#name","#key","#computeMac","#file","#entries","#byKey","#offset","#nextId","#append","#db","#receipts","#deleteSubtree","#active","#run","#clearActive","#pending","#tail","#epochs","#index","#host","#deletions","#queue","#operations","#removeSubtree","#copyInto","#inputGate","#outputGate","#isFacet","#container","#selfId","#depth","#tree","#facets","#parentId","#monitorOnBroken","#forgetIfNeverRuns","#teardown","#actor","#ctx","#durableStorage","#cache","#env","#currentExternalEntry","#withExternalEntry","#alarmTail","#deliverAlarmImpl","#runAlarmHandler"],"sources":["../src/io/io-gate.ts","../src/io/io-context.ts","../src/api/actor.ts","../src/api/export-loopback.ts","../src/api/worker-loader.ts","../src/api/sql.ts","../src/api/sync-kv.ts","../src/api/actor-state.ts","../src/api/http.ts","../src/api/global-scope.ts","../src/api/web-socket.ts","../src/io/actor-cache.ts","../src/util/sqlite-kv.ts","../src/util/sqlite-metadata.ts","../src/io/actor-sqlite.ts","../src/io/worker.ts","../src/server/sha256.ts","../src/server/actor-id-impl.ts","../src/server/facet-tree-index.ts","../src/server/facet-deletion.ts","../src/server/actor-container.ts","../src/server/actor-namespace.ts","../src/transport/rpc-session.ts"],"sourcesContent":["/**\n * ← workerd `src/workerd/io/io-gate.{h,c++}`\n *\n * An I/O gate allows someone to \"lock\" a type of I/O so that other concurrent tasks trying to\n * perform that type of I/O are blocked until the lock is released.\n *\n * I/O gates are used in actors to implement consistency guarantees, allowing in-memory state and\n * storage to be synchronized.\n *\n * Each Actor has two main gates:\n * - Input gate: While locked, blocks all incoming I/O events of any type from being delivered to\n * the actor, other than the specific event or events that hold the lock. This includes\n * blocking responses to subrequests, timer events, input streams, etc. Used when storage\n * operations are outstanding, so that awaiting a storage operation does not risk allowing\n * concurrent events that render the state inconsistent.\n * - Output gate: While locked, blocks all outgoing messages from an actor that would allow the\n * rest of the world to observe the actor's state. Held while writes that have been confirmed\n * to the application are still being flushed to disk. If the flush fails, these messages will\n * never be sent, so that the rest of the world cannot observe a prematurely-confirmed write.\n *\n * Three things kj gives for free and JS does not, resolved the same way at every site:\n *\n * 1. **Destructors.** `~Lock` releases and `~CriticalSection` diagnoses a dropped section as\n * deadlock. Both become explicit: `Lock.release()` and `CriticalSection.drop()`. A `Lock`\n * released twice throws rather than corrupting the refcount.\n * 2. **Cancel-by-drop.** Dropping a `kj::Promise` unwinds its waiter. Every such site takes an\n * `AbortSignal`, the convention `Timer.afterDelay` already set in `io-context.ts`. Aborting a\n * `wait()` rejects it with `CanceledError`; a never-settling promise would be an invisible\n * hang, which is what this repo's fail-closed tenet exists to prevent.\n * 3. **`kj::ForkedPromise` holding an exception with no branches.** JS reports that as an\n * unhandled rejection, so every promise this module stores keeps a no-op `catch` of its own\n * and hands observers a separate view.\n *\n * Error strings are copied verbatim from upstream; users and upstream tests match on them.\n *\n * Not ported: `SpanParent`/`SpanBuilder` tracing, since there is no `trace.h` here and upstream's\n * own tests pass `nullptr` at every call site; and the `~InputGate` assertion that no locks\n * outlive the gate, which guards against dangling references GC makes impossible.\n *\n * Spec: §1.1, §1.2, §1.5, decisions 3, 5 and 13 in\n * docs/decisions.md.\n */\n\n/**\n * Raised when a `wait()` is cancelled through its `AbortSignal`.\n *\n * kj has no equivalent, because a cancelled continuation simply never runs. It is deliberately\n * NOT a gate failure: a cancelled waiter leaves the gate exactly as it found it, so\n * `CriticalSection.wait()` rethrows this one without calling `setBroken()`.\n */\nexport class CanceledError extends Error {\n override readonly name = \"CanceledError\";\n}\n\n/** Mirrors `OutputGate::makeUnfulfilledException()`: one place that spells the exception. */\nfunction makeCanceledError(): CanceledError {\n return new CanceledError(\"input gate wait was canceled\");\n}\n\n/**\n * `addEventListener(\"abort\", ...)` never fires for a signal that has already aborted, so a\n * pre-aborted signal would silently hold its lock forever. Every cancellation site goes through\n * here, and every one of them first rejects a pre-aborted wait before touching gate state, so\n * \"cancelled\" always means \"left the gate exactly as it found it\".\n */\nfunction onAbort(signal: AbortSignal | undefined, run: () => void): void {\n if (signal === undefined) return;\n if (signal.aborted) {\n run();\n return;\n }\n signal.addEventListener(\"abort\", run, { once: true });\n}\n\n/**\n * ← `kj::OneOf<kj::Own<kj::PromiseFulfiller<void>>, kj::Exception> brokenState`.\n *\n * `InputGate` starts in `fulfiller` — it builds its promise in the constructor — while\n * `OutputGate` starts in `none` and only makes one when `onBroken()` is first called.\n */\ntype BrokenState =\n | { readonly kind: \"none\" }\n | { readonly kind: \"fulfiller\"; readonly reject: (exception: unknown) => void }\n | { readonly kind: \"exception\"; readonly exception: unknown };\n\n// =======================================================================================\n// InputGate\n\n/**\n * Hooks that can be used to customize InputGate behavior.\n *\n * Technically, everything implemented here could be accomplished by a class that wraps\n * InputGate, but the part of the code that wants to implement these hooks is far away from the\n * part of the code that calls into the InputGate, and so it was more convenient to give the\n * caller a way to inject behavior into InputGate.\n */\nexport interface InputGateHooks {\n inputGateLocked(): void;\n inputGateReleased(): void;\n inputGateWaiterAdded(): void;\n inputGateWaiterRemoved(): void;\n}\n\n/** ← `InputGate::Hooks::DEFAULT`. */\nexport const DEFAULT_INPUT_GATE_HOOKS: InputGateHooks = {\n inputGateLocked() {},\n inputGateReleased() {},\n inputGateWaiterAdded() {},\n inputGateWaiterRemoved() {},\n};\n\n/** ← `InputGate::Waiter`: a `kj::List` node plus the adapted promise's fulfiller. */\nclass Waiter {\n /** Rewritten by `CriticalSection.succeeded()` when a straggler is reparented. */\n gate: InputGate;\n readonly isChildWaiter: boolean;\n /** ← `link.isLinked()`. */\n linked = true;\n\n readonly #resolve: (lock: Lock) => void;\n readonly #reject: (exception: unknown) => void;\n\n constructor(\n gate: InputGate,\n isChildWaiter: boolean,\n resolve: (lock: Lock) => void,\n reject: (exception: unknown) => void,\n ) {\n this.gate = gate;\n this.isChildWaiter = isChildWaiter;\n this.#resolve = resolve;\n this.#reject = reject;\n\n gate.hooks.inputGateWaiterAdded();\n if (isChildWaiter) {\n gate.waitingChildren.push(this);\n } else {\n gate.waiters.push(this);\n }\n }\n\n unlink(): void {\n if (!this.linked) return;\n this.linked = false;\n const list = this.isChildWaiter ? this.gate.waitingChildren : this.gate.waiters;\n const index = list.indexOf(this);\n if (index < 0) {\n throw new Error(\"InputGate::Waiter is linked but absent from its gate's list\");\n }\n list.splice(index, 1);\n }\n\n fulfill(lock: Lock): void {\n this.unlink();\n this.gate.hooks.inputGateWaiterRemoved();\n this.#resolve(lock);\n }\n\n reject(exception: unknown): void {\n this.unlink();\n this.gate.hooks.inputGateWaiterRemoved();\n this.#reject(exception);\n }\n}\n\n/**\n * An InputGate blocks incoming events from being delivered to an actor while the lock is held.\n *\n * Upstream marks the state below `private` and befriends `Lock` and `CriticalSection`.\n * TypeScript has no friendship, and `protected` would not let `CriticalSection` reach these\n * members on its *parent* gate, which `succeeded()` does. The boundary that actually holds is\n * the package facade in `src/index.ts`, which exports none of these types.\n */\nexport class InputGate {\n readonly hooks: InputGateHooks;\n\n /**\n * How many instances of `Lock` currently exist? When this reaches zero, we'll release some\n * waiters.\n *\n * Upstream also carries a `bool isCriticalSection`, because `CriticalSection` inherits\n * `InputGate` privately and has to `static_cast` back. `instanceof` is the same test with no\n * cast and no field that can disagree with the object it describes.\n */\n lockCount = 0;\n\n readonly waiters: Waiter[] = [];\n\n /**\n * Waiters representing CriticalSections that are ready to start. These take priority over other\n * waiters.\n */\n readonly waitingChildren: Waiter[] = [];\n\n /** A fulfiller for onBroken(), or an exception if already broken. */\n brokenState: BrokenState;\n\n readonly #brokenPromise: Promise<never>;\n\n constructor(hooks: InputGateHooks = DEFAULT_INPUT_GATE_HOOKS) {\n this.hooks = hooks;\n const { promise, reject } = Promise.withResolvers<never>();\n this.#brokenPromise = promise;\n this.brokenState = { kind: \"fulfiller\", reject };\n // kj's ForkedPromise just holds the exception until someone adds a branch.\n void promise.catch(() => {});\n }\n\n /** Wait until there are no `Lock`s, then create a new one and return it. */\n wait(signal?: AbortSignal): Promise<Lock> {\n if (signal?.aborted === true) {\n return Promise.reject(makeCanceledError());\n } else if (this.brokenState.kind === \"exception\") {\n return Promise.reject(this.brokenState.exception);\n } else if (this.lockCount === 0) {\n return Promise.resolve(new Lock(this));\n } else {\n return this.newWaiterPromise(false, signal);\n }\n }\n\n /**\n * Rejects if and when calls to `wait()` become broken due to a failed critical section. The\n * actor should be shut down in this case. This promise never resolves, only rejects.\n */\n onBroken(): Promise<never> {\n if (this.brokenState.kind === \"exception\") {\n return Promise.reject(this.brokenState.exception);\n } else {\n return this.#brokenPromise;\n }\n }\n\n /** ← `kj::newAdaptedPromise<Lock, Waiter>(gate, isChildWaiter, span)`. */\n newWaiterPromise(isChildWaiter: boolean, signal?: AbortSignal): Promise<Lock> {\n const { promise, resolve, reject } = Promise.withResolvers<Lock>();\n const waiter = new Waiter(this, isChildWaiter, resolve, reject);\n onAbort(signal, () => {\n // ← `~Waiter` on the cancellation path. A waiter that already settled is unlinked, and\n // cancelling it is the no-op that dropping a settled promise is.\n if (!waiter.linked) return;\n waiter.reject(makeCanceledError());\n });\n return promise;\n }\n\n releaseLock(): void {\n if (this instanceof CriticalSection && this.state === \"REPARENTED\") {\n // This lock was for a critical section that has already completed, therefore the lock\n // should be considered \"reparented\", and we should forward the release to the parent.\n\n // Ensure any waiters on us have already been reparented.\n if (this.waitingChildren.length !== 0 || this.waiters.length !== 0 || this.lockCount !== 0) {\n throw new Error(\"releasing a lock on a reparented CriticalSection that still holds state\");\n }\n\n this.parentAsInputGate().releaseLock();\n return;\n }\n\n if (this.lockCount === 0) {\n throw new Error(\"InputGate::releaseLock() with no locks outstanding\");\n }\n this.lockCount--;\n\n // Check if any waiters can be released.\n if (this.lockCount === 0) {\n this.hooks.inputGateReleased();\n const child = this.waitingChildren[0];\n if (child !== undefined) {\n child.fulfill(new Lock(this));\n } else {\n const waiter = this.waiters[0];\n if (waiter !== undefined) {\n waiter.fulfill(new Lock(this));\n }\n }\n }\n }\n\n /** Called when a critical section fails. All future waiters will throw this exception. */\n setBroken(exception: unknown): void {\n // `reject()` unlinks the waiter it settles, so walk copies of both lists.\n for (const waiter of [...this.waitingChildren]) waiter.reject(exception);\n for (const waiter of [...this.waiters]) waiter.reject(exception);\n if (this.brokenState.kind === \"fulfiller\") {\n this.brokenState.reject(exception);\n }\n this.brokenState = { kind: \"exception\", exception };\n }\n}\n\n/** ← `InputGate::Lock`. A lock that blocks all new events from being delivered while it exists. */\nexport class Lock {\n /** ← \"Becomes null on move.\" Here it becomes undefined on `release()`. */\n #gate: InputGate | undefined;\n\n constructor(gate: InputGate) {\n this.#gate = gate;\n\n // Upstream keeps a second member, `kj::Own<CriticalSection> cs`, whose job is to hold the\n // section alive for the lock's lifetime. `gate` already points at the same object, and GC\n // does the holding, so here it is a local.\n let gateToLock: InputGate = gate;\n if (gate instanceof CriticalSection && gate.state === \"REPARENTED\") {\n gateToLock = gate.parentAsInputGate();\n }\n\n if (++gateToLock.lockCount === 1) {\n gateToLock.hooks.inputGateLocked();\n }\n }\n\n /** ← `~Lock`. */\n release(): void {\n const gate = this.#gate;\n if (gate === undefined) {\n throw new Error(\"InputGate::Lock was released twice\");\n }\n this.#gate = undefined;\n gate.releaseLock();\n }\n\n /**\n * Increments the lock's refcount, returning a duplicate `Lock`. All `Lock`s must be released\n * before the gate is unlocked.\n */\n addRef(): Lock {\n return new Lock(this.#requireGate());\n }\n\n /**\n * Start a new critical section from this lock. After `wait()` has been called on the returned\n * critical section for the first time, no further Locks will be handed out by\n * InputGate::wait() until the CriticalSection has been dropped.\n *\n * CriticalSections can be nested. If this Lock is itself part of a CriticalSection, the new\n * CriticalSection will be nested within it and the outer CriticalSection's wait() won't\n * produce a Lock again until the inner CriticalSection is dropped.\n */\n startCriticalSection(): CriticalSection {\n return new CriticalSection(this.#requireGate());\n }\n\n /** If this lock was taken in a CriticalSection, return it. */\n getCriticalSection(): CriticalSection | undefined {\n const gate = this.#requireGate();\n return gate instanceof CriticalSection ? gate : undefined;\n }\n\n isFor(otherGate: InputGate): boolean {\n if (otherGate instanceof CriticalSection) {\n throw new Error(\"InputGate::Lock::isFor() takes the root gate, not a CriticalSection\");\n }\n\n let ptr = this.#requireGate();\n while (ptr instanceof CriticalSection) {\n ptr = ptr.parentAsInputGate();\n }\n return ptr === otherGate;\n }\n\n /** ← `operator==`. */\n equals(other: Lock): boolean {\n return this.#requireGate() === other.#requireGate();\n }\n\n #requireGate(): InputGate {\n const gate = this.#gate;\n if (gate === undefined) {\n throw new Error(\"InputGate::Lock was used after release\");\n }\n return gate;\n }\n}\n\n/** ← `InputGate::CriticalSection::State`. */\ntype CriticalSectionState =\n /** wait() hasn't been called. */\n | \"NOT_STARTED\"\n /** wait() has been called once, and that wait hasn't finished yet. */\n | \"INITIAL_WAIT\"\n /** First lock has been obtained, waiting for success() or failed(). */\n | \"RUNNING\"\n /** success() or failed() has been called. */\n | \"REPARENTED\";\n\n/**\n * A CriticalSection is a procedure that must not be interrupted by anything \"external\".\n * While a CriticalSection is running, all events that were not initiated by the\n * CriticalSection itself will be blocked from being delivered.\n *\n * The difference between a Lock and a CriticalSection is that a critical section may succeed\n * or fail. A failed critical section permanently breaks the input gate. Locks, on the other\n * hand, are simply released when dropped.\n *\n * A CriticalSection itself holds a Lock, which blocks the \"parent scope\" from continuing\n * execution until the critical section is done. Meanwhile, the code running inside the critical\n * section obtains nested Locks. These nested locks control concurrency of the operations\n * initiated within the critical section in the same way that input locks normally do at the\n * top-level scope. E.g., if a critical section initiates a storage read and a fetch() at the\n * same time, the fetch() is prevented from returning until after the storage read has returned.\n */\nexport class CriticalSection extends InputGate {\n state: CriticalSectionState = \"NOT_STARTED\";\n\n /**\n * Points to the parent scope, which may be another CriticalSection in the case of nesting.\n * ← `kj::OneOf<InputGate*, kj::Own<CriticalSection>>`; the two arms are one `instanceof` apart.\n */\n readonly #parent: InputGate;\n\n /**\n * A lock in the parent scope. `parentLock` becomes non-null after the first lock is obtained,\n * and becomes null again when succeeded() is called.\n */\n #parentLock: Lock | undefined;\n\n constructor(parent: InputGate) {\n // Upstream's CriticalSection has no base initializer, so it gets `Hooks::DEFAULT` rather than\n // the parent gate's hooks: metrics are counted once, at the root.\n super();\n this.#parent = parent;\n }\n\n /**\n * Wait for a nested lock in order to continue this CriticalSection.\n *\n * The first call to wait() begins the CriticalSection. After that wait completes, until the\n * CriticalSection is done and dropped, no other locks will be allowed on this InputGate, except\n * locks requested by calling wait() on this CriticalSection -- or one of its children.\n *\n * Everything before the first `await` runs in the caller's synchronous slice, which is what\n * lets the NOT_STARTED path take its parent lock before any other event can queue behind it.\n */\n override async wait(signal?: AbortSignal): Promise<Lock> {\n // Before the state machine, not inside it: the NOT_STARTED arm takes a parent lock in its\n // synchronous slice, and a cancelled wait must not leave one behind.\n if (signal?.aborted === true) throw makeCanceledError();\n\n for (;;) {\n switch (this.state) {\n case \"NOT_STARTED\": {\n this.state = \"INITIAL_WAIT\";\n\n const target = this.parentAsInputGate();\n if (target.brokenState.kind === \"exception\") {\n // Oops, we're broken.\n const exception = target.brokenState.exception;\n this.setBroken(exception);\n throw exception;\n }\n\n // Add ourselves to this parent's child waiter list.\n if (target.lockCount === 0) {\n this.state = \"RUNNING\";\n this.#parentLock = new Lock(target);\n continue;\n } else {\n let lock: Lock;\n try {\n lock = await target.newWaiterPromise(true, signal);\n } catch (exception) {\n // kj destroys the coroutine on cancellation, so no catch runs and the state stays\n // INITIAL_WAIT — the case `drop()` calls \"had better have been canceled\".\n if (exception instanceof CanceledError) throw exception;\n this.state = \"RUNNING\";\n this.setBroken(exception);\n throw exception;\n }\n this.state = \"RUNNING\";\n this.#parentLock = lock;\n continue;\n }\n }\n case \"INITIAL_WAIT\":\n // To avoid the need for a ForkedPromise, we assume wait() is called once initially to\n // get things started. This is the case in practice because any further tasks would be\n // started only after some code runs under the initial lock.\n throw new Error(\"CriticalSection::wait() should be called once initially\");\n case \"RUNNING\":\n // CriticalSection is active, so defer to InputGate implementation.\n return await super.wait(signal);\n case \"REPARENTED\":\n // Once the CriticalSection has declared itself done, then any straggler tasks it\n // initiated are adopted by the parent. Upstream needs a KJ_SWITCH_ONEOF here so as not\n // to bypass a parent CriticalSection's own override of wait(); JS is always virtual.\n return await this.#parent.wait(signal);\n }\n }\n }\n\n /**\n * Call when the critical section has completed successfully. If this is not called before the\n * CriticalSection is dropped, then failed() is called implicitly.\n *\n * Returns the input lock that was held on the parent critical section. This can be used to\n * continue execution in the parent before any other input arrives.\n */\n succeeded(): Lock {\n if (this.state !== \"RUNNING\") {\n throw new Error(\"CriticalSection::succeeded() requires a running critical section\");\n }\n\n // Once the CriticalSection has declared itself done, then any straggler tasks it initiated are\n // adopted by the parent. Appending preserves FIFO order against the parent's own waiters.\n const parentGate = this.parentAsInputGate();\n for (const waiter of this.waitingChildren) waiter.gate = parentGate;\n parentGate.waitingChildren.push(...this.waitingChildren);\n this.waitingChildren.length = 0;\n for (const waiter of this.waiters) waiter.gate = parentGate;\n parentGate.waiters.push(...this.waiters);\n this.waiters.length = 0;\n parentGate.lockCount += this.lockCount;\n this.lockCount = 0;\n\n this.state = \"REPARENTED\";\n const result = this.#parentLock;\n if (result === undefined) {\n throw new Error(\"CriticalSection::succeeded() with no parent lock\");\n }\n this.#parentLock = undefined;\n return result;\n }\n\n /**\n * Call to indicate the CriticalSection has failed with the given exception. This immediately\n * breaks the InputGate.\n */\n failed(exception: unknown): void {\n if (this.brokenState.kind === \"exception\") {\n // Already failed I guess.\n return;\n }\n\n this.setBroken(exception);\n if (this.#parent instanceof CriticalSection) {\n this.#parent.failed(exception);\n } else {\n this.#parent.setBroken(exception);\n }\n }\n\n /** ← `~CriticalSection`. */\n drop(): void {\n switch (this.state) {\n case \"NOT_STARTED\":\n // Oh well.\n break;\n case \"INITIAL_WAIT\":\n // The initial wait() had better have been canceled... but we have no way to tell here.\n break;\n case \"RUNNING\":\n this.failed(\n new Error(\n \"jsg.Error: A critical section within this Durable Object awaited a Promise that \" +\n \"apparently will never complete. This could happen in particular if a critical \" +\n \"section awaits a task that was initiated outside of the critical section. Since \" +\n \"a critical section blocks all other tasks from completing, this leads to \" +\n \"deadlock.\",\n ),\n );\n break;\n case \"REPARENTED\":\n // Common case.\n break;\n }\n\n // `parentLock` is a `kj::Maybe<Lock>` MEMBER (`io-gate.h:234`), so the destructor body above\n // is followed by its destruction, which hands the parent lock back. After the switch, not\n // inside it: `failed()` must see the lock count upstream would show it.\n //\n // Only RUNNING can still hold one, and not even always — see `wait()`'s catch arm, which\n // sets RUNNING for a section broken during its initial wait without ever acquiring a lock.\n // NOT_STARTED and INITIAL_WAIT never assign it, and REPARENTED gave it away in\n // `succeeded()`. Clearing first, as `succeeded()` does, makes a second drop a no-op rather\n // than a \"released twice\" throw.\n const parentLock = this.#parentLock;\n if (parentLock !== undefined) {\n this.#parentLock = undefined;\n parentLock.release();\n }\n }\n\n /** Return a reference for the parent scope, skipping any reparented CriticalSections */\n parentAsInputGate(): InputGate {\n // Upstream walks a `ptr` starting at `this` and reads `ptr->parent` each turn; walking the\n // parent link itself visits the same chain without aliasing `this`.\n let parent = this.#parent;\n for (;;) {\n if (!(parent instanceof CriticalSection)) return parent;\n if (parent.state !== \"REPARENTED\") return parent;\n // Keep looping...\n parent = parent.#parent;\n }\n }\n}\n\n// =======================================================================================\n// makeReentryCallback\n\n/**\n * ← the gate half of `IoContext::makeReentryCallback()` (`io-context.h:1507`), which is\n * `ctx.run(func, cs)` with the critical section captured here rather than looked up later.\n *\n * Upstream, on why the critical section travels with the callback at all:\n *\n * > \"What if the call was made within blockConcurrencyWhile()? The callback will be blocked until\n * > the critical section ends, which could lead to deadlock if the critical section code is\n * > waiting on it? ... The callback is allowed to run within the critical section\n * > (blockConcurrencyWhile()) from which it was called.\"\n *\n * `criticalSection` must come from the capturing lock's `getCriticalSection()`, at the moment of\n * capture. It cannot be recovered from gate state on invocation: a *new* external event that\n * inherited the running section would skip the queue, and `blockConcurrencyWhile` would silently\n * block nothing (Part 4).\n *\n * The lock covers the callback's synchronous slice and is released when the callback returns\n * control — decision 1, and the reason a callback that awaits something does not wedge the gate.\n * A callback needing the lock across an await takes `lock.addRef()`, which is upstream's\n * `awaitIoWithInputLock` in the one shape io-gate can express (§1.2).\n *\n * The returned function can be called multiple times.\n */\nexport function makeReentryCallback<Args extends unknown[], Result>(\n gate: InputGate,\n criticalSection: CriticalSection | undefined,\n func: (lock: Lock, ...args: Args) => Result | PromiseLike<Result>,\n): (...args: Args) => Promise<Result> {\n return async (...args: Args): Promise<Result> => {\n const lock = await (criticalSection === undefined ? gate.wait() : criticalSection.wait());\n\n let result: Result | PromiseLike<Result>;\n try {\n result = func(lock, ...args);\n } finally {\n lock.release();\n }\n return await result;\n };\n}\n\n// =======================================================================================\n// OutputGate\n\n/**\n * Hooks that can be used to customize OutputGate behavior. See `InputGateHooks` for why these\n * are injected rather than wrapped.\n */\nexport interface OutputGateHooks {\n /**\n * Optionally make a promise which should be raced with the lock promise to implement a\n * timeout. The returned promise should be something that throws an exception after some\n * timeout has expired.\n */\n makeTimeoutPromise(): Promise<never>;\n\n outputGateLocked(): void;\n outputGateReleased(): void;\n outputGateWaiterAdded(): void;\n outputGateWaiterRemoved(): void;\n}\n\n/** ← `OutputGate::Hooks::DEFAULT`. */\nexport const DEFAULT_OUTPUT_GATE_HOOKS: OutputGateHooks = {\n /** ← `kj::NEVER_DONE`. */\n makeTimeoutPromise: () => new Promise<never>(() => {}),\n outputGateLocked() {},\n outputGateReleased() {},\n outputGateWaiterAdded() {},\n outputGateWaiterRemoved() {},\n};\n\n/** ← `kj::Own<kj::PromiseFulfiller<void>>`, the one link `lockWhile` holds in the chain. */\ninterface VoidFulfiller {\n isWaiting(): boolean;\n fulfill(): void;\n reject(exception: unknown): void;\n}\n\n/** ← `OutputGate::makeUnfulfilledException()`. */\nfunction makeUnfulfilledException(): Error {\n return new Error(\"output lock was canceled before completion\");\n}\n\n/**\n * An OutputGate blocks outgoing messages from an Actor until writes which they might depend on\n * are confirmed.\n *\n * A promise chain, not a counter (§1.1): each `lockWhile` joins a new link onto the chain and\n * re-forks it, so a `wait()` is bound to exactly the locks outstanding when it was taken and is\n * unaffected by any later `lockWhile`.\n */\nexport class OutputGate {\n readonly #hooks: OutputGateHooks;\n #pastLocksPromise: Promise<void> = Promise.resolve();\n /** A fulfiller for onBroken(), or an exception if already broken. */\n #brokenState: BrokenState = { kind: \"none\" };\n\n constructor(hooks: OutputGateHooks = DEFAULT_OUTPUT_GATE_HOOKS) {\n this.#hooks = hooks;\n }\n\n /**\n * Block all future `wait()` calls until `promise` completes. Returns a wrapper around\n * `promise`. If `promise` rejects, the exception will propagate to all future `wait()`s. If the\n * returned promise is canceled before completion, all future `wait()`s will also throw.\n */\n lockWhile<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n const fulfiller = this.#lock();\n const raced = Promise.race([promise, this.#hooks.makeTimeoutPromise()]);\n\n this.#hooks.outputGateLocked();\n\n return new Promise<T>((resolve, reject) => {\n // ← the `kj::defer(rejectIfCanceled)` arm that runs when the coroutine is destroyed.\n // Upstream leaves the dropped promise unobservable; here the caller still holds it, and a\n // promise that never settles is a hang nobody can see, so it takes the same exception.\n onAbort(signal, () => {\n // The guard comes first, as it does in `Waiter`. Upstream can call the hook before its\n // own check because `kj::defer` runs once ever, on whichever path exits the scope; an\n // abort listener can fire after the lock already settled, so the invariant to preserve\n // is \"exactly one release per lockWhile\", not upstream's statement order.\n if (!fulfiller.isWaiting()) return;\n this.#hooks.outputGateReleased();\n const exception = makeUnfulfilledException();\n this.#setBroken(exception);\n fulfiller.reject(exception);\n reject(exception);\n });\n\n void raced.then(\n (value) => {\n // kj would have destroyed this frame on cancellation; there is nothing left to settle.\n if (!fulfiller.isWaiting()) return;\n fulfiller.fulfill();\n this.#hooks.outputGateReleased();\n resolve(value);\n },\n (exception: unknown) => {\n if (!fulfiller.isWaiting()) return;\n this.#setBroken(exception);\n fulfiller.reject(exception);\n this.#hooks.outputGateReleased();\n reject(exception);\n },\n );\n });\n }\n\n /**\n * Wait until all preceding locks are released. The wait will not be affected by any future\n * call to `lockWhile()`.\n */\n wait(): Promise<void> {\n this.#hooks.outputGateWaiterAdded();\n return this.#pastLocksPromise.then(\n () => {\n this.#hooks.outputGateWaiterRemoved();\n },\n (exception: unknown) => {\n this.#hooks.outputGateWaiterRemoved();\n throw exception;\n },\n );\n }\n\n /**\n * Rejects if and when calls to `wait()` become broken due to a failed lockWhile(). The actor\n * should be shut down in this case. This promise never resolves, only rejects.\n *\n * This method can only be called once.\n */\n onBroken(): Promise<never> {\n if (this.#brokenState.kind === \"fulfiller\") {\n throw new Error(\"onBroken() can only be called once\");\n }\n\n if (this.#brokenState.kind === \"exception\") {\n return Promise.reject(this.#brokenState.exception);\n } else {\n const { promise, reject } = Promise.withResolvers<never>();\n this.#brokenState = { kind: \"fulfiller\", reject };\n void promise.catch(() => {});\n return promise;\n }\n }\n\n isBroken(): boolean {\n return this.#brokenState.kind === \"exception\";\n }\n\n #lock(): VoidFulfiller {\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n\n // ← `kj::joinPromises`, which waits for EVERY branch and only then propagates the first\n // exception. `Promise.all` is fail-fast, which \"OutputGate exception\" explicitly forbids: a\n // later lock failing must not release an earlier `wait()`.\n this.#setPastLocks(\n Promise.allSettled([this.#pastLocksPromise, promise]).then((results) => {\n for (const result of results) {\n if (result.status === \"rejected\") throw result.reason;\n }\n }),\n );\n\n let waiting = true;\n return {\n isWaiting: () => waiting,\n fulfill: () => {\n waiting = false;\n resolve();\n },\n reject: (exception) => {\n waiting = false;\n reject(exception);\n },\n };\n }\n\n #setPastLocks(promise: Promise<void>): void {\n this.#pastLocksPromise = promise;\n // kj's ForkedPromise holds a rejection with no branches attached; JS calls that unhandled.\n void promise.catch(() => {});\n }\n\n #setBroken(exception: unknown): void {\n // We assume the exception is already propagated into `pastLocksPromise`, so all we need to do\n // is handle onBroken().\n if (this.#brokenState.kind === \"fulfiller\") {\n this.#brokenState.reject(exception);\n }\n this.#brokenState = { kind: \"exception\", exception };\n }\n}\n","/**\n * ← workerd `src/workerd/io/io-context.{h,c++}`\n *\n * IoContext: the one door, plus the two await forms.\n *\n * This is the file with no true upstream correspondence for its *enforcement*.\n * Workerd acquires the input gate at isolate entry, so acquisition is\n * structural. We have no isolate hook, so a lock is taken at our own dispatch\n * boundary instead. See \"The enforcement point is the one thing we cannot port\"\n * in the design record.\n *\n * What this file does, stated before anything about how it got here:\n *\n * 1. `#currentInputLocks` is a STACK of the locks held by the slices that are\n * running. It is upstream's single `kj::Maybe<InputGate::Lock>\n * currentInputLock` member (`io-context.h:993`) with the `Maybe` widened,\n * and a \"frame\" is an entry in it. A frame carries nothing else: the only\n * two things ever read from one are the lock (`getInputLock`) and the\n * critical section that lock belongs to (`getCriticalSection`), and the\n * lock answers both.\n * 2. A lock is released, and leaves the stack, at the END OF THE MICROTASK\n * CHECKPOINT of the slice holding it — not when that slice's synchronous\n * body returns. That is upstream's own boundary, not a relaxation of it:\n * `runImpl`'s inner `KJ_DEFER` calls `js.runMicrotasks()`\n * (`io-context.c++:1262`) and `runInContextScope`'s outer one then clears\n * `currentInputLock` (`:1214`), inner scope first, so the whole checkpoint\n * drains under the lock. `currentInputLock` holds the `Lock` by value, so\n * clearing it is the release. `atCheckpointEnd` below is that point.\n * 3. NEITHER await form releases anything at the moment of the await.\n * `awaitIo` reads `getCriticalSection()` and `awaitIoWithInputLock` takes\n * an `addRef`; both then return a promise and let the slice end normally.\n * So an invocation that calls `awaitIo` keeps the gate until its own\n * checkpoint-end exit and the gate opens there — which is still before any\n * real I/O can complete, so \"a bare timer releases the input gate\" holds.\n * Upstream is the same: `getCriticalSection()` (`io-context.c++:362`) does\n * not touch `currentInputLock`, and `:1214` is the only place that clears\n * it. The difference between the two forms is entirely on the far side —\n * `awaitIo` re-enters through `run(func, criticalSection)` and queues for a\n * fresh lock, `awaitIoWithInputLock` re-enters holding the ref it took.\n * 4. Removal from the stack is by identity, not by popping, because entries do\n * overlap — three deep in the unit tests. One invocation can have several\n * held awaits outstanding (`Promise.all` over two storage reads), and a\n * section's last body slice overlaps the slice that resolves it.\n *\n * Two mechanics were validated against real workerd before this scaffolding\n * landed, and both are easy to get wrong:\n *\n * 1. The ambient \"which lock am I under\" must be a STACK of invocation frames,\n * not a single slot, so that `current` always names the running invocation.\n * The prototype that found this stated it as \"`awaitIo` splices its frame\n * out and re-pushes the SAME frame on resume\". That is not what happens\n * here and the difference is worth knowing: nothing splices at the point of\n * the await, because a lock already leaves the stack when its slice ends,\n * which is the same event that releases it (`#exit` does both). A\n * resumption then pushes a fresh lock. The prototype needed the splice\n * because its door held one lock for a whole invocation; the identity that\n * has to survive an await here is the critical section, and that is\n * captured at the call rather than looked up later.\n * 2. That ambient is safe here for a reason that does NOT generalise to the\n * §2.3 ambient-field hazard: the gate guarantees pushes and pops nest\n * properly in time, because only one holder chain is inside at once.\n * `_cf_currentSubAgentBridge` has no such guarantee, which is why it is a\n * live bug and this is not.\n *\n * Consequence: no async context is required. Do not add a dependency on\n * decision 8 here without re-running the conformance gate suite first.\n *\n * The invariant a future simplifier has to re-check: a single slot would pass\n * every test in `io-context.test.ts`, and that was established by trying it,\n * not by argument. `current()` is only read from inside a slice, every slice\n * pushes its own lock last, and no second slice can begin while an earlier\n * frame is still waiting for its checkpoint-end exit — that frame is holding\n * the gate. So the top of a stack and the last write to a slot always agree.\n * The stack is still what is here, because a slot would be holding a stale\n * value at every one of the overlaps in (4), and that is unobservable for\n * exactly as long as the invariant holds. Tightening (2) back to the end of the\n * synchronous body breaks it immediately, which is the regime the mechanic was\n * found in.\n *\n * Spec: §1.2, §1.3, §1.5, §1.6, §1.7.1, §1.9, decisions 1, 2, 4 and 13 in\n * docs/decisions.md.\n *\n * `TimeoutManager` is the only part of this file a consumer's own code reaches\n * directly: every host-provided async primitive a\n * Durable Object can await has to route through here, or the continuation after\n * it resumes with an empty invocation stack. `TimeoutManager` below is the\n * timer half; `api/global-scope.ts` and `api/web-socket.ts` are the rest.\n *\n * Not ported, because the substrate has no equivalent to port onto: isolate and\n * async locks (`Worker::Lock`, `jsg::Lock`, `takeAsyncLock`) and everything\n * that exists to enter or leave an isolate — which is precisely the thing this\n * file substitutes for; the limit enforcer and `afterLimitTimeout` (the\n * deadline takes the `Timer` port instead); trace spans, already a recorded\n * divergence documented in §1.12; subrequest channels and HTTP, which are\n * `api/http.ts`'s gating over the substrate's own `fetch`;\n * `IoOwn`/`IoPtr`/`DeleteQueue`, which guard cross-context dereferences that GC\n * makes impossible; hang detection and `registerPendingEvent`, which need the\n * isolate's own idea of pending work; and the thread-local\n * `IoContext::current()` static, whose lock-resolving half the invocation stack\n * replaces — its *identity* half is `currentSlice` below, narrowed to the\n * synchronous slice, with one consumer and no resolver. `EventOutcome` and\n * `RequestObserver` are metrics types with no port, so `waitUntilStatus()`\n * returns the first exception instead.\n */\n\nimport {\n CriticalSection,\n type InputGate,\n Lock,\n type OutputGate,\n} from \"./io-gate\";\n\n/**\n * ← `kj::Timer`, threaded into IoContext upstream.\n *\n * A port with one production implementation would be an invented seam; this\n * one has two (real clock in browser and workerd) plus a fake the conformance\n * suite cannot exist without — the 30-second critical-section deadline and the\n * alarm retry ladder are not assertable on wall-clock time in CI.\n */\nexport interface Timer {\n now(): number;\n /** `kj::Timer::afterDelay`. The signal replaces kj's cancel-by-drop. */\n afterDelay(ms: number, signal?: AbortSignal): Promise<void>;\n}\n\n/**\n * ← the `Worker::Actor` surface reached through an `IoContext`:\n * `a.getInputGate()`, `a.getOutputGate()` and `a.shutdownActorCache()` from\n * `io-context.{h,c++}` itself, plus `assertCanSetAlarm()`, which\n * `api/actor-state.c++:486` reaches through\n * `IoContext::current().getActorOrThrow()`.\n *\n * `Worker::Actor` lives in `io/worker.h`, the same Bazel target as this file, so\n * naming the members its consumers use is upstream's own layering rather than a\n * new seam. Every context here is an actor context — there is no non-actor\n * request in a Durable Object runtime — so upstream's\n * `kj::Maybe<Worker::Actor&>` and every branch that tests it collapse to this\n * being required, and `getActorOrThrow()` cannot actually throw.\n */\nexport interface Actor {\n getInputGate(): InputGate;\n getOutputGate(): OutputGate;\n /** Abort abandons scheduled writes rather than flushing them (§1.6). */\n shutdownActorCache(reason: unknown): void;\n /**\n * ← `Worker::Actor::assertCanSetAlarm()` (`io/worker.c++:4090`). Every branch\n * of it reads the actor's class-instance lifecycle, which `server/` owns, so\n * `api/actor-state.ts`'s obligation is to call it and the container's is to\n * answer it.\n */\n assertCanSetAlarm(): void;\n}\n\n/** ← `static constexpr int64_t max = 3153600000000; // Milliseconds in 100 years`. */\nconst MAX_TIMEOUT_MS = 3_153_600_000_000;\n\n/** ← `afterLimitTimeout(30 * kj::SECONDS)` in `IoContext::blockConcurrencyWhile`. */\nexport const BLOCK_CONCURRENCY_WHILE_TIMEOUT_MS = 30_000;\n\n/** Copied verbatim: users and upstream tests match on it. */\nexport const BLOCK_CONCURRENCY_WHILE_TIMEOUT_MESSAGE =\n \"A call to blockConcurrencyWhile() in a Durable Object waited for too long. \" +\n \"The call was canceled and the Durable Object was reset.\";\n\n/** ← `jsg::annotateBroken(msg, \"broken.inputGateBroken\")`. */\nconst INPUT_GATE_BROKEN_PREFIX = \"broken.inputGateBroken; \";\n\n/**\n * THE check every storage entry point in `api/` makes before touching the\n * database, and the only place this package throws for a missing input lock.\n *\n * Upstream never faces the question. `IoContext::current()` is a thread-local\n * read with a `KJ_REQUIRE` behind it, and it cannot fail for a storage call\n * because isolate entry is the only way into an actor and it always took a\n * lock. We have no isolate hook (see this file's header), so a continuation\n * that resumed from a raw `setTimeout`, a raw `fetch`, or any other promise the\n * runtime does not own comes back with an empty invocation stack, and its next\n * storage call reaches `ActorSqlite` — which is synchronous, touches no gate,\n * and would happily serve it outside any transaction boundary.\n *\n * So this throws, matching the assert. It is deliberately ONE function called\n * from every entry point rather than a check written at each of them: the\n * policy is a design decision that belongs to the design record, and when it\n * changes it has to change in one place rather than across a surface the\n * vendored consumer reaches from hundreds of call sites. There is no lenient\n * mode, no flag, and no implicit acquire — a lost invocation is loud, and a\n * lost transaction boundary is not.\n */\nexport function requireInputLock(ctx: IoContext, op: string): void {\n if (ctx.hasCurrent()) return;\n throw new Error(`${op}: no input lock available in this context${ctx.describeLostLock()}`);\n}\n\n/**\n * A stack for `noteGateUse`, captured where user frames are still on the stack.\n *\n * The invocation stack's own push and pop are scheduler moments — `#runImpl`\n * runs from a gate resumption and `#exit` from a `MessageChannel` callback — so\n * a trace taken there names only runtime internals. The moments that still see\n * the caller are the synchronous entries into the gate machinery: an `awaitIo`\n * call, an `entry` dispatch, a callback's registration. V8's zero-cost async\n * traces extend those with the awaiting chain, which is usually the frame the\n * reader actually wants.\n *\n * The first slice drops the `Error` header (absent on SpiderMonkey) and the two\n * runtime frames: this helper and the gate entry point that called it.\n */\nexport function captureGateStack(): string | undefined {\n const stack = new Error().stack;\n if (stack === undefined) return undefined;\n const frames = stack.split(\"\\n\");\n const trimmed = frames.slice(frames[0]?.startsWith(\"Error\") ? 3 : 2).join(\"\\n\");\n return trimmed === \"\" ? undefined : trimmed;\n}\n\n/**\n * The end of the microtask checkpoint — the moment `runImpl`'s `KJ_DEFER` fires.\n *\n * Upstream drains the whole checkpoint INSIDE the isolate run: the defer calls\n * `js.runMicrotasks()` and only the outer defer in `runInContextScope` then\n * clears `currentInputLock`. So a continuation that awaits nothing but\n * already-resolved promises stays under the same lock, and a continuation that\n * waits on real I/O does not. In JS the only observable end of a microtask drain\n * is the next macrotask, so that is where a lock leaves the invocation stack.\n *\n * Measured, because the obvious alternatives are wrong in ways nothing catches:\n * releasing synchronously when the invoked function returns, or on the next\n * microtask, both hand the lock back BEFORE the code awaiting the I/O resumes as\n * soon as one promise sits between the two — one `async` wrapper, a `.then`, a\n * `Promise.all` — and `actor-state.ts` is exactly such a wrapper. The gate would\n * then open in the middle of a storage await with no test failing, which is the\n * silent loss of atomicity §1.7.1 names.\n *\n * `MessageChannel` and not `setTimeout`, decided by benchmark rather than by\n * argument, because the two are three orders of magnitude apart on the shapes\n * that wait for a release. A chain of these schedules each hand-off from inside\n * the previous one's callback, so a `setTimeout` chain's nesting level climbs\n * past five and stays there, where browsers clamp it to 4ms. Median per hand-off\n * over 50 chained hops:\n *\n * | | setTimeout | MessageChannel |\n * | node | 1.273 ms | 0.018 ms |\n * | chromium page | 4.96 ms | 0.024 ms |\n * | chromium Worker | 5.542 ms | 0.022 ms |\n *\n * Only two shapes pay it: an `awaitIo` chain, which has to re-acquire the lock\n * its slice gave up, and a queue of events waiting on the holder. A chain of\n * held storage awaits does not — the lock passes from `addRef` to `addRef` and\n * the release is off the critical path. So 50 sequential facet RPCs cost 277ms\n * of pure clamp in a Worker under `setTimeout` and 1.1ms under this.\n *\n * One channel per BATCH, and a batch is an explicit array: `atCheckpointEnd`\n * pushes onto `pendingCheckpointEnds` and only the push that finds it empty opens\n * a channel. Ordering then comes from the array, which the language guarantees,\n * rather than from delivery order across separate channels, which no\n * specification does. That mattered because the storage engine below depends on\n * a commit scheduled inside a slice running before the release scheduled at the\n * end of that slice; separate channels do deliver in post order in Node,\n * measured across 200 of them including one scheduled from inside another's\n * callback, but a browser that chose otherwise would open the gate onto a\n * transaction a previous event left open, and nothing would say so.\n *\n * A callback scheduled DURING a drain lands in the next batch, which is the\n * semantics to want: one hand-off is one checkpoint end, and a slice that begins\n * inside this drain gets its own. The drain runs every callback even if one\n * throws, and rethrows the first exception afterwards, because abandoning the\n * rest of a batch is how a gate wedges with nothing to see.\n *\n * A long-lived shared port was rejected for the reason it always is: it has to be\n * closed on abort and `unref`'d so it cannot hold a test runner's event loop\n * open, and an `unref`'d port can drop a release at exit — a wedged gate. A\n * channel that lives for exactly one message cannot. Batching gets most of what\n * a shared port was worth anyway: a slice that schedules a commit and a release\n * now allocates one channel where it used to allocate two.\n *\n * **Exported because `kj::evalLater()` is this same point.** `ActorSqlite` opens\n * its implicit transaction on the first write and commits it \"on the next turn of\n * the event loop\" (`actor-sqlite.c++:352-357`); upstream's next turn is after the\n * isolate run, which is after `js.runMicrotasks()`, which is after\n * `currentInputLock` is cleared. Upstream's two boundaries are one boundary, and\n * they stay one here only if the commit rides the same primitive as the release.\n * Two consequences the storage engine depends on, both properties of this\n * function rather than of `ActorSqlite`:\n *\n * 1. **Everything that holds the input lock across an await is a microtask\n * chain.** `awaitIoWithInputLock` resumes through `#awaitIoImpl`'s `.then`\n * into `run(func, lock)`, which never waits on the gate. So a whole run of\n * held storage awaits finishes before the next hand-off and its writes are\n * one transaction (§1.7.1 row 1).\n * 2. **Everything that releases it needs at least one hand-off.** `awaitIo`\n * resumes through `gate.wait()`, which cannot resolve until `#exit` runs\n * here. So a timer or outbound await puts the commit between the two writes\n * (§1.7.1 row 2).\n *\n */\nexport function atCheckpointEnd(run: () => void): void {\n pendingCheckpointEnds.push(run);\n if (pendingCheckpointEnds.length > 1) return;\n\n const channel = new MessageChannel();\n // Assigning `onmessage` starts the port; `addEventListener` would need `start()`.\n channel.port1.onmessage = () => {\n channel.port1.close();\n channel.port2.close();\n // A snapshot, so a callback scheduled by one of these belongs to the next batch — and, since\n // the queue is empty while the batch runs, that push opens the next channel by itself.\n const batch = pendingCheckpointEnds.splice(0);\n let failure: { readonly exception: unknown } | undefined;\n for (const callback of batch) {\n try {\n callback();\n } catch (exception) {\n failure ??= { exception };\n }\n }\n if (failure !== undefined) throw failure.exception;\n };\n channel.port2.postMessage(0);\n}\n\n/** The current batch. Its order is the hand-off order every consumer below relies on. */\nconst pendingCheckpointEnds: (() => void)[] = [];\n\n// =======================================================================================\n// `IoContext::current()`, narrowed to what JS can express\n\n/**\n * ← `static thread_local IoContext* threadLocalRequest` (`io-context.c++:25`).\n *\n * **This is NOT an async context and must not become one.** It is set on entry\n * to a slice's SYNCHRONOUS body and restored the instant that body returns —\n * which for an `async` function is its first `await`. It propagates through\n * exactly nothing. The package's \"no async context is required\" property\n * (README, Part 4 mechanic 1) is undisturbed: nothing resolves a lock through\n * this, and deleting it would change no gate behaviour.\n *\n * Upstream's scope is wider and cannot be matched. `runInContextScope` saves the\n * previous context, installs itself, and restores at the end of the isolate run\n * — which drains the whole microtask checkpoint synchronously, so upstream's\n * `current()` covers a slice's continuations too. JS cannot drain a checkpoint\n * synchronously, so covering continuations here would mean holding the value\n * until `atCheckpointEnd`, and by then a SECOND actor's body can have run and\n * left. That is not a hazard upstream has: two actors' slices genuinely overlap\n * in this window (§1.10 gives every facet its own gates, so nothing serialises\n * a parent against its child), and the value would be wrong with nothing to say\n * so.\n *\n * So the port keeps only the half that is exact, and the one consumer is a\n * tripwire that refuses on mismatch and stays quiet on `undefined` — never a\n * resolver. See `requireOwnSlice` in `api/global-scope.ts`.\n */\nlet currentSlice: IoContext | undefined;\n\n/** ← `IoContext::tryCurrent()` (`io-context.c++:1416-1422`), over the narrowed scope above. */\nexport function tryCurrentSlice(): IoContext | undefined {\n return currentSlice;\n}\n\n/**\n * ← the `SuppressIoContextScope` constructor's `threadLocalRequest = this` half\n * (`io-context.c++:1208`), as a function rather than an assignment in `#runImpl`.\n *\n * A function because `currentSlice = this` reads to a linter as a `this` alias — the\n * ES5 `var self = this` habit — when it is the opposite: publishing the running\n * context to a module scope, which is exactly what the C++ does to a thread local.\n */\nfunction enterSlice(context: IoContext | undefined): void {\n currentSlice = context;\n}\n\n/** ← `kj::OneOf<T, kj::Exception>`, the result of `promiseForExceptionOrT()`. */\ntype Outcome<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly exception: unknown };\n\n/** ← `promiseForExceptionOrT()`: merge the rejection into the value so it survives the hop. */\nfunction promiseForExceptionOrT<T>(promise: Promise<T>): Promise<Outcome<T>> {\n return promise.then(\n (value): Outcome<T> => ({ ok: true, value }),\n (exception: unknown): Outcome<T> => ({ ok: false, exception }),\n );\n}\n\n/** ← `IdentityFunc<T>`. */\nfunction identity<T>(value: T): T {\n return value;\n}\n\n/**\n * ← the `if (!msg.startsWith(\"broken.\"))` guard in `blockConcurrencyWhile`'s error\n * handler. Upstream rewrites the exception's description in place, so this does\n * too. `jsg`'s exception tunnelling — the `jsg.Error:` / `remote.` prefixes\n * `annotateBroken()` also produces — has no port here, so only the brokenness tag\n * it exists to carry survives.\n */\nfunction annotateInputGateBroken(exception: unknown): void {\n if (!(exception instanceof Error)) return;\n if (exception.message.startsWith(\"broken.\") || exception.message.startsWith(\"remote.broken.\")) {\n return;\n }\n exception.message = INPUT_GATE_BROKEN_PREFIX + exception.message;\n}\n\n/**\n * ← `jsg::isExceptionFromInputGateBroken` (`jsg/exception.c++:168-172`):\n * \"annotateBroken() produces 'broken.inputGateBroken; {message}', optionally\n * prefixed with 'remote.' when crossing RPC boundaries. Strip the remote prefix\n * first, then check the tag.\"\n *\n * Its writer is `annotateInputGateBroken` directly above, which is why the two\n * live together rather than the reader moving to its consumer: `jsg/` has no\n * module here, and a prefix known in two places is a prefix that drifts.\n */\nexport function isExceptionFromInputGateBroken(exception: unknown): boolean {\n if (!(exception instanceof Error)) return false;\n let description = exception.message;\n // \"there are cases where we return a tunneled error through multiple workers, so let's be\n // paranoid and allow for multiple 'remote.' prefixes\" (`jsg/exception.c++:52-57`).\n while (description.startsWith(REMOTE_EXCEPTION_PREFIX)) {\n description = description.slice(REMOTE_EXCEPTION_PREFIX.length);\n }\n return description.startsWith(INPUT_GATE_BROKEN_PREFIX);\n}\n\n/** ← `ERROR_REMOTE_PREFIX` (`jsg/exception.h`). */\nconst REMOTE_EXCEPTION_PREFIX = \"remote.\";\n\n/**\n * ← `jsg::EXCEPTION_IS_USER_ERROR` (`jsg/exception.h:160`), a\n * `kj::Exception::DetailTypeId` attached to an arbitrary exception rather than a\n * type of exception.\n *\n * A symbol-keyed property is the closest JS has: it rides any thrown object,\n * survives a rethrow, and cannot collide with anything an application writes.\n * `Symbol.for` rather than `Symbol()` so the detail is still legible after the\n * exception crosses a realm — the mistake decision 18 records capnweb making.\n */\nexport const EXCEPTION_IS_USER_ERROR = Symbol.for(\"workerd.exceptionIsUserError\");\n\n/** ← `error.setDetail(jsg::EXCEPTION_IS_USER_ERROR, kj::heapArray<byte>(0))`. */\nexport function setUserErrorDetail(exception: unknown): void {\n if (typeof exception !== \"object\" || exception === null) return;\n Object.defineProperty(exception, EXCEPTION_IS_USER_ERROR, {\n value: true,\n enumerable: false,\n configurable: true,\n });\n}\n\n/** ← `e.getDetail(jsg::EXCEPTION_IS_USER_ERROR) != kj::none`. */\nexport function hasUserErrorDetail(exception: unknown): boolean {\n if (typeof exception !== \"object\" || exception === null) return false;\n return (exception as Record<symbol, unknown>)[EXCEPTION_IS_USER_ERROR] === true;\n}\n\n// =======================================================================================\n// Timers\n\n/**\n * ← `TimeoutManager::TimeoutParameters` (`io/io-timers.h:71-80`).\n *\n * `callback` is nullable for upstream's stated reason: \"This is a maybe to allow\n * cancel to clear it and free the reference when it is no longer needed.\"\n */\ntype TimeoutParameters = {\n readonly repeat: boolean;\n readonly msDelay: number;\n callback: (() => void) | undefined;\n};\n\n/** ← `IoContext::TimeoutManagerImpl::TimeoutState` (`io-context.c++:133-148`). */\ntype TimeoutState = {\n readonly params: TimeoutParameters;\n isCanceled: boolean;\n /**\n * ← `kj::Maybe<kj::Promise<void>> maybePromise`, whose presence upstream reads\n * as \"this timeout is armed\". kj cancels by dropping the promise; there is no\n * drop here, so the signal that aborts the underlying `Timer.afterDelay` is\n * carried beside it — the same substitution Section 1 made for every kj\n * cancel-by-drop.\n */\n armed: AbortController | undefined;\n};\n\n/**\n * ← `IoContext::TimeoutManagerImpl` (`io-context.c++:40-140`, `:742-880`).\n *\n * **The one mechanic worth reading twice: a timer is NOT `awaitIo`.** Upstream\n * says why in a comment on the very line (`io-context.c++:756-758`): \"the manual\n * use of run() here (including carrying over the critical section) is kind of\n * ugly, but using awaitIo() doesn't work here because we need the ability to\n * cancel the timer, so we don't want to addTask() it, which awaitIo() does\n * implicitly.\" So the shape is `cs = ctx.getCriticalSection()` captured at the\n * call, then `ctx.run(callback, cs)` when it fires. The captured section is what\n * makes a timer armed inside `blockConcurrencyWhile` run INSIDE that section\n * rather than queueing on the root gate behind it.\n *\n * **Substrate divergence: one `Timer.afterDelay` per timeout, where upstream\n * keeps a sorted `timeoutTimes` map and a single `timerTask` for the nearest.**\n * That structure exists because `kj::TimerChannel::atTime` supports one pending\n * wait, so upstream has to multiplex; `Timer.afterDelay` takes as many\n * concurrent waits as are asked for. The observable properties it produced —\n * timers fire in deadline order, ties broken by arming order — are the ones both\n * lane timers already have, since both are `setTimeout` underneath. Nothing else\n * in `resetTimerTask` is observable, so nothing else is ported.\n *\n * Not ported: `TimeoutId::Generator` and its cross-`ServiceWorkerGlobalScope`\n * assertion (`io-context.c++:52-60`), which exists to catch an IoContext being\n * current for a different V8 context — a confusion with no shape here, since a\n * timeout id is minted by the manager that owns it; `registerPendingEvent`,\n * which needs the isolate's own idea of pending work; and `getNextTimeout`,\n * whose only caller is the limit enforcer.\n */\nclass TimeoutManager {\n readonly #timer: Timer;\n readonly #timeouts = new Map<number, TimeoutState>();\n #nextId = 1;\n\n constructor(timer: Timer) {\n this.#timer = timer;\n }\n\n /** ← `TimeoutManagerImpl::setTimeout` (`io-context.c++:51-67`). */\n setTimeout(ctx: IoContext, params: TimeoutParameters): number {\n const id = this.#nextId++;\n const state: TimeoutState = { params, isCanceled: false, armed: undefined };\n this.#timeouts.set(id, state);\n this.#arm(ctx, id, state);\n return id;\n }\n\n /** ← `TimeoutManagerImpl::clearTimeout` (`io-context.c++:874-883`). */\n clearTimeout(id: number): void {\n const state = this.#timeouts.get(id);\n // \"We can't find this timeout, thus we act as if it was already canceled.\"\n if (state === undefined) return;\n this.#cancel(id, state);\n }\n\n /** ← `TimeoutManagerImpl::getTimeoutCount` (`io-context.c++:71-73`). */\n getTimeoutCount(): number {\n return this.#timeouts.size;\n }\n\n /** ← `TimeoutManagerImpl::cancelAll` (`io-context.c++:83-87`). */\n cancelAll(): void {\n for (const [id, state] of [...this.#timeouts]) this.#cancel(id, state);\n }\n\n /** ← `TimeoutState::cancel` — clear the flag, drop the callback reference, disarm. */\n #cancel(id: number, state: TimeoutState): void {\n state.isCanceled = true;\n state.params.callback = undefined;\n state.armed?.abort();\n state.armed = undefined;\n this.#timeouts.delete(id);\n }\n\n /** ← `TimeoutManagerImpl::setTimeoutImpl` (`io-context.c++:742-853`). */\n #arm(ctx: IoContext, id: number, state: TimeoutState): void {\n // Captured HERE, at the arming call, exactly as upstream captures it into the `.then` lambda.\n // Reading it when the timer fires would give a new external event the running section and\n // `blockConcurrencyWhile` would silently block nothing (Part 4, mechanic 2).\n const criticalSection = ctx.getCriticalSection();\n const wake = new AbortController();\n state.armed = wake;\n\n const fired = this.#timer.afterDelay(state.params.msDelay, wake.signal).then(\n async () => {\n if (state.isCanceled) return;\n state.armed = undefined;\n await this.#fire(ctx, id, state, criticalSection);\n },\n (exception: unknown) => {\n // kj cancels by dropping the promise, which cannot report anything; Section 1 records\n // that the substitution turns every cancel-by-drop into an `AbortSignal` whose waiter\n // rejects with `CanceledError`. A wake THIS manager aborted is that cancellation and not\n // a failure. Anything else is the timer port's and is reported, so a substrate that\n // fails to keep time cannot look like a timer nobody armed.\n if (!state.isCanceled) throw exception;\n },\n );\n\n // ← `context.addWaitUntil(kj::mv(paf.promise))` (`io-context.c++:845-851`): \"Add a wait-until\n // task which resolves when this timer completes. This ensures that `IncomingRequest::drain()`\n // waits until all timers finish.\"\n //\n // Divergence, and it is the fail-closed direction. Upstream additionally swallows the chain's\n // rejection outright (`[](kj::Exception&&) {}`, `io-context.c++:817`) because a JS throw from\n // the callback has already reached the isolate's uncaught-exception path. There is no such path\n // here, so a swallow would lose it entirely; routing the rejection through the waitUntil set\n // records it in `waitUntilStatus()` — the context's existing failure channel — instead of\n // inventing a second one.\n ctx.addWaitUntil(fired);\n }\n\n /** ← the body of the `.then` at `io-context.c++:759-816`, which is one `context.run`. */\n async #fire(\n ctx: IoContext,\n id: number,\n state: TimeoutState,\n criticalSection: CriticalSection | undefined,\n ): Promise<void> {\n await ctx.run(() => {\n // \"We've been canceled before running. Nothing more to do.\"\n if (state.isCanceled) return;\n const callback = state.params.callback;\n if (callback === undefined) return;\n\n // ← \"First, move our timeout promise to the task set so it's safe to call clearInterval()\n // inside the user's callback.\" A non-repeating timeout is done with its entry either way; a\n // repeating one keeps it so `clearInterval` inside the callback still finds it.\n if (!state.params.repeat) {\n state.params.callback = undefined;\n this.#timeouts.delete(id);\n }\n\n // ← the `KJ_DEFER(unwindDetector.catchExceptionsIfUnwinding(...))`: \"The user's callback\n // might throw, but we need to at least attempt to reschedule interval callbacks even if\n // they throw.\"\n try {\n callback();\n } finally {\n if (state.params.repeat && !state.isCanceled) this.#arm(ctx, id, state);\n }\n }, criticalSection);\n }\n}\n\n/**\n * A set of background promises, with the one behaviour `kj::TaskSet` adds over an\n * array: a failing task reports to `taskFailed` instead of becoming an unhandled\n * rejection, and the set can be waited on until empty.\n */\nclass TaskSet {\n readonly #tasks = new Set<Promise<void>>();\n readonly #taskFailed: (exception: unknown) => void;\n\n constructor(taskFailed: (exception: unknown) => void) {\n this.#taskFailed = taskFailed;\n }\n\n add(promise: Promise<void>): void {\n const task = promise.then(\n () => {\n this.#tasks.delete(task);\n },\n (exception: unknown) => {\n this.#tasks.delete(task);\n this.#taskFailed(exception);\n },\n );\n this.#tasks.add(task);\n }\n\n /** ← `kj::TaskSet::onEmpty()`. Re-checks, since a task can add another. */\n async onEmpty(): Promise<void> {\n while (this.#tasks.size > 0) {\n await Promise.all([...this.#tasks]);\n }\n }\n}\n\n// =======================================================================================\n// IoContext\n\nexport class IoContext {\n readonly #actor: Actor;\n readonly #timer: Timer;\n\n /**\n * ← `kj::Maybe<InputGate::Lock> currentInputLock`, made a stack.\n *\n * The top entry is the lock of the slice that is running right now. Entries are\n * removed by identity rather than popped, so `#exit` never depends on the order\n * the overlapping slices happen to leave in.\n */\n readonly #currentInputLocks: Lock[] = [];\n\n /**\n * Where this context's gate was last deliberately engaged, for\n * `describeLostLock`. One slot, overwritten on every engagement — the gate\n * serialises slices, so the latest note is the best available ancestor of\n * whatever continuation is running lockless now.\n */\n #lastGateUse: { readonly what: string; readonly stack: string | undefined; readonly at: number } | undefined;\n\n #abortException: { readonly exception: unknown } | undefined;\n readonly #abortPromise: Promise<never>;\n readonly #rejectAbort: (exception: unknown) => void;\n\n /**\n * Two sets, as upstream: `abortWhen()` always uses `tasks` so that a monitor\n * which never completes cannot hold up a drain, while `addTask()` in an actor\n * is a waitUntil task.\n */\n readonly #tasks: TaskSet;\n readonly #waitUntilTasks: TaskSet;\n #addTaskCounter = 0;\n #waitUntilStatus: { readonly exception: unknown } | undefined;\n\n /** ← `kj::Own<TimeoutManager> timeoutManager` (`io-context.h:1043`). */\n readonly #timeouts: TimeoutManager;\n\n constructor(actor: Actor, timer: Timer) {\n this.#actor = actor;\n this.#timer = timer;\n this.#timeouts = new TimeoutManager(timer);\n\n const { promise, reject } = Promise.withResolvers<never>();\n this.#abortPromise = promise;\n this.#rejectAbort = reject;\n // kj's ForkedPromise just holds the exception until someone adds a branch.\n void promise.catch(() => {});\n\n this.#tasks = new TaskSet((exception) => this.#taskFailed(exception));\n this.#waitUntilTasks = new TaskSet((exception) => this.#taskFailed(exception));\n\n // Arrange to complain if the input gate is broken, which indicates a critical section\n // failed and the actor can no longer be used.\n this.abortWhen(actor.getInputGate().onBroken());\n\n // Also complain if the output gate is broken, which indicates a critical storage failure\n // that means we cannot continue execution.\n this.abortWhen(actor.getOutputGate().onBroken());\n }\n\n // -----------------------------------------------------------------\n // The ambient lock\n\n /**\n * Get the current input lock. Throws an exception if no input lock is held (e.g. because\n * this is not an actor request).\n *\n * ← `KJ_ASSERT_NONNULL(currentInputLock, ...).addRef()`. The `addRef` IS the §1.2\n * distinction: it is the only way to hold the gate past the end of this slice.\n */\n getInputLock(): Lock {\n return this.#requireCurrent().addRef();\n }\n\n /** Get the current CriticalSection, if there is one, or returns null if not. */\n getCriticalSection(): CriticalSection | undefined {\n return this.#currentInputLocks.at(-1)?.getCriticalSection();\n }\n\n /** Is a gated slice running? The question `IoContext::hasCurrent()` answers upstream. */\n hasCurrent(): boolean {\n return this.#currentInputLocks.length > 0;\n }\n\n /**\n * ← `IoContext::isCurrent()` (`io-context.c++:1428-1430`), over the narrowed\n * scope `currentSlice` documents: true only while a synchronous body of THIS\n * context is on the JS stack.\n *\n * Distinct from `hasCurrent()` above, which asks whether this context holds a\n * lock at all — true throughout an outstanding held await, and true for a\n * parent whose slice is awaiting a facet while the facet's body runs. This one\n * is the question a shared global has to answer: is the code calling me this\n * actor's?\n */\n isCurrentSlice(): boolean {\n return currentSlice === this;\n }\n\n /**\n * Record that user code just engaged this context's gate — an `awaitIo`, an\n * `entry` dispatch, a re-entry callback firing. No upstream analogue, because\n * upstream cannot lose the lock; here a continuation that awaits a promise\n * the runtime does not own comes back lockless, the throw lands at the next\n * storage call three layers later, and the gap between \"where the code last\n * verifiably ran gated\" and the throw site is exactly where the foreign await\n * hides. This is that first coordinate. Always on: the capture rides calls\n * that already allocate promise machinery, and a stack costs microseconds\n * against the diagnosis it replaces.\n */\n noteGateUse(what: string, stack: string | undefined): void {\n this.#lastGateUse = { what, stack, at: this.now() };\n }\n\n /**\n * The suffix `requireInputLock` appends when the invocation stack is empty:\n * where this context's gate was last engaged, and how long before the throw.\n *\n * \"Last engaged\" is the honest claim, not \"this continuation's ancestor\" —\n * once the offending chain went lockless the gate reopened, so another slice\n * may have run in between and be the note this reports. In practice the loss\n * is discovered within the same event storm and the note is the parent; when\n * it is not, an engagement of this actor moments earlier is still the right\n * neighbourhood to search.\n */\n describeLostLock(): string {\n const use = this.#lastGateUse;\n if (use === undefined) {\n return \" (this context has never held its gate: the call arrived from outside any actor invocation)\";\n }\n const age = Math.round(this.now() - use.at);\n const stackSuffix = use.stack === undefined ? \"\" : `, at:\\n${use.stack}`;\n return ` (an await after the last gated point resumed from a promise the runtime does not own; the gate was last engaged by ${use.what} ${age}ms before this call${stackSuffix})`;\n }\n\n /**\n * ← `IoContext::getActorOrThrow()`. Upstream's throws when the request is not\n * an actor request; there is no such request here, so it is a plain accessor.\n */\n getActorOrThrow(): Actor {\n return this.#actor;\n }\n\n /** ← `IoContext::now()` (`io-context.h:703`), which reads the same timer. */\n now(): number {\n return this.#timer.now();\n }\n\n // -----------------------------------------------------------------\n // Timers\n\n /**\n * ← `IoContext::setTimeoutImpl` (`io-context.c++:885-899`), clamp included.\n *\n * The generator parameter is gone with `TimeoutId::Generator` — see\n * `TimeoutManager`'s header — so the signature is upstream's minus that one\n * argument.\n */\n setTimeoutImpl(repeat: boolean, callback: () => void, msDelay: number): number {\n // \"Clamp the range on timers to [0, 3153600000000] (inclusive). The specs do not indicate a\n // clear maximum range for setTimeout/setInterval so the limit here is fairly arbitrary. 100\n // years max should be plenty safe.\"\n const delay =\n msDelay <= 0 || Number.isNaN(msDelay)\n ? 0\n : msDelay >= MAX_TIMEOUT_MS\n ? MAX_TIMEOUT_MS\n : Math.trunc(msDelay);\n return this.#timeouts.setTimeout(this, { repeat, msDelay: delay, callback });\n }\n\n /** ← `IoContext::clearTimeoutImpl` (`io-context.c++:901-903`). */\n clearTimeoutImpl(id: number): void {\n this.#timeouts.clearTimeout(id);\n }\n\n /** ← `IoContext::getTimeoutCount` (`io-context.c++:905-907`). */\n getTimeoutCount(): number {\n return this.#timeouts.getTimeoutCount();\n }\n\n // -----------------------------------------------------------------\n // The output gate\n\n /**\n * Wait until all outstanding output locks have been unlocked. Does not wait for future\n * output locks, even if they are created before past locks are unlocked.\n */\n waitForOutputLocks(): Promise<void> {\n return this.#actor.getOutputGate().wait();\n }\n\n /**\n * Check if the output gate is currently broken. This indicates that there was a problem\n * with committing storage writes.\n */\n isOutputGateBroken(): boolean {\n return this.#actor.getOutputGate().isBroken();\n }\n\n /** Lock output until the given promise completes. */\n lockOutputWhile<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n return this.#actor.getOutputGate().lockWhile(promise, signal);\n }\n\n // -----------------------------------------------------------------\n // Abort\n\n /**\n * Rejects if and when the context should be aborted, e.g. because a gate broke. This\n * promise never resolves, only rejects.\n */\n onAbort(): Promise<never> {\n return this.#abortPromise;\n }\n\n /** Force context abort now. */\n abort(exception: unknown): void {\n if (this.#abortException !== undefined) {\n return;\n }\n this.#abortException = { exception };\n\n // Stop the ActorCache from flushing any scheduled write operations to prevent any\n // unnecessary or unintentional async work.\n this.#actor.shutdownActorCache(exception);\n\n // ← `timeoutManager->cancelAll()` in `~IoContext_IncomingRequest`, plus the\n // `context.abortException == kj::none` guard that stops `setTimeoutImpl` rescheduling into an\n // aborted context (`io-context.c++:832`). Upstream reaches both through destruction; with no\n // destructors, abort is the one event that stands for it. Without this a pending timer wakes\n // into `run()`, which refuses an aborted context, and the refusal lands in `waitUntilStatus()`\n // as a failure nobody caused.\n this.#timeouts.cancelAll();\n\n this.#rejectAbort(exception);\n }\n\n /**\n * Await the given promise and, if it throws, call `abort()` with the exception. The promise\n * given here should just be a monitoring promise, it should not represent any sort of\n * background work beyond monitoring.\n */\n abortWhen(promise: Promise<unknown>): void {\n if (this.#abortException === undefined) {\n this.#tasks.add(\n promise.then(\n () => {},\n (exception: unknown) => {\n this.abort(exception);\n },\n ),\n );\n }\n }\n\n // -----------------------------------------------------------------\n // Task scheduling\n\n /**\n * Arrange for the given promise to execute as part of this request.\n *\n * \"In Actors, we treat all tasks as wait-until tasks, because it's perfectly legit to start\n * a task under one request and then expect some other request to handle it later.\" Every\n * context here is an actor context, so that branch is the only branch.\n */\n addTask(promise: Promise<void>): void {\n ++this.#addTaskCounter;\n this.addWaitUntil(promise);\n }\n\n /**\n * Indicates that the script has requested that it stay active until the given promise\n * resolves. `drainWaitUntil()` waits until all such promises have completed. Touches\n * neither gate (§1.9).\n */\n addWaitUntil(promise: Promise<void>): void {\n this.#waitUntilTasks.add(promise);\n }\n\n /** Returns the number of times addTask() has been called (even if the tasks have completed). */\n taskCount(): number {\n return this.#addTaskCounter;\n }\n\n /**\n * The first exception a background task failed with, if any.\n *\n * ← `waitUntilStatus()`, which returns an `EventOutcome` derived from the exception by\n * `RequestObserver`. There is no observer here, so the exception itself is the status —\n * and keeping it is what stops a failed background task from being swallowed, since\n * upstream's other half of `taskFailed()` is a log this package has no port for.\n */\n waitUntilStatus(): unknown {\n return this.#waitUntilStatus?.exception;\n }\n\n /**\n * ← `IncomingRequest::drain()`, actor branch. \"For actors, all promises are canceled on\n * actor shutdown, not on a fixed timeout, because work doesn't necessarily happen on a\n * per-request basis in actors.\"\n */\n async drainWaitUntil(): Promise<void> {\n await Promise.race([this.#waitUntilTasks.onEmpty(), this.#abortPromise.catch(() => {})]);\n }\n\n // -----------------------------------------------------------------\n // Entry\n\n /**\n * Run the given callback within this context, holding an input lock.\n *\n * ← the two `IoContext::run()` overloads: given a CriticalSection it waits on that, given\n * an already-held Lock it runs under it, and given neither it takes a fresh lock from the\n * gate. The third case is what a new external event does, and it is the reason inheritance\n * cannot be read from gate state — see `makeReentryCallback`.\n */\n async run<T>(\n func: (lock: Lock) => T | PromiseLike<T>,\n ilOrCs?: Lock | CriticalSection,\n ): Promise<T> {\n // Before we try running anything, let's make sure our IoContext hasn't been aborted. If it\n // has been aborted, there's likely not an active request so later operations will fail\n // anyway.\n const aborted = this.#abortException;\n if (aborted !== undefined) {\n throw aborted.exception;\n }\n\n let lock: Lock;\n if (ilOrCs === undefined) {\n lock = await this.#actor.getInputGate().wait();\n } else if (ilOrCs instanceof CriticalSection) {\n lock = await ilOrCs.wait();\n } else {\n lock = ilOrCs;\n }\n\n return await this.#runImpl(func, lock);\n }\n\n /**\n * Make a function which, when called, re-enters this IoContext to run some code.\n *\n * Upstream, on why the critical section travels with the callback at all:\n *\n * > \"What if the call was made within blockConcurrencyWhile()? The callback will be blocked\n * > until the critical section ends, which could lead to deadlock if the critical section\n * > code is waiting on it? ... The callback is allowed to run within the critical section\n * > (blockConcurrencyWhile()) from which it was called.\"\n *\n * The section is read here, at the point of capture, and never on invocation: a new\n * external event that inherited the running section would skip the queue and\n * `blockConcurrencyWhile` would silently block nothing (Part 4, mechanic 2).\n *\n * The returned function can be called multiple times.\n *\n * It does not route through `io-gate.ts`'s `makeReentryCallback`, which is the same idea\n * expressed at the gate. Upstream's `IoContext::makeReentryCallback` is literally\n * `ctx.run(func, cs)`, and going through the gate helper instead would take a lock this\n * file then has to make current a second time. The gate copy stays: it is the shape a\n * consumer holding only a gate needs, and Section 1's tests cover it.\n */\n makeReentryCallback<Args extends unknown[], Result>(\n func: (lock: Lock, ...args: Args) => Result | PromiseLike<Result>,\n ): (...args: Args) => Promise<Result> {\n // A reentry callback is meant for *re-*entry, so should only be created while already\n // inside the IoContext. Initial entry should just use run().\n this.#requireCurrent();\n const criticalSection = this.getCriticalSection();\n // Captured once, here, because the fire is a scheduler moment with no user\n // frames — the registration site is the trace a reader can act on.\n const registrationStack = captureGateStack();\n\n return async (...args: Args): Promise<Result> => {\n this.noteGateUse(\"a re-entry callback registered at the site below\", registrationStack);\n const call = this.run((lock) => func(lock, ...args), criticalSection);\n\n // ← the `addTask()` + `registerPendingEvent()` pair, which keeps the context live while\n // a callback is outstanding. Upstream scopes that to the callback's lifetime via a\n // destructor; with no destructors the closest live analogue is the in-flight call, which\n // is what should stop `drainWaitUntil()` reporting idle. The outcome is swallowed here\n // only because the caller already receives it.\n this.addTask(\n call.then(\n () => {},\n () => {},\n ),\n );\n\n return await call;\n };\n }\n\n // -----------------------------------------------------------------\n // The two await forms\n\n /**\n * Waits for some background I/O to complete, then executes `func` on the result.\n *\n * The input lock is NOT held across the wait: the resumption re-enters through\n * `run(func, criticalSection)` and takes a fresh lock, so it queues behind whatever\n * arrived in the meantime. This is what makes a Durable Object awaiting another Durable\n * Object fully re-entrant (§1.3).\n *\n * `func` is a parameter rather than something the caller chains, for upstream's reason:\n * chaining \"required returning to the KJ event loop between running func() and running\n * whatever JavaScript code was waiting on it\". Here the equivalent cost is a promise hop\n * outside the lock.\n */\n awaitIo<T>(promise: Promise<T>): Promise<T>;\n awaitIo<T, R>(promise: Promise<T>, func: (value: T) => R | PromiseLike<R>): Promise<R>;\n awaitIo<T, R>(\n promise: Promise<T>,\n func: (value: T) => R | PromiseLike<R> = identity as (value: T) => R,\n ): Promise<R> {\n this.noteGateUse(\"awaitIo\", captureGateStack());\n return this.#awaitIoImpl(promise, this.getCriticalSection(), func);\n }\n\n /**\n * Waits for the given I/O while holding the input lock, so that all other I/O is blocked\n * from completing in the meantime (unless it is also holding the same input lock).\n *\n * This is the whole of §1.2's asymmetry, and per §1.7.1 it is also the implicit-transaction\n * boundary: the four async storage calls take this form, everything else takes `awaitIo`.\n * Calling it outside a gated slice throws rather than inventing a lock — a lost invocation\n * is loud, a lost transaction boundary is not.\n */\n awaitIoWithInputLock<T>(promise: Promise<T>): Promise<T>;\n awaitIoWithInputLock<T, R>(\n promise: Promise<T>,\n func: (value: T) => R | PromiseLike<R>,\n ): Promise<R>;\n awaitIoWithInputLock<T, R>(\n promise: Promise<T>,\n func: (value: T) => R | PromiseLike<R> = identity as (value: T) => R,\n ): Promise<R> {\n let inputLock: Lock;\n try {\n // The exception is unchanged; only its shape is. A method that returns a promise and\n // sometimes throws synchronously instead escapes the caller's `.catch`, and this is the\n // one call every storage method makes.\n inputLock = this.getInputLock();\n } catch (exception) {\n return Promise.reject(exception);\n }\n this.noteGateUse(\"awaitIoWithInputLock\", captureGateStack());\n return this.#awaitIoImpl(promise, inputLock, func);\n }\n\n // -----------------------------------------------------------------\n // blockConcurrencyWhile\n\n /**\n * Runs `callback` within its own critical section, returning its final result. If\n * `callback` throws, the input lock will break, resetting the actor.\n *\n * Three behaviours live here rather than in `io-gate.ts`, which has no timer, and rather\n * than in `api/actor-state.ts`, whose own `blockConcurrencyWhile` is a one-line forward:\n * the 30-second deadline, the brokenness annotation, and the fact that on failure the\n * returned promise is never settled at all.\n */\n blockConcurrencyWhile<T>(callback: (lock: Lock) => T | PromiseLike<T>): Promise<T> {\n const lock = this.getInputLock();\n this.noteGateUse(\"blockConcurrencyWhile\", captureGateStack());\n const criticalSection = lock.startCriticalSection();\n const { promise: result, resolve } = Promise.withResolvers<T>();\n\n this.addTask(\n (async () => {\n try {\n const value = await this.#runCriticalSection(criticalSection, callback);\n\n // Hand the parent lock back and resolve under it, so the caller's continuation runs\n // before any other input arrives.\n await this.#runImpl(() => {\n resolve(value);\n }, criticalSection.succeeded());\n } catch (exception) {\n // Annotate as broken for periodic metrics. If we already set up a brokenness reason,\n // we shouldn't override it.\n annotateInputGateBroken(exception);\n\n // Note that on failure, no further InputLocks will be obtainable and the actor will\n // shut down, so don't worry about holding a lock until we get back to application\n // code -- we won't! In fact, we don't even bother calling resolver.reject() because\n // it's meaningless at this point.\n criticalSection.failed(exception);\n\n throw exception;\n } finally {\n // ← `~CriticalSection`. A no-op after `succeeded()`; on the failure path it is what\n // hands the parent lock back, since `failed()` does not.\n criticalSection.drop();\n }\n })(),\n );\n\n // ← the destruction of `auto lock` at the end of the upstream scope. Everything above is\n // synchronous, so the end of the setup is the end of the scope.\n lock.release();\n\n return result;\n }\n\n // -----------------------------------------------------------------\n\n /**\n * ← `runImpl()` + `runInContextScope()`: check the lock belongs to this actor, make it the\n * current one, run, and let `KJ_DEFER` clear it.\n *\n * The defer fires after the microtask checkpoint, not when `func` returns — see\n * `atCheckpointEnd`. Everything else about the scope is isolate machinery with no port.\n */\n async #runImpl<T>(func: (lock: Lock) => T | PromiseLike<T>, lock: Lock): Promise<T> {\n if (!lock.isFor(this.#actor.getInputGate())) {\n throw new Error(\"IoContext::runImpl() was given a lock belonging to another actor\");\n }\n\n this.#currentInputLocks.push(lock);\n let result: T | PromiseLike<T>;\n // ← `SuppressIoContextScope previousRequest; threadLocalRequest = this;` (`io-context.c++:1208`)\n // and its restoring destructor. Scoped to the synchronous body only — see `currentSlice`.\n const previousSlice = currentSlice;\n enterSlice(this);\n try {\n result = func(lock);\n } finally {\n enterSlice(previousSlice);\n atCheckpointEnd(() => {\n this.#exit(lock);\n });\n }\n return await result;\n }\n\n /**\n * ← `requireCurrent()`. Upstream asks whether this IoContext is the thread's current one;\n * with no thread-local there is only one question left, and it is the one every caller of\n * `requireCurrent()` actually depends on: is a gated slice running?\n */\n #requireCurrent(): Lock {\n const lock = this.#currentInputLocks.at(-1);\n if (lock === undefined) {\n throw new Error(`no input lock available in this context${this.describeLostLock()}`);\n }\n return lock;\n }\n\n /** ← the far side of `runInContextScope`'s `KJ_DEFER`. */\n #exit(lock: Lock): void {\n const at = this.#currentInputLocks.lastIndexOf(lock);\n if (at < 0) {\n throw new Error(\"IoContext invocation stack lost a lock it was holding\");\n }\n this.#currentInputLocks.splice(at, 1);\n lock.release();\n }\n\n /**\n * ← `awaitIoImpl()`.\n *\n * The KJ-side rejection is merged into the value so a single continuation handles both, the\n * continuation re-enters through `run(func, ilOrCs)`, and the whole thing rides `addTask()`.\n * When `ilOrCs` is a Lock this is `awaitIoWithInputLock` and the gate never opened; when it\n * is a CriticalSection or nothing this is `awaitIo` and the resumption queues for a fresh\n * lock like any other event.\n */\n #awaitIoImpl<T, R>(\n promise: Promise<T>,\n ilOrCs: Lock | CriticalSection | undefined,\n func: (value: T) => R | PromiseLike<R>,\n ): Promise<R> {\n const { promise: result, resolve, reject } = Promise.withResolvers<R>();\n\n this.addTask(\n promiseForExceptionOrT(promise).then(async (outcome) => {\n try {\n await this.run((): void => {\n if (outcome.ok) {\n // `func` runs under the lock, which is the guarantee that makes it a parameter.\n try {\n resolve(func(outcome.value));\n } catch (exception) {\n reject(exception);\n }\n } else {\n reject(outcome.exception);\n }\n }, ilOrCs);\n } catch (exception) {\n // `run()` refuses to re-enter an aborted context, and both of its throws happen\n // before the lock reaches the invocation stack. Upstream would destroy the whole\n // continuation here, releasing the held lock with it; with no destructors it has to\n // be handed back by name. `result` is deliberately left unsettled, as upstream\n // leaves it: the actor is being torn down and `onAbort()` is what reports that.\n if (ilOrCs instanceof Lock) ilOrCs.release();\n throw exception;\n }\n }),\n );\n\n return result;\n }\n\n /**\n * ← the first `.then()` of `blockConcurrencyWhile`: start the section, run the callback\n * under its first nested lock, and race the deadline.\n */\n async #runCriticalSection<T>(\n criticalSection: CriticalSection,\n callback: (lock: Lock) => T | PromiseLike<T>,\n ): Promise<T> {\n const inputLock = await criticalSection.wait();\n\n return await this.#runImpl((lock) => {\n // Remember that this can throw synchronously, and it's important that we catch such\n // throws and call cs->failed().\n const running = callback(lock);\n\n // Arrange to time out if the critical section runs more than 30 seconds, so that objects\n // won't be hung forever if they have a critical section that deadlocks.\n const deadline = new AbortController();\n const timeout = this.#timer\n .afterDelay(BLOCK_CONCURRENCY_WHILE_TIMEOUT_MS, deadline.signal)\n .then((): never => {\n throw new Error(BLOCK_CONCURRENCY_WHILE_TIMEOUT_MESSAGE);\n });\n\n // ← `exclusiveJoin`. The loser cannot be cancelled — a recorded divergence — but the\n // timer half of it can, which is what the signal is for: a section that finishes must\n // not leave a live 30-second timer behind.\n return Promise.race([Promise.resolve(running), timeout]).finally(() => {\n deadline.abort();\n });\n }, inputLock);\n }\n\n /** ← `IoContext::taskFailed()`, minus the logging half, which has no port. */\n #taskFailed(exception: unknown): void {\n if (this.#waitUntilStatus === undefined) {\n this.#waitUntilStatus = { exception };\n }\n }\n}\n","/**\n * ← workerd `src/workerd/api/actor.{h,c++}`\n *\n * Upstream's own opening comment is the best summary of why this file is named\n * what it is: \"'Actors' are the internal name for Durable Objects, because they\n * implement a sort of actor model. We ended up not calling the product 'Actors'\n * publicly because we found that people who were familiar with actor-model\n * programming were more confused than helped by it.\"\n *\n * Five classes and three outgoing factories. The five are here:\n * `ColoLocalActorNamespace` (`actor.h:25`), `DurableObjectId` (`:42`),\n * `DurableObject` (`:87`), `DurableObjectNamespace` (`:142`) and\n * `DurableObjectClass` (`:367`). The three factories — `GlobalActorOutgoingFactory`\n * (`:293`), `LocalActorOutgoingFactory` (`:331`) and `ReplicaActorOutgoingFactory`\n * (`:352`) — are **not**, and their absence is the whole of this file's seam:\n * every one of them is a bag of addressing data plus a lazily-created actor\n * channel, and `newSingleUseClient` returns a `WorkerInterface`, which is capnp\n * dispatch with no port. `ActorChannelFactory` and `ColoLocalActorChannelFactory`\n * below are the shape they plug into, holding exactly the fields the two\n * reachable factories' constructors capture.\n * `ActorRetryRequestMetadata` stays on that same omitted transport seam:\n * upstream passes it from an outgoing factory to `ActorChannel`, while the\n * host-provided `Fetcher` here already owns retry policy and exposes no metadata.\n *\n * **`ColoLocalActorNamespace` is ported, not treated as a substrate boundary**,\n * and the reason is worth stating because the opposite call is easy to defend\n * badly. It is the pre-SQLite, non-durable actor namespace, and this host cannot\n * host one — there is no storage-less actor kind here, and `createActorContainer`\n * requires a `SqlDatabaseProvider`. But *hosting* is not in this file. What is in\n * this file is the JS-facing half: one argument check and one outgoing-stub\n * request, which has precisely the same substrate needs as\n * `DurableObjectNamespace.get()`, which nobody proposes cutting. The boundary, if\n * there is one, sits in `server/` at the point something has to place an\n * ephemeral actor — so there is nothing here to cut, and cutting it would be the\n * feature subset the package README forbids.\n *\n * It is also not idle, though an earlier revision of this comment gave the wrong\n * reason. It claimed `ctx.exports` surfaces a storage-less actor class as a\n * `LoopbackColoLocalActorNamespace`; upstream's own comment\n * (`api/export-loopback.h:111-115`) says that case is a\n * `LoopbackDurableObjectClass`. `LoopbackColoLocalActorNamespace` is \"for\n * colo-local (ephemeral) actor namespaces\" (`:191`) and is built from a\n * *configured* binding, `Global::LoopbackEphemeralActorNamespace`\n * (`server/workerd-api.c++:666-670`) — reachable through configuration rather\n * than through a bare export. The conclusion stands; the path to it is that one.\n *\n * Two things are absent because there is nothing to resolve them against:\n *\n * - **The numbered-channel arm of every binding.** Each of upstream's\n * `kj::OneOf<uint, IoOwn<...>>` keeps only its object arm. Upstream resolves a\n * binding to a `uint` at configuration time; here a binding is a property of\n * the `env` object the consumer supplies, and there is no channel table for a\n * number to index. The object arm is upstream's own alternative, offered on\n * `DurableObjectNamespace` for the case where one \"is constructed dynamically\n * within an execution context, rather than being a long-lived binding\" — which\n * is every binding here.\n * - **Compatibility flags.** `getEnableVersionApi`, `getReplicaRouting`,\n * `getDurableObjectGetExisting` and `getDurableObjectFetchRequiresSchemeAuthority`\n * are read four times in `actor.c++`. A runtime with no deployed history takes\n * the current behaviour, which is the same judgment `deleteAll()`'s\n * `deleteAllDeletesAlarm` row already records. The one that is not a flag\n * decision is `enableReplicaRouting`, which is `false` because replication is a\n * named substrate boundary in `io/actor-cache.ts`.\n *\n * `serialize`/`deserialize` on `DurableObjectClass` are a boundary of their own:\n * they are built on `jsg::Serializer`, `Frankenvalue`, capnp `rpc::JsValue::External`\n * and channel tokens, none of which has a port. Both throw one named message.\n *\n * Spec: §1.10, §1.11 in docs/decisions.md.\n */\n\nimport type { ActorGetMode, ActorId, ActorIdFactory, ActorRoutingMode, ActorVersion } from \"../io/actor-id\";\nimport type { ActorClassChannel } from \"../io/io-channels\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← the `[1, 2048]` bound in `ColoLocalActorNamespace::get`.\n *\n * Upstream compares `actorId.size()`, which for a `kj::String` is **bytes**, so\n * this is measured in UTF-8 bytes rather than in UTF-16 code units. That costs\n * one `TextEncoder` pass and buys an exact match on a bound a caller can hit.\n */\nexport const MAX_COLO_LOCAL_ACTOR_ID_BYTES = 2048;\n\n/**\n * Upstream never faces this: JSG unwraps a `jsg::Ref<DurableObjectId>` parameter\n * and throws a `TypeError` before the method body runs, so `getInner()` cannot be\n * reached on something that is not one. Here the parameter type is\n * workers-types' structural `DurableObjectId` interface, which any object with a\n * `toString` and an `equals` satisfies — so the unwrap has to be written, and it\n * fails closed rather than guessing at the string form.\n */\nexport const FOREIGN_ACTOR_ID_MESSAGE =\n \"This DurableObjectId was not created by this runtime, so its underlying actor id cannot be \" +\n \"read. Ids must come from newUniqueId(), idFromName() or idFromString() on a \" +\n \"DurableObjectNamespace.\";\n\n/** Substrate boundary: `jsg::Serializer`, `Frankenvalue` and channel tokens have no port. */\nexport const ACTOR_CLASS_SERIALIZATION_UNIMPLEMENTED_MESSAGE =\n \"DurableObjectClass cannot be serialized in this runtime: upstream writes a channel token \" +\n \"through jsg::Serializer and Frankenvalue, and neither the token nor the serializer has an \" +\n \"equivalent here.\";\n\n/**\n * Replication is a named substrate boundary (`io/actor-cache.ts`), so no request\n * this file builds asks for replica routing. Upstream reads\n * `FeatureFlags::get(js).getReplicaRouting()` here.\n */\nconst ENABLE_REPLICA_ROUTING = false;\n\n// =======================================================================================\n// The outgoing seam — the shape the three factories plug into\n\n/**\n * ← what `GlobalActorOutgoingFactory`'s constructor captures (`actor.h:297-303`),\n * one field per constructor parameter minus the channel number.\n */\nexport type GlobalActorRequest = {\n readonly id: ActorId;\n readonly locationHint: string | undefined;\n readonly mode: ActorGetMode;\n readonly enableReplicaRouting: boolean;\n readonly routingMode: ActorRoutingMode;\n readonly version: ActorVersion | undefined;\n};\n\n/**\n * ← `DurableObjectNamespace::ActorChannelFactory` (`actor.h:147-157`) composed\n * with `IoChannelFactory::getGlobalActor`, which is what its one implementation\n * forwards to.\n *\n * The composition is not a shortcut. Upstream's `getGlobalActor` returns an\n * `ActorChannel`, and the only thing done with one is `startRequest(...)` →\n * `WorkerInterface`, which the `Fetcher` then drives. `WorkerInterface` has no\n * port and `Fetcher` construction is `api/http.{h,c++}`'s, which is not ported,\n * so the channel and the stub it produces are one object here — the same collapse\n * `io/worker.ts`'s `FacetManager.getFacet` and `server/actor-container.ts`'s\n * `FacetHandle.stub` already make.\n *\n * Section 7 implements this. The laziness upstream's factory has — \"Lazily\n * initialize actorChannel\" — belongs to the implementation, not to the interface,\n * because upstream's own laziness is per-`newSingleUseClient` and there is no\n * per-request client here to be lazy about.\n */\nexport interface ActorChannelFactory {\n getGlobalActor(request: GlobalActorRequest): Fetcher;\n}\n\n/** ← what `LocalActorOutgoingFactory`'s constructor captures (`actor.h:333-335`). */\nexport type ColoLocalActorRequest = {\n readonly actorId: string;\n};\n\n/**\n * ← `IoChannelFactory::getColoLocalActor`, reached through\n * `LocalActorOutgoingFactory`.\n *\n * Upstream gives `ColoLocalActorNamespace` only the numbered-channel arm, because\n * an ephemeral namespace is always a configured binding there. With no channel\n * table the factory arm is the only one available, so this is the same\n * substitution upstream itself offers `DurableObjectNamespace` — applied to the\n * one constructor that did not already have it.\n */\nexport interface ColoLocalActorChannelFactory {\n getColoLocalActor(request: ColoLocalActorRequest): Fetcher;\n}\n\n// =======================================================================================\n// ColoLocalActorNamespace\n\n/**\n * ← `ColoLocalActorNamespace` (`actor.h:25-37`). \"A capability to an ephemeral\n * Actor namespace.\"\n */\nexport class ColoLocalActorNamespace implements globalThis.ColoLocalActorNamespace {\n readonly #channel: ColoLocalActorChannelFactory;\n\n constructor(channel: ColoLocalActorChannelFactory) {\n this.#channel = channel;\n }\n\n /** ← `ColoLocalActorNamespace::get` (`actor.c++:116-129`). */\n get(actorId: string): Fetcher {\n const bytes = utf8Length(actorId);\n if (!(bytes > 0 && bytes <= MAX_COLO_LOCAL_ACTOR_ID_BYTES)) {\n throw new TypeError(\n `Actor ID length must be in the range [1, ${MAX_COLO_LOCAL_ACTOR_ID_BYTES}].`,\n );\n }\n return this.#channel.getColoLocalActor({ actorId });\n }\n}\n\nconst textEncoder = new TextEncoder();\n\n/** `kj::String::size()` is bytes; `String.prototype.length` is UTF-16 code units. */\nfunction utf8Length(value: string): number {\n return textEncoder.encode(value).length;\n}\n\n// =======================================================================================\n// DurableObjectId\n\n/**\n * ← `DurableObjectId` (`actor.h:42-84`). \"DurableObjectId type seen by\n * JavaScript.\"\n *\n * `name` and `jurisdiction` are read from the inner id **once, at construction**,\n * where upstream's are `JSG_READONLY_INSTANCE_PROPERTY`s that re-read it on every\n * access. That is not a preference: `@cloudflare/workers-types` declares both\n * `readonly name?: string`, and under `exactOptionalPropertyTypes` a getter\n * returning `string | undefined` does not satisfy an optional `string`. An own\n * property assigned only when the value exists does, and it is what keeps this\n * class assignable to the interface with no cast (§2.4). The one behaviour lost\n * is `ActorIdImpl::clearName()` (`server/actor-id-impl.h`) taking effect on an\n * already-wrapped id — a `server/`-internal that runs before the id reaches JS.\n */\nexport class DurableObjectId implements globalThis.DurableObjectId {\n readonly #id: ActorId;\n readonly name?: string;\n readonly jurisdiction?: string;\n\n constructor(id: ActorId) {\n this.#id = id;\n const name = id.getName();\n if (name !== undefined) this.name = name;\n const jurisdiction = id.getJurisdiction();\n if (jurisdiction !== undefined) this.jurisdiction = jurisdiction;\n }\n\n /** ← `getInner()`. Not JS-visible upstream either; the outgoing factories take it. */\n getInner(): ActorId {\n return this.#id;\n }\n\n /** \"Converts to a string which can be passed back to the constructor to reproduce the same ID.\" */\n toString(): string {\n return this.#id.toString();\n }\n\n equals(other: globalThis.DurableObjectId): boolean {\n return this.#id.equals(innerIdOf(other));\n }\n}\n\n/** The unwrap JSG performs for a `jsg::Ref<DurableObjectId>` parameter. */\nfunction requireDurableObjectId(id: globalThis.DurableObjectId): DurableObjectId {\n if (id instanceof DurableObjectId) return id;\n throw new TypeError(FOREIGN_ACTOR_ID_MESSAGE);\n}\n\nfunction innerIdOf(id: globalThis.DurableObjectId): ActorId {\n return requireDurableObjectId(id).getInner();\n}\n\n// =======================================================================================\n// The DurableObject stub\n\n/**\n * ← `DurableObject` (`actor.h:87-139`). \"Stub object used to send messages to a\n * remote durable object.\"\n *\n * Upstream's carries its whole behaviour by `JSG_INHERIT(Fetcher)` and adds\n * exactly two readonly properties. So does this: the `Fetcher` is the transport's\n * and everything except `id` and `name` belongs to it. `asDurableObjectStub`\n * below is where the inheritance goes.\n */\nexport class DurableObject {\n readonly #id: DurableObjectId;\n readonly #fetcher: Fetcher;\n\n constructor(id: DurableObjectId, fetcher: Fetcher) {\n this.#id = id;\n this.#fetcher = fetcher;\n }\n\n /** ← `JSG_READONLY_INSTANCE_PROPERTY(id, getId)`. */\n getId(): DurableObjectId {\n return this.#id;\n }\n\n /** ← `JSG_READONLY_INSTANCE_PROPERTY(name, getName)`. */\n getName(): string | undefined {\n return this.#id.name;\n }\n\n /** The `Fetcher` upstream inherits from rather than holds. */\n getFetcher(): Fetcher {\n return this.#fetcher;\n }\n}\n\n/**\n * ← `js.alloc<DurableObject>(...)` plus `JSG_INHERIT(Fetcher)` plus the\n * `JSG_TS_OVERRIDE` that renames the resource type to `DurableObjectStub`.\n *\n * The named assertion is the same one `io/worker.ts`'s `asFacetStub` makes and\n * for the same reason: `DurableObjectStub<T>` is `Fetcher<T, …> & { id, name }`,\n * and `Fetcher<T>` for an unresolved `T` is `Rpc.Provider<T, …>`, a conditional\n * type TypeScript defers until `T` is known — where `T` is the caller's claim\n * about a class it named, which no value can confirm. Upstream is in the same\n * position and answers it the same way, with the parameter living only inside a\n * `JSG_TS_OVERRIDE`.\n *\n * The `Proxy` is what JSG inheritance costs in JS. Two properties have to answer\n * from the id and every other property — `fetch`, `connect`, and every RPC method\n * name, which are the whole point of a stub — has to reach the transport with\n * `this` still bound to it. Bound methods are memoised so `stub.foo === stub.foo`,\n * which upstream gets for free by there being one object rather than two.\n */\nexport function asDurableObjectStub<T extends Rpc.DurableObjectBranded | undefined>(\n object: DurableObject,\n): DurableObjectStub<T> {\n const fetcher = object.getFetcher();\n const bound = new Map<string | symbol, unknown>();\n\n const stub = new Proxy(fetcher, {\n get(target, property): unknown {\n if (property === \"id\") return object.getId();\n if (property === \"name\") return object.getName();\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const value: unknown = Reflect.get(target, property, target);\n if (typeof value !== \"function\") return value;\n const method: unknown = value.bind(target);\n bound.set(property, method);\n return method;\n },\n\n has(target, property): boolean {\n if (property === \"id\" || property === \"name\") return true;\n return Reflect.has(target, property);\n },\n\n ownKeys(target): ArrayLike<string | symbol> {\n const keys = Reflect.ownKeys(target).filter((key) => key !== \"id\" && key !== \"name\");\n return [\"id\", \"name\", ...keys];\n },\n\n getOwnPropertyDescriptor(target, property): PropertyDescriptor | undefined {\n if (property === \"id\" || property === \"name\") {\n return {\n value: property === \"id\" ? object.getId() : object.getName(),\n writable: false,\n enumerable: true,\n // Configurable, because the target does not have these keys and a Proxy may not\n // report a non-configurable descriptor for a property its target lacks.\n configurable: true,\n };\n }\n return Reflect.getOwnPropertyDescriptor(target, property);\n },\n });\n\n return stub as DurableObjectStub<T>;\n}\n\n// =======================================================================================\n// DurableObjectNamespace\n\n/** ← `DurableObjectNamespace::NewUniqueIdOptions` (`actor.h:166-177`). */\nexport type NewUniqueIdOptions = {\n /** \"Restricts the new unique ID to a set of colos within a jurisdiction.\" */\n readonly jurisdiction?: string | null;\n};\n\n/** ← `DurableObjectNamespace::GetDurableObjectOptions` (`actor.h:193-234`). */\nexport type GetDurableObjectOptions = {\n readonly locationHint?: string;\n /**\n * \"`routingMode` may be be of interest to applications using Durable Objects\n * replicas. It can be one of the following options: none: the default,\n * indicates we will pick for the application. 'primary-only': guarantees we\n * route directly to the primary (skip any replicas).\"\n */\n readonly routingMode?: string;\n readonly version?: { readonly cohort?: string };\n};\n\n/**\n * ← `DurableObjectNamespace` (`actor.h:142-291`). \"Global durable object class\n * binding type.\"\n */\nexport class DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined>\n implements globalThis.DurableObjectNamespace<T>\n{\n readonly #channel: ActorChannelFactory;\n readonly #idFactory: ActorIdFactory;\n\n constructor(channel: ActorChannelFactory, idFactory: ActorIdFactory) {\n this.#channel = channel;\n this.#idFactory = idFactory;\n }\n\n /**\n * \"Create a new unique ID for a durable object that will be allocated nearby\n * the calling colo.\"\n */\n newUniqueId(options?: NewUniqueIdOptions): DurableObjectId {\n return new DurableObjectId(this.#idFactory.newUniqueId(options?.jurisdiction ?? undefined));\n }\n\n /**\n * \"Create a name-derived ID. Passing in the same `name` (to the same class)\n * will always produce the same ID.\"\n */\n idFromName(name: string): DurableObjectId {\n return new DurableObjectId(this.#idFactory.idFromName(name));\n }\n\n /**\n * \"Create a DurableObjectId from the stringified form of the ID (as produced by\n * calling `toString()` on a durable object ID). Throws if the ID is not a\n * 64-digit hex number, or if the ID was not originally created for this class.\"\n */\n idFromString(id: string): DurableObjectId {\n return new DurableObjectId(this.#idFactory.idFromString(id));\n }\n\n /** \"Gets a durable object by ID or creates it if it doesn't already exist.\" */\n get(id: globalThis.DurableObjectId, options?: GetDurableObjectOptions): DurableObjectStub<T> {\n return this.#getImpl(\"GET_OR_CREATE\", id, options);\n }\n\n /**\n * \"Gets a durable object by name or creates it if it doesn't already exist.\n * Short for `idFromName()` followed by `get()`.\"\n */\n getByName(name: string, options?: GetDurableObjectOptions): DurableObjectStub<T> {\n return this.#getImpl(\"GET_OR_CREATE\", this.idFromName(name), options);\n }\n\n /**\n * \"Experimental. Gets a durable object by ID if it already exists. Currently,\n * gated for use by cloudflare only.\"\n *\n * Upstream exposes it only when the `durableObjectGetExisting` compat flag is\n * on, and `@cloudflare/workers-types` 4.20260702.1 does not declare it. It is\n * exposed unconditionally here, which is the current-behaviour reading every\n * other compat flag in this file gets.\n */\n getExisting(\n id: globalThis.DurableObjectId,\n options?: GetDurableObjectOptions,\n ): DurableObjectStub<T> {\n return this.#getImpl(\"GET_EXISTING\", id, options);\n }\n\n /**\n * \"Creates a subnamespace with the jurisdiction hardcoded.\"\n *\n * The argument is optional because upstream's is a\n * `jsg::Optional<kj::Maybe<kj::String>>`, so both \"omitted\" and \"null\" mean the\n * same thing — `cloneWithJurisdiction(kj::none)`, a subnamespace with none.\n */\n jurisdiction(jurisdiction?: string | null): DurableObjectNamespace<T> {\n return new DurableObjectNamespace<T>(\n this.#channel,\n this.#idFactory.cloneWithJurisdiction(jurisdiction ?? undefined),\n );\n }\n\n /** ← `DurableObjectNamespace::getImpl` (`actor.c++:167-213`). */\n #getImpl(\n mode: ActorGetMode,\n id: globalThis.DurableObjectId,\n options: GetDurableObjectOptions | undefined,\n ): DurableObjectStub<T> {\n const durableObjectId = requireDurableObjectId(id);\n const inner = durableObjectId.getInner();\n if (!this.#idFactory.matchesJurisdiction(inner)) {\n throw new TypeError(\n \"get called on jurisdictional subnamespace with an ID from a different jurisdiction\",\n );\n }\n\n let routingMode: ActorRoutingMode = \"DEFAULT\";\n const requestedRoutingMode = options?.routingMode;\n if (requestedRoutingMode !== undefined) {\n if (requestedRoutingMode !== \"primary-only\") {\n throw new RangeError(`unknown routingMode: ${requestedRoutingMode}`);\n }\n routingMode = \"PRIMARY_ONLY\";\n }\n\n const fetcher = this.#channel.getGlobalActor({\n id: inner,\n locationHint: options?.locationHint,\n mode,\n enableReplicaRouting: ENABLE_REPLICA_ROUTING,\n routingMode,\n version: actorVersionOf(options?.version),\n });\n\n // The id handed to the stub is the one the caller passed, as upstream's `id.addRef()` is.\n return asDurableObjectStub<T>(new DurableObject(durableObjectId, fetcher));\n }\n}\n\n/**\n * ← `version = ActorVersion{.cohort = kj::mv(v.cohort)}` (`actor.c++:186-190`),\n * behind `FeatureFlags::get(js).getEnableVersionApi()` which this file reads as\n * on. A version with no cohort is still a version, which is why the empty object\n * is not collapsed to `undefined`.\n */\nfunction actorVersionOf(version: { readonly cohort?: string } | undefined): ActorVersion | undefined {\n if (version === undefined) return undefined;\n return version.cohort === undefined ? {} : { cohort: version.cohort };\n}\n\n// =======================================================================================\n// DurableObjectClass\n\n/**\n * ← `DurableObjectClass` (`actor.h:367-393`). \"DurableObjectClass represents a\n * binding to a Durable Object class that can be used as a facet. The only use of\n * this type is to pass to `ctx.facets.get()`.\"\n *\n * `getChannel()` takes no `IoContext` because the parameter existed to resolve the\n * numbered-channel arm, and there is no numbered-channel arm here.\n */\nexport class DurableObjectClass<_T extends Rpc.DurableObjectBranded | undefined = undefined>\n implements globalThis.DurableObjectClass<_T>\n{\n readonly #channel: ActorClassChannel;\n\n constructor(channel: ActorClassChannel) {\n this.#channel = channel;\n }\n\n /** ← `DurableObjectClass::getChannel` (`actor.c++:232-242`). */\n getChannel(): ActorClassChannel {\n return this.#channel;\n }\n\n /**\n * ← `DurableObjectClass::serialize` (`actor.c++:244-306`). Substrate boundary.\n *\n * `requireAllowsTransfer()` runs first, exactly as upstream's does, so a class\n * that refuses transfer reports that rather than the boundary — the refusal is\n * the more specific answer and it is the one upstream would give too.\n */\n serialize(): never {\n this.#channel.requireAllowsTransfer();\n throw new Error(ACTOR_CLASS_SERIALIZATION_UNIMPLEMENTED_MESSAGE);\n }\n\n /** ← `DurableObjectClass::deserialize` (`actor.c++:308-359`). Substrate boundary. */\n static deserialize(): never {\n throw new Error(ACTOR_CLASS_SERIALIZATION_UNIMPLEMENTED_MESSAGE);\n }\n}\n","/**\n * ← workerd `src/workerd/api/export-loopback.{h,c++}`\n *\n * The four types `ctx.exports` is made of. Upstream's own comment on the first\n * says what they all are: \"the type of a property of `ctx.exports` which points\n * back at a … entrypoint of this Worker\", specialized by *invoking* it.\n *\n * - `LoopbackServiceStub` (`export-loopback.h:18`) — a stateless entrypoint. A\n * `Fetcher` with empty props, callable to get one with props.\n * - `LoopbackDurableObjectClass` (`:116`) — an actor class with **no storage\n * configured**. A `DurableObjectClass`, callable to get a specialized one.\n * - `LoopbackDurableObjectNamespace` (`:155`) — an actor class **with** storage:\n * \"we want a binding that behaves *both* like a LoopbackDurableObjectClass\n * *and* like a DurableObjectNamespace binding.\"\n * - `LoopbackColoLocalActorNamespace` (`:192`) — the same, for a colo-local\n * (ephemeral) namespace binding.\n *\n * The third is why this file blocks `server/`. The vendored consumer reads\n * `ctx.exports[className]` and needs one value to answer both `idFromName`\n * (`vendor/agents/packages/agents/src/index.ts:10829`, `:10855`) and\n * `ctx.facets.get`'s class check (`:10857`) — namespace-shaped and class-shaped\n * at once, which is exactly what `LoopbackDurableObjectNamespace` is for.\n * Upstream's own `api/tests/worker-loader-test.js:449-450` pins the same pair.\n *\n * **`JSG_CALLABLE` becomes a `Proxy` with an `apply` trap.** A JS value can only\n * be invoked if it is a function, and a class instance is not one; the private\n * fields these classes inherit mean the callable cannot simply be a function\n * whose prototype is the instance, because an inherited method would then run\n * with `this` set to the function. So each class keeps its behaviour and an\n * `asLoopback…` function produces the JS-visible value — the same split, for the\n * same reason, that `asDurableObjectStub` already makes for `JSG_INHERIT`.\n * `getPrototypeOf` is what keeps `instanceof` answering, which is how\n * `DurableObjectFacets.get` discriminates the three arms of its class switch.\n *\n * **Two `IoChannelFactory` methods are declared here rather than in\n * `io/io-channels.ts`.** `getSubrequestChannel` and `getActorClass` are what\n * `export-loopback.c++` reaches for, and both take a channel *number* upstream —\n * which this package does not have (`io/io-channels.ts`'s header: there is no\n * numbered channel table). So each collapses into a factory taking an object\n * request, exactly as `api/actor.ts` already does for `IoChannelFactory`'s\n * `getGlobalActor` and `getColoLocalActor`, and each is declared beside its one\n * consumer for the same reason `ActorChannelFactory` is. Section 7 fills them.\n *\n * **Non-serializability survives, and Section 7b is where it is enforced.**\n * Upstream is explicit that `LoopbackServiceStub` is \"intentionally NOT\n * serializable, unlike its parent class Fetcher\", and\n * `api/tests/worker-loader-test.js:104` asserts the message;\n * `LoopbackDurableObjectClass` likewise declares no `JSG_SERIALIZABLE` where\n * `DurableObjectClass` (`actor.h:389`) does, and neither namespace type declares\n * one either — `JSG_INHERIT` does not carry serializability, which is what the\n * test's own comment says it is checking.\n *\n * An earlier revision of this paragraph said the refusal did not survive, and\n * named `src/transport/` as the layer that would have to make it. Both halves\n * were wrong about *where*: the test reaches the refusal through\n * `worker.getEntrypoint(name, {props})`, and `WorkerStub::getEntrypoint`'s first\n * act is `Frankenvalue::fromJs`, which runs `jsg::Serializer` inside\n * `api/worker-loader.c++`. So `api/worker-loader.ts`'s `requireSerializableProps`\n * refuses all four of these in `props` and in `env`, with upstream's message and\n * a `DataCloneError`. `DurableObjectClass.serialize` remains a separate named\n * substrate boundary that throws for every class, loopback or not.\n *\n * The version half of `LoopbackServiceStub` is present and `Options`, the\n * flag-off form, is not: `FeatureFlags::getEnableVersionApi()` is read as on\n * here, the same current-behaviour reading `api/actor.ts` gives the four\n * compatibility flags it meets. That makes this a superset of\n * `@cloudflare/workers-types` 4.20260702.1, which generated the flag-off\n * signature — the same relationship `DurableObjectNamespace.getExisting` has.\n *\n * Spec: §1.10, §1.11, decisions 14 and 16 in\n * docs/decisions.md.\n */\n\nimport type { ActorIdFactory } from \"../io/actor-id\";\nimport type { ActorClassChannel } from \"../io/io-channels\";\nimport {\n ColoLocalActorNamespace,\n DurableObjectClass,\n DurableObjectNamespace,\n type ActorChannelFactory,\n type ColoLocalActorChannelFactory,\n} from \"./actor\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← what JSG's struct unwrapper does with a value that is not an object\n * (`jsg/struct.h:246`). Undefined and null are **not** in that set: a struct\n * whose every field is optional — which both option structs here are — unwraps\n * from either as an empty struct (`jsg/struct.h:236-243`), so `ctx.exports.Foo()`\n * is upstream's own empty-options call and not an error.\n */\nexport const LOOPBACK_OPTIONS_NOT_AN_OBJECT_MESSAGE =\n \"A ctx.exports binding is invoked with an options object: pass { props }, or nothing at all.\";\n\n/** ← what JSG does unwrapping a `jsg::JsRef<jsg::JsObject>` from a non-object. */\nexport const LOOPBACK_PROPS_NOT_AN_OBJECT_MESSAGE =\n \"`props` must be an object. Upstream unwraps it as a jsg::JsObject, which refuses anything else.\";\n\n// =======================================================================================\n// The outgoing seam — the two IoChannelFactory methods this file reaches\n\n/** ← `IoChannelFactory::VersionRequest` (`io/io-channels.h:123-131`). */\nexport type VersionRequest = {\n /** \"Request a version within the given cohort.\" */\n readonly cohort: string | undefined;\n};\n\n/**\n * ← the two arguments `IoChannelFactory::getSubrequestChannel` takes besides the\n * channel number (`io/io-channels.h:243-245`). Upstream: \"`props` and\n * `versionRequest` can only be specified if this is a loopback channel (i.e.\n * from ctx.exports).\"\n */\nexport type SubrequestChannelRequest = {\n /** ← `kj::Maybe<Frankenvalue> props`. */\n readonly props: unknown;\n readonly version: VersionRequest | undefined;\n};\n\n/**\n * ← `IoChannelFactory::getSubrequestChannel` composed with the `Fetcher` upstream\n * builds over the `SubrequestChannel` it returns.\n *\n * The composition is `api/actor.ts`'s: a `SubrequestChannel` is only ever driven\n * through `startRequest()` → `WorkerInterface`, which has no port, while the\n * JS-visible product is a `Fetcher` — so the channel and the stub it produces are\n * one object here.\n */\nexport interface SubrequestChannelFactory {\n getSubrequestChannel(request: SubrequestChannelRequest): Fetcher;\n}\n\n/** ← the `props` argument of `IoChannelFactory::getActorClass` (`io/io-channels.h:315`). */\nexport type ActorClassRequest = {\n readonly props: unknown;\n};\n\n/** ← `IoChannelFactory::getActorClass`, which returns the token `io/io-channels.ts` ports. */\nexport interface ActorClassChannelFactory {\n getActorClass(request: ActorClassRequest): ActorClassChannel;\n}\n\n// =======================================================================================\n// The option structs\n\n/** ← `LoopbackServiceStub::OptionsWithVersion::Version` (`export-loopback.h:32-36`). */\nexport type LoopbackServiceStubVersion = {\n /** `jsg::Optional<kj::Maybe<kj::String>>`: omitted and null are the same request. */\n readonly cohort?: string | null;\n};\n\n/** ← `LoopbackServiceStub::OptionsWithVersion` (`export-loopback.h:31-42`). */\nexport type LoopbackServiceStubOptions = {\n readonly props?: unknown;\n readonly version?: LoopbackServiceStubVersion;\n};\n\n/** ← `LoopbackDurableObjectClass::Options` (`export-loopback.h:120-124`). */\nexport type LoopbackDurableObjectClassOptions = {\n readonly props?: unknown;\n};\n\n// =======================================================================================\n// LoopbackServiceStub\n\n/**\n * ← `LoopbackServiceStub` (`export-loopback.h:18-109`).\n *\n * Upstream is a `Fetcher` on the loopback channel and holds the channel number a\n * second time so `callImpl` can re-specialize it. Here the `Fetcher` is the\n * transport's — `api/http.{h,c++}` is not ported — so the unspecialized stub is\n * what the factory returns for a request with no props and no version, and the\n * factory is the thing held twice over.\n */\nexport class LoopbackServiceStub {\n readonly #channel: SubrequestChannelFactory;\n readonly #fetcher: Fetcher;\n\n constructor(channel: SubrequestChannelFactory) {\n this.#channel = channel;\n this.#fetcher = channel.getSubrequestChannel({ props: undefined, version: undefined });\n }\n\n /** The `Fetcher` upstream inherits from rather than holds, as `DurableObject`'s is. */\n getFetcher(): Fetcher {\n return this.#fetcher;\n }\n\n /**\n * ← `LoopbackServiceStub::callImpl` (`export-loopback.c++:11-29`) reached\n * through `callWithVersion` (`export-loopback.h:53-55`), which is the callable\n * when `enableVersionApi` is on. \"Create a specialized Fetcher which can be\n * passed over RPC.\"\n */\n callWithVersion(options: LoopbackServiceStubOptions): Fetcher {\n return this.#channel.getSubrequestChannel({\n props: requireProps(options.props),\n version: versionRequestOf(options.version),\n });\n }\n}\n\n/**\n * ← `js.alloc<LoopbackServiceStub>(…)` plus `JSG_CALLABLE(callWithVersion)`.\n *\n * The declared type is a superset of `@cloudflare/workers-types`' by exactly the\n * `version` field, for the reason in this module's header.\n */\nexport type LoopbackServiceStubValue<\n T extends Rpc.WorkerEntrypointBranded | undefined = undefined,\n> = Fetcher<T> & ((options?: LoopbackServiceStubOptions) => Fetcher<T>);\n\nexport function asLoopbackServiceStub<\n T extends Rpc.WorkerEntrypointBranded | undefined = undefined,\n>(stub: LoopbackServiceStub): LoopbackServiceStubValue<T> {\n return asCallable({\n properties: stub.getFetcher(),\n prototype: LoopbackServiceStub.prototype,\n call: (options) => stub.callWithVersion(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// LoopbackDurableObjectClass\n\n/**\n * ← `LoopbackDurableObjectClass` (`export-loopback.h:116-148`). \"Similar to\n * LoopbackServiceStub, but for actor classes … this is used for actor classes\n * that do *not* have any storage configured. If you simply export a class\n * extending `DurableObject` but you don't configure storage for it, it shows up\n * in `ctx.exports` as this type. This can be used to create a Durable Object\n * facet.\"\n *\n * Upstream's base `DurableObjectClass` holds the channel *number*, and\n * `getChannel(ioctx)` resolves it lazily. There is no numbered arm here, so the\n * unspecialized channel is requested once, in the constructor — which is the same\n * value `getActorClass(channel)` with default props would have produced.\n */\nexport class LoopbackDurableObjectClass<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> extends DurableObjectClass<T> {\n readonly #channel: ActorClassChannelFactory;\n\n constructor(channel: ActorClassChannelFactory) {\n super(channel.getActorClass({ props: undefined }));\n this.#channel = channel;\n }\n\n /**\n * ← `LoopbackDurableObjectClass::call` (`export-loopback.c++:31-40`). \"Create a\n * specialized DurableObjectClass which can be passed over RPC.\"\n *\n * The result is a plain `DurableObjectClass`, as `js.alloc<DurableObjectClass>`\n * is: specializing a loopback class does not produce another loopback class.\n */\n call(options: LoopbackDurableObjectClassOptions): DurableObjectClass<T> {\n return new DurableObjectClass<T>(\n this.#channel.getActorClass({ props: requireProps(options.props) }),\n );\n }\n}\n\n/** ← `js.alloc<LoopbackDurableObjectClass>(…)` plus `JSG_CALLABLE(call)`. */\nexport type LoopbackDurableObjectClassValue<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> = DurableObjectClass<T> &\n ((options?: LoopbackDurableObjectClassOptions) => DurableObjectClass<T>);\n\nexport function asLoopbackDurableObjectClass<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n>(actorClass: LoopbackDurableObjectClass<T>): LoopbackDurableObjectClassValue<T> {\n return asCallable({\n properties: actorClass,\n prototype: Object.getPrototypeOf(actorClass),\n call: (options) => actorClass.call(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// LoopbackDurableObjectNamespace\n\n/**\n * ← `LoopbackDurableObjectNamespace` (`export-loopback.h:155-189`).\n *\n * Upstream: \"used when the class has storage configured. In this case, we want a\n * binding that behaves *both* like a LoopbackDurableObjectClass *and* like a\n * DurableObjectNamespace binding. Easy enough, we'll inherit\n * DurableObjectNamespace, but also make the binding invokable as a function like\n * LoopbackDurableObjectClass.\"\n */\nexport class LoopbackDurableObjectNamespace<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> extends DurableObjectNamespace<T> {\n readonly #loopbackClass: LoopbackDurableObjectClass<T>;\n\n constructor(\n channel: ActorChannelFactory,\n idFactory: ActorIdFactory,\n loopbackClass: LoopbackDurableObjectClass<T>,\n ) {\n super(channel, idFactory);\n this.#loopbackClass = loopbackClass;\n }\n\n /** ← `getClass()`. \"getClass() accessor for use from C++ only.\" */\n getClass(): LoopbackDurableObjectClass<T> {\n return this.#loopbackClass;\n }\n\n /** ← `call`. \"Invoking the binding creates a specialization of the class -- not the namespace.\" */\n call(options: LoopbackDurableObjectClassOptions): DurableObjectClass<T> {\n return this.#loopbackClass.call(options);\n }\n}\n\n/**\n * ← `js.alloc<LoopbackDurableObjectNamespace>(…)` plus `JSG_CALLABLE(call)`.\n *\n * This is the type of a `ctx.exports` entry for a Durable Object class with\n * storage, and the reason it is stated in terms of this package's classes rather\n * than `@cloudflare/workers-types`' `LoopbackDurableObjectNamespace` is that the\n * pinned interface is `interface LoopbackDurableObjectNamespace extends\n * DurableObjectNamespace {}` — no call signature, because that resource type\n * carries no `JSG_TS_OVERRIDE` to generate one from. `Cloudflare.Exports`\n * describes the same value correctly, as `LoopbackDurableObjectClass<T> &\n * DurableObjectNamespace<T>`, and `PinnedLoopbackTypes` below checks against\n * that rather than against the interface.\n *\n * `call` is omitted because `JSG_CALLABLE` registers it as the object's call\n * behaviour rather than as a property: on the value, `.call` is\n * `Function.prototype.call`, which is what `asCallable`'s `get` trap answers.\n */\nexport type LoopbackDurableObjectNamespaceValue<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n> = Omit<LoopbackDurableObjectNamespace<T>, \"call\"> &\n ((options?: LoopbackDurableObjectClassOptions) => DurableObjectClass<T>);\n\nexport function asLoopbackDurableObjectNamespace<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n>(namespace: LoopbackDurableObjectNamespace<T>): LoopbackDurableObjectNamespaceValue<T> {\n return asCallable({\n properties: namespace,\n prototype: Object.getPrototypeOf(namespace),\n call: (options) => namespace.call(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// LoopbackColoLocalActorNamespace\n\n/**\n * ← `LoopbackColoLocalActorNamespace` (`export-loopback.h:192-220`). \"Like\n * LoopbackDurableObjectNamespace, but for colo-local (ephemeral) actor\n * namespaces.\"\n */\nexport class LoopbackColoLocalActorNamespace extends ColoLocalActorNamespace {\n readonly #loopbackClass: LoopbackDurableObjectClass;\n\n constructor(channel: ColoLocalActorChannelFactory, loopbackClass: LoopbackDurableObjectClass) {\n super(channel);\n this.#loopbackClass = loopbackClass;\n }\n\n /** ← `getClass()`. \"getClass() accessor for use from C++ only.\" */\n getClass(): LoopbackDurableObjectClass {\n return this.#loopbackClass;\n }\n\n /** ← `call`. \"Invoking the binding creates a specialization of the class -- not the namespace.\" */\n call(options: LoopbackDurableObjectClassOptions): DurableObjectClass {\n return this.#loopbackClass.call(options);\n }\n}\n\n/**\n * ← `js.alloc<LoopbackColoLocalActorNamespace>(…)` plus `JSG_CALLABLE(call)`,\n * with `call` omitted for the reason given on the durable namespace above.\n */\nexport type LoopbackColoLocalActorNamespaceValue = Omit<LoopbackColoLocalActorNamespace, \"call\"> &\n ((options?: LoopbackDurableObjectClassOptions) => DurableObjectClass);\n\nexport function asLoopbackColoLocalActorNamespace(\n namespace: LoopbackColoLocalActorNamespace,\n): LoopbackColoLocalActorNamespaceValue {\n return asCallable({\n properties: namespace,\n prototype: Object.getPrototypeOf(namespace),\n call: (options) => namespace.call(requireOptions(options)),\n });\n}\n\n// =======================================================================================\n// The pinned-types check\n\n/** `Value` must be assignable to `Declared`; declaring the constraint is the check. */\ntype Assignable<Value extends Declared, Declared> = Value;\n\n/**\n * Checked rather than claimed: every value this module produces satisfies the\n * shape `@cloudflare/workers-types` 4.20260702.1 declares for it. The last two\n * are checked against `Cloudflare.Exports`' own description of a `ctx.exports`\n * entry — `LoopbackForExport<T>` intersected with the namespace — because the\n * two named interfaces there are call-signature-less, per the note above.\n */\nexport type PinnedLoopbackTypes = [\n Assignable<LoopbackServiceStubValue, globalThis.LoopbackServiceStub>,\n Assignable<LoopbackDurableObjectClassValue, globalThis.LoopbackDurableObjectClass>,\n Assignable<\n LoopbackDurableObjectNamespaceValue,\n globalThis.LoopbackDurableObjectClass & globalThis.DurableObjectNamespace\n >,\n Assignable<\n LoopbackColoLocalActorNamespaceValue,\n globalThis.LoopbackDurableObjectClass & globalThis.ColoLocalActorNamespace\n >,\n];\n\n// =======================================================================================\n// The mechanics JSG supplies\n\n/**\n * ← `JSG_CALLABLE`, which makes a JSG resource object invocable while leaving\n * every other property answering from the resource type.\n *\n * `properties` is where reads land, with `this` bound to it so a method reaching\n * a private field still finds one — the same binding, memoised the same way,\n * that `asDurableObjectStub` performs for `JSG_INHERIT`. `prototype` is what\n * `instanceof` sees, and it is separate from `properties` because\n * `LoopbackServiceStub` is one object with two halves: upstream's identity is the\n * resource type while its behaviour is the inherited `Fetcher`'s.\n *\n * The target is an arrow function rather than a plain one because a plain\n * function has a non-configurable own `prototype` property, which a Proxy may not\n * hide from `ownKeys`.\n *\n * This is the one assertion the four producers above need, made once here. It is\n * `asDurableObjectStub`'s, for `asDurableObjectStub`'s reason: the declared value\n * is a `Fetcher<T>` or a `DurableObjectClass<T>` intersected with a call\n * signature, and `T` is the caller's claim about a class it named, which no value\n * can confirm. Upstream states the same shapes the same way, in a\n * `JSG_TS_OVERRIDE` that no C++ value is checked against either.\n */\nconst INVOCATION_METHODS = new Set<string | symbol>([\"call\", \"apply\", \"bind\"]);\n\nfunction asCallable<Value>(facade: {\n readonly properties: object;\n readonly prototype: object | null;\n readonly call: (options: unknown) => unknown;\n}): Value {\n const bound = new Map<string | symbol, unknown>();\n const target = (): never => {\n throw new Error(\"unreachable: the apply trap answers every invocation\");\n };\n\n return new Proxy(target, {\n apply(_target, _thisArg, args: readonly unknown[]): unknown {\n return facade.call(args[0]);\n },\n\n get(target, property, receiver): unknown {\n // `call`, `apply` and `bind` belong to the callable rather than to the property source.\n // Upstream's object is a function and answers all three from `Function.prototype`, and\n // `call` is also the C++ method name `JSG_CALLABLE` registers — which is the object's call\n // behaviour there and not a JS property, so it must not become one here. Answering from\n // the target keeps `foo.call(thisArg, options)` meaning `foo(options)`, as it does upstream.\n if (INVOCATION_METHODS.has(property)) return Reflect.get(target, property, receiver);\n\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const value: unknown = Reflect.get(facade.properties, property, facade.properties);\n if (typeof value !== \"function\") return value;\n const method: unknown = value.bind(facade.properties);\n bound.set(property, method);\n return method;\n },\n\n has(_target, property): boolean {\n return Reflect.has(facade.properties, property);\n },\n\n ownKeys(): ArrayLike<string | symbol> {\n return Reflect.ownKeys(facade.properties);\n },\n\n getOwnPropertyDescriptor(_target, property): PropertyDescriptor | undefined {\n const descriptor = Reflect.getOwnPropertyDescriptor(facade.properties, property);\n if (descriptor === undefined) return undefined;\n // Configurable, because the target does not have this key and a Proxy may not report a\n // non-configurable descriptor for a property its target lacks.\n return { ...descriptor, configurable: true };\n },\n\n getPrototypeOf(): object | null {\n return facade.prototype;\n },\n }) as Value;\n}\n\n/**\n * ← JSG's struct unwrapper (`jsg/struct.h:236-246`), for the two option structs\n * here: every field of both is optional, so undefined and null yield an empty\n * struct and anything that is not an object is a `TypeError`. V8's `IsObject()`\n * is true for functions, which is why one is not refused here either.\n *\n * `cohort` is not checked, because upstream does not check it: JSG's `kj::String`\n * unwrapper calls `ToString` on whatever it is given (`jsg/value.h:501-506`), so\n * refusing a non-string here would refuse what workerd coerces. That is the same\n * reading `api/actor.ts`'s `actorVersionOf` already takes of the same field.\n */\nfunction requireOptions<Options extends object>(options: unknown): Options {\n if (\n options !== undefined &&\n options !== null &&\n typeof options !== \"object\" &&\n typeof options !== \"function\"\n ) {\n throw new TypeError(LOOPBACK_OPTIONS_NOT_AN_OBJECT_MESSAGE);\n }\n return (options ?? {}) as Options;\n}\n\n/** ← `jsg::Optional<jsg::JsRef<jsg::JsObject>> props` — present means an object. */\nfunction requireProps(props: unknown): unknown {\n if (props === undefined) return undefined;\n if (props === null || (typeof props !== \"object\" && typeof props !== \"function\")) {\n throw new TypeError(LOOPBACK_PROPS_NOT_AN_OBJECT_MESSAGE);\n }\n return props;\n}\n\n/** ← `.cohort = kj::mv(version.cohort).orDefault(kj::none)` (`export-loopback.c++:19-23`). */\nfunction versionRequestOf(\n version: LoopbackServiceStubVersion | undefined,\n): VersionRequest | undefined {\n if (version === undefined) return undefined;\n return { cohort: version.cohort ?? undefined };\n}\n","/**\n * ← workerd `src/workerd/api/worker-loader.{h,c++}`\n *\n * The Worker Loader binding: `get(name, getCode)` and `load(code)`, the\n * `WorkerStub` they return, and the two ways a dynamic Worker is reached —\n * `getEntrypoint()` for a `Fetcher` and `getDurableObjectClass()` for a\n * `DurableObjectClass`, which is the single bridge between dynamic Workers and\n * facets. Per §1.11 Code Mode is two features composed: a dynamic Worker for\n * execution and a facet for durable state, because \"Dynamically-loaded isolates\n * can't directly have storage\" (`server/server.c++:4209`).\n *\n * **The scaffolding this file replaces was a hypothesis, and the C++ wants a\n * different shape.** It declared `IsolateHost.execute({executionId, code,\n * namespaces}, onToolCall)` plus `cancel(executionId)`, with a\n * `SandboxNamespaceDescriptor` of `{provider, name}` and a `SandboxToolDispatch`\n * of `(provider, name, args, toolCallId)`. Not one of those words appears in\n * `worker-loader.{h,c++}` or in `io-channels.h`: providers, tool calls and\n * execution ids are the *consumer's* concepts, and this package may not know\n * about Rook, Think or agents. What upstream actually declares is\n * `IoChannelFactory::loadIsolate(channel, name, fetchSource) ->\n * WorkerStubChannel` (`io/io-channels.h:339-343`), with `getEntrypoint` and\n * `getActorClass` on the channel — a Worker-shaped seam, not an\n * execution-shaped one. The scaffolding had transcribed\n * `OffscreenCodemodeExecutor`, which is decision 15's *subject*, not its result.\n * `ActorPorts.isolates` went with it: a Worker Loader is a binding a host puts in\n * `env`, exactly as `DurableObjectNamespace` and `ctx.exports` already are, not a\n * port the container needs — upstream's own is `Global::WorkerLoader{channel}`\n * compiled into the bindings (`server/workerd-api.c++:748`).\n *\n * **`get()` does not cache; the namespace behind it does.** `WorkerLoader::get`\n * calls `loadIsolate` unconditionally and mints a fresh `WorkerStub` every call\n * (`worker-loader.c++:63-83`). The find-or-create by name lives one layer down, in\n * `Server::WorkerLoaderNamespace::loadIsolate` (`server.c++:4243-4281`), together\n * with the rule that a **null or absent name mints a fresh isolate every time** —\n * which upstream's own `isolateUniqueness` test pins at\n * `api/tests/worker-loader-test.js:527-541`. So what this layer owns is which name\n * reaches the seam: `load(code)` is documented as \"Shortcut for `get(null, () =>\n * code)`\" and both it and `get(null)` pass none.\n *\n * **What `load()` owns that `get()` does not is *when* the code is validated.**\n * `load()` builds the whole `DynamicWorkerSource` synchronously before it returns\n * (`worker-loader.c++:88`), so a malformed module list throws out of `load()`;\n * `get()` defers everything into the callback, so the same mistake surfaces at the\n * first request on the stub, which is what upstream's tests assert\n * (`worker-loader-test.js:812`, `:829`, `:856`). That eager capture is also a\n * memory-safety fix: `data` and `wasm` bytes are copied out of the caller's buffer\n * at that moment, because a resizable `ArrayBuffer` can be shrunk to zero\n * afterwards (`worker-loader.c++:225-232`, `:242-245`, and\n * `api/tests/worker-loader-rab-test.js`).\n *\n * **`globalOutbound: null` is the default posture, per decision 15, and what it\n * enforces here is one hop further out than on workerd.** Upstream substitutes a\n * `NullGlobalOutboundChannel` whose `startRequest` throws\n * (`server.c++:4306-4331`), so ambient `fetch` inside the loaded Worker fails from\n * inside the isolate. This layer's whole job is the same one upstream's is:\n * collapse the three JS states — omitted, `null`, a `Fetcher` — into the two the\n * source carries, where absent means blocked and omitted means the caller's own\n * outbound. Enforcement belongs to whatever `loadIsolate` returns, because that is\n * the thing with an isolate to deny.\n *\n * **The one thing this file refuses that upstream refuses elsewhere.**\n * `Frankenvalue::fromJs` serializes `props` and `env` inside these methods, and a\n * `ctx.exports` binding that has not been invoked declares no `JSG_SERIALIZABLE`,\n * so it is refused there with a `DataCloneError` — pinned at\n * `api/tests/worker-loader-test.js:104`. `api/export-loopback.ts`'s header records\n * that refusal as not surviving; it survives here, because this is the layer\n * upstream refuses at. See `requireSerializableProps` below.\n *\n * **There are no source or `env` size caps, and an earlier statement of this\n * section's spec said there were** — \"64 MiB of module source, 1 MiB of `env`\n * (`worker-loader.c++:15-21`)\". Those lines are `WorkerStub::getEntrypoint`'s\n * props-and-limits prologue, and no cap of either size exists anywhere in the\n * open-source runtime: the complete list of refusals in the load path is the ten\n * `JSG_REQUIRE`/`JSG_FAIL_REQUIRE` sites this file ports, and none of them\n * measures a length. Those are Cloudflare's documented *production* limits, which\n * workerd does not reproduce — the same class of thing as `ResourceLimits`, and\n * recorded on it. Nothing here counts bytes.\n *\n * Spec: §1.11, decisions 15 and 16 in\n * docs/decisions.md.\n */\n\nimport type {\n CompatibilityDateValidation,\n CompatibilityFlagsRequest,\n DynamicWorkerSource,\n EntrypointRequest,\n ResourceLimits,\n WorkerStubChannel,\n} from \"../io/io-channels\";\nimport type { IoContext } from \"../io/io-context\";\nimport { requireInputLock } from \"../io/io-context\";\nimport type { Module as SourceModule, ModuleContent, WorkerSource } from \"../io/worker-source\";\nimport { DurableObjectClass } from \"./actor\";\nimport {\n LoopbackColoLocalActorNamespace,\n LoopbackDurableObjectClass,\n LoopbackDurableObjectNamespace,\n LoopbackServiceStub,\n} from \"./export-loopback\";\n\n// =======================================================================================\n// Messages\n\n/** ← `JSG_REQUIRE(code.modules.fields.size() > 0, …)` (`worker-loader.c++:175-176`). */\nexport const NO_MODULES_MESSAGE = \"Dynamic Worker code must contain at least one module.\";\n\nconst MODULE_NAME_PREFIX =\n \"Module name must end with '.js' or '.py' (or the content must be an object \" +\n \"indicating the type explicitly). Got: \";\n\n/** ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:204-206`. */\nexport function moduleNameMessage(name: string): string {\n return `${MODULE_NAME_PREFIX}${name}`;\n}\n\n/**\n * ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:197-201`, the `.ts` / `.tsx` / `.jsx`\n * arm. Upstream's is the message above plus the bundler suggestion.\n */\nexport function typeScriptModuleNameMessage(name: string): string {\n return (\n `${MODULE_NAME_PREFIX}${name}. If you're trying to load TypeScript, bundle it first with ` +\n \"'@cloudflare/worker-bundler' and pass the generated JavaScript modules.\"\n );\n}\n\n/** ← `JSG_REQUIRE(fieldCount == 1, …)` (`worker-loader.c++:212-215`). */\nexport function moduleFieldCountMessage(name: string, fieldCount: number): string {\n return (\n \"Each module must contain exactly one of 'js', 'cjs', 'text', 'data', 'json', 'py', or \" +\n `'wasm'. Module '${name}' contained ${fieldCount} properties.`\n );\n}\n\n/** ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:261-262`. */\nexport function jsModuleInPythonWorkerMessage(name: string): string {\n return `Module \"${name}\" is a JS module, but the main module is a Python module.`;\n}\n\n/** ← `JSG_FAIL_REQUIRE` at `worker-loader.c++:266-267`. */\nexport function pythonModuleInJsWorkerMessage(name: string): string {\n return `Module \"${name}\" is a Python module, but the main module isn't a Python module.`;\n}\n\n/** ← `JSG_REQUIRE` at `worker-loader.c++:152-154`. Upstream's carries no closing period. */\nexport const STREAMING_TAILS_EXPERIMENTAL_MESSAGE =\n \"Streaming tail workers are experimental. You must pass the option \" +\n \"'allowExperimental: true' to the worker loader to use them\";\n\n/**\n * ← `JSG_REQUIRE_NONNULL(weakIoctx->tryGet(), Error, …)` (`worker-loader.c++:73-74`),\n * the guard the AUTOVULN-CLOUDFLARE-WORKERD-256 fix added.\n *\n * **The precondition differs and the failure mode nearly did too.** Upstream's\n * `IoContext` is per REQUEST, so a stub can outlive the context that made it and\n * the raw `&ioctx` capture was a use-after-free; the WeakRef turns that into this\n * message. Ours is per CONTAINER and outlives every stub it made, so the\n * destroyed case cannot happen — what remains reachable is an **aborted** actor,\n * and for that `IoContext::awaitIo` deliberately leaves its promise unsettled\n * (\"`result` is deliberately left unsettled, as upstream leaves it\",\n * `io/io-context.ts`). Upstream can afford that because `runAlarm`'s caller and\n * everything else in a torn-down request is being destroyed anyway; a dynamic\n * worker load cannot, because `WorkerStubChannel`'s contract is that a failed\n * load makes every request on the stub **fail** — a load that never settles makes\n * every request on the stub hang instead, which is the failure this repository's\n * own divergence 149 exists to prevent (\"a JS promise has to settle, and one that\n * never does is a hang nobody can see\"). So the abort is observed explicitly and\n * answered with upstream's own message.\n */\nexport const DEAD_LOAD_CONTEXT_MESSAGE =\n \"The request which initiated this dynamic worker load has already completed.\";\n\n/** ← `JSG_REQUIRE(!allowExperimental, …)` (`worker-loader.c++:282-284`). */\nexport const ALLOW_EXPERIMENTAL_MESSAGE =\n \"'allowExperimental' is only allowed when the calling worker has the 'experimental' \" +\n \"compat flag set.\";\n\n/**\n * ← `Serializer::throwDataCloneErrorForObject` (`jsg/ser.c++:175-183`), whose type\n * name is `obj->GetConstructorName()` — the JSG resource type's name, which is the\n * class name here. Pinned for `LoopbackServiceStub` at\n * `api/tests/worker-loader-test.js:104`.\n */\nexport function notSerializableMessage(typeName: string): string {\n return `Could not serialize object of type \"${typeName}\". This type does not support serialization.`;\n}\n\n/** Not something `jsg::asBytes()` would accept for a `kj::Array<const byte>` body. */\nexport const NOT_BYTES_MESSAGE =\n \"A module's 'data' or 'wasm' body must be an ArrayBuffer or a view over one.\";\n\n// =======================================================================================\n// The outgoing seam — the two IoChannelFactory methods this file reaches\n\n/**\n * ← the two arguments `IoChannelFactory::loadIsolate` takes besides the channel\n * number (`io/io-channels.h:339-343`). Upstream: \"Use a dynamic Worker loader\n * binding to obtain an Worker by name. If name is null, or if the named Worker\n * doesn't already exist, the callback will be called to fetch the source code from\n * which the Worker should be created.\"\n *\n * Upstream's own note on the callback, at `worker-loader.c++:90-94`, is the\n * contract an implementation has to honour: \"the callback we pass to\n * `loadIsolate()` technically may be called any number of times. Yes, even though\n * we aren't providing an ID. The runtime can actually evict the isolate while a\n * stub still exists, as long as there is no active request on the stub, and then\n * recreate the isolate on the next request.\"\n */\nexport type LoadIsolateRequest = {\n /**\n * ← `kj::Maybe<kj::String> name`. Absent means the isolate is not cached and a\n * fresh one is minted per call (`server.c++:4264-4281`).\n */\n readonly name: string | undefined;\n /** ← `kj::Function<kj::Promise<DynamicWorkerSource>()> fetchSource`. */\n fetchSource(): Promise<DynamicWorkerSource>;\n};\n\n/**\n * ← `IoChannelFactory`'s two dynamic-worker methods, collapsed the way\n * `api/actor.ts` and `api/export-loopback.ts` already collapse theirs: both take a\n * channel *number* upstream and there is no numbered channel table here, so each\n * becomes a factory method taking an object request. Declared beside its one\n * consumer for the same reason `ActorChannelFactory` is.\n *\n * This is the whole substrate seam of §1.11. A host implements it three ways — the\n * offscreen document in the browser, an in-realm module evaluation under Node, and\n * the real `worker_loaders` binding on workerd — and nothing above it has to know\n * which.\n */\nexport interface IsolateChannelFactory {\n /** ← `IoChannelFactory::loadIsolate`. Returns before the Worker has loaded. */\n loadIsolate(request: LoadIsolateRequest): WorkerStubChannel;\n\n /**\n * ← `getSubrequestChannel(IoContext::NULL_CLIENT_CHANNEL)`\n * (`worker-loader.c++:137-138`, `io/io-context.h:753`) — the calling worker's own\n * global outbound, which a loaded Worker inherits when `globalOutbound` is\n * omitted. Upstream reaches it by channel number 0; with no channel table it is a\n * method on the one factory that needs it.\n *\n * Upstream deliberately does not call `requireAllowsTransfer()` on this one: \"if\n * it was the global outbound of the parent, it must be OK to be the global\n * outbound of the child.\"\n */\n getNullClientChannel(): Fetcher;\n}\n\n// =======================================================================================\n// The JS-facing structs\n\n/**\n * ← `WorkerLoader::Module` (`worker-loader.h:62-78`). \"Exactly one must be filled\n * in.\"\n *\n * `data` and `wasm` are `ArrayBuffer | ArrayBufferView` where\n * `@cloudflare/workers-types` declares `ArrayBuffer`, because upstream unwraps\n * them with `jsg::asBytes()`, which accepts either — and upstream's own tests pass\n * a `Uint8Array` to both (`worker-loader-test.js:585`, `:645`). A superset of the\n * pinned types, the same relationship `DurableObjectNamespace.getExisting` has.\n *\n * `serializedJson` is absent: upstream's own comment calls it a HACK for owning\n * the string `Worker::Script::Source` only borrows, and a JS string is owned.\n */\nexport type Module = {\n /** ES module. */\n readonly js?: string;\n /** Common JS module. */\n readonly cjs?: string;\n /** \"text blob, imports as a string\" */\n readonly text?: string;\n /** \"byte blob, imports as ArrayBuffer\" */\n readonly data?: ArrayBuffer | ArrayBufferView;\n /** \"arbitrary JS value, will be serialized to JSON and then parsed again when imported\" */\n readonly json?: unknown;\n /** Python module. */\n readonly py?: string;\n /** \"compiled WASM module\" */\n readonly wasm?: ArrayBuffer | ArrayBufferView;\n};\n\n/** ← `WorkerLoader::WorkerCode` (`worker-loader.h:80-120`). */\nexport type WorkerCode = {\n readonly compatibilityDate: string;\n readonly compatibilityFlags?: readonly string[];\n readonly allowExperimental?: boolean;\n readonly limits?: ResourceLimits;\n readonly mainModule: string;\n /**\n * \"Modules are specified as an object mapping names to content. If the content is\n * just a string, an ES module is assumed. If it's an object, the type of module\n * is determined based on which property is set.\"\n */\n readonly modules: Record<string, Module | string>;\n /** \"Any RPC-serializable value!\" */\n readonly env?: unknown;\n /**\n * \"`Fetcher` (e.g. service binding) representing the loaded worker's global\n * outbound. If omitted, inherit the current worker's global outbound. If `null`,\n * block the global outbound (all requests throw errors).\"\n */\n readonly globalOutbound?: Fetcher | null;\n /** \"Specify tail workers.\" */\n readonly tails?: readonly Fetcher[];\n readonly streamingTails?: readonly Fetcher[];\n};\n\n/** ← `WorkerStub::EntrypointOptions` (`worker-loader.h:22-27`). */\nexport type EntrypointOptions = {\n readonly props?: unknown;\n readonly limits?: ResourceLimits;\n};\n\n// =======================================================================================\n// WorkerStub\n\n/**\n * ← `WorkerStub` (`worker-loader.h:15-50`). \"JS stub pointing to a remote Worker\n * loaded using WorkerLoader. This is not a stub for a specific entrypoint, but\n * instead the entire Worker, allowing the caller to call any entrypoint (and\n * specify arbitrary props).\"\n */\nexport class WorkerStub implements globalThis.WorkerStub {\n readonly #channel: WorkerStubChannel;\n\n constructor(channel: WorkerStubChannel) {\n this.#channel = channel;\n }\n\n /** ← `WorkerStub::getEntrypoint` (`worker-loader.c++:13-36`). */\n getEntrypoint<T extends Rpc.WorkerEntrypointBranded | undefined = undefined>(\n name?: string | null,\n options?: EntrypointOptions,\n ): Fetcher<T> {\n return asEntrypointStub<T>(this.#channel.getEntrypoint(entrypointRequestOf(name, options)));\n }\n\n /**\n * ← `WorkerStub::getDurableObjectClass` (`worker-loader.c++:38-61`).\n *\n * **This is the bridge into facets and it is a real connection, not a named\n * boundary.** The `ActorClassChannel` the channel answers with is the same token\n * `DurableObjectClass.getChannel()` hands to `FacetStartInfo.actorClass`, which\n * `FacetManager.getFacet` hands to `FacetHost.start` — so a class obtained here\n * goes straight into `ctx.facets.get(name, () => ({ class }))` with nothing in\n * between, which is exactly the shape upstream's `FacetTestActor` uses\n * (`worker-loader-test.js:421-433`).\n */\n getDurableObjectClass<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name?: string | null,\n options?: EntrypointOptions,\n ): DurableObjectClass<T> {\n return new DurableObjectClass<T>(this.#channel.getActorClass(entrypointRequestOf(name, options)));\n }\n}\n\n/**\n * The one assertion `getEntrypoint` needs, and it is `asFacetStub`'s\n * (`io/worker.ts`) for `asFacetStub`'s reason: `Fetcher<T>` for an unresolved `T`\n * is a conditional type over the caller's claim about an entrypoint it named, and\n * no value can confirm that claim. Upstream states the same shape the same way, in\n * a `JSG_TS_OVERRIDE` (`worker-loader.h:40-45`) that no C++ value is checked\n * against either. What IS checked is the half that carries behaviour — `fetch` and\n * `connect` — because the argument is a `Fetcher` before it is widened.\n */\nfunction asEntrypointStub<T extends Rpc.WorkerEntrypointBranded | undefined>(\n stub: Fetcher,\n): Fetcher<T> {\n return stub as Fetcher<T>;\n}\n\n/**\n * ← the identical prologue of both `WorkerStub` methods (`worker-loader.c++:16-32`\n * and `:41-57`).\n *\n * `\"default\"` collapses to no name, which is upstream's own line\n * (`if (n2 != \"default\"_kj)`) and is why `getEntrypoint(\"default\")` and\n * `getEntrypoint()` reach the same entrypoint.\n */\nfunction entrypointRequestOf(\n name: string | null | undefined,\n options: EntrypointOptions | undefined,\n): EntrypointRequest {\n return {\n name: entrypointNameOf(name),\n props: requireSerializableProps(options?.props, \"props\"),\n limits: options?.limits,\n };\n}\n\nfunction entrypointNameOf(name: string | null | undefined): string | undefined {\n // ← `jsg::Optional<kj::Maybe<kj::String>>`: absent and null are the same request. Anything\n // else reaches JSG's `kj::String` unwrapper, which calls ToString (`jsg/value.h:501-506`) —\n // the same reading `api/export-loopback.ts` gives `version.cohort`.\n if (name === undefined || name === null) return undefined;\n const text = String(name);\n return text === \"default\" ? undefined : text;\n}\n\n// =======================================================================================\n// WorkerLoader\n\n/**\n * The two constructor inputs upstream's `WorkerLoader` resolves from ambients this\n * package does not have.\n */\nexport type WorkerLoaderOptions = {\n /**\n * ← `WorkerLoader`'s second constructor parameter (`worker-loader.h:58`), whose\n * comment is \"`compatDateValidation` will differ between workerd vs.\n * production\". It is carried onto the `DynamicWorkerSource` rather than consumed\n * here, because the compilation it feeds is a substrate boundary — see\n * `CompatibilityFlagsRequest` in `io/io-channels.ts`.\n */\n readonly compatDateValidation: CompatibilityDateValidation;\n\n /**\n * ← `FeatureFlags::get(js).getWorkerdExperimental()` (`worker-loader.c++:281`) —\n * the *calling* worker's `experimental` compatibility flag, which gates\n * `allowExperimental` on the loaded one.\n *\n * Every other compatibility flag this package meets was answered by \"a runtime\n * with no deployed history takes the current behaviour\" (`api/actor.ts`, and the\n * README row for `deleteAllDeletesAlarm`). That reading does not work here:\n * `experimental` has no default-on date and never turns on by itself, so taking\n * the current behaviour would hard-code `false`, make `allowExperimental: true`\n * always throw, and put `streamingTails` out of reach — the feature subset the\n * README's second paragraph forbids. So the bit moves from an ambient to an\n * explicit input, which is what this package does with every ambient.\n * `compileCompatibilityFlags`'s own parameter for the same bit is named\n * `allowExperimentalFeatures`.\n */\n readonly allowExperimentalFeatures: boolean;\n};\n\n/**\n * ← `WorkerLoader` (`worker-loader.h:52-150`). \"JS interface for worker loader\n * binding.\"\n *\n * Takes an `IoContext` where upstream reads `IoContext::current()`, which is the\n * substitution every class in `api/` makes (`DurableObjectFacets`,\n * `DurableObjectStorageOperations`); and an `IsolateChannelFactory` where upstream\n * holds a channel number, which is the substitution every outgoing seam in `api/`\n * makes.\n */\nexport class WorkerLoader implements globalThis.WorkerLoader {\n readonly #ctx: IoContext;\n readonly #channel: IsolateChannelFactory;\n readonly #options: WorkerLoaderOptions;\n\n constructor(ctx: IoContext, channel: IsolateChannelFactory, options: WorkerLoaderOptions) {\n this.#ctx = ctx;\n this.#channel = channel;\n this.#options = options;\n }\n\n /**\n * ← `WorkerLoader::get` (`worker-loader.c++:63-83`).\n *\n * Nothing is validated here: the code callback is deferred whole into the reentry\n * callback, so every refusal `toDynamicWorkerSource` can make surfaces at the\n * first request on the returned stub instead. That is upstream's own behaviour\n * and its tests depend on it.\n */\n get(name: string | null | undefined, getCode: () => WorkerCode | Promise<WorkerCode>): WorkerStub {\n const ctx = this.#ctx;\n\n // ← `ioctx.makeReentryCallback(…)` (`worker-loader.c++:67`), and it is decision 13 for the\n // same reason the facet startup callback is: a Worker loaded from inside\n // blockConcurrencyWhile() would otherwise queue behind the section waiting for it.\n const reenterAndGetCode = ctx.makeReentryCallback(\n async (): Promise<DynamicWorkerSource> =>\n // ← the inner `getCode(js).then(js, …)` (`:70-76`). A jsg promise continuation re-enters\n // the isolate, so the source is built holding a fresh input lock rather than in whatever\n // context the code promise happened to resolve in; `awaitIo` is that re-entry, and it is\n // what keeps `toDynamicWorkerSource` gated (divergence 147).\n await Promise.race([\n ctx.awaitIo(Promise.resolve(getCode()), (code) => this.#toDynamicWorkerSource(code)),\n // ← `JSG_REQUIRE_NONNULL(weakIoctx->tryGet(), …)` (`:73-74`). `awaitIo`'s own answer to\n // an aborted context is to leave its promise unsettled, which would wedge every request\n // on the stub — see `DEAD_LOAD_CONTEXT_MESSAGE`. `onAbort()` only ever rejects.\n ctx.onAbort().catch((): never => {\n throw new Error(DEAD_LOAD_CONTEXT_MESSAGE);\n }),\n ]),\n );\n\n return new WorkerStub(\n this.#channel.loadIsolate({ name: loadNameOf(name), fetchSource: reenterAndGetCode }),\n );\n }\n\n /**\n * ← `WorkerLoader::load` (`worker-loader.c++:85-107`). \"Shortcut for `get(null,\n * () => code)`.\"\n *\n * A shortcut with two consequences upstream states outright. The source is built\n * **now**, synchronously, so every refusal below throws from this call rather\n * than from the first request; and `name` is `kj::none`, so the isolate is not\n * cached and a fresh Worker is minted per call.\n *\n * Upstream's clone-per-invocation is absent because a JS source object is\n * immutable and shared safely — see `io/worker-source.ts`'s header. The\n * atomic-refcount wrapper it needs for that (\"it may ultimately destroy the\n * `ownContent` in another thread ... Ugh!\") goes with it.\n */\n load(code: WorkerCode): WorkerStub {\n // ← `auto& ioctx = IoContext::current();` (`:86`), which asserts. `get()` does not need the\n // line because `makeReentryCallback` makes the same assertion for it.\n requireInputLock(this.#ctx, \"load()\");\n\n const source = this.#toDynamicWorkerSource(code);\n return new WorkerStub(\n this.#channel.loadIsolate({ name: undefined, fetchSource: async () => source }),\n );\n }\n\n /** ← `WorkerLoader::toDynamicWorkerSource` (`worker-loader.c++:109-172`). */\n #toDynamicWorkerSource(code: WorkerCode): DynamicWorkerSource {\n const source = extractSource(code);\n const compatibilityFlags = this.#extractCompatFlags(code);\n\n // ← `Frankenvalue::fromJs(js, codeEnv.getHandle(js))` (`:117-120`).\n const env = requireSerializableProps(code.env, \"env\");\n\n // ← `:122-139`. Three JS states collapse to two: `null` leaves the source's outbound absent,\n // which is what blocks it, and an omitted one inherits the caller's.\n let globalOutbound: Fetcher | undefined;\n if (code.globalOutbound !== undefined) {\n if (code.globalOutbound !== null) {\n globalOutbound = requireTransferableChannel(code.globalOutbound);\n } else {\n // \"Application passed `null` to disable internet access. Leave `globalOutbound` as\n // `kj::none`.\"\n }\n } else {\n // \"Inherit the calling worker's global outbound channel.\" No transferrability check, per\n // upstream: the parent's outbound is by definition allowed to be the child's.\n globalOutbound = this.#channel.getNullClientChannel();\n }\n\n // ← `:141-148`.\n const tails = (code.tails ?? []).map(requireTransferableChannel);\n\n // ← `:150-161`.\n const streamingTailsInput = code.streamingTails;\n let streamingTails: readonly Fetcher[] = [];\n if (streamingTailsInput !== undefined) {\n if ((code.allowExperimental ?? false) !== true) {\n throw new Error(STREAMING_TAILS_EXPERIMENTAL_MESSAGE);\n }\n streamingTails = streamingTailsInput.map(requireTransferableChannel);\n }\n\n return {\n source,\n compatibilityFlags,\n limits: code.limits,\n env,\n globalOutbound,\n tails,\n streamingTails,\n };\n }\n\n /**\n * ← `WorkerLoader::extractCompatFlags` (`worker-loader.c++:278-306`), first half\n * only.\n *\n * The second half compiles the date and flags into a `CompatibilityFlags::Reader`\n * by walking that schema's capnp annotations, and reports\n * `errorReporter.errors.front()`. There is no `compatibility-date.capnp` here and\n * no schema reflection to walk one with, so the inputs travel on the\n * `DynamicWorkerSource` to the layer that has an isolate to configure. See\n * `CompatibilityFlagsRequest` in `io/io-channels.ts`.\n */\n #extractCompatFlags(code: WorkerCode): CompatibilityFlagsRequest {\n const allowExperimental = code.allowExperimental ?? false;\n if (!this.#options.allowExperimentalFeatures) {\n if (allowExperimental) throw new Error(ALLOW_EXPERIMENTAL_MESSAGE);\n }\n\n return {\n compatibilityDate: code.compatibilityDate,\n compatibilityFlags: code.compatibilityFlags ?? [],\n allowExperimental,\n dateValidation: this.#options.compatDateValidation,\n };\n }\n}\n\n/**\n * ← `kj::Maybe<kj::String> name` on `WorkerLoader::get`. Absent and null are the\n * same request, and both mint a fresh isolate — `worker-loader-test.js:527-541`\n * checks `get(null)` and two `get(undefined)`s all get their own module scope.\n *\n * Unlike the entrypoint name, `\"default\"` is not special here: it names an\n * isolate, not an export.\n */\nfunction loadNameOf(name: string | null | undefined): string | undefined {\n return name === undefined || name === null ? undefined : String(name);\n}\n\n// =======================================================================================\n// extractSource\n\n/**\n * ← `WorkerLoader::extractSource` (`worker-loader.c++:174-276`).\n *\n * Iteration order is the object's own key order, which is `jsg::Dict`'s: both the\n * fieldCount and mixed-language refusals name the FIRST offending module in that\n * order, and upstream's `noMixedJsPythonModules` pair depends on it\n * (`worker-loader-test.js:803-835`).\n */\nfunction extractSource(code: WorkerCode): WorkerSource {\n const entries = Object.entries(code.modules);\n if (entries.length === 0) throw new TypeError(NO_MODULES_MESSAGE);\n\n const modules: SourceModule[] = entries.map(([name, value]) => ({\n name,\n content: moduleContentOf(name, value),\n }));\n\n // ← `:255`. Whether the Worker is Python is decided by the MAIN module's name alone.\n const isPython = code.mainModule.endsWith(\".py\");\n\n // ← `:257-269`. \"Disallow Python modules when the main module is a JS module, and vice versa.\"\n for (const module of modules) {\n const isJsModule =\n module.content.type === \"esModule\" || module.content.type === \"commonJsModule\";\n if (isPython && isJsModule) {\n throw new TypeError(jsModuleInPythonWorkerMessage(module.name));\n }\n const isPythonModule = module.content.type === \"pythonModule\";\n if (!isPython && isPythonModule) {\n throw new TypeError(pythonModuleInJsWorkerMessage(module.name));\n }\n }\n\n return { variant: { type: \"modulesSource\", mainModule: code.mainModule, modules, isPython } };\n}\n\n/** ← the `KJ_SWITCH_ONEOF(entry.value)` at `worker-loader.c++:179-251`. */\nfunction moduleContentOf(name: string, value: Module | string): ModuleContent {\n if (typeof value === \"string\") return stringModuleContentOf(name, value);\n return objectModuleContentOf(name, value);\n}\n\n/** ← the `kj::String` arm (`:180-207`): the name alone decides the type. */\nfunction stringModuleContentOf(name: string, body: string): ModuleContent {\n if (name.endsWith(\".py\")) return { type: \"pythonModule\", body };\n if (name.endsWith(\".js\")) return { type: \"esModule\", body };\n if (name.endsWith(\".ts\") || name.endsWith(\".tsx\") || name.endsWith(\".jsx\")) {\n throw new TypeError(typeScriptModuleNameMessage(name));\n }\n throw new TypeError(moduleNameMessage(name));\n}\n\n/** The seven fields of `WorkerLoader::Module`, in upstream's `JSG_STRUCT` order. */\nconst MODULE_FIELDS = [\"js\", \"cjs\", \"text\", \"data\", \"json\", \"py\", \"wasm\"] as const;\n\n/** ← the `Module` arm (`:208-250`). */\nfunction objectModuleContentOf(name: string, module: Module): ModuleContent {\n // ← the seven `!= kj::none` sums at `:209-211`. `jsg::Optional` reads undefined as absent, so a\n // field explicitly set to undefined does not count — which is what makes a `{...spread}` of a\n // partially-filled module behave the same way in both runtimes.\n const fieldCount = MODULE_FIELDS.filter((field) => module[field] !== undefined).length;\n if (fieldCount !== 1) throw new TypeError(moduleFieldCountMessage(name, fieldCount));\n\n if (module.js !== undefined) return { type: \"esModule\", body: module.js };\n if (module.cjs !== undefined) return { type: \"commonJsModule\", body: module.cjs };\n if (module.text !== undefined) return { type: \"textModule\", body: module.text };\n // ← `:225-232`. \"The kj::Array<const byte> produced by jsg::asBytes() points into a V8\n // BackingStore. If the user passed a *resizable* ArrayBuffer they can call resize(0) (or\n // transfer/detach) after load() returns but before the child isolate is compiled\n // asynchronously, leaving us with a (ptr,len) into PROT_NONE pages. Copy now so the bytes\n // survive until compileDataGlobal().\"\n if (module.data !== undefined) return { type: \"dataModule\", body: copyBytes(module.data) };\n if (module.json !== undefined) {\n // ← `js.serializeJson(kj::mv(json))` (`:234-235`). Upstream then clears the field because it\n // moved out of a V8Ref; nothing is moved here. `JSON.stringify` answers undefined for a value\n // it cannot represent at the root — a function or a symbol — where V8's JSON serializer\n // throws; the string is what a module body has to be, so the undefined is made one.\n return { type: \"jsonModule\", body: JSON.stringify(module.json) ?? \"undefined\" };\n }\n if (module.py !== undefined) return { type: \"pythonModule\", body: module.py };\n if (module.wasm !== undefined) return { type: \"wasmModule\", body: copyBytes(module.wasm) };\n\n // ← `KJ_UNREACHABLE` (`:247`): fieldCount === 1 has already found one of the seven.\n throw new Error(\"unreachable: exactly one module field is set\");\n}\n\n/**\n * ← `jsg::asBytes()` followed by `kj::heapArray<const kj::byte>(data.asPtr())`\n * (`worker-loader.c++:231`, `:244`). The copy is the whole point — see the caller.\n */\nfunction copyBytes(value: ArrayBuffer | ArrayBufferView): Uint8Array {\n if (value instanceof ArrayBuffer) return new Uint8Array(value.slice(0));\n if (ArrayBuffer.isView(value)) {\n return new Uint8Array(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));\n }\n throw new TypeError(NOT_BYTES_MESSAGE);\n}\n\n// =======================================================================================\n// What may cross into a dynamic Worker\n\n/**\n * ← `Fetcher::getSubrequestChannel(ioctx)` followed by\n * `channel->requireAllowsTransfer()` (`worker-loader.c++:125-126`, `:144-145`,\n * `:157-158`).\n *\n * **The check has nothing to call, and that is a recorded divergence rather than\n * an omission.** Upstream's `SubrequestChannel` carries `requireAllowsTransfer()`;\n * here a `SubrequestChannel` and the `Fetcher` built over it are one object\n * (`io/io-channels.ts`'s header, and the same collapse `api/actor.ts` and\n * `api/export-loopback.ts` already made), and a `Fetcher` is\n * `@cloudflare/workers-types`' interface with no such member. The one refusal it\n * produces in the open-source runtime is `throwDynamicEntrypointTransferError`\n * (`server.c++:167-173`), raised by `WorkerService::requireAllowsTransfer` when\n * `isDynamic` — an isolate-host fact here, exactly as it is a `server/` fact there.\n *\n * Kept as a named function rather than inlined so the three call sites read as\n * upstream's do, and so there is one place to put the check if a `Fetcher` seam\n * ever grows one.\n */\nfunction requireTransferableChannel(fetcher: Fetcher): Fetcher {\n return fetcher;\n}\n\n/**\n * ← `Frankenvalue::fromJs(js, …)`, whose serializer refuses any object whose JSG\n * resource type declares no `JSG_SERIALIZABLE` (`jsg/ser.c++:175-183`).\n *\n * Four types reachable from this package are in that set, and all four for one\n * reason: `JSG_INHERIT` does not carry serializability. Upstream says so twice — in\n * `export-loopback.h:57-58` (\"Note that `LoopbackServiceStub` is intentionally NOT\n * serializable, unlike its parent class Fetcher\") and in the test that pins it,\n * whose comment reads \"it's more testing LoopbackServiceStub and that\n * serializability is not inherited\" (`worker-loader-test.js:91-92`). None of\n * `LoopbackServiceStub`, `LoopbackDurableObjectClass`,\n * `LoopbackDurableObjectNamespace` or `LoopbackColoLocalActorNamespace` declares\n * `JSG_SERIALIZABLE`; every one of them *invoked* produces something that does — a\n * `Fetcher` or a plain `DurableObjectClass` — which is exactly the distinction\n * `worker-loader-test.js:62-107` measures, accepting the invoked form in `props`\n * and refusing the bare binding.\n *\n * **This discharges the obligation the README left open on Section 7.** That row\n * says the refusal would have to come from `src/transport/` if a `Fetcher` ever\n * became serializable; the layer upstream refuses at is this one, because\n * `Frankenvalue::fromJs` runs inside `getEntrypoint`, `getDurableObjectClass` and\n * `toDynamicWorkerSource`. Putting it here makes it reachable today rather than\n * conditional on a transport change that has not happened, and it depends on no\n * transport fact — so `api/` still imports no transport library.\n *\n * The walk descends into plain objects and arrays only. Everything else is a host\n * object: either one the substrate knows how to carry (a `Fetcher`, a\n * `DurableObjectClass`, an `RpcTarget`) or one of the four above. Walking a host\n * object's own keys would drive proxy traps — a stub's `get` mints an RPC import —\n * which is a cost upstream's serializer never pays, because it asks the type rather\n * than the value.\n */\nfunction requireSerializableProps(root: unknown, field: string): unknown {\n // A cycle would otherwise walk forever; upstream's serializer handles one natively.\n const seen = new Set<object>();\n\n const visit = (value: unknown, path: string): void => {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) return;\n const subject = value as object;\n\n const refused = notSerializableType(subject);\n if (refused !== undefined) {\n throw new DOMException(`${notSerializableMessage(refused)} At ${path}.`, \"DataCloneError\");\n }\n\n if (seen.has(subject)) return;\n seen.add(subject);\n\n if (Array.isArray(subject)) {\n subject.forEach((entry, index) => {\n visit(entry, `${path}[${index}]`);\n });\n return;\n }\n\n // Plain objects only — see the note above on why a host object is not descended into.\n const prototype: unknown = Object.getPrototypeOf(subject);\n if (prototype !== Object.prototype && prototype !== null) return;\n for (const [name, entry] of Object.entries(subject)) visit(entry, `${path}.${name}`);\n };\n\n visit(root, `<${field}>`);\n return root;\n}\n\n/**\n * The four `ctx.exports` binding types, named by the class whose name\n * `GetConstructorName()` would report.\n *\n * The four are mutually exclusive — each extends a different base\n * (`api/export-loopback.ts`) — so the order is presentational. What the order does\n * NOT do is reach a base class: `DurableObjectClass`, `DurableObjectNamespace`,\n * `ColoLocalActorNamespace` and `Fetcher` are all serializable upstream\n * (`actor.h:389`), and it is exactly `JSG_INHERIT`'s failure to carry\n * serializability that makes the four subclasses refuse where their bases accept.\n */\nfunction notSerializableType(value: object): string | undefined {\n if (value instanceof LoopbackServiceStub) return \"LoopbackServiceStub\";\n if (value instanceof LoopbackDurableObjectNamespace) return \"LoopbackDurableObjectNamespace\";\n if (value instanceof LoopbackColoLocalActorNamespace) return \"LoopbackColoLocalActorNamespace\";\n if (value instanceof LoopbackDurableObjectClass) return \"LoopbackDurableObjectClass\";\n return undefined;\n}\n\n// =======================================================================================\n// The pinned-types check\n\n/** `Value` must be assignable to `Declared`; declaring the constraint is the check. */\ntype Assignable<Value extends Declared, Declared> = Value;\n\n/**\n * §2.4's no-cast rule: these reach a consumer as `env` bindings typed by\n * `@cloudflare/workers-types`, so the type system checks the surface rather than a\n * cast doing it. The three struct rows point the other way, because a struct is an\n * argument: what has to hold is that every code a consumer can write against the\n * pinned type is one this file accepts. `Module` is a strict superset by the two\n * byte fields, for the reason its own comment gives.\n */\nexport type PinnedWorkerLoaderTypes = [\n Assignable<WorkerLoader, globalThis.WorkerLoader>,\n Assignable<WorkerStub, globalThis.WorkerStub>,\n Assignable<globalThis.WorkerLoaderWorkerCode, WorkerCode>,\n Assignable<globalThis.WorkerLoaderModule, Module>,\n Assignable<globalThis.WorkerStubEntrypointOptions, EntrypointOptions>,\n];\n","/**\n * ← workerd `src/workerd/api/sql.{h,c++}`\n *\n * `SqlStorage` and its two nested types. ~330 call sites depend on this — it is\n * the real storage layer, not KV.\n *\n * Four things about the translation, in descending order of how much they cost:\n *\n * 1. **The cursor is materialised, not live.** Upstream's `Cursor` owns a\n * running `SqliteDatabase::Query` and pulls one row at a time; the backend\n * seam this package chose (`SqlDatabase.exec` → `SqlResult`) has already\n * collected every row before a cursor exists. Everything downstream of that\n * follows: there is no statement cache, so `CachedStatement`, the 1 MiB LRU\n * and `reusedCachedQueryForTest` are absent with it; there is no live\n * statement to cancel, so `Cursor::canceled` and `selfRef` — both already\n * dead upstream, written but never assigned — have nothing to guard; and\n * `endQuery`'s job of returning a statement to the cache is nothing here, so\n * the counters it saves off are simply the counters. What is kept is every\n * observable: the position is shared across `next`/`toArray`/`one`/`raw`,\n * and a drained cursor keeps yielding done.\n * 2. **`Cursor` and `Statement` must be constructible with no arguments**, or\n * `SqlStorage` cannot satisfy workers-types without a cast: the interface\n * types them `typeof SqlStorageCursor` / `typeof SqlStorageStatement`, and\n * both are `abstract` there, so their construct signatures take none.\n * Upstream's are unconstructible from JS for the same reason they are\n * `abstract` in the types — JSG nested types have no JS constructor — so the\n * faithful shape is a constructor that refuses. `sql.Cursor` exists for\n * `instanceof`, which is all upstream exposes it for.\n * 3. **The regulator is ported whole; what is missing is the authorizer that\n * calls it.** All three callbacks are here and none of them needed the\n * authorizer to compute anything — `isAllowedName` is a prefix test,\n * `isAllowedTrigger` is `return true`, `allowTransactions` throws. What the\n * authorizer supplied was the *identifiers*, not the decisions. With no\n * authorizer the statement text is the only source, so `exec` tokenizes it\n * and runs `isAllowedName` over every identifier-shaped token. That is\n * deliberately STRICTER than upstream — see `SQL_RESERVED_PREFIX_MESSAGE`.\n * 4. **`ingest` stays at upstream's SQLite seam.** `SqliteDatabase.ingest()`\n * executes every complete statement and returns the partial tail, using the\n * same compiled boundaries and regulator as `exec`.\n *\n * Spec: §1.4, §2.4 in docs/decisions.md.\n */\n\nimport { requireInputLock } from \"../io/io-context\";\nimport type { IoContext } from \"../io/io-context\";\nimport type { SqlIngestResult, SqliteDatabase, SqlValue } from \"../util/sqlite\";\n\n/**\n * ← `SqlStorage::BindingValue`. JSG converts these public JavaScript values\n * to workerd's `Maybe<OneOf<Array<byte>, String, double>>` before C++ sees them;\n * `toSqlBindingValue()` is that conversion for this no-isolate runtime.\n */\nexport type BindingValue =\n | ArrayBuffer\n | ArrayBufferView\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/** ← the `SqlStorageValue` `JSG_TS_DEFINE` on `Cursor`. */\nexport type SqlRow = Record<string, SqlStorageValue>;\n\n/** ← `SqlStorage::IngestResult`. */\nexport type SqlStorageIngestResult = SqlIngestResult;\n\n/**\n * ← `SqlStorageRegulator::allowTransactions()`, copied verbatim. Users match on\n * it and it is the one regulator callback our substrate can still answer.\n */\nexport const SQL_TRANSACTION_REFUSED_MESSAGE =\n \"To execute a transaction, please use the state.storage.transaction() or \" +\n \"state.storage.transactionSync() APIs instead of the SQL BEGIN TRANSACTION or SAVEPOINT \" +\n \"statements. The JavaScript API is safer because it will automatically roll back on \" +\n \"exceptions, and because it interacts correctly with Durable Objects' automatic atomic \" +\n \"write coalescing.\";\n\n/** See translation 2 in the header: the class is exposed for `instanceof` only. */\nexport const CURSOR_NOT_CONSTRUCTIBLE_MESSAGE =\n \"Illegal invocation: SqlStorage.Cursor cannot be constructed directly. Use sql.exec().\";\n\n/** Same, for the prepared-statement compatibility shim. */\nexport const STATEMENT_NOT_CONSTRUCTIBLE_MESSAGE =\n \"Illegal invocation: SqlStorage.Statement cannot be constructed directly. Use sql.prepare().\";\n\n/**\n * ← SQLite's own denial text, with the reason appended.\n *\n * There is no upstream string to copy here: `SqlStorageRegulator::onError` just\n * rethrows whatever SQLite produced, and SQLite produces `not authorized` for an\n * authorizer denial (`access to X.Y is prohibited` for the column-read case,\n * which needs a resolved identifier we do not have). The prefix is kept so that\n * anything matching upstream still matches; the rest is here because a bare\n * `not authorized` is not debuggable.\n */\nexport const SQL_RESERVED_PREFIX_MESSAGE =\n \"not authorized: a SQL statement may not name the reserved _cf_ prefix, which is where this \" +\n \"Durable Object keeps its own KV and metadata tables.\";\n\n/**\n * ← the five transaction-control forms `sqlite3_stmt_readonly()` reports\n * read-only and the authorizer reports as `SQLITE_TRANSACTION` /\n * `SQLITE_SAVEPOINT`. The same set `util/sqlite.ts` classifies, read here from\n * the leading keyword because the untrusted path has to refuse them before the\n * trusted one applies them.\n */\nconst TRANSACTION_CONTROL = /^\\s*(?:BEGIN|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\\b/i;\n\n/** Cheap pre-test, so the tokenizer below runs only on a statement that could fail it. */\nconst RESERVED_PREFIX_HINT = /_cf_/i;\n\n/** A SQL identifier. Double-quoted and bracketed forms are still identifiers, so only the\n * delimiters are stripped and the word inside is scanned like any other. */\nconst IDENTIFIER = /[A-Za-z_][A-Za-z0-9_$]*/g;\n\n/**\n * Everything in a statement an identifier cannot come from: single-quoted string\n * literals (SQLite escapes an embedded quote by doubling it), `--` line comments,\n * and `/* *\\/` block comments. Replaced with a space before tokenizing, so what is\n * left is code.\n *\n * Backtick-quoted names are NOT here: MySQL-compatible quoting produces an\n * identifier, exactly as the double-quoted form does.\n */\nconst NOT_CODE = /'(?:[^']|'')*'|--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g;\n\n/**\n * ← `SqlStorageRegulator` (`sql.h:15-22`, `sql.c++:143-173`), whole.\n *\n * Upstream reaches these through the SQLite authorizer while a statement is\n * being compiled. `exec` calls them from the statement text instead, which is\n * the same translation Section 3 made for the write classifier and for\n * transaction state.\n */\nexport const SqlStorageRegulator = {\n /**\n * Upstream's body is `return !name.startsWith(\"_cf_\")`, with an autogate that\n * makes the comparison case-insensitive and logs a warning until it lands. The\n * case-insensitive form is taken here: it is the direction upstream is moving,\n * and there is no logger for the warning half.\n */\n isAllowedName(name: string): boolean {\n return name.length < 4 || name.slice(0, 4).toLowerCase() !== \"_cf_\";\n },\n\n /** Upstream's body is `return true`. */\n isAllowedTrigger(_name: string): boolean {\n return true;\n },\n\n /** Upstream's body is a `JSG_FAIL_REQUIRE` with this message. */\n allowTransactions(): never {\n throw new Error(SQL_TRANSACTION_REFUSED_MESSAGE);\n },\n\n /** \"Bill for queries executed from JavaScript.\" Nothing reads it — `SqliteObserver` has no port. */\n shouldAddQueryStats(): boolean {\n return true;\n },\n};\n\n/**\n * The text-level stand-in for the authorizer's `isAllowedName` calls — see\n * `SQL_RESERVED_PREFIX_MESSAGE` and the README row.\n *\n * Upstream refuses a *resolved identifier* that starts with `_cf_`, because it\n * reaches `isAllowedName` through the SQLite authorizer while the statement is\n * being compiled. There is no authorizer here, so this tokenizes the statement\n * text instead, over everything that is not a string literal or a comment —\n * which is the same set of characters an identifier can come from.\n *\n * **The literals were once refused too, and that was wrong.** The first draft\n * scanned the whole statement on the reasoning that no legitimate consumer\n * statement contains the token, so being stricter than upstream was the safe\n * direction. A retained conformance case uses `_cf_keepAliveHeartbeat` as a\n * bound value: real workerd accepts it, so this parser must distinguish data\n * from identifiers. `conformance/suite/sql.spec.ts` pins the rule: refused as a\n * table name and as a quoted identifier, allowed as data.\n *\n * A name that merely CONTAINS the token — `my_cf_thing` — stays allowed, because\n * `isAllowedName` tests a prefix.\n */\nfunction requireAllowedNames(query: string): void {\n if (!RESERVED_PREFIX_HINT.test(query)) return;\n const code = query.replace(NOT_CODE, \" \");\n for (const [token] of code.matchAll(IDENTIFIER)) {\n if (!SqlStorageRegulator.isAllowedName(token)) throw new Error(SQL_RESERVED_PREFIX_MESSAGE);\n }\n}\n\n/** Refuse transaction control against one SQLite-decided statement boundary. */\nfunction refuseTransactionControl(statement: string): void {\n const code = statement.replace(NOT_CODE, \" \");\n if (TRANSACTION_CONTROL.test(code)) SqlStorageRegulator.allowTransactions();\n}\n\n/**\n * ← the `jsg::Ref<DurableObjectStorage>` `SqlStorage` holds, narrowed to the one\n * member it reaches through (`SqlStorage::getDb`). `DurableObjectStorage`\n * satisfies it; narrowing is what keeps this file free of a value-level import\n * cycle, which upstream tolerates because C++ headers do not have one.\n */\nexport interface SqlStorageOwner {\n /** ← `DurableObjectStorage::getSqliteDb`. Throws if not SQLite-backed. */\n getSqliteDb(): SqliteDatabase;\n}\n\n/** The rows a cursor walks, plus the counters that outlive them. */\ntype CursorState = {\n readonly columnNames: string[];\n readonly rawRows: readonly (readonly SqlStorageValue[])[];\n readonly rowsWritten: number;\n};\n\n/**\n * ← `SqlStorage::Cursor`.\n *\n * `rowsRead` is the one counter that is not upstream's. Upstream reads\n * `Query::getRowsRead()`, a billing counter sourced from libsql's\n * `STMTSTATUS_ROWS_READ` that counts index rows and that neither backend\n * exposes — the same absence the README already records for `SqlResult`. The\n * interface requires a number, so this returns the rows the cursor has yielded,\n * which is what today's browser host returns and what its tests assert. It\n * undercounts any query that scans more rows than it returns.\n */\nexport class Cursor<T extends SqlRow = SqlRow> implements SqlStorageCursor<T> {\n readonly columnNames: string[];\n readonly #rawRows: readonly (readonly SqlStorageValue[])[];\n readonly #rowsWritten: number;\n #position = 0;\n\n constructor(state?: CursorState) {\n if (state === undefined) throw new Error(CURSOR_NOT_CONSTRUCTIBLE_MESSAGE);\n this.columnNames = state.columnNames;\n this.#rawRows = state.rawRows;\n this.#rowsWritten = state.rowsWritten;\n }\n\n /** ← `Cursor::next`, whose `RowIterator::Next` is this exact shape. */\n next(): { done?: false; value: T } | { done: true; value?: never } {\n const row = this.#nextRow();\n if (row === undefined) return { done: true };\n return { done: false, value: row };\n }\n\n /** ← `Cursor::toArray`, which drains from the current position. */\n toArray(): T[] {\n const rows: T[] = [];\n for (;;) {\n const row = this.#nextRow();\n if (row === undefined) return rows;\n rows.push(row);\n }\n }\n\n /** ← `Cursor::one`. Both messages are upstream's, verbatim. */\n one(): T {\n const row = this.#nextRow();\n if (row === undefined) {\n throw new Error(\"Expected exactly one result from SQL query, but got no results.\");\n }\n if (this.#position < this.#rawRows.length) {\n // Upstream drops the query here before throwing, so the statement cannot be reused.\n this.#position = this.#rawRows.length;\n throw new Error(\"Expected exactly one result from SQL query, but got multiple results.\");\n }\n return row;\n }\n\n /** ← `Cursor::raw`, which shares this cursor's position rather than restarting. */\n raw<U extends SqlStorageValue[]>(): IterableIterator<U> {\n const iterator: IterableIterator<U> = {\n [Symbol.iterator](): IterableIterator<U> {\n return iterator;\n },\n next: (): IteratorResult<U> => {\n const raw = this.#nextRaw();\n if (raw === undefined) return { done: true, value: undefined };\n const values: SqlStorageValue[] = [...raw];\n return { done: false, value: asRawRow<U>(values) };\n },\n };\n return iterator;\n }\n\n /** ← `JSG_ITERABLE(rows)`. */\n [Symbol.iterator](): IterableIterator<T> {\n const iterator: IterableIterator<T> = {\n [Symbol.iterator](): IterableIterator<T> {\n return iterator;\n },\n next: (): IteratorResult<T> => {\n const row = this.#nextRow();\n if (row === undefined) return { done: true, value: undefined };\n return { done: false, value: row };\n },\n };\n return iterator;\n }\n\n get rowsRead(): number {\n return this.#position;\n }\n\n /** ← `Cursor::getRowsWritten`, which is `SqlResult.rowsWritten` here. */\n get rowsWritten(): number {\n return this.#rowsWritten;\n }\n\n #nextRaw(): readonly SqlStorageValue[] | undefined {\n const raw = this.#rawRows[this.#position];\n if (raw === undefined) return undefined;\n this.#position += 1;\n return raw;\n }\n\n /** ← `Cursor::rowIteratorNext`: zip the column names onto the row. */\n #nextRow(): T | undefined {\n const raw = this.#nextRaw();\n if (raw === undefined) return undefined;\n const row: SqlRow = {};\n this.columnNames.forEach((name, index) => {\n row[name] = raw[index] ?? null;\n });\n return asRow<T>(row);\n }\n}\n\n/**\n * ← `SqlStorage::Statement`, which upstream describes as \"supported only for\n * backwards compatibility ... it is actually just a wrapper around `exec()`\".\n * `JSG_CALLABLE(run)` makes the object itself callable, so `prepare()` returns a\n * function wearing this prototype rather than an object with a `run` method.\n */\nexport class Statement {\n constructor() {\n throw new Error(STATEMENT_NOT_CONSTRUCTIBLE_MESSAGE);\n }\n}\n\n/** What `prepare()` hands back: `Statement::run`, reachable by calling it. */\nexport interface PreparedStatement {\n <T extends SqlRow = SqlRow>(...bindings: BindingValue[]): Cursor<T>;\n}\n\nexport class SqlStorage implements globalThis.SqlStorage {\n readonly #ctx: IoContext;\n readonly #owner: SqlStorageOwner;\n /** ← `kj::Maybe<uint> pageSize`, memoized for the same reason. */\n #pageSize: number | undefined;\n\n constructor(ctx: IoContext, owner: SqlStorageOwner) {\n this.#ctx = ctx;\n this.#owner = owner;\n }\n\n /** ← `JSG_NESTED_TYPE(Cursor)`. Exposed so `instanceof` works, as upstream's is. */\n readonly Cursor = Cursor;\n /** ← `JSG_NESTED_TYPE(Statement)`. */\n readonly Statement = Statement;\n\n exec<T extends SqlRow = SqlRow>(query: string, ...bindings: BindingValue[]): Cursor<T> {\n requireInputLock(this.#ctx, \"sql.exec()\");\n const db = this.#owner.getSqliteDb();\n const sqlBindings = bindings.map(toSqlBindingValue);\n\n // Name checks stay a preflight because the backend cannot return a compiled\n // statement for a missing reserved table. This text-level check is the\n // deliberately stricter authorizer substitute documented above.\n requireAllowedNames(query);\n\n // The backend supplies the same statement boundary SQLite compiled. That is\n // load-bearing for CREATE TRIGGER, whose body legitimately contains semicolons.\n const result = db.run({ regulate: refuseTransactionControl }, query, ...sqlBindings);\n return new Cursor<T>({\n columnNames: [...result.columnNames],\n rawRows: result.rawRows.map((row) => row.map(toSqlStorageValue)),\n rowsWritten: result.rowsWritten,\n });\n }\n\n /**\n * ← `SqlStorage::getDatabaseSize`.\n *\n * Upstream's second query is `PRAGMA page_size;`, which `sqlite3_stmt_readonly()`\n * reports read-only. With no such call the text is the only source and §1.7.1's\n * rule is write-unless-provably-a-read, so a bare `PRAGMA` would open a\n * transaction and take an output-gate lock to answer a size question. The\n * `pragma_page_size` table-valued function is the same value read through the\n * `SELECT` upstream already uses for the page count.\n */\n get databaseSize(): number {\n requireInputLock(this.#ctx, \"sql.databaseSize\");\n const db = this.#owner.getSqliteDb();\n const pages = db.run(\n \"select (select * from pragma_page_count) - (select * from pragma_freelist_count);\",\n );\n return readNumber(pages, \"page count\") * this.#getPageSize(db);\n }\n\n /** ← `SqlStorage::prepare`. Experimental and deprecated upstream; `exec` caches for you. */\n prepare(query: string): PreparedStatement {\n requireInputLock(this.#ctx, \"sql.prepare()\");\n const run = <T extends SqlRow = SqlRow>(...bindings: BindingValue[]): Cursor<T> =>\n this.exec<T>(query, ...bindings);\n Object.setPrototypeOf(run, Statement.prototype);\n return run;\n }\n\n /** ← `SqlStorage::ingest`. */\n ingest(query: string): SqlStorageIngestResult {\n requireInputLock(this.#ctx, \"sql.ingest()\");\n requireAllowedNames(query);\n return this.#owner.getSqliteDb().ingest(query, refuseTransactionControl);\n }\n\n /** ← `SqlStorage::setMaxPageCountForTest`, which is what its name says. */\n setMaxPageCountForTest(count: number): void {\n requireInputLock(this.#ctx, \"sql.setMaxPageCountForTest()\");\n this.#owner.getSqliteDb().run(`PRAGMA max_page_count = ${count}`);\n }\n\n /** ← `SqlStorage::getPageSize`. */\n #getPageSize(db: SqliteDatabase): number {\n const cached = this.#pageSize;\n if (cached !== undefined) return cached;\n const size = readNumber(db.run(\"select * from pragma_page_size;\"), \"page size\");\n this.#pageSize = size;\n return size;\n }\n}\n\nfunction readNumber(result: { readonly rawRows: readonly (readonly unknown[])[] }, what: string): number {\n const value = result.rawRows[0]?.[0];\n if (typeof value === \"number\") return value;\n if (typeof value === \"bigint\") return Number(value);\n throw new Error(`Expected a number for the database's ${what}.`);\n}\n\n/** ← JSG's conversion from JavaScript arguments to `SqlStorage::BindingValue`. */\nfunction toSqlBindingValue(value: unknown): SqlValue {\n if (value === null || value === undefined) return null;\n if (typeof value === \"string\" || typeof value === \"number\") return value;\n if (typeof value === \"boolean\") return String(value);\n if (typeof value === \"bigint\") {\n throw new TypeError(\"Cannot convert a BigInt value to a number\");\n }\n if (value instanceof ArrayBuffer) return copyBytes(new Uint8Array(value));\n if (ArrayBuffer.isView(value)) {\n return copyBytes(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n }\n throw new TypeError(`Cannot convert ${Object.prototype.toString.call(value)} to a SQL value`);\n}\n\nfunction copyBytes(bytes: Uint8Array): Uint8Array {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy;\n}\n\n/**\n * ← `SqlStorage::wrapSqlValue` plus the `Query::getValue` switch above it.\n *\n * Upstream's int64 arm carries its own comment: \"int64 will become BigInt, but\n * most applications won't want all their integers to be BigInt. We will coerce\n * to a double here.\" That coercion is kept rather than refused, because it is\n * the documented behaviour of `sql.exec` and a caller storing an id larger than\n * 2^53 has already lost on workerd.\n */\nfunction toSqlStorageValue(value: unknown): SqlStorageValue {\n if (value === null || value === undefined) return null;\n if (typeof value === \"string\" || typeof value === \"number\") return value;\n if (typeof value === \"bigint\") return Number(value);\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value instanceof Uint8Array) {\n const copy = new ArrayBuffer(value.byteLength);\n new Uint8Array(copy).set(value);\n return copy;\n }\n throw new Error(`SQL returned a ${typeof value}, which is not a SqlStorageValue.`);\n}\n\n/**\n * The two narrowings a generic row type needs. `T` is the caller's claim about\n * the shape of a row SQLite produced at runtime, so no check can confirm it and\n * upstream does not try — its `Cursor<T>` is the same claim written in a\n * `JSG_TS_OVERRIDE`. Confined to these two functions so the claim is one place\n * rather than sprinkled through the cursor.\n */\nfunction asRow<T extends SqlRow>(row: SqlRow): T {\n return row as T;\n}\n\nfunction asRawRow<U extends SqlStorageValue[]>(values: SqlStorageValue[]): U {\n return values as U;\n}\n","/**\n * ← workerd `src/workerd/api/sync-kv.{h,c++}`\n *\n * \"Synchronous KV storage. Available as ctx.storage.kv on SQLite-backed DOs.\"\n *\n * This module is not in Section 5's brief and exists because\n * `DurableObjectStorage` cannot satisfy workers-types without it: the interface\n * declares `kv: SyncKvStorage` unconditionally, and §2.4's rule is that the\n * surface is verified by the type system rather than by a cast. It is also a\n * genuine part of the contract — a whole KV surface that skips the promise\n * wrapper, over the same `SqliteKv` `DurableObjectStorage` writes through, with\n * the same codec.\n *\n * Two things upstream has that are absent, both already absent below this file:\n * the trace spans every method opens, and the billing counters. What is kept is\n * the whole of the behaviour, including the one error that is neither of those:\n * a `list()` iterator invalidated by a second `list()` says so rather than\n * silently ending, which is `SqliteKv::ListCursor::wasCanceled()`.\n *\n * Spec: §2.4 in docs/decisions.md.\n */\n\nimport type { IoContext } from \"../io/io-context\";\nimport { requireInputLock } from \"../io/io-context\";\nimport type { SqliteKv, SqliteKvListCursor } from \"../util/sqlite-kv\";\nimport { compileListOptions, deserializeValue, serializeValue } from \"./actor-state\";\n\n/**\n * ← the `jsg::Ref<DurableObjectStorage>` `SyncKvStorage` holds, narrowed to the\n * one member it reaches through (`SyncKvStorage::getSqliteKv`).\n */\nexport interface SyncKvStorageOwner {\n getSqliteKv(): SqliteKv;\n}\n\n/** ← `SyncKvStorage::ListOptions`, which is `ListOptions` minus the two gate flags. */\nexport type SyncKvListOptions = {\n start?: string;\n startAfter?: string;\n end?: string;\n prefix?: string;\n reverse?: boolean;\n limit?: number;\n};\n\nexport class SyncKvStorage implements globalThis.SyncKvStorage {\n readonly #ctx: IoContext;\n readonly #owner: SyncKvStorageOwner;\n\n constructor(ctx: IoContext, owner: SyncKvStorageOwner) {\n this.#ctx = ctx;\n this.#owner = owner;\n }\n\n get<T = unknown>(key: string): T | undefined {\n requireInputLock(this.#ctx, \"kv.get()\");\n const value = this.#owner.getSqliteKv().get(key);\n if (value === undefined) return undefined;\n return deserializeValue(key, value) as T;\n }\n\n /**\n * ← `SyncKvStorage::list`, which reuses `compileListOptions` — \"This is public\n * so that SyncKvStorage can reuse it.\"\n */\n list<T = unknown>(options?: SyncKvListOptions): Iterable<[string, T]> {\n requireInputLock(this.#ctx, \"kv.list()\");\n const compiled = compileListOptions(options);\n if (compiled === undefined) {\n // Key range is empty. Upstream allocates a cursor over a null query for exactly this.\n return { [Symbol.iterator]: () => emptyIterator<T>() };\n }\n\n const cursor = this.#owner\n .getSqliteKv()\n .list(compiled.start, compiled.end, compiled.limit, compiled.reverse ? \"REVERSE\" : \"FORWARD\");\n return { [Symbol.iterator]: () => listIterator<T>(cursor) };\n }\n\n put<T>(key: string, value: T): void {\n requireInputLock(this.#ctx, \"kv.put()\");\n this.#owner.getSqliteKv().put(key, serializeValue(key, value));\n }\n\n delete(key: string): boolean {\n requireInputLock(this.#ctx, \"kv.delete()\");\n return this.#owner.getSqliteKv().delete(key);\n }\n}\n\n/** ← `SyncKvStorage::listNext`, whose cancellation branch is the reason it is not a plain loop. */\nfunction listIterator<T>(cursor: SqliteKvListCursor): IterableIterator<[string, T]> {\n const iterator: IterableIterator<[string, T]> = {\n [Symbol.iterator]: () => iterator,\n next: (): IteratorResult<[string, T]> => {\n const pair = cursor.next();\n if (pair !== undefined) {\n return { done: false, value: [pair.key, deserializeValue(pair.key, pair.value) as T] };\n }\n if (cursor.wasCanceled()) {\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 return { done: true, value: undefined };\n },\n };\n return iterator;\n}\n\nfunction emptyIterator<T>(): IterableIterator<[string, T]> {\n const iterator: IterableIterator<[string, T]> = {\n [Symbol.iterator]: () => iterator,\n next: (): IteratorResult<[string, T]> => ({ done: true, value: undefined }),\n };\n return iterator;\n}\n","/**\n * ← workerd `src/workerd/api/actor-state.{h,c++}`\n *\n * The JS-facing storage objects: `DurableObjectStorageOperations` and its two\n * subclasses, `DurableObjectFacets`, and `DurableObjectState`. Everything below\n * this file is reached through one of them.\n *\n * **`DurableObjectStorage` satisfies workers-types with no cast (§2.4).** That\n * was checked rather than asserted, and two shapes here exist only because it\n * has to: `sql.Cursor` and `sql.Statement` must be constructible with no\n * arguments (see `sql.ts`), and `storage.kv` is required, which is why\n * `api/sync-kv.ts` exists at all. The narrowings that remain are all one thing —\n * `get<T>` returns the caller's claim about the shape of a value SQLite handed\n * back as bytes, which no check can confirm and which upstream states the same\n * way, as a `jsg::JsRef<jsg::JsValue>` behind a `JSG_TS_OVERRIDE`'d\n * `Promise<T>`. There is no `as unknown as` anywhere in this layer.\n *\n * **Every throw is synchronous, including from the promise-returning methods.**\n * That is upstream's: a `JSG_REQUIRE` inside a method returning `jsg::Promise`\n * throws into the isolate before the promise exists, so `put(k, undefined)`\n * throws rather than rejecting. The same goes for a value that will not decode,\n * because §1.4 makes the SQLite path take `transformCacheResult`'s value arm and\n * run the decoder synchronously.\n *\n * **What the input gate does and does not do here.** Every entry point calls\n * `requireInputLock` — see its comment in `io/io-context.ts`, which is the one\n * place this package decides what an empty invocation stack means. Nothing else\n * takes a lock: a read returns a value, a write returns a resolved promise, and\n * `atCheckpointEnd` is what keeps the whole chain inside one transaction\n * (§1.7.1). The two exceptions are upstream's own — `sync()` and the bookmark\n * pair release the gate via `awaitIo`, and `transaction()` takes a critical\n * section.\n *\n * **Decision 2's branch has one reachable site**, and it is not where upstream's\n * is. `transformCacheResult` branches on `allowConcurrency` because upstream's\n * `ActorCacheOps` returns `kj::OneOf<T, kj::Promise<T>>`; §1.4 measures that the\n * SQLite arm is always the immediate one, so Section 4 collapsed the `OneOf` and\n * the branch has nothing to select between. `transformMaybeBackpressure` keeps\n * it, because `DeleteAllResults.backpressure` is still a promise in\n * `io/actor-cache.ts`. Both helpers are kept under upstream's names so the\n * question \"where did `allowConcurrency` go\" is answered by reading them.\n *\n * Not ported, because the substrate has no equivalent: Hibernatable WebSockets,\n * which is the whole reason `DurableObjectState`'s eight WebSocket methods are\n * named throwing stubs; V8's private wire bytes, replaced by a browser-safe\n * structured-clone encoding with the same public value semantics; the billing\n * counters\n * (`billingUnits`, `ActorObserver`, `updateStorageWriteUnit`) and the trace\n * spans, both already absent throughout; `enableSql`, a workerd namespace option\n * that exists to simulate a non-SQLite Durable Object; and `ReplicaActorOutgoingFactory`,\n * whose replication half is a named boundary in `io/actor-cache.ts`.\n *\n * Spec: §1.4, §1.5, §1.10, §2.4, §2.5, decisions 2, 4 and 14 in\n * docs/decisions.md.\n */\n\nimport {\n deserialize as deserializeStructuredClone,\n serialize as serializeStructuredClone,\n} from \"@ungap/structured-clone\";\nimport type {\n ActorCacheInterface,\n ActorCacheOps,\n ActorCacheTransaction,\n GetResultList,\n ReadOptions,\n WriteOptions,\n} from \"../io/actor-cache\";\nimport type { IoContext } from \"../io/io-context\";\nimport { requireInputLock, setUserErrorDetail } from \"../io/io-context\";\nimport type { FacetManager, FacetStartInfo } from \"../io/worker\";\nimport type { SqliteKv } from \"../util/sqlite-kv\";\nimport type { SqliteDatabase } from \"../util/sqlite\";\nimport { DurableObjectClass } from \"./actor\";\nimport { LoopbackColoLocalActorNamespace, LoopbackDurableObjectNamespace } from \"./export-loopback\";\nimport type { ActorScopeBindings } from \"./global-scope\";\nimport { SqlStorage } from \"./sql\";\nimport { SyncKvStorage } from \"./sync-kv\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← `MAX_FACET_NAME_LENGTH` / `MAX_FACET_TREE_DEPTH`\n * (`actor-state.c++:943,947`), in the anonymous namespace beside the facet code\n * that enforces them. The scaffolding had them in `server/`, which is neither\n * where upstream puts them nor where they are checked.\n */\nexport const FACET_NAME_MAX_LENGTH = 256;\n/** Root is at depth 0, so the deepest allowed facet is at depth 3. */\nexport const FACET_TREE_MAX_DEPTH = 4;\n\n/**\n * The substrate boundary named in the package README: Hibernatable WebSockets\n * exist so the platform can evict an actor while keeping its sockets open, and\n * Chrome exposes no equivalent lifecycle. Under this repo's fail-closed tenet\n * the throw IS the specified behaviour, which is why §2.5 orders the four\n * silent no-op stubs beside it replaced.\n */\nexport const HIBERNATION_UNIMPLEMENTED_MESSAGE =\n \"Hibernatable WebSockets are not available in this runtime: they exist so the platform can \" +\n \"evict a Durable Object while keeping its sockets open, and there is no equivalent lifecycle \" +\n \"to be faithful to.\";\n\n/**\n * ← what falls off the end of `DurableObjectFacets::get`'s class switch\n * (`actor-state.c++:1029-1043`).\n *\n * Upstream accepts three things as `FacetStartupOptions.class`: a bare\n * `DurableObjectClass`, a `LoopbackDurableObjectNamespace`, or a\n * `LoopbackColoLocalActorNamespace`, unwrapping the last two through\n * `getClass()`. All three are ported — the loopback pair by\n * `api/export-loopback.ts` — and `KJ_UNREACHABLE` is the fourth case there\n * because JSG has already refused anything else while unwrapping the\n * `kj::OneOf`. The check has to be written here because\n * `@cloudflare/workers-types` declares `interface DurableObjectClass<_T> {}`,\n * which every object satisfies, so nothing refuses it before the method body.\n */\nexport const FACET_CLASS_UNSUPPORTED_MESSAGE =\n \"facets.get() was given a class this runtime cannot resolve. `class` must be a \" +\n \"DurableObjectClass, a LoopbackDurableObjectNamespace or a LoopbackColoLocalActorNamespace — \" +\n \"which is what a ctx.exports entry for a Durable Object class is.\";\n\n/** ← `DurableObjectStorageOperations::OpName`. Named only where an error quotes them. */\nconst OP_GET = \"get()\";\nconst OP_GET_ALARM = \"getAlarm()\";\nconst OP_LIST = \"list()\";\nconst OP_PUT = \"put()\";\nconst OP_PUT_ALARM = \"setAlarm()\";\nconst OP_DELETE = \"delete()\";\nconst OP_DELETE_ALARM = \"deleteAlarm()\";\nconst OP_ROLLBACK = \"rollback()\";\n\n/** The key immediately after `k` in byte order is `k` plus this. */\nconst NULL_CHARACTER = \"\\u0000\";\n/** ← the `0xff` upstream strips from the tail of a prefix, in UTF-16 code units. */\nconst MAX_CODE_UNIT = 0xffff;\n\n// =======================================================================================\n// The value codec\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n/** A byte JSON could never begin with, `DO`, and the local codec version. */\nconst VALUE_CODEC_HEADER = new Uint8Array([0, 0x44, 0x4f, 1]);\n\n/**\n * ← `serializeV8Value`. The wire bytes differ because V8's serializer is not\n * available in browsers; the public structured-clone value semantics do not.\n * The short header keeps the new representation unambiguous while old JSON rows\n * remain readable.\n */\nexport function serializeValue(_key: string, value: unknown): Uint8Array {\n const body = textEncoder.encode(JSON.stringify(serializeStructuredClone(value)));\n const encoded = new Uint8Array(VALUE_CODEC_HEADER.byteLength + body.byteLength);\n encoded.set(VALUE_CODEC_HEADER);\n encoded.set(body, VALUE_CODEC_HEADER.byteLength);\n return encoded;\n}\n\n/**\n * ← `deserializeV8Value`.\n *\n * Upstream logs \"the key (to help find the data in the database if it hasn't\n * been deleted), the length of the value, and the first three bytes of the value\n * (which is just the v8-internal version header and the tag that indicates the\n * type of the value, but not its contents)\". Our four-byte header carries only\n * a marker and version for the same reason.\n */\nexport function deserializeValue(key: string, buffer: Uint8Array): unknown {\n if (buffer.byteLength === 0) {\n throw new Error(`unexpectedly empty value buffer; key = ${key}`);\n }\n try {\n const structured = VALUE_CODEC_HEADER.every((byte, index) => buffer[index] === byte);\n const bytes = structured ? buffer.subarray(VALUE_CODEC_HEADER.byteLength) : buffer;\n const parsed = JSON.parse(textDecoder.decode(bytes)) as unknown;\n return structured\n ? deserializeStructuredClone(parsed as ReturnType<typeof serializeStructuredClone>)\n : parsed;\n } catch (exception) {\n throw new Error(\n \"actor storage deserialization failed: failed to deserialize stored value; \" +\n `key = ${key}; size = ${buffer.byteLength}`,\n { cause: exception },\n );\n }\n}\n\n/** ← `deserializeMaybeV8Value`. */\nfunction deserializeMaybeValue(key: string, buffer: Uint8Array | undefined): unknown {\n return buffer === undefined ? undefined : deserializeValue(key, buffer);\n}\n\n// =======================================================================================\n// The option transforms\n\n/**\n * ← `transformCacheResult` and `transformCacheResultWithCacheStatus`\n * (`actor-state.c++:49-101`), with the arm that cannot happen removed.\n *\n * Upstream's body is a two-arm switch on `kj::OneOf<T, kj::Promise<T>>`, and the\n * `allowConcurrency` branch lives in the promise arm. §1.4 measures that a\n * SQLite-backed actor returns the immediate arm at every call site, so Section 4\n * collapsed the `OneOf` to `T` and there is no promise left to await — and\n * therefore no gate decision to make. The name is kept so a reader comparing the\n * two files finds the answer here rather than inferring an omission. The\n * `WithCacheStatus` variant differs only in a `cached` flag feeding billing\n * counters that have no port, so the two collapse to one function.\n */\nfunction transformCacheResult<T, R>(value: T, func: (value: T) => R): Promise<R> {\n return Promise.resolve(func(value));\n}\n\n/**\n * ← `transformMaybeBackpressure` (`actor-state.c++:103-119`). THIS is decision\n * 2's live site: `DeleteAllResults.backpressure` is still `Promise<void> |\n * undefined`, so the branch has something to select between.\n *\n * Upstream's own note, kept because it is the reason the flag is threaded here\n * at all: \"In practice `allowConcurrency` will have no effect on a backpressure\n * promise since backpressure blocks everything anyway, but we pass the option\n * through for consistency in case of future changes.\"\n */\nfunction transformMaybeBackpressure(\n ctx: IoContext,\n options: { readonly allowConcurrency?: boolean },\n maybeBackpressure: Promise<void> | undefined,\n): Promise<void> {\n if (maybeBackpressure === undefined) return Promise.resolve();\n if (options.allowConcurrency === true) return ctx.awaitIo(maybeBackpressure);\n return ctx.awaitIoWithInputLock(maybeBackpressure, () => {});\n}\n\n// =======================================================================================\n// compileListOptions\n\n/** ← `DurableObjectStorageOperations::CompiledListOptions`. */\nexport type CompiledListOptions = {\n readonly start: string;\n readonly end: string | undefined;\n readonly reverse: boolean;\n readonly limit: number | undefined;\n};\n\n/**\n * ← `DurableObjectStorageOperations::compileListOptions`\n * (`actor-state.c++:314-417`). Returns undefined if the list operation would\n * provably return no results. Public because `SyncKvStorage` reuses it, exactly\n * as upstream's comment says it must.\n *\n * Two translations. `startAfter` gains ONE null character where upstream's\n * `kj::String` gains two, because the second of upstream's is the terminator and\n * a JS string has none. And every comparison here is on UTF-16 code units where\n * upstream's is on UTF-8 bytes, while the range the database actually applies is\n * SQLite's `BINARY` collation over UTF-8 — the two orders agree for every key\n * outside the astral planes, and a key that mixes astral characters with a\n * prefix can land on the wrong side of a clamp this function computes.\n */\nexport function compileListOptions(\n options: DurableObjectListOptions | undefined,\n): CompiledListOptions | undefined {\n let start = \"\";\n let end: string | undefined;\n let reverse = false;\n let limit: number | undefined;\n\n if (options !== undefined) {\n if (options.start !== undefined) {\n if (options.startAfter !== undefined) {\n throw new TypeError(\"list() cannot be called with both start and startAfter values.\");\n }\n start = options.start;\n }\n if (options.startAfter !== undefined) {\n // Convert an exclusive startAfter into an inclusive start key, so the implementation below\n // does not have to handle both. ONE null character, not upstream's two: the second of\n // upstream's is `kj::String`'s terminator, and a JS string has none.\n start = options.startAfter + NULL_CHARACTER;\n }\n if (options.end !== undefined) end = options.end;\n if (options.reverse !== undefined) reverse = options.reverse;\n if (options.limit !== undefined) {\n if (!(options.limit > 0)) throw new TypeError(\"List limit must be positive.\");\n limit = options.limit;\n }\n\n const prefix = options.prefix;\n if (prefix !== undefined && prefix.length > 0) {\n // Let's clamp `start` and `end` to include only keys with the given prefix.\n if (start < prefix) {\n // `start` is before `prefix`, so listing should actually start at `prefix`.\n start = prefix;\n } else if (start.startsWith(prefix)) {\n // `start` is within the prefix, so need not be modified.\n } else {\n // `start` comes after the last value with the prefix, so there's no overlap.\n return undefined;\n }\n\n const keyAfterPrefix = firstKeyAfterPrefix(prefix);\n if (keyAfterPrefix === undefined) {\n // The prefix is a run of maximal code units, so it includes the entire key space through\n // the last possible key. Hence there is no end — but an end specified earlier still holds.\n } else if (end === undefined) {\n // We didn't have any end set, so use the end of the prefix range.\n end = keyAfterPrefix;\n } else if (end <= prefix) {\n // No keys could possibly match both the end and the prefix.\n return undefined;\n } else if (end.startsWith(prefix)) {\n // `end` is within the prefix, so need not be modified.\n } else {\n // `end` comes after all keys with the prefix, so stop at the end of the prefix.\n end = keyAfterPrefix;\n }\n }\n }\n\n if (end !== undefined && end <= start) {\n // Key range is empty.\n return undefined;\n }\n\n return { start, end, reverse, limit };\n}\n\n/**\n * ← the `keyAfterPrefix` vector: strip maximal trailing units, then increment.\n *\n * Returns undefined when the prefix is nothing but maximal units, which is\n * upstream's \"the prefix is a string of some number of 0xff bytes, so includes\n * the entire key space up through the last possible key\".\n */\nfunction firstKeyAfterPrefix(prefix: string): string | undefined {\n let head = prefix;\n while (head.length > 0 && head.charCodeAt(head.length - 1) === MAX_CODE_UNIT) {\n head = head.slice(0, -1);\n }\n if (head.length === 0) return undefined;\n return head.slice(0, -1) + String.fromCharCode(head.charCodeAt(head.length - 1) + 1);\n}\n\n// =======================================================================================\n// DurableObjectStorageOperations\n\n/**\n * ← `DurableObjectStorageOperations`. \"Common implementation of\n * DurableObjectStorage and DurableObjectTransaction. This class is designed to\n * be used as a mixin.\"\n */\nexport abstract class DurableObjectStorageOperations {\n protected readonly ctx: IoContext;\n\n constructor(ctx: IoContext) {\n this.ctx = ctx;\n }\n\n protected abstract getCache(op: string): ActorCacheOps;\n\n /** Whether to skip caching and allow concurrency on all operations. */\n protected useDirectIo(): boolean {\n return false;\n }\n\n /**\n * ← `configureOptions`. Both subclasses answer `useDirectIo()` false, so this\n * is the identity today; it is upstream's hook and the only place the two\n * flags are forced on.\n */\n protected configureOptions<T extends { allowConcurrency?: boolean; noCache?: boolean }>(\n options: T,\n ): T {\n if (!this.useDirectIo()) return options;\n return { ...options, allowConcurrency: true, noCache: true };\n }\n\n get<T = unknown>(key: string, options?: DurableObjectGetOptions): Promise<T | undefined>;\n get<T = unknown>(keys: string[], options?: DurableObjectGetOptions): Promise<Map<string, T>>;\n get<T = unknown>(\n keyOrKeys: string | string[],\n maybeOptions?: DurableObjectGetOptions,\n ): Promise<T | undefined> | Promise<Map<string, T>> {\n requireInputLock(this.ctx, OP_GET);\n const options = this.configureOptions({ ...maybeOptions });\n if (typeof keyOrKeys === \"string\") return this.#getOne<T>(keyOrKeys, options);\n return this.#getMultiple<T>(keyOrKeys, options);\n }\n\n getAlarm(maybeOptions?: DurableObjectGetAlarmOptions): Promise<number | null> {\n requireInputLock(this.ctx, OP_GET_ALARM);\n // Even if we do not have an alarm handler, we might once have had one. It's fine to return\n // whatever a previous alarm setting or a falsy result.\n const options = this.configureOptions({ ...maybeOptions, noCache: false });\n return transformCacheResult(this.getCache(OP_GET_ALARM).getAlarm(options), (date) => date);\n }\n\n list<T = unknown>(maybeOptions?: DurableObjectListOptions): Promise<Map<string, T>> {\n requireInputLock(this.ctx, OP_LIST);\n const compiled = compileListOptions(maybeOptions);\n if (compiled === undefined) return Promise.resolve(new Map<string, T>());\n\n const options = this.configureOptions({ ...maybeOptions });\n const cache = this.getCache(OP_LIST);\n const result = compiled.reverse\n ? cache.listReverse(compiled.start, compiled.end, compiled.limit, options)\n : cache.list(compiled.start, compiled.end, compiled.limit, options);\n return transformCacheResult(result, (rows) => listResultsToMap<T>(rows));\n }\n\n put<T>(key: string, value: T, options?: DurableObjectPutOptions): Promise<void>;\n put<T>(entries: Record<string, T>, options?: DurableObjectPutOptions): Promise<void>;\n put<T>(\n keyOrEntries: string | Record<string, T>,\n valueOrOptions?: T | DurableObjectPutOptions,\n maybeOptions?: DurableObjectPutOptions,\n ): Promise<void> {\n requireInputLock(this.ctx, OP_PUT);\n // The second parameter carries a value in one overload and the options bag in the other, and\n // which it is follows from the first — so the two narrowings below are the discrimination\n // upstream does with `optionsTypeHandler.tryUnwrap`, made by testing the parameter that\n // actually decides rather than the one that is ambiguous.\n if (typeof keyOrEntries === \"string\") {\n if (valueOrOptions === undefined) {\n throw new TypeError(\"put() called with undefined value.\");\n }\n return this.#putOne(\n keyOrEntries,\n valueOrOptions as T,\n this.configureOptions({ ...maybeOptions }),\n );\n }\n return this.#putMultiple(\n keyOrEntries,\n this.configureOptions({ ...(valueOrOptions as DurableObjectPutOptions | undefined) }),\n );\n }\n\n delete(key: string, options?: DurableObjectPutOptions): Promise<boolean>;\n delete(keys: string[], options?: DurableObjectPutOptions): Promise<number>;\n delete(\n keyOrKeys: string | string[],\n maybeOptions?: DurableObjectPutOptions,\n ): Promise<boolean> | Promise<number> {\n requireInputLock(this.ctx, OP_DELETE);\n const options = this.configureOptions({ ...maybeOptions });\n if (typeof keyOrKeys === \"string\") {\n return transformCacheResult(\n this.getCache(OP_DELETE).delete(keyOrKeys, options),\n (deleted) => deleted,\n );\n }\n return transformCacheResult(\n this.getCache(OP_DELETE).deleteMultiple(keyOrKeys, options),\n (count) => count,\n );\n }\n\n setAlarm(scheduledTime: number | Date, maybeOptions?: DurableObjectSetAlarmOptions): Promise<void> {\n requireInputLock(this.ctx, OP_PUT_ALARM);\n const when = scheduledTime instanceof Date ? scheduledTime.getTime() : scheduledTime;\n if (!(when > 0)) {\n throw new TypeError(\"setAlarm() cannot be called with an alarm time <= 0\");\n }\n\n // \"This doesn't check if we have an alarm handler per say. It checks if we have an initialized\n // (post-ctor) JS durable object with an alarm handler.\"\n this.ctx.getActorOrThrow().assertCanSetAlarm();\n\n const options = this.configureOptions({ ...maybeOptions, noCache: false });\n\n // \"We fudge times set in the past to Date.now() to ensure that any one user can't DDOS the\n // alarm polling system by putting dates far in the past and therefore getting sorted earlier by\n // the index. This also ensures uniqueness of alarm times (which is required for correctness).\"\n this.getCache(OP_PUT_ALARM).setAlarm(Math.max(when, this.ctx.now()), options);\n return Promise.resolve();\n }\n\n deleteAlarm(maybeOptions?: DurableObjectSetAlarmOptions): Promise<void> {\n requireInputLock(this.ctx, OP_DELETE_ALARM);\n // Even if we do not have an alarm handler, we might once have had one. It's fine to remove that\n // alarm or noop on the absence of one.\n const options = this.configureOptions({ ...maybeOptions, noCache: false });\n this.getCache(OP_DELETE_ALARM).setAlarm(null, options);\n return Promise.resolve();\n }\n\n #getOne<T>(key: string, options: ReadOptions): Promise<T | undefined> {\n const value = this.getCache(OP_GET).get(key, options);\n return transformCacheResult(value, (bytes) => deserializeMaybeValue(key, bytes) as T | undefined);\n }\n\n #getMultiple<T>(keys: string[], options: ReadOptions): Promise<Map<string, T>> {\n const result = this.getCache(OP_GET).getMultiple(keys, options);\n return transformCacheResult(result, (rows) => listResultsToMap<T>(rows));\n }\n\n #putOne<T>(key: string, value: T, options: WriteOptions): Promise<void> {\n this.getCache(OP_PUT).put(key, serializeValue(key, value), options);\n return Promise.resolve();\n }\n\n #putMultiple<T>(entries: Record<string, T>, options: WriteOptions): Promise<void> {\n const pairs: { key: string; value: Uint8Array }[] = [];\n for (const [key, value] of Object.entries(entries)) {\n // \"We silently drop fields with value=undefined in putMultiple. There aren't many good\n // options here, as deleting an undefined field is confusing, throwing could break otherwise\n // working code, and a stray undefined here or there is probably closer to what the user\n // desires.\"\n if (value === undefined) continue;\n pairs.push({ key, value: serializeValue(key, value) });\n }\n this.getCache(OP_PUT).putMultiple(pairs, options);\n return Promise.resolve();\n }\n}\n\n/** ← `listResultsToMap` and `getMultipleResultsToMap`, minus the billing halves. */\nfunction listResultsToMap<T>(rows: GetResultList): Map<string, T> {\n const map = new Map<string, T>();\n for (const entry of rows) {\n map.set(entry.key, deserializeValue(entry.key, entry.value) as T);\n }\n return map;\n}\n\n// =======================================================================================\n// DurableObjectStorage\n\n/**\n * The engine `DurableObjectStorage` drives.\n *\n * Upstream holds an `ActorCacheInterface` and reaches `getSqliteDatabase()` /\n * `getSqliteKv()` through it, both `kj::Maybe`s that are non-null exactly when\n * the actor is SQLite-backed — which here it always is. `transactionSync` is the\n * third member and is one layer lower than upstream's for the reason\n * `io/actor-sqlite.ts` records: the savepoint depth counter and `notifyWrite`\n * both live there, so this file's is a one-line forward the way\n * `blockConcurrencyWhile` already is.\n */\nexport type StorageCache = ActorCacheInterface & {\n getSqliteDatabase(): SqliteDatabase;\n getSqliteKv(): SqliteKv;\n transactionSync<T>(callback: () => T): T;\n};\n\nexport class DurableObjectStorage\n extends DurableObjectStorageOperations\n implements globalThis.DurableObjectStorage\n{\n readonly #cache: StorageCache;\n #sql: SqlStorage | undefined;\n #kv: SyncKvStorage | undefined;\n\n constructor(ctx: IoContext, cache: StorageCache) {\n super(ctx);\n this.#cache = cache;\n }\n\n /** ← `DurableObjectStorage::getActorCacheInterface`, which `DurableObjectState::abort` needs. */\n getActorCacheInterface(): StorageCache {\n return this.#cache;\n }\n\n /** ← `DurableObjectStorage::getSqliteDb`. Always SQLite-backed here; see the header. */\n getSqliteDb(): SqliteDatabase {\n return this.#cache.getSqliteDatabase();\n }\n\n /** ← `DurableObjectStorage::getSqliteKv`. */\n getSqliteKv(): SqliteKv {\n return this.#cache.getSqliteKv();\n }\n\n protected override getCache(): ActorCacheOps {\n return this.#cache;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(sql, getSql)`. */\n get sql(): SqlStorage {\n this.#sql ??= new SqlStorage(this.ctx, this);\n return this.#sql;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(kv, getKv)`. */\n get kv(): SyncKvStorage {\n this.#kv ??= new SyncKvStorage(this.ctx, this);\n return this.#kv;\n }\n\n /**\n * ← `DurableObjectStorage::deleteAll`.\n *\n * `deleteAlarm` is upstream's `FeatureFlags::get(js).getDeleteAllDeletesAlarm()`,\n * a compatibility flag that exists so Workers published before it keep the old\n * behaviour. A runtime with no deployed history takes the current behaviour.\n */\n deleteAll(maybeOptions?: DurableObjectPutOptions): Promise<void> {\n requireInputLock(this.ctx, \"deleteAll()\");\n const options = this.configureOptions({ ...maybeOptions });\n const result = this.#cache.deleteAll(options, { deleteAlarm: true });\n return transformMaybeBackpressure(this.ctx, options, result.backpressure);\n }\n\n /**\n * ← `DurableObjectStorage::transaction`.\n *\n * The critical section is load bearing and upstream says why: \"the call to\n * `startTransaction()` is when the SQLite-backed implementation will actually\n * invoke `BEGIN TRANSACTION`, so it's important that we're inside the\n * blockConcurrencyWhile block before that point so we don't accidentally catch\n * some other asynchronous event in our transaction.\"\n *\n * The exception is packed into the result rather than thrown out of the\n * section, and then rethrown outside it. Upstream's reason: \"We don't actually\n * want to reset the object, we only want to roll back the transaction and\n * propagate the exception.\" A throw out of a critical section permanently\n * breaks the input gate (§1.5), so a failing transaction callback would\n * destroy the actor.\n */\n transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T> {\n requireInputLock(this.ctx, \"transaction()\");\n type TxnResult =\n | { readonly isError: false; readonly value: T }\n | { readonly isError: true; readonly exception: unknown };\n\n return this.ctx\n .blockConcurrencyWhile(async (): Promise<TxnResult> => {\n const txn = new DurableObjectTransaction(this.ctx, this.#cache.startTransaction());\n try {\n const value = await closure(txn);\n txn.maybeCommit();\n return { isError: false, value };\n } catch (exception) {\n txn.maybeRollback();\n return { isError: true, exception };\n }\n })\n .then((result) => {\n if (result.isError) throw result.exception;\n return result.value;\n });\n }\n\n /** ← `DurableObjectStorage::transactionSync`, a forward for the reason above. */\n transactionSync<T>(callback: () => T): T {\n requireInputLock(this.ctx, \"transactionSync()\");\n return this.#cache.transactionSync(callback);\n }\n\n /**\n * ← `DurableObjectStorage::sync`.\n *\n * Upstream's `awaitIo` rather than `awaitIoWithInputLock`, which is the one\n * storage method that deliberately opens the gate: \"we're merely checking if\n * we have any pending or in-flight operations, and providing a promise that\n * resolves when they succeed.\"\n */\n sync(): Promise<void> {\n requireInputLock(this.ctx, \"sync()\");\n return this.ctx.awaitIo(this.#cache.onNoPendingFlush());\n }\n\n /**\n * Real, not a boundary: `ActorSqlite`'s is \"an ersatz implementation that's\n * good enough for local dev with D1's Session API\", built on the metadata\n * table's local-development bookmark. Anything above this package that\n * surfaces it to an application should know it is a counter and not a\n * recovery point — as it is on workerd.\n */\n getCurrentBookmark(): Promise<string> {\n requireInputLock(this.ctx, \"getCurrentBookmark()\");\n return this.ctx.awaitIo(this.#cache.getCurrentBookmark());\n }\n\n waitForBookmark(bookmark: string): Promise<void> {\n requireInputLock(this.ctx, \"waitForBookmark()\");\n return this.ctx.awaitIo(this.#cache.waitForBookmark(bookmark));\n }\n\n /** Substrate boundary: point-in-time recovery. Upstream reaches the cache directly, as this does. */\n getBookmarkForTime(timestamp: number | Date): Promise<string> {\n return this.#cache.getBookmarkForTime(\n timestamp instanceof Date ? timestamp.getTime() : timestamp,\n );\n }\n\n /** Substrate boundary: point-in-time recovery. */\n onNextSessionRestoreBookmark(bookmark: string): Promise<string> {\n return this.#cache.onNextSessionRestoreBookmark(bookmark);\n }\n\n /** Substrate boundary: replication. */\n ensureReplicas(): void {\n this.#cache.ensureReplicas();\n }\n\n /** Substrate boundary: replication. */\n disableReplicas(): void {\n this.#cache.disableReplicas();\n }\n\n /**\n * ← `DurableObjectStorage::getPrimary` / `isReplica`. `maybePrimary` is set\n * only by the replica constructor, and nothing constructs a replica here, so\n * these answer upstream's own non-replica case rather than a stubbed one.\n */\n getPrimary(): undefined {\n return undefined;\n }\n\n isReplica(): boolean {\n return false;\n }\n}\n\n// =======================================================================================\n// DurableObjectTransaction\n\nexport class DurableObjectTransaction\n extends DurableObjectStorageOperations\n implements globalThis.DurableObjectTransaction\n{\n /** Becomes undefined when committed or rolled back. */\n #cacheTxn: ActorCacheTransaction | undefined;\n #rolledBack = false;\n\n constructor(ctx: IoContext, cacheTxn: ActorCacheTransaction) {\n super(ctx);\n this.#cacheTxn = cacheTxn;\n }\n\n protected override getCache(op: string): ActorCacheOps {\n if (this.#rolledBack) throw new Error(`Cannot ${op} on rolled back transaction`);\n const txn = this.#cacheTxn;\n if (txn === undefined) {\n throw new Error(\n `Cannot call ${op} on transaction that has already committed: ` +\n \"did you move `txn` outside of the closure?\",\n );\n }\n return txn;\n }\n\n /** Called from JS. */\n rollback(): void {\n if (this.#rolledBack) return; // allow multiple calls to rollback()\n this.getCache(OP_ROLLBACK); // just for the checks\n const txn = this.#cacheTxn;\n if (txn !== undefined) {\n txn.rollback();\n // ← the `IoContext::addWaitUntil(prom.attach(mv(cacheTxn)))`, whose attach is the\n // destruction Section 1 turned into an explicit drop.\n txn.drop();\n this.#cacheTxn = undefined;\n }\n this.#rolledBack = true;\n }\n\n /** Just throws an exception saying this isn't supported. */\n deleteAll(): never {\n throw new Error(\"Cannot call deleteAll() within a transaction\");\n }\n\n /**\n * Called from the runtime, not JS, after the transaction callback has\n * completed. Does nothing if the transaction is already committed or rolled\n * back. Synchronous, because `ActorCacheTransaction::commit` is (§1.4).\n */\n maybeCommit(): void {\n const txn = this.#cacheTxn;\n if (txn === undefined) return;\n this.#cacheTxn = undefined;\n txn.commit();\n txn.drop();\n }\n\n /** Same, for the failure path. Upstream's drops the transaction, whose destructor rolls back. */\n maybeRollback(): void {\n const txn = this.#cacheTxn;\n this.#cacheTxn = undefined;\n this.#rolledBack = true;\n txn?.drop();\n }\n}\n\n// =======================================================================================\n// DurableObjectFacets\n\n/**\n * ← `requireValidFacetName` (`actor-state.c++:949-952`).\n *\n * The comparison is `name.size()` on a `kj::StringPtr`, which is **UTF-8 bytes**,\n * so it is measured in bytes here too — the same `TextEncoder` pass, for the same\n * reason, that `ColoLocalActorNamespace.get`'s `[1, 2048]` bound already costs.\n * Comparing `name.length` accepts a 256-character non-ASCII name that upstream\n * refuses, which is a bound a caller can hit.\n */\nfunction requireValidFacetName(name: string): void {\n if (textEncoder.encode(name).length > FACET_NAME_MAX_LENGTH) {\n throw new TypeError(`Facet name is too long (max ${FACET_NAME_MAX_LENGTH} characters).`);\n }\n}\n\n/**\n * ← the `KJ_SWITCH_ONEOF(options.$class)` lambda (`actor-state.c++:1029-1043`).\n *\n * Three arms, and the order matters for the same reason it does upstream: a\n * `LoopbackDurableObjectClass` *is* a `DurableObjectClass`, so it takes the bare\n * arm here exactly as JSG's `kj::OneOf` unwraps it into the first alternative.\n * The two loopback namespaces are not classes and carry one, which `getClass()`\n * hands back.\n *\n * A `ctx.exports` entry is the callable façade `api/export-loopback.ts` produces\n * rather than the instance itself, and every check below is an `instanceof` that\n * the façade's `getPrototypeOf` answers — which is why that trap exists.\n */\nfunction requireFacetClass(actorClass: unknown): DurableObjectClass {\n if (actorClass instanceof DurableObjectClass) return actorClass;\n if (actorClass instanceof LoopbackDurableObjectNamespace) return actorClass.getClass();\n if (actorClass instanceof LoopbackColoLocalActorNamespace) return actorClass.getClass();\n throw new TypeError(FACET_CLASS_UNSUPPORTED_MESSAGE);\n}\n\n/**\n * ← `DurableObjectFacets`.\n *\n * **`clone` is the fourth method, and the vendored C++ snapshot does not have\n * it.** The design record cites `actor-state.h:431-497` and\n * `server.c++:721-749`; neither line range contains it, `DurableObjectFacets`\n * there exposes exactly `get`, `abort` and `delete`, and\n * `Worker::Actor::FacetManager` has exactly `getDepth`, `getFacet`, `abortFacet`\n * and `deleteFacet`. It is real all the same: `@cloudflare/workers-types`\n * 4.20260702.1 — a month newer than the snapshot — declares\n * `clone(src: string, dst: string): void` on `DurableObjectFacets`. So the\n * signature comes from the types and the semantics from §1.10 (abort dst, delete\n * dst storage, recursive copy of the src subtree), and the orchestration is\n * `server/`'s `cloneFacet`. There is nothing upstream to check the body against,\n * which makes it the one method here with no reference — worth knowing when it\n * is wrong.\n */\nexport class DurableObjectFacets implements globalThis.DurableObjectFacets {\n readonly #ctx: IoContext;\n readonly #facetManager: FacetManager | undefined;\n readonly #parentId: string;\n\n constructor(ctx: IoContext, facetManager: FacetManager | undefined, parentId: string) {\n this.#ctx = ctx;\n this.#facetManager = facetManager;\n this.#parentId = parentId;\n }\n\n /**\n * Get a facet by name, starting it if it isn't already running.\n * `getStartupOptions` is invoked only if the facet wasn't already running.\n *\n * Returns a `Fetcher` instead of a `DurableObject` because the returned stub\n * does not have the `id` or `name` methods that a DO stub normally has.\n */\n get<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name: string,\n getStartupOptions: () => FacetStartupOptions<T> | Promise<FacetStartupOptions<T>>,\n ): Fetcher<T> {\n requireValidFacetName(name);\n const facetManager = this.#getFacetManager();\n\n if (facetManager.getDepth() + 1 >= FACET_TREE_MAX_DEPTH) {\n throw new Error(\n \"Facet nesting depth limit exceeded. The maximum depth including the root Durable \" +\n `Object is ${FACET_TREE_MAX_DEPTH}.`,\n );\n }\n\n // Where upstream reads `IoContext::current()`, which is after both checks above.\n requireInputLock(this.#ctx, \"facets.get()\");\n\n // ← `ioCtx.makeReentryCallback(...)` (`actor-state.c++:1011`), which is decision 13: without\n // it a facet started from inside blockConcurrencyWhile() would queue behind the section that\n // is waiting for it.\n const getStartInfo = this.#ctx.makeReentryCallback(async (): Promise<FacetStartInfo> => {\n const options = await getStartupOptions();\n const id = options.id;\n return {\n // ← `actorClass.getChannel(ioCtx)` (`actor-state.c++:1045`).\n actorClass: requireFacetClass(options.class).getChannel(),\n // Child inherits parent ID.\n id:\n id === undefined\n ? this.#parentId\n : typeof id === \"string\"\n ? id\n : id.name ?? id.toString(),\n };\n });\n\n return facetManager.getFacet<T>(name, getStartInfo);\n }\n\n abort(name: string, reason: unknown): void {\n requireValidFacetName(name);\n this.#getFacetManager().abortFacet(name, reason);\n }\n\n delete(name: string): void {\n requireValidFacetName(name);\n this.#getFacetManager().deleteFacet(name);\n }\n\n clone(src: string, dst: string): void {\n requireValidFacetName(src);\n requireValidFacetName(dst);\n this.#getFacetManager().cloneFacet(src, dst);\n }\n\n #getFacetManager(): FacetManager {\n const facetManager = this.#facetManager;\n if (facetManager === undefined) {\n throw new Error(\"This Durable Object does not support creating facets.\");\n }\n return facetManager;\n }\n}\n\n// =======================================================================================\n// DurableObjectState\n\nexport type DurableObjectStateOptions = {\n id: DurableObjectId;\n /** The `ctx.exports` class registry. */\n exports: Record<string, unknown>;\n props: unknown;\n storage?: DurableObjectStorage;\n /** Absent for an actor whose host offers no facets, as upstream's `kj::Maybe` is. */\n facets?: FacetManager;\n /** ← `ActorVersion`, a deployment cohort with nothing to read it here. */\n version?: { cohort?: string };\n /**\n * This actor's `ServiceWorkerGlobalScope` half — the container's own\n * `globals`. Required, unlike `storage` and `facets`: a host that offers no\n * storage is a real posture upstream has, but an actor with no gated timers\n * is not, and the failure of a missing one is an ungated timer that WORKS\n * until a continuation after it touches storage. See\n * `DurableObjectState.globals`.\n */\n globals: ActorScopeBindings;\n};\n\n/** The type passed as the first parameter to a Durable Object class's constructor. */\nexport class DurableObjectState implements globalThis.DurableObjectState {\n readonly #ctx: IoContext;\n readonly #options: DurableObjectStateOptions;\n #facets: DurableObjectFacets | undefined;\n\n constructor(ctx: IoContext, options: DurableObjectStateOptions) {\n this.#ctx = ctx;\n this.#options = options;\n }\n\n get id(): DurableObjectId {\n return this.#options.id;\n }\n\n get props(): unknown {\n return this.#options.props;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(exports, getExports)`, behind `enableCtxExports` upstream. */\n get exports(): Record<string, unknown> {\n return this.#options.exports;\n }\n\n get version(): { cohort?: string } | undefined {\n return this.#options.version;\n }\n\n /**\n * NO upstream correspondence, because upstream needs none: a\n * `ServiceWorkerGlobalScope` IS the isolate's global object there, so an\n * actor's class reaches its gated `setTimeout` by writing `setTimeout`.\n *\n * Here one realm hosts several actors, so the names on `globalThis` can only\n * be bound to one of them and a continuation cannot be asked which one it\n * belongs to. `ctx` is the one reference every Durable Object class already\n * holds and that already means exactly one actor — the constructor was handed\n * it — so it is where the scope goes. An actor's method writes\n * `this.ctx.globals.setTimeout(…)`; a free function it calls takes the scope\n * as a parameter.\n *\n * `installActorScope` still exists and is still what a host uses for a\n * dynamically-loaded Worker source, which has no `ctx` to reach through and\n * its own module scope to destructure into. The two are the same object.\n */\n get globals(): ActorScopeBindings {\n return this.#options.globals;\n }\n\n get storage(): DurableObjectStorage {\n const storage = this.#options.storage;\n if (storage === undefined) {\n throw new Error(\"This Durable Object does not have storage.\");\n }\n return storage;\n }\n\n /** ← `JSG_LAZY_INSTANCE_PROPERTY(facets, getFacets)`. */\n get facets(): DurableObjectFacets {\n this.#facets ??= new DurableObjectFacets(\n this.#ctx,\n this.#options.facets,\n this.#options.id.toString(),\n );\n return this.#facets;\n }\n\n waitUntil(promise: Promise<unknown>): void {\n this.#ctx.addWaitUntil(promise.then(() => {}));\n }\n\n /**\n * ← `DurableObjectState::blockConcurrencyWhile` (`actor-state.c++:1128-1131`),\n * which is a one-line forward and nothing else. The 30-second deadline, the\n * brokenness annotation and the never-settled promise on failure all live in\n * `IoContext::blockConcurrencyWhile`, which Section 2 already implements.\n *\n * Its precondition comes with it: `IoContext::blockConcurrencyWhile` calls\n * `getInputLock()`, which asserts, so this is reachable only from inside a\n * gated slice.\n */\n blockConcurrencyWhile<T>(callback: () => Promise<T>): Promise<T> {\n return this.#ctx.blockConcurrencyWhile(() => callback());\n }\n\n /**\n * ← `DurableObjectState::abort`. Reset the object, including breaking the\n * output gate and canceling any writes that haven't been committed yet.\n *\n * `js.terminateExecutionNow()` has no port — there is no isolate to terminate —\n * so the caller's own slice keeps running to its next await, where `IoContext`\n * refuses to re-enter.\n */\n abort(reason?: string): void {\n const description =\n reason === undefined\n ? \"broken.outputGateBroken; jsg.Error: Application called abort() to reset Durable Object.\"\n : `broken.outputGateBroken; jsg.Error: ${reason}`;\n const error = new Error(description);\n // ← `error.setDetail(jsg::EXCEPTION_IS_USER_ERROR, ...)` (`actor-state.c++:1143`). It is what\n // tells `isAlarmFailureUserError` that this reset was the application's doing, so an alarm\n // handler that aborts is retried a bounded number of times rather than forever.\n setUserErrorDetail(error);\n\n // \"Make sure we _synchronously_ break storage so that there's no chance our promise fulfilling\n // will race against the output gate, possibly allowing writes to complete before being\n // canceled.\"\n this.#options.storage?.getActorCacheInterface().shutdown(error);\n\n this.#ctx.abort(error);\n }\n\n /** ← `DurableObjectState::getPrimaryStub`. Non-null only for a replica; see the storage note. */\n get primaryStub(): undefined {\n return this.#options.storage?.getPrimary();\n }\n\n /** Substrate boundary: replication. */\n configureReadReplication(options: { mode: string }): Promise<void> {\n const storage = this.#options.storage;\n if (storage === undefined) {\n throw new TypeError(\"This actor does not support read replication.\");\n }\n if (storage.isReplica()) {\n throw new Error(\"Replica Durable Objects cannot call configureReadReplication().\");\n }\n if (options.mode !== \"auto\" && options.mode !== \"disabled\") {\n throw new TypeError(\n `configureReadReplication() called with unknown mode setting: ${options.mode}.`,\n );\n }\n return this.#ctx.awaitIo(\n storage.getActorCacheInterface().configureReadReplication(options.mode === \"auto\"),\n );\n }\n\n // -----------------------------------------------------------------\n // Hibernatable WebSockets — the substrate boundary. §2.5 orders the silent\n // no-op stubs replaced with throws, so all eight throw the same named message.\n\n acceptWebSocket(_ws: WebSocket, _tags?: string[]): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getWebSockets(_tag?: string): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n setWebSocketAutoResponse(_maybeReqResp?: WebSocketRequestResponsePair): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getWebSocketAutoResponse(): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getWebSocketAutoResponseTimestamp(_ws: WebSocket): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n setHibernatableWebSocketEventTimeout(_timeoutMs?: number): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getHibernatableWebSocketEventTimeout(): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n\n getTags(_ws: WebSocket): never {\n throw new Error(HIBERNATION_UNIMPLEMENTED_MESSAGE);\n }\n}\n","/**\n * ← workerd `src/workerd/api/http.{h,c++}` — the gating, and nothing else.\n *\n * `http.c++` is 2,400 lines of `Request`, `Response`, `Headers`, `Body`,\n * `Fetcher` and the redirect machine. None of it is ported: the substrate ships\n * all of it, to the same specification, and re-implementing WHATWG Fetch over\n * `fetch` would be the feature-subset failure the porting philosophy describes,\n * with a much larger surface than the eighty lines it saves.\n *\n * What the substrate's copy cannot have is the half that is not in the spec at\n * all: **every asynchronous step of a fetch is an io-context operation**, so on\n * workerd the code after `await res.json()` resumes holding an input lock the\n * same way the code after `await fetch(…)` does. §1.3 is the whole of it —\n * `api/http.c++` contains ten `awaitIo(` calls and zero\n * `awaitIoWithInputLock`, so an outbound request releases the input gate and its\n * continuation re-takes one.\n *\n * A `Response` is where that matters and where it is easiest to miss. `fetch`\n * itself is one `awaitIo` in `api/global-scope.ts`, which is obvious; the body\n * is a SECOND await, arbitrarily later, and a raw `Response` would resolve it\n * from a promise this package does not own. The continuation would come back\n * with an empty invocation stack and the next `ctx.storage` call would throw —\n * divergence 147, arriving from a line that looks like it only parses JSON.\n *\n * Upstream reaches the same place by construction rather than by wrapping: a\n * `Response`'s body is an `IoOwn<ReadableStream>`, and `IoOwn` is precisely \"a\n * thing that may only be touched from inside its IoContext\"\n * (`io-context.h`'s `IoOwn`/`IoPtr`/`DeleteQueue` block). There is no such\n * ownership here — GC makes a cross-context dereference impossible in the way\n * that block guards against, which is why the package does not port it — so the\n * property it produced has to be produced by the wrapper below.\n *\n * Spec: §1.3 and decision 1 in\n * docs/decisions.md.\n */\n\n/**\n * The `Body` mixin's consuming methods (`http.h`'s `Body` resource type). Each\n * one reads the whole stream, so each one is an await that has to resume gated.\n *\n * `formData` is included even though nothing in this package's consumer calls\n * it: a subset here is a hole with no error, which is the one direction this\n * layer may not be wrong in.\n */\nconst BODY_CONSUMERS = [\"arrayBuffer\", \"blob\", \"bytes\", \"formData\", \"json\", \"text\"] as const;\n\ntype IoAwaiter = {\n awaitIo<T>(promise: Promise<T>): Promise<T>;\n};\n\n/**\n * Wrap a `Request` or `Response` so every asynchronous step of reading it\n * resumes inside a gated slice.\n *\n * A `Proxy` rather than a subclass, for a reason that is the substrate's rather\n * than a preference: `Response`'s internals are exotic, `new Response(res.body)`\n * would lose `status`, `url`, `redirected` and the header casing, and a class\n * that delegated every member by hand would silently stop covering whatever the\n * platform adds next. The trap covers what has to be covered and forwards the\n * rest to the real object, bound to it, so a member this file has never heard of\n * behaves exactly as the substrate's does.\n *\n * `clone()` is wrapped too. It returns a second body owner over a tee of the\n * same stream, and an unwrapped one would be the same hole one call further out.\n */\nfunction gateBody<T extends Request | Response>(ctx: IoAwaiter, value: T): T {\n const bound = new Map<string | symbol, unknown>();\n\n return new Proxy(value, {\n get(subject, property): unknown {\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n\n if (property === \"body\") {\n const body = subject.body;\n if (body === null) return null;\n const gated = gateReadableStream(ctx, body);\n bound.set(property, gated);\n return gated;\n }\n\n if (property === \"clone\") {\n const clone = (): T => gateBody(ctx, subject.clone() as T);\n bound.set(property, clone);\n return clone;\n }\n\n if ((BODY_CONSUMERS as readonly (string | symbol)[]).includes(property)) {\n const consume = (...args: unknown[]): Promise<unknown> =>\n ctx.awaitIo(\n (subject[property as (typeof BODY_CONSUMERS)[number]] as (...a: unknown[]) => Promise<unknown>).apply(\n subject,\n args,\n ),\n );\n bound.set(property, consume);\n return consume;\n }\n\n // `headers`, `status`, `ok` and friends are accessors on the prototype that read internal\n // slots, so they have to be read with the real object as the receiver rather than the proxy.\n // A method reached this way is bound for the same reason.\n const value: unknown = Reflect.get(subject, property, subject);\n if (typeof value === \"function\") {\n const method = (value as (...a: unknown[]) => unknown).bind(subject);\n bound.set(property, method);\n return method;\n }\n return value;\n },\n });\n}\n\n/** Wrap a host-provided request so consuming or streaming its body resumes gated. */\nexport function gateRequestBody(ctx: IoAwaiter, request: Request): Request {\n return gateBody(ctx, request);\n}\n\n/** Wrap an outbound response so consuming or streaming its body resumes gated. */\nexport function gateResponseBody(ctx: IoAwaiter, response: Response): Response {\n return gateBody(ctx, response);\n}\n\n/**\n * ← the same property one layer down: a body read through `getReader()` is a\n * sequence of awaits, so each `read()` is one.\n *\n * Only the default reader is covered. A BYOB reader is refused rather than\n * passed through ungated — see `BYOB_READER_UNGATABLE_MESSAGE`.\n */\nexport const BYOB_READER_UNGATABLE_MESSAGE =\n \"getReader({ mode: 'byob' }): a BYOB reader cannot be gated by this runtime, because \" +\n \"`ReadableStream.getReader` is the only seam it has and a byte stream's `read(view)` \" +\n \"returns the caller's own buffer. Read the body through `arrayBuffer()` or a default reader.\";\n\n// Instrument the native object itself. Chromium's `Response` constructor does not recognise a\n// `Proxy` around a `ReadableStream` as `BodyInit`; it stringifies the proxy instead.\nexport function gateReadableStream<T>(ctx: IoAwaiter, stream: ReadableStream<T>): ReadableStream<T> {\n const getReader = stream.getReader.bind(stream);\n const tee = stream.tee.bind(stream);\n\n Object.defineProperties(stream, {\n getReader: {\n configurable: true,\n writable: true,\n value(options?: { mode?: string }): unknown {\n // Fail closed. A byte reader whose `read(view)` this layer cannot intercept would hand\n // its continuation back ungated, which is the exact failure this module exists to\n // prevent, and it would do it silently.\n if (options?.mode === \"byob\") throw new Error(BYOB_READER_UNGATABLE_MESSAGE);\n return gateReader(ctx, getReader());\n },\n },\n // `tee()` splits into two streams; both are bodies and both get the same treatment.\n tee: {\n configurable: true,\n writable: true,\n value(): [ReadableStream<T>, ReadableStream<T>] {\n const [a, b] = tee();\n return [gateReadableStream(ctx, a), gateReadableStream(ctx, b)];\n },\n },\n });\n\n return stream;\n}\n\nfunction gateReader<T>(\n ctx: IoAwaiter,\n reader: ReadableStreamDefaultReader<T>,\n): ReadableStreamDefaultReader<T> {\n return new Proxy(reader, {\n get(subject, property): unknown {\n if (property === \"read\") {\n return (): Promise<ReadableStreamReadResult<T>> => ctx.awaitIo(subject.read());\n }\n const value: unknown = Reflect.get(subject, property, subject);\n return typeof value === \"function\"\n ? (value as (...a: unknown[]) => unknown).bind(subject)\n : value;\n },\n });\n}\n","/**\n * ← workerd `src/workerd/api/global-scope.{h,c++}` — the alarm half, and the\n * async-primitive half `ServiceWorkerGlobalScope` exposes to an application.\n *\n * The event surface (`fetch`/`scheduled`/`trace`/`queue` handlers) still has no\n * port: that belongs to layers this package does not have. What is here is the\n * other thing that class is, and the thing a Durable Object actually reaches —\n * `JSG_METHOD(setTimeout)`, `clearTimeout`, `setInterval`, `clearInterval`,\n * `JSG_METHOD(fetch)`, and `JSG_LAZY_INSTANCE_PROPERTY(scheduler, getScheduler)`\n * (`global-scope.h:776-808`). `Scheduler` itself is `api/basics.h:781-797`; it\n * is one class with one method and it lives beside its only exposure rather than\n * in a `api/basics.ts` that would hold nothing else, since everything else in\n * that file — `Event`, `EventTarget`, `AbortController`, `AbortSignal` — the\n * substrate already provides.\n *\n * **Why this file gained a half.** Workerd's globals hold no context: each one\n * reads `IoContext::current()` at call time (`global-scope.c++:944`, `:961`,\n * `:989`, `:1160`), because acquisition is structural and every entry into the\n * isolate has already taken the lock. There is no isolate hook here, so a\n * continuation that resumes from a promise the runtime does not own comes back\n * with an empty invocation stack and its next `ctx.storage` call throws `no\n * input lock available in this context`. Every host-provided async primitive\n * therefore has to gate itself, and this is where they do.\n *\n * The three primitives take three different mechanisms, and flattening them into\n * \"wrap it in awaitIo\" would be wrong three ways:\n *\n * - **Timers** capture the critical section at the ARMING call and re-enter\n * through `ctx.run(callback, cs)` when they fire. Not `awaitIo`, deliberately\n * — see `TimeoutManager` in `io/io-context.ts` for upstream's own reason.\n * - **`fetch`** is `awaitIo` (`http.c++` has ten of them and zero\n * `awaitIoWithInputLock`), preceded by an output-gate wait so nothing departs\n * ahead of the writes it might reveal (`http.c++:1488`). §1.3.\n * - **WebSocket** is neither: `api/web-socket.ts`, because a socket is a long\n * stream of events rather than one result.\n *\n * **The context is held, not looked up, and that is the whole of the\n * enforcement substitution.** One scope per actor. See `requireOwnSlice` for\n * what happens when a facet reaches a scope that is not its own.\n *\n * Spec: §1.2, §1.3, §1.8 and decisions 1 and 16 in\n * docs/decisions.md.\n */\n\nimport {\n hasUserErrorDetail,\n isExceptionFromInputGateBroken,\n tryCurrentSlice,\n type IoContext,\n} from \"../io/io-context\";\nimport { gateResponseBody } from \"./http\";\n\n/**\n * ← `AlarmInvocationInfo` (`api/global-scope.h:386-412`): \"a jsg::Object used to\n * pass alarm invocation info to an alarm handler.\"\n *\n * `scheduledTime` is already milliseconds here where upstream converts a\n * `kj::Date` to them at construction (`global-scope.h:390`), which is the same\n * unit `@cloudflare/workers-types` declares and the same one `setAlarm` takes.\n */\nexport class AlarmInvocationInfo implements globalThis.AlarmInvocationInfo {\n readonly scheduledTime: number;\n readonly retryCount: number;\n\n constructor(scheduledTime: number, retry: number) {\n this.scheduledTime = scheduledTime;\n this.retryCount = retry;\n }\n\n get isRetry(): boolean {\n return this.retryCount > 0;\n }\n}\n\n/**\n * ← `isAlarmFailureUserError` (`api/global-scope.c++:501-515`), whose own\n * comment lists the three arms: \"Returns true if an alarm failure should count\n * against the user's retry limit. A failure is user-generated if any of: the\n * exception was explicitly tagged with EXCEPTION_IS_USER_ERROR at construction\n * time (e.g. state.abort(), exceededCpu, exceededMemory, overload queue); the\n * exception originated from user code throwing inside blockConcurrencyWhile,\n * which breaks the input gate as a secondary side-effect; the exception is a\n * plain jsg.* error without broken.* or jsg-internal.* prefixes, meaning the\n * user's handler threw directly.\"\n *\n * The first two arms port exactly: this package writes both markers itself —\n * `DurableObjectState.abort()` sets the detail, and `IoContext` annotates a\n * broken input gate with upstream's own prefix.\n *\n * **The third arm has no input here, and its default is inverted deliberately.**\n * Upstream reads it off jsg's exception tunnelling: a `jsg.Error:` prefix that\n * is neither `jsg-internal.` nor a Durable Object reset means the user's handler\n * threw. There is no tunnelling in this runtime — an `Error` out of a handler\n * carries no provenance at all — so a plain exception is reported here as NOT a\n * user error, where upstream would report it as one.\n *\n * That inversion is narrower than it sounds, and it is the safe direction. The\n * caller is\n * `shouldRetryCountsAgainstLimits = !isOutputGateBroken() || isUserGeneratedError`\n * (`global-scope.c++:624`), so for an intact actor a handler failure counts\n * whatever this answers; the only case the two readings disagree on is a handler\n * failure that arrives together with a broken output gate. Upstream counts that\n * and eventually abandons the alarm. This does not, so the alarm outlives the\n * actor's reset and is retried after the restart — which is what\n * `!tunneled.isDurableObjectReset` (`:514`) is reaching for on the arm above it\n * and what the product ranking asks for outright. A default of \"user error\"\n * would abandon exactly the alarms that most need keeping.\n */\nexport function isAlarmFailureUserError(exception: unknown): boolean {\n if (hasUserErrorDetail(exception)) return true;\n if (isExceptionFromInputGateBroken(exception)) return true;\n return false;\n}\n\n// =======================================================================================\n// The async primitives an application reaches\n\n/** ← `Scheduler::WaitOptions` (`api/basics.h:775-778`). */\nexport type SchedulerWaitOptions = { signal?: AbortSignal };\n\n/**\n * ← `Scheduler` (`api/basics.h:781-797`), whose own comment is: \"The scheduler\n * class is an emerging web platform standard API that is meant to be global and\n * provides task scheduling APIs. We currently only implement a subset of the API\n * that is being defined.\"\n *\n * `wait` is \"essentially an awaitable alternative to setTimeout()\", and upstream\n * implements it as exactly that — `setTimeoutInternal` onto the same timeout\n * manager (`basics.c++:1007`), which is why it inherits the gating rather than\n * having any of its own.\n */\nexport class Scheduler {\n readonly #scope: ActorGlobalScope;\n\n constructor(scope: ActorGlobalScope) {\n this.#scope = scope;\n }\n\n /** ← `Scheduler::wait` (`basics.c++:989-1020`). */\n wait(delay: number, options?: SchedulerWaitOptions): Promise<void> {\n // ← the pre-check: an already-aborted signal rejects without arming anything.\n if (options?.signal?.aborted === true) {\n return Promise.reject(abortReasonOf(options.signal));\n }\n\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n let id: number;\n try {\n id = this.#scope.setTimeout(() => {\n resolve();\n }, delay);\n } catch (exception) {\n // The exception is unchanged; only its shape is. A method that returns a promise and\n // sometimes throws synchronously instead escapes the caller's `.catch` — the same reason\n // `IoContext.awaitIoWithInputLock` reshapes `getInputLock()`'s throw. The one thing that\n // can throw here is the foreign-slice refusal, and it must reach a caller that only wrote\n // `await scheduler.wait(…).catch(…)`.\n return Promise.reject(exception);\n }\n\n // ← the `signal` branch below `paf`: aborting clears the timeout and rejects.\n options?.signal?.addEventListener(\"abort\", () => {\n this.#scope.clearTimeout(id);\n reject(abortReasonOf(options.signal));\n });\n\n return promise;\n }\n\n /**\n * NO upstream correspondence: `scheduler.yield()` is the Prioritized Task\n * Scheduling API's, which workerd does not implement — `Scheduler` above has\n * exactly one `JSG_METHOD`. It is here because Chrome ships a `scheduler`\n * global in workers that DOES have `yield` and no `wait`, so a scope that\n * replaced Chrome's and dropped `yield` would break page-shaped code that a\n * Durable Object never runs but a shared worker global might. A zero-delay\n * gated timer is the closest honest reading and it keeps the lock property.\n */\n yield(): Promise<void> {\n return this.wait(0);\n }\n}\n\n/**\n * ← `SubtleCrypto` (`api/crypto.h`), whose every method is a `jsg::Promise`\n * built inside the isolate's `IoContext` — so on workerd a continuation after\n * `await crypto.subtle.digest(...)` holds the input lock, and nothing has to say\n * so.\n *\n * Here `globalThis.crypto` is the PLATFORM's, and its promise is one this\n * package does not own. The vendored `agents` package hashes inside a method\n * that then writes, so an ungated `digest` made every routine mutation throw at\n * its own `setState` — three frames below the await that lost the lock, with\n * nothing naming the cause. `conformance/suite/gates.spec.ts` is the row that\n * settles it against workerd.\n *\n * `getRandomValues` and `randomUUID` are NOT gated and are forwarded as they\n * are: both are synchronous, so there is no continuation to lose a lock.\n */\nclass GatedSubtleCrypto {\n readonly #requireOwnSlice: (op: string) => void;\n readonly #ctx: IoContext;\n readonly #subtle: SubtleCrypto;\n\n constructor(requireOwnSlice: (op: string) => void, ctx: IoContext, subtle: SubtleCrypto) {\n this.#requireOwnSlice = requireOwnSlice;\n this.#ctx = ctx;\n this.#subtle = subtle;\n }\n\n /**\n * Every asynchronous `SubtleCrypto` method, forwarded through `awaitIo`.\n *\n * Written as one generic hop rather than twelve near-identical methods,\n * because the shape is identical for all of them — the arguments are opaque to\n * this layer and the only thing added is the gate. `requireOwnSlice` runs\n * first for the reason `fetch` runs it: a facet that reached a parent's global\n * would resume under the wrong actor's gate.\n */\n #gated<K extends AsyncSubtleMethod>(method: K): SubtleCrypto[K] {\n const forward = (...args: unknown[]): Promise<unknown> => {\n try {\n this.#requireOwnSlice(`crypto.subtle.${method}`);\n } catch (exception) {\n // Reshaped rather than thrown, for `Scheduler.wait`'s reason: this returns a promise,\n // so a synchronous throw would escape the caller's `.catch`.\n return Promise.reject(exception);\n }\n const call = this.#subtle[method] as (...rest: unknown[]) => Promise<unknown>;\n return this.#ctx.awaitIo(call.apply(this.#subtle, args));\n };\n return forward as SubtleCrypto[K];\n }\n\n readonly decrypt = this.#gated(\"decrypt\");\n readonly deriveBits = this.#gated(\"deriveBits\");\n readonly deriveKey = this.#gated(\"deriveKey\");\n readonly digest = this.#gated(\"digest\");\n readonly encrypt = this.#gated(\"encrypt\");\n readonly exportKey = this.#gated(\"exportKey\");\n readonly generateKey = this.#gated(\"generateKey\");\n readonly importKey = this.#gated(\"importKey\");\n readonly sign = this.#gated(\"sign\");\n readonly unwrapKey = this.#gated(\"unwrapKey\");\n readonly verify = this.#gated(\"verify\");\n readonly wrapKey = this.#gated(\"wrapKey\");\n}\n\n/** Every `SubtleCrypto` member that returns a promise. */\ntype AsyncSubtleMethod = {\n [K in keyof SubtleCrypto]: SubtleCrypto[K] extends (...args: never[]) => Promise<unknown>\n ? K\n : never;\n}[keyof SubtleCrypto];\n\n/**\n * ← `ServiceWorkerGlobalScope`'s `crypto`. The synchronous members are the\n * platform's own; `subtle` is the gated one above.\n */\nclass GatedCrypto {\n readonly subtle: SubtleCrypto;\n readonly #crypto: Crypto;\n\n constructor(requireOwnSlice: (op: string) => void, ctx: IoContext, crypto: Crypto) {\n this.#crypto = crypto;\n this.subtle = new GatedSubtleCrypto(\n requireOwnSlice,\n ctx,\n crypto.subtle,\n ) as unknown as SubtleCrypto;\n }\n\n getRandomValues<T extends ArrayBufferView | null>(array: T): T {\n return this.#crypto.getRandomValues(array as never) as T;\n }\n\n randomUUID(): `${string}-${string}-${string}-${string}-${string}` {\n return this.#crypto.randomUUID();\n }\n}\n\n/** ← `s->getReason(js)`, which is what `Scheduler::wait` rejects with. */\nfunction abortReasonOf(signal: AbortSignal | undefined): unknown {\n return signal?.reason ?? new DOMException(\"The operation was aborted.\", \"AbortError\");\n}\n\n/** What the host supplies beneath `ServiceWorkerGlobalScope::fetch`. */\nexport type FetchPort = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type ActorGlobalScopeOptions = {\n /** Opaque identity of the external entry whose synchronous body is running. */\n readonly currentExternalEntry?: (() => object | undefined) | undefined;\n /**\n * The `Crypto` the gated one delegates to. Defaults to the realm's own, which\n * is what a host wants: unlike `fetch`, there is no per-actor outbound to\n * route this through — `SubtleCrypto` is pure computation, and the only thing\n * the actor's scope adds is the gate around its promise.\n */\n readonly crypto?: Crypto | undefined;\n /**\n * ← the global outbound `Fetcher` `ServiceWorkerGlobalScope::fetch` resolves\n * (`global-scope.c++:1160`). Absent means this actor has no ambient outbound,\n * which is upstream's `globalOutbound: null` posture (§1.11) — `fetch` then\n * refuses by name rather than reaching a `fetch` this package does not own.\n */\n readonly fetch?: FetchPort | undefined;\n};\n\n/** Thrown where `globalOutbound` is absent. Asserted rather than skipped, so it cannot drift. */\nexport const NO_GLOBAL_OUTBOUND_MESSAGE =\n \"fetch(): this actor has no global outbound, so an ambient fetch cannot be gated.\";\n\n/**\n * The message a scope answers with when it is reached from another actor's\n * slice. Exported because the failure it names is the one thing about this layer\n * that cannot be found by reading the calling code — see `requireOwnSlice`.\n */\nexport const FOREIGN_SLICE_MESSAGE =\n \"was reached from a different actor's slice. A facet that reads a global \" +\n \"instead of its own binding gets its parent's scope, and its continuation would resume \" +\n \"under the wrong actor's input gate.\";\n\n/**\n * ← `ServiceWorkerGlobalScope`, the async-primitive half. One per actor.\n *\n * A consumer installs this into whatever scope its actor's code reads —\n * `globalThis` for a class in the worker's own module graph, a module-scoped\n * binding for a class that arrived as a dynamically-loaded Worker source, which\n * is upstream's own arrangement (a dynamic Worker has its own global scope bound\n * to its own context, §1.11).\n */\nexport class ActorGlobalScope {\n readonly #ctx: IoContext;\n readonly #fetch: FetchPort | undefined;\n readonly #readCurrentExternalEntry: (() => object | undefined) | undefined;\n readonly scheduler: Scheduler;\n readonly crypto: GatedCrypto;\n\n constructor(ctx: IoContext, options: ActorGlobalScopeOptions = {}) {\n this.#ctx = ctx;\n this.#fetch = options.fetch;\n this.#readCurrentExternalEntry = options.currentExternalEntry;\n this.scheduler = new Scheduler(this);\n this.crypto = new GatedCrypto(\n (op) => {\n this.#requireOwnSlice(op);\n },\n ctx,\n // `platformCrypto`, captured at import, and NOT `globalThis.crypto` read here: a\n // host installs its scope before it builds the container, so reading the global now\n // would find the installed binding and recurse into itself on the first digest.\n options.crypto ?? platformCrypto,\n );\n }\n\n /** Opaque identity available only during an external entry's synchronous body. */\n get currentExternalEntry(): object | undefined {\n return this.#readCurrentExternalEntry?.();\n }\n\n /** Re-enter this actor after a host promise settles. */\n awaitIo<T>(promise: Promise<T>): Promise<T> {\n return this.#ctx.awaitIo(promise);\n }\n\n /**\n * The tripwire, and the reason this class can be bound rather than ambient.\n *\n * A scope is reached lexically, so a facet source that writes\n * `globalThis.scheduler.wait(…)` instead of the `scheduler` its own module\n * scope binds gets its PARENT's scope. Upstream cannot have this: a dynamic\n * Worker is a separate isolate with a separate global object, so the wrong\n * scope is not nameable. Here there is one realm, and the design record says\n * of it: \"nothing can detect it.\"\n *\n * This detects the case that occurs, and refuses. `IoContext.isCurrentSlice()`\n * is true only while a synchronous body of that context is on the JS stack,\n * and a facet's body calling a foreign global IS such a moment — the facet\n * entered through `entry()`/`run()`, and its body runs to its first `await`\n * with the ambient set. So the mismatch is certain, and the refusal names the\n * actor rather than surfacing three layers away as `no input lock available in\n * this context` from a storage call that had nothing to do with it.\n *\n * **What it does not catch, stated rather than implied.** A call made from a\n * CONTINUATION — after the calling body's first `await` — finds no ambient at\n * all, because `currentSlice` is restored when the body returns and JS cannot\n * drain a microtask checkpoint synchronously the way `runInContextScope` does.\n * The check then passes and the bound context is used, which is the status quo\n * behaviour and no worse than it. Widening the ambient to cover continuations\n * is not available: two actors' slices genuinely overlap in that window (§1.10\n * gives a facet its own gates, so nothing serialises it against its parent),\n * so a wider ambient would be WRONG rather than merely absent, and wrong with\n * nothing to say so. A tripwire that is silent when it cannot tell is worth\n * more than one that guesses.\n */\n #requireOwnSlice(op: string): void {\n const running = tryCurrentSlice();\n if (running === undefined || running === this.#ctx) return;\n throw new Error(`${op}: this actor's global scope ${FOREIGN_SLICE_MESSAGE}`);\n }\n\n /** ← `ServiceWorkerGlobalScope::setTimeout` (`global-scope.c++:944-950`). */\n setTimeout(callback: (...args: never[]) => void, msDelay = 0, ...args: unknown[]): number {\n this.#requireOwnSlice(\"setTimeout\");\n return this.#ctx.setTimeoutImpl(false, () => callback(...(args as never[])), msDelay);\n }\n\n /** ← `ServiceWorkerGlobalScope::clearTimeout` (`global-scope.c++:967-975`). */\n clearTimeout(id?: number | null): void {\n // ← `KJ_IF_SOME(id, timeoutId)`: a missing or non-numeric id is not an error, it is a no-op.\n if (typeof id !== \"number\") return;\n this.#ctx.clearTimeoutImpl(id);\n }\n\n /** ← `ServiceWorkerGlobalScope::setInterval` (`global-scope.c++:959-965`). */\n setInterval(callback: (...args: never[]) => void, msDelay = 0, ...args: unknown[]): number {\n this.#requireOwnSlice(\"setInterval\");\n return this.#ctx.setTimeoutImpl(true, () => callback(...(args as never[])), msDelay);\n }\n\n /** ← `ServiceWorkerGlobalScope::clearInterval`, which is `clearTimeout`'s own body. */\n clearInterval(id?: number | null): void {\n this.clearTimeout(id);\n }\n\n /**\n * ← `ServiceWorkerGlobalScope::fetch` (`global-scope.h:703-705`) reaching\n * `fetchImpl` (`http.c++:1740-1760`).\n *\n * Two gates, in upstream's order. The OUTPUT gate first, because an outbound\n * request is exactly the observation §1.1 exists to hold back — \"blocks all\n * outgoing messages from an actor that would allow the rest of the world to\n * observe the actor's state\" — and `fetchImpl` waits on it before the request\n * departs (`http.c++:1488`, `:1759`). The INPUT gate is released for the\n * duration and re-taken on resumption, which is `awaitIo` and which is what\n * makes an actor awaiting the network stay re-entrant (§1.3).\n */\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n try {\n // Reshaped rather than thrown, for the reason `Scheduler.wait` gives above: this returns a\n // promise, so a synchronous throw would escape the caller's `.catch`.\n this.#requireOwnSlice(\"fetch\");\n } catch (exception) {\n return Promise.reject(exception);\n }\n const outbound = this.#fetch;\n if (outbound === undefined) return Promise.reject(new Error(NO_GLOBAL_OUTBOUND_MESSAGE));\n\n const ctx = this.#ctx;\n return ctx.awaitIo(\n (async (): Promise<Response> => {\n await ctx.waitForOutputLocks();\n return await outbound(input, init);\n })(),\n // A `Response` is a promise for its body as much as it is a value: `await res.json()`\n // resumes from a promise this package would not own, so the body is gated too.\n (response) => gateResponseBody(ctx, response),\n );\n }\n}\n\n// =======================================================================================\n// Installing a scope\n\n/**\n * The bound form of `ActorGlobalScope`, which is what a scope object actually\n * holds. Bound, because these are read as free variables — `setTimeout(…)`, not\n * `scope.setTimeout(…)` — so a method that needed its receiver would break the\n * moment it was destructured, which is exactly how a dynamically-loaded Worker\n * source receives them.\n */\nexport type ActorScopeBindings = {\n readonly awaitIo: <T>(promise: Promise<T>) => Promise<T>;\n readonly scheduler: {\n wait(delay: number, options?: SchedulerWaitOptions): Promise<void>;\n yield(): Promise<void>;\n };\n readonly setTimeout: (\n callback: (...args: never[]) => void,\n msDelay?: number,\n ...args: unknown[]\n ) => number;\n readonly clearTimeout: (id?: number | null) => void;\n readonly setInterval: (\n callback: (...args: never[]) => void,\n msDelay?: number,\n ...args: unknown[]\n ) => number;\n readonly clearInterval: (id?: number | null) => void;\n readonly fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n readonly crypto: Crypto;\n readonly currentExternalEntry?: object | undefined;\n};\n\n/**\n * The capabilities an actor's code reads, bound to one scope.\n *\n * `resolve` is a thunk because the owner may change across root respawns, or a\n * shared realm may select the actor whose synchronous slice is running. It is\n * consulted only when an operation begins; it does not propagate identity\n * across a promise continuation. Actor-owned code should retain its explicit\n * scope instead. A single-actor host simply writes `() => scope`.\n */\nexport function actorScopeBindings(resolve: () => ActorGlobalScope): ActorScopeBindings {\n return {\n awaitIo: (promise) => resolve().awaitIo(promise),\n scheduler: {\n wait: (delay, options) => resolve().scheduler.wait(delay, options),\n yield: () => resolve().scheduler.yield(),\n },\n setTimeout: (callback, msDelay, ...args) => resolve().setTimeout(callback, msDelay, ...args),\n clearTimeout: (id) => {\n resolve().clearTimeout(id);\n },\n setInterval: (callback, msDelay, ...args) => resolve().setInterval(callback, msDelay, ...args),\n clearInterval: (id) => {\n resolve().clearInterval(id);\n },\n fetch: (input, init) => resolve().fetch(input, init),\n crypto: scopeCrypto(resolve),\n get currentExternalEntry(): object | undefined {\n return resolve().currentExternalEntry;\n },\n };\n}\n\n/**\n * `crypto`, bound the way every other name here is bound: nothing resolves until\n * an operation actually runs.\n *\n * That laziness is required rather than tidy, and both lanes proved it. A facet's\n * module destructures its seven names at module scope, which is BEFORE its container\n * exists — so a `crypto` that resolved on read threw at import. And on the root\n * path `globalThis.crypto` is read by things that are not the actor at all: capnweb,\n * the sqlite driver, the test runner. So the binding is a pair of plain objects\n * whose methods resolve, and reading `crypto` or `crypto.subtle` resolves nothing.\n *\n * The synchronous members go to the PLATFORM's `crypto` rather than through the\n * scope, because gating buys nothing for a call with no continuation — and because\n * they are exactly the ones a non-actor caller reaches for.\n */\nfunction scopeCrypto(resolve: () => ActorGlobalScope): Crypto {\n const subtle: Record<string, unknown> = {};\n for (const method of ASYNC_SUBTLE_METHODS) {\n subtle[method] = (...args: unknown[]): Promise<unknown> => {\n const target = resolve().crypto.subtle;\n const call = target[method] as (...rest: unknown[]) => Promise<unknown>;\n return Reflect.apply(call, target, args);\n };\n }\n return {\n subtle: subtle as unknown as SubtleCrypto,\n getRandomValues: <T extends ArrayBufferView | null>(array: T): T =>\n platformCrypto.getRandomValues(array as never) as T,\n randomUUID: () => platformCrypto.randomUUID(),\n } as unknown as Crypto;\n}\n\n/** Captured at import, before any host installs a scope over it. */\nconst platformCrypto = globalThis.crypto;\n\n/** ← every `SubtleCrypto` member that returns a promise, as a value the binding can iterate. */\nconst ASYNC_SUBTLE_METHODS = [\n \"decrypt\",\n \"deriveBits\",\n \"deriveKey\",\n \"digest\",\n \"encrypt\",\n \"exportKey\",\n \"generateKey\",\n \"importKey\",\n \"sign\",\n \"unwrapKey\",\n \"verify\",\n \"wrapKey\",\n] as const satisfies readonly AsyncSubtleMethod[];\n\n/**\n * Write the web-platform bindings onto a scope object — `globalThis` for a class in the worker's\n * own module graph, a plain object a dynamically-loaded source destructures for\n * one that is not.\n *\n * **A host should call this rather than assigning the names itself**, and the\n * reason is the failure it prevents: a host that installs five of the six leaves\n * one primitive ungated, and an ungated primitive that WORKS is invisible until\n * a continuation after it touches storage — possibly never, on the path that\n * matters. The set is the package's, so it can grow without every host growing\n * with it.\n *\n * **It ASSIGNS, and that is not incidental.** Chrome ships a `scheduler` global\n * in dedicated workers — the Prioritized Task Scheduling API, `postTask` and\n * `yield`, no `wait` — so a host writing `??=` silently keeps Chrome's and every\n * timer await fails somewhere else entirely with `scheduler.wait is not a\n * function`. Measured on the browser conformance lane, and the extension meets\n * the same global at cutover.\n *\n * **What a host must do first:** capture whatever raw timers its own substrate\n * needs. Everything BELOW the runtime — a `Timer` port, a transport's own\n * retries — has to keep the platform's, or arming a timeout goes through a\n * timeout. That is not hypothetical: pointing the node lane at these primitives\n * without capturing first produced `RangeError: Maximum call stack size\n * exceeded` on the first row.\n */\nexport function installActorScope(target: object, resolve: () => ActorGlobalScope): void {\n const bindings = actorScopeBindings(resolve);\n // Descriptors, not values: `crypto` is a getter, and reading it here would resolve the scope\n // at install time — which is before the container exists on the facet path, where the whole\n // arrangement is a late binding.\n for (const [name, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(bindings))) {\n // These are explicit actor capabilities, not web-platform globals.\n if (name === \"awaitIo\" || name === \"currentExternalEntry\") continue;\n Object.defineProperty(target, name, { ...descriptor, configurable: true });\n }\n}\n","/**\n * ← workerd `src/workerd/api/web-socket.{h,c++}` — the gating, and nothing else.\n *\n * A socket is the one primitive that is neither of the other two, and §1.8 says\n * why in three lines: incoming frames \"each take a fresh input lock via\n * `context.run(...)`\", the read loop \"captures the critical section at\n * `accept()` time\", and outbound messages \"each carry their own output-gate\n * promise captured at `send()` time\". Upstream states the first outright, on the\n * line that does it (`web-socket.c++:1056-1059`):\n *\n * > \"Re-enter the context with context.run(). This is arguably a bit unusual\n * > compared to other I/O which is delivered by return from context.awaitIo(),\n * > but the difference here is that we have a long stream of events over time.\n * > It makes sense to use context.run() each time a new event arrives.\"\n *\n * So a socket cannot be `awaitIo`: there is no single result to resume from.\n * `accept()` starts a loop, and the loop is the gate's caller.\n *\n * **What is ported and what is not.** The frame protocol, the hibernation\n * states, auto-response, `WebSocketPair` and the byte accounting are all\n * absent — the substrate ships a `WebSocket`, and hibernation is a recorded\n * substrate boundary with no Chrome lifecycle to be faithful to. What is here is\n * `WebSocket::Accepted`: the three gate properties above, over whatever socket\n * the host hands in. That is the same division `api/http.ts` makes and for the\n * same reason.\n *\n * **The accept contract, and the hole it leaves.** After `acceptWebSocket`, the\n * gated view owns the raw socket's events. A consumer that keeps a reference to\n * the raw socket and registers a listener on it directly gets that listener\n * called ungated, and nothing here can prevent it — upstream cannot be reached\n * that way because `accept()` moves the `kj::WebSocket` into `Accepted` and the\n * JS object never had it. The refusal below covers the case that is detectable\n * (accepting the same socket twice); the rest is the accept contract, stated.\n *\n * Spec: §1.1, §1.8 and decision 5 in\n * docs/decisions.md.\n */\n\nimport type { IoContext } from \"../io/io-context\";\nimport type { CriticalSection } from \"../io/io-gate\";\n\n/**\n * The socket beneath. Deliberately structural and minimal: a real `WebSocket`,\n * the extension's `WebSocketFacade` over capnweb, and a test double all satisfy\n * it, and none of them is a type this package should name.\n */\nexport interface RawWebSocket {\n addEventListener(type: string, listener: (event: Event) => void): void;\n send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void;\n close(code?: number, reason?: string): void;\n}\n\n/** ← the `JSG_REQUIRE(!native.state.is<Accepted>(), ...)` at the head of `accept()`. */\nexport const ALREADY_ACCEPTED_MESSAGE =\n \"acceptWebSocket(): this socket has already been accepted by an actor. A socket's frames are \" +\n \"delivered by exactly one read loop, and a second accept would deliver them under two gates.\";\n\n/** Sockets this runtime has accepted, so the refusal above is answerable. */\nconst accepted = new WeakSet<RawWebSocket>();\n\n/** The four events a `WebSocket` dispatches, which `readLoop` and its `.then` cover upstream. */\nconst SOCKET_EVENTS = [\"open\", \"message\", \"close\", \"error\"] as const;\ntype SocketEvent = (typeof SOCKET_EVENTS)[number];\n\n/**\n * ← `WebSocket::Accepted` (`web-socket.h:~300-360`), reached through\n * `accept()` → `internalAccept(js, IoContext::current().getCriticalSection())`\n * → `startReadLoop` (`web-socket.c++:133`, `:426`, `:429-433`, `:507`).\n *\n * An `EventTarget`, so a consumer registers listeners the way it would on a real\n * socket — but on THIS object rather than on the raw one, because this is what\n * runs them inside a gated slice.\n */\nexport class AcceptedWebSocket extends EventTarget {\n readonly #ctx: IoContext;\n readonly #socket: RawWebSocket;\n /**\n * ← `readLoop`'s `cs` parameter, captured at accept and replayed for every\n * frame via `mapAddRef(cs)` (`web-socket.c++:1110`). A socket accepted inside\n * `blockConcurrencyWhile` therefore delivers its messages inside that critical\n * section — §1.8's second bullet, and the reason this is captured here rather\n * than read when a frame arrives.\n */\n readonly #criticalSection: CriticalSection | undefined;\n\n /**\n * ← `OutgoingMessagesMap outgoingMessages` plus `ensurePumping`\n * (`web-socket.h:582-590`, `web-socket.c++:948-975`), as a chain.\n *\n * The table is insertion-ordered and the pump awaits each entry's own\n * `outputLock` before sending it, so messages leave in order and message N\n * waits only for the writes outstanding when IT was enqueued. A promise chain\n * is the same two properties with nothing to schedule.\n */\n #pump: Promise<void> = Promise.resolve();\n\n onopen: ((event: Event) => void) | null = null;\n onmessage: ((event: MessageEvent) => void) | null = null;\n onclose: ((event: CloseEvent) => void) | null = null;\n onerror: ((event: Event) => void) | null = null;\n\n constructor(ctx: IoContext, socket: RawWebSocket) {\n super();\n this.#ctx = ctx;\n this.#socket = socket;\n this.#criticalSection = ctx.getCriticalSection();\n\n // ← `startReadLoop`. One listener per event type on the raw socket, forever; each delivery is\n // one gated run. Upstream's loop is a coroutine over `ws.receive()`, which is the same shape\n // an event listener already is here.\n for (const type of SOCKET_EVENTS) {\n socket.addEventListener(type, (event: Event) => {\n this.#deliver(type, event);\n });\n }\n }\n\n /**\n * ← `co_await context.run([...](auto& wLock) { dispatchEventImpl(...) }, mapAddRef(cs))`\n * (`web-socket.c++:1065-1110`).\n *\n * The run rides `addWaitUntil`, as upstream's read loop does (\"We put the read\n * loop in a `waitUntil`, since there would otherwise be a race condition\n * between delivering the final close message and the request being canceled\",\n * `web-socket.c++:537-541`). That is also what stops a listener's throw\n * becoming an unhandled rejection: it lands in `waitUntilStatus()`.\n */\n #deliver(type: SocketEvent, event: Event): void {\n this.#ctx.addWaitUntil(\n this.#ctx.run(() => {\n // One rebuilt event for both forms: handing the handler the raw one would give it a\n // different `target` from the listener beside it, for the same frame.\n const delivered = cloneEventFor(type, event);\n this.dispatchEvent(delivered);\n // Consumers use both forms — a client library sets handlers, a server library listens —\n // so both are called, exactly as `WebSocketFacade` does for the same reason.\n const handler = this[`on${type}`] as ((event: Event) => void) | null;\n handler?.(delivered);\n }, this.#criticalSection),\n );\n }\n\n /**\n * ← `WebSocket::send` (`web-socket.c++:~640`), which inserts a\n * `GatedMessage{IoContext::current().waitForOutputLocksIfNecessary(), …}`.\n *\n * Synchronous, as upstream's is: the wait is the pump's, not the caller's. The\n * output gate is what \"blocks all outgoing messages from an actor that would\n * allow the rest of the world to observe the actor's state\" (§1.1), and a\n * socket frame is exactly such a message.\n *\n * `waitForOutputLocksIfNecessary()` collapses to `waitForOutputLocks()` here\n * for the reason the whole file collapses `kj::Maybe<Worker::Actor&>`: its\n * body is `actor.map(…)` (`io-context.c++:383-386`) and every context in this\n * runtime is an actor context.\n */\n send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void {\n this.#enqueue(() => {\n this.#socket.send(data);\n });\n }\n\n /** ← `WebSocket::close`, which enqueues a `Close` through the same gate. */\n close(code?: number, reason?: string): void {\n this.#enqueue(() => {\n this.#socket.close(code, reason);\n });\n }\n\n #enqueue(write: () => void): void {\n // Captured HERE, at the call, so message N waits for the writes outstanding when it was\n // enqueued and not for whatever is outstanding when the pump reaches it.\n const outputLock = this.#ctx.waitForOutputLocks();\n this.#pump = this.#pump.then(async () => {\n await outputLock;\n write();\n });\n // The chain is the actor's work, so a broken output gate reports where every other background\n // failure reports rather than as an unhandled rejection.\n this.#ctx.addWaitUntil(this.#pump);\n }\n}\n\n/**\n * ← `accept()` / `state.acceptWebSocket()`, as the one verb.\n *\n * Named for what upstream names it, because the critical-section capture is a\n * property of accepting rather than of constructing: \"a socket accepted inside a\n * `blockConcurrencyWhile` delivers its messages inside that critical section\"\n * (§1.8).\n */\nexport function acceptWebSocket(ctx: IoContext, socket: RawWebSocket): AcceptedWebSocket {\n if (accepted.has(socket)) throw new Error(ALREADY_ACCEPTED_MESSAGE);\n accepted.add(socket);\n return new AcceptedWebSocket(ctx, socket);\n}\n\n/**\n * An `Event` may be dispatched by exactly one target at a time, so the raw\n * socket's event object cannot be re-dispatched: `dispatchEvent` on an event\n * that is already dispatched throws `InvalidStateError`, and one that has\n * finished carries the raw socket as its `target`. Rebuilding it is what makes\n * `event.target` the accepted socket, which is what a listener expects.\n */\nfunction cloneEventFor(type: SocketEvent, event: Event): Event {\n if (type === \"message\") {\n const source = event as MessageEvent;\n return new MessageEvent(\"message\", {\n data: source.data,\n origin: source.origin,\n lastEventId: source.lastEventId,\n });\n }\n if (type === \"close\") {\n const source = event as CloseEvent;\n return new CloseEvent(\"close\", {\n code: source.code,\n reason: source.reason,\n wasClean: source.wasClean,\n });\n }\n return new Event(type);\n}\n","/**\n * ← workerd `src/workerd/io/actor-cache.h` — INTERFACE ONLY.\n *\n * The `actor-cache.c++` LRU implementation is ABSENT rather than skipped: it\n * caches a remote storage service that none of our substrates have. Upstream\n * does not use it in SQLite mode either — `ActorSqlite` is the sole\n * `ActorCacheInterface` implementation there, and the same is true here.\n *\n * The two behaviours decision 5 names live in `io/actor-sqlite.ts`, which is\n * where workerd's SQLite path exhibits them: `allowUnconfirmed` skips the\n * output-gate lock but STILL breaks the gate on error, and a batch started as\n * unconfirmed is retroactively upgraded when a must-confirm write joins it.\n *\n * Ordering guarantee, upstream's words (`actor-cache.h:334-340`): writes are\n * never committed out-of-order, by brute force — one transaction commits all\n * dirty keys at once.\n *\n * This file carries only what `ActorSqlite` genuinely implements. Everything in\n * `ActorCacheInterface` that exists solely for the LRU — `evictStale`'s\n * backpressure, the RPC storage client, the shared LRU and its hooks — is\n * absent with it.\n *\n * The one shape that is ours rather than upstream's: **every read and write is\n * synchronous.** Upstream returns `kj::OneOf<T, kj::Promise<T>>` so a cache miss\n * can go to the network; §1.4 measures that a SQLite-backed actor never does,\n * and the SQLite arm of every one of those `OneOf`s is the immediate value. A\n * `OneOf` with one reachable arm is a promise nobody can observe, and keeping it\n * would make `api/actor-state.ts` unwrap something that is never a promise.\n * `onNoPendingFlush` and `abandonAlarm` stay asynchronous because upstream's\n * SQLite arm is genuinely asynchronous there.\n *\n * Spec: §1.7, decisions 2 and 5.\n */\n\n/** ← `ActorCacheOps::Key`. \"Keys are text for now.\" */\nexport type Key = string;\n\n/** ← `ActorCacheOps::Value`. Values are raw bytes; the value encoding is `api/`'s. */\nexport type Value = Uint8Array;\n\n/** ← `ActorCacheOps::KeyValuePair`. */\nexport type KeyValuePair = {\n readonly key: Key;\n readonly value: Value;\n};\n\n/**\n * ← `ActorCacheOps::GetResultList`, which upstream makes a class so it can\n * iterate pointers into the cache's own storage. Ours has already copied.\n */\nexport type GetResultList = readonly KeyValuePair[];\n\n/**\n * The option bags. Per §1.2 `allowConcurrency` is precisely the input-gate\n * opt-out: it selects `awaitIo` over `awaitIoWithInputLock`, which per §1.7.1\n * also ends the implicit transaction.\n *\n * Nothing passes any of these today — not upstream, not this repo, not the\n * vendored tests. They are built anyway; building half of the\n * `awaitIoWithInputLock` branch is the feature-subset failure the porting\n * philosophy rejects. The conformance suite exercises them deliberately.\n *\n * Placement note: upstream's `ActorCacheReadOptions` holds only `noCache`, and\n * `allowConcurrency` is read one layer up, in `DurableObjectStorageOperations`\n * (`actor-state.c++:68-79`) — `ActorCacheOps` never sees it. Part 4's table puts\n * decision 2 in this file, so it is declared here and consumed by `api/`;\n * `ActorSqlite` itself reads neither `allowConcurrency` nor `noCache`, exactly\n * as upstream's does not.\n */\nexport type ReadOptions = {\n /** Release the input gate across the await. Ends the implicit transaction. */\n allowConcurrency?: boolean;\n /** Do not retain the value in cache. */\n noCache?: boolean;\n};\n\nexport type WriteOptions = ReadOptions & {\n /** Skip the output-gate lock. Never skips break-on-error. */\n allowUnconfirmed?: boolean;\n};\n\n/** ← `DeleteAllOptions`. */\nexport type DeleteAllOptions = {\n /**\n * When true, deleteAll() will also delete any scheduled alarm. The alarm\n * deletion is guaranteed to take effect only after the deleteAll() itself\n * succeeds, so that we never end up in a state where the alarm is deleted but\n * KV data remains.\n */\n deleteAlarm?: boolean;\n};\n\n/**\n * ← `ActorCacheInterface::DeleteAllResults`.\n *\n * Upstream splits these \"so client code that doesn't need the count doesn't have\n * to wait for it just to account for backpressure\". Both arms are immediate for\n * SQLite: `backpressure` is always `kj::none` and `count` is a ready promise.\n */\nexport type DeleteAllResults = {\n readonly backpressure: Promise<void> | undefined;\n readonly count: number;\n};\n\n/**\n * ← `ActorCacheInterface::CancelAlarmHandler`. Alarm should be canceled without\n * retry, because alarm state has changed such that the requested alarm time is\n * no longer valid.\n */\nexport type CancelAlarmHandler = {\n /** Caller should wait for this promise to complete before canceling. */\n readonly waitBeforeCancel: Promise<void>;\n};\n\n/**\n * ← the `kj::Own<void>` that `RunAlarmHandler` carries, whose disposer runs\n * `maybeDeleteDeferredAlarm()`. Section 1's rule applies: a kj destructor\n * becomes an explicit call, so the caller attaches `drop()` to the promise\n * representing the handler's execution rather than a scope exit.\n */\nexport interface DeferredAlarmDeleter {\n drop(): void;\n}\n\n/** ← `ActorCacheInterface::RunAlarmHandler`. Alarm should be run. */\nexport type RunAlarmHandler = {\n readonly deferredDelete: DeferredAlarmDeleter;\n};\n\n/** ← `kj::OneOf<CancelAlarmHandler, RunAlarmHandler>`. */\nexport type ArmAlarmResult =\n | { readonly kind: \"cancel\"; readonly cancel: CancelAlarmHandler }\n | { readonly kind: \"run\"; readonly run: RunAlarmHandler };\n\n/** ← `ActorCache::SHUTDOWN_ERROR_MESSAGE`, which `ActorSqlite::shutdown` reuses. */\nexport const SHUTDOWN_ERROR_MESSAGE =\n \"broken.ignored; jsg.Error: Durable Object storage is no longer accessible.\";\n\n/**\n * ← the message every unimplemented `ActorCacheInterface` PITR method throws.\n * `ActorSqlite` overrides two of the four; the other two keep this.\n */\nexport const PITR_UNIMPLEMENTED_MESSAGE =\n \"This Durable Object's storage back-end does not implement point-in-time recovery.\";\n\n/** ← the message the three replication methods throw. */\nexport const REPLICATION_UNIMPLEMENTED_MESSAGE =\n \"This Durable Object's storage back-end does not support replication.\";\n\n/**\n * Common interface between the storage engine and a transaction on it.\n *\n * ← `ActorCacheOps`. Upstream's `list`/`listReverse` split exists because the\n * two directions \"require a subtly different implementation of pretty much the\n * entire algorithm\" in the cache; both are kept, because both are separate\n * entry points a caller reaches.\n */\nexport interface ActorCacheOps {\n get(key: Key, options: ReadOptions): Value | undefined;\n getMultiple(keys: readonly Key[], options: ReadOptions): GetResultList;\n getAlarm(options: ReadOptions): number | null;\n list(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions,\n ): GetResultList;\n listReverse(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions,\n ): GetResultList;\n\n put(key: Key, value: Value, options: WriteOptions): void;\n putMultiple(pairs: readonly KeyValuePair[], options: WriteOptions): void;\n /** Returns whether the key was present. */\n delete(key: Key, options: WriteOptions): boolean;\n /** Returns how many of the keys were present. */\n deleteMultiple(keys: readonly Key[], options: WriteOptions): number;\n setAlarm(newAlarmTime: number | null, options: WriteOptions): void;\n}\n\n/**\n * ← `ActorCacheInterface::Transaction`.\n *\n * \"If commit() is not called before the Transaction is destroyed, nothing is\n * written.\" JS has no destruction, so `drop()` is that moment and exactly one of\n * `commit()`/`rollback()`+`drop()` has to run — the same contract Section 1\n * established for `Lock` and `CriticalSection`.\n */\nexport interface ActorCacheTransaction extends ActorCacheOps {\n /**\n * Write all changes to the underlying storage.\n *\n * \"This will NOT detect conflicts, it will always just write blindly, because\n * conflicts inherently cannot happen.\"\n */\n commit(): void;\n rollback(): void;\n /** ← `~ExplicitTxn`: roll back if not committed, then leave the txn stack. */\n drop(): void;\n}\n\n/**\n * Abstract interface that upstream implements twice, and that this package\n * implements once — `ActorSqlite` is the sole implementation, exactly as on\n * workerd-with-SQLite.\n */\nexport interface ActorCacheInterface extends ActorCacheOps {\n startTransaction(): ActorCacheTransaction;\n deleteAll(options: WriteOptions, deleteAllOptions?: DeleteAllOptions): DeleteAllResults;\n /**\n * \"Call each time the isolate lock is taken to evict stale entries.\" There is\n * no cache to evict from and never any backpressure to apply.\n */\n evictStale(now: number): undefined;\n shutdown(exception?: unknown): void;\n\n armAlarmHandler(scheduledTime: number, currentTime: number): ArmAlarmResult;\n cancelDeferredAlarmDeletion(): void;\n abandonAlarm(scheduledTime: number): Promise<number | null>;\n\n /** Implements `sync()`. */\n onNoPendingFlush(): Promise<void>;\n\n getCurrentBookmark(): Promise<string>;\n getBookmarkForTime(timestamp: number): Promise<string>;\n onNextSessionRestoreBookmark(bookmark: string): Promise<string>;\n waitForBookmark(bookmark: string): Promise<void>;\n\n ensureReplicas(): void;\n disableReplicas(): void;\n configureReadReplication(enabled: boolean): Promise<void>;\n}\n","/**\n * ← workerd `src/workerd/util/sqlite-kv.{h,c++}`\n *\n * KV storage on top of SQLite, for Durable Object storage.\n *\n * The table is named `_cf_KV`. The naming is designed so that if the\n * application is allowed to perform direct SQL queries, we can block it from\n * accessing any table prefixed with `_cf_`.\n *\n * This layer is bytes in, bytes out, exactly as upstream is. The structured\n * value encoding happens above it, in `api/actor-state.ts`, which is where\n * upstream V8-serializes.\n *\n * Three translations, each of them forced:\n *\n * - `get`'s callback exists upstream to avoid copying bytes out of a live\n * sqlite row. Our backends have already materialised the row by the time we\n * see it, so there is no copy to avoid and the value is returned.\n * - `delete_` is spelled `delete` — the C++ name carries a trailing underscore\n * only because `delete` is a keyword there.\n * - Upstream's `Uninitialized` / `Initialized` pair exists solely to hold\n * thirteen `SqliteDatabase::Statement`s. Prepared statements are not part of\n * our backend seam (each `exec` prepares), so the pair collapses into the\n * `tableCreated` flag it already sits beside. The statements survive as\n * `STMT` below: same names, same order, SQL copied verbatim, so the\n * correspondence a reader needs is intact.\n *\n * Not ported: `SqliteKvRegulator`. Its remaining job is `shouldAddQueryStats`,\n * which is row-count billing; neither backend exposes those counters.\n *\n * Spec: §2.4 in docs/decisions.md.\n */\n\nimport {\n getBlob,\n getInt64,\n getText,\n hasCurrentSqliteTable,\n type ResetListener,\n type SqliteDatabase,\n} from \"./sqlite\";\n\nexport type KeyPtr = string;\nexport type ValuePtr = Uint8Array;\n\n/** ← `SqliteKv::Order`. */\nexport type Order = \"FORWARD\" | \"REVERSE\";\n\n/** ← `SqliteKv::WriteOptions`. */\nexport type WriteOptions = {\n allowUnconfirmed?: boolean;\n};\n\n/** ← `SqliteKv::ListCursor::KeyValuePair`, and the shape `put(pairs)` iterates. */\nexport type KeyValuePair = {\n key: KeyPtr;\n value: ValuePtr;\n};\n\n/** ← the `Initialized` statement bundle, verbatim. */\nconst STMT = {\n get: `\n SELECT value FROM _cf_KV WHERE key = ?\n `,\n put: `\n INSERT INTO _cf_KV VALUES(?, ?)\n ON CONFLICT DO UPDATE SET value = excluded.value\n `,\n delete: `\n DELETE FROM _cf_KV WHERE key = ?\n `,\n list: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key\n `,\n listEnd: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key\n `,\n listLimit: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key\n LIMIT ?\n `,\n listEndLimit: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key\n LIMIT ?\n `,\n listReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key DESC\n `,\n listEndReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key DESC\n `,\n listLimitReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ?\n ORDER BY key DESC\n LIMIT ?\n `,\n listEndLimitReverse: `\n SELECT * FROM _cf_KV\n WHERE key >= ? AND key < ?\n ORDER BY key DESC\n LIMIT ?\n `,\n countKeys: `\n SELECT count(*) FROM _cf_KV\n `,\n multiPutSavepoint: `\n SAVEPOINT _cf_put_multiple_savepoint\n `,\n multiPutRelease: `\n RELEASE _cf_put_multiple_savepoint\n `,\n} as const;\n\nconst CREATE_TABLE = `\n CREATE TABLE IF NOT EXISTS _cf_KV (\n key TEXT PRIMARY KEY,\n value BLOB\n ) WITHOUT ROWID\n `;\n\nexport class SqliteKv implements ResetListener {\n readonly #db: SqliteDatabase;\n\n /**\n * Has the `_cf_KV` table been created? Separate from the statement bundle\n * upstream, since it has to be repeated after a reset.\n */\n #tableCreated = false;\n\n #currentCursor: SqliteKvListCursor | null = null;\n\n constructor(db: SqliteDatabase) {\n this.#db = db;\n this.#tableCreated = hasCurrentSqliteTable(db, \"_cf_KV\", CREATE_TABLE);\n db.addResetListener(this);\n }\n\n /**\n * Search for a match for the given key. Returns the value if found, undefined\n * if not.\n */\n get(key: KeyPtr): ValuePtr | undefined {\n // \"No table, so no value\" is answered from `#tableCreated` without a\n // statement, which is the one path a latched critical error would not\n // otherwise stop.\n this.#db.assertUsable();\n if (!this.#tableCreated) return undefined;\n\n const row = this.#db.run(STMT.get, key).rawRows[0];\n if (row === undefined) return undefined;\n return getBlob(row, 0);\n }\n\n /**\n * Search for all known keys and values in a range. `end` and `limit` can be\n * undefined to request no constraint be enforced.\n *\n * With a callback, calls it for each row seen and returns the count. Without\n * one, returns a cursor which can be iterated one at a time.\n */\n list(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n ): SqliteKvListCursor;\n list(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n callback: (key: KeyPtr, value: ValuePtr) => void,\n ): number;\n list(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n callback?: (key: KeyPtr, value: ValuePtr) => void,\n ): SqliteKvListCursor | number {\n const cursor = this.#openCursor(begin, end, limit, order);\n return callback === undefined ? cursor : cursor.forEach(callback);\n }\n\n /** Store a value into the table, or atomically store multiple values. */\n put(key: KeyPtr, value: ValuePtr, options?: WriteOptions): void;\n put(pairs: Iterable<KeyValuePair>, options: WriteOptions): void;\n put(\n keyOrPairs: KeyPtr | Iterable<KeyValuePair>,\n valueOrOptions?: ValuePtr | WriteOptions,\n maybeOptions?: WriteOptions,\n ): void {\n // The two overloads share a parameter position, and narrowing it by test\n // rather than by cast is what keeps a caller who mixes them up from writing\n // an options object into the table as a value.\n if (typeof keyOrPairs === \"string\") {\n if (!(valueOrOptions instanceof Uint8Array)) {\n throw new Error(\"put(key, value) takes a Uint8Array value.\");\n }\n const allowUnconfirmed = maybeOptions?.allowUnconfirmed ?? false;\n this.#ensureInitialized(allowUnconfirmed);\n this.#db.run({ allowUnconfirmed }, STMT.put, keyOrPairs, valueOrOptions);\n return;\n }\n if (valueOrOptions instanceof Uint8Array) {\n throw new Error(\"put(pairs, options) takes an options object.\");\n }\n this.#putMultiple(keyOrPairs, valueOrOptions ?? {});\n }\n\n /** Delete the key and return whether it was matched. */\n delete(key: KeyPtr, options: WriteOptions = {}): boolean {\n const allowUnconfirmed = options.allowUnconfirmed ?? false;\n this.#ensureInitialized(allowUnconfirmed);\n return this.#db.run({ allowUnconfirmed }, STMT.delete, key).rowsWritten > 0;\n }\n\n deleteAll(): number {\n // Upstream's TODO(perf) applies verbatim: apps almost certainly don't care\n // about the return value, but historically we returned the count of keys\n // deleted, so now we're stuck counting the table size for no good reason.\n let count = 0;\n if (this.#tableCreated) {\n const row = this.#db.run(STMT.countKeys).rawRows[0];\n if (row === undefined) throw new Error(\"count(*) returned no row.\");\n count = getInt64(row, 0);\n }\n this.#db.reset();\n return count;\n }\n\n /** ResetListener interface: we'll need to recreate the table on the next operation. */\n beforeSqliteReset(): void {\n this.#tableCreated = false;\n // Upstream's cursors are ResetListeners of their own and throw\n // \"query canceled because reset()\" afterwards. Ours hold a materialised\n // array that a reset cannot invalidate, so cancelling is what keeps a\n // cursor from outliving the data it was reading.\n this.#cancelCurrentCursor();\n }\n\n #openCursor(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n ): SqliteKvListCursor {\n // Same cache-served early return as `get`.\n this.#db.assertUsable();\n if (!this.#tableCreated) return new SqliteKvListCursor(null, null);\n\n const [sql, params] = selectListStatement(begin, end, limit, order);\n this.#cancelCurrentCursor();\n const cursor = new SqliteKvListCursor(this, this.#db.run(sql, ...params).rawRows);\n this.#currentCursor = cursor;\n return cursor;\n }\n\n /** Called by a cursor that has run out of rows, mirroring `~ListCursor::State`. */\n releaseCursor(cursor: SqliteKvListCursor): void {\n if (this.#currentCursor === cursor) this.#currentCursor = null;\n }\n\n #cancelCurrentCursor(): void {\n const cursor = this.#currentCursor;\n if (cursor !== null) {\n cursor.cancel();\n this.#currentCursor = null;\n }\n }\n\n #putMultiple(pairs: Iterable<KeyValuePair>, options: WriteOptions): void {\n const allowUnconfirmed = options.allowUnconfirmed ?? false;\n this.#ensureInitialized(allowUnconfirmed);\n this.#db.run({ allowUnconfirmed }, STMT.multiPutSavepoint);\n\n try {\n for (const pair of pairs) {\n this.put(pair.key, pair.value, { allowUnconfirmed });\n }\n } catch (error) {\n // If any of the puts throw, roll the savepoint back and re-throw the\n // exception from the put that failed.\n this.#rollbackMultiPut(allowUnconfirmed, error);\n throw error;\n }\n this.#db.run({ allowUnconfirmed }, STMT.multiPutRelease);\n }\n\n /**\n * Upstream logs and swallows a failure here, on the grounds that it should be\n * rare. This repo has no logger and a storage layer that swallows an error\n * corrupts data silently, so a failed rollback is raised instead — carrying\n * the put failure as its cause, since that is the one the caller came for.\n * The normal path is unchanged: a rollback that succeeds re-throws the\n * original untouched.\n */\n #rollbackMultiPut(allowUnconfirmed: boolean, cause: unknown): void {\n try {\n // This should be rare, so we don't keep a statement for it.\n this.#db.run({ allowUnconfirmed }, \"ROLLBACK TO _cf_put_multiple_savepoint\");\n this.#db.run({ allowUnconfirmed }, STMT.multiPutRelease);\n } catch (rollbackError) {\n throw new Error(`Rolling back a multi-put failed: ${String(rollbackError)}`, { cause });\n }\n }\n\n /**\n * Make sure the KV table is created. Not called until the first write —\n * upstream's `ensureInitialized`, minus the statement bundle.\n */\n #ensureInitialized(allowUnconfirmed: boolean): void {\n if (this.#tableCreated) return;\n\n this.#db.run({ allowUnconfirmed }, CREATE_TABLE);\n this.#tableCreated = true;\n\n // If we're in a transaction and it gets rolled back, we better mark that\n // the table is actually not created anymore.\n this.#db.onRollback(() => {\n this.#tableCreated = false;\n });\n }\n}\n\n/**\n * ← `SqliteKv::ListCursor`.\n *\n * Upstream's iterates a live sqlite statement, which is why only one may be\n * open at a time and why a new `list()` cancels the previous cursor. Our rows\n * arrive materialised, so nothing forces that constraint — it is kept because\n * `wasCanceled()` is part of the contract above this layer, and a cursor whose\n * cancellation depended on the substrate would make the browser and Node lanes\n * disagree. What we do lose is streaming: an unbounded `list()` reads the whole\n * range into memory, where upstream reads a row at a time.\n */\nexport class SqliteKvListCursor {\n readonly #parent: SqliteKv | null;\n #rows: readonly (readonly unknown[])[] | null;\n #index = 0;\n #canceled = false;\n\n constructor(parent: SqliteKv | null, rows: readonly (readonly unknown[])[] | null) {\n this.#parent = parent;\n this.#rows = rows;\n }\n\n next(): KeyValuePair | undefined {\n const rows = this.#rows;\n if (rows === null) return undefined;\n\n const row = rows[this.#index];\n if (row === undefined) {\n this.#exhaust();\n return undefined;\n }\n this.#index += 1;\n return { key: getText(row, 0), value: getBlob(row, 1) };\n }\n\n forEach(callback: (key: KeyPtr, value: ValuePtr) => void): number {\n let count = 0;\n for (;;) {\n const pair = this.next();\n if (pair === undefined) return count;\n callback(pair.key, pair.value);\n count += 1;\n }\n }\n\n /**\n * If true, the cursor was canceled due to a new list() operation starting.\n * Only one list() is allowed at a time.\n */\n wasCanceled(): boolean {\n return this.#canceled;\n }\n\n /** Called by `SqliteKv` only. */\n cancel(): void {\n this.#rows = null;\n this.#canceled = true;\n }\n\n #exhaust(): void {\n this.#rows = null;\n this.#parent?.releaseCursor(this);\n }\n}\n\n/** ← the eight-way branch in `SqliteKv::list`, in the same order. */\nfunction selectListStatement(\n begin: KeyPtr,\n end: KeyPtr | undefined,\n limit: number | undefined,\n order: Order,\n): [sql: string, params: (string | number)[]] {\n if (order === \"FORWARD\") {\n if (end !== undefined) {\n if (limit !== undefined) return [STMT.listEndLimit, [begin, end, limit]];\n return [STMT.listEnd, [begin, end]];\n }\n if (limit !== undefined) return [STMT.listLimit, [begin, limit]];\n return [STMT.list, [begin]];\n }\n if (end !== undefined) {\n if (limit !== undefined) return [STMT.listEndLimitReverse, [begin, end, limit]];\n return [STMT.listEndReverse, [begin, end]];\n }\n if (limit !== undefined) return [STMT.listLimitReverse, [begin, limit]];\n return [STMT.listReverse, [begin]];\n}\n","/**\n * ← workerd `src/workerd/util/sqlite-metadata.{h,c++}`\n *\n * A simple metadata kv storage and cache on top of SQLite. Currently used to\n * store:\n *\n * - Durable Object alarm times (hardcoded as key = 1);\n * - a local development bookmark used to simulate the getCurrentBookmark API\n * used by D1 (hardcoded as key = 2), not used in production.\n *\n * The table is named `_cf_METADATA`. The naming is designed so that if the\n * application is allowed to perform direct SQL queries, we can block it from\n * accessing any table prefixed with `_cf_`.\n *\n * Times are milliseconds, not nanoseconds. Upstream stores\n * `(t - UNIX_EPOCH) / kj::NANOSECONDS` as an int64. A JS number runs out of\n * integer precision 104 days into the epoch at nanosecond scale, so storing\n * what upstream stores would silently round every alarm. Milliseconds are also\n * what every caller above this already uses.\n *\n * The local-development bookmark IS ported, which the package's bookmark\n * substrate boundary might seem to rule out. It does not: that boundary is\n * `getCurrentBookmark` / `getBookmarkForTime` / `onNextSessionRestoreBookmark`,\n * which need point-in-time recovery from the storage engine. Key 2 is an\n * integer in a row, and D1 uses it locally precisely because it needs nothing.\n *\n * Spec: §1.8, §2.6 in docs/decisions.md.\n */\n\nimport {\n getInt64,\n hasCurrentSqliteTable,\n isNull,\n type ResetListener,\n type SqliteDatabase,\n} from \"./sqlite\";\n\n/** ← the `Initialized` statement bundle. */\nconst STMT = {\n getAlarm: `\n SELECT value FROM _cf_METADATA WHERE key = 1\n `,\n setAlarm: `\n INSERT INTO _cf_METADATA VALUES(1, ?)\n ON CONFLICT DO UPDATE SET value = excluded.value\n `,\n getLocalDevelopmentBookmark: `\n SELECT value FROM _cf_METADATA WHERE key = 2\n `,\n setLocalDevelopmentBookmark: `\n INSERT INTO _cf_METADATA VALUES(2, ?)\n ON CONFLICT DO UPDATE SET value = excluded.value\n `,\n} as const;\n\nconst CREATE_TABLE = `\n CREATE TABLE IF NOT EXISTS _cf_METADATA (\n key INTEGER PRIMARY KEY,\n value BLOB\n )\n `;\n\n/** ← `SqliteMetadata::Cache`. */\ntype Cache = {\n alarmTime: number | null;\n};\n\nexport class SqliteMetadata implements ResetListener {\n readonly #db: SqliteDatabase;\n #tableCreated: boolean;\n #cache: Cache | undefined;\n\n constructor(db: SqliteDatabase) {\n this.#db = db;\n this.#tableCreated = hasCurrentSqliteTable(db, \"_cf_METADATA\", CREATE_TABLE);\n if (this.#tableCreated) {\n const unexpected = db.run(\"SELECT key FROM _cf_METADATA WHERE key NOT IN (1, 2) LIMIT 1\")\n .rawRows[0];\n if (unexpected !== undefined) {\n throw new Error(\n `Incompatible @mcp-b/do-runtime storage data: _cf_METADATA contains unsupported key ${getInt64(unexpected, 0)}.`,\n );\n }\n }\n db.addResetListener(this);\n }\n\n /** Return currently set alarm time, or null. */\n getAlarm(): number | null {\n return this.#ensureCached().alarmTime;\n }\n\n /**\n * Sets current alarm time, or null. Returns true if the value changed, false\n * if it was already set to the same value.\n */\n setAlarm(currentTime: number | null, allowUnconfirmed: boolean): boolean {\n const cached = this.#cache;\n if (cached !== undefined && cached.alarmTime === currentTime) {\n return false;\n }\n this.#setAlarmUncached(currentTime, allowUnconfirmed);\n this.#db.onRollback(() => {\n this.#cache = cached;\n });\n this.#cache = { alarmTime: currentTime };\n return true;\n }\n\n /** Return the current local development bookmark, or null if none has been set. */\n getLocalDevelopmentBookmark(): number | null {\n this.#ensureInitialized(false);\n const row = this.#db.run(STMT.getLocalDevelopmentBookmark).rawRows[0];\n if (row === undefined || isNull(row, 0)) return null;\n\n const bookmark = getInt64(row, 0);\n if (bookmark < 0) throw new Error(`Local development bookmark is negative: ${bookmark}.`);\n return bookmark;\n }\n\n /** Set the current ersatz bookmark. */\n setLocalDevelopmentBookmark(bookmark: number): void {\n // Upstream's `uint64_t` parameter plus its `KJ_REQUIRE(bookmark <= maxValue)`, expressed in\n // the range a JS number can actually carry without rounding.\n if (!Number.isSafeInteger(bookmark) || bookmark < 0) {\n throw new Error(\n `Local development bookmark is not a non-negative safe integer: ${bookmark}.`,\n );\n }\n this.#ensureInitialized(false);\n this.#db.run(STMT.setLocalDevelopmentBookmark, bookmark);\n }\n\n /** ResetListener interface: we'll need to recreate the table on the next operation. */\n beforeSqliteReset(): void {\n this.#tableCreated = false;\n this.#cache = undefined;\n }\n\n #ensureCached(): Cache {\n // The only read in this class that can be answered without a statement, so\n // the only one a latched critical error would not already stop — and the\n // one whose answer SQLite may have rolled back underneath.\n this.#db.assertUsable();\n const cached = this.#cache;\n if (cached !== undefined) return cached;\n\n const populated: Cache = {\n alarmTime: this.#getAlarmUncached(),\n };\n this.#cache = populated;\n return populated;\n }\n\n #getAlarmUncached(): number | null {\n if (!this.#tableCreated) return null;\n\n const row = this.#db.run(STMT.getAlarm).rawRows[0];\n if (row === undefined || isNull(row, 0)) return null;\n return getInt64(row, 0);\n }\n\n #setAlarmUncached(currentTime: number | null, allowUnconfirmed: boolean): void {\n this.#ensureInitialized(allowUnconfirmed);\n // Our getter code also allows representing an empty alarm value as a\n // missing row or table, but a null-value row seems efficient and simple.\n this.#db.run({ allowUnconfirmed }, STMT.setAlarm, currentTime);\n }\n\n /**\n * Make sure the metadata table is created. Not called until the first write —\n * except by the bookmark getter, which is upstream's shape too.\n */\n #ensureInitialized(allowUnconfirmed: boolean): void {\n if (this.#tableCreated) return;\n\n this.#db.run({ allowUnconfirmed }, CREATE_TABLE);\n this.#tableCreated = true;\n this.#db.onRollback(() => {\n this.#tableCreated = false;\n });\n }\n}\n","/**\n * ← workerd `src/workerd/io/actor-sqlite.{h,c++}`\n *\n * The storage engine. Owns:\n * - implicit transactions, bounded by GATE RELEASE rather than by an\n * event-loop turn (§1.7.1 — measured; a storage await does not end the\n * transaction, a timer or outbound await does);\n * - `onWrite` taking the output-gate lock at the first must-confirm write,\n * one lock per flush batch;\n * - `transactionSync` as SAVEPOINT/RELEASE/ROLLBACK TO with a depth counter,\n * plus the async-callback guard today's version lacks;\n * - alarm arm/consume/deferred-deletion, and `deleteAll`.\n *\n * Sole `ActorCacheInterface` implementation, exactly as on workerd-with-SQLite.\n *\n * The single most important constraint in the whole port lives here: the\n * transaction boundary and the gate boundary are the same line. Implement them\n * as one mechanism. Release at every await — the naive reading of §1.2 — and\n * every multi-statement write silently loses atomicity, with nothing failing\n * until a crash lands between two statements that were meant to be one.\n *\n * **How that one line is drawn here, since it is the question the design record\n * left open.** Upstream needs no gate hook: `startImplicitTxn` wraps the commit\n * in `kj::evalLater`, which runs it on the next turn of the KJ event loop, and\n * the next KJ turn is by construction after the isolate run — which is after\n * `js.runMicrotasks()`, which is after `KJ_DEFER` clears `currentInputLock`.\n * \"Next turn\" and \"gate release\" are one boundary upstream, so `ActorSqlite`\n * hangs the commit on the cheaper of the two. They are one boundary here for the\n * same reason, provided the commit rides `atCheckpointEnd` — the primitive\n * `io-context.ts` releases on. Its comment carries the proof; the short form is\n * that holding the lock across an await is a pure microtask chain and releasing\n * it always costs a hand-off, so no write can cross a hand-off inside one\n * transaction and no two events can share one. `IoContext` therefore grows no\n * per-invocation exit notification, and the root gate's `inputGateReleased` hook\n * is *not* the right edge: it fires when `lockCount` hits zero, which never\n * happens inside a critical section, so decision 4's fifteen boot phases would\n * become a single transaction nobody chose.\n *\n * `onWrite` and `onCriticalError` are `SqliteDatabase`'s, in `util/sqlite.ts`,\n * exactly as upstream has them, and the constructor binds itself to both the way\n * `ActorSqlite`'s does. What is ours is only the substitute for the question\n * upstream answers with `sqlite3_stmt_readonly()` — see `isWrite` there.\n *\n * Not ported, because the substrate has no equivalent to port onto: `SpanParent`\n * tracing, already a Section 1 divergence, so every `traceSpan` parameter and\n * `currentCommitSpan` with it; `debugAlarmSync` and every `LOG_*`, which are a\n * logger this package does not have; and `TxnCommitRegulator::onError`, which\n * re-reports `SQLITE_CONSTRAINT` during commit as a user-visible error — error\n * codes do not cross the backend seam, the same reason Section 3 dropped\n * `SqliteKvRegulator::onError`.\n *\n * Spec: §1.4, §1.7, §1.7.1, §1.8, §2.4, §2.6, decisions 2, 5, 6 and 7 in\n * docs/decisions.md.\n */\n\nimport type {\n ActorCacheInterface,\n ActorCacheTransaction,\n ArmAlarmResult,\n DeferredAlarmDeleter,\n DeleteAllOptions,\n DeleteAllResults,\n GetResultList,\n Key,\n KeyValuePair,\n ReadOptions,\n Value,\n WriteOptions,\n} from \"./actor-cache\";\nimport {\n PITR_UNIMPLEMENTED_MESSAGE,\n REPLICATION_UNIMPLEMENTED_MESSAGE,\n SHUTDOWN_ERROR_MESSAGE,\n} from \"./actor-cache\";\nimport { atCheckpointEnd } from \"./io-context\";\nimport type { OutputGate } from \"./io-gate\";\nimport { SqliteKv } from \"../util/sqlite-kv\";\nimport { SqliteMetadata } from \"../util/sqlite-metadata\";\nimport { type SqliteCriticalError, SqliteDatabase } from \"../util/sqlite\";\n\n/**\n * The alarm port — one outbound method, matching upstream's seam exactly.\n *\n * Everything else about alarms is runtime-internal: arm/consume semantics here,\n * retry ladder and serialised delivery in `server/alarm-scheduler.ts`. Delivery\n * comes back IN through `ActorContainer.deliverAlarm`, not through this port.\n */\nexport interface AlarmOutlet {\n /**\n * Must be durable before the returned promise resolves.\n *\n * `priorTask` is upstream's second parameter and is load bearing rather than\n * decorative: \"any work we must wait on prior to scheduling the new request,\n * as of this writing, this would be the alarmLaterInFlight promise, which\n * tracks any in-flight request to move the alarm 'later' than is currently\n * set.\" An implementation that ignores it can send a move-earlier request\n * concurrently with a move-later one and lose the ordering invariant that the\n * scheduled alarm is always at or before the persisted one.\n *\n * May throw synchronously; `ActorSqlite` relies on it, because a scheduling\n * failure has to reach the caller before the local database commits.\n */\n scheduleRun(newAlarmTime: number | null, priorTask: Promise<void>): Promise<void>;\n}\n\n/** ← `ActorSqlite::Hooks::DEFAULT`, whose `scheduleRun` refuses. */\nexport const DEFAULT_ALARM_OUTLET: AlarmOutlet = {\n scheduleRun(): Promise<void> {\n throw new Error(\"alarms are not yet implemented for SQLite-backed Durable Objects\");\n },\n};\n\n// =======================================================================================\n// The anonymous namespace at the top of actor-sqlite.c++\n\n/** Returns true if a given (set or unset) alarm will fire earlier than another. */\nfunction willFireEarlier(alarm1: number | null, alarm2: number | null): boolean {\n // Intuitively, an unset alarm is effectively indistinguishable from an alarm set at infinity.\n return (alarm1 ?? Infinity) < (alarm2 ?? Infinity);\n}\n\n/**\n * Set options.allowUnconfirmed to false and log a reason why.\n *\n * Upstream mutates the caller's bag and logs; there is no logger here and the\n * bag belongs to the caller, so the disabled copy is returned instead.\n */\nfunction disableAllowUnconfirmed(options: WriteOptions, _reason: string): WriteOptions {\n return { ...options, allowUnconfirmed: false };\n}\n\n/**\n * ← `kj::evalLater`, which is where upstream's implicit transaction commits.\n *\n * See `atCheckpointEnd` in `io-context.ts` for why that primitive and not\n * `queueMicrotask`, `setTimeout`, or a hook on the input gate.\n */\nfunction evalLater<T>(func: () => Promise<T>): Promise<T> {\n const { promise, resolve, reject } = Promise.withResolvers<T>();\n atCheckpointEnd(() => {\n func().then(resolve, reject);\n });\n return promise;\n}\n\n/**\n * ← `kj::TaskSet` plus its `ErrorHandler`. `ActorSqlite` owns one of its own,\n * separate from `IoContext`'s, exactly as upstream does.\n */\nclass TaskSet {\n readonly #tasks = new Set<Promise<void>>();\n readonly #taskFailed: (exception: unknown) => void;\n\n constructor(taskFailed: (exception: unknown) => void) {\n this.#taskFailed = taskFailed;\n }\n\n add(promise: Promise<void>): void {\n const task = promise.then(\n () => {\n this.#tasks.delete(task);\n },\n (exception: unknown) => {\n this.#tasks.delete(task);\n this.#taskFailed(exception);\n },\n );\n this.#tasks.add(task);\n }\n}\n\n// =======================================================================================\n// ActorSqlite\n\n/** ← `kj::OneOf<NoTxn, ImplicitTxn*, ExplicitTxn*>`. */\ntype CurrentTxn =\n | { readonly kind: \"none\" }\n | { readonly kind: \"implicit\"; readonly txn: ImplicitTxn }\n | { readonly kind: \"explicit\"; readonly txn: ExplicitTxn };\n\nconst NO_TXN: CurrentTxn = { kind: \"none\" };\n\n/** ← `ActorSqlite::PrecommitAlarmState`. */\ntype PrecommitAlarmState = {\n /** Promise for the completion of precommit alarm scheduling */\n schedulingPromise?: Promise<void>;\n};\n\n/**\n * An implementation of ActorCacheOps that is backed by SqliteKv.\n *\n * Constructing one arranges to honor the output gate, that is, any writes to the\n * database which occur without any `await`s in between will automatically be\n * combined into a single atomic write. This is accomplished using transactions.\n * In addition to ensuring atomicity, this tends to improve performance, as\n * SQLite is able to coalesce writes across statements that modify the same page.\n *\n * `commitCallback` will be invoked after committing a transaction. The output\n * gate will block on the returned promise. This can be used e.g. when the\n * database needs to be replicated to other machines before being considered\n * durable.\n *\n * Members upstream marks `private` and reaches through `ImplicitTxn` and\n * `ExplicitTxn`, which are nested classes with implicit friendship, are ordinary\n * members here for the reason `io-gate.ts` gives: TypeScript has no friendship,\n * and the boundary that actually holds is the package facade in `src/index.ts`.\n */\nexport class ActorSqlite implements ActorCacheInterface {\n /** Upstream-private; reached by the two transaction classes. */\n readonly db: SqliteDatabase;\n /** Upstream-private; reached by the two transaction classes. */\n readonly outputGate: OutputGate;\n /** Upstream-private; reached by the two transaction classes. */\n readonly commitTasks: TaskSet;\n readonly #kv: SqliteKv;\n readonly #metadata: SqliteMetadata;\n\n readonly #commitCallback: () => Promise<void>;\n readonly #hooks: AlarmOutlet;\n\n /** Upstream-private; the transaction classes read it to skip their rollback. */\n broken: unknown | undefined;\n\n /**\n * When set to `none`, there is no transaction outstanding.\n *\n * When set to an `ImplicitTxn`, an implicit transaction is currently open,\n * owned by `commitTasks`. If there is a need to commit this early, e.g. to\n * start an explicit transaction, that can be done through this reference.\n *\n * When set to an `ExplicitTxn`, an explicit transaction is currently open, so\n * no implicit transactions should be used in the meantime.\n */\n currentTxn: CurrentTxn = NO_TXN;\n\n /** If true, then a commit is scheduled as a result of deleteAll() having been called. */\n #deleteAllCommitScheduled = false;\n\n /**\n * State for tracking completion of all commits (both confirmed and\n * unconfirmed) for implementing sync() in onNoPendingFlush.\n *\n * Upstream-private; `ExplicitTxn::commit` replaces it.\n */\n lastCommit: Promise<void> = Promise.resolve();\n\n /**\n * We need to track some additional alarm state to guarantee at-least-once\n * alarm delivery: within an alarm handler, we want the observable alarm state\n * to look like the running alarm was deleted at the start of the handler (when\n * armAlarmHandler() is called), but we don't actually want to persist that\n * deletion until after the handler has successfully completed.\n *\n * Upstream-private; `ExplicitTxn::commit` clears it when the txn was alarm-dirty.\n */\n haveDeferredDelete = false;\n\n /** Some state only used for tracking calling invariants. */\n #inAlarmHandler = false;\n\n /** The alarm state for which we last received confirmation that the db was durably stored. */\n #lastConfirmedAlarmDbState: number | null;\n\n /**\n * The latest time we'd expect a scheduled alarm to fire, given the current set\n * of in-flight scheduling requests, without yet knowing if any of them\n * succeeded or failed. We use this value to maintain the invariant that the\n * scheduled alarm is always equal to or earlier than the alarm value in the\n * persisted database state.\n */\n #alarmScheduledNoLaterThan: number | null;\n\n /** A promise for an in-progress alarm notification update and database commit. */\n #pendingCommit: Promise<void> | undefined;\n\n /**\n * Promise for the currently in-flight \"move alarm later\" operation, if any.\n * Used to serialize move-earlier operations against any pending move-later\n * operation.\n */\n #alarmLaterInFlight: Promise<void> = Promise.resolve();\n\n /** True when a \"move alarm later\" request is currently in-flight via scheduleLaterAlarm(). */\n #alarmLaterIsInFlight = false;\n\n /**\n * When a \"move alarm later\" request is already in-flight and we need to\n * schedule another one, we store the desired alarm time here. When the\n * in-flight request completes, it checks this variable and starts a new\n * request if needed. `undefined` means there is no pending time at all; null\n * means \"clear the alarm\".\n */\n #pendingLaterAlarmTime: number | null | undefined;\n\n /**\n * Version counter that increments on every alarm change. Used to detect if\n * another commit modified the alarm while we were async, allowing us to skip\n * redundant post-commit alarm syncs. This provides automatic coalescing of\n * rapid alarm changes.\n */\n #alarmVersion = 0;\n\n /** ← `DurableObjectStorage::transactionSyncDepth`; see `transactionSync`. */\n #transactionSyncDepth = 0;\n\n constructor(\n db: SqliteDatabase,\n outputGate: OutputGate,\n commitCallback: () => Promise<void>,\n hooks: AlarmOutlet = DEFAULT_ALARM_OUTLET,\n ) {\n this.db = db;\n this.outputGate = outputGate;\n this.#commitCallback = commitCallback;\n this.#hooks = hooks;\n this.#kv = new SqliteKv(db);\n this.#metadata = new SqliteMetadata(db);\n this.commitTasks = new TaskSet((exception) => {\n this.#taskFailed(exception);\n });\n\n db.onWrite((allowUnconfirmed) => {\n this.#onWrite(allowUnconfirmed);\n });\n db.onCriticalError((exception) => {\n this.#onCriticalError(exception);\n });\n this.#lastConfirmedAlarmDbState = this.#metadata.getAlarm();\n\n // Because we preserve an invariant that scheduled alarms are always at or earlier than\n // persisted db alarm state, it should be OK to populate our idea of the latest scheduled alarm\n // using the current db alarm state. At worst, it may perform one unnecessary scheduling\n // request in cases where a previous alarm-state-altering transaction failed.\n this.#alarmScheduledNoLaterThan = this.#metadata.getAlarm();\n }\n\n isCommitScheduled(): boolean {\n return this.currentTxn.kind !== \"none\" || this.#deleteAllCommitScheduled;\n }\n\n getSqliteDatabase(): SqliteDatabase {\n return this.db;\n }\n\n getSqliteKv(): SqliteKv {\n this.requireNotBroken();\n return this.#kv;\n }\n\n // -----------------------------------------------------------------\n // Transaction plumbing\n\n #onCriticalError(exception: SqliteCriticalError): void {\n // If we have already experienced a terminal exception, no need to replace it\n if (this.broken === undefined) {\n const broken = new Error(`broken.outputGateBroken; ${exception.message}`, {\n cause: exception,\n });\n this.broken = broken;\n\n // Also ensure output gate is explicitly broken.\n this.commitTasks.add(this.outputGate.lockWhile(Promise.reject(broken)));\n }\n }\n\n #startImplicitTxn(): void {\n const txn = new ImplicitTxn(this);\n\n // We implement the magic of accumulating all of the writes between JavaScript awaits in one\n // transaction by wrapping the commit function with evalLater, which runs the function on the\n // next turn of the event loop.\n const commitPromise = evalLater(async (): Promise<void> => {\n try {\n // Don't commit if shutdown() has been called.\n this.requireNotBroken();\n\n // Start the schedule request before commit(), for correctness in workerd.\n const precommitAlarmState = this.startPrecommitAlarmScheduling();\n\n try {\n txn.commit();\n } catch (exception) {\n // HACK: If we became broken during `COMMIT TRANSACTION` then throw the broken exception\n // instead of whatever SQLite threw.\n this.requireNotBroken();\n\n // No, we're not broken, so propagate the exception as-is.\n throw exception;\n }\n\n // The callback is only expected to commit writes up until this point. Any new writes that\n // occur while the callback is in progress are NOT included, therefore require a new commit\n // to be scheduled. So, we should drop `txn` to cause `currentTxn` to become NoTxn now,\n // rather than after the callback.\n txn.drop();\n\n await this.commitImpl(precommitAlarmState);\n } finally {\n // ← the coroutine frame's destruction, which rolls the transaction back on any path that\n // did not reach the drop above.\n txn.drop();\n }\n }).catch(async (exception: unknown): Promise<void> => {\n // Unconditionally break the output gate if commit threw an error, no matter whether the\n // commit was confirmed or unconfirmed.\n await this.outputGate.lockWhile(Promise.reject(exception));\n });\n\n this.commitTasks.add(commitPromise);\n\n // Commits must be executed in order, so we only have to track the most recent commit promise.\n this.lastCommit = commitPromise;\n }\n\n #onWrite(allowUnconfirmed: boolean): void {\n this.requireNotBroken();\n if (this.currentTxn.kind === \"none\") {\n this.#startImplicitTxn();\n }\n\n // Update the status of the current transaction.\n const current = this.currentTxn;\n switch (current.kind) {\n case \"none\":\n throw new Error(\"we must have a transaction at this point\");\n case \"implicit\":\n if (!current.txn.isSomeWriteConfirmed() && !allowUnconfirmed) {\n // This is adding a must-confirm write to the transaction, so we must ensure the\n // outputGate locks for remainder of this transaction.\n current.txn.setSomeWriteConfirmed(true);\n this.commitTasks.add(this.outputGate.lockWhile(this.lastCommit));\n }\n break;\n case \"explicit\":\n if (!current.txn.isSomeWriteConfirmed() && !allowUnconfirmed) {\n // ExplicitTxns don't have a pending commit and don't lock the output gate during the\n // transaction, so there's nothing to do here.\n current.txn.setSomeWriteConfirmed(true);\n }\n break;\n }\n }\n\n // -----------------------------------------------------------------\n // Alarm scheduling\n\n /**\n * Issues a request to the alarm scheduler for the given time, returning a\n * promise that resolves when the request is confirmed.\n *\n * Not an `async` function, because it is important for correctness that a\n * synchronously thrown exception in scheduleRun() can escape synchronously to\n * the caller.\n */\n #requestScheduledAlarm(requestedTime: number | null, priorTask: Promise<void>): Promise<void> {\n const movingAlarmLater = willFireEarlier(this.#alarmScheduledNoLaterThan, requestedTime);\n if (movingAlarmLater) {\n // Since we are setting the alarm to be later, we can update alarmScheduledNoLaterThan\n // immediately and still preserve the invariant that the scheduled alarm time is equal to or\n // earlier than the persisted db alarm value.\n this.#alarmScheduledNoLaterThan = requestedTime;\n }\n\n return this.#hooks.scheduleRun(requestedTime, priorTask).then(() => {\n if (!movingAlarmLater) {\n this.#alarmScheduledNoLaterThan = requestedTime;\n }\n });\n }\n\n /**\n * Schedules a \"move alarm later\" operation. If no move-later is currently\n * in-flight, starts one immediately. If one is already in-flight, stores the\n * desired time in `pendingLaterAlarmTime` so it will be picked up when the\n * current in-flight operation completes.\n */\n #scheduleLaterAlarm(newAlarmTime: number | null): void {\n if (this.#alarmLaterIsInFlight) {\n // There's already a move-later request in-flight. Just store the desired time; the in-flight\n // request's completion handler will pick it up and start a new request. This overwrites any\n // previously pending time, which is fine -- only the latest value matters.\n this.#pendingLaterAlarmTime = newAlarmTime;\n return;\n }\n\n this.#alarmLaterIsInFlight = true;\n this.#alarmLaterInFlight = this.#requestScheduledAlarm(\n newAlarmTime,\n this.#alarmLaterInFlight,\n ).catch(() => {\n // If an exception occurs when scheduling the alarm later, it's OK -- the alarm will\n // eventually fire at the earlier time, and the rescheduling will be retried.\n // We catch here to prevent the chain from breaking on errors.\n });\n\n this.commitTasks.add(\n this.#alarmLaterInFlight\n .then(() => {\n this.#alarmLaterIsInFlight = false;\n const nextTime = this.#pendingLaterAlarmTime;\n if (nextTime !== undefined) {\n this.#pendingLaterAlarmTime = undefined;\n this.#scheduleLaterAlarm(nextTime);\n }\n })\n .catch(() => {\n // Move-later alarm failures are non-fatal; catch here to prevent taskFailed() from\n // breaking the output gate.\n }),\n );\n }\n\n /**\n * To be called just before committing the local sqlite db, to synchronously\n * start any necessary alarm scheduling.\n *\n * Upstream-private; `ExplicitTxn::commit` calls it for the root transaction.\n */\n startPrecommitAlarmScheduling(): PrecommitAlarmState {\n const state: PrecommitAlarmState = {};\n if (\n this.#pendingCommit === undefined &&\n willFireEarlier(this.#metadata.getAlarm(), this.#alarmScheduledNoLaterThan)\n ) {\n // We must wait on the `alarmLaterInFlight` promise here, otherwise, if there is an in-flight\n // \"move later\" alarm task and it fails, our \"move earlier\" alarm might interleave, succeed,\n // and be followed by a retry of the in-flight \"move later\" alarm.\n //\n // Clear any pending move-later alarm time. Since we are about to move the alarm earlier, any\n // coalesced later time is now obsolete. This also prevents the scheduleLaterAlarm completion\n // handler from starting a concurrent scheduleRun when it drains pendingLaterAlarmTime after\n // the current in-flight request resolves.\n this.#pendingLaterAlarmTime = undefined;\n state.schedulingPromise = this.#requestScheduledAlarm(\n this.#metadata.getAlarm(),\n this.#alarmLaterInFlight,\n );\n }\n return state;\n }\n\n /**\n * Performs the rest of the asynchronous commit, to be waited on after\n * committing the local sqlite db. Should be called in the same turn of the\n * event loop as startPrecommitAlarmScheduling() and passed the state that it\n * returned.\n *\n * Upstream-private; `ExplicitTxn::commit` calls it for the root transaction.\n */\n async commitImpl(precommitAlarmState: PrecommitAlarmState): Promise<void> {\n // We assume that exceptions thrown during commit will propagate to the caller, such that they\n // will ensure cancelDeferredAlarmDeletion() is called, if necessary.\n\n const pending = this.#pendingCommit;\n if (pending !== undefined) {\n // If an earlier commitImpl() invocation is already in the process of updating precommit\n // alarms but has not yet made the commitCallback() call, it should be OK to wait on it to\n // perform the precommit alarm update and db commit for this invocation, too.\n await pending;\n return;\n }\n\n // There are no pending commits in-flight, so we set up a promise that other callers can wait\n // on, to perform the alarm scheduling and database persistence work for all of them. If an\n // exception is thrown below, it is propagated to the other waiters before it is rethrown, which\n // is what upstream gets from the fulfiller's destructor noticing the stack unwinding.\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n this.#pendingCommit = promise;\n void promise.catch(() => {});\n\n try {\n // Wait for the first precommit alarm scheduling request to complete, if any. This was set up\n // in startPrecommitAlarmScheduling() and is essentially the first iteration of the below\n // loop, but needed to be initiated synchronously before the local database commit to ensure\n // correctness in workerd.\n if (precommitAlarmState.schedulingPromise !== undefined) {\n await precommitAlarmState.schedulingPromise;\n }\n\n // While the local db state requires an earlier alarm than is known might be scheduled, issue\n // an alarm update request for the earlier time and wait for it to complete. This helps ensure\n // that the successfully scheduled alarm time is always earlier or equal to the alarm state in\n // the successfully persisted db.\n //\n // Note that we do not pass alarmLaterInFlight here: we already waited for it above, and\n // `pendingCommit` was set before yielding, so no one could have started another \"move-later\"\n // alarm until we finish.\n while (willFireEarlier(this.#metadata.getAlarm(), this.#alarmScheduledNoLaterThan)) {\n await this.#requestScheduledAlarm(this.#metadata.getAlarm(), Promise.resolve());\n }\n\n // Issue the commitCallback() request to persist the db state, then synchronously clear the\n // pending commit so that the next commitImpl() invocation starts its own set of precommit\n // alarm updates and db commit.\n const alarmStateForCommit = this.#metadata.getAlarm();\n\n // Capture the alarm version before going async to detect concurrent alarm changes. If the\n // alarmVersion changes while we are in-flight, we should skip attempting any move-later alarm\n // update.\n const alarmVersionBeforeAsync = this.#alarmVersion;\n\n const commitCallbackPromise = this.#commitCallback();\n this.#pendingCommit = undefined;\n\n // Wait for the db to persist.\n await commitCallbackPromise;\n this.#lastConfirmedAlarmDbState = alarmStateForCommit;\n\n // Notify any merged commitImpl() requests that the db persistence completed.\n resolve();\n\n // If another commit modified the alarm while we were async, skip post-commit alarm sync.\n //\n // 1. The other commit will handle its own alarm sync\n // 2. Post-commit syncs are inherently optional (the alarm will self-correct)\n // 3. This coalesces redundant alarm updates for better performance\n // 4. This avoids race conditions where a later commit moved the alarm earlier, requiring a\n // pre-commit alarm update, and this update may have already been made before we get here.\n if (this.#alarmVersion === alarmVersionBeforeAsync) {\n // No intervening alarm changes, it is safe to schedule a move-later alarm update if needed.\n if (willFireEarlier(this.#alarmScheduledNoLaterThan, alarmStateForCommit)) {\n this.#scheduleLaterAlarm(alarmStateForCommit);\n }\n }\n } catch (exception) {\n // Upstream leaves `pendingCommit` holding the now-rejected forked promise rather than\n // clearing it: a merged commit still has to see the failure, and by this point the output\n // gate is breaking anyway.\n reject(exception);\n throw exception;\n }\n }\n\n #taskFailed(exception: unknown): void {\n // The output gate should already have been broken since it wraps all commit tasks that can\n // throw. So, we don't have to report anything here, the exception will already propagate\n // elsewhere. We should block further operations, though.\n if (this.broken === undefined) {\n this.broken = exception;\n }\n }\n\n /** Upstream-private; the transaction classes call it before touching the db. */\n requireNotBroken(): void {\n if (this.broken !== undefined) {\n throw this.broken;\n }\n }\n\n /** Called when the deferred alarm deleter is dropped, to delete the alarm if not reset or cancelled during the handler. */\n #maybeDeleteDeferredAlarm(): void {\n // Upstream warns when this runs outside a handler (\"pretty sure this can't happen\"); there is\n // no logger, and the state update below is what the warning accompanies rather than guards.\n this.#inAlarmHandler = false;\n\n if (this.haveDeferredDelete) {\n // If we have reached this point, the client is destroying its DeferredAlarmDeleter at the end\n // of an alarm handler run, and deletion hasn't been cancelled, indicating that the handler\n // returned success.\n //\n // If the output gate has somehow broken in the interim, attempting to write the deletion here\n // will cause the drop to throw, which the caller probably isn't expecting. So we'll skip the\n // deletion attempt, and let the caller detect the gate brokenness through other means.\n if (this.broken === undefined) {\n // The safe thing to do is to require confirmation.\n if (this.#metadata.setAlarm(null, false)) {\n this.#alarmVersion += 1;\n }\n }\n this.haveDeferredDelete = false;\n }\n }\n\n // =======================================================================================\n // ActorCacheInterface implementation\n\n get(key: Key, _options: ReadOptions = {}): Value | undefined {\n this.requireNotBroken();\n return this.#kv.get(key);\n }\n\n getMultiple(keys: readonly Key[], _options: ReadOptions = {}): GetResultList {\n this.requireNotBroken();\n\n const results: KeyValuePair[] = [];\n for (const key of keys) {\n const value = this.#kv.get(key);\n if (value !== undefined) results.push({ key, value });\n }\n results.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));\n return results;\n }\n\n getAlarm(_options: ReadOptions = {}): number | null {\n this.requireNotBroken();\n\n let transactionAlarmDirty = false;\n if (this.currentTxn.kind === \"explicit\") {\n transactionAlarmDirty = this.currentTxn.txn.getAlarmDirty();\n }\n\n if (this.haveDeferredDelete && !transactionAlarmDirty) {\n // If an alarm handler is currently running, and a new alarm time has not been set yet, we\n // need to return that there is no alarm.\n return null;\n }\n return this.#metadata.getAlarm();\n }\n\n list(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n _options: ReadOptions = {},\n ): GetResultList {\n this.requireNotBroken();\n\n const results: KeyValuePair[] = [];\n this.#kv.list(begin, end, limit, \"FORWARD\", (key, value) => {\n results.push({ key, value });\n });\n\n // Already guaranteed sorted.\n return results;\n }\n\n listReverse(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n _options: ReadOptions = {},\n ): GetResultList {\n this.requireNotBroken();\n\n const results: KeyValuePair[] = [];\n this.#kv.list(begin, end, limit, \"REVERSE\", (key, value) => {\n results.push({ key, value });\n });\n\n // Already guaranteed sorted (reversed).\n return results;\n }\n\n put(key: Key, value: Value, options: WriteOptions = {}): void {\n this.requireNotBroken();\n this.#kv.put(key, value, { allowUnconfirmed: options.allowUnconfirmed ?? false });\n }\n\n putMultiple(pairs: readonly KeyValuePair[], options: WriteOptions = {}): void {\n this.requireNotBroken();\n if (this.currentTxn.kind === \"none\") {\n // If we are not in a transaction, start an ImplicitTxn since that's what would happen on the\n // first write anyway. `SqliteKv::put(pairs)` opens with a SAVEPOINT, which is not a write, so\n // without this the savepoint would stand alone instead of nesting inside the transaction.\n this.#startImplicitTxn();\n }\n if (this.currentTxn.kind === \"none\") {\n throw new Error(\"we must have a transaction at this point\");\n }\n\n this.#kv.put(pairs, { allowUnconfirmed: options.allowUnconfirmed ?? false });\n }\n\n delete(key: Key, options: WriteOptions = {}): boolean {\n this.requireNotBroken();\n return this.#kv.delete(key, { allowUnconfirmed: options.allowUnconfirmed ?? false });\n }\n\n deleteMultiple(keys: readonly Key[], options: WriteOptions = {}): number {\n this.requireNotBroken();\n\n let count = 0;\n for (const key of keys) {\n if (this.#kv.delete(key, { allowUnconfirmed: options.allowUnconfirmed ?? false })) count += 1;\n }\n return count;\n }\n\n setAlarm(newAlarmTime: number | null, options: WriteOptions = {}): void {\n this.requireNotBroken();\n\n // Only increment version counter if the alarm value actually changed. This is important because\n // if the value didn't change, no SQLite write occurs, so no implicit transaction is started,\n // and we don't want to invalidate in-flight commits without a replacement commit.\n if (this.#metadata.setAlarm(newAlarmTime, options.allowUnconfirmed ?? false)) {\n this.#alarmVersion += 1;\n }\n\n if (this.currentTxn.kind === \"explicit\") {\n this.currentTxn.txn.setAlarmDirty();\n } else {\n this.haveDeferredDelete = false;\n }\n }\n\n startTransaction(): ActorCacheTransaction {\n this.requireNotBroken();\n return new ExplicitTxn(this);\n }\n\n deleteAll(options: WriteOptions = {}, deleteAllOptions: DeleteAllOptions = {}): DeleteAllResults {\n this.requireNotBroken();\n const effectiveOptions = disableAllowUnconfirmed(options, \"deleteAll is not supported\");\n\n // kv.deleteAll() clears the database, so save and possibly restore the alarm state.\n const localAlarmState = this.#metadata.getAlarm();\n\n // deleteAll() cannot be part of a transaction because it deletes the database altogether. So,\n // we have to close our transactions or fail.\n const current = this.currentTxn;\n switch (current.kind) {\n case \"none\":\n // good\n break;\n case \"implicit\":\n // Whatever the implicit transaction did, it's about to be blown away anyway. Roll it back\n // so we don't waste time flushing these writes anywhere.\n current.txn.rollback();\n this.currentTxn = NO_TXN;\n break;\n case \"explicit\":\n // Keep in mind:\n //\n // ctx.storage.transaction(txn => {\n // txn.deleteAll(); // calls the transaction's deleteAll()\n // ctx.storage.deleteAll(); // calls this method\n // });\n //\n // Directly calling `ctx.storage` inside a transaction (as opposed to using the `txn`\n // object) should still be treated as part of the transaction, and so should throw the\n // same thing.\n throw new Error(\"Cannot call deleteAll() within a transaction\");\n }\n\n if (!this.#deleteAllCommitScheduled) {\n // Make sure a commit callback is queued for the deleteAll().\n this.commitTasks.add(\n this.outputGate.lockWhile(\n evalLater(async (): Promise<void> => {\n // Don't commit if shutdown() has been called.\n this.requireNotBroken();\n\n this.#deleteAllCommitScheduled = false;\n if (this.currentTxn.kind === \"implicit\") {\n // An implicit transaction is already scheduled, so we'll count on it to perform a\n // commit when it's done. This is particularly important for the case where\n // deleteAll() was called while an alarm is outstanding; resetting the alarm state\n // (below) starts an implicit transaction. We don't want to commit the deletion\n // without that transaction.\n return;\n }\n // Use commitImpl() rather than commitCallback() so that alarm scheduling is handled.\n // This is important when deleteAll() deletes an alarm: commitImpl() detects that\n // getAlarm() moved to null and notifies the scheduler via requestScheduledAlarm(null).\n const precommitAlarmState = this.startPrecommitAlarmScheduling();\n await this.commitImpl(precommitAlarmState);\n }),\n ),\n );\n this.#deleteAllCommitScheduled = true;\n }\n\n const count = this.#kv.deleteAll();\n\n // Reset alarm state, if necessary. If no alarm is set, leave the metadata table uninitialized.\n if (localAlarmState !== null) {\n if (deleteAllOptions.deleteAlarm === true) {\n // The reset already removed the alarm metadata. Bump the version so an in-flight commit\n // cannot perform stale post-commit scheduling, and let this commit sync the cancellation.\n this.#alarmVersion += 1;\n this.haveDeferredDelete = false;\n } else if (\n this.#metadata.setAlarm(localAlarmState, effectiveOptions.allowUnconfirmed ?? false)\n ) {\n this.#alarmVersion += 1;\n }\n }\n\n return { backpressure: undefined, count };\n }\n\n evictStale(_now: number): undefined {\n // This implementation never needs to apply backpressure.\n return undefined;\n }\n\n shutdown(exception?: unknown): void {\n if (this.broken === undefined) {\n // Any scheduled flushes will fail once the commit is invoked and notices that `broken` has a\n // value. Any in-flight flushes will continue to run in the background. Remember that these\n // in-flight flushes may or may not be awaited by the worker, but they still hold the output\n // lock as long as `allowUnconfirmed` wasn't used.\n this.broken = exception ?? new Error(SHUTDOWN_ERROR_MESSAGE);\n\n // We explicitly do not schedule a flush to break the output gate. This means that if a\n // request is ongoing after the actor cache is shutting down, the output gate is only broken\n // if they had to send a flush after shutdown, either from a scheduled flush or a retry after\n // failure.\n } else {\n // We've already experienced a terminal exception either from shutdown or OOM, there should\n // already be a flush scheduled that will break the output gate.\n }\n }\n\n armAlarmHandler(scheduledTime: number, currentTime: number): ArmAlarmResult {\n if (this.#inAlarmHandler) {\n throw new Error(\"armAlarmHandler() called while an alarm handler is already running\");\n }\n\n // Upstream warns when `haveDeferredDelete` is already set here (\"unlikely to happen, unless\n // caller is starting new alarm handler before previous alarm handler cleanup has completed\").\n\n const localAlarmState = this.#metadata.getAlarm();\n if (localAlarmState !== scheduledTime) {\n if (localAlarmState === this.#lastConfirmedAlarmDbState) {\n // If the local alarm time is already in the past, just run the handler now. This avoids\n // blocking alarm execution on the alarm manager sync when storage is overloaded. The alarm\n // will either delete itself on success or reschedule on failure.\n if (willFireEarlier(localAlarmState, currentTime)) {\n this.haveDeferredDelete = true;\n this.#inAlarmHandler = true;\n return { kind: \"run\", run: { deferredDelete: this.#newDeferredAlarmDeleter() } };\n }\n\n // If there's a clean db time that differs from the requested handler's scheduled time, this\n // run should be canceled.\n if (willFireEarlier(scheduledTime, localAlarmState)) {\n // If the handler's scheduled time is earlier than the clean scheduled time, we may be\n // recovering from a failed db commit or scheduling request, so we need to request that\n // the alarm be rescheduled for the current db time, and tell the caller to wait for\n // successful rescheduling before cancelling the current handler invocation.\n //\n // Since we're requesting to move the alarm time to later, we need to update the\n // alarmLaterInFlight promise. One branch feeds alarmLaterInFlight with error catching so\n // the chain remains usable, and the other is the returned promise, which propagates\n // errors to the caller. We update alarmLaterInFlight here rather than using\n // scheduleLaterAlarm(), because we need that separate un-caught branch.\n const schedulingPromise = this.#requestScheduledAlarm(\n localAlarmState,\n this.#alarmLaterInFlight,\n );\n // Clear any stale pending time so that when the existing completion handler fires it does\n // not start a redundant scheduleLaterAlarm for the same time that armAlarmHandler is\n // already scheduling.\n this.#pendingLaterAlarmTime = undefined;\n this.#alarmLaterInFlight = schedulingPromise.catch(() => {\n // If an exception occurs when scheduling the alarm later, it's OK -- the alarm will\n // eventually fire at the earlier time, and the rescheduling will be retried.\n });\n return { kind: \"cancel\", cancel: { waitBeforeCancel: schedulingPromise } };\n }\n\n // We have a clean local alarm time that is earlier than the handler's scheduled time, which\n // suggests that either the alarm manager is working with stale data or that the local alarm\n // time has somehow gotten out of sync with the scheduled alarm time.\n //\n // We pass a ready promise because being in this branch (SQLite is ahead of the alarm\n // manager) means there's no recent move-later operation to wait for.\n return {\n kind: \"cancel\",\n cancel: {\n waitBeforeCancel: this.#requestScheduledAlarm(localAlarmState, Promise.resolve()),\n },\n };\n }\n // There's an alarm write that hasn't been set yet pending for a time different than ours --\n // we won't cancel the alarm because it hasn't been confirmed, but we shouldn't delete the\n // pending write.\n this.haveDeferredDelete = false;\n } else {\n this.haveDeferredDelete = true;\n }\n this.#inAlarmHandler = true;\n\n return { kind: \"run\", run: { deferredDelete: this.#newDeferredAlarmDeleter() } };\n }\n\n cancelDeferredAlarmDeletion(): void {\n // Upstream warns when this runs outside a handler (\"pretty sure this can't happen\").\n this.haveDeferredDelete = false;\n }\n\n async abandonAlarm(scheduledTime: number): Promise<number | null> {\n // Called when the alarm scheduler has given up retrying an alarm after too many counted\n // failures. Clear the alarm from SQLite so getAlarm() returns null instead of a stale time.\n // Only clear if SQLite currently has the exact alarm being abandoned and we're not mid-handler.\n // The time check guards against the race where the user set a new alarm (which always has a\n // time >= now() > scheduledTime due to past-time clamping in setAlarm) before this call\n // arrived.\n if (this.#inAlarmHandler) {\n // Shouldn't happen -- the scheduler shouldn't call abandonAlarm while a handler is running.\n return null;\n }\n const storedTime = this.#metadata.getAlarm();\n if (storedTime !== null) {\n if (storedTime === scheduledTime) {\n this.setAlarm(null, {});\n return null;\n }\n // The user set a different alarm. Return it so the scheduler can re-register.\n return storedTime;\n }\n return null;\n }\n\n /**\n * This implements sync().\n *\n * sync() should wait for ALL writes (both confirmed and unconfirmed) that are\n * outstanding at the time sync() is called. We use lastCommit which keeps track\n * of the most recent commit to be formed. We join with the outputGate because\n * there are a lot of edge cases where we break the output gate and it's easiest\n * to catch all of those instances here rather than updating everything to also\n * break lastCommit.\n */\n async onNoPendingFlush(): Promise<void> {\n // ← `kj::joinPromisesFailFast`, which `Promise.all` already is.\n await Promise.all([this.lastCommit, this.outputGate.wait()]);\n }\n\n /**\n * This is an ersatz implementation that's good enough for local dev with D1's\n * Session API.\n *\n * The returned bookmark satisfies the properties that D1 cares about:\n *\n * * Later bookmarks sort after earlier bookmarks. We implement this by\n * incrementing the bookmark whenever getCurrentBookmark() is called.\n *\n * * Bookmarks from the current session sort after bookmarks from previous\n * sessions. We implement this by saving an ersatz bookmark in the metadata\n * table.\n *\n * This is NOT the point-in-time-recovery bookmark API, which is a substrate\n * boundary: it needs nothing the substrate lacks, which is exactly why Section\n * 3 ported `getLocalDevelopmentBookmark`/`setLocalDevelopmentBookmark`.\n */\n async getCurrentBookmark(): Promise<string> {\n this.requireNotBroken();\n let bookmark = 0;\n const stored = this.#metadata.getLocalDevelopmentBookmark();\n if (stored !== null) {\n bookmark = stored + 1;\n }\n this.#metadata.setLocalDevelopmentBookmark(bookmark);\n\n const paddedHex = (value: number): string => value.toString(16).padStart(8, \"0\");\n\n // Turn the bookmark into a format matching what Cloudflare's production returns.\n const uint32Max = 0xffff_ffff;\n return [\n paddedHex(Math.floor(bookmark / uint32Max)),\n paddedHex(bookmark % uint32Max),\n paddedHex(0),\n \"0\".repeat(32),\n ].join(\"-\");\n }\n\n async waitForBookmark(_bookmark: string): Promise<void> {\n // This is an ersatz implementation that's good enough for local dev with D1's Session API.\n this.requireNotBroken();\n }\n\n async getBookmarkForTime(_timestamp: number): Promise<string> {\n throw new Error(PITR_UNIMPLEMENTED_MESSAGE);\n }\n\n async onNextSessionRestoreBookmark(_bookmark: string): Promise<string> {\n throw new Error(PITR_UNIMPLEMENTED_MESSAGE);\n }\n\n ensureReplicas(): void {\n throw new Error(REPLICATION_UNIMPLEMENTED_MESSAGE);\n }\n\n disableReplicas(): void {\n throw new Error(REPLICATION_UNIMPLEMENTED_MESSAGE);\n }\n\n async configureReadReplication(_enabled: boolean): Promise<void> {\n throw new Error(REPLICATION_UNIMPLEMENTED_MESSAGE);\n }\n\n // =======================================================================================\n // transactionSync\n\n /**\n * ← `DurableObjectStorage::transactionSync` (`actor-state.c++:713-753`).\n *\n * One layer lower than upstream, which is where `util/sqlite.ts` already\n * records it belongs: the savepoint depth counter and `notifyWrite` both live\n * here, and `api/actor-state.ts`'s `transactionSync` becomes a one-line forward\n * the way `blockConcurrencyWhile` already is.\n *\n * The nesting guard §2.4 asks for is upstream's own and is the depth-named\n * savepoint: a second `BEGIN IMMEDIATE` is a SQLite error, a nested SAVEPOINT\n * is not, which is why this issues savepoints and lets the implicit transaction\n * underneath be the only `BEGIN`.\n *\n * The async-callback guard is ours and has no upstream twin, because upstream's\n * `jsg::Function<jsg::JsRef<jsg::JsValue>()>` callback cannot be awaited at\n * all: it returns a value, and a JS function that returns a promise simply has\n * its promise ignored. Here the same mistake is silent and corrupting — the\n * RELEASE fires at the first await and everything after it lands outside the\n * transaction — so a thenable result is refused and the savepoint rolled back.\n * Work the callback already started is not cancellable and keeps running; the\n * throw is what stops it being mistaken for transactional.\n */\n transactionSync<T>(callback: () => T): T {\n // SAVEPOINT is a readonly statement, but we need to trigger an outer TRANSACTION.\n this.db.notifyWrite();\n\n const depth = this.#transactionSyncDepth++;\n try {\n this.db.run(`SAVEPOINT _cf_sync_savepoint_${depth}`);\n try {\n const result = callback();\n\n if (isThenable(result)) {\n throw new Error(\n \"transactionSync() callback returned a promise. The transaction commits when the \" +\n \"callback returns, so everything after its first await would land outside it.\",\n );\n }\n\n // If a critical error forced an automatic rollback, we throw an exception to convey failure\n // to the caller of transactionSync(), even if the callback did not throw.\n if (this.db.observedCriticalError() !== undefined) {\n throw new Error(\"Cannot commit transaction due to an earlier SQL critical error\");\n }\n\n this.db.run(`RELEASE _cf_sync_savepoint_${depth}`);\n return result;\n } catch (exception) {\n // If a critical error forced an automatic rollback, we skip the rollback and release\n // attempt, because savepoints should already be released.\n if (this.db.observedCriticalError() === undefined) {\n this.db.run(`ROLLBACK TO _cf_sync_savepoint_${depth}`);\n this.db.run(`RELEASE _cf_sync_savepoint_${depth}`);\n }\n throw exception;\n }\n } finally {\n this.#transactionSyncDepth -= 1;\n }\n }\n\n #newDeferredAlarmDeleter(): DeferredAlarmDeleter {\n let dropped = false;\n return {\n drop: (): void => {\n if (dropped) throw new Error(\"the deferred alarm deleter was dropped twice\");\n dropped = true;\n this.#maybeDeleteDeferredAlarm();\n },\n };\n }\n}\n\nfunction isThenable(value: unknown): boolean {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) return false;\n return typeof (value as { then?: unknown }).then === \"function\";\n}\n\n// =======================================================================================\n// ImplicitTxn\n\n/** ← `ActorSqlite::ImplicitTxn`. */\nclass ImplicitTxn {\n readonly #parent: ActorSqlite;\n #committed = false;\n #dropped = false;\n\n /** True if any of the writes in this commit are confirmed writes. */\n #someWriteConfirmed = false;\n\n constructor(parent: ActorSqlite) {\n if (parent.currentTxn.kind !== \"none\") {\n throw new Error(\"an implicit transaction requires that no transaction is open\");\n }\n this.#parent = parent;\n parent.db.run(\"BEGIN TRANSACTION\");\n parent.currentTxn = { kind: \"implicit\", txn: this };\n }\n\n commit(): void {\n // Ignore redundant commit()s.\n if (!this.#committed) {\n this.#parent.db.run(\"COMMIT TRANSACTION\");\n this.#committed = true;\n }\n }\n\n rollback(): void {\n // As of this writing, rollback() is only called when the database is about to be reset.\n if (!this.#committed) {\n this.#parent.db.run(\"ROLLBACK TRANSACTION\");\n this.#committed = true;\n }\n }\n\n setSomeWriteConfirmed(someWriteConfirmed: boolean): void {\n this.#someWriteConfirmed = someWriteConfirmed;\n }\n\n isSomeWriteConfirmed(): boolean {\n return this.#someWriteConfirmed;\n }\n\n /** ← `~ImplicitTxn`. Idempotent, because the commit path drops before and after the callback. */\n drop(): void {\n if (this.#dropped) return;\n this.#dropped = true;\n\n const current = this.#parent.currentTxn;\n if (current.kind === \"implicit\" && current.txn === this) {\n this.#parent.currentTxn = NO_TXN;\n }\n if (!this.#committed && this.#parent.broken === undefined) {\n // Failed to commit, so roll back.\n //\n // This should only happen in cases of catastrophic error.\n this.#parent.db.run(\"ROLLBACK TRANSACTION\");\n }\n }\n}\n\n// =======================================================================================\n// ExplicitTxn\n\n/** ← `ActorSqlite::ExplicitTxn`. */\nclass ExplicitTxn implements ActorCacheTransaction {\n readonly #actorSqlite: ActorSqlite;\n readonly #parent: ExplicitTxn | undefined;\n readonly #depth: number;\n #hasChild = false;\n #committed = false;\n #dropped = false;\n #alarmDirty = false;\n /** True if any of the writes in this commit are confirmed writes. */\n #someWriteConfirmed = false;\n\n constructor(actorSqlite: ActorSqlite) {\n this.#actorSqlite = actorSqlite;\n\n const current = actorSqlite.currentTxn;\n if (current.kind === \"implicit\") {\n // An implicit transaction is open, commit it now because it would be weird if writes\n // performed before the explicit transaction started were postponed until the transaction\n // completes. Note that this isn't violating any atomicity guarantees because the transaction\n // API is async, and atomicity is only guaranteed over synchronous code.\n current.txn.commit();\n this.#parent = undefined;\n this.#depth = 0;\n } else if (current.kind === \"explicit\") {\n const exp = current.txn;\n if (exp.#hasChild) {\n throw new Error(\n \"critical section should have blocked creation of more than one child at a time\",\n );\n }\n this.#parent = exp;\n exp.#hasChild = true;\n this.#depth = exp.#depth + 1;\n this.#alarmDirty = exp.#alarmDirty;\n this.#someWriteConfirmed = exp.#someWriteConfirmed;\n } else {\n this.#parent = undefined;\n this.#depth = 0;\n }\n actorSqlite.currentTxn = { kind: \"explicit\", txn: this };\n\n // To support nested transactions, we assign each savepoint a name based on its nesting depth.\n actorSqlite.db.run(`SAVEPOINT _cf_savepoint_${this.#depth}`);\n }\n\n getAlarmDirty(): boolean {\n return this.#alarmDirty;\n }\n\n setAlarmDirty(): void {\n this.#alarmDirty = true;\n }\n\n setSomeWriteConfirmed(someWriteConfirmed: boolean): void {\n this.#someWriteConfirmed = someWriteConfirmed;\n }\n\n isSomeWriteConfirmed(): boolean {\n return this.#someWriteConfirmed;\n }\n\n commit(): void {\n const actor = this.#actorSqlite;\n actor.requireNotBroken();\n if (this.#hasChild) {\n throw new Error(\n \"critical sections should have prevented committing transaction while nested txn is \" +\n \"outstanding\",\n );\n }\n\n // Start the schedule request before root transaction commit(), for correctness in workerd.\n const precommitAlarmState =\n this.#parent === undefined ? actor.startPrecommitAlarmScheduling() : undefined;\n\n actor.db.run(`RELEASE _cf_savepoint_${this.#depth}`);\n this.#committed = true;\n\n const parent = this.#parent;\n if (parent !== undefined) {\n if (this.#alarmDirty) parent.#alarmDirty = true;\n if (this.#someWriteConfirmed) parent.#someWriteConfirmed = true;\n // No backpressure for SQLite.\n return;\n }\n\n if (this.#alarmDirty) {\n actor.haveDeferredDelete = false;\n }\n\n // We committed the root transaction, so it's time to signal any replication layer and lock the\n // output gate in the meantime.\n //\n // Unlike ImplicitTxn, which locks the output gate at the start of the first write that requires\n // confirmation, ExplicitTxn only locks when we're going to confirm the commit.\n if (precommitAlarmState === undefined) {\n throw new Error(\"a root transaction committed without precommit alarm state\");\n }\n let commitPromise = actor.commitImpl(precommitAlarmState).catch(\n async (exception: unknown): Promise<void> => {\n // Unconditionally break the output gate if commit threw an error, no matter whether the\n // commit was confirmed or unconfirmed.\n await actor.outputGate.lockWhile(Promise.reject(exception));\n },\n );\n if (this.#someWriteConfirmed) {\n commitPromise = actor.outputGate.lockWhile(commitPromise);\n }\n actor.commitTasks.add(commitPromise);\n actor.lastCommit = commitPromise;\n }\n\n rollback(): void {\n this.#actorSqlite.requireNotBroken();\n if (this.#hasChild) {\n throw new Error(\n \"Cannot roll back an outer transaction while a nested transaction is still running.\",\n );\n }\n if (!this.#committed) {\n this.#rollbackImpl();\n this.#committed = true;\n }\n }\n\n /** ← `~ExplicitTxn`. */\n drop(): void {\n if (this.#dropped) return;\n this.#dropped = true;\n\n let rollbackFailure: { readonly exception: unknown } | undefined;\n if (!this.#committed && this.#actorSqlite.broken === undefined) {\n // Assume rollback if not committed.\n try {\n this.#rollbackImpl();\n } catch (exception) {\n rollbackFailure = { exception };\n }\n }\n\n // ← the `KJ_DEFER([&]() noexcept {...})`: \"We'd better crash if any of this state update fails,\n // otherwise dangling pointers.\" It runs after the rollback no matter what. A JS `finally` that\n // throws would swallow the rollback's own exception, so the rollback's is held and rethrown\n // below instead; if the state update itself throws, that one wins, which is the same ordering\n // upstream's `noexcept` produces.\n if (this.#hasChild) {\n throw new Error(\"an explicit transaction was dropped while a nested one was outstanding\");\n }\n const current = this.#actorSqlite.currentTxn;\n if (current.kind !== \"explicit\" || current.txn !== this) {\n throw new Error(\"an explicit transaction was dropped out of order\");\n }\n const parent = this.#parent;\n if (parent !== undefined) {\n parent.#hasChild = false;\n this.#actorSqlite.currentTxn = { kind: \"explicit\", txn: parent };\n } else {\n this.#actorSqlite.currentTxn = NO_TXN;\n }\n\n if (rollbackFailure !== undefined) throw rollbackFailure.exception;\n }\n\n #rollbackImpl(): void {\n this.#actorSqlite.db.run(`ROLLBACK TO _cf_savepoint_${this.#depth}`);\n this.#actorSqlite.db.run(`RELEASE _cf_savepoint_${this.#depth}`);\n const parent = this.#parent;\n if (parent !== undefined) {\n this.#alarmDirty = parent.#alarmDirty;\n this.#someWriteConfirmed = parent.#someWriteConfirmed;\n } else {\n this.#alarmDirty = false;\n this.#someWriteConfirmed = false;\n }\n }\n\n // Implements ActorCacheOps. These all forward to the ActorSqlite instance.\n\n get(key: Key, options: ReadOptions = {}): Value | undefined {\n return this.#actorSqlite.get(key, options);\n }\n getMultiple(keys: readonly Key[], options: ReadOptions = {}): GetResultList {\n return this.#actorSqlite.getMultiple(keys, options);\n }\n getAlarm(options: ReadOptions = {}): number | null {\n return this.#actorSqlite.getAlarm(options);\n }\n list(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions = {},\n ): GetResultList {\n return this.#actorSqlite.list(begin, end, limit, options);\n }\n listReverse(\n begin: Key,\n end: Key | undefined,\n limit: number | undefined,\n options: ReadOptions = {},\n ): GetResultList {\n return this.#actorSqlite.listReverse(begin, end, limit, options);\n }\n put(key: Key, value: Value, options: WriteOptions = {}): void {\n this.#actorSqlite.put(key, value, options);\n }\n putMultiple(pairs: readonly KeyValuePair[], options: WriteOptions = {}): void {\n this.#actorSqlite.putMultiple(pairs, options);\n }\n delete(key: Key, options: WriteOptions = {}): boolean {\n return this.#actorSqlite.delete(key, options);\n }\n deleteMultiple(keys: readonly Key[], options: WriteOptions = {}): number {\n return this.#actorSqlite.deleteMultiple(keys, options);\n }\n setAlarm(newAlarmTime: number | null, options: WriteOptions = {}): void {\n this.#actorSqlite.setAlarm(newAlarmTime, options);\n }\n}\n","/**\n * ← workerd `src/workerd/io/worker.h` — `Worker::Actor::FacetManager` only\n * (`io/worker.h:901`).\n *\n * This file exists to settle a layering question the scaffolding got backwards.\n * The facet surface `api/actor-state.ts` consumes was declared in\n * `server/actor-container.ts`, which would give `api/` → `server/` a dependency\n * upstream does not have: `api/actor-state.c++` includes from `api/`, `io/` and\n * `jsg/` and from `server/` never, and the manager it reaches for is a nested\n * class of `Worker::Actor` in `io/worker.h`. Per the README's rule for a\n * legitimate upstream include crossing a wall, the reference widens to match\n * upstream rather than the files being reshuffled to avoid it.\n *\n * `FacetManager` is not the same interface as `server/actor-container.ts`'s\n * `FacetHost`, and conflating them is what produced the inverted dependency.\n * `FacetHost` is the substrate PLACEMENT port — where a facet runs, the callable\n * stub across that placement, and physical storage deletion — and it has no\n * upstream twin, because workerd's facets are in-process. `FacetManager` is the\n * package-owned layer above it that owns naming, ids, the limits, receipts and\n * `clone()` orchestration, and it is the only facet thing `api/` may see.\n * `server/` implements it on top of `FacetHost`.\n *\n * The rest of `worker.h` — `Worker`, `Worker::Isolate`, `Worker::Lock`,\n * `Worker::Actor` itself — is isolate machinery with no port. The three\n * `Worker::Actor` members `io/io-context.ts` reaches for are declared there, as\n * that file's own comment explains; `assertCanSetAlarm()` joins them because\n * `api/actor-state.c++` reaches for it through\n * `IoContext::current().getActorOrThrow()`.\n *\n * Spec: §1.10, decision 14 in docs/decisions.md.\n */\n\nimport type { ActorClassChannel } from \"./io-channels\";\n\n/**\n * ← `Worker::Actor::FacetManager::StartInfo`.\n *\n * `actorClass` is upstream's own type — a resolved\n * `IoChannelFactory::ActorClassChannel`, which `io/io-channels.ts` ports and\n * `DurableObjectClass.getChannel()` produces. An earlier revision typed it as\n * `DurableObjectClass`, the `@cloudflare/workers-types` interface, which is\n * declared `interface DurableObjectClass<_T> {}` and therefore accepts any\n * object at all: it was `unknown` with a name, and it left `server/` with\n * nothing to resolve a class against. Upstream resolves it one step earlier —\n * `DurableObjectFacets::get` calls `actorClass.getChannel(ioCtx)` inside the\n * reentry callback (`actor-state.c++:1044`) — so `api/actor-state.ts` now does\n * the same and this field carries the resolved channel.\n *\n * `id` is upstream's `Worker::Actor::Id` as its stable name when present, or\n * the string form of an unnamed `DurableObjectId`.\n */\nexport type FacetStartInfo = {\n readonly actorClass: ActorClassChannel;\n /** `ctx.id` for the child. Defaults to the parent's, as upstream's does. */\n readonly id: string;\n};\n\n/**\n * ← `Worker::Actor::FacetManager` (`io/worker.h:901-931`).\n *\n * Upstream's comment on the last three: \"These methods are C++ equivalents of\n * the JavaScript ctx.facets API.\"\n *\n * `cloneFacet` is the fourth, and it is not in the vendored C++ snapshot — see\n * the note on `DurableObjectFacets.clone` in `api/actor-state.ts`.\n */\nexport interface FacetManager {\n /** Returns the nesting depth of this facet. Root = 0, direct child of root = 1, etc. */\n getDepth(): number;\n\n getFacet<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name: string,\n getStartInfo: () => Promise<FacetStartInfo>,\n ): Fetcher<T>;\n\n abortFacet(name: string, reason: unknown): void;\n\n deleteFacet(name: string): void;\n\n /** Aborts `dst`, deletes its storage, then copies the whole `src` subtree onto it. */\n cloneFacet(src: string, dst: string): void;\n}\n\n/**\n * The one type assertion the facet surface needs, in one named place so an\n * implementation does not have to reinvent it.\n *\n * `Fetcher<T>` for an unresolved `T` is `Rpc.Provider<T, …> & { fetch, connect }`\n * — a conditional type TypeScript defers until `T` is known, and `T` is the\n * caller's claim about the shape of a class it named. No value can confirm that\n * claim, so no value can be checked against it. Upstream is in exactly the same\n * position and answers it the same way: `DurableObjectFacets::get` returns a\n * plain `jsg::Ref<Fetcher>` and the type parameter exists only inside a\n * `JSG_TS_OVERRIDE`. What IS checked is the half that carries behaviour —\n * `fetch` and `connect` — because the argument is a `Fetcher` before it is\n * widened.\n */\nexport function asFacetStub<T extends Rpc.DurableObjectBranded | undefined>(\n stub: Fetcher,\n): Fetcher<T> {\n return stub as Fetcher<T>;\n}\n","/**\n * ← workerd `NO upstream correspondence`\n *\n * The substrate replacement for the two includes `server/actor-id-impl.{h,c++}`\n * makes — `<openssl/sha.h>` and `<openssl/hmac.h>` — and nothing else. Only\n * `actor-id-impl.ts` consumes it, which is why it sits here rather than in\n * `util/`: `src/util/` corresponds 1:1 to `src/workerd/util/`, and workerd has no\n * digest there. `server/facet-deletion.ts` sets the precedent for a file in this\n * directory with no upstream twin.\n *\n * **Why this exists at all.** Every method on `ActorIdFactory` is synchronous\n * (`io/actor-id.h:66-71`), and the browser exposes no synchronous digest:\n * `crypto.subtle.digest` returns a promise, and `node:crypto` is one lane only.\n * So the algorithm is written out. It is a **substrate** divergence in decision\n * 16's sense and not a semantic one — the bytes are the bytes FIPS 180-4 and RFC\n * 2104 specify, which is exactly what BoringSSL computes, so an id minted here is\n * the same 64 hex digits workerd mints from the same unique key. That equality is\n * the whole reason for writing the real digest rather than a cheaper keyed\n * function the reduced threat model would have tolerated: it keeps workerd\n * available as an oracle for ids, where an invented construction would have made\n * every future id question original research.\n *\n * No dependency was added. Nothing in the workspace ships a synchronous SHA-256,\n * and the catalog's `crypto-browserify` is a CommonJS bundler shim for the\n * extension that would not typecheck under this package's `WebWorker`-only lib.\n */\n\n/** ← `SHA256_DIGEST_LENGTH`. */\nexport const SHA256_DIGEST_LENGTH = 32;\n\n/** SHA-256's block size, and therefore HMAC's — RFC 2104's `B`. */\nconst BLOCK_LENGTH = 64;\n\n/** FIPS 180-4 §4.2.2: the first 32 bits of the cube roots of the first 64 primes. */\n// prettier-ignore\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\n/** FIPS 180-4 §5.3.3: the first 32 bits of the square roots of the first 8 primes. */\n// prettier-ignore\nconst INITIAL_HASH = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/**\n * `noUncheckedIndexedAccess` types every element read as possibly undefined.\n * Every index below is in range by construction, and this package does not\n * substitute a value for one that should not be missing.\n */\nfunction at(array: Uint8Array | Uint32Array, index: number): number {\n const value = array[index];\n if (value === undefined) throw new Error(`sha256: index ${index} is outside its array`);\n return value;\n}\n\nfunction rotr(value: number, bits: number): number {\n return ((value >>> bits) | (value << (32 - bits))) >>> 0;\n}\n\n/** ← `SHA256(data, length, out)`. FIPS 180-4 §6.2. */\nexport function sha256(message: Uint8Array): Uint8Array {\n // §5.1.1: append 0x80, then zeroes, then the 64-bit big-endian bit length,\n // padding to a whole number of blocks. The +9 is that one byte plus the eight\n // the length occupies, which is why a 56-byte message needs a second block.\n const paddedLength = (Math.ceil((message.length + 9) / BLOCK_LENGTH) | 0) * BLOCK_LENGTH;\n const padded = new Uint8Array(paddedLength);\n padded.set(message);\n padded[message.length] = 0x80;\n const view = new DataView(padded.buffer);\n // A BigInt because a bit count above 2^53 is not exactly representable as a\n // number, and a message that large is a caller's business rather than ours.\n view.setBigUint64(paddedLength - 8, BigInt(message.length) * 8n, false);\n\n const hash = INITIAL_HASH.slice();\n const w = new Uint32Array(64);\n\n for (let block = 0; block < paddedLength; block += BLOCK_LENGTH) {\n // §6.2.2 step 1: the message schedule.\n for (let i = 0; i < 16; i++) w[i] = view.getUint32(block + i * 4, false);\n for (let i = 16; i < 64; i++) {\n const w15 = at(w, i - 15);\n const w2 = at(w, i - 2);\n const s0 = (rotr(w15, 7) ^ rotr(w15, 18) ^ (w15 >>> 3)) >>> 0;\n const s1 = (rotr(w2, 17) ^ rotr(w2, 19) ^ (w2 >>> 10)) >>> 0;\n w[i] = (at(w, i - 16) + s0 + at(w, i - 7) + s1) >>> 0;\n }\n\n // §6.2.2 step 2.\n let a = at(hash, 0);\n let b = at(hash, 1);\n let c = at(hash, 2);\n let d = at(hash, 3);\n let e = at(hash, 4);\n let f = at(hash, 5);\n let g = at(hash, 6);\n let h = at(hash, 7);\n\n // §6.2.2 step 3.\n for (let i = 0; i < 64; i++) {\n const sigma1 = (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) >>> 0;\n const choice = ((e & f) ^ (~e & g)) >>> 0;\n const temp1 = (h + sigma1 + choice + at(K, i) + at(w, i)) >>> 0;\n const sigma0 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) >>> 0;\n const majority = ((a & b) ^ (a & c) ^ (b & c)) >>> 0;\n const temp2 = (sigma0 + majority) >>> 0;\n\n h = g;\n g = f;\n f = e;\n e = (d + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n\n // §6.2.2 step 4.\n hash[0] = (at(hash, 0) + a) >>> 0;\n hash[1] = (at(hash, 1) + b) >>> 0;\n hash[2] = (at(hash, 2) + c) >>> 0;\n hash[3] = (at(hash, 3) + d) >>> 0;\n hash[4] = (at(hash, 4) + e) >>> 0;\n hash[5] = (at(hash, 5) + f) >>> 0;\n hash[6] = (at(hash, 6) + g) >>> 0;\n hash[7] = (at(hash, 7) + h) >>> 0;\n }\n\n const digest = new Uint8Array(SHA256_DIGEST_LENGTH);\n const digestView = new DataView(digest.buffer);\n for (let i = 0; i < 8; i++) digestView.setUint32(i * 4, at(hash, i), false);\n return digest;\n}\n\n/**\n * ← `HMAC(EVP_sha256(), key, keyLength, data, dataLength, out, &outLength)`.\n * RFC 2104.\n *\n * Upstream's comment on why a MAC is used for something that is not\n * authentication: \"We're using HMAC as a keyed hash here, not actually for\n * authentication, but it works\" (`actor-id-impl.c++:74-75`).\n */\nexport function hmacSha256(key: Uint8Array, message: Uint8Array): Uint8Array {\n // RFC 2104 §2: a key longer than one block is replaced by its own digest, and\n // a shorter one is zero-padded. Exactly one block is used as it stands, which\n // is why the comparison is `>` and not `>=`.\n const block = new Uint8Array(BLOCK_LENGTH);\n block.set(key.length > BLOCK_LENGTH ? sha256(key) : key);\n\n const inner = new Uint8Array(BLOCK_LENGTH + message.length);\n const outer = new Uint8Array(BLOCK_LENGTH + SHA256_DIGEST_LENGTH);\n for (let i = 0; i < BLOCK_LENGTH; i++) {\n inner[i] = at(block, i) ^ 0x36;\n outer[i] = at(block, i) ^ 0x5c;\n }\n inner.set(message, BLOCK_LENGTH);\n outer.set(sha256(inner), BLOCK_LENGTH);\n return sha256(outer);\n}\n","/**\n * ← workerd `src/workerd/server/actor-id-impl.{h,c++}`\n *\n * The implementation behind `io/actor-id.ts`'s two interfaces, which that file's\n * header names as Section 6's problem: \"upstream's is a keyed SHA-256\n * construction … a faithful port of it needs a synchronous digest, which the\n * browser does not expose.\"\n *\n * **What upstream computes.** The factory's key is `SHA256(uniqueKey)`, where\n * `uniqueKey` is the namespace's configured string (`workerd-api.c++:675`).\n * An id is 32 bytes in two halves: a 16-byte base and the first 16 bytes of\n * `HMAC-SHA256(key, base)` — `computeMac` (`actor-id-impl.c++:115-125`), which\n * writes a full 32-byte HMAC into a 48-byte working buffer of which only the\n * first 32 bytes ever become the id. `idFromName` derives the base from\n * `HMAC-SHA256(key, name)` (`:71-83`); `newUniqueId` draws it from the entropy\n * source (`:48-69`); `idFromString` takes it from the supplied hex and refuses\n * the string unless the MAC it recomputes matches the half that came with it\n * (`:85-100`). `toString` is `kj::encodeHex` of the 32 bytes.\n *\n * **The digest is written out; the bytes are unchanged.** Every method on\n * `ActorIdFactory` is synchronous (`io/actor-id.h:66-71`) and no browser API\n * offers a synchronous digest, so `server/sha256.ts` supplies SHA-256 and\n * HMAC-SHA-256 in place of BoringSSL. It computes what FIPS 180-4 and RFC 2104\n * specify, so this is decision 16's **substrate** divergence and not a semantic\n * one: `idFromName` here produces the identical 64 hex digits workerd produces\n * from the same unique key, which keeps workerd usable as an oracle for ids.\n *\n * That equality is why the construction is ported whole rather than narrowed.\n * The reduced threat model would have tolerated much less — ids never cross the\n * host boundary, there is no colo, no jurisdiction routing and no second worker\n * re-deriving an id from the same key, so nothing here forges an id — but only\n * two of the contract's properties are cheap to satisfy any other way. The other\n * two are not: `idFromName` must be **stable forever**, because the id names the\n * actor's storage and a name that hashed differently after a restart loses its\n * data; and `idFromString` must **refuse a string this namespace did not mint**,\n * which is a decision only the keyed MAC half can make. A narrower construction\n * would have satisfied both and cost the oracle, turning every future question\n * about an id into original research on a bespoke artifact — the failure the\n * \"Porting philosophy\" section describes.\n *\n * **`isPredictableModeForTest()` is absent** (`actor-id-impl.c++:59-62`). It is a\n * `util/thread-scopes.h` process-global test hack with no port here, it makes\n * `newUniqueId` return a counter, and `actor-id-impl-test.c++` does not use it.\n * Its body is also wrong upstream: `kj::arrayPtr(id).slice(counter)` slices by\n * the counter's *value*, which is a no-op for every counter it can legitimately\n * reach and out of bounds once the counter passes the buffer's 48 bytes.\n *\n * Spec: §1.10 in docs/decisions.md.\n */\n\nimport type { ActorId, ActorIdFactory } from \"../io/actor-id\";\nimport { hmacSha256, sha256, SHA256_DIGEST_LENGTH } from \"./sha256\";\n\n// =======================================================================================\n// Constants\n\n/**\n * ← `JSG_REQUIRE(jurisdiction == kj::none, Error, …)` (`actor-id-impl.c++:50-51`,\n * `:108`).\n *\n * Verbatim, \"in workerd\" and all: the conformance suite runs one assertion\n * against both runtimes, so a reworded message would be a difference where there\n * is none.\n */\nexport const JURISDICTION_UNIMPLEMENTED_MESSAGE =\n \"Jurisdiction restrictions are not implemented in workerd.\";\n\n/** ← the first `JSG_REQUIRE` in `idFromString` (`actor-id-impl.c++:87-89`). */\nexport const INVALID_ACTOR_ID_MESSAGE = \"Invalid Durable Object ID: must be 64 hex digits\";\n\n/** ← the second `JSG_REQUIRE` in `idFromString` (`actor-id-impl.c++:96-97`). */\nexport const WRONG_NAMESPACE_ACTOR_ID_MESSAGE =\n \"Durable Object ID is not valid for this namespace.\";\n\n/**\n * Upstream `kj::downcast`s the argument of `equals` (`actor-id-impl.c++:33`),\n * which asserts in a debug build and is undefined in a release one. There is one\n * `ActorId` implementation here, so a correct caller cannot reach this; it fails\n * closed rather than comparing something meaningless.\n */\nexport const FOREIGN_ACTOR_ID_MESSAGE =\n \"This actor id was not created by this runtime, so it cannot be compared with one that was.\";\n\n/** ← `ActorIdFactoryImpl::BASE_LENGTH` — `SHA256_DIGEST_LENGTH / 2` (`actor-id-impl.h:44`). */\nconst BASE_LENGTH = SHA256_DIGEST_LENGTH / 2;\n\n/**\n * The working buffer `newUniqueId`, `idFromName` and `idFromString` all build.\n * Upstream's comment (`actor-id-impl.c++:53-56`): \"We want to randomly-generate\n * the first 16 bytes, then HMAC those to produce the latter 16 bytes. But the\n * HMAC will produce 32 bytes, so we're only taking a prefix of it. We'll allocate\n * a single array big enough to output the HMAC as a suffix, which will then get\n * truncated.\"\n */\nconst WORKING_LENGTH = BASE_LENGTH + SHA256_DIGEST_LENGTH;\n\n/** What `kj::decodeHex` accepts, at the length the first `JSG_REQUIRE` demands. */\nconst ACTOR_ID_PATTERN = /^[0-9a-fA-F]{64}$/;\n\nconst encoder = new TextEncoder();\n\n// =======================================================================================\n// ActorIdImpl\n\n/** ← `ActorIdFactoryImpl::ActorIdImpl` (`actor-id-impl.h:13-30`). */\nexport class ActorIdImpl implements ActorId {\n readonly #id: Uint8Array;\n #name: string | undefined;\n\n /**\n * ← the constructor (`actor-id-impl.c++:14-18`). Its parameter is declared\n * `const kj::byte idParam[SHA256_DIGEST_LENGTH]` and its body `memcpy`s\n * exactly `sizeof(id)` bytes, so a caller may hand over the longer working\n * buffer and only its first 32 bytes become the id. The copy is upstream's\n * too — a later write to the caller's buffer is not seen here.\n */\n constructor(id: Uint8Array, name: string | undefined) {\n if (id.length < SHA256_DIGEST_LENGTH) {\n throw new Error(`an actor id is ${SHA256_DIGEST_LENGTH} bytes, and this buffer holds ${id.length}`);\n }\n this.#id = id.slice(0, SHA256_DIGEST_LENGTH);\n this.#name = name;\n }\n\n /** ← `toString()` — `kj::encodeHex`, which is lowercase (`actor-id-impl.c++:20-22`). */\n toString(): string {\n let out = \"\";\n for (const byte of this.#id) out += byte.toString(16).padStart(2, \"0\");\n return out;\n }\n\n /** ← `getName()` (`actor-id-impl.c++:24-26`). */\n getName(): string | undefined {\n return this.#name;\n }\n\n /** ← `getJurisdiction()`, which is unconditionally none (`actor-id-impl.c++:28-30`). */\n getJurisdiction(): string | undefined {\n return undefined;\n }\n\n /**\n * ← `equals()` (`actor-id-impl.c++:32-34`). The id bytes only — the name is\n * deliberately not part of identity, which is what upstream's own table\n * asserts by giving two equal ids different names.\n */\n equals(other: ActorId): boolean {\n if (!(other instanceof ActorIdImpl)) throw new Error(FOREIGN_ACTOR_ID_MESSAGE);\n const mine = this.#id;\n const theirs = other.#id;\n for (let i = 0; i < SHA256_DIGEST_LENGTH; i++) {\n if (mine[i] !== theirs[i]) return false;\n }\n return true;\n }\n\n /** ← `clearName()` (`actor-id-impl.h:23-25`). Not JS-visible; `server/` calls it. */\n clearName(): void {\n this.#name = undefined;\n }\n}\n\n// =======================================================================================\n// ActorIdFactoryImpl\n\n/** ← `ActorIdFactoryImpl` (`actor-id-impl.h:8-46`). */\nexport class ActorIdFactoryImpl implements ActorIdFactory {\n readonly #key: Uint8Array;\n\n /**\n * ← both constructors (`actor-id-impl.c++:40-46`). C++ overloads on the\n * parameter type; one constructor branching on it is the same two behaviours.\n * The string form is the namespace's configured `uniqueKey`\n * (`workerd-api.c++:675`, `:680`); the byte form exists for\n * `cloneWithJurisdiction`, which passes the already-derived key.\n */\n constructor(uniqueKey: string | Uint8Array) {\n if (typeof uniqueKey === \"string\") {\n this.#key = sha256(encoder.encode(uniqueKey));\n return;\n }\n if (uniqueKey.length !== SHA256_DIGEST_LENGTH) {\n throw new Error(`an actor id factory key is ${SHA256_DIGEST_LENGTH} bytes`);\n }\n this.#key = uniqueKey.slice();\n }\n\n /** ← `newUniqueId()` (`actor-id-impl.c++:48-69`). */\n newUniqueId(jurisdiction: string | undefined): ActorId {\n if (jurisdiction !== undefined) throw new Error(JURISDICTION_UNIMPLEMENTED_MESSAGE);\n\n const id = new Uint8Array(WORKING_LENGTH);\n // ← `getEntropy(kj::arrayPtr(id, BASE_LENGTH))` (`util/entropy.h`): \"Fills\n // `output` with cryptographically-random bytes.\"\n crypto.getRandomValues(id.subarray(0, BASE_LENGTH));\n this.#computeMac(id);\n return new ActorIdImpl(id, undefined);\n }\n\n /** ← `idFromName()` (`actor-id-impl.c++:71-83`). */\n idFromName(name: string): ActorId {\n const id = new Uint8Array(WORKING_LENGTH);\n\n // Compute the first half of the ID by HMACing the name itself. We're using HMAC as a keyed\n // hash here, not actually for authentication, but it works.\n id.set(hmacSha256(this.#key, encoder.encode(name)));\n\n this.#computeMac(id);\n return new ActorIdImpl(id, name);\n }\n\n /** ← `idFromString()` (`actor-id-impl.c++:85-100`). */\n idFromString(str: string): ActorId {\n // Upstream's three conditions — 64 characters, `kj::decodeHex` reported no\n // errors, 32 bytes out — are one test here, because a 64-character match on\n // this pattern decodes to 32 bytes and cannot report an error.\n if (!ACTOR_ID_PATTERN.test(str)) throw new TypeError(INVALID_ACTOR_ID_MESSAGE);\n const decoded = new Uint8Array(SHA256_DIGEST_LENGTH);\n for (let i = 0; i < SHA256_DIGEST_LENGTH; i++) {\n decoded[i] = Number.parseInt(str.slice(i * 2, i * 2 + 2), 16);\n }\n\n const id = new Uint8Array(WORKING_LENGTH);\n id.set(decoded.subarray(0, BASE_LENGTH));\n this.#computeMac(id);\n\n // Verify that the computed mac matches the input.\n for (let i = 0; i < SHA256_DIGEST_LENGTH - BASE_LENGTH; i++) {\n if (id[BASE_LENGTH + i] !== decoded[BASE_LENGTH + i]) {\n throw new TypeError(WRONG_NAMESPACE_ACTOR_ID_MESSAGE);\n }\n }\n\n return new ActorIdImpl(id, undefined);\n }\n\n /** ← `cloneWithJurisdiction()` (`actor-id-impl.c++:102-109`). */\n cloneWithJurisdiction(maybeJurisdiction: string | undefined): ActorIdFactory {\n if (maybeJurisdiction === undefined) return new ActorIdFactoryImpl(this.#key);\n throw new Error(JURISDICTION_UNIMPLEMENTED_MESSAGE);\n }\n\n /** ← `matchesJurisdiction()`, which is unconditionally true (`actor-id-impl.c++:111-113`). */\n matchesJurisdiction(_id: ActorId): boolean {\n return true;\n }\n\n /**\n * ← `computeMac()` (`actor-id-impl.c++:115-125`). \"Given that the first\n * `BASE_LENGTH` bytes of `id` are filled in, compute the second half of the ID\n * by HMACing the first half. The id must be in a buffer large enough to store\n * the first half of the ID plus a full HMAC, even though only a prefix of the\n * HMAC becomes part of the final ID.\"\n */\n #computeMac(id: Uint8Array): void {\n id.set(hmacSha256(this.#key, id.subarray(0, BASE_LENGTH)), BASE_LENGTH);\n }\n}\n","/**\n * ← workerd `src/workerd/server/facet-tree-index.{h,c++}`\n *\n * Upstream's own summary: \"Implements an index, stored on disk, which maps\n * leaves of a tree to small integers in a stable way.\" One facet — id zero — is\n * the root; every other facet has a parent and a name, names are unique among\n * siblings but not globally, and each (parent, name) pair is assigned the next\n * sequential id the first time it is seen. Deleting a facet does not release its\n * id: recreating the same name under the same parent gets the same id back,\n * which is what decision 14 means by \"stable ids across delete-and-recreate.\"\n *\n * The whole index is held in memory, loaded at construction, because upstream\n * assumes \"the total number of facets created for a single Durable Object over\n * its entire lifetime will never be very large\" (`facet-tree-index.h:19-22`).\n * That is what makes the file append-only, and the append-only format is what\n * makes a torn tail safe to discard: an entry written but not synced cannot have\n * been relied on, so a nonsensical entry ends the read and the remainder is\n * truncated away.\n *\n * **The one seam: `kj::File` becomes `IndexFile`.** Upstream takes a\n * `kj::Own<const kj::File>` and calls exactly four members on it —\n * `readAllBytes`, `write`, `truncate` and `datasync`. There is no `kj/filesystem`\n * port and no reason to build one for four methods, so those four become an\n * interface and `server/` supplies it. Every method is synchronous because every\n * method upstream is, and because `facets.get` is synchronous all the way down;\n * both substrates can answer that (`FileSystemSyncAccessHandle` in a worker,\n * `node:fs`'s sync family), which is the same shape the storage backends already\n * take.\n *\n * **A name is its UTF-8 bytes, not its JS string.** Upstream's names are\n * `kj::String`s, so the on-disk bytes *are* the identity and the ordering.\n * `TextEncoder` is not injective on JS strings — every lone surrogate encodes to\n * U+FFFD — so keying this index by the JS string would let two distinct names\n * collide on disk and share one facet's storage file after a reload. Entries are\n * therefore identified and ordered by their encoded bytes, and `forEachChild`\n * reports the round-tripped name, which is what a reload would report. That also\n * makes the ordering exact: upstream's `kj::TreeSet` orders by `kj::String`'s\n * byte comparison, where JS `<` would order by UTF-16 code unit and disagree for\n * any name mixing astral characters with U+E000..U+FFFF.\n *\n * **The scaffolding recorded a divergence here that is wrong, and it is not\n * kept.** That header said workerd keeps one index per root actor while \"our tree\n * spans workers, so each parent indexes its direct children.\" Upstream's index\n * already *is* keyed by (parent, name) — `getId(parent, name)`,\n * `forEachChild(parentId, …)` — so a per-parent index changes nothing about what\n * is indexed and only changes what an id *means*: upstream's ids are sequential\n * across the whole tree, and they name storage files in one flat namespace,\n * `<actor-id>.<facetId>.sqlite` (`server.c++:2737-2743`). Per-parent counters\n * would mint id 1 under every parent and collide those files. Nor does the\n * premise hold: the index is owned by the root *container*, not by an actor's\n * worker (`server.c++:2680-2681`, `:2697`), and `FacetHost` already speaks a flat\n * `FacetId = number` with a precomputed subtree — which only a whole-tree index\n * can produce. Ported as upstream has it.\n *\n * Spec: §1.10, decision 14 in docs/decisions.md.\n */\n\n/**\n * ← the `kj::File` members `FacetTreeIndex` calls, and nothing else.\n *\n * `datasync()` is not decoration: the format's recovery story is that an entry\n * which was written but never synced was never relied upon, so a substrate that\n * drops it turns a torn tail from \"discard and reassign\" into \"two facets, one\n * id\".\n */\nexport interface IndexFile {\n /** ← `kj::File::readAllBytes()`. Called once, at construction. */\n readAllBytes(): Uint8Array;\n /** ← `kj::File::write(offset, data)`. Extends the file when it writes past the end. */\n write(offset: number, data: Uint8Array): void;\n /** ← `kj::File::truncate(size)`. Only ever shrinks, to drop a corrupted tail. */\n truncate(size: number): void;\n /** ← `kj::File::datasync()`. */\n datasync(): void;\n}\n\n/**\n * ← `FacetTreeIndex::MAGIC_NUMBER` (`facet-tree-index.h:116`). Upstream writes it\n * \"in host byte order (which is little-endian on all supported platforms)\", so\n * every integer in the format is read and written little-endian here.\n */\nconst MAGIC_NUMBER = 0xc4cd_ce5b_c5b0_ef57n;\n\n/** The magic number's width, which is also the offset of the first entry. */\nconst MAGIC_LENGTH = 8;\n\n/** ← `FacetTreeIndex::MAX_ID` — `static_cast<uint16_t>(kj::maxValue)`. */\nconst MAX_ID = 0xffff;\n\n/** ← `sizeof(FacetTreeIndex::EntryHeader)`: two `uint16_t`s, parent id then name length. */\nconst ENTRY_HEADER_LENGTH = 4;\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * A byte sequence as one code unit per byte, which makes it both a byte-exact\n * `Map` key and a byte-lexicographic sort key: JS compares strings by UTF-16 code\n * unit, and over 0..255 that is byte order, with a common prefix sorting first\n * exactly as `memcmp` leaves it.\n */\nfunction byteString(bytes: Uint8Array): string {\n let out = \"\";\n // Chunked because String.fromCharCode is variadic and a name may be 65535\n // bytes long, which is more arguments than a call is guaranteed to accept.\n for (let i = 0; i < bytes.length; i += 4096) {\n out += String.fromCharCode(...bytes.subarray(i, i + 4096));\n }\n return out;\n}\n\n/** ← `FacetTreeIndex::Entry`, plus the encoded form upstream gets for free from `kj::String`. */\ntype Entry = {\n readonly parent: number;\n /** The decoded name, which is what a reload of this file would produce. */\n readonly name: string;\n /** Byte identity and sort key — see the header on why the JS string is neither. */\n readonly nameKey: string;\n};\n\n/** ← `FacetTreeIndex` (`facet-tree-index.h:50-123`). */\nexport class FacetTreeIndex {\n readonly #file: IndexFile;\n\n /**\n * ← `FacetTreeIndex::offset`. \"Offset at which to write the next entry.\n * Typically points to the end of the file (except when a corrupted tail was\n * detected).\"\n */\n #offset = 0;\n\n /**\n * ← `kj::TreeSet<Entry> entries`, split into the two things that set was doing\n * at once. The array is upstream's insertion order — \"there's no need to store\n * the ID of each entry since they are strictly ordered with no erasures\", so\n * index + 1 is the id — and the map is the (parent, name) lookup the tree\n * ordering provided. Sorting moves to `forEachChild`, which is the only reader\n * that wants it.\n */\n readonly #entries: Entry[] = [];\n readonly #byKey = new Map<string, number>();\n\n /**\n * ← the constructor (`facet-tree-index.c++:11-86`). \"Construct the index,\n * reading the given file to populate the initial index, and then arranging to\n * append new entries to the file as needed.\"\n */\n constructor(file: IndexFile) {\n this.#file = file;\n\n // Read the file to populate the initial index\n const fileBytes = file.readAllBytes();\n\n // Check if the magic number is present.\n //\n // If the file size is less than or equal to the magic number size itself, it's possible that a\n // previous session suffered a failure while writing the magic number. In that case we can assume\n // nothing was ever written to the index, so we just rewrite it and start over.\n if (fileBytes.length <= MAGIC_LENGTH) {\n // New file, initialize with magic number.\n const magic = new Uint8Array(MAGIC_LENGTH);\n new DataView(magic.buffer).setBigUint64(0, MAGIC_NUMBER, true);\n file.write(0, magic);\n file.datasync();\n this.#offset = MAGIC_LENGTH;\n return;\n }\n\n const view = new DataView(fileBytes.buffer, fileBytes.byteOffset, fileBytes.byteLength);\n\n // On the other hand, because we datasync() immediately after writing the magic number, we can\n // assume that if _more_ bytes are written than just the magic number, then a failure did _not_\n // occurr during the writing of the magic number, and therefore, if it contains the wrong bytes,\n // the file must be in a format we don't recognize.\n if (view.getBigUint64(0, true) !== MAGIC_NUMBER) {\n throw new Error(\"unknown magic number on facet tree index\");\n }\n this.#offset = MAGIC_LENGTH;\n\n // Read entries\n while (this.#offset + ENTRY_HEADER_LENGTH <= fileBytes.length) {\n if (this.#nextId() > MAX_ID) throw new Error(\"Maximum number of facets exceeded\");\n\n const parentId = view.getUint16(this.#offset, true);\n const nameLength = view.getUint16(this.#offset + 2, true);\n\n // Validation checks\n if (nameLength === 0) {\n // Empty name is invalid.\n break;\n }\n\n if (this.#offset + ENTRY_HEADER_LENGTH + nameLength > fileBytes.length) {\n // Name extends beyond file bounds, invalid.\n break;\n }\n\n if (parentId >= this.#nextId()) {\n // Invalid parent ID (parent must already exist).\n break;\n }\n\n // Extract the name\n const nameBytes = fileBytes.subarray(\n this.#offset + ENTRY_HEADER_LENGTH,\n this.#offset + ENTRY_HEADER_LENGTH + nameLength,\n );\n const nameKey = byteString(nameBytes);\n\n if (this.#byKey.has(`${parentId}:${nameKey}`)) {\n // Duplicate entry is invalid.\n break;\n }\n this.#append({ parent: parentId, name: decoder.decode(nameBytes), nameKey });\n\n // Entry was valid and processed successfully, now we can update the offset\n this.#offset += ENTRY_HEADER_LENGTH + nameLength;\n }\n\n if (this.#offset < fileBytes.length) {\n // It appears we stopped at a corrupted entry. We assume such corruption can only be the result\n // of a power failure in the middle of writing an entry during a past session. Any entry which\n // was written but not synced can be presumed to have never been used, so we can simply\n // truncate it from the file.\n file.truncate(this.#offset);\n }\n }\n\n /** ← `FacetTreeIndex::getId`. \"Gets the ID for the given facet, assigning it if needed.\" */\n getId(parent: number, name: string): number {\n const nameBytes = encoder.encode(name);\n if (nameBytes.length === 0) throw new Error(\"Facet name cannot be empty\");\n if (nameBytes.length > MAX_ID) throw new Error(\"Facet name too long\");\n if (parent > this.#entries.length) throw new Error(\"Invalid parent ID\");\n\n const nameKey = byteString(nameBytes);\n const key = `${parent}:${nameKey}`;\n\n // Use findOrCreate to either find an existing entry or create a new one\n const found = this.#byKey.get(key);\n if (found !== undefined) return found + 1;\n\n // New entry, need to assign a new ID and append to file\n if (this.#nextId() > MAX_ID) throw new Error(\"Maximum number of facets exceeded\");\n\n // Prepare entry data\n const entrySize = ENTRY_HEADER_LENGTH + nameBytes.length;\n const entryData = new Uint8Array(entrySize);\n const header = new DataView(entryData.buffer);\n header.setUint16(0, parent, true);\n header.setUint16(2, nameBytes.length, true);\n entryData.set(nameBytes, ENTRY_HEADER_LENGTH);\n\n this.#file.write(this.#offset, entryData);\n\n // We don't want to return an entry that might disappear after a power failure, so sync it\n // now.\n this.#file.datasync();\n\n this.#offset += entrySize;\n\n // Calculate the ID based on the entry's position in the set\n // Root facet (ID 0) isn't in the entries set, so add 1 to the index\n return this.#append({ parent, name: decoder.decode(nameBytes), nameKey }) + 1;\n }\n\n /**\n * ← `FacetTreeIndex::forEachChild`. \"For each child of the given parent ID,\n * call the callback.\"\n *\n * Upstream walks a `kj::TreeSet` range, so children arrive ordered by name\n * rather than by id; the sort here is that ordering, over the same bytes.\n */\n forEachChild(parentId: number, callback: (childId: number, name: string) => void): void {\n const children: { id: number; entry: Entry }[] = [];\n this.#entries.forEach((entry, index) => {\n if (entry.parent === parentId) children.push({ id: index + 1, entry });\n });\n children.sort((a, b) => (a.entry.nameKey < b.entry.nameKey ? -1 : 1));\n for (const child of children) callback(child.id, child.entry.name);\n }\n\n /** ← `FacetTreeIndex::nextId`. \"Off-by-one due to root not being in the set.\" */\n #nextId(): number {\n return this.#entries.length + 1;\n }\n\n /** Adds one entry in insertion order and returns its index, which is its id minus one. */\n #append(entry: Entry): number {\n const index = this.#entries.length;\n this.#entries.push(entry);\n this.#byKey.set(`${entry.parent}:${entry.nameKey}`, index);\n return index;\n }\n}\n","/**\n * ← workerd `NO upstream correspondence`\n *\n * Generation-fenced deletion receipts, serialized subtree deletion, reference\n * epochs. Keyed by facet id, never by an app address.\n *\n * **Why there is no upstream twin.** `ActorContainer::deleteFacet`\n * (`server.c++:2642-2655`) aborts the child and then calls\n * `directory->remove(...)` — synchronous, in-process, on a real filesystem. It\n * cannot be interrupted between \"the app asked\" and \"the bytes are gone\", so it\n * needs no record that it was asked. Here the same call is\n * `FacetHost.deleteStorage`, which is asynchronous because it is the HOST's and a\n * host's storage removal is not required to be prompt: OPFS removal is\n * asynchronous in general, and the extension's supervisor crosses a worker to do\n * it. `ctx.facets.delete()` is synchronous and `void` regardless — so the app's\n * request outlives the process that has to carry it out. §2.7 records the browser\n * host's answer to that, generation-fenced receipts, as \"a genuine improvement\n * over workerd, which has no equivalent because its facets are in-process\". This\n * is that answer, moved down into the runtime and re-keyed.\n *\n * In-process facets do not remove this gap. What upstream gets from them is that\n * `kj::Directory::remove` is a synchronous call it can finish before returning.\n * The seam here is `Promise<void>` whoever implements it, so the gap between \"the\n * app asked\" and \"the bytes are gone\" is still real and still spans a possible\n * teardown. The two conformance lanes happen to close that gap promptly — one\n * through `rmSync`, one through the SAH pool's `unlink` — and the receipt is what\n * makes a host that cannot, such as the extension's supervisor, survivable.\n *\n * **What changed in the move, and it is the whole of the change.** The\n * extension's version (`offscreen/worker/host/facet-deletion.ts`) is keyed by an\n * `AgentWorkerAddress` — a root name plus a path of `{className, name}` steps —\n * and derives \"is this address inside that subtree\" by comparing path prefixes.\n * Here the key is a `FacetId`, the small integer `server/facet-tree-index.ts`\n * assigns, and ancestry is not derivable from it: id 7 says nothing about who its\n * parent is. So every operation that needs a subtree is *given* one, computed\n * from the index by the caller that already holds it, and this file has no\n * opinion about tree shape at all. That is a smaller module, not a larger one:\n * three of the extension's helpers — `isAgentAddressInTree`,\n * `isAgentStorageKeyInTree`, `isAgentStorageEntryInTree` — exist only to answer\n * the ancestry question from a string, and none of them has anything to do here.\n *\n * Storage is the facet-tree database rather than the actor's own, and that is\n * load bearing: `SqliteKv::deleteAll()` calls `db.reset()`\n * (`util/sqlite-kv.ts`), which replaces the actor's database file wholesale. A\n * receipt recorded there would be destroyed by the very `deleteAll()` whose\n * cascade it exists to make recoverable. It sits beside the tree index for the\n * same reason the index does — both are facts about the tree rather than about\n * any one actor's contents.\n *\n * Spec: §2.7, decision 14 in docs/decisions.md.\n */\n\nimport { hasCurrentSqliteTable, type SqlDatabase } from \"../util/sqlite\";\nimport type { FacetId } from \"./actor-container\";\n\n/** The table the receipts live in, beside the tree index. */\nconst RECEIPTS_TABLE = \"_cf_FACET_DELETIONS\";\nconst CREATE_RECEIPTS_TABLE = `CREATE TABLE IF NOT EXISTS ${RECEIPTS_TABLE} (\n facet_id INTEGER PRIMARY KEY,\n generation INTEGER NOT NULL\n)`;\n\n/**\n * One recorded intent to delete a facet's storage.\n *\n * `generation` is the fence. A receipt is cleared only if the row still carries\n * the generation this receipt was issued with, so a delete that was requested\n * again while the first deletion was in flight cannot have its second request\n * erased by the first request's completion.\n */\nexport type FacetDeletionReceipt = {\n readonly id: FacetId;\n readonly generation: number;\n};\n\n/**\n * Parent-owned durable receipts for the synchronous `ctx.facets.delete()`\n * boundary. The doomed child never owns its own deletion decision — it may not\n * be running, and if it is, it is the thing being destroyed.\n */\nexport class FacetDeletionReceiptStore {\n readonly #db: SqlDatabase;\n\n constructor(db: SqlDatabase) {\n this.#db = db;\n hasCurrentSqliteTable(db, RECEIPTS_TABLE, CREATE_RECEIPTS_TABLE);\n this.#db.exec(CREATE_RECEIPTS_TABLE, []);\n }\n\n /** Bumps the generation for `id` and returns the receipt naming it. */\n record(id: FacetId): FacetDeletionReceipt {\n requireFacetId(id);\n // One statement, so it is one implicit SQLite transaction and is durable when it returns —\n // which is what lets `ctx.facets.delete()` stay synchronous and still be recoverable. The\n // extension's version wrapped the read and the write in `transactionSync`; a single upsert\n // that computes the next generation from the row it is replacing needs no transaction at all.\n const rows = this.#db.exec(\n `INSERT INTO ${RECEIPTS_TABLE} (facet_id, generation)\n VALUES (?, 1)\n ON CONFLICT(facet_id) DO UPDATE SET generation = generation + 1\n RETURNING generation`,\n [id],\n ).rawRows;\n const generation = rows[0]?.[0];\n if (typeof generation !== \"number\" || !Number.isSafeInteger(generation) || generation <= 0) {\n throw new Error(`recording a facet deletion receipt for ${id} produced no generation`);\n }\n return { id, generation };\n }\n\n read(id: FacetId): FacetDeletionReceipt | undefined {\n requireFacetId(id);\n const rows = this.#db.exec(`SELECT generation FROM ${RECEIPTS_TABLE} WHERE facet_id = ?`, [\n id,\n ]).rawRows;\n const row = rows[0];\n if (row === undefined) return undefined;\n return { id, generation: requireGeneration(id, row[0]) };\n }\n\n /**\n * Every outstanding receipt, oldest facet first, for boot-time replay.\n *\n * The `ORDER BY` cannot be shown to matter and is kept anyway: `facet_id` is\n * an `INTEGER PRIMARY KEY`, which is the rowid, so both backends scan the\n * table in that order with or without it. Removing it survives the whole\n * suite — a mutant that no test can kill, because killing it needs a SQLite\n * that returns rows out of rowid order, and nothing this package can reach\n * does. Relying on the scan order rather than saying so is the kind of thing\n * that is right until a schema change makes it silently wrong.\n */\n list(): FacetDeletionReceipt[] {\n return this.#db\n .exec(`SELECT facet_id, generation FROM ${RECEIPTS_TABLE} ORDER BY facet_id`, [])\n .rawRows.map((row) => {\n const id = row[0];\n if (typeof id !== \"number\" || !Number.isSafeInteger(id) || id <= 0) {\n throw new Error(`facet deletion receipt has an invalid facet id: ${String(id)}`);\n }\n return { id, generation: requireGeneration(id, row[1]) };\n });\n }\n\n /**\n * Clears the receipt if and only if it is still the one that was issued.\n * Returns false when a newer request has superseded it, which is the whole\n * point of the generation.\n */\n clear(receipt: FacetDeletionReceipt): boolean {\n return (\n this.#db.exec(`DELETE FROM ${RECEIPTS_TABLE} WHERE facet_id = ? AND generation = ?`, [\n receipt.id,\n receipt.generation,\n ]).rowsWritten > 0\n );\n }\n}\n\nfunction requireFacetId(id: FacetId): void {\n if (!Number.isSafeInteger(id) || id <= 0) {\n throw new Error(`a facet deletion receipt names a facet, and ${id} is not one`);\n }\n}\n\nfunction requireGeneration(id: FacetId, value: unknown): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n throw new Error(`facet deletion receipt for ${id} has an invalid generation`);\n }\n return value;\n}\n\n/**\n * Replays and generation-fences one parent's durable child-deletion receipts.\n *\n * Recording is synchronous — that is the boundary `ctx.facets.delete()` has to\n * hold — and only the physical deletion crosses an async boundary. A second\n * delete of the same facet while the first is in flight records a newer\n * generation and queues behind it rather than racing it, so a facet cannot be\n * half-deleted by two overlapping attempts.\n */\nexport class FacetDeletionController {\n readonly #receipts: FacetDeletionReceiptStore;\n readonly #deleteSubtree: (receipt: FacetDeletionReceipt) => Promise<void>;\n readonly #active = new Map<FacetId, { generation: number; promise: Promise<void> }>();\n\n constructor(\n receipts: FacetDeletionReceiptStore,\n deleteSubtree: (receipt: FacetDeletionReceipt) => Promise<void>,\n ) {\n this.#receipts = receipts;\n this.#deleteSubtree = deleteSubtree;\n }\n\n /**\n * Record the intent durably now, then carry it out after the caller's actor\n * ordering has settled. The record is synchronous even when the barrier is\n * still pending.\n */\n delete(id: FacetId, waitBeforeDelete: Promise<unknown> = Promise.resolve()): Promise<void> {\n return this.#run(this.#receipts.record(id), waitBeforeDelete);\n }\n\n /** Carry out whatever is still recorded for `id`, until nothing is. */\n async flush(id: FacetId): Promise<void> {\n for (;;) {\n const receipt = this.#receipts.read(id);\n if (receipt === undefined) return;\n await this.#run(receipt);\n }\n }\n\n /** ← boot. Every receipt a previous session left behind is carried out before the actor runs. */\n async recoverAll(): Promise<void> {\n await Promise.all(this.#receipts.list().map((receipt) => this.flush(receipt.id)));\n }\n\n #run(\n receipt: FacetDeletionReceipt,\n waitBeforeDelete: Promise<unknown> = Promise.resolve(),\n ): Promise<void> {\n const active = this.#active.get(receipt.id);\n // An in-flight attempt at this generation or newer already covers this request.\n if (active !== undefined && active.generation >= receipt.generation) return active.promise;\n\n // A failed predecessor must not stop the successor; it has its own receipt and its own\n // caller to report to.\n const previous = active?.promise.catch(() => undefined) ?? Promise.resolve();\n const ready = Promise.all([previous, waitBeforeDelete.catch(() => undefined)]);\n const promise = ready.then(async () => {\n await this.#deleteSubtree(receipt);\n this.#receipts.clear(receipt);\n });\n const entry = { generation: receipt.generation, promise };\n this.#active.set(receipt.id, entry);\n void promise.then(\n () => this.#clearActive(receipt.id, entry),\n () => this.#clearActive(receipt.id, entry),\n );\n return promise;\n }\n\n #clearActive(id: FacetId, entry: { generation: number; promise: Promise<void> }): void {\n if (this.#active.get(id) === entry) this.#active.delete(id);\n }\n}\n\n/**\n * Serializes physical subtree deletion while retaining subtree-aware waits.\n *\n * Two deletions that overlap in the tree must not run at once: the inner one\n * would be removing files the outer one is walking. Serializing every deletion\n * is the simplest thing that is correct, and deletion is not on any hot path.\n * `waitFor` is the other half — anything about to *use* a facet has to wait for\n * a pending deletion that covers it, and the ids each pending operation covers\n * are recorded rather than derived, because a facet id does not encode its\n * ancestry.\n */\nexport class SerializedSubtreeDeletionQueue {\n readonly #pending = new Map<Promise<void>, ReadonlySet<FacetId>>();\n #tail: Promise<void> = Promise.resolve();\n\n /** Runs `operation` after every operation already queued, covering `ids`. */\n run(ids: Iterable<FacetId>, operation: () => Promise<void>): Promise<void> {\n const covered = new Set(ids);\n // The tail swallows failures so one failed deletion does not cancel every later one; the\n // returned promise still carries the failure to its own caller.\n const promise = this.#tail.then(operation);\n this.#tail = promise.catch(() => undefined);\n this.#pending.set(promise, covered);\n void this.#tail.then(() => {\n this.#pending.delete(promise);\n });\n return promise;\n }\n\n /** Resolves once no queued deletion covers `id`. Failures are not the waiter's to report. */\n async waitFor(id: FacetId): Promise<void> {\n const barriers: Promise<unknown>[] = [];\n for (const [promise, covered] of this.#pending) {\n if (covered.has(id)) barriers.push(promise.catch(() => undefined));\n }\n await Promise.all(barriers);\n }\n}\n\n/**\n * Epochs make every capability captured before an ancestor abort or delete\n * stale.\n *\n * The hazard this closes has no workerd equivalent for the same reason the\n * receipts do not: upstream's `abortFacet` erases the map entry and the stub\n * that was handed out is refcounted against a container that is now broken, so\n * a later call on it fails by itself. Here the stub is a value that outlives the\n * placement, so something has to be able to say \"the thing you are holding was\n * torn down\". Invalidation is by explicit subtree because a `FacetId` does not\n * encode ancestry.\n */\nexport class FacetReferenceEpochs {\n readonly #epochs = new Map<FacetId, number>();\n\n /** The epoch to remember alongside a capability. */\n capture(id: FacetId): number {\n const epoch = this.#epochs.get(id) ?? 0;\n this.#epochs.set(id, epoch);\n return epoch;\n }\n\n /** Bumps `root` and every id in `subtree`, so captures older than this call stop matching. */\n invalidate(root: FacetId, subtree: Iterable<FacetId> = []): void {\n const ids = new Set<FacetId>([root, ...subtree]);\n for (const id of ids) this.#epochs.set(id, (this.#epochs.get(id) ?? 0) + 1);\n }\n\n isCurrent(id: FacetId, epoch: number): boolean {\n return (this.#epochs.get(id) ?? 0) === epoch;\n }\n}\n","/**\n * ← workerd `src/workerd/server/server.c++` — `ActorNamespace::ActorContainer`\n * (`:2383-2968`), which is at once the supervisor's per-actor record, its\n * `Worker::Actor::FacetManager`, and the code that builds the storage engine.\n *\n * Composes the gates, the context, the storage engine and the facet tree into\n * one actor. Constructs the Durable Object class under workerd's boot\n * semantics, and on break aborts facets, abandons scheduled writes, refuses\n * re-entry, and surfaces `onBroken`.\n *\n * **The three line ranges this file was handed are all in the wrong class, and\n * the right ones are above.** `server.c++:1199-1214`, `:1225-1237` and\n * `:1293-1297` are all inside `Server::DiskDirectoryService` (`:1058`) — the\n * directory-listing branch of a static-file handler, its entry-type switch, and\n * a `sendError(501, \"Not Implemented\")`. None of them has anything to do with\n * actors. The three things they were offered for are real, and are at\n * `:2864-2877` (alarm hooks installed only `if (parent == kj::none)`, with\n * `// TODO(someday): Support alarms in facets, somehow.`), `:2885-2897`\n * (`afterReset`, where `deleteAll()`'s cascade to descendant facet storage\n * lives) and `:2603-2620` / `:2953-2956` (`getFacetContainer` and\n * `actorClass->newActor`, the two halves of facet actor construction). Every\n * citation in this file was checked line by line against\n * `e8f1e125bd48f048a3e82c48d37e5e3902fffbd6`, which is the tree Section 6a's\n * citations were taken from and agree with.\n *\n * **Ordering, because it is the part that cannot be read off upstream.**\n * Upstream builds the actor lazily inside `getActor()`, so `ctx.storage` does\n * not exist until the first request arrives and nothing can observe the gap.\n * Here `ActorContainer.state` is a plain property that promises a\n * `DurableObjectState` answering `.storage`, and the database behind it opens\n * asynchronously (`SqlDatabaseProvider.open`, Section 3's seam). Something has to\n * give, and the honest one is the factory: `createActorContainer` returns a\n * promise, and everything it returns is fully built. The alternative — a `state`\n * property that throws until `start()` — is a worse lie, because it makes the\n * one declared field of the public interface conditional on a call the type\n * system cannot see.\n *\n * Spec: §1.6, §1.10, decisions 6 and 14 in\n * docs/decisions.md.\n */\n\nimport { DurableObjectState, DurableObjectStorage } from \"../api/actor-state\";\nimport { DurableObjectId } from \"../api/actor\";\nimport { RpcTarget } from \"../api/cloudflare-workers\";\nimport type { FetchPort } from \"../api/global-scope\";\nimport {\n ActorGlobalScope,\n AlarmInvocationInfo,\n actorScopeBindings,\n isAlarmFailureUserError,\n} from \"../api/global-scope\";\nimport type { AcceptedWebSocket, RawWebSocket } from \"../api/web-socket\";\nimport { acceptWebSocket } from \"../api/web-socket\";\nimport type { IsolateChannelFactory, WorkerLoaderOptions } from \"../api/worker-loader\";\nimport { WorkerLoader } from \"../api/worker-loader\";\nimport type { AlarmOutlet } from \"../io/actor-sqlite\";\nimport { ActorSqlite, DEFAULT_ALARM_OUTLET } from \"../io/actor-sqlite\";\nimport type { AlarmResult } from \"./alarm-scheduler\";\nimport type { Actor, Timer } from \"../io/io-context\";\nimport { IoContext, captureGateStack } from \"../io/io-context\";\nimport { InputGate, OutputGate } from \"../io/io-gate\";\nimport type { FacetManager, FacetStartInfo } from \"../io/worker\";\nimport { asFacetStub } from \"../io/worker\";\nimport type { SqlDatabase, SqlDatabaseProvider } from \"../util/sqlite\";\nimport { hasCurrentSqliteTable, SqliteDatabase } from \"../util/sqlite\";\nimport { ActorIdFactoryImpl } from \"./actor-id-impl\";\nimport type { IndexFile } from \"./facet-tree-index\";\nimport { FacetTreeIndex } from \"./facet-tree-index\";\nimport type { FacetDeletionReceipt } from \"./facet-deletion\";\nimport {\n FacetDeletionController,\n FacetDeletionReceiptStore,\n FacetReferenceEpochs,\n SerializedSubtreeDeletionQueue,\n} from \"./facet-deletion\";\n\nexport type FacetId = number;\n\nexport type FacetStartRequest = {\n id: FacetId;\n /** The `facets.get` name, `class\\0name` form preserved. */\n name: string;\n /** Resolved against `ctx.exports` by `api/actor-state.ts`. */\n className: string;\n /** This facet's depth. The container enforces <= 4 including the root. */\n depth: number;\n /**\n * The `ctx.id` the child was told to take, present only when the startup\n * options supplied one. Absent means the child inherits the parent's, which\n * is upstream's `ioCtx.getActorOrThrow().cloneId()` (`actor-state.c++:1026`).\n *\n * The scaffolding called this \"the DurableObjectId name\". It is not\n * necessarily a name: `FacetStartupOptions.id` is `DurableObjectId | string`\n * (`actor-state.h:453`), so this carries a named id's stable name, an unnamed\n * id's 64-hex string, or the string the app supplied. The host decides what to\n * do with it, exactly as upstream's `Worker::Actor::Id` leaves that to the\n * supervisor.\n */\n routedId?: string;\n};\n\nexport interface FacetHandle {\n /**\n * The placement's outcome, resolving to what `facets.get` will call —\n * Fetcher-shaped per §1.10: no id, no name.\n *\n * `start` is synchronous because `facets.get` is, but placing an actor is not: a database\n * has to open and a constructor has to run. Upstream has exactly this shape and\n * does not have to say so — `getFacetContainer` hands `ActorChannelImpl` a\n * `kj::Promise<ClassAndId>` (`server.c++:2603-2620`) and the channel is\n * returned before it resolves, so a failure to construct reaches the caller at\n * the first call on the stub. Measured on workerd 1.20260722.1: a facet whose\n * constructor throws returns a stub from `facets.get()`, rejects the first call\n * with the constructor's own message, and leaves the parent untouched.\n *\n * Keeping the placement promise here makes construction failures observable at\n * the first call and leaves `asFacetTransport` as the sole deferral layer.\n */\n stub: Promise<object>;\n /**\n * Rejects when a RUNNING facet breaks — the signal upstream gets from\n * `actor.onBroken()` and monitors in `monitorOnBroken`\n * (`server.c++:2767-2800`).\n *\n * **A break travels DOWN and never up, so nothing here reaches the parent.**\n * `ActorContainer::abort` (`:2565-2589`) and `monitorOnBroken` each loop\n * `for (auto& facet: facets)` and abort the container's OWN children; a broken\n * child takes itself and its subtree, and nothing above it notices.\n * `conformance/suite/facets.spec.ts` guards this against workerd: the parent and\n * its other facets remain live.\n *\n * `FacetManagerImpl` consumes this signal for `monitorOnBroken`'s two local\n * effects: tell the host to tear down the broken placement (which aborts its\n * descendants), and erase it from the PARENT's facet map (`:2777-2780`,\n * `:2794-2798`). That frees the name for a fresh placement without changing\n * the parent or its siblings.\n *\n * **A placement that never completed does not belong here** — it is a start\n * that failed, not a break, and it travels through `stub`. Measured on\n * workerd: a facet whose construction fails does not break its parent, and the\n * next `facets.get` runs the startup callback again.\n */\n broken: Promise<never>;\n}\n\n/**\n * The facet port. Substrate is only placement, the callable stub across that\n * placement, and physical storage deletion for children a parent cannot open.\n *\n * NOT substrate, and therefore not in this interface: naming, ids, the\n * depth/name/count limits, deletion receipts and epochs, and `clone()`\n * orchestration. Those are package-owned. In particular there is no\n * addressing-strategy port: once\n * the package speaks facet ids, the app-address mapping is the browser\n * adapter's private business and needs no interface at all.\n *\n * This is NOT the interface `api/actor-state.ts` consumes. That one is\n * `io/worker.ts`'s `FacetManager`, upstream's own `Worker::Actor::FacetManager`,\n * which this file implements on top of this port — see that file's header for\n * why the two were conflated and why the fix was to widen rather than reshuffle.\n * The `clone()` orchestration named above is `cloneFacet`'s body, and the\n * limits named above are enforced by `DurableObjectFacets` where upstream\n * enforces them.\n *\n * One host serves a whole actor tree, as upstream's `ActorNamespace` does: every\n * `FacetId` it is handed is an id in the root's index, so a facet's own host\n * must be able to place and remove any of its descendants.\n */\nexport interface FacetHost {\n /**\n * Synchronous, like `facets.get` itself — but the placement it begins is not,\n * and `FacetHandle.stub` is where that is declared. A host reports a placement\n * it could not finish by rejecting that promise, and reports nothing about it\n * on `broken`: see `FacetHandle`.\n *\n * A synchronous throw is still legal and still means the same thing — the\n * facet cannot be started — and `getFacet` turns it into the same rejected\n * stub. What is no longer possible is a host that fails asynchronously and has\n * nowhere to say so.\n */\n start(request: FacetStartRequest): FacetHandle;\n /**\n * Kills the instance; storage survives (measured on workerd).\n *\n * **Never called while a placement for `id` is in flight**, and never before\n * that placement's `stub` has settled. The container orders the two against\n * each other, so a host needs no queue of its own and is never handed an abort\n * for a facet it is still placing — which it could only no-op, its placement\n * map having no entry for the id yet.\n *\n * It may still be called for an id that never ran: a placement that failed, or\n * one refused before `start` was reached. Upstream's is too — `abortFacet`\n * finds the container whether or not its `kj::Promise<ClassAndId>` ever\n * resolved (`server.c++:2635-2640`) — so a host that has nothing to kill\n * should return, not throw.\n */\n abort(id: FacetId, reason?: string): void;\n /**\n * Physical removal, descendants included. `subtree` is the descendants alone,\n * deepest first — upstream removes children before the parent\n * (`server.c++:2754-2759`) — and `id` is the facet itself.\n */\n deleteStorage(id: FacetId, subtree: readonly FacetId[]): Promise<void>;\n /**\n * Physical copy of one facet's storage onto another, for `cloneFacet`. The\n * recursive walk of the source subtree is this file's; copying one database\n * is the substrate's, the same split `deleteStorage` already makes.\n */\n copyStorage(src: FacetId, dst: FacetId): Promise<void>;\n}\n\n/**\n * The `FacetHost` for a host that places no facets — the shape of every first\n * integration, provided so hosts stop re-typing it. `start` refuses by name.\n * `abort` returns, per its contract above: a host with nothing to kill returns.\n * The storage operations refuse, because a call to either proves a facet once\n * existed — which this host could not have placed.\n */\nexport const noFacets: FacetHost = {\n start(): FacetHandle {\n throw new Error(\"this host places no facets\");\n },\n abort(): void {},\n deleteStorage(): Promise<void> {\n return Promise.reject(new Error(\"this host places no facets\"));\n },\n copyStorage(): Promise<void> {\n return Promise.reject(new Error(\"this host places no facets\"));\n },\n};\n\n/**\n * The four ports. Each one is a seam workerd itself takes as a constructor\n * input; a port that would exist only because our code is currently shaped\n * badly is an invented seam and was rejected. Rejected, for the record:\n * a transport port (one implementation per substrate, forever), a logger port\n * (fail closed — errors throw, breakage surfaces on `onBroken`), a value-codec\n * port (giving lanes different codecs would make the Node lane lie about the\n * browser), and an addressing-strategy port (unnecessary once the package\n * speaks facet ids).\n *\n * A fifth, `isolates?: IsolateHost`, was here from the scaffolding and Section 7b\n * removed it. A Worker Loader is a **binding**, not a port: upstream builds it\n * from `Global::WorkerLoader{channel}` alongside every other binding\n * (`server/workerd-api.c++:748`) and it reaches an application through `env`,\n * exactly as `DurableObjectNamespace` and `ctx.exports` already do here. A host\n * constructs `WorkerLoader` over its own `IsolateChannelFactory` and puts it in\n * `env`; the container never sees one. See `api/worker-loader.ts`'s header.\n */\nexport type ActorPorts = {\n sql: SqlDatabaseProvider;\n /**\n * Root containers only — facets have no alarm slot (§1.10).\n *\n * `AlarmScheduler.hooks(actorId)` is the implementation to put here: upstream\n * builds one `AlarmScheduler` per namespace and gives each actor a\n * three-line `ActorSqliteHooks` adapter over it (`server.c++:2325-2350`,\n * `:3199-3219`), which is the same composition.\n */\n alarms: AlarmOutlet;\n facets: FacetHost;\n timer: Timer;\n /**\n * ← the global outbound `Fetcher` a Worker's `fetch` resolves\n * (`api/global-scope.c++:1160`), which `container.globals.fetch` gates.\n *\n * Optional, and absence is upstream's `globalOutbound: null` posture rather\n * than a missing port: a Worker configured that way has no ambient `fetch` at\n * all, which is how Code Mode forces every I/O through connectors (§1.11).\n * `fetch` then refuses by name instead of reaching a `fetch` this package does\n * not own — an ungated one that works is the failure this layer exists to\n * prevent.\n */\n fetch?: FetchPort;\n};\n\n/**\n * The whole-tree facet state, which belongs to the root container and is shared\n * by every container in one actor tree.\n *\n * Upstream keeps the same thing in the same place — \"FacetTreeIndex for this\n * actor. Only initialized on the root\" (`server.c++:2680-2681`), reached from a\n * facet by `root.ensureFacetTreeIndex()` (`:2697`) — and can do so with a plain\n * reference because every facet of an actor is an object in one process. None of\n * these methods can cross a worker boundary: `facets.get()` is synchronous all\n * the way down, so `getId` has to answer without yielding. A facet in another\n * worker cannot be handed this object and therefore cannot have facets of its\n * own. Every host here\n * now places in the parent's realm and passes the root's object straight through.\n *\n * It is an interface rather than a plain reference anyway, because a facet\n * container is constructed on its own and the root's index is the one piece of\n * state it cannot build for itself: ids are sequential across the whole tree. A\n * host that does not supply one gets a facet that cannot have facets of its own\n * and says so, rather than a per-parent counter that would collide the storage.\n */\nexport interface FacetTree {\n /** ← `FacetTreeIndex::getId`. Assigns on first sight, stable thereafter. */\n getId(parent: FacetId, name: string): FacetId;\n /** ← `FacetTreeIndex::forEachChild`, collected. Ordered by the child's UTF-8 name. */\n children(parent: FacetId): readonly { readonly id: FacetId; readonly name: string }[];\n /** ← `deleteDescendantStorage`'s recursion, as a list: descendants only, deepest first. */\n descendants(id: FacetId): FacetId[];\n /**\n * Records the intent durably now, then removes `id` and its descendants after\n * the current parent and descendant operations represented by `waitBeforeDelete`.\n */\n deleteSubtree(id: FacetId, waitBeforeDelete: Promise<unknown>): Promise<void>;\n /** Copies the whole `src` subtree onto `dst`, minting `dst`'s children as it goes. */\n copySubtree(src: FacetId, dst: FacetId): Promise<void>;\n /** Runs one placement or abort after every earlier operation on the same stable facet id. */\n runOperation(id: FacetId, operation: () => Promise<void>): void;\n /** Snapshots the current operation tail for `id` and every indexed descendant. */\n subtreeOperationBarrier(id: FacetId): Promise<void>;\n /**\n * Resolves once no queued deletion still covers `id`, which is what makes a\n * facet re-created under a name that is still being deleted safe to start.\n */\n settled(id: FacetId): Promise<void>;\n /** Every capability captured before an ancestor abort or delete goes stale here. */\n readonly epochs: FacetReferenceEpochs;\n /** ← boot. Carries out every deletion a previous session recorded and did not finish. */\n recoverDeletions(): Promise<void>;\n}\n\n/**\n * ← `IoContext::awaitIo`, as the one primitive a host needs in order to build a\n * platform async primitive of its own.\n */\nexport type ActorContainerOptions = {\n /** The DurableObjectId name. */\n id: string;\n /**\n * The namespace's unique key, upstream's `uniqueKey` configuration field\n * (`server.c++:2919`, read from `config::Worker::DurableObjectNamespace::Durable`).\n * `ActorIdFactoryImpl` derives its factory key as `SHA256(uniqueKey)` and an\n * id as 16 bytes of base plus 16 bytes of `HMAC-SHA256(key, base)`.\n *\n * **The host must keep this stable forever.** `ctx.id` is\n * `idFromName(options.id)` under this key, and the id names the actor's\n * storage, so a key that changes across a restart changes every id and every\n * actor loses its data. There is no default and it is not optional, because a\n * default is exactly the shape that would let a host acquire this obligation\n * without noticing it. This package cannot check the property for itself —\n * nothing it can observe distinguishes \"a new key\" from \"a new actor\" — so\n * this comment is the whole of the enforcement.\n */\n uniqueKey: string;\n /** The `ctx.exports` class registry. Keys are the consumer's concern. */\n exports: Record<string, unknown>;\n env: unknown;\n ports: ActorPorts;\n /** Present when this container hosts a facet rather than a root. */\n facet?: {\n /** Root is 0, a direct child of the root is 1. `getDepth()` answers with it. */\n depth: number;\n /** This facet's own id, the one its parent allocated from the tree index. */\n id: FacetId;\n /** The root-owned tree this facet and every descendant share. */\n tree: FacetTree;\n };\n};\n\n/** The local entry proxy: data properties stay local; every method becomes one async event. */\nexport type ActorEntry<T extends object> = {\n [K in keyof T]: T[K] extends (...args: infer Args) => infer Result\n ? (...args: Args) => Promise<Awaited<Result>>\n : T[K];\n};\n\nexport interface ActorContainer {\n /** Implements the workers-types interface. No `as unknown as` cast (§2.4). */\n readonly state: DurableObjectState;\n\n /**\n * The actor tree this container belongs to, which a root builds for itself and\n * a facet is handed.\n *\n * It is on the interface because the host is the only thing that can carry it\n * from a parent to a child: `FacetHost.start` builds the nested container, and\n * a facet that may have facets of its own needs the root's index rather than\n * one of its own (see `FacetTree`). Upstream needs no equivalent because a\n * facet reaches `root.ensureFacetTreeIndex()` through a plain reference\n * (`server.c++:2697`), and every facet of an actor is an object in one process.\n *\n */\n readonly facetTree: FacetTree;\n\n /**\n * Whether this container owns the synchronous actor slice on the JS stack.\n * This is the narrow identity check a host loopback needs to call the raw\n * instance instead of queueing behind the lock it already holds. It resolves\n * no container and carries no state into continuations.\n */\n isCurrentSlice(): boolean;\n\n /**\n * Whether this actor's input lock is on the current invocation stack.\n *\n * ← `IoContext::hasCurrent()`. Wider than `isCurrentSlice()`: a slice ends\n * when its synchronous body returns, but the lock it took drains the whole\n * microtask checkpoint (§1.2), so actor code chained one promise past a gated\n * resumption is lock-holding without being slice-current. That window is\n * where a host stub still has a caller to identify: an outbound call made\n * there must resume through the caller's `awaitIo`, or the code after it\n * comes back with no input lock and its next storage call throws. A host\n * that resolves callers with `isCurrentSlice()` alone routes exactly those\n * calls ungated, which is how the loss stays invisible until three layers\n * later.\n */\n hasCurrent(): boolean;\n\n /**\n * Construct the instance under workerd's boot semantics: the input gate is\n * held for the constructor's synchronous slice, and boot-time\n * deletion-receipt replay precedes it.\n */\n start<T extends object>(construct: (ctx: DurableObjectState, env: unknown) => T): Promise<T>;\n\n /**\n * THE door for RPC targets. A proxy whose every method invocation is one\n * gated event. This single wrapper is what replaces the serialised tail,\n * all three dispatch tables, and the 33 hand-written exemptions.\n *\n * EVERY call queues, including one made while this actor is holding its own\n * lock across an await. That is §1.2's whole content and the suite pins it: a\n * second event posted while a storage await holds the gate must not interleave,\n * and a door that reused the held lock could not tell that event apart from a\n * call the actor made to itself. Telling them apart needs to know WHO is\n * calling, which is a host's question rather than a container's — see the\n * extension host's `loopbackStub`, where an actor reaching its own\n * `DurableObjectNamespace` binding skips this door entirely because the lock it\n * would take is the one it is already holding.\n */\n entry<T extends object>(target: T): ActorEntry<T>;\n\n /**\n * The door for events that are not method calls — one WebSocket frame, one\n * host-originated callback. Upstream: `IoContext::run`.\n */\n run<T>(event: () => T | PromiseLike<T>): Promise<T>;\n\n /**\n * ← `IoContext::awaitIo`. The form a HOST-PROVIDED async primitive must take,\n * and the only gate primitive this package makes public.\n *\n * Every platform async thing an application can await — `scheduler.wait`, a\n * `fetch`, a WebSocket round trip — is an io-context primitive upstream, which\n * is why \"resuming from an await re-enters the isolate with a fresh input\n * lock\" needs saying nowhere in workerd: there is no other kind of await.\n * There is here. A raw `setTimeout` resolves a promise the runtime does not\n * own, the application's continuation resumes with an empty invocation stack,\n * and its next `ctx.storage` call throws `no input lock available in this\n * context` — the README's divergence 147. Wrapping the promise in this makes\n * the continuation resume inside a gated slice, which is what upstream's does.\n *\n * It releases the input gate for the duration, per §1.3, so the actor stays\n * re-entrant while it waits. The holding form,\n * `IoContext::awaitIoWithInputLock`, is deliberately NOT public: that one is\n * the transaction boundary of §1.7.1, it belongs to the four async storage\n * calls, and a host holding it by hand is the serialised tail growing back.\n */\n awaitIo<T>(promise: Promise<T>): Promise<T>;\n\n /**\n * ← `ServiceWorkerGlobalScope`, the async-primitive half: this actor's\n * `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval`, `fetch` and\n * `scheduler` (`api/global-scope.ts`).\n *\n * **This is what \"own the primitives in the worker global\" means, and the\n * ownership is the point.** `awaitIo` above is the primitive a host needs to\n * build one of these; this is the set already built, so a host installs rather\n * than reimplements the surface.\n *\n * **One scope per actor, installed lexically, and never resolved from an\n * ambient.** Upstream's globals read `IoContext::current()` because acquisition\n * is structural there; this one holds its context. A host puts it where its\n * actor's code reads it — `globalThis` for a class in the worker's own module\n * graph, a module-scoped binding for a class that arrived as a\n * dynamically-loaded Worker source, which is upstream's own arrangement (§1.11:\n * a dynamic Worker has its own global scope bound to its own context). What\n * happens when a facet reaches past its binding to a parent's scope is\n * `ActorGlobalScope`'s `requireOwnSlice`.\n */\n readonly globals: ActorGlobalScope;\n\n /**\n * ← `WebSocket::accept()` / `state.acceptWebSocket()`\n * (`api/web-socket.c++:133`, `:426`), whose gating is `api/web-socket.ts`.\n *\n * Separate from `globals` because accepting is an act rather than a binding:\n * the critical section is captured at THIS call, so a socket accepted inside\n * `blockConcurrencyWhile` delivers its frames inside that section (§1.8).\n */\n acceptWebSocket(socket: RawWebSocket): AcceptedWebSocket;\n\n /**\n * ← `WorkerInterface::runAlarm(scheduledTime, retryCount)`\n * (`io/worker-interface.h:107`), which is what `AlarmScheduler` calls and what\n * `ServiceWorkerGlobalScope::runAlarm` answers. Strictly serialised (§1.8).\n *\n * It reports rather than throws, because the two bits the scheduler's ladder\n * turns on — retry, and whether the retry counts against the limit — are not\n * derivable from \"the promise rejected\".\n *\n * `retryCount` reaches the handler as `AlarmInvocationInfo`. It is the\n * scheduler's `countedRetry` for this alarm, so the container takes it as an\n * argument exactly as upstream's `runAlarm` does.\n */\n deliverAlarm(scheduledTime: number, retryCount: number): Promise<AlarmResult>;\n\n /**\n * ← `WorkerInterface::abandonAlarm` (`io/worker-interface.h:114`), forwarded to\n * `ActorSqlite::abandonAlarm` (`io/actor-sqlite.c++:1039-1060`).\n *\n * Called when the scheduler has given up retrying, so the actor clears its own\n * alarm state and `getAlarm()` stops reporting a time that will never fire.\n * Answers the actor's stored alarm time when it differs from `scheduledTime` —\n * meaning the application set a different one — and null when the alarm was\n * cleared or there was none.\n */\n abandonAlarm(scheduledTime: number): Promise<number | null>;\n\n /**\n * Output-gate wait for outbound sends that do not ride an `entry()` reply.\n * A broadcast path calls this before each frame (decision 5).\n */\n waitOutputLocks(): Promise<void>;\n\n /** For the host's idle check — today's `drainWaitUntil`. */\n drainWaitUntil(): Promise<void>;\n\n /**\n * ← `WorkerdApi::compileGlobals`'s `Global::WorkerLoader` arm\n * (`server/workerd-api.c++:748-752`), which is the step that turns a configured\n * loader channel into the JS binding an application finds in `env`.\n *\n * **The one binding the runtime has to construct, and the reason is the\n * context.** Upstream's `WorkerLoader` holds a channel number and a\n * validation mode and nothing else, because `get()` and `load()` read\n * `IoContext::current()` when they are called. This package deliberately has no\n * ambient of any kind, so the context is a constructor input — and it must be\n * *this* container's, since `makeReentryCallback` inherits the critical section\n * a `blockConcurrencyWhile` is holding (decision 13). `IoContext` is not\n * exported, on purpose (see `src/index.ts`'s header), so this method is how a\n * host gets a loader bound to the right one.\n *\n * The host still owns the name: assign the result onto the `env` object it\n * passed in, which is what upstream's binding compilation does one layer down.\n * A container whose host never calls this simply has no loader binding, exactly\n * as a Worker with no `workerLoader` in its config does.\n */\n workerLoader(channel: IsolateChannelFactory, options: WorkerLoaderOptions): WorkerLoader;\n\n /**\n * Rejects when either gate breaks, or when a facet the parent did not abort\n * breaks (decisions 6 and 14). The host consumes this: terminate the worker,\n * respawn on the next event.\n */\n readonly onBroken: Promise<never>;\n\n /** The programmatic `ctx.abort()` path. */\n abort(reason?: unknown): void;\n}\n\n// =======================================================================================\n// Constants\n\n/** ← the database `ports.sql` opens for the actor's own KV and SQL. */\nconst ACTOR_DATABASE_NAME = \"root\";\n\n/**\n * ← `<actor-id>.facets` (`server.c++:2711-2714`), as a database rather than a\n * file.\n *\n * Upstream opens a second file beside the actor's SQLite database and calls four\n * `kj::File` members on it. There is no `kj/filesystem` port and the browser\n * cannot give a supervisor a synchronous file handle at all — OPFS sync access\n * handles are worker-only, measured — so the bytes live in a second database\n * from the same provider, which the actor's own worker already has open.\n *\n * A **second** database rather than a table in the actor's own, and the reason is\n * not tidiness. `SqliteKv::deleteAll()` calls `db.reset()`, which replaces the\n * actor's database file wholesale; upstream's index survives that because it is a\n * separate file, and decision 14's \"stable ids across delete-and-recreate\"\n * depends on it surviving. An index inside the actor's database would also be\n * written inside whatever transaction happens to be open — the implicit one, or a\n * `transactionSync` savepoint — so a rolled-back transaction would take an id\n * assignment with it while the facet holding that id kept running. Upstream's\n * index write is `datasync`'d immediately and is in no transaction at all, and a\n * separate connection is what reproduces that.\n */\nconst FACET_DATABASE_NAME = \"facets\";\n\n/** ← the storage the tree index's bytes live in. One row, holding the whole file. */\nconst INDEX_TABLE = \"_cf_FACET_INDEX\";\nconst CREATE_INDEX_TABLE = `CREATE TABLE IF NOT EXISTS ${INDEX_TABLE} (\n k INTEGER PRIMARY KEY CHECK (k = 0),\n bytes BLOB NOT NULL\n)`;\n\n/** ← `JSG_KJ_EXCEPTION(FAILED, Error, \"Facet was deleted.\")` (`server.c++:2644`). */\nconst FACET_DELETED_MESSAGE = \"Facet was deleted.\";\n\n/**\n * A facet has no alarm slot, and this is where that becomes visible.\n *\n * `server.c++:2864-2877` installs alarm hooks only `if (parent == kj::none)` and\n * gives a facet `ActorSqlite::Hooks::getDefaultHooks()`, whose `scheduleRun`\n * throws — so on workerd a `setAlarm()` inside a facet appears to succeed and\n * then breaks the whole actor asynchronously, which is open bug\n * https://github.com/cloudflare/workerd/issues/6810. This runtime refuses at the\n * call instead, as recorded in §2.7. A deliberate semantic\n * divergence: the observable behaviour is a synchronous throw naming the facet\n * where workerd's is a destroyed actor three turns later.\n */\nexport const FACET_ALARM_UNIMPLEMENTED_MESSAGE =\n \"A facet has no alarm slot. Alarm hooks are installed only on a root Durable Object, so a \" +\n \"facet cannot schedule one: record the wake on the root and route the work back down.\";\n\n// =======================================================================================\n// The tree index, over a database\n\n/**\n * ← the `kj::File` `FacetTreeIndex` is constructed over, backed by one BLOB.\n *\n * `datasync()` is a no-op and that is a property of the substrate rather than a\n * shortcut: nothing else ever opens a transaction on this connection, so every\n * statement below is its own implicit SQLite transaction and is durable by the\n * time `exec` returns. The read-modify-write is O(file) per append, which is\n * what upstream's own bound makes affordable — the format is four bytes plus a\n * name per facet and there can be at most 65,535 facets over an actor's whole\n * lifetime (`facet-tree-index.h:19-22`).\n */\nexport function newDatabaseIndexFile(db: SqlDatabase): IndexFile {\n hasCurrentSqliteTable(db, INDEX_TABLE, CREATE_INDEX_TABLE);\n db.exec(CREATE_INDEX_TABLE, []);\n\n const read = (): Uint8Array => {\n const value = db.exec(`SELECT bytes FROM ${INDEX_TABLE} WHERE k = 0`, []).rawRows[0]?.[0];\n if (value === undefined) return new Uint8Array(0);\n if (value instanceof Uint8Array) return value;\n throw new Error(\"the facet tree index row is not a BLOB\");\n };\n\n const store = (bytes: Uint8Array): void => {\n db.exec(\n `INSERT INTO ${INDEX_TABLE} (k, bytes) VALUES (0, ?)\n ON CONFLICT(k) DO UPDATE SET bytes = excluded.bytes`,\n [bytes],\n );\n };\n\n return {\n readAllBytes: read,\n\n write(offset: number, data: Uint8Array): void {\n const current = read();\n // kj's file grows on a write past the end and zero-fills the gap.\n const size = Math.max(current.length, offset + data.length);\n const next = new Uint8Array(size);\n next.set(current, 0);\n next.set(data, offset);\n store(next);\n },\n\n truncate(size: number): void {\n const current = read();\n if (size === current.length) return;\n const next = new Uint8Array(size);\n next.set(current.subarray(0, Math.min(size, current.length)), 0);\n store(next);\n },\n\n datasync(): void {\n // See the note above: one statement is one transaction on this connection.\n },\n };\n}\n\n// =======================================================================================\n// ActorTree\n\n/**\n * The root container's copy of everything that is true of the tree rather than\n * of one actor: the index, the deletion receipts, the serialization of physical\n * deletion, and the reference epochs.\n */\nclass ActorTree implements FacetTree {\n readonly #index: FacetTreeIndex;\n readonly #host: FacetHost;\n readonly #deletions: FacetDeletionController;\n readonly #queue = new SerializedSubtreeDeletionQueue();\n /**\n * One operation tail per stable facet id, shared by every manager in the\n * tree. A parent deletion must see a descendant manager's placement before\n * asking the host to unlink that descendant's storage.\n */\n readonly #operations = new Map<FacetId, Promise<void>>();\n readonly epochs = new FacetReferenceEpochs();\n\n constructor(db: SqlDatabase, host: FacetHost) {\n this.#index = new FacetTreeIndex(newDatabaseIndexFile(db));\n this.#host = host;\n this.#deletions = new FacetDeletionController(new FacetDeletionReceiptStore(db), (receipt) =>\n this.#removeSubtree(receipt),\n );\n }\n\n getId(parent: FacetId, name: string): FacetId {\n return this.#index.getId(parent, name);\n }\n\n children(parent: FacetId): readonly { readonly id: FacetId; readonly name: string }[] {\n const found: { id: FacetId; name: string }[] = [];\n this.#index.forEachChild(parent, (id, name) => {\n found.push({ id, name });\n });\n return found;\n }\n\n /**\n * ← `deleteDescendantStorage` (`server.c++:2754-2759`), flattened. Upstream\n * recurses into a child before removing it, so the deepest storage goes first;\n * this list is in that order and the caller removes `id` itself afterwards.\n */\n descendants(id: FacetId): FacetId[] {\n const out: FacetId[] = [];\n for (const child of this.children(id)) {\n out.push(...this.descendants(child.id));\n out.push(child.id);\n }\n return out;\n }\n\n deleteSubtree(id: FacetId, waitBeforeDelete: Promise<unknown>): Promise<void> {\n return this.#deletions.delete(id, waitBeforeDelete);\n }\n\n async copySubtree(src: FacetId, dst: FacetId): Promise<void> {\n // A copy touches every id in both subtrees, so it queues behind — and blocks — any deletion\n // that overlaps either one. Nothing else may be walking these files while it runs.\n const touched = [src, dst, ...this.descendants(src), ...this.descendants(dst)];\n await this.#queue.run(touched, () => this.#copyInto(src, dst));\n }\n\n runOperation(id: FacetId, operation: () => Promise<void>): void {\n const pending = this.#operations.get(id);\n // Both outcomes chained: an abort is not conditional on the placement before it succeeding.\n const done = pending === undefined ? operation() : pending.then(operation, operation);\n this.#operations.set(id, done);\n void done.finally(() => {\n if (this.#operations.get(id) === done) this.#operations.delete(id);\n });\n }\n\n async subtreeOperationBarrier(id: FacetId): Promise<void> {\n const pending = new Set<Promise<void>>();\n for (const target of [id, ...this.descendants(id)]) {\n const operation = this.#operations.get(target);\n if (operation !== undefined) pending.add(operation);\n }\n await Promise.all([...pending].map((operation) => operation.catch(() => undefined)));\n }\n\n recoverDeletions(): Promise<void> {\n return this.#deletions.recoverAll();\n }\n\n /** Waits out any deletion covering `id`, which is what makes a re-created facet safe to start. */\n settled(id: FacetId): Promise<void> {\n return this.#queue.waitFor(id);\n }\n\n #removeSubtree(receipt: FacetDeletionReceipt): Promise<void> {\n const subtree = this.descendants(receipt.id);\n return this.#queue.run([receipt.id, ...subtree], () =>\n this.#host.deleteStorage(receipt.id, subtree),\n );\n }\n\n async #copyInto(src: FacetId, dst: FacetId): Promise<void> {\n await this.#host.copyStorage(src, dst);\n for (const child of this.children(src)) {\n await this.#copyInto(child.id, this.getId(dst, child.name));\n }\n }\n}\n\n// =======================================================================================\n// The Actor\n\n/** ← `Worker::Actor::Impl::classInstance` (`io/worker.c++:4091-4115`). */\ntype ClassInstance =\n | { readonly kind: \"before-ctor\" }\n | { readonly kind: \"initializing\" }\n | { readonly kind: \"running\"; readonly instance: object }\n | { readonly kind: \"failed\"; readonly exception: unknown };\n\n/**\n * ← `Worker::Actor`, restricted to the four members `io/io-context.ts` names.\n *\n * The gates are constructed here because upstream constructs them here:\n * `Worker::Actor::Impl` owns its own `InputGate` and `OutputGate`\n * (`worker.c++:3784`), and that is per-facet rather than shared with the parent,\n * which is the whole mechanism behind §1.10's parent↔child re-entrancy.\n */\nclass ActorImpl implements Actor {\n readonly #inputGate = new InputGate();\n readonly #outputGate = new OutputGate();\n readonly #isFacet: boolean;\n\n /** Assigned after construction; `storage` is a WXT auto-import in extension bundles. */\n actorStorage: ActorSqlite | undefined;\n\n classInstance: ClassInstance = { kind: \"before-ctor\" };\n\n constructor(isFacet: boolean) {\n this.#isFacet = isFacet;\n }\n\n getInputGate(): InputGate {\n return this.#inputGate;\n }\n\n getOutputGate(): OutputGate {\n return this.#outputGate;\n }\n\n /** ← `Worker::Actor::shutdownActorCache`. Abandons scheduled writes rather than flushing (§1.6). */\n shutdownActorCache(reason: unknown): void {\n this.actorStorage?.shutdown(reason);\n }\n\n /**\n * ← `Worker::Actor::assertCanSetAlarm()` (`io/worker.c++:4090-4116`), one arm\n * per state of its `classInstance` switch.\n *\n * `NoClass` has no arm because this runtime has no class-less actor: every\n * container is built around a constructor. The facet refusal at the top is the\n * divergence `FACET_ALARM_UNIMPLEMENTED_MESSAGE` documents; everything below\n * it is upstream's, message for message.\n */\n assertCanSetAlarm(): void {\n if (this.#isFacet) throw new Error(FACET_ALARM_UNIMPLEMENTED_MESSAGE);\n\n switch (this.classInstance.kind) {\n case \"before-ctor\":\n throw new Error(\"setAlarm() invoked before Durable Object ctor\");\n case \"initializing\":\n // We don't explicitly know if we have an alarm handler or not, so just let it happen.\n // We'll handle it when we go to run the alarm.\n return;\n case \"running\":\n if (!hasAlarmHandler(this.classInstance.instance)) {\n throw new TypeError(\n \"Your Durable Object class must have an alarm() handler in order to call setAlarm()\",\n );\n }\n return;\n case \"failed\":\n // We've failed in the ctor, might as well just throw that exception for now.\n throw this.classInstance.exception;\n }\n }\n}\n\nfunction hasAlarmHandler(instance: object): boolean {\n return typeof (instance as { alarm?: unknown }).alarm === \"function\";\n}\n\n// =======================================================================================\n// FacetManagerImpl\n\n/** One name in the parent's facet map. ← the `ActorMap facets` entry (`server.c++:2686`). */\ntype FacetEntry = {\n readonly id: FacetId;\n readonly started: Promise<FacetHandle>;\n handle: FacetHandle | undefined;\n};\n\n/** For awaiting a promise's settlement without adopting its outcome. */\nconst noop = (): void => {};\n\n/**\n * ← `ActorContainer`'s `Worker::Actor::FacetManager` half (`server.c++:2622-2654`).\n *\n * Upstream's `getFacet` hands the child container a `kj::Promise<ClassAndId>` and\n * returns an `ActorChannelImpl` immediately, so the stub exists before the\n * startup callback has run. `FacetHost.start` is synchronous and wants a resolved\n * request, so the deferral moves here: the stub returned is a proxy that awaits\n * the start and then forwards. Same observable shape — `facets.get()` returns\n * synchronously, and the first call on the result waits for the class.\n *\n * A broken facet is monitored without escalating the break. Upstream\n * `monitorOnBroken` (`server.c++:2767-2800`) aborts that container's own\n * children and erases it from its parent's map; it does not abort the parent.\n * Here the host owns the child container, so `#monitorOnBroken` asks the host to\n * tear it down and removes only the matching entry. `#forgetIfNeverRuns` is the\n * separate path for a placement that never became a running facet.\n */\nclass FacetManagerImpl implements FacetManager {\n readonly #container: ActorContainerImpl;\n readonly #host: FacetHost;\n readonly #selfId: FacetId;\n readonly #depth: number;\n readonly #tree: FacetTree;\n readonly #facets = new Map<string, FacetEntry>();\n\n constructor(\n container: ActorContainerImpl,\n host: FacetHost,\n selfId: FacetId,\n depth: number,\n tree: FacetTree,\n ) {\n this.#container = container;\n this.#host = host;\n this.#selfId = selfId;\n this.#depth = depth;\n this.#tree = tree;\n }\n\n /** ← `getDepth()` (`server.c++:2622-2627`). */\n getDepth(): number {\n return this.#depth;\n }\n\n /** ← `getFacet()` (`server.c++:2629-2633`) plus `getFacetContainer()` (`:2603-2620`). */\n getFacet<T extends Rpc.DurableObjectBranded | undefined = undefined>(\n name: string,\n getStartInfo: () => Promise<FacetStartInfo>,\n ): Fetcher<T> {\n const existing = this.#facets.get(name);\n if (existing !== undefined) {\n return asFacetStub<T>(asFacetTransport(existing, this.#container));\n }\n\n const tree = this.#tree;\n const id = tree.getId(this.#selfId, name);\n const epoch = tree.epochs.capture(id);\n const depth = this.#depth + 1;\n\n // The entry has to exist before the placement runs, so that it can write the handle back onto\n // it; a resolver pair is what lets `started` stay a plain `Promise<FacetHandle>` rather than\n // becoming optional for the one turn it takes to fill in.\n const { promise, resolve, reject } = Promise.withResolvers<FacetHandle>();\n const entry: FacetEntry = { id, handle: undefined, started: promise };\n\n const place = async (): Promise<void> => {\n let handle: FacetHandle;\n try {\n const info = await getStartInfo();\n // A facet re-created under a name that is still being deleted must not open its database\n // while the old one is being removed. Nothing above this layer can see the difference,\n // which is exactly why it has to be waited for here.\n await tree.settled(id);\n if (!tree.epochs.isCurrent(id, epoch)) {\n throw new Error(`Facet \"${name}\" was torn down before it finished starting.`);\n }\n handle = this.#host.start({\n id,\n name,\n className: info.actorClass.className,\n depth,\n ...(info.id === this.#parentId() ? {} : { routedId: info.id }),\n });\n entry.handle = handle;\n this.#monitorOnBroken(name, entry, handle);\n } catch (exception) {\n // Everything up to a usable handle, so a failure reaches `started` and nothing else. The\n // queue must not be the one to carry it: an id whose placement failed is idle, not broken.\n reject(exception);\n return;\n }\n resolve(handle);\n // `started` settles where it always did — the moment the host accepted the placement — and\n // the id stays busy PAST it, until the placement itself has landed. `start` returning is not\n // the facet running, and an abort\n // delivered inside it reaches a host that has nothing yet to abort.\n await handle.stub.then(noop, noop);\n };\n\n // Attached before the placement runs, and it is the whole of this entry's failure handling —\n // see its own comment.\n this.#forgetIfNeverRuns(name, entry);\n tree.runOperation(id, place);\n this.#facets.set(name, entry);\n return asFacetStub<T>(asFacetTransport(entry, this.#container));\n }\n\n /**\n * ← the fact that a facet which failed to start is **not running**, and\n * `getFacet` \"runs the startup callback only when the facet is not already\n * running\" (§1.10, workerd PR #4431) therefore runs it again.\n *\n * Measured on workerd 1.20260722.1 rather than inferred: a name whose first\n * `facets.get` supplied a class that throws in its constructor accepts a\n * working class on the very next `facets.get`, with no `abort()` in between,\n * and the facet then counts its own storage from 1. A map entry kept after a\n * failed placement would answer every later get with the same dead handle, so\n * the name would be poisoned for the life of the actor.\n *\n * Both failures count, because both leave the same nothing behind: a `start`\n * that rejected before the host was called at all (a startup callback that\n * threw, or a tear-down that invalidated the reference epoch), and a placement\n * the host accepted and could not finish.\n *\n * It is also the handler that keeps either from being reported as an unhandled\n * rejection when nobody ever calls the stub — the same thing `IoContext` does\n * for its abort promise — without hiding it from a real caller, which reaches\n * it through `asFacetTransport`.\n */\n #forgetIfNeverRuns(name: string, entry: FacetEntry): void {\n void entry.started\n .then(async (handle) => {\n await handle.stub;\n })\n .catch(() => {\n // Only if this entry is still the one under that name: a tear-down removes it first, and\n // a later `getFacet` may already have put a fresh entry in its place.\n if (this.#facets.get(name) === entry) this.#facets.delete(name);\n });\n }\n\n /**\n * ← `monitorOnBroken` (`server.c++:2767-2800`): tear down the broken container\n * (and therefore its own descendants), then free its name in the parent's map.\n * The identity check keeps a late rejection from touching a replacement that\n * already occupies the stable facet id.\n */\n #monitorOnBroken(name: string, entry: FacetEntry, handle: FacetHandle): void {\n void handle.broken.catch((reason: unknown) => {\n if (this.#facets.get(name) !== entry) return;\n this.#facets.delete(name);\n this.#teardown(entry, describeReason(reason));\n });\n }\n\n /** ← `abortFacet()` (`server.c++:2635-2640`). */\n abortFacet(name: string, reason: unknown): void {\n const entry = this.#facets.get(name);\n if (entry === undefined) return;\n this.#facets.delete(name);\n this.#teardown(entry, describeReason(reason));\n }\n\n /**\n * ← `deleteFacet()` (`server.c++:2642-2655`): abort any running facet, then\n * delete the underlying storage, descendants first.\n *\n * Upstream's second half is a synchronous `directory->remove`. Ours is a\n * durable receipt plus an asynchronous removal, which is what\n * `server/facet-deletion.ts` exists for — the record is synchronous, so the\n * `void` return still means \"this will happen\", and a session that dies\n * between the two replays it at boot.\n */\n deleteFacet(name: string): void {\n const tree = this.#tree;\n this.abortFacet(name, new Error(FACET_DELETED_MESSAGE));\n\n // Note that upstream skips this entirely when the index has never been written, on the grounds\n // that \"if there's no facet index then there couldn't possibly be any child storage\". `getId`\n // assigns on first sight, so asking for a name that was never created costs one index entry\n // and then deletes nothing — which is also what makes the id stable if it is created later.\n const id = tree.getId(this.#selfId, name);\n tree.epochs.invalidate(id, tree.descendants(id));\n this.#container.trackFacetTeardown(tree.deleteSubtree(id, tree.subtreeOperationBarrier(id)));\n }\n\n /**\n * ← `DurableObjectFacets::clone`, which has **no body anywhere in workerd** —\n * `Worker::Actor::FacetManager` (`io/worker.h:901-931`) declares four members\n * and none of them is a clone, while `@cloudflare/workers-types` 4.20260702.1\n * declares `clone(src, dst)`. So the semantics come from §1.10's own prose:\n * abort `dst`, delete its storage, recursively copy the `src` subtree onto it.\n *\n * Two things that prose does not settle, assumed here and flagged rather than\n * hidden. It does not say whether `src` must exist — this treats a `src` that\n * was never created as an empty subtree, because `getId` assigns on sight and\n * there is nothing to distinguish \"never created\" from \"created and empty\".\n * And it does not say whether `dst`'s own children survive: this deletes\n * `dst`'s whole subtree before copying, because \"delete dst storage\" followed\n * by a recursive copy leaves no reading in which a child of the old `dst`\n * should still be there.\n */\n cloneFacet(src: string, dst: string): void {\n const tree = this.#tree;\n this.abortFacet(dst, new Error(FACET_DELETED_MESSAGE));\n\n const srcId = tree.getId(this.#selfId, src);\n const dstId = tree.getId(this.#selfId, dst);\n if (srcId === dstId) throw new TypeError(\"facets.clone() cannot clone a facet onto itself.\");\n\n tree.epochs.invalidate(dstId, tree.descendants(dstId));\n this.#container.trackFacetTeardown(\n tree\n .deleteSubtree(dstId, tree.subtreeOperationBarrier(dstId))\n .then(() => tree.copySubtree(srcId, dstId)),\n );\n }\n\n /** ← `monitorOnBroken`'s `for (auto& facet: facets) facet.value->abort(...)` (`server.c++:2777-2780`). */\n abortAll(reason: unknown): void {\n const description = describeReason(reason);\n for (const [name, entry] of this.#facets) {\n this.#facets.delete(name);\n this.#teardown(entry, description);\n }\n }\n\n /** ← `afterReset`'s `deleteDescendantStorage(dir, selfId)` (`server.c++:2885-2897`). */\n deleteAllDescendants(): void {\n const tree = this.#tree;\n this.abortAll(new Error(FACET_DELETED_MESSAGE));\n for (const child of tree.children(this.#selfId)) {\n tree.epochs.invalidate(child.id, tree.descendants(child.id));\n this.#container.trackFacetTeardown(\n tree.deleteSubtree(child.id, tree.subtreeOperationBarrier(child.id)),\n );\n }\n }\n\n /**\n * ← `ActorContainer::abort` (`server.c++:2565-2589`) as `abortFacet` reaches it\n * (`:2635-2640`), which is synchronous AND effective the instant it runs.\n *\n * Ours can only be effective once the host has finished placing, so the abort\n * goes to the back of the id's queue when one is in flight and straight\n * through when the id is idle. `abortFacet` stays `void` either way — the\n * queueing is invisible above this line, which is the point: `ctx.facets`'s\n * synchronous shape is upstream's and is not negotiable (`:2635`).\n *\n * Nothing here has to record that this break was the parent's own doing: a\n * facet breaking never reaches its parent, so the parent's own tear-down and a\n * facet dying by itself are the same event as far as the parent is concerned.\n */\n #teardown(entry: FacetEntry, description: string): void {\n this.#tree.runOperation(entry.id, async () => {\n this.#host.abort(entry.id, description);\n });\n }\n\n #parentId(): string {\n return this.#container.state.id.toString();\n }\n}\n\nfunction describeReason(reason: unknown): string {\n if (typeof reason === \"string\") return reason;\n if (reason instanceof Error) return reason.message;\n return String(reason);\n}\n\n/** Well-known members a stub proxy must answer as absent rather than as a method. */\nconst NON_METHOD_PROPERTIES: ReadonlySet<string | symbol> = new Set<string | symbol>([\n \"then\",\n \"catch\",\n \"finally\",\n Symbol.toPrimitive,\n Symbol.toStringTag,\n Symbol.iterator,\n Symbol.asyncIterator,\n]);\n\n/**\n * The point where the host's placement stub becomes the `Fetcher` the facet API\n * promises, plus the deferral upstream gets from `ActorChannelImpl` holding a\n * promise.\n *\n * The assertion is `asFacetStub`'s, one layer lower. `FacetHost.start` returns\n * `stub: Promise<object>` because a host mints the handle synchronously and the\n * placement it stands for is not finished yet, so the declared type is the widest\n * thing every host can actually satisfy, and `Promise<Fetcher>` is not it.\n *\n * **This function is the only deferral.** `FacetHandle.stub` carries the\n * placement promise and the proxy below waits for it before forwarding.\n *\n * **The assertion here is a separate one and would survive a narrower\n * `FacetHandle.stub`.** What is not describable is the `Fetcher` *this* function\n * returns: it is a `get`-trap `Proxy` that supplies `fetch`, `connect` and every\n * RPC method name at call time, and TypeScript types a `Proxy` as its target.\n * Typing the target `Fetcher` would only move the assertion to\n * `Object.create(null) as Fetcher`. So this stays where it is, for the reason the\n * two `asFacetStub`-shaped assertions beside it stay: the surface is supplied\n * dynamically, not that the value beneath is unknown.\n */\nfunction asFacetTransport(entry: FacetEntry, owner: ActorContainerImpl): Fetcher {\n const bound = new Map<string | symbol, unknown>();\n\n const stub = new Proxy(Object.create(null) as object, {\n get(_target, property): unknown {\n // A proxy that answered `then` with a function would make itself a thenable, and\n // `await facets.get(...)` would hang waiting for it to call back.\n if (NON_METHOD_PROPERTIES.has(property)) return undefined;\n\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n\n // ← `awaitIo`, which is what makes an outbound RPC BOTH release the input gate and resume\n // holding one (§1.3). Without it the caller's continuation comes back with an empty\n // invocation stack — divergence 147 — and its next `ctx.storage` or `ctx.facets` call\n // throws. Upstream never faces the question because every promise JS can await originates\n // in an io-context primitive, and a facet stub is one of them.\n const method = (...args: unknown[]): Promise<unknown> => {\n // Capture re-entry now, while the caller's slice (and any surrounding\n // critical section) is current. Waiting for output locks first can move\n // this work onto a later microtask with no current input lock.\n const callArgs = args.map((arg) =>\n arg instanceof RpcTarget ? owner.bindReentryTarget(arg) : arg,\n );\n return owner.awaitIo(\n owner.waitOutputLocks().then(async (): Promise<unknown> => {\n const handle = entry.handle ?? (await entry.started);\n // The placement, which may still be in flight and may have failed. A failure arrives\n // here and nowhere else — it is what upstream's `kj::Promise<ClassAndId>` failing\n // does, and it is what workerd was measured to do (§1.10).\n const target = (await handle.stub) as Record<string | symbol, unknown>;\n const fn = target[property];\n if (typeof fn !== \"function\") {\n throw new TypeError(`This facet stub has no method ${String(property)}.`);\n }\n // A Cap'n Web method stub is a callable Proxy. Reading its `.apply`\n // would serialize a remote property lookup (`method.apply`) instead\n // of invoking the local call trap, so use the intrinsic directly.\n return await Reflect.apply(fn as (...rest: unknown[]) => unknown, target, callArgs);\n }),\n );\n };\n bound.set(property, method);\n return method;\n },\n });\n\n return stub as Fetcher;\n}\n\n// =======================================================================================\n// ActorContainerImpl\n\nclass ActorContainerImpl implements ActorContainer {\n readonly #actor: ActorImpl;\n readonly #ctx: IoContext;\n #currentExternalEntry: object | undefined;\n readonly #durableStorage: DurableObjectStorage;\n readonly #cache: ActorSqlite;\n readonly #facets: FacetManagerImpl;\n readonly #tree: ActorTree | undefined;\n readonly #env: unknown;\n readonly state: DurableObjectState;\n readonly facetTree: FacetTree;\n readonly globals: ActorGlobalScope;\n\n /** ← §1.8's \"delivery is strictly serialized\", measured. One at a time, in order. */\n #alarmTail: Promise<unknown> = Promise.resolve();\n\n constructor(\n options: ActorContainerOptions,\n db: SqliteDatabase,\n tree: ActorTree | undefined,\n facetTree: FacetTree,\n ) {\n const facet = options.facet;\n this.#actor = new ActorImpl(facet !== undefined);\n this.#ctx = new IoContext(this.#actor, options.ports.timer);\n this.#env = options.env;\n this.#tree = tree;\n\n this.#cache = new ActorSqlite(\n db,\n this.#actor.getOutputGate(),\n // ← `[](SpanParent) -> kj::Promise<void> { return kj::READY_NOW; }` (`server.c++:2900`).\n // Upstream's commit callback exists for a replication layer workerd's local storage has none\n // of; the local commit is already durable when `COMMIT TRANSACTION` returns.\n async () => {},\n // ← `if (parent == kj::none) ... else getDefaultHooks()` (`server.c++:2864-2877`). A facet\n // takes upstream's default hooks, whose `scheduleRun` throws.\n //\n // Nothing can reach them, because `assertCanSetAlarm` refuses first — so giving a facet a\n // live outlet here changes nothing observable and survives the whole suite. It is upstream's\n // own line and it stays: the refusal above it is a divergence, and if the divergence is ever\n // withdrawn this is what workerd's behaviour falls back to.\n facet === undefined ? options.ports.alarms : DEFAULT_ALARM_OUTLET,\n );\n this.#actor.actorStorage = this.#cache;\n\n this.#durableStorage = new DurableObjectStorage(this.#ctx, this.#cache);\n this.globals = new ActorGlobalScope(this.#ctx, {\n fetch: options.ports.fetch,\n currentExternalEntry: () => this.#currentExternalEntry,\n });\n this.facetTree = facetTree;\n this.#facets = new FacetManagerImpl(\n this,\n options.ports.facets,\n facet?.id ?? 0,\n facet?.depth ?? 0,\n this.facetTree,\n );\n\n // ← the `afterReset` hook (`server.c++:2885-2897`): \"reset() is used when the app called\n // deleteAll(), in which case we also want to delete all child facets.\" Ours is\n // `beforeSqliteReset`, which is the listener Section 3 ported, and the difference does not\n // matter — the descendants live in other databases entirely.\n db.addResetListener({\n beforeSqliteReset: () => {\n this.#facets.deleteAllDescendants();\n },\n });\n\n const idFactory = new ActorIdFactoryImpl(options.uniqueKey);\n this.state = new DurableObjectState(this.#ctx, {\n id: new DurableObjectId(idFactory.idFromName(options.id)),\n exports: options.exports,\n props: undefined,\n storage: this.#durableStorage,\n facets: this.#facets,\n // The same object `container.globals` is, so a class that reaches through\n // `ctx` and a dynamically-loaded source that destructured the seven names\n // are gated by one scope rather than two that could drift.\n globals: actorScopeBindings(() => this.globals),\n });\n }\n\n get onBroken(): Promise<never> {\n // ← `IoContext`'s two `abortWhen` calls, which are already wired to both gates\n // (`io-context.c++:206-215`). A facet of this actor breaking is NOT one of the ways in: a\n // break travels down, so what reaches here is this container's own failure.\n return this.#ctx.onAbort();\n }\n\n isCurrentSlice(): boolean {\n return this.#ctx.isCurrentSlice();\n }\n\n hasCurrent(): boolean {\n return this.#ctx.hasCurrent();\n }\n\n /**\n * ← `ActorContainer::start` (`server.c++:2854-2957`) as far as the class\n * instance, plus decision 4's boot semantics.\n *\n * Deletion-receipt replay precedes the constructor because a facet the previous\n * session was told to delete must not be reachable from `onStart`. Upstream has\n * no equivalent step for the reason `server/facet-deletion.ts`'s header gives.\n */\n async start<T extends object>(\n construct: (ctx: DurableObjectState, env: unknown) => T,\n ): Promise<T> {\n await this.#tree?.recoverDeletions();\n\n this.#actor.classInstance = { kind: \"initializing\" };\n try {\n // The input gate is held for the constructor's synchronous slice and the microtask\n // checkpoint that drains after it, which is upstream's own boundary (§1.2).\n const instance = await this.#ctx.run(() => construct(this.state, this.#env));\n this.#actor.classInstance = { kind: \"running\", instance };\n return instance;\n } catch (exception) {\n this.#actor.classInstance = { kind: \"failed\", exception };\n throw exception;\n }\n }\n\n entry<T extends object>(target: T): ActorEntry<T> {\n const bound = new Map<string | symbol, unknown>();\n\n return new Proxy(target, {\n get: (subject, property): unknown => {\n // The receiver is the target rather than the proxy, so a getter on the class does not\n // re-enter this trap for every field it touches.\n const value: unknown = Reflect.get(subject, property, subject);\n if (typeof value !== \"function\") return value;\n\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const gated = async (...args: unknown[]): Promise<unknown> => {\n // The dispatch is the one moment that knows both the method name and\n // the caller's frames — the provenance `describeLostLock` reports.\n this.#ctx.noteGateUse(`entry ${String(property)}()`, captureGateStack());\n const result = await this.#ctx.run(() =>\n this.#withExternalEntry(() =>\n (value as (...rest: unknown[]) => unknown).apply(subject, args),\n ),\n );\n // ← the reply being piped through `waitForOutputLocks()`. This is §1.1's whole point:\n // a method that returns without awaiting its own write still must not answer before\n // that write is durable.\n await this.#ctx.waitForOutputLocks();\n return result;\n };\n bound.set(property, gated);\n return gated;\n },\n }) as ActorEntry<T>;\n }\n\n /**\n * Bind an exported Workers RPC callback to the actor slice that created it.\n *\n * A facet call is bidirectional: the caller can pass an `RpcTarget` and the\n * callee can invoke it before returning. That invocation is re-entry into the\n * caller, not an unscoped JavaScript callback. Capturing one generic re-entry\n * function here preserves a surrounding critical section and keeps method\n * discovery lazy for Cap'n Web's property-path dispatch.\n */\n bindReentryTarget<T extends object>(target: T): T {\n const invoke = this.#ctx.makeReentryCallback(\n async (_lock, property: string | symbol, args: unknown[]): Promise<unknown> => {\n const value: unknown = Reflect.get(target, property, target);\n if (typeof value !== \"function\") {\n throw new TypeError(`This RPC callback has no method ${String(property)}.`);\n }\n const result = await Reflect.apply(value as (...rest: unknown[]) => unknown, target, args);\n await this.#ctx.waitForOutputLocks();\n return result;\n },\n );\n const bound = new Map<string | symbol, unknown>();\n return new Proxy(target, {\n get(subject, property): unknown {\n const value: unknown = Reflect.get(subject, property, subject);\n if (typeof value !== \"function\") return value;\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n const callback = (...args: unknown[]): Promise<unknown> => invoke(property, args);\n bound.set(property, callback);\n return callback;\n },\n });\n }\n\n run<T>(event: () => T | PromiseLike<T>): Promise<T> {\n return this.#ctx.run(() => this.#withExternalEntry(event));\n }\n\n #withExternalEntry<T>(body: () => T): T {\n const previous = this.#currentExternalEntry;\n this.#currentExternalEntry = {};\n try {\n return body();\n } finally {\n this.#currentExternalEntry = previous;\n }\n }\n\n // An arrow property rather than a method, because `asFacetTransport` is handed it as a value\n // and the facet stub's whole job is to be called with `this` bound elsewhere.\n awaitIo = <T>(promise: Promise<T>): Promise<T> => this.#ctx.awaitIo(promise);\n\n acceptWebSocket(socket: RawWebSocket): AcceptedWebSocket {\n return acceptWebSocket(this.#ctx, socket);\n }\n\n /**\n * ← the alarm run in `Worker::Actor`: arm, run the handler under a fresh\n * top-level lock, wait for the output locks, then let the deferred deleter\n * drop.\n *\n * \"Alarms enter with no lock and no critical section, so an alarm queues behind\n * any held lock and takes a fresh top-level lock\" (§1.8) — which is exactly\n * `ctx.run(func)` with no third argument. The retry ladder and the watchdog are\n * `server/alarm-scheduler.ts`'s; what is here is one delivery, and the\n * serialization of one delivery against the next, which is the property\n * `_cf_executingScheduleRowId` upstream depends on.\n */\n deliverAlarm(scheduledTime: number, retryCount: number): Promise<AlarmResult> {\n const delivery = this.#alarmTail.then(\n () => this.#deliverAlarmImpl(scheduledTime, retryCount),\n () => this.#deliverAlarmImpl(scheduledTime, retryCount),\n );\n this.#alarmTail = delivery.catch(() => undefined);\n return delivery;\n }\n\n abandonAlarm(scheduledTime: number): Promise<number | null> {\n return this.#cache.abandonAlarm(scheduledTime);\n }\n\n waitOutputLocks(): Promise<void> {\n return this.#ctx.waitForOutputLocks();\n }\n\n drainWaitUntil(): Promise<void> {\n return this.#ctx.drainWaitUntil();\n }\n\n /** ← `WorkerdApi::compileGlobals`'s `Global::WorkerLoader` arm. */\n workerLoader(channel: IsolateChannelFactory, options: WorkerLoaderOptions): WorkerLoader {\n return new WorkerLoader(this.#ctx, channel, options);\n }\n\n /**\n * ← `DurableObjectState::abort`, which is what the programmatic path is\n * upstream too. Everything §1.6 asks for is already downstream of it: the cache\n * is shut down synchronously so no scheduled write can still land,\n * `IoContext::abort` refuses re-entry, and `onBroken` is the abort promise.\n * Aborting the facets is this layer's own addition, and it is\n * `monitorOnBroken`'s first act (`server.c++:2777-2780`).\n */\n abort(reason?: unknown): void {\n this.#facets.abortAll(reason ?? new Error(\"Parent Durable Object was aborted.\"));\n this.state.abort(reason === undefined ? undefined : describeReason(reason));\n }\n\n /**\n * A physical deletion or copy outlives the synchronous call that asked for it,\n * so it rides `addWaitUntil`: `drainWaitUntil()` then reports the actor busy\n * until it finishes, and a failure lands in `waitUntilStatus()` instead of\n * becoming an unhandled rejection nobody sees.\n */\n trackFacetTeardown(work: Promise<void>): void {\n this.#ctx.addWaitUntil(work);\n }\n\n /**\n * ← `ServiceWorkerGlobalScope::runAlarm` (`api/global-scope.c++:518-691`),\n * whose every step is a member of this class: `armAlarmHandler` and its two\n * arms, the handler under a fresh top-level lock, `waitForOutputLocks`, and the\n * deferred deleter dropping last.\n *\n * Two of its steps have nothing to port onto and are absent rather than\n * skipped: the 15-minute walltime `timeoutPromise` (`:558-586`) needs\n * `afterLimitTimeout` and a limit enforcer, neither of which this package has,\n * and every `LOG_NOSENTRY` around the classification is a log with nothing to\n * write to. What survives is the decision those logs describe.\n */\n async #deliverAlarmImpl(scheduledTime: number, retryCount: number): Promise<AlarmResult> {\n const armed = this.#cache.armAlarmHandler(scheduledTime, this.#ctx.now());\n if (armed.kind === \"cancel\") {\n // ← `CancelAlarmHandler` (`global-scope.c++:684-688`). Not a failure: SQLite has moved past\n // this alarm and has asked the scheduler to re-register the time it does hold.\n await armed.cancel.waitBeforeCancel;\n return { outcome: \"canceled\", retry: false, retryCountsAgainstLimit: true };\n }\n\n try {\n const instance = this.#actor.classInstance;\n if (instance.kind === \"running\" && !hasAlarmHandler(instance.instance)) {\n // ← \"Attempted to run a scheduled alarm without a handler, did you remember to export an\n // alarm() function?\" (`global-scope.c++:543-549`). Upstream logs the warning once and\n // reports SCRIPT_NOT_FOUND, which does NOT retry — so the deferred deleter still drops and\n // the alarm is cleared rather than redelivered to a class that can never answer it.\n return { outcome: \"script-not-found\", retry: false, retryCountsAgainstLimit: true };\n }\n\n let result: AlarmResult;\n try {\n await this.#ctx.run(() => this.#runAlarmHandler(scheduledTime, retryCount));\n result = { outcome: \"ok\", retry: false, retryCountsAgainstLimit: true };\n } catch (exception) {\n // ← the `.catch_` (`global-scope.c++:593-641`). \"We assume that exceptions thrown during\n // commit will propagate to the caller, such that they will ensure\n // cancelDeferredAlarmDeletion() is called\": a handler that failed must not have its alarm\n // deleted, or the retry the scheduler is about to make has nothing to run.\n this.#cache.cancelDeferredAlarmDeletion();\n result = {\n outcome: \"exception\",\n retry: true,\n retryCountsAgainstLimit: true,\n errorDescription: describeReason(exception),\n };\n }\n\n try {\n // ← `context.waitForOutputLocks()` (`global-scope.c++:645`), which is where a write the\n // handler did not await gets its chance to fail.\n await this.#ctx.waitForOutputLocks();\n } catch (exception) {\n // ← the output-lock error branch (`:647-681`), whose\n // `shouldRetryCountsAgainstLimits` is `isUserGeneratedError` alone: a gate that broke\n // after the handler ran is a reset, and a reset must not spend the alarm's retry budget.\n //\n // Divergence: upstream does NOT cancel the deferred deletion here, because its deleter is\n // owned by the `catch_` lambda and fires at the end of the chain either way. Cancelling is\n // the side that keeps the alarm — a deletion written through a gate that has just broken\n // cannot commit, so the only thing at stake is whether a gate that recovers loses it.\n this.#cache.cancelDeferredAlarmDeletion();\n result = {\n outcome: \"exception\",\n retry: true,\n retryCountsAgainstLimit: isAlarmFailureUserError(exception),\n errorDescription: describeReason(exception),\n };\n }\n return result;\n } finally {\n armed.run.deferredDelete.drop();\n }\n }\n\n #runAlarmHandler(scheduledTime: number, retryCount: number): unknown {\n const instance = this.#actor.classInstance;\n if (instance.kind !== \"running\") {\n throw new Error(\"An alarm was delivered to a Durable Object that has not been constructed.\");\n }\n if (!hasAlarmHandler(instance.instance)) {\n throw new TypeError(\"Your Durable Object class must have an alarm() handler.\");\n }\n // ← `alarm(lock, js.alloc<AlarmInvocationInfo>(scheduledTime, retryCount))` (`:588`).\n return (instance.instance as { alarm: (info: AlarmInvocationInfo) => unknown }).alarm(\n new AlarmInvocationInfo(scheduledTime, retryCount),\n );\n }\n}\n\n// =======================================================================================\n// createActorContainer\n\n/**\n * Builds one actor: the two gates, the `IoContext` over them, the storage engine\n * over the actor's database, the facet tree, the id factory, and the `api/`\n * classes on top.\n *\n * Asynchronous because `SqlDatabaseProvider.open` is — see this file's header for\n * why that surfaces here rather than being hidden behind a lazily-opening\n * `state`.\n */\nexport async function createActorContainer(\n options: ActorContainerOptions,\n): Promise<ActorContainer> {\n const db = new SqliteDatabase(await options.ports.sql.open(ACTOR_DATABASE_NAME));\n\n // ← `ensureFacetTreeIndex()`'s `KJ_REQUIRE(parent == kj::none, \"only 'root' may\n // ensureFacetTreeIndex()\")` (`server.c++:2704`). A facet is handed the root's rather than\n // opening one, which is also why this is the only `open` a facet container makes.\n if (options.facet !== undefined) {\n return new ActorContainerImpl(options, db, undefined, options.facet.tree);\n }\n const tree = new ActorTree(\n await options.ports.sql.open(FACET_DATABASE_NAME),\n options.ports.facets,\n );\n return new ActorContainerImpl(options, db, tree, tree);\n}\n","import { DurableObjectNamespace, type ActorChannelFactory } from \"../api/actor\";\nimport { ActorIdFactoryImpl } from \"./actor-id-impl\";\n\n/** Assemble the configured namespace binding a host places in `env`. */\nexport function createDurableObjectNamespace<\n T extends Rpc.DurableObjectBranded | undefined = undefined,\n>(uniqueKey: string, channel: ActorChannelFactory): DurableObjectNamespace<T> {\n return new DurableObjectNamespace<T>(channel, new ActorIdFactoryImpl(uniqueKey));\n}\n","/**\n * ← workerd `NO upstream correspondence (capnweb adaptation)`\n *\n * The one door onto a capnweb session, so that decision 18's identity graft\n * cannot be skipped by establishing one some other way.\n *\n * The `RpcTarget` identity graft lives here because the guarantee belongs to\n * the call that establishes a session, not to whichever sibling module happened\n * to run a side effect first. It is re-applied for every session and is\n * idempotent.\n *\n * **What this deliberately is not.** It is not a transport abstraction and takes\n * no options capnweb does not: a lane or a host that needs\n * `newWebSocketRpcSession` instead should call `reconcileRpcTargetIdentity()`\n * itself and say so, rather than growing this into a second capnweb API. The\n * `MessagePort` form is the only one this substrate uses — the extension's\n * offscreen↔worker hop and the browser lane's page↔actor and page↔alarms hops are\n * all `newMessagePortRpcSession` — and a port carries structured clone, which is\n * what makes capnweb's `structuredClonable` encoding level available.\n *\n * Spec: decision 18 in docs/decisions.md.\n */\n\nimport {\n newMessagePortRpcSession,\n RpcTarget as TransportRpcTarget,\n type RpcStub,\n} from \"capnweb\";\nimport { RpcTarget } from \"../api/cloudflare-workers\";\n\n/** Make the declared Workers RpcTarget recognizable to capnweb by reference. */\nexport function reconcileRpcTargetIdentity(): void {\n if ((RpcTarget as unknown) === (TransportRpcTarget as unknown)) return;\n if (\n Object.prototype.isPrototypeOf.call(\n TransportRpcTarget.prototype,\n RpcTarget.prototype,\n )\n ) {\n return;\n }\n const existing: unknown = Object.getPrototypeOf(RpcTarget.prototype);\n if (existing !== Object.prototype) {\n throw new Error(\n \"The cloudflare:workers RpcTarget already inherits from something other than Object, so \" +\n \"the capnweb identity cannot be reconciled without discarding that link.\",\n );\n }\n Object.setPrototypeOf(RpcTarget.prototype, TransportRpcTarget.prototype);\n}\n\n/**\n * Establish a capnweb session over a `MessagePort`, with the `RpcTarget`\n * identity reconciled first.\n *\n * `localMain` is what the peer reaches; the returned stub is what the peer\n * exposed. Both ends call this — a session is symmetric — and either side may\n * omit its main when it exports nothing.\n */\nexport function newRpcSession<T = unknown>(port: MessagePort, localMain?: unknown): RpcStub<T> {\n reconcileRpcTargetIdentity();\n // Through `unknown`, because capnweb's own return type is `RpcStub<Stubify<...>>` and asking a\n // checker to compare that against `RpcStub<T>` structurally is what makes it recurse until it\n // gives up (TS2589, and two TS2321s behind it). The narrowing is the point of the signature —\n // the caller names the peer's main — and it is unchecked either way.\n return newMessagePortRpcSession(port, localMain) as unknown as RpcStub<T>;\n}\n"],"mappings":"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"}
|