@mcp-b/do-runtime 0.1.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +110 -0
  3. package/LICENSE.workerd +176 -0
  4. package/NOTICE +7 -0
  5. package/README.md +282 -0
  6. package/dist/backends/node-sqlite.d.ts +38 -0
  7. package/dist/backends/node-sqlite.js +335 -0
  8. package/dist/backends/node-sqlite.js.map +1 -0
  9. package/dist/backends/sqlite-wasm.d.ts +130 -0
  10. package/dist/backends/sqlite-wasm.js +259 -0
  11. package/dist/backends/sqlite-wasm.js.map +1 -0
  12. package/dist/chunks/sqlite-DFg92Tgt.js +498 -0
  13. package/dist/chunks/sqlite-DFg92Tgt.js.map +1 -0
  14. package/dist/cloudflare-workers.js +351 -0
  15. package/dist/cloudflare-workers.js.map +1 -0
  16. package/dist/conformance/host.d.ts +58 -0
  17. package/dist/conformance.js +18 -0
  18. package/dist/conformance.js.map +1 -0
  19. package/dist/index.js +7184 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/server/alarm-scheduler.js +513 -0
  22. package/dist/server/alarm-scheduler.js.map +1 -0
  23. package/dist/src/api/actor-state.d.ts +396 -0
  24. package/dist/src/api/actor.d.ts +306 -0
  25. package/dist/src/api/cloudflare-workers.d.ts +259 -0
  26. package/dist/src/api/export-loopback.d.ts +264 -0
  27. package/dist/src/api/global-scope.d.ts +262 -0
  28. package/dist/src/api/http.d.ts +52 -0
  29. package/dist/src/api/sql.d.ts +188 -0
  30. package/dist/src/api/sync-kv.d.ts +51 -0
  31. package/dist/src/api/web-socket.d.ts +93 -0
  32. package/dist/src/api/worker-loader.d.ts +354 -0
  33. package/dist/src/index.d.ts +130 -0
  34. package/dist/src/io/actor-cache.d.ts +203 -0
  35. package/dist/src/io/actor-id.d.ts +74 -0
  36. package/dist/src/io/actor-sqlite.d.ts +298 -0
  37. package/dist/src/io/io-channels.d.ts +191 -0
  38. package/dist/src/io/io-context.d.ts +451 -0
  39. package/dist/src/io/io-gate.d.ts +298 -0
  40. package/dist/src/io/worker-source.d.ts +108 -0
  41. package/dist/src/io/worker.d.ts +88 -0
  42. package/dist/src/server/actor-container.d.ts +525 -0
  43. package/dist/src/server/actor-id-impl.d.ts +118 -0
  44. package/dist/src/server/alarm-scheduler.d.ts +201 -0
  45. package/dist/src/server/facet-deletion.d.ts +156 -0
  46. package/dist/src/server/facet-tree-index.d.ts +94 -0
  47. package/dist/src/server/sha256.d.ts +39 -0
  48. package/dist/src/transport/rpc-session.d.ts +34 -0
  49. package/dist/src/util/sqlite-kv.d.ts +98 -0
  50. package/dist/src/util/sqlite-metadata.d.ts +46 -0
  51. package/dist/src/util/sqlite.d.ts +291 -0
  52. package/package.json +111 -0
