@mcp-b/do-runtime 0.4.0 → 0.6.0

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#channel","#id","#fetcher","#idFactory","#getImpl","#channel","#fetcher","#loopbackClass","#channel","#ctx","#options","#toDynamicWorkerSource","#extractCompatFlags","#pull","#columnNames","#rawRows","#rowsWritten","#nextRow","#position","#nextRaw","#ctx","#owner","#getPageSize","#pageSize","#ctx","#kv","#getOne","#getMultiple","#putOne","#putMultiple","#cache","#sql","#cacheTxn","#rolledBack","#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/api/actor.ts","../src/api/export-loopback.ts","../src/api/worker-loader.ts","../src/api/sql.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/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 */\ntype 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 */\ntype 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 message a `SQLITE_DENY` from the authorizer surfaces to JavaScript,\n * byte-identical so a caller matching on it ports unchanged.\n */\nexport const SQL_NOT_AUTHORIZED_MESSAGE = \"not authorized: SQLITE_AUTH\";\n\n/** Comments are never code. String literals STAY: pragma arguments may be quoted. */\nconst NOT_COMMENT = /--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g;\n\n/** Cheap pre-test; `PRAGMA` and the `pragma_` functions both contain it. */\nconst PRAGMA_HINT = /pragma/i;\n\n/** `PRAGMA [schema.]name`, then `= value`, `(argument)`, or nothing. */\nconst PRAGMA_STATEMENT =\n /^\\s*PRAGMA\\s+(?:[A-Za-z_][A-Za-z0-9_$]*\\s*\\.\\s*)?([A-Za-z_][A-Za-z0-9_$]*)(?:\\s*=\\s*([\\s\\S]+?)|\\s*\\(\\s*([\\s\\S]*?)\\s*\\))?\\s*;?\\s*$/i;\n\n/**\n * ← `ALLOWED_PRAGMAS` and `PragmaSignature` (`util/sqlite.c++:525-563`),\n * verbatim. `table_list`, `table_info`, and `table_xinfo` are special-cased\n * ahead of the table in the authorizer, exactly as upstream's `SQLITE_PRAGMA`\n * case does (`util/sqlite.c++:1194-1273`).\n */\nconst ALLOWED_PRAGMAS = new Map<\n string,\n \"NO_ARG\" | \"BOOLEAN\" | \"OBJECT_NAME\" | \"OPTIONAL_OBJECT_NAME\" | \"NULL_OR_NUMBER\" | \"NULL_NUMBER_OR_OBJECT_NAME\"\n>([\n [\"data_version\", \"NO_ARG\"],\n [\"case_sensitive_like\", \"BOOLEAN\"],\n [\"foreign_keys\", \"BOOLEAN\"],\n [\"defer_foreign_keys\", \"BOOLEAN\"],\n [\"ignore_check_constraints\", \"BOOLEAN\"],\n [\"legacy_alter_table\", \"BOOLEAN\"],\n [\"recursive_triggers\", \"BOOLEAN\"],\n [\"reverse_unordered_selects\", \"BOOLEAN\"],\n [\"foreign_key_check\", \"OPTIONAL_OBJECT_NAME\"],\n [\"foreign_key_list\", \"OBJECT_NAME\"],\n [\"index_info\", \"OBJECT_NAME\"],\n [\"index_list\", \"OBJECT_NAME\"],\n [\"index_xinfo\", \"OBJECT_NAME\"],\n [\"quick_check\", \"NULL_NUMBER_OR_OBJECT_NAME\"],\n [\"optimize\", \"NULL_OR_NUMBER\"],\n]);\n\n/** Upstream compares the eight literal forms as PREFIXES, case-insensitively. */\nconst BOOLEAN_PRAGMA_VALUE = /^(?:true|false|yes|no|on|off|1|0)/i;\n\n/**\n * The pragmas SQLite ships (https://www.sqlite.org/pragma.html), so a\n * `pragma_X` identifier can be told apart: `X` here means the table-valued\n * pragma function and follows the allowlist; any other `pragma_`-prefixed\n * identifier is an ordinary application name, which upstream's authorizer\n * distinguishes by resolution and the conformance suite pins.\n */\nconst SQLITE_PRAGMA_NAMES = new Set([\n \"analysis_limit\", \"application_id\", \"auto_vacuum\", \"automatic_index\",\n \"busy_timeout\", \"cache_size\", \"cache_spill\", \"case_sensitive_like\",\n \"cell_size_check\", \"checkpoint_fullfsync\", \"collation_list\",\n \"compile_options\", \"data_version\", \"database_list\", \"defer_foreign_keys\",\n \"encoding\", \"foreign_key_check\", \"foreign_key_list\", \"foreign_keys\",\n \"freelist_count\", \"full_column_names\", \"fullfsync\", \"function_list\",\n \"hard_heap_limit\", \"ignore_check_constraints\", \"incremental_vacuum\",\n \"index_info\", \"index_list\", \"index_xinfo\", \"integrity_check\",\n \"journal_mode\", \"journal_size_limit\", \"legacy_alter_table\",\n \"legacy_file_format\", \"locking_mode\", \"max_page_count\", \"mmap_size\",\n \"module_list\", \"optimize\", \"page_count\", \"page_size\", \"pragma_list\",\n \"query_only\", \"quick_check\", \"read_uncommitted\", \"recursive_triggers\",\n \"reverse_unordered_selects\", \"schema_version\", \"secure_delete\",\n \"short_column_names\", \"shrink_memory\", \"soft_heap_limit\", \"synchronous\",\n \"table_info\", \"table_list\", \"table_xinfo\", \"temp_store\", \"threads\",\n \"trusted_schema\", \"user_version\", \"wal_autocheckpoint\", \"wal_checkpoint\",\n \"writable_schema\",\n]);\n\n/** kj's `tryParseAs` is decimal; keep the same acceptance. */\nconst DECIMAL = /^[+-]?\\d+$/;\n\n/** One layer of SQL quoting off a pragma argument, any of the four forms. */\nfunction unquoted(argument: string): string {\n const first = argument[0];\n const last = argument[argument.length - 1];\n if (argument.length >= 2) {\n if ((first === \"'\" || first === '\"' || first === \"`\") && last === first) {\n return argument.slice(1, -1);\n }\n if (first === \"[\" && last === \"]\") return argument.slice(1, -1);\n }\n return argument;\n}\n\n/** ← the `SQLITE_PRAGMA` authorizer case (`util/sqlite.c++:1194-1273`), whole. */\nfunction isAllowedPragma(name: string, argument: string | undefined): boolean {\n const pragma = name.toLowerCase();\n if (pragma === \"table_list\") return true;\n if (pragma === \"table_info\" || pragma === \"table_xinfo\") {\n // \"Allow if the specific named table is not protected.\"\n if (argument === undefined) return false;\n return SqlStorageRegulator.isAllowedName(unquoted(argument));\n }\n const signature = ALLOWED_PRAGMAS.get(pragma);\n if (signature === undefined) return false;\n switch (signature) {\n case \"NO_ARG\":\n return argument === undefined;\n case \"BOOLEAN\":\n // \"We allow omitting the argument in order to read back the current value.\"\n return argument === undefined || BOOLEAN_PRAGMA_VALUE.test(unquoted(argument));\n case \"OBJECT_NAME\":\n return argument !== undefined && SqlStorageRegulator.isAllowedName(unquoted(argument));\n case \"OPTIONAL_OBJECT_NAME\":\n return argument === undefined || SqlStorageRegulator.isAllowedName(unquoted(argument));\n case \"NULL_OR_NUMBER\":\n return argument === undefined || DECIMAL.test(argument);\n case \"NULL_NUMBER_OR_OBJECT_NAME\":\n return (\n argument === undefined ||\n DECIMAL.test(argument) ||\n SqlStorageRegulator.isAllowedName(unquoted(argument))\n );\n }\n}\n\n/**\n * The text-level stand-in for the authorizer's `SQLITE_PRAGMA` case, against\n * one SQLite-decided statement boundary. Load-bearing beyond fidelity:\n * `user_version` is where runtime storage versioning keeps its per-file stamp\n * (`util/sqlite-migrations.ts`), and `writable_schema` would let application\n * SQL rewrite `sqlite_master` out from under the `_cf_` reservation.\n *\n * The `pragma_` table-valued functions reach the same authorizer path\n * upstream, so they follow the same allowlist here — by pragma NAME only. An\n * argument the text cannot see (a string literal or a binding) goes unchecked\n * where upstream's authorizer sees the resolved value; a `_cf_` name smuggled\n * that way reads schema whose shape is public source anyway, while identifier\n * arguments stay covered by `requireAllowedNames`. The README divergence row\n * records this.\n */\nfunction requireAllowedPragmas(statement: string): void {\n if (!PRAGMA_HINT.test(statement)) return;\n const code = statement.replace(NOT_COMMENT, \" \");\n const direct = code.match(PRAGMA_STATEMENT);\n if (direct !== null) {\n const [, name = \"\", assigned, called] = direct;\n const argument = (assigned ?? called)?.trim();\n if (!isAllowedPragma(name, argument === \"\" ? undefined : argument)) {\n throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n }\n return;\n }\n // A statement that leads with PRAGMA but does not parse as one is refused —\n // the deliberately stricter direction the reserved-name check already takes.\n if (/^\\s*PRAGMA\\b/i.test(code)) throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n const literalFree = code.replace(NOT_CODE, \" \");\n for (const [token] of literalFree.matchAll(IDENTIFIER)) {\n if (token.length <= 7 || token.slice(0, 7).toLowerCase() !== \"pragma_\") continue;\n const name = token.slice(7).toLowerCase();\n if (!SQLITE_PRAGMA_NAMES.has(name)) continue;\n if (\n name !== \"table_list\" &&\n name !== \"table_info\" &&\n name !== \"table_xinfo\" &&\n !ALLOWED_PRAGMAS.has(name)\n ) {\n throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n }\n }\n}\n\n/** Everything the untrusted path refuses at one statement boundary. */\nfunction regulateUntrustedStatement(statement: string): void {\n refuseTransactionControl(statement);\n requireAllowedPragmas(statement);\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/** ← `JSG_INHERIT_INTRINSIC(v8::kIteratorPrototype)` (`jsg/iterator.h:1044`). */\nconst IteratorPrototype: object = Object.getPrototypeOf(\n Object.getPrototypeOf([][Symbol.iterator]()),\n) as object;\n\n/**\n * ← the `JSG_ITERATOR` types (`jsg/iterator.h:1036-1050`): `next` and\n * self-iterability on `%IteratorPrototype%` — which is what carries the ES\n * iterator helpers; `raw().toArray()` is what Drizzle's durable-sqlite driver\n * calls — and NOTHING else. No `return`, no `throw` (only the async variant\n * registers `return_`, `:1069-1085`), so `IteratorClose` after a `break`, a\n * partial destructuring, or a `take()` is a no-op and a retained iterator\n * resumes. Results are `JSG_STRUCT(done, value)` in that key order\n * (`jsg/iterator.h:706-710`).\n */\nclass RawIterator<U extends SqlStorageValue[]> implements IterableIterator<U> {\n readonly #pull: () => readonly SqlStorageValue[] | undefined;\n\n constructor(pull: () => readonly SqlStorageValue[] | undefined) {\n this.#pull = pull;\n }\n\n next(): { done: false; value: U } | { done: true; value: undefined } {\n const raw = this.#pull();\n if (raw === undefined) return { done: true, value: undefined };\n return { done: false, value: asRawRow<U>([...raw]) };\n }\n\n [Symbol.iterator](): IterableIterator<U> {\n return this;\n }\n}\nObject.setPrototypeOf(RawIterator.prototype, IteratorPrototype);\nObject.defineProperty(RawIterator.prototype, Symbol.toStringTag, {\n value: \"RawIterator\",\n configurable: true,\n});\n\n/** ← `RowIterator`, shaped exactly as `RawIterator` above. */\nclass RowIterator<T extends SqlRow> implements IterableIterator<T> {\n readonly #pull: () => T | undefined;\n\n constructor(pull: () => T | undefined) {\n this.#pull = pull;\n }\n\n next(): { done: false; value: T } | { done: true; value: undefined } {\n const row = this.#pull();\n if (row === undefined) return { done: true, value: undefined };\n return { done: false, value: row };\n }\n\n [Symbol.iterator](): IterableIterator<T> {\n return this;\n }\n}\nObject.setPrototypeOf(RowIterator.prototype, IteratorPrototype);\nObject.defineProperty(RowIterator.prototype, Symbol.toStringTag, {\n value: \"RowIterator\",\n configurable: true,\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 /**\n * ← `JSG_READONLY_PROTOTYPE_PROPERTY(columnNames)` (`sql.h:210`): a\n * prototype accessor, not an own field, so a cursor JSON-stringifies to `{}`.\n */\n get columnNames(): string[] {\n return this.#columnNames;\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) {\n // ← `JSG_STRUCT(done, value)` serializes an OWN `value: undefined` on\n // the done result; the published type says the key is absent. Callers\n // observe the runtime shape, so it wins — on workerd exactly the same.\n return { done: true, value: undefined } as unknown as { done: true; value?: never };\n }\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 /**\n * ← `Cursor::raw`, which shares this cursor's position rather than\n * restarting. The iterator's shape is `RawIterator`'s whole doc comment.\n */\n raw<U extends SqlStorageValue[]>(): IterableIterator<U> {\n return new RawIterator<U>(() => this.#nextRaw());\n }\n\n /** ← `JSG_ITERABLE(rows)`, yielding through the same shared position. */\n [Symbol.iterator](): IterableIterator<T> {\n return new RowIterator<T>(() => this.#nextRow());\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/** ← the jsg resource-type tag every workerd API object carries (`resource.h`). */\nObject.defineProperty(Cursor.prototype, Symbol.toStringTag, {\n value: \"Cursor\",\n configurable: true,\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: regulateUntrustedStatement }, 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, regulateUntrustedStatement);\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/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. The narrowings that\n * 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 run the decoder before `Promise.resolve`.\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. §1.4 measures that SQLite cache operations are immediate, so their\n * `kj::OneOf<T, kj::Promise<T>>` branch has nothing to select between.\n * `transformMaybeBackpressure` keeps the branch because\n * `DeleteAllResults.backpressure` is still a promise in `io/actor-cache.ts`.\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, SqliteKvListCursor } 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\";\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 */\nfunction serializeValue(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 */\nfunction deserializeValue<T = unknown>(key: string, buffer: Uint8Array): T {\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 const value = structured\n ? deserializeStructuredClone(parsed as ReturnType<typeof serializeStructuredClone>)\n : parsed;\n return value as T;\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// =======================================================================================\n// The option transforms\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`. */\ntype 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. `SyncKvStorage` reuses it, exactly as upstream's\n * 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 */\nfunction 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// SyncKvStorage\n\n/**\n * ← workerd `src/workerd/api/sync-kv.{h,c++}`. The synchronous surface lives\n * beside the asynchronous storage owner because both share the same codec and\n * list-option compiler over one `SqliteKv`.\n */\nclass SyncKvStorage implements globalThis.SyncKvStorage {\n readonly #ctx: IoContext;\n readonly #kv: SqliteKv;\n\n constructor(ctx: IoContext, kv: SqliteKv) {\n this.#ctx = ctx;\n this.#kv = kv;\n }\n\n get<T = unknown>(key: string): T | undefined {\n requireInputLock(this.#ctx, \"kv.get()\");\n const value = this.#kv.get(key);\n if (value === undefined) return undefined;\n return deserializeValue<T>(key, value);\n }\n\n list<T = unknown>(options?: globalThis.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 [];\n }\n\n const cursor = this.#kv.list(\n compiled.start,\n compiled.end,\n compiled.limit,\n compiled.reverse ? \"REVERSE\" : \"FORWARD\",\n );\n return listIterator<T>(cursor);\n }\n\n put<T>(key: string, value: T): void {\n requireInputLock(this.#ctx, \"kv.put()\");\n this.#kv.put(key, serializeValue(value));\n }\n\n delete(key: string): boolean {\n requireInputLock(this.#ctx, \"kv.delete()\");\n return this.#kv.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 for (;;) {\n const pair = cursor.next();\n if (pair !== undefined) {\n yield [pair.key, deserializeValue<T>(pair.key, pair.value)];\n continue;\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;\n }\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 */\nabstract 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 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 = { ...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 = { ...maybeOptions, noCache: false };\n return Promise.resolve(this.getCache(OP_GET_ALARM).getAlarm(options));\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 = { ...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 Promise.resolve(listResultsToMap<T>(result));\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(keyOrEntries, valueOrOptions as T, { ...maybeOptions });\n }\n return this.#putMultiple(\n keyOrEntries,\n { ...(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 = { ...maybeOptions };\n if (typeof keyOrKeys === \"string\") {\n return Promise.resolve(this.getCache(OP_DELETE).delete(keyOrKeys, options));\n }\n return Promise.resolve(this.getCache(OP_DELETE).deleteMultiple(keyOrKeys, options));\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 = { ...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 = { ...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 Promise.resolve(value === undefined ? undefined : deserializeValue<T>(key, value));\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 Promise.resolve(listResultsToMap<T>(result));\n }\n\n #putOne<T>(key: string, value: T, options: WriteOptions): Promise<void> {\n this.getCache(OP_PUT).put(key, serializeValue(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(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<T>(entry.key, entry.value));\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: globalThis.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 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(): globalThis.SyncKvStorage {\n this.#kv ??= new SyncKvStorage(this.ctx, this.#cache.getSqliteKv());\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 = { ...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\nclass 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 awaitIo<T, R>(promise: Promise<T>, func: (value: T) => R | PromiseLike<R>): Promise<R>;\n};\n\n/** A consumed Blob is a second-order body: every read it produces needs the same gate. */\nfunction gateBlob(ctx: IoAwaiter, blob: Blob): Blob {\n const arrayBuffer = blob.arrayBuffer.bind(blob);\n const bytes = blob.bytes.bind(blob);\n const slice = blob.slice.bind(blob);\n const stream = blob.stream.bind(blob);\n const text = blob.text.bind(blob);\n\n Object.defineProperties(blob, {\n arrayBuffer: {\n configurable: true,\n writable: true,\n value: (): Promise<ArrayBuffer> => ctx.awaitIo(arrayBuffer()),\n },\n bytes: {\n configurable: true,\n writable: true,\n value: (): Promise<Uint8Array<ArrayBuffer>> => ctx.awaitIo(bytes()),\n },\n slice: {\n configurable: true,\n writable: true,\n value: (start?: number, end?: number, contentType?: string): Blob =>\n gateBlob(ctx, slice(start, end, contentType)),\n },\n stream: {\n configurable: true,\n writable: true,\n value: (): ReadableStream<Uint8Array<ArrayBuffer>> => gateReadableStream(ctx, stream()),\n },\n text: {\n configurable: true,\n writable: true,\n value: (): Promise<string> => ctx.awaitIo(text()),\n },\n });\n\n return blob;\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 const result = (\n subject[property as (typeof BODY_CONSUMERS)[number]] as (\n ...a: unknown[]\n ) => Promise<unknown>\n ).apply(subject, args);\n return ctx.awaitIo(result, (value) =>\n property === \"blob\" ? gateBlob(ctx, value as Blob) : value,\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 cancel = stream.cancel.bind(stream);\n const getReader = stream.getReader.bind(stream);\n const tee = stream.tee.bind(stream);\n const pipeThrough = stream.pipeThrough.bind(stream);\n const pipeTo = stream.pipeTo.bind(stream);\n const values = async function* (options?: {\n preventCancel?: boolean;\n }): AsyncGenerator<T, void, unknown> {\n const reader = gateReader(ctx, getReader());\n let finished = false;\n try {\n for (;;) {\n let result: ReadableStreamReadResult<T>;\n try {\n result = await reader.read();\n } catch (exception) {\n finished = true;\n throw exception;\n }\n if (result.done) {\n finished = true;\n return;\n }\n yield result.value;\n }\n } finally {\n try {\n if (!finished && options?.preventCancel !== true) await reader.cancel();\n } finally {\n reader.releaseLock();\n }\n }\n };\n\n Object.defineProperties(stream, {\n cancel: {\n configurable: true,\n writable: true,\n value(reason?: unknown): Promise<void> {\n return ctx.awaitIo(cancel(reason));\n },\n },\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 // The pipe operations launder the gating: the native machinery reads the source through\n // internal spec operations (not the `getReader` property above), and `pipeThrough` hands\n // back the transform's readable — a brand-new stream with none of this instrumentation.\n // `res.body.pipeThrough(new TextDecoderStream()).getReader().read()` would resume foreign\n // on every chunk. The pipe's own internals never surface a user continuation, so the two\n // seams that do are the ones gated: the returned readable, and `pipeTo`'s settlement.\n pipeThrough: {\n configurable: true,\n writable: true,\n value<U>(\n transform: ReadableWritablePair<U, T>,\n options?: StreamPipeOptions,\n ): ReadableStream<U> {\n return gateReadableStream(ctx, pipeThrough(transform, options));\n },\n },\n pipeTo: {\n configurable: true,\n writable: true,\n value(destination: WritableStream<T>, options?: StreamPipeOptions): Promise<void> {\n return ctx.awaitIo(pipeTo(destination, options));\n },\n },\n // Async iteration launders the gating exactly like pipeThrough: the native iterator takes\n // its reader through an internal spec operation rather than the getReader property above.\n // Iterating through the gated reader keeps every chunk inside an input-gated slice.\n values: { configurable: true, writable: true, value: values },\n [Symbol.asyncIterator]: { configurable: true, writable: true, value: values },\n });\n\n return stream;\n}\n\nfunction gateReader<T>(\n ctx: IoAwaiter,\n reader: ReadableStreamDefaultReader<T>,\n): ReadableStreamDefaultReader<T> {\n const bound = new Map<string | symbol, unknown>();\n\n return new Proxy(reader, {\n get(subject, property): unknown {\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n\n if (property === \"closed\") {\n // `closed` can remain pending for the stream's lifetime. Gate and register that one\n // promise once rather than adding a new pending actor task on every property read.\n const closed = ctx.awaitIo(subject.closed);\n bound.set(property, closed);\n return closed;\n }\n if (property === \"read\") {\n const read = (): Promise<ReadableStreamReadResult<T>> => ctx.awaitIo(subject.read());\n bound.set(property, read);\n return read;\n }\n if (property === \"cancel\") {\n const cancel = (reason?: unknown): Promise<void> => ctx.awaitIo(subject.cancel(reason));\n bound.set(property, cancel);\n return cancel;\n }\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 * ← 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, { input: 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 }, { input: 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, tryCurrentIoContext } 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 { ensureRuntimeStorageVersion } from \"../util/sqlite-migrations\";\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 an outbound call must resume through the caller's `awaitIo`, or the\n * code after it comes back with no input lock and its next storage call\n * throws. Lock state is not caller identity: a parent and its running facet\n * can both return true. `resolveLoopback()` owns that decision.\n */\n hasCurrent(): boolean;\n\n /**\n * Resolve an in-realm actor call without making the host infer caller identity.\n * A call from this exact actor context uses the raw instance; every other call\n * uses its gated entry, routed through the caller's output gate and `awaitIo`\n * when there is one. The runtime resolves a current slice or\n * transformed continuation first; `caller` is the lock-holding structural\n * fallback for untransformed post-await code. Both callbacks are lazy: only\n * the selected invocation runs.\n */\n resolveLoopback<Result>(\n invokeDirect: () => Result,\n invokeEntry: () => Promise<Awaited<Result>>,\n caller?: ActorContainer,\n ): Result | Promise<Awaited<Result>>;\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. `resolveLoopback()` makes that distinction:\n * an actor reaching its own `DurableObjectNamespace` binding from its exact\n * current context skips this door because the lock it would take is the one\n * it holds. `signal` is bound to the returned proxy and cancels invocations\n * that are still waiting for admission; it does not interrupt an admitted\n * method or its output-gate drain.\n */\n entry<T extends object>(target: T, signal?: AbortSignal): 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`. `signal` cancels only\n * while the event is queued for an input lock.\n */\n run<T>(event: () => T | PromiseLike<T>, signal?: AbortSignal): 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 resolveLoopback<Result>(\n invokeDirect: () => Result,\n invokeEntry: () => Promise<Awaited<Result>>,\n caller?: ActorContainer,\n ): Result | Promise<Awaited<Result>> {\n const context = tryCurrentIoContext();\n if (context === this.#ctx) return invokeDirect();\n if (context !== undefined) {\n return context.awaitIo(context.waitForOutputLocks().then(invokeEntry));\n }\n if (caller === undefined) return invokeEntry();\n if (!caller.hasCurrent()) {\n throw new Error(\"resolveLoopback() caller has no current input lock\");\n }\n if (caller === this) return invokeDirect();\n return caller.awaitIo(caller.waitOutputLocks().then(invokeEntry));\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, signal?: AbortSignal): 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 () =>\n this.#withExternalEntry(() =>\n (value as (...rest: unknown[]) => unknown).apply(subject, args),\n ),\n { signal },\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>, signal?: AbortSignal): Promise<T> {\n return this.#ctx.run(\n () => this.#withExternalEntry(event),\n { signal },\n );\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 input option. 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 actorDb = await options.ports.sql.open(ACTOR_DATABASE_NAME);\n ensureRuntimeStorageVersion(actorDb, ACTOR_DATABASE_NAME);\n const db = new SqliteDatabase(actorDb);\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 facetDb = await options.ports.sql.open(FACET_DATABASE_NAME);\n ensureRuntimeStorageVersion(facetDb, FACET_DATABASE_NAME);\n const tree = new ActorTree(facetDb, options.ports.facets);\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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"}
1
+ {"version":3,"file":"index.js","names":["#channel","#id","#fetcher","#idFactory","#getImpl","#channel","#fetcher","#loopbackClass","#channel","#ctx","#options","#toDynamicWorkerSource","#extractCompatFlags","#pull","#columnNames","#rawRows","#rowsWritten","#nextRow","#position","#nextRaw","#ctx","#owner","#getPageSize","#pageSize","#ctx","#kv","#getOne","#getMultiple","#putOne","#putMultiple","#cache","#sql","#cacheTxn","#rolledBack","#facetManager","#parentId","#getFacetManager","#options","#facets","#request","#response","#sentClose","#socket","#pairState","#ctx","#enableClassic","#receive","#readyState","#binaryType","#delivery","#ownClose","#peerClose","#markPairUsed","#enqueue","#activateHibernation","#pending","#deliverClassic","#receiveClose","#pump","#dispatch","#host","#entries","#rehydrate","#pairConstructor","#createPair","#listenRaw","#autoResponse","#eventTimeout","#schedule","#remove","#scope","#requireOwnSlice","#ctx","#subtle","#gated","#crypto","#fetch","#readCurrentExternalEntry","#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","#webSockets","#runWebSocketHandler","#currentExternalEntry","#withExternalEntry","#alarmTail","#deliverAlarmImpl","#runAlarmHandler"],"sources":["../src/api/actor.ts","../src/api/export-loopback.ts","../src/api/worker-loader.ts","../src/api/sql.ts","../src/api/actor-state.ts","../src/api/http.ts","../src/api/web-socket.ts","../src/api/global-scope.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/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 */\ntype 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 */\ntype 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, and that is not the whole authorizer.**\n * Four of its five members are here as callbacks, and none needed the\n * authorizer to compute anything — `isAllowedName` is a prefix test,\n * `isAllowedTrigger` is `return true`, `allowTransactions` throws,\n * `shouldAddQueryStats` is a constant. The fifth, `onError`, is not a\n * callback at all in this port: it is every `throw new Error(message)`\n * below, which is all its upstream body does with a refusal message.\n * For those, what the authorizer supplied was the *identifiers*:\n * with none, 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 *\n * But the authorizer also makes decisions no callback ever sees, and those\n * do NOT arrive with the regulator: `SQLITE_ATTACH` / `SQLITE_DETACH`, the\n * `SQLITE_CREATE_TEMP_*` family and the `temp` schema, `SQLITE_PRAGMA`, and\n * the `SQLITE_CREATE_VTABLE` module list. Each is refused from the text in\n * `refuseUnauthorizedForms` and `requireAllowedPragmas`. `SQLITE_FUNCTION`\n * is the one still unported — see the README divergence row.\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 *\n * `;` counts as leading trivia here and in every other leading-keyword refusal\n * below. A statement boundary comes from the backend, and `node:sqlite` reports\n * an empty leading statement as part of the span it compiled: the `sourceSQL`\n * for `;ATTACH ...` is the whole string, so an anchor of `^\\s*` would read the\n * keyword as `;` and let the compiled ATTACH through. The browser backend cuts\n * the same input at the first `;` and refuses the empty statement instead.\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 * Comments are never code. String literals STAY, for both of this regex's callers: pragma\n * arguments may be quoted, and SQLite's misquoting feature reads a single-quoted string as an\n * identifier — `CREATE TABLE 'temp'.t(x)` really creates a temp-schema table — so the checks\n * that read identifier positions must still see it. `NOT_CODE` blanks literals, which is right\n * for the token scans and would be a bypass for these callers.\n */\nconst NOT_COMMENT = /--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g;\n\n/**\n * ← `SqlStorageRegulator` (`sql.h:15-22`, `sql.c++:141-165`), 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 message a `SQLITE_DENY` from the authorizer surfaces to JavaScript,\n * byte-identical so a caller matching on it ports unchanged.\n */\nexport const SQL_NOT_AUTHORIZED_MESSAGE = \"not authorized: SQLITE_AUTH\";\n\n/**\n * The forms neither the regulator nor any callback sees: the authorizer's own\n * action codes, plus `VACUUM`, which SQLite itself refuses by precondition.\n *\n * Porting `SqlStorageRegulator` whole (point 3 in the file header) carried over its members, but\n * not the authorizer's own action codes: `SQLITE_ATTACH`, `SQLITE_DETACH`, `SQLITE_CREATE_TEMP_*`\n * and `SQLITE_CREATE_VTABLE` consult no callback, so nothing here refused them. Every form below\n * was measured on real workerd through the conformance oracle, not inferred.\n *\n * `ATTACH` and `DETACH` are also the isolation boundary rather than a fidelity detail: both\n * backends open a real file, so on `node:sqlite` an `ATTACH` reads another actor's database and\n * a `VACUUM INTO` writes anywhere the process can. The reserved-name scan does not cover it,\n * because that scan tokenizes the SUBMITTED statement — `other._cf_KV` is caught, and every\n * application table in the same attached database is not.\n */\nconst DATABASE_ATTACHMENT = /^[\\s;]*(?:ATTACH|DETACH)\\b/i;\n\n/**\n * ← the `SQLITE_CREATE_TEMP_*` denials (`sqlite.c++:1323`) and the `dbName == temp` rule\n * (`sqlite.c++:1073`), which permits a temp-schema database name only `READ` and `UPDATE`.\n * Upstream's own reason to deny them applies here unchanged: a temporary table makes SQLite\n * open a separate temporary file that the storage engine knows nothing about.\n *\n * Two spellings, one refusal each by its own upstream path: `CREATE TEMP TABLE t(x)` is the\n * keyword and hits the action codes; `CREATE TABLE temp.t(x)` is the schema qualifier and hits\n * the `dbName` rule — and the qualifier was the live gap, where the table was created, written\n * and read back here while workerd refused it outright. The qualifier accepts every quoting\n * SQLite does, single quotes included, with or without whitespace after the keyword (measured:\n * workerd refuses `CREATE TABLE 'temp'.t(x)` and `CREATE TABLE\"temp\".t(x)` the same way), and\n * is matched only in the object-name position, so an application table merely NAMED `tempest`\n * or `temporary_log` is untouched. The keyword spelling needs no qualifier arm of its own here:\n * `TEMP_SCHEMA` already refuses every `CREATE TEMP…` before this pattern is consulted.\n *\n * The rest of the `dbName` rule goes unported on purpose: with no way to create a temp-schema\n * object, `INSERT`/`DELETE`/`DROP` against one die in SQLite as `no such table`, and the one\n * silent form measures identically — workerd allows `DROP TABLE IF EXISTS temp.ghost` too.\n */\nconst TEMP_SCHEMA = /^[\\s;]*CREATE\\s+(?:TEMP|TEMPORARY)\\b/i;\nconst TEMP_QUALIFIED =\n /^[\\s;]*CREATE\\s+(?:UNIQUE\\s+|VIRTUAL\\s+)?(?:TABLE|VIEW|TRIGGER|INDEX)\\s*(?:IF\\s+NOT\\s+EXISTS\\s*)?(?:\"temp\"|'temp'|`temp`|\\[temp\\]|temp)\\s*\\./i;\n\n/**\n * ← `SQLITE_CREATE_VTABLE` (`sqlite.c++:1298-1316`): a virtual table is native-code callbacks, so\n * upstream allows exactly four modules — FTS5 and its `fts5vocab` companion, R*Tree and its\n * `rtree_i32` variant — and denies every other module SQLite was compiled with.\n *\n * `dbstat` is why this is not only fidelity: it reports a row per table with page counts and\n * byte sizes, so `SELECT name FROM d` enumerates `_cf_KV` and the rest of the runtime's own\n * tables without the statement ever naming them — around `requireAllowedNames`, which can only\n * see the text it was given.\n *\n * The table name and the module accept every quoting SQLite does — double quotes, backticks,\n * brackets, and the misquoting feature's single-quoted string, with or without whitespace\n * before them — because the module has to be read from PAST the name, and a guessed name\n * boundary is a bypass in both directions: an unparseable name skipped the check, and\n * `\"a USING fts5 b\" USING dbstat` read its module out of the quoted name. Measured: workerd\n * refuses both, refuses `CREATE VIRTUAL TABLE\"d\"USING dbstat`, resolves `USING \"dbstat\"` to\n * the same denial, and allows `USING 'fts5'`. A `CREATE VIRTUAL TABLE` whose module the\n * pattern cannot read is refused outright — the deliberately stricter direction the\n * unparseable-PRAGMA fallback below already takes.\n */\n// The bare arm takes what SQLite's tokenizer does: alphanumerics, `_`, `$`, and any\n// character past ASCII — a table named `résumé` is legal and workerd allows it.\nconst SQL_IDENTIFIER_SOURCE =\n /\"(?:[^\"]|\"\")*\"|'(?:[^']|'')*'|`(?:[^`]|``)*`|\\[[^\\]]*\\]|[A-Za-z_\\u0080-\\uffff][A-Za-z0-9_$\\u0080-\\uffff]*/\n .source;\nconst VIRTUAL_TABLE = /^[\\s;]*CREATE\\s+VIRTUAL\\s+TABLE\\b/i;\nconst VIRTUAL_TABLE_MODULE = new RegExp(\n String.raw`^[\\s;]*CREATE\\s+VIRTUAL\\s+TABLE\\s*(?:IF\\s+NOT\\s+EXISTS\\s*)?(?:${SQL_IDENTIFIER_SOURCE})\\s*(?:\\.\\s*(?:${SQL_IDENTIFIER_SOURCE})\\s*)?USING\\s*(${SQL_IDENTIFIER_SOURCE})`,\n \"i\",\n);\nconst ALLOWED_VIRTUAL_TABLE_MODULES = new Set([\"fts5\", \"fts5vocab\", \"rtree\", \"rtree_i32\"]);\n\n/**\n * `VACUUM` has no action code of its own, so the authorizer never sees it. What refuses it\n * upstream is SQLite's own `cannot VACUUM from within a transaction` precondition, against the\n * transaction a Durable Object always has open — and that message is what the oracle returned,\n * for `VACUUM`, `VACUUM main` and `VACUUM INTO` alike. Byte-identical for the same reason\n * `SQL_NOT_AUTHORIZED_MESSAGE` is: a caller matching on it ports unchanged.\n *\n * Refused here unconditionally rather than by transaction state, which is a divergence only in\n * mechanism: this runtime never runs a statement where upstream would have allowed it.\n */\nconst VACUUM_STATEMENT = /^[\\s;]*VACUUM\\b/i;\nexport const SQL_VACUUM_REFUSED_MESSAGE = \"cannot VACUUM from within a transaction: SQLITE_ERROR\";\n\n/** Refuse the authorizer-only forms against one SQLite-decided statement boundary. */\nfunction refuseUnauthorizedForms(statement: string): void {\n const code = statement.replace(NOT_COMMENT, \" \");\n if (VACUUM_STATEMENT.test(code)) throw new Error(SQL_VACUUM_REFUSED_MESSAGE);\n if (DATABASE_ATTACHMENT.test(code) || TEMP_SCHEMA.test(code) || TEMP_QUALIFIED.test(code)) {\n throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n }\n if (VIRTUAL_TABLE.test(code)) {\n const moduleName = VIRTUAL_TABLE_MODULE.exec(code)?.[1];\n if (\n moduleName === undefined ||\n !ALLOWED_VIRTUAL_TABLE_MODULES.has(unquoted(moduleName).toLowerCase())\n ) {\n throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n }\n }\n}\n\n/** Cheap pre-test; `PRAGMA` and the `pragma_` functions both contain it. */\nconst PRAGMA_HINT = /pragma/i;\n\n/** `PRAGMA [schema.]name`, then `= value`, `(argument)`, or nothing. */\nconst PRAGMA_STATEMENT =\n /^[\\s;]*PRAGMA\\s+(?:[A-Za-z_][A-Za-z0-9_$]*\\s*\\.\\s*)?([A-Za-z_][A-Za-z0-9_$]*)(?:\\s*=\\s*([\\s\\S]+?)|\\s*\\(\\s*([\\s\\S]*?)\\s*\\))?\\s*;?\\s*$/i;\n\n/**\n * ← `ALLOWED_PRAGMAS` (`util/sqlite.c++:543-571`) and `PragmaSignature` (`:528-535`),\n * verbatim. `table_list`, `table_info`, and `table_xinfo` are special-cased\n * ahead of the table in the authorizer, exactly as upstream's `SQLITE_PRAGMA`\n * case does (`util/sqlite.c++:1194-1273`).\n */\nconst ALLOWED_PRAGMAS = new Map<\n string,\n \"NO_ARG\" | \"BOOLEAN\" | \"OBJECT_NAME\" | \"OPTIONAL_OBJECT_NAME\" | \"NULL_OR_NUMBER\" | \"NULL_NUMBER_OR_OBJECT_NAME\"\n>([\n [\"data_version\", \"NO_ARG\"],\n // Upstream's own comment: \"The R*Tree module issues `PRAGMA page_size` (with no argument)\n // internally to read the current page size. `PRAGMA page_size=N`, which would attempt to\n // change the page size, is still rejected.\" `NO_ARG` is what rejects the assignment.\n [\"page_size\", \"NO_ARG\"],\n [\"case_sensitive_like\", \"BOOLEAN\"],\n [\"foreign_keys\", \"BOOLEAN\"],\n [\"defer_foreign_keys\", \"BOOLEAN\"],\n [\"ignore_check_constraints\", \"BOOLEAN\"],\n [\"legacy_alter_table\", \"BOOLEAN\"],\n [\"recursive_triggers\", \"BOOLEAN\"],\n [\"reverse_unordered_selects\", \"BOOLEAN\"],\n [\"foreign_key_check\", \"OPTIONAL_OBJECT_NAME\"],\n [\"foreign_key_list\", \"OBJECT_NAME\"],\n [\"index_info\", \"OBJECT_NAME\"],\n [\"index_list\", \"OBJECT_NAME\"],\n [\"index_xinfo\", \"OBJECT_NAME\"],\n [\"quick_check\", \"NULL_NUMBER_OR_OBJECT_NAME\"],\n [\"optimize\", \"NULL_OR_NUMBER\"],\n]);\n\n/** Upstream compares the eight literal forms as PREFIXES, case-insensitively. */\nconst BOOLEAN_PRAGMA_VALUE = /^(?:true|false|yes|no|on|off|1|0)/i;\n\n/**\n * The pragmas SQLite ships (https://www.sqlite.org/pragma.html), so a\n * `pragma_X` identifier can be told apart: `X` here means the table-valued\n * pragma function and follows the allowlist; any other `pragma_`-prefixed\n * identifier is an ordinary application name, which upstream's authorizer\n * distinguishes by resolution and the conformance suite pins.\n */\nconst SQLITE_PRAGMA_NAMES = new Set([\n \"analysis_limit\", \"application_id\", \"auto_vacuum\", \"automatic_index\",\n \"busy_timeout\", \"cache_size\", \"cache_spill\", \"case_sensitive_like\",\n \"cell_size_check\", \"checkpoint_fullfsync\", \"collation_list\",\n \"compile_options\", \"data_version\", \"database_list\", \"defer_foreign_keys\",\n \"encoding\", \"foreign_key_check\", \"foreign_key_list\", \"foreign_keys\",\n \"freelist_count\", \"full_column_names\", \"fullfsync\", \"function_list\",\n \"hard_heap_limit\", \"ignore_check_constraints\", \"incremental_vacuum\",\n \"index_info\", \"index_list\", \"index_xinfo\", \"integrity_check\",\n \"journal_mode\", \"journal_size_limit\", \"legacy_alter_table\",\n \"legacy_file_format\", \"locking_mode\", \"max_page_count\", \"mmap_size\",\n \"module_list\", \"optimize\", \"page_count\", \"page_size\", \"pragma_list\",\n \"query_only\", \"quick_check\", \"read_uncommitted\", \"recursive_triggers\",\n \"reverse_unordered_selects\", \"schema_version\", \"secure_delete\",\n \"short_column_names\", \"shrink_memory\", \"soft_heap_limit\", \"synchronous\",\n \"table_info\", \"table_list\", \"table_xinfo\", \"temp_store\", \"threads\",\n \"trusted_schema\", \"user_version\", \"wal_autocheckpoint\", \"wal_checkpoint\",\n \"writable_schema\",\n]);\n\n/** kj's `tryParseAs` is decimal; keep the same acceptance. */\nconst DECIMAL = /^[+-]?\\d+$/;\n\n/**\n * One layer of SQL quoting, any of the four forms — a pragma argument, or the module token\n * `VIRTUAL_TABLE_MODULE` captured. Doubled inner quotes stay doubled, which cannot change a\n * verdict here: no allowlisted comparison target contains a quote character.\n */\nfunction unquoted(argument: string): string {\n const first = argument[0];\n const last = argument[argument.length - 1];\n if (argument.length >= 2) {\n if ((first === \"'\" || first === '\"' || first === \"`\") && last === first) {\n return argument.slice(1, -1);\n }\n if (first === \"[\" && last === \"]\") return argument.slice(1, -1);\n }\n return argument;\n}\n\n/** ← the `SQLITE_PRAGMA` authorizer case (`util/sqlite.c++:1194-1273`), whole. */\nfunction isAllowedPragma(name: string, argument: string | undefined): boolean {\n const pragma = name.toLowerCase();\n if (pragma === \"table_list\") return true;\n if (pragma === \"table_info\" || pragma === \"table_xinfo\") {\n // \"Allow if the specific named table is not protected.\"\n if (argument === undefined) return false;\n return SqlStorageRegulator.isAllowedName(unquoted(argument));\n }\n const signature = ALLOWED_PRAGMAS.get(pragma);\n if (signature === undefined) return false;\n switch (signature) {\n case \"NO_ARG\":\n return argument === undefined;\n case \"BOOLEAN\":\n // \"We allow omitting the argument in order to read back the current value.\"\n return argument === undefined || BOOLEAN_PRAGMA_VALUE.test(unquoted(argument));\n case \"OBJECT_NAME\":\n return argument !== undefined && SqlStorageRegulator.isAllowedName(unquoted(argument));\n case \"OPTIONAL_OBJECT_NAME\":\n return argument === undefined || SqlStorageRegulator.isAllowedName(unquoted(argument));\n case \"NULL_OR_NUMBER\":\n return argument === undefined || DECIMAL.test(argument);\n case \"NULL_NUMBER_OR_OBJECT_NAME\":\n return (\n argument === undefined ||\n DECIMAL.test(argument) ||\n SqlStorageRegulator.isAllowedName(unquoted(argument))\n );\n }\n}\n\n/**\n * The text-level stand-in for the authorizer's `SQLITE_PRAGMA` case, against\n * one SQLite-decided statement boundary. Load-bearing beyond fidelity:\n * `user_version` is where runtime storage versioning keeps its per-file stamp\n * (`util/sqlite-migrations.ts`), and `writable_schema` would let application\n * SQL rewrite `sqlite_master` out from under the `_cf_` reservation.\n *\n * The `pragma_` table-valued functions reach the same authorizer path\n * upstream, so they follow the same allowlist here — by pragma NAME only. An\n * argument the text cannot see (a string literal or a binding) goes unchecked\n * where upstream's authorizer sees the resolved value; a `_cf_` name smuggled\n * that way reads schema whose shape is public source anyway, while identifier\n * arguments stay covered by `requireAllowedNames`. The README divergence row\n * records this.\n */\nfunction requireAllowedPragmas(statement: string): void {\n if (!PRAGMA_HINT.test(statement)) return;\n const code = statement.replace(NOT_COMMENT, \" \");\n const direct = code.match(PRAGMA_STATEMENT);\n if (direct !== null) {\n const [, name = \"\", assigned, called] = direct;\n const argument = (assigned ?? called)?.trim();\n if (!isAllowedPragma(name, argument === \"\" ? undefined : argument)) {\n throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n }\n return;\n }\n // A statement that leads with PRAGMA but does not parse as one is refused —\n // the deliberately stricter direction the reserved-name check already takes.\n if (/^[\\s;]*PRAGMA\\b/i.test(code)) throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n const literalFree = code.replace(NOT_CODE, \" \");\n for (const [token] of literalFree.matchAll(IDENTIFIER)) {\n if (token.length <= 7 || token.slice(0, 7).toLowerCase() !== \"pragma_\") continue;\n const name = token.slice(7).toLowerCase();\n if (!SQLITE_PRAGMA_NAMES.has(name)) continue;\n if (\n name !== \"table_list\" &&\n name !== \"table_info\" &&\n name !== \"table_xinfo\" &&\n !ALLOWED_PRAGMAS.has(name)\n ) {\n throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);\n }\n }\n}\n\n/** Everything the untrusted path refuses at one statement boundary. */\nfunction regulateUntrustedStatement(statement: string): void {\n refuseTransactionControl(statement);\n refuseUnauthorizedForms(statement);\n requireAllowedPragmas(statement);\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/** ← `JSG_INHERIT_INTRINSIC(v8::kIteratorPrototype)` (`jsg/iterator.h:1044`). */\nconst IteratorPrototype: object = Object.getPrototypeOf(\n Object.getPrototypeOf([][Symbol.iterator]()),\n) as object;\n\n/**\n * ← the `JSG_ITERATOR` types (`jsg/iterator.h:1036-1050`): `next` and\n * self-iterability on `%IteratorPrototype%` — which is what carries the ES\n * iterator helpers; `raw().toArray()` is what Drizzle's durable-sqlite driver\n * calls — and NOTHING else. No `return`, no `throw` (only the async variant\n * registers `return_`, `:1069-1085`), so `IteratorClose` after a `break`, a\n * partial destructuring, or a `take()` is a no-op and a retained iterator\n * resumes. Results are `JSG_STRUCT(done, value)` in that key order\n * (`jsg/iterator.h:706-710`).\n */\nclass RawIterator<U extends SqlStorageValue[]> implements IterableIterator<U> {\n readonly #pull: () => readonly SqlStorageValue[] | undefined;\n\n constructor(pull: () => readonly SqlStorageValue[] | undefined) {\n this.#pull = pull;\n }\n\n next(): { done: false; value: U } | { done: true; value: undefined } {\n const raw = this.#pull();\n if (raw === undefined) return { done: true, value: undefined };\n return { done: false, value: asRawRow<U>([...raw]) };\n }\n\n [Symbol.iterator](): IterableIterator<U> {\n return this;\n }\n}\nObject.setPrototypeOf(RawIterator.prototype, IteratorPrototype);\nObject.defineProperty(RawIterator.prototype, Symbol.toStringTag, {\n value: \"RawIterator\",\n configurable: true,\n});\n\n/** ← `RowIterator`, shaped exactly as `RawIterator` above. */\nclass RowIterator<T extends SqlRow> implements IterableIterator<T> {\n readonly #pull: () => T | undefined;\n\n constructor(pull: () => T | undefined) {\n this.#pull = pull;\n }\n\n next(): { done: false; value: T } | { done: true; value: undefined } {\n const row = this.#pull();\n if (row === undefined) return { done: true, value: undefined };\n return { done: false, value: row };\n }\n\n [Symbol.iterator](): IterableIterator<T> {\n return this;\n }\n}\nObject.setPrototypeOf(RowIterator.prototype, IteratorPrototype);\nObject.defineProperty(RowIterator.prototype, Symbol.toStringTag, {\n value: \"RowIterator\",\n configurable: true,\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 /**\n * ← `JSG_READONLY_PROTOTYPE_PROPERTY(columnNames)` (`sql.h:210`): a\n * prototype accessor, not an own field, so a cursor JSON-stringifies to `{}`.\n */\n get columnNames(): string[] {\n return this.#columnNames;\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) {\n // ← `JSG_STRUCT(done, value)` serializes an OWN `value: undefined` on\n // the done result; the published type says the key is absent. Callers\n // observe the runtime shape, so it wins — on workerd exactly the same.\n return { done: true, value: undefined } as unknown as { done: true; value?: never };\n }\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 /**\n * ← `Cursor::raw`, which shares this cursor's position rather than\n * restarting. The iterator's shape is `RawIterator`'s whole doc comment.\n */\n raw<U extends SqlStorageValue[]>(): IterableIterator<U> {\n return new RawIterator<U>(() => this.#nextRaw());\n }\n\n /** ← `JSG_ITERABLE(rows)`, yielding through the same shared position. */\n [Symbol.iterator](): IterableIterator<T> {\n return new RowIterator<T>(() => this.#nextRow());\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/** ← the jsg resource-type tag every workerd API object carries (`resource.h`). */\nObject.defineProperty(Cursor.prototype, Symbol.toStringTag, {\n value: \"Cursor\",\n configurable: true,\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: regulateUntrustedStatement }, 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, regulateUntrustedStatement);\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/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. The narrowings that\n * 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 run the decoder before `Promise.resolve`.\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. §1.4 measures that SQLite cache operations are immediate, so their\n * `kj::OneOf<T, kj::Promise<T>>` branch has nothing to select between.\n * `transformMaybeBackpressure` keeps the branch because\n * `DeleteAllResults.backpressure` is still a promise in `io/actor-cache.ts`.\n *\n * Not ported, because the substrate has no equivalent: V8's private wire bytes,\n * replaced by a browser-safe structured-clone encoding with the same public\n * value semantics; the billing 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, SqliteKvListCursor } 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 type { HibernatableWebSocketRegistry } from \"./web-socket\";\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 * ← 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/** ← `actor-state.c++:455`, verbatim: the one message both overloads' misuse produces. */\nconst PUT_OVERLOAD_MESSAGE =\n \"put() may only be called with a single key-value pair and optional options as \" +\n \"put(key, value, options) or with multiple key-value pairs and optional options as \" +\n \"put(entries, options)\";\n\n/**\n * ← the `kj::OneOf<kj::String, jsg::Dict<…>>` unwrap on put()'s first parameter: `jsg::Dict`\n * takes any JS object except an Array — functions and Maps included — and `kj::String` takes\n * everything else by coercion. A type predicate, so the overload split narrows without a cast.\n */\nfunction isEntriesArgument<T>(value: string | Record<string, T>): value is Record<string, T> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n !Array.isArray(value)\n );\n}\n\n/**\n * ← the struct wrapper (`jsg/struct.h:246-258`), which is NOT the Dict wrapper: `PutOptions` is\n * all-optional fields, so `null` unwraps to default options, and any object does — arrays and\n * functions included, because the wrapper checks `IsObject()` with no Array exclusion. Only a\n * non-null primitive fails to unwrap. Measured on real workerd: `put({k: 1}, null)`, `…, [])`\n * and `…, function () {})` all write, and `put({k: 1}, \"v\")` alone is the overload error.\n */\nfunction isPutOptions(value: unknown): boolean {\n return value === null || typeof value === \"object\" || typeof value === \"function\";\n}\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(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<T = unknown>(key: string, buffer: Uint8Array): T {\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 const value = structured\n ? deserializeStructuredClone(parsed as ReturnType<typeof serializeStructuredClone>)\n : parsed;\n return value as T;\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// =======================================================================================\n// The option transforms\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`. */\ntype 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. `SyncKvStorage` reuses it, exactly as upstream's\n * 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 */\nfunction 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// SyncKvStorage\n\n/**\n * ← workerd `src/workerd/api/sync-kv.{h,c++}`. The synchronous surface lives\n * beside the asynchronous storage owner because both share the same codec and\n * list-option compiler over one `SqliteKv`.\n */\nclass SyncKvStorage implements globalThis.SyncKvStorage {\n readonly #ctx: IoContext;\n readonly #kv: SqliteKv;\n\n constructor(ctx: IoContext, kv: SqliteKv) {\n this.#ctx = ctx;\n this.#kv = kv;\n }\n\n get<T = unknown>(key: string): T | undefined {\n requireInputLock(this.#ctx, \"kv.get()\");\n const value = this.#kv.get(key);\n if (value === undefined) return undefined;\n return deserializeValue<T>(key, value);\n }\n\n list<T = unknown>(options?: globalThis.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 [];\n }\n\n const cursor = this.#kv.list(\n compiled.start,\n compiled.end,\n compiled.limit,\n compiled.reverse ? \"REVERSE\" : \"FORWARD\",\n );\n return listIterator<T>(cursor);\n }\n\n put<T>(key: string, value: T): void {\n requireInputLock(this.#ctx, \"kv.put()\");\n this.#kv.put(key, serializeValue(value));\n }\n\n delete(key: string): boolean {\n requireInputLock(this.#ctx, \"kv.delete()\");\n return this.#kv.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 for (;;) {\n const pair = cursor.next();\n if (pair !== undefined) {\n yield [pair.key, deserializeValue<T>(pair.key, pair.value)];\n continue;\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;\n }\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 */\nabstract 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 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 = { ...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 = { ...maybeOptions, noCache: false };\n return Promise.resolve(this.getCache(OP_GET_ALARM).getAlarm(options));\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 = { ...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 Promise.resolve(listResultsToMap<T>(result));\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 `isEntriesArgument` below is the parameter-1\n // unwrap, and the guard after it is `optionsTypeHandler.tryUnwrap` on parameter 2. Two\n // upstream steps, in that order: which overload, then whether the rest of the call agrees\n // with it.\n //\n // ← the `kj::OneOf<kj::String, jsg::Dict<...>>` unwrap, which picks the overload by which\n // alternative accepts the argument. `jsg::Dict` takes a plain object and refuses an Array;\n // `kj::String` takes everything else by stringifying it — so a non-string key is NOT a\n // mistake upstream, it is the single-key overload with a coerced key. Reading one as entries\n // instead is a silently dropped write, because `Object.entries` on a primitive is `[]`: the\n // call resolves having written nothing.\n //\n // Measured on real workerd: `put(123, \"v\")` writes `\"123\"`, `put(null, \"v\")` writes `\"null\"`,\n // `put(10n, \"v\")` writes `\"10\"`, `put([[\"a\", 1]], \"v\")` writes `\"a,1\"`, and a symbol key\n // throws V8's own conversion error. That last one is why the coercion below is a template\n // literal: `String(symbol)` is the one form that returns a description instead of throwing,\n // so it would swallow the case upstream refuses. `put(new Map(...))` reaches the Dict\n // alternative and writes nothing, which the entries branch already reproduces.\n //\n // A function reaches the `Dict` alternative too, so it is entries here rather than a key\n // stringified to its own source text.\n if (!isEntriesArgument(keyOrEntries)) {\n if (valueOrOptions === undefined) {\n throw new TypeError(\"put() called with undefined value.\");\n }\n return this.#putOne(`${keyOrEntries}`, valueOrOptions as T, { ...maybeOptions });\n }\n // ← the `else` of `optionsTypeHandler.tryUnwrap` (`actor-state.c++:449-456`): once the key\n // unwrapped as a `Dict`, a second argument can only be the options bag, and a non-null\n // primitive there is the caller mixing the two overloads. Without this the value spreads\n // into the options — `put({a: 1}, \"v\")` wrote key `a` with `{0: \"v\"}` for options.\n if (valueOrOptions !== undefined && !isPutOptions(valueOrOptions)) {\n throw new TypeError(PUT_OVERLOAD_MESSAGE);\n }\n return this.#putMultiple(keyOrEntries, {\n ...(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 = { ...maybeOptions };\n if (typeof keyOrKeys === \"string\") {\n return Promise.resolve(this.getCache(OP_DELETE).delete(keyOrKeys, options));\n }\n return Promise.resolve(this.getCache(OP_DELETE).deleteMultiple(keyOrKeys, options));\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 = { ...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 = { ...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 Promise.resolve(value === undefined ? undefined : deserializeValue<T>(key, value));\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 Promise.resolve(listResultsToMap<T>(result));\n }\n\n #putOne<T>(key: string, value: T, options: WriteOptions): Promise<void> {\n this.getCache(OP_PUT).put(key, serializeValue(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(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<T>(entry.key, entry.value));\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: globalThis.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 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(): globalThis.SyncKvStorage {\n this.#kv ??= new SyncKvStorage(this.ctx, this.#cache.getSqliteKv());\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 = { ...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\nclass 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 webSockets: HibernatableWebSocketRegistry;\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 acceptWebSocket(ws: WebSocket, tags?: string[]): void {\n this.#options.webSockets.acceptWebSocket(ws, tags);\n }\n\n getWebSockets(tag?: string): WebSocket[] {\n return tag === undefined\n ? this.#options.webSockets.getWebSockets()\n : this.#options.webSockets.getWebSockets(tag);\n }\n\n setWebSocketAutoResponse(maybeReqResp?: WebSocketRequestResponsePair): void {\n this.#options.webSockets.setWebSocketAutoResponse(maybeReqResp);\n }\n\n getWebSocketAutoResponse(): WebSocketRequestResponsePair | null {\n return this.#options.webSockets.getWebSocketAutoResponse();\n }\n\n getWebSocketAutoResponseTimestamp(ws: WebSocket): Date | null {\n return this.#options.webSockets.getWebSocketAutoResponseTimestamp(ws);\n }\n\n setHibernatableWebSocketEventTimeout(timeoutMs?: number): void {\n this.#options.webSockets.setHibernatableWebSocketEventTimeout(timeoutMs);\n }\n\n getHibernatableWebSocketEventTimeout(): number | null {\n return this.#options.webSockets.getHibernatableWebSocketEventTimeout();\n }\n\n getTags(ws: WebSocket): string[] {\n return this.#options.webSockets.getTags(ws);\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 awaitIo<T, R>(promise: Promise<T>, func: (value: T) => R | PromiseLike<R>): Promise<R>;\n};\n\n/** A consumed Blob is a second-order body: every read it produces needs the same gate. */\nfunction gateBlob(ctx: IoAwaiter, blob: Blob): Blob {\n const arrayBuffer = blob.arrayBuffer.bind(blob);\n const bytes = blob.bytes.bind(blob);\n const slice = blob.slice.bind(blob);\n const stream = blob.stream.bind(blob);\n const text = blob.text.bind(blob);\n\n Object.defineProperties(blob, {\n arrayBuffer: {\n configurable: true,\n writable: true,\n value: (): Promise<ArrayBuffer> => ctx.awaitIo(arrayBuffer()),\n },\n bytes: {\n configurable: true,\n writable: true,\n value: (): Promise<Uint8Array<ArrayBuffer>> => ctx.awaitIo(bytes()),\n },\n slice: {\n configurable: true,\n writable: true,\n value: (start?: number, end?: number, contentType?: string): Blob =>\n gateBlob(ctx, slice(start, end, contentType)),\n },\n stream: {\n configurable: true,\n writable: true,\n value: (): ReadableStream<Uint8Array<ArrayBuffer>> => gateReadableStream(ctx, stream()),\n },\n text: {\n configurable: true,\n writable: true,\n value: (): Promise<string> => ctx.awaitIo(text()),\n },\n });\n\n return blob;\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 const result = (\n subject[property as (typeof BODY_CONSUMERS)[number]] as (\n ...a: unknown[]\n ) => Promise<unknown>\n ).apply(subject, args);\n return ctx.awaitIo(result, (value) =>\n property === \"blob\" ? gateBlob(ctx, value as Blob) : value,\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 cancel = stream.cancel.bind(stream);\n const getReader = stream.getReader.bind(stream);\n const tee = stream.tee.bind(stream);\n const pipeThrough = stream.pipeThrough.bind(stream);\n const pipeTo = stream.pipeTo.bind(stream);\n const values = async function* (options?: {\n preventCancel?: boolean;\n }): AsyncGenerator<T, void, unknown> {\n const reader = gateReader(ctx, getReader());\n let finished = false;\n try {\n for (;;) {\n let result: ReadableStreamReadResult<T>;\n try {\n result = await reader.read();\n } catch (exception) {\n finished = true;\n throw exception;\n }\n if (result.done) {\n finished = true;\n return;\n }\n yield result.value;\n }\n } finally {\n try {\n if (!finished && options?.preventCancel !== true) await reader.cancel();\n } finally {\n reader.releaseLock();\n }\n }\n };\n\n Object.defineProperties(stream, {\n cancel: {\n configurable: true,\n writable: true,\n value(reason?: unknown): Promise<void> {\n return ctx.awaitIo(cancel(reason));\n },\n },\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 // The pipe operations launder the gating: the native machinery reads the source through\n // internal spec operations (not the `getReader` property above), and `pipeThrough` hands\n // back the transform's readable — a brand-new stream with none of this instrumentation.\n // `res.body.pipeThrough(new TextDecoderStream()).getReader().read()` would resume foreign\n // on every chunk. The pipe's own internals never surface a user continuation, so the two\n // seams that do are the ones gated: the returned readable, and `pipeTo`'s settlement.\n pipeThrough: {\n configurable: true,\n writable: true,\n value<U>(\n transform: ReadableWritablePair<U, T>,\n options?: StreamPipeOptions,\n ): ReadableStream<U> {\n return gateReadableStream(ctx, pipeThrough(transform, options));\n },\n },\n pipeTo: {\n configurable: true,\n writable: true,\n value(destination: WritableStream<T>, options?: StreamPipeOptions): Promise<void> {\n return ctx.awaitIo(pipeTo(destination, options));\n },\n },\n // Async iteration launders the gating exactly like pipeThrough: the native iterator takes\n // its reader through an internal spec operation rather than the getReader property above.\n // Iterating through the gated reader keeps every chunk inside an input-gated slice.\n values: { configurable: true, writable: true, value: values },\n [Symbol.asyncIterator]: { configurable: true, writable: true, value: values },\n });\n\n return stream;\n}\n\nfunction gateReader<T>(\n ctx: IoAwaiter,\n reader: ReadableStreamDefaultReader<T>,\n): ReadableStreamDefaultReader<T> {\n const bound = new Map<string | symbol, unknown>();\n\n return new Proxy(reader, {\n get(subject, property): unknown {\n const cached = bound.get(property);\n if (cached !== undefined) return cached;\n\n if (property === \"closed\") {\n // `closed` can remain pending for the stream's lifetime. Gate and register that one\n // promise once rather than adding a new pending actor task on every property read.\n const closed = ctx.awaitIo(subject.closed);\n bound.set(property, closed);\n return closed;\n }\n if (property === \"read\") {\n const read = (): Promise<ReadableStreamReadResult<T>> => ctx.awaitIo(subject.read());\n bound.set(property, read);\n return read;\n }\n if (property === \"cancel\") {\n const cancel = (reason?: unknown): Promise<void> => ctx.awaitIo(subject.cancel(reason));\n bound.set(property, cancel);\n return cancel;\n }\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 * ← workerd `src/workerd/api/web-socket.{h,c++}` — classic and hibernatable\n * socket delivery over the actor's input/output gates.\n *\n * The runtime owns the WebSocket object produced by `WebSocketPair`; embedders\n * still own network transports supplied as `RawWebSocket`s. Hibernation state is\n * per container and can be mirrored through `HibernationHost` for reconstruction.\n */\n\nimport type { IoContext } from \"../io/io-context\";\nimport type { CriticalSection } from \"../io/io-gate\";\nimport { deserializeValue, serializeValue } from \"./actor-state\";\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 readonly readyState?: number;\n binaryType?: string;\n}\n\nexport interface HibernationHost {\n accepted(socket: RawWebSocket, tags: readonly string[]): void;\n attachment(socket: RawWebSocket, bytes: Uint8Array | null): void;\n autoResponse(pair: { request: string; response: string } | null): void;\n closed(socket: RawWebSocket): void;\n}\n\nexport type RehydratedWebSocket = {\n socket: RawWebSocket;\n tags?: readonly string[];\n attachment?: Uint8Array;\n autoResponseTimestamp?: number;\n};\n\ntype WebSocketPairConstructor = typeof WebSocketPair;\n\nclass WebSocketRequestResponsePairImpl implements WebSocketRequestResponsePair {\n readonly #request: string;\n readonly #response: string;\n\n constructor(request: string, response: string) {\n this.#request = String(request);\n this.#response = String(response);\n }\n\n get request(): string {\n return this.#request;\n }\n\n get response(): string {\n return this.#response;\n }\n}\n\nconst RuntimeWebSocketRequestResponsePair: typeof WebSocketRequestResponsePair =\n new Proxy(WebSocketRequestResponsePairImpl, {\n apply(): never {\n throw new TypeError(\n \"Failed to construct 'WebSocketRequestResponsePair': Please use the 'new' operator, this DOM object constructor cannot be called as a function.\",\n );\n },\n });\n\nexport { RuntimeWebSocketRequestResponsePair as WebSocketRequestResponsePair };\n\ntype RuntimeWebSocketPair = {\n 0: AcceptedWebSocket;\n 1: AcceptedWebSocket;\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\nexport const HIBERNATION_ALREADY_ACCEPTED_MESSAGE =\n \"Cannot call `acceptWebSocket()` if the WebSocket was already accepted via `accept()`\";\nexport const HIBERNATION_AFTER_ACCEPT_MESSAGE =\n \"Can't accept() WebSocket after enabling hibernation.\";\nexport const HIBERNATION_PAIR_USED_MESSAGE =\n \"Cannot call `acceptWebSocket()` on this WebSocket because its pair has already been accepted or used in a Response.\";\n\nconst MAX_HIBERNATABLE_SOCKETS = 32_768;\nconst MAX_TAGS = 10;\nconst MAX_TAG_LENGTH = 256;\nconst MAX_ATTACHMENT_BYTES = 16_384;\nconst MAX_AUTO_RESPONSE_BYTES = 2_048;\nconst MAX_EVENT_TIMEOUT = 604_800_000;\nconst MAX_CLOSE_REASON_BYTES = 123;\n\nconst WEB_SOCKET_READY_STATES = {\n READY_STATE_CONNECTING: 0,\n READY_STATE_OPEN: 1,\n READY_STATE_CLOSING: 2,\n READY_STATE_CLOSED: 3,\n CONNECTING: 0,\n OPEN: 1,\n CLOSING: 2,\n CLOSED: 3,\n} as const;\n\nconst textEncoder = new TextEncoder();\n\nconst SOCKET_EVENTS = [\"open\", \"message\", \"close\", \"error\"] as const;\ntype SocketEvent = (typeof SOCKET_EVENTS)[number];\n\ntype PairState = {\n used: boolean;\n hibernationAccepted: boolean;\n};\n\ntype SocketAcceptance =\n | { mode: \"classic\" }\n | { mode: \"hibernatable\"; registry: HibernatableWebSocketRegistry };\n\ntype SocketDelivery =\n | { mode: \"pending\" }\n | { mode: \"classic\"; criticalSection: CriticalSection | undefined }\n | { mode: \"hibernatable\"; registry: HibernatableWebSocketRegistry };\n\ntype SocketMetadata = {\n accepted?: SocketAcceptance;\n attachment?: Uint8Array;\n rawListenersInstalled?: true;\n};\n\nconst metadata = new WeakMap<object, SocketMetadata>();\n\nfunction socketMetadata(socket: object): SocketMetadata {\n let value = metadata.get(socket);\n if (value === undefined) {\n value = {};\n metadata.set(socket, value);\n }\n return value;\n}\n\nfunction isRawWebSocket(value: unknown): value is RawWebSocket {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"addEventListener\" in value &&\n typeof value.addEventListener === \"function\" &&\n \"send\" in value &&\n typeof value.send === \"function\" &&\n \"close\" in value &&\n typeof value.close === \"function\"\n );\n}\n\nfunction requireWebSocket(value: unknown, operation: string): RawWebSocket {\n if (!isRawWebSocket(value)) {\n throw new TypeError(\n `Failed to execute '${operation}' on 'WebSocket': parameter 1 is not of type 'WebSocket'.`,\n );\n }\n return value;\n}\n\nfunction serializeAttachment(socket: RawWebSocket, value: unknown): void {\n try {\n structuredClone(value);\n } catch (error) {\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw new DOMException(\n error.message.replace(/^Failed to execute 'structuredClone' on '[^']+': /, \"\"),\n \"DataCloneError\",\n );\n }\n throw error;\n }\n const bytes = serializeValue(value);\n // ponytail: the local codec's string envelope is seven bytes wider than V8's;\n // replace this size adapter if the package adopts V8 wire bytes.\n const measuredBytes =\n typeof value === \"string\" ? textEncoder.encode(value).byteLength + 5 : bytes.byteLength;\n if (measuredBytes > MAX_ATTACHMENT_BYTES) {\n throw new Error(\n `A WebSocket 'attachment' cannot be larger than ${MAX_ATTACHMENT_BYTES} bytes.'attachment' was ${measuredBytes} bytes.`,\n );\n }\n const state = socketMetadata(socket);\n state.attachment = bytes;\n if (state.accepted?.mode === \"hibernatable\") {\n state.accepted.registry.attachmentChanged(socket, bytes);\n }\n}\n\nfunction deserializeAttachment(socket: RawWebSocket): unknown {\n const attachment = socketMetadata(socket).attachment;\n if (attachment === undefined) return null;\n return deserializeValue(\"WebSocket attachment\", attachment);\n}\n\nfunction serializeAttachmentMethod(this: unknown, value?: unknown): void {\n if (arguments.length === 0) {\n throw new TypeError(\n \"Failed to execute 'serializeAttachment' on 'WebSocket': parameter 1 is not of type 'Value'.\",\n );\n }\n serializeAttachment(requireWebSocket(this, \"serializeAttachment\"), value);\n}\n\nfunction deserializeAttachmentMethod(this: unknown): unknown {\n return deserializeAttachment(requireWebSocket(this, \"deserializeAttachment\"));\n}\n\nfunction cloneMessageData(data: unknown): string | ArrayBuffer | Blob {\n if (typeof data === \"string\" || data instanceof Blob) return data;\n if (data instanceof ArrayBuffer) return data.slice(0);\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength).slice().buffer;\n }\n return String(data);\n}\n\nclass MemoryWebSocketEndpoint extends EventTarget implements RawWebSocket {\n peer!: MemoryWebSocketEndpoint;\n #sentClose = false;\n\n send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void {\n this.peer.dispatchEvent(new MessageEvent(\"message\", { data: cloneMessageData(data) }));\n }\n\n close(code = 1000, reason = \"\"): void {\n if (this.#sentClose) return;\n this.#sentClose = true;\n this.peer.dispatchEvent(new CloseEvent(\"close\", { code, reason, wasClean: true }));\n }\n}\n\n/** One public socket identity, in classic or hibernatable mode after acceptance. */\nexport class AcceptedWebSocket extends EventTarget implements RawWebSocket, WebSocket {\n static readonly READY_STATE_CONNECTING = WEB_SOCKET_READY_STATES.READY_STATE_CONNECTING;\n static readonly READY_STATE_OPEN = WEB_SOCKET_READY_STATES.READY_STATE_OPEN;\n static readonly READY_STATE_CLOSING = WEB_SOCKET_READY_STATES.READY_STATE_CLOSING;\n static readonly READY_STATE_CLOSED = WEB_SOCKET_READY_STATES.READY_STATE_CLOSED;\n static readonly CONNECTING = WEB_SOCKET_READY_STATES.CONNECTING;\n static readonly OPEN = WEB_SOCKET_READY_STATES.OPEN;\n static readonly CLOSING = WEB_SOCKET_READY_STATES.CLOSING;\n static readonly CLOSED = WEB_SOCKET_READY_STATES.CLOSED;\n\n declare readonly READY_STATE_CONNECTING: 0;\n declare readonly READY_STATE_OPEN: 1;\n declare readonly READY_STATE_CLOSING: 2;\n declare readonly READY_STATE_CLOSED: 3;\n declare readonly CONNECTING: 0;\n declare readonly OPEN: 1;\n declare readonly CLOSING: 2;\n declare readonly CLOSED: 3;\n readonly bufferedAmount = 0;\n readonly extensions = \"\";\n readonly protocol = \"\";\n readonly url = \"\";\n\n #ctx: IoContext;\n readonly #socket: RawWebSocket;\n readonly #pairState: PairState | undefined;\n #delivery: SocketDelivery = { mode: \"pending\" };\n #pump: Promise<void> = Promise.resolve();\n #pending: { type: SocketEvent; event: Event }[] = [];\n #readyState: number = AcceptedWebSocket.OPEN;\n #ownClose = false;\n #peerClose = false;\n #binaryType: \"blob\" | \"arraybuffer\" = \"blob\";\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, pairState?: PairState) {\n super();\n this.#ctx = ctx;\n this.#socket = socket;\n this.#pairState = pairState;\n if (pairState === undefined) this.#enableClassic();\n for (const type of SOCKET_EVENTS) {\n socket.addEventListener(type, (event: Event) => {\n this.#receive(type, event);\n });\n }\n }\n\n get readyState(): number {\n return this.#readyState;\n }\n\n get binaryType(): \"blob\" | \"arraybuffer\" {\n return this.#binaryType;\n }\n\n set binaryType(value: \"blob\" | \"arraybuffer\") {\n this.#binaryType = value;\n }\n\n accept(): void {\n if (this.#delivery.mode === \"hibernatable\") {\n throw new TypeError(HIBERNATION_AFTER_ACCEPT_MESSAGE);\n }\n if (this.#delivery.mode === \"classic\") throw new Error(ALREADY_ACCEPTED_MESSAGE);\n if (this.#pairState !== undefined) this.#pairState.used = true;\n this.#enableClassic();\n }\n\n send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void {\n if (this.#delivery.mode === \"hibernatable\" && this.#ownClose) {\n throw new TypeError(\"Can't call WebSocket send() after close().\");\n }\n if (this.#peerClose || this.#readyState === AcceptedWebSocket.CLOSED) return;\n this.#markPairUsed();\n this.#enqueue(() => this.#socket.send(data));\n }\n\n close(code?: number, reason = \"\"): void {\n if (this.#readyState === AcceptedWebSocket.CLOSED || this.#ownClose) return;\n if (this.#delivery.mode === \"hibernatable\" || this.#pairState !== undefined) {\n validateClose(code, reason);\n }\n this.#markPairUsed();\n this.#ownClose = true;\n this.#readyState = this.#peerClose ? AcceptedWebSocket.CLOSED : AcceptedWebSocket.CLOSING;\n this.#enqueue(() => this.#socket.close(code, reason));\n }\n\n serializeAttachment(value: unknown): void {\n if (arguments.length === 0) serializeAttachmentMethod.call(this);\n else serializeAttachment(this, value);\n }\n\n deserializeAttachment(): unknown {\n return deserializeAttachment(this);\n }\n\n acceptHibernation(registry: HibernatableWebSocketRegistry): void {\n if (this.#delivery.mode !== \"pending\") {\n throw new Error(HIBERNATION_ALREADY_ACCEPTED_MESSAGE);\n }\n if (this.#pairState?.used === true && !this.#pairState.hibernationAccepted) {\n throw new Error(HIBERNATION_PAIR_USED_MESSAGE);\n }\n if (this.#pairState !== undefined) {\n this.#pairState.used = true;\n this.#pairState.hibernationAccepted = true;\n }\n this.#activateHibernation(registry, this.#ctx);\n }\n\n rehydrateHibernation(registry: HibernatableWebSocketRegistry, ctx: IoContext): void {\n this.#activateHibernation(registry, ctx);\n }\n\n #activateHibernation(registry: HibernatableWebSocketRegistry, ctx: IoContext): void {\n this.#ctx = ctx;\n this.#delivery = { mode: \"hibernatable\", registry };\n this.#pending = [];\n }\n\n markPairUsed(): void {\n this.#markPairUsed();\n }\n\n #markPairUsed(): void {\n if (this.#pairState !== undefined) this.#pairState.used = true;\n }\n\n #enableClassic(): void {\n const delivery: SocketDelivery = {\n mode: \"classic\",\n criticalSection: this.#ctx.getCriticalSection(),\n };\n this.#delivery = delivery;\n socketMetadata(this).accepted = { mode: \"classic\" };\n const pending = this.#pending;\n this.#pending = [];\n for (const item of pending) {\n this.#deliverClassic(item.type, item.event, delivery.criticalSection);\n }\n }\n\n #receive(type: SocketEvent, event: Event): void {\n if (type === \"close\") {\n this.#receiveClose(event as CloseEvent);\n return;\n }\n const delivery = this.#delivery;\n if (delivery.mode === \"pending\") this.#pending.push({ type, event });\n else if (delivery.mode === \"classic\") {\n this.#deliverClassic(type, event, delivery.criticalSection);\n } else delivery.registry.receive(this, type, event);\n }\n\n #receiveClose(event: CloseEvent): void {\n if (this.#ownClose) {\n this.#readyState = AcceptedWebSocket.CLOSED;\n } else {\n this.#peerClose = true;\n this.#readyState = AcceptedWebSocket.CLOSING;\n if (this.#delivery.mode === \"classic\" && this.#pairState !== undefined) {\n // Pair halves perform the WebSocket close handshake in-memory. An\n // embedder-supplied raw socket owns its own protocol and only reports.\n if (event.code === 1005 || event.code === 1006 || event.code === 1015) {\n this.#readyState = AcceptedWebSocket.CLOSED;\n } else {\n this.close(event.code, event.reason);\n }\n }\n }\n const delivery = this.#delivery;\n if (delivery.mode === \"pending\") this.#pending.push({ type: \"close\", event });\n else if (delivery.mode === \"classic\") {\n this.#deliverClassic(\"close\", event, delivery.criticalSection);\n } else delivery.registry.receive(this, \"close\", event);\n }\n\n #deliverClassic(\n type: SocketEvent,\n event: Event,\n criticalSection: CriticalSection | undefined,\n ): void {\n this.#ctx.addWaitUntil(\n this.#ctx.run(() => {\n const delivered = cloneEventFor(type, event);\n this.dispatchEvent(delivered);\n const handler = this[`on${type}`] as ((event: Event) => void) | null;\n handler?.(delivered);\n }, { input: criticalSection }),\n );\n }\n\n #enqueue(write: () => void): void {\n const outputLock = this.#ctx.waitForOutputLocks();\n this.#pump = this.#pump.then(async () => {\n await outputLock;\n write();\n });\n this.#ctx.addWaitUntil(this.#pump);\n }\n}\n\nfor (const [name, value] of Object.entries(WEB_SOCKET_READY_STATES)) {\n Object.defineProperty(AcceptedWebSocket.prototype, name, { value, enumerable: true });\n}\n\ntype HandlerDispatch = {\n message(socket: RawWebSocket, message: string | ArrayBuffer): unknown;\n close(socket: RawWebSocket, code: number, reason: string, wasClean: boolean): unknown;\n error(socket: RawWebSocket, error: unknown): unknown;\n};\n\ntype RegistryEntry = {\n readonly socket: RawWebSocket;\n readonly tags: string[];\n autoResponseTimestamp?: number;\n};\n\nexport class HibernatableWebSocketRegistry {\n readonly #ctx: IoContext;\n readonly #dispatch: HandlerDispatch;\n readonly #host: HibernationHost | undefined;\n readonly #entries: RegistryEntry[] = [];\n #autoResponse: WebSocketRequestResponsePair | null = null;\n #eventTimeout: number | null = null;\n #pairConstructor: WebSocketPairConstructor | undefined;\n\n constructor(\n ctx: IoContext,\n dispatch: HandlerDispatch,\n host?: HibernationHost,\n rehydrated: readonly RehydratedWebSocket[] = [],\n ) {\n this.#ctx = ctx;\n this.#dispatch = dispatch;\n this.#host = host;\n for (const value of rehydrated) this.#rehydrate(value);\n }\n\n get WebSocketPair(): WebSocketPairConstructor {\n const registry = this;\n this.#pairConstructor ??= new Proxy(\n class WebSocketPair {\n declare readonly 0: WebSocket;\n declare readonly 1: WebSocket;\n },\n { construct: () => registry.#createPair() },\n );\n return this.#pairConstructor;\n }\n\n acceptWebSocket(socket: RawWebSocket, tags?: string[]): void {\n if (!isRawWebSocket(socket)) {\n throw new TypeError(\n \"Failed to execute 'acceptWebSocket' on 'DurableObjectState': parameter 1 is not of type 'WebSocket'.\",\n );\n }\n const state = socketMetadata(socket);\n if (state.accepted !== undefined) throw new Error(HIBERNATION_ALREADY_ACCEPTED_MESSAGE);\n if (this.#entries.length >= MAX_HIBERNATABLE_SOCKETS) {\n throw new Error(\n `only ${MAX_HIBERNATABLE_SOCKETS} websockets can be accepted on a single Durable Object instance`,\n );\n }\n const normalizedTags = normalizeTags(tags);\n if (socket instanceof AcceptedWebSocket) socket.acceptHibernation(this);\n else this.#listenRaw(socket);\n state.accepted = { mode: \"hibernatable\", registry: this };\n this.#entries.push({ socket, tags: normalizedTags });\n this.#host?.accepted(socket, normalizedTags);\n }\n\n getWebSockets(tag?: string): WebSocket[] {\n if (arguments.length > 0) {\n if (typeof tag !== \"string\") return [];\n return this.#entries\n .filter((entry) => entry.tags.includes(tag))\n .map((entry) => entry.socket as WebSocket);\n }\n return this.#entries.map((entry) => entry.socket as WebSocket).reverse();\n }\n\n getTags(socket: RawWebSocket): string[] {\n const state = isRawWebSocket(socket) ? metadata.get(socket) : undefined;\n if (state?.accepted === undefined) {\n throw new Error(\n \"you must call 'acceptWebSocket()' before attempting to access the tags of a WebSocket.\",\n );\n }\n if (state.accepted.mode !== \"hibernatable\") {\n throw new Error(\"only hibernatable websockets can have tags.\");\n }\n const entry = this.#entries.find((candidate) => candidate.socket === socket);\n if (entry === undefined) {\n throw new Error(\n \"you must call 'acceptWebSocket()' before attempting to access the tags of a WebSocket.\",\n );\n }\n return [...entry.tags];\n }\n\n setWebSocketAutoResponse(pair?: WebSocketRequestResponsePair): void {\n if (pair === undefined) {\n this.#autoResponse = null;\n this.#host?.autoResponse(null);\n return;\n }\n if (!(pair instanceof WebSocketRequestResponsePairImpl)) {\n throw new TypeError(\n \"Failed to execute 'setWebSocketAutoResponse' on 'DurableObjectState': parameter 1 is not of type 'WebSocketRequestResponsePair'.\",\n );\n }\n validateAutoResponseSize(\"Request\", pair.request);\n validateAutoResponseSize(\"Response\", pair.response);\n this.#autoResponse = pair;\n this.#host?.autoResponse({ request: pair.request, response: pair.response });\n }\n\n getWebSocketAutoResponse(): WebSocketRequestResponsePair | null {\n const pair = this.#autoResponse;\n return pair === null\n ? null\n : new RuntimeWebSocketRequestResponsePair(pair.request, pair.response);\n }\n\n getWebSocketAutoResponseTimestamp(socket: RawWebSocket): Date | null {\n if (!isRawWebSocket(socket)) {\n throw new TypeError(\n \"Failed to execute 'getWebSocketAutoResponseTimestamp' on 'DurableObjectState': parameter 1 is not of type 'WebSocket'.\",\n );\n }\n const timestamp = this.#entries.find((entry) => entry.socket === socket)?.autoResponseTimestamp;\n return timestamp === undefined ? null : new Date(timestamp);\n }\n\n setHibernatableWebSocketEventTimeout(value?: number): void {\n if (value === undefined || Number(value) === 0) {\n this.#eventTimeout = null;\n return;\n }\n const number = Number(value);\n if (Number.isNaN(number)) {\n throw new TypeError(\"The value cannot be converted because it is not an integer.\");\n }\n if (number < 0) {\n throw new TypeError(\n \"The value cannot be converted because it is negative and this API expects a positive number.\",\n );\n }\n if (number > 0xffff_ffff) {\n throw new TypeError(\"Value out of range. Must be less than or equal to 4294967295.\");\n }\n const timeout = Math.trunc(number);\n if (timeout > MAX_EVENT_TIMEOUT) {\n throw new Error(`Event timeout should not exceed ${MAX_EVENT_TIMEOUT} ms.`);\n }\n this.#eventTimeout = timeout;\n }\n\n getHibernatableWebSocketEventTimeout(): number | null {\n return this.#eventTimeout;\n }\n\n attachmentChanged(socket: RawWebSocket, bytes: Uint8Array): void {\n if (this.#entries.some((entry) => entry.socket === socket)) {\n this.#host?.attachment(socket, bytes);\n }\n }\n\n receive(socket: RawWebSocket, type: SocketEvent, event: Event): void {\n const entry = this.#entries.find((candidate) => candidate.socket === socket);\n if (entry === undefined) return;\n if (type === \"message\") {\n const data = (event as MessageEvent).data as unknown;\n if (typeof data === \"string\" && data === this.#autoResponse?.request) {\n entry.autoResponseTimestamp = this.#ctx.now();\n socket.send(this.#autoResponse.response);\n return;\n }\n const message = cloneMessageData(data);\n if (message instanceof Blob) {\n this.#ctx.addWaitUntil(\n message.arrayBuffer().then((buffer) => {\n this.#schedule(() => this.#dispatch.message(socket, buffer));\n }),\n );\n return;\n }\n this.#schedule(() => this.#dispatch.message(socket, message));\n return;\n }\n if (type === \"close\") {\n this.#remove(entry);\n const close = event as CloseEvent;\n this.#schedule(() =>\n this.#dispatch.close(socket, close.code, close.reason, close.wasClean),\n );\n return;\n }\n if (type === \"error\") this.#schedule(() => this.#dispatch.error(socket, event));\n }\n\n #schedule(handler: () => unknown): void {\n this.#ctx.addWaitUntil(this.#ctx.run(handler).then(() => {}));\n }\n\n #remove(entry: RegistryEntry): void {\n const index = this.#entries.indexOf(entry);\n if (index === -1) return;\n this.#entries.splice(index, 1);\n this.#host?.closed(entry.socket);\n }\n\n #listenRaw(socket: RawWebSocket): void {\n const state = socketMetadata(socket);\n if (state.rawListenersInstalled === true) return;\n state.rawListenersInstalled = true;\n for (const type of [\"message\", \"close\", \"error\"] as const) {\n socket.addEventListener(type, (event) => {\n const accepted = socketMetadata(socket).accepted;\n if (accepted?.mode === \"hibernatable\") {\n accepted.registry.receive(socket, type, event);\n }\n });\n }\n }\n\n #rehydrate(value: RehydratedWebSocket): void {\n const socket = value.socket;\n if (!isRawWebSocket(socket)) {\n throw new TypeError(\"ActorContainerOptions.webSockets contains a non-WebSocket value.\");\n }\n const tags = normalizeTags(value.tags);\n const state = socketMetadata(socket);\n state.accepted = { mode: \"hibernatable\", registry: this };\n if (value.attachment !== undefined) {\n state.attachment = value.attachment.slice();\n }\n if (socket instanceof AcceptedWebSocket) socket.rehydrateHibernation(this, this.#ctx);\n else this.#listenRaw(socket);\n const entry: RegistryEntry = { socket, tags };\n if (value.autoResponseTimestamp !== undefined) {\n entry.autoResponseTimestamp = value.autoResponseTimestamp;\n }\n this.#entries.push(entry);\n }\n\n #createPair(): RuntimeWebSocketPair {\n const pairState: PairState = { used: false, hibernationAccepted: false };\n const left = new MemoryWebSocketEndpoint();\n const right = new MemoryWebSocketEndpoint();\n left.peer = right;\n right.peer = left;\n return {\n 0: new AcceptedWebSocket(this.#ctx, left, pairState),\n 1: new AcceptedWebSocket(this.#ctx, right, pairState),\n };\n }\n}\n\nexport function acceptWebSocket(ctx: IoContext, socket: RawWebSocket): AcceptedWebSocket {\n const state = socketMetadata(socket);\n if (state.accepted !== undefined) throw new Error(ALREADY_ACCEPTED_MESSAGE);\n if (socket instanceof AcceptedWebSocket) {\n socket.accept();\n return socket;\n }\n state.accepted = { mode: \"classic\" };\n const accepted = new AcceptedWebSocket(ctx, socket);\n return accepted;\n}\n\nexport function markWebSocketUsed(socket: RawWebSocket): void {\n if (socket instanceof AcceptedWebSocket) socket.markPairUsed();\n}\n\nexport function installWebSocketGlobals(\n target: object,\n pairConstructor: WebSocketPairConstructor,\n): void {\n const constructor = globalThis.WebSocket;\n for (const [name, value] of Object.entries(WEB_SOCKET_READY_STATES)) {\n defineValue(constructor, name, value);\n defineValue(constructor.prototype, name, value);\n }\n defineValue(constructor.prototype, \"serializeAttachment\", serializeAttachmentMethod);\n defineValue(constructor.prototype, \"deserializeAttachment\", deserializeAttachmentMethod);\n defineValue(target, \"WebSocket\", constructor);\n defineValue(target, \"WebSocketPair\", pairConstructor);\n defineValue(target, \"WebSocketRequestResponsePair\", RuntimeWebSocketRequestResponsePair);\n}\n\nfunction defineValue(target: object, name: string, value: unknown): void {\n const current = Object.getOwnPropertyDescriptor(target, name);\n if (current?.configurable === false) return;\n Object.defineProperty(target, name, { configurable: true, writable: true, value });\n}\n\nfunction normalizeTags(tags: unknown): string[] {\n if (tags === undefined) return [];\n if (!Array.isArray(tags)) {\n throw new TypeError(\n \"Failed to execute 'acceptWebSocket' on 'DurableObjectState': parameter 2 is not of type 'Array'.\",\n );\n }\n if (tags.length > MAX_TAGS) {\n throw new Error(`a Hibernatable WebSocket cannot have more than ${MAX_TAGS} tags`);\n }\n const normalized = [...new Set(tags.map(String))];\n for (const tag of normalized) {\n if (tag.length > MAX_TAG_LENGTH) {\n throw new Error(\n `\"${tag}\" is longer than the max tag length (${MAX_TAG_LENGTH} characters).`,\n );\n }\n }\n return normalized;\n}\n\nfunction validateAutoResponseSize(side: \"Request\" | \"Response\", value: string): void {\n const bytes = textEncoder.encode(value).byteLength;\n if (bytes > MAX_AUTO_RESPONSE_BYTES) {\n throw new RangeError(\n `${side} cannot be larger than ${MAX_AUTO_RESPONSE_BYTES} bytes. A ${side.toLowerCase()} of size ${bytes} was provided.`,\n );\n }\n}\n\nfunction validateClose(code: number | undefined, reason: string): void {\n if (code !== undefined && code !== 1000 && (code < 3000 || code > 4999)) {\n throw new DOMException(`Invalid WebSocket close code: ${code}.`, \"InvalidAccessError\");\n }\n if (textEncoder.encode(reason).byteLength > MAX_CLOSE_REASON_BYTES) {\n throw new DOMException(\n `WebSocket close reason must not be longer than ${MAX_CLOSE_REASON_BYTES} bytes when UTF-8 encoded.`,\n \"SyntaxError\",\n );\n }\n}\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/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, { input: 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\";\nimport {\n installWebSocketGlobals,\n WebSocketRequestResponsePair,\n type HibernatableWebSocketRegistry,\n} from \"./web-socket\";\n\ntype WebSocketPairConstructor = typeof WebSocketPair;\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 readonly webSockets: HibernatableWebSocketRegistry;\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 declare readonly WebSocket: typeof globalThis.WebSocket;\n declare readonly WebSocketPair: WebSocketPairConstructor;\n declare readonly WebSocketRequestResponsePair: typeof WebSocketRequestResponsePair;\n\n constructor(ctx: IoContext, options: ActorGlobalScopeOptions) {\n this.#ctx = ctx;\n this.#fetch = options.fetch;\n this.#readCurrentExternalEntry = options.currentExternalEntry;\n installWebSocketGlobals(this, options.webSockets.WebSocketPair);\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 WebSocket: typeof globalThis.WebSocket;\n readonly WebSocketPair: WebSocketPairConstructor;\n readonly WebSocketRequestResponsePair: typeof WebSocketRequestResponsePair;\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 const BoundWebSocketPair: WebSocketPairConstructor = new Proxy(\n class WebSocketPair {\n declare readonly 0: WebSocket;\n declare readonly 1: WebSocket;\n },\n { construct: () => new (resolve().WebSocketPair)() },\n );\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 WebSocket: globalThis.WebSocket,\n WebSocketPair: BoundWebSocketPair,\n WebSocketRequestResponsePair,\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 actor globals 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 only a subset leaves a\n * 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/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 {\n AcceptedWebSocket,\n HibernationHost,\n RawWebSocket,\n RehydratedWebSocket,\n} from \"../api/web-socket\";\nimport { acceptWebSocket, HibernatableWebSocketRegistry } 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, tryCurrentIoContext } from \"../io/io-context\";\nimport type { InputGateHooks, OutputGateHooks } from \"../io/io-gate\";\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 { ensureRuntimeStorageVersion } from \"../util/sqlite-migrations\";\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 five 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 hibernation?: HibernationHost;\n};\n\nexport type { HibernationHost } from \"../api/web-socket\";\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 webSockets?: readonly RehydratedWebSocket[];\n gateHooks?: { input?: InputGateHooks; output?: OutputGateHooks };\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 an outbound call must resume through the caller's `awaitIo`, or the\n * code after it comes back with no input lock and its next storage call\n * throws. Lock state is not caller identity: a parent and its running facet\n * can both return true. `resolveLoopback()` owns that decision.\n */\n hasCurrent(): boolean;\n\n /**\n * Resolve an in-realm actor call without making the host infer caller identity.\n * A call from this exact actor context uses the raw instance; every other call\n * uses its gated entry, routed through the caller's output gate and `awaitIo`\n * when there is one. The runtime resolves a current slice or\n * transformed continuation first; `caller` is the lock-holding structural\n * fallback for untransformed post-await code. Both callbacks are lazy: only\n * the selected invocation runs.\n */\n resolveLoopback<Result>(\n invokeDirect: () => Result,\n invokeEntry: () => Promise<Awaited<Result>>,\n caller?: ActorContainer,\n ): Result | Promise<Awaited<Result>>;\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. `resolveLoopback()` makes that distinction:\n * an actor reaching its own `DurableObjectNamespace` binding from its exact\n * current context skips this door because the lock it would take is the one\n * it holds. `signal` is bound to the returned proxy and cancels invocations\n * that are still waiting for admission; it does not interrupt an admitted\n * method or its output-gate drain.\n */\n entry<T extends object>(target: T, signal?: AbortSignal): 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`. `signal` cancels only\n * while the event is queued for an input lock.\n */\n run<T>(event: () => T | PromiseLike<T>, signal?: AbortSignal): 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 quiescence(): {\n armedTimers: number;\n pendingWaitUntil: number;\n inputLockHeld: boolean;\n outputGateBroken: boolean;\n };\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: InputGate;\n readonly #outputGate: 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(\n isFacet: boolean,\n hooks: ActorContainerOptions[\"gateHooks\"] = {},\n ) {\n this.#isFacet = isFacet;\n this.#inputGate = new InputGate(hooks.input);\n this.#outputGate = new OutputGate(hooks.output);\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 #webSockets: HibernatableWebSocketRegistry;\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, options.gateHooks);\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.#webSockets = new HibernatableWebSocketRegistry(\n this.#ctx,\n {\n message: (socket, message) => this.#runWebSocketHandler(\"webSocketMessage\", socket, message),\n close: (socket, code, reason, wasClean) =>\n this.#runWebSocketHandler(\"webSocketClose\", socket, code, reason, wasClean),\n error: (socket, error) => this.#runWebSocketHandler(\"webSocketError\", socket, error),\n },\n options.ports.hibernation,\n options.webSockets,\n );\n this.globals = new ActorGlobalScope(this.#ctx, {\n fetch: options.ports.fetch,\n currentExternalEntry: () => this.#currentExternalEntry,\n webSockets: this.#webSockets,\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 actor globals\n // are gated by one scope rather than two that could drift.\n globals: actorScopeBindings(() => this.globals),\n webSockets: this.#webSockets,\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 resolveLoopback<Result>(\n invokeDirect: () => Result,\n invokeEntry: () => Promise<Awaited<Result>>,\n caller?: ActorContainer,\n ): Result | Promise<Awaited<Result>> {\n const context = tryCurrentIoContext();\n if (context === this.#ctx) return invokeDirect();\n if (context !== undefined) {\n return context.awaitIo(context.waitForOutputLocks().then(invokeEntry));\n }\n if (caller === undefined) return invokeEntry();\n if (!caller.hasCurrent()) {\n throw new Error(\"resolveLoopback() caller has no current input lock\");\n }\n if (caller === this) return invokeDirect();\n return caller.awaitIo(caller.waitOutputLocks().then(invokeEntry));\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, signal?: AbortSignal): 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 () =>\n this.#withExternalEntry(() =>\n (value as (...rest: unknown[]) => unknown).apply(subject, args),\n ),\n { signal },\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>, signal?: AbortSignal): Promise<T> {\n return this.#ctx.run(\n () => this.#withExternalEntry(event),\n { signal },\n );\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 input option. 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 quiescence() {\n return {\n armedTimers: this.#ctx.getTimeoutCount(),\n pendingWaitUntil: this.#ctx.waitUntilTaskCount(),\n inputLockHeld: this.#ctx.hasCurrent(),\n outputGateBroken: this.#ctx.isOutputGateBroken(),\n };\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 #runWebSocketHandler(\n name: \"webSocketMessage\" | \"webSocketClose\" | \"webSocketError\",\n socket: RawWebSocket,\n ...args: unknown[]\n ): unknown {\n const instance = this.#actor.classInstance;\n if (instance.kind !== \"running\") return undefined;\n const handler: unknown = Reflect.get(instance.instance, name);\n if (typeof handler !== \"function\") return undefined;\n return Reflect.apply(handler, instance.instance, [socket, ...args]);\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 actorDb = await options.ports.sql.open(ACTOR_DATABASE_NAME);\n ensureRuntimeStorageVersion(actorDb, ACTOR_DATABASE_NAME);\n const db = new SqliteDatabase(actorDb);\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 facetDb = await options.ports.sql.open(FACET_DATABASE_NAME);\n ensureRuntimeStorageVersion(facetDb, FACET_DATABASE_NAME);\n const tree = new ActorTree(facetDb, options.ports.facets);\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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"}