@@ -0,0 +1,396 @@
1
+ /**
2
+ * ← workerd `src/workerd/api/actor-state.{h,c++}`
3
+ *
4
+ * The JS-facing storage objects: `DurableObjectStorageOperations` and its two
5
+ * subclasses, `DurableObjectFacets`, and `DurableObjectState`. Everything below
6
+ * this file is reached through one of them.
7
+ *
8
+ * **`DurableObjectStorage` satisfies workers-types with no cast (§2.4).** That
9
+ * was checked rather than asserted, and two shapes here exist only because it
10
+ * has to: `sql.Cursor` and `sql.Statement` must be constructible with no
11
+ * arguments (see `sql.ts`), and `storage.kv` is required, which is why
12
+ * `api/sync-kv.ts` exists at all. The narrowings that remain are all one thing —
13
+ * `get<T>` returns the caller's claim about the shape of a value SQLite handed
14
+ * back as bytes, which no check can confirm and which upstream states the same
15
+ * way, as a `jsg::JsRef<jsg::JsValue>` behind a `JSG_TS_OVERRIDE`'d
16
+ * `Promise<T>`. There is no `as unknown as` anywhere in this layer.
17
+ *
18
+ * **Every throw is synchronous, including from the promise-returning methods.**
19
+ * That is upstream's: a `JSG_REQUIRE` inside a method returning `jsg::Promise`
20
+ * throws into the isolate before the promise exists, so `put(k, undefined)`
21
+ * throws rather than rejecting. The same goes for a value that will not decode,
22
+ * because §1.4 makes the SQLite path take `transformCacheResult`'s value arm and
23
+ * run the decoder synchronously.
24
+ *
25
+ * **What the input gate does and does not do here.** Every entry point calls
26
+ * `requireInputLock` — see its comment in `io/io-context.ts`, which is the one
27
+ * place this package decides what an empty invocation stack means. Nothing else
28
+ * takes a lock: a read returns a value, a write returns a resolved promise, and
29
+ * `atCheckpointEnd` is what keeps the whole chain inside one transaction
30
+ * (§1.7.1). The two exceptions are upstream's own — `sync()` and the bookmark
31
+ * pair release the gate via `awaitIo`, and `transaction()` takes a critical
32
+ * section.
33
+ *
34
+ * **Decision 2's branch has one reachable site**, and it is not where upstream's
35
+ * is. `transformCacheResult` branches on `allowConcurrency` because upstream's
36
+ * `ActorCacheOps` returns `kj::OneOf<T, kj::Promise<T>>`; §1.4 measures that the
37
+ * SQLite arm is always the immediate one, so Section 4 collapsed the `OneOf` and
38
+ * the branch has nothing to select between. `transformMaybeBackpressure` keeps
39
+ * it, because `DeleteAllResults.backpressure` is still a promise in
40
+ * `io/actor-cache.ts`. Both helpers are kept under upstream's names so the
41
+ * question "where did `allowConcurrency` go" is answered by reading them.
42
+ *
43
+ * Not ported, because the substrate has no equivalent: Hibernatable WebSockets,
44
+ * which is the whole reason `DurableObjectState`'s eight WebSocket methods are
45
+ * named throwing stubs; V8's private wire bytes, replaced by a browser-safe
46
+ * structured-clone encoding with the same public value semantics; the billing
47
+ * counters
48
+ * (`billingUnits`, `ActorObserver`, `updateStorageWriteUnit`) and the trace
49
+ * spans, both already absent throughout; `enableSql`, a workerd namespace option
50
+ * that exists to simulate a non-SQLite Durable Object; and `ReplicaActorOutgoingFactory`,
51
+ * whose replication half is a named boundary in `io/actor-cache.ts`.
52
+ *
53
+ * Spec: §1.4, §1.5, §1.10, §2.4, §2.5, decisions 2, 4 and 14 in
54
+ * docs/decisions.md.
55
+ */
56
+ import type { ActorCacheInterface, ActorCacheOps, ActorCacheTransaction } from "../io/actor-cache.js";
57
+ import type { IoContext } from "../io/io-context.js";
58
+ import type { FacetManager } from "../io/worker.js";
59
+ import type { SqliteKv } from "../util/sqlite-kv.js";
60
+ import type { SqliteDatabase } from "../util/sqlite.js";
61
+ import type { ActorScopeBindings } from "./global-scope.js";
62
+ import { SqlStorage } from "./sql.js";
63
+ import { SyncKvStorage } from "./sync-kv.js";
64
+ /**
65
+ * ← `MAX_FACET_NAME_LENGTH` / `MAX_FACET_TREE_DEPTH`
66
+ * (`actor-state.c++:943,947`), in the anonymous namespace beside the facet code
67
+ * that enforces them. The scaffolding had them in `server/`, which is neither
68
+ * where upstream puts them nor where they are checked.
69
+ */
70
+ export declare const FACET_NAME_MAX_LENGTH = 256;
71
+ /** Root is at depth 0, so the deepest allowed facet is at depth 3. */
72
+ export declare const FACET_TREE_MAX_DEPTH = 4;
73
+ /**
74
+ * The substrate boundary named in the package README: Hibernatable WebSockets
75
+ * exist so the platform can evict an actor while keeping its sockets open, and
76
+ * Chrome exposes no equivalent lifecycle. Under this repo's fail-closed tenet
77
+ * the throw IS the specified behaviour, which is why §2.5 orders the four
78
+ * silent no-op stubs beside it replaced.
79
+ */
80
+ export declare const HIBERNATION_UNIMPLEMENTED_MESSAGE: string;
81
+ /**
82
+ * ← what falls off the end of `DurableObjectFacets::get`'s class switch
83
+ * (`actor-state.c++:1029-1043`).
84
+ *
85
+ * Upstream accepts three things as `FacetStartupOptions.class`: a bare
86
+ * `DurableObjectClass`, a `LoopbackDurableObjectNamespace`, or a
87
+ * `LoopbackColoLocalActorNamespace`, unwrapping the last two through
88
+ * `getClass()`. All three are ported — the loopback pair by
89
+ * `api/export-loopback.ts` — and `KJ_UNREACHABLE` is the fourth case there
90
+ * because JSG has already refused anything else while unwrapping the
91
+ * `kj::OneOf`. The check has to be written here because
92
+ * `@cloudflare/workers-types` declares `interface DurableObjectClass<_T> {}`,
93
+ * which every object satisfies, so nothing refuses it before the method body.
94
+ */
95
+ export declare const FACET_CLASS_UNSUPPORTED_MESSAGE: string;
96
+ /**
97
+ * ← `serializeV8Value`. The wire bytes differ because V8's serializer is not
98
+ * available in browsers; the public structured-clone value semantics do not.
99
+ * The short header keeps the new representation unambiguous while old JSON rows
100
+ * remain readable.
101
+ */
102
+ export declare function serializeValue(_key: string, value: unknown): Uint8Array;
103
+ /**
104
+ * ← `deserializeV8Value`.
105
+ *
106
+ * Upstream logs "the key (to help find the data in the database if it hasn't
107
+ * been deleted), the length of the value, and the first three bytes of the value
108
+ * (which is just the v8-internal version header and the tag that indicates the
109
+ * type of the value, but not its contents)". Our four-byte header carries only
110
+ * a marker and version for the same reason.
111
+ */
112
+ export declare function deserializeValue(key: string, buffer: Uint8Array): unknown;
113
+ /** ← `DurableObjectStorageOperations::CompiledListOptions`. */
114
+ export type CompiledListOptions = {
115
+ readonly start: string;
116
+ readonly end: string | undefined;
117
+ readonly reverse: boolean;
118
+ readonly limit: number | undefined;
119
+ };
120
+ /**
121
+ * ← `DurableObjectStorageOperations::compileListOptions`
122
+ * (`actor-state.c++:314-417`). Returns undefined if the list operation would
123
+ * provably return no results. Public because `SyncKvStorage` reuses it, exactly
124
+ * as upstream's comment says it must.
125
+ *
126
+ * Two translations. `startAfter` gains ONE null character where upstream's
127
+ * `kj::String` gains two, because the second of upstream's is the terminator and
128
+ * a JS string has none. And every comparison here is on UTF-16 code units where
129
+ * upstream's is on UTF-8 bytes, while the range the database actually applies is
130
+ * SQLite's `BINARY` collation over UTF-8 — the two orders agree for every key
131
+ * outside the astral planes, and a key that mixes astral characters with a
132
+ * prefix can land on the wrong side of a clamp this function computes.
133
+ */
134
+ export declare function compileListOptions(options: DurableObjectListOptions | undefined): CompiledListOptions | undefined;
135
+ /**
136
+ * ← `DurableObjectStorageOperations`. "Common implementation of
137
+ * DurableObjectStorage and DurableObjectTransaction. This class is designed to
138
+ * be used as a mixin."
139
+ */
140
+ export declare abstract class DurableObjectStorageOperations {
141
+ #private;
142
+ protected readonly ctx: IoContext;
143
+ constructor(ctx: IoContext);
144
+ protected abstract getCache(op: string): ActorCacheOps;
145
+ /** Whether to skip caching and allow concurrency on all operations. */
146
+ protected useDirectIo(): boolean;
147
+ /**
148
+ * ← `configureOptions`. Both subclasses answer `useDirectIo()` false, so this
149
+ * is the identity today; it is upstream's hook and the only place the two
150
+ * flags are forced on.
151
+ */
152
+ protected configureOptions<T extends {
153
+ allowConcurrency?: boolean;
154
+ noCache?: boolean;
155
+ }>(options: T): T;
156
+ get<T = unknown>(key: string, options?: DurableObjectGetOptions): Promise<T | undefined>;
157
+ get<T = unknown>(keys: string[], options?: DurableObjectGetOptions): Promise<Map<string, T>>;
158
+ getAlarm(maybeOptions?: DurableObjectGetAlarmOptions): Promise<number | null>;
159
+ list<T = unknown>(maybeOptions?: DurableObjectListOptions): Promise<Map<string, T>>;
160
+ put<T>(key: string, value: T, options?: DurableObjectPutOptions): Promise<void>;
161
+ put<T>(entries: Record<string, T>, options?: DurableObjectPutOptions): Promise<void>;
162
+ delete(key: string, options?: DurableObjectPutOptions): Promise<boolean>;
163
+ delete(keys: string[], options?: DurableObjectPutOptions): Promise<number>;
164
+ setAlarm(scheduledTime: number | Date, maybeOptions?: DurableObjectSetAlarmOptions): Promise<void>;
165
+ deleteAlarm(maybeOptions?: DurableObjectSetAlarmOptions): Promise<void>;
166
+ }
167
+ /**
168
+ * The engine `DurableObjectStorage` drives.
169
+ *
170
+ * Upstream holds an `ActorCacheInterface` and reaches `getSqliteDatabase()` /
171
+ * `getSqliteKv()` through it, both `kj::Maybe`s that are non-null exactly when
172
+ * the actor is SQLite-backed — which here it always is. `transactionSync` is the
173
+ * third member and is one layer lower than upstream's for the reason
174
+ * `io/actor-sqlite.ts` records: the savepoint depth counter and `notifyWrite`
175
+ * both live there, so this file's is a one-line forward the way
176
+ * `blockConcurrencyWhile` already is.
177
+ */
178
+ export type StorageCache = ActorCacheInterface & {
179
+ getSqliteDatabase(): SqliteDatabase;
180
+ getSqliteKv(): SqliteKv;
181
+ transactionSync<T>(callback: () => T): T;
182
+ };
183
+ export declare class DurableObjectStorage extends DurableObjectStorageOperations implements globalThis.DurableObjectStorage {
184
+ #private;
185
+ constructor(ctx: IoContext, cache: StorageCache);
186
+ /** ← `DurableObjectStorage::getActorCacheInterface`, which `DurableObjectState::abort` needs. */
187
+ getActorCacheInterface(): StorageCache;
188
+ /** ← `DurableObjectStorage::getSqliteDb`. Always SQLite-backed here; see the header. */
189
+ getSqliteDb(): SqliteDatabase;
190
+ /** ← `DurableObjectStorage::getSqliteKv`. */
191
+ getSqliteKv(): SqliteKv;
192
+ protected getCache(): ActorCacheOps;
193
+ /** ← `JSG_LAZY_INSTANCE_PROPERTY(sql, getSql)`. */
194
+ get sql(): SqlStorage;
195
+ /** ← `JSG_LAZY_INSTANCE_PROPERTY(kv, getKv)`. */
196
+ get kv(): SyncKvStorage;
197
+ /**
198
+ * ← `DurableObjectStorage::deleteAll`.
199
+ *
200
+ * `deleteAlarm` is upstream's `FeatureFlags::get(js).getDeleteAllDeletesAlarm()`,
201
+ * a compatibility flag that exists so Workers published before it keep the old
202
+ * behaviour. A runtime with no deployed history takes the current behaviour.
203
+ */
204
+ deleteAll(maybeOptions?: DurableObjectPutOptions): Promise<void>;
205
+ /**
206
+ * ← `DurableObjectStorage::transaction`.
207
+ *
208
+ * The critical section is load bearing and upstream says why: "the call to
209
+ * `startTransaction()` is when the SQLite-backed implementation will actually
210
+ * invoke `BEGIN TRANSACTION`, so it's important that we're inside the
211
+ * blockConcurrencyWhile block before that point so we don't accidentally catch
212
+ * some other asynchronous event in our transaction."
213
+ *
214
+ * The exception is packed into the result rather than thrown out of the
215
+ * section, and then rethrown outside it. Upstream's reason: "We don't actually
216
+ * want to reset the object, we only want to roll back the transaction and
217
+ * propagate the exception." A throw out of a critical section permanently
218
+ * breaks the input gate (§1.5), so a failing transaction callback would
219
+ * destroy the actor.
220
+ */
221
+ transaction<T>(closure: (txn: DurableObjectTransaction) => Promise<T>): Promise<T>;
222
+ /** ← `DurableObjectStorage::transactionSync`, a forward for the reason above. */
223
+ transactionSync<T>(callback: () => T): T;
224
+ /**
225
+ * ← `DurableObjectStorage::sync`.
226
+ *
227
+ * Upstream's `awaitIo` rather than `awaitIoWithInputLock`, which is the one
228
+ * storage method that deliberately opens the gate: "we're merely checking if
229
+ * we have any pending or in-flight operations, and providing a promise that
230
+ * resolves when they succeed."
231
+ */
232
+ sync(): Promise<void>;
233
+ /**
234
+ * Real, not a boundary: `ActorSqlite`'s is "an ersatz implementation that's
235
+ * good enough for local dev with D1's Session API", built on the metadata
236
+ * table's local-development bookmark. Anything above this package that
237
+ * surfaces it to an application should know it is a counter and not a
238
+ * recovery point — as it is on workerd.
239
+ */
240
+ getCurrentBookmark(): Promise<string>;
241
+ waitForBookmark(bookmark: string): Promise<void>;
242
+ /** Substrate boundary: point-in-time recovery. Upstream reaches the cache directly, as this does. */
243
+ getBookmarkForTime(timestamp: number | Date): Promise<string>;
244
+ /** Substrate boundary: point-in-time recovery. */
245
+ onNextSessionRestoreBookmark(bookmark: string): Promise<string>;
246
+ /** Substrate boundary: replication. */
247
+ ensureReplicas(): void;
248
+ /** Substrate boundary: replication. */
249
+ disableReplicas(): void;
250
+ /**
251
+ * ← `DurableObjectStorage::getPrimary` / `isReplica`. `maybePrimary` is set
252
+ * only by the replica constructor, and nothing constructs a replica here, so
253
+ * these answer upstream's own non-replica case rather than a stubbed one.
254
+ */
255
+ getPrimary(): undefined;
256
+ isReplica(): boolean;
257
+ }
258
+ export declare class DurableObjectTransaction extends DurableObjectStorageOperations implements globalThis.DurableObjectTransaction {
259
+ #private;
260
+ constructor(ctx: IoContext, cacheTxn: ActorCacheTransaction);
261
+ protected getCache(op: string): ActorCacheOps;
262
+ /** Called from JS. */
263
+ rollback(): void;
264
+ /** Just throws an exception saying this isn't supported. */
265
+ deleteAll(): never;
266
+ /**
267
+ * Called from the runtime, not JS, after the transaction callback has
268
+ * completed. Does nothing if the transaction is already committed or rolled
269
+ * back. Synchronous, because `ActorCacheTransaction::commit` is (§1.4).
270
+ */
271
+ maybeCommit(): void;
272
+ /** Same, for the failure path. Upstream's drops the transaction, whose destructor rolls back. */
273
+ maybeRollback(): void;
274
+ }
275
+ /**
276
+ * ← `DurableObjectFacets`.
277
+ *
278
+ * **`clone` is the fourth method, and the vendored C++ snapshot does not have
279
+ * it.** The design record cites `actor-state.h:431-497` and
280
+ * `server.c++:721-749`; neither line range contains it, `DurableObjectFacets`
281
+ * there exposes exactly `get`, `abort` and `delete`, and
282
+ * `Worker::Actor::FacetManager` has exactly `getDepth`, `getFacet`, `abortFacet`
283
+ * and `deleteFacet`. It is real all the same: `@cloudflare/workers-types`
284
+ * 4.20260702.1 — a month newer than the snapshot — declares
285
+ * `clone(src: string, dst: string): void` on `DurableObjectFacets`. So the
286
+ * signature comes from the types and the semantics from §1.10 (abort dst, delete
287
+ * dst storage, recursive copy of the src subtree), and the orchestration is
288
+ * `server/`'s `cloneFacet`. There is nothing upstream to check the body against,
289
+ * which makes it the one method here with no reference — worth knowing when it
290
+ * is wrong.
291
+ */
292
+ export declare class DurableObjectFacets implements globalThis.DurableObjectFacets {
293
+ #private;
294
+ constructor(ctx: IoContext, facetManager: FacetManager | undefined, parentId: string);
295
+ /**
296
+ * Get a facet by name, starting it if it isn't already running.
297
+ * `getStartupOptions` is invoked only if the facet wasn't already running.
298
+ *
299
+ * Returns a `Fetcher` instead of a `DurableObject` because the returned stub
300
+ * does not have the `id` or `name` methods that a DO stub normally has.
301
+ */
302
+ get<T extends Rpc.DurableObjectBranded | undefined = undefined>(name: string, getStartupOptions: () => FacetStartupOptions<T> | Promise<FacetStartupOptions<T>>): Fetcher<T>;
303
+ abort(name: string, reason: unknown): void;
304
+ delete(name: string): void;
305
+ clone(src: string, dst: string): void;
306
+ }
307
+ export type DurableObjectStateOptions = {
308
+ id: DurableObjectId;
309
+ /** The `ctx.exports` class registry. */
310
+ exports: Record<string, unknown>;
311
+ props: unknown;
312
+ storage?: DurableObjectStorage;
313
+ /** Absent for an actor whose host offers no facets, as upstream's `kj::Maybe` is. */
314
+ facets?: FacetManager;
315
+ /** ← `ActorVersion`, a deployment cohort with nothing to read it here. */
316
+ version?: {
317
+ cohort?: string;
318
+ };
319
+ /**
320
+ * This actor's `ServiceWorkerGlobalScope` half — the container's own
321
+ * `globals`. Required, unlike `storage` and `facets`: a host that offers no
322
+ * storage is a real posture upstream has, but an actor with no gated timers
323
+ * is not, and the failure of a missing one is an ungated timer that WORKS
324
+ * until a continuation after it touches storage. See
325
+ * `DurableObjectState.globals`.
326
+ */
327
+ globals: ActorScopeBindings;
328
+ };
329
+ /** The type passed as the first parameter to a Durable Object class's constructor. */
330
+ export declare class DurableObjectState implements globalThis.DurableObjectState {
331
+ #private;
332
+ constructor(ctx: IoContext, options: DurableObjectStateOptions);
333
+ get id(): DurableObjectId;
334
+ get props(): unknown;
335
+ /** ← `JSG_LAZY_INSTANCE_PROPERTY(exports, getExports)`, behind `enableCtxExports` upstream. */
336
+ get exports(): Record<string, unknown>;
337
+ get version(): {
338
+ cohort?: string;
339
+ } | undefined;
340
+ /**
341
+ * NO upstream correspondence, because upstream needs none: a
342
+ * `ServiceWorkerGlobalScope` IS the isolate's global object there, so an
343
+ * actor's class reaches its gated `setTimeout` by writing `setTimeout`.
344
+ *
345
+ * Here one realm hosts several actors, so the names on `globalThis` can only
346
+ * be bound to one of them and a continuation cannot be asked which one it
347
+ * belongs to. `ctx` is the one reference every Durable Object class already
348
+ * holds and that already means exactly one actor — the constructor was handed
349
+ * it — so it is where the scope goes. An actor's method writes
350
+ * `this.ctx.globals.setTimeout(…)`; a free function it calls takes the scope
351
+ * as a parameter.
352
+ *
353
+ * `installActorScope` still exists and is still what a host uses for a
354
+ * dynamically-loaded Worker source, which has no `ctx` to reach through and
355
+ * its own module scope to destructure into. The two are the same object.
356
+ */
357
+ get globals(): ActorScopeBindings;
358
+ get storage(): DurableObjectStorage;
359
+ /** ← `JSG_LAZY_INSTANCE_PROPERTY(facets, getFacets)`. */
360
+ get facets(): DurableObjectFacets;
361
+ waitUntil(promise: Promise<unknown>): void;
362
+ /**
363
+ * ← `DurableObjectState::blockConcurrencyWhile` (`actor-state.c++:1128-1131`),
364
+ * which is a one-line forward and nothing else. The 30-second deadline, the
365
+ * brokenness annotation and the never-settled promise on failure all live in
366
+ * `IoContext::blockConcurrencyWhile`, which Section 2 already implements.
367
+ *
368
+ * Its precondition comes with it: `IoContext::blockConcurrencyWhile` calls
369
+ * `getInputLock()`, which asserts, so this is reachable only from inside a
370
+ * gated slice.
371
+ */
372
+ blockConcurrencyWhile<T>(callback: () => Promise<T>): Promise<T>;
373
+ /**
374
+ * ← `DurableObjectState::abort`. Reset the object, including breaking the
375
+ * output gate and canceling any writes that haven't been committed yet.
376
+ *
377
+ * `js.terminateExecutionNow()` has no port — there is no isolate to terminate —
378
+ * so the caller's own slice keeps running to its next await, where `IoContext`
379
+ * refuses to re-enter.
380
+ */
381
+ abort(reason?: string): void;
382
+ /** ← `DurableObjectState::getPrimaryStub`. Non-null only for a replica; see the storage note. */
383
+ get primaryStub(): undefined;
384
+ /** Substrate boundary: replication. */
385
+ configureReadReplication(options: {
386
+ mode: string;
387
+ }): Promise<void>;
388
+ acceptWebSocket(_ws: WebSocket, _tags?: string[]): never;
389
+ getWebSockets(_tag?: string): never;
390
+ setWebSocketAutoResponse(_maybeReqResp?: WebSocketRequestResponsePair): never;
391
+ getWebSocketAutoResponse(): never;
392
+ getWebSocketAutoResponseTimestamp(_ws: WebSocket): never;
393
+ setHibernatableWebSocketEventTimeout(_timeoutMs?: number): never;
394
+ getHibernatableWebSocketEventTimeout(): never;
395
+ getTags(_ws: WebSocket): never;
396
+ }