@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,351 @@
1
+ //#region src/api/cloudflare-workers.ts
2
+ /**
3
+ * ← workerd `src/cloudflare/workers.ts` — the built-in `cloudflare:workers`
4
+ * module.
5
+ *
6
+ * Upstream's own header explains the file's shape: "C++ built-in modules do not
7
+ * yet support named exports, so we must define this wrapper module that simply
8
+ * re-exports the classes from the built-in module." The classes come from
9
+ * `cloudflare-internal:workers` (`src/cloudflare/internal/workers.d.ts`); the
10
+ * behaviour this file owns is the two proxies and the three scope functions.
11
+ *
12
+ * **The export surface was re-derived, not inherited.** The extension shim this
13
+ * replaces (`offscreen/worker/host/shims/cloudflare-workers.ts`, 58 lines)
14
+ * documents its surface as the result of grepping `from "cloudflare:workers"`
15
+ * across `vendor/agents/packages/agents/src`. Re-running that grep across all of
16
+ * `vendor/agents` finds six values — `env` (178 imports), `exports` (48),
17
+ * `WorkerEntrypoint` (16), `RpcTarget` (16), `DurableObject` (13),
18
+ * `WorkflowEntrypoint` (3) — and **four types the shim does not have**:
19
+ * `WorkflowEvent` (8), `WorkflowSleepDuration` (4), `WorkflowStep` (3) and
20
+ * `WorkflowStepEvent` (2). `@cloudflare/workers-types` declares only
21
+ * `WorkflowSleepDuration` of those four globally, so the other three are
22
+ * declared here, where the module that exports them lives.
23
+ *
24
+ * Everything else upstream exports is ported too, per the package README's rule
25
+ * that consumer count is not the filter: `RpcStub`, `RpcPromise`, `RpcProperty`,
26
+ * `ServiceStub`, `waitUntil`, `cache`, `tracing` and `abortIsolate`. Each of
27
+ * those is a named throwing boundary, and each throw says which layer owns the
28
+ * thing that is missing rather than that it is missing.
29
+ *
30
+ * **The one thing to know before wiring this in.** `RpcTarget` is declared here,
31
+ * as upstream declares it — capnweb's own documentation says "on Cloudflare
32
+ * Workers, this `RpcTarget` is an alias for the one exported from the
33
+ * `cloudflare:workers` module, so they can be used interchangably." That alias is
34
+ * **unreachable** in capnweb 0.10.0: `let workersModule = globalThis[Symbol("workers-module")]`
35
+ * reads a symbol created fresh inside capnweb's own module and exported nowhere,
36
+ * so it is always `undefined` and capnweb falls back to its private `class {}`.
37
+ * `value instanceof RpcTarget` inside capnweb therefore tests capnweb's class,
38
+ * not this one, which is why today's extension shim re-exports capnweb's. The
39
+ * transport adaptation (`src/transport/`) owns reconciling the two; `api/` may not
40
+ * import a transport library, and inverting the dependency — making the module
41
+ * that defines the base class depend on the library that aliases it — is the
42
+ * layering upstream does not have.
43
+ *
44
+ * Spec: the shim-surface inventory in docs/shim-surface.md and decision 16 in
45
+ * docs/decisions.md.
46
+ */
47
+ /**
48
+ * `entrypoints.waitUntil` reaches `IoContext::current()`, a thread-local this
49
+ * package deliberately does not port — `io/io-context.ts`'s invocation stack
50
+ * replaces it, and it is reachable only from inside a gated slice rather than
51
+ * from module scope.
52
+ */
53
+ var MODULE_WAIT_UNTIL_UNIMPLEMENTED_MESSAGE = "The module-level waitUntil() from cloudflare:workers has no current request to attach to in this runtime. Call ctx.waitUntil() on the DurableObjectState or ExecutionContext you were given instead.";
54
+ /**
55
+ * Upstream: "In workerd, the handler aborts the process (unless used on a
56
+ * dynamic worker). In the edge runtime it will condemn and terminate the current
57
+ * isolate." There is no isolate to condemn, which is the same absence
58
+ * `DurableObjectState.abort()` records for `js.terminateExecutionNow()`.
59
+ */
60
+ var ABORT_ISOLATE_UNIMPLEMENTED_MESSAGE = "abortIsolate() is not available in this runtime: there is no isolate to condemn. Break the actor's output gate instead, which is what DurableObjectState.abort() does.";
61
+ /** The Workers Cache API is an edge facility; `caches` in a browser is a different contract. */
62
+ var CACHE_UNIMPLEMENTED_MESSAGE = "The cloudflare:workers cache context is not available in this runtime: CacheContext.purge() is an edge operation with no browser equivalent.";
63
+ /** The four stub types are the RPC system's, and the RPC system here is the transport adaptation. */
64
+ var RPC_STUB_UNIMPLEMENTED_MESSAGE = "RpcStub, RpcPromise, RpcProperty and ServiceStub belong to the RPC system, which in this runtime is the capnweb transport adaptation rather than this module. Construct one through the transport.";
65
+ /**
66
+ * Upstream's `exports` proxy defines no `set` trap, so an assignment lands on the
67
+ * empty proxy target and is silently lost — its comment says "This proxy is
68
+ * read-only - mutations are not supported." A silent loss is the failure mode
69
+ * this repository's fail-closed tenet exists to prevent, so it throws instead.
70
+ */
71
+ var EXPORTS_READ_ONLY_MESSAGE = "The cloudflare:workers exports object is read-only. Install worker exports with withExports() or withEnvAndExports().";
72
+ /**
73
+ * Upstream's scopes are `AsyncContext`-propagated, so an `async` callback keeps
74
+ * its bindings across an await. Decision 8's propagation is not built (and Part 4
75
+ * records that this package needs none), so the scope here is the synchronous
76
+ * call — which is exactly what upstream's `fn: () => unknown` signature describes
77
+ * and nothing more. A callback that returns a thenable would silently read the
78
+ * wrong bindings after its first await, so it is refused: the same guard, for the
79
+ * same reason, that `transactionSync` already applies to its callback.
80
+ */
81
+ var WITH_SCOPE_ASYNC_MESSAGE = "withEnv(), withExports() and withEnvAndExports() take a synchronous callback in this runtime. The returned value is a thenable, and everything after its first await would run outside the scope with the previous bindings installed.";
82
+ /**
83
+ * The scope stacks. Upstream's current env comes from
84
+ * `innerEnv.getCurrentEnv()`, which is `kj::none` before the runtime installs
85
+ * one — the branch every trap below guards with `if (inner)`. Here the bottom of
86
+ * each stack is a real object installed at module load, so that branch is
87
+ * unreachable and the guard collapses.
88
+ *
89
+ * The bottom entry is also what makes `Object.assign(env, bindings)` work, which
90
+ * is how a host installs long-lived bindings: upstream's `set` trap forwards into
91
+ * the current env, and here the current env outside any scope is that object.
92
+ */
93
+ var envScopes = [{}];
94
+ var exportsScopes = [{}];
95
+ function topOf(scopes) {
96
+ const top = scopes.at(-1);
97
+ if (top === void 0) throw new Error("cloudflare:workers scope stack is empty");
98
+ return top;
99
+ }
100
+ /**
101
+ * ← the `env` proxy (`workers.ts:41-104`). Upstream's comment, which is the whole
102
+ * reason this is a proxy rather than an object: "Since env is imported as a
103
+ * module-level reference, the object identity cannot be changed. The proxy
104
+ * provides indirection, delegating to different underlying env objects based on
105
+ * async context (see withEnv()). Mutations via this proxy modify the current
106
+ * underlying env object in-place - if you're inside a withEnv() scope, mutations
107
+ * affect the override object, not the base environment."
108
+ */
109
+ var env = new Proxy({}, {
110
+ get(_target, property) {
111
+ return Reflect.get(topOf(envScopes), property);
112
+ },
113
+ set(_target, property, newValue) {
114
+ return Reflect.set(topOf(envScopes), property, newValue);
115
+ },
116
+ has(_target, property) {
117
+ return Reflect.has(topOf(envScopes), property);
118
+ },
119
+ ownKeys() {
120
+ return Reflect.ownKeys(topOf(envScopes));
121
+ },
122
+ deleteProperty(_target, property) {
123
+ return Reflect.deleteProperty(topOf(envScopes), property);
124
+ },
125
+ defineProperty(_target, property, attributes) {
126
+ return Reflect.defineProperty(topOf(envScopes), property, attributes);
127
+ },
128
+ getOwnPropertyDescriptor(_target, property) {
129
+ return Reflect.getOwnPropertyDescriptor(topOf(envScopes), property);
130
+ }
131
+ });
132
+ /**
133
+ * ← the `exports` proxy (`workers.ts:109-147`). Same indirection as `env`, minus
134
+ * the mutating traps — with `set` and `defineProperty` throwing where upstream
135
+ * lets them fall through to the dead proxy target.
136
+ */
137
+ var exports = new Proxy({}, {
138
+ get(_target, property) {
139
+ return Reflect.get(topOf(exportsScopes), property);
140
+ },
141
+ set() {
142
+ throw new TypeError(EXPORTS_READ_ONLY_MESSAGE);
143
+ },
144
+ defineProperty() {
145
+ throw new TypeError(EXPORTS_READ_ONLY_MESSAGE);
146
+ },
147
+ deleteProperty() {
148
+ throw new TypeError(EXPORTS_READ_ONLY_MESSAGE);
149
+ },
150
+ has(_target, property) {
151
+ return Reflect.has(topOf(exportsScopes), property);
152
+ },
153
+ ownKeys() {
154
+ return Reflect.ownKeys(topOf(exportsScopes));
155
+ },
156
+ getOwnPropertyDescriptor(_target, property) {
157
+ return Reflect.getOwnPropertyDescriptor(topOf(exportsScopes), property);
158
+ }
159
+ });
160
+ /** ← `withEnv` (`workers.ts:21-23`). */
161
+ function withEnv(newEnv, fn) {
162
+ return runInScopes([{
163
+ scopes: envScopes,
164
+ value: newEnv
165
+ }], fn);
166
+ }
167
+ /** ← `withExports` (`workers.ts:25-27`). */
168
+ function withExports(newExports, fn) {
169
+ return runInScopes([{
170
+ scopes: exportsScopes,
171
+ value: newExports
172
+ }], fn);
173
+ }
174
+ /** ← `withEnvAndExports` (`workers.ts:29-34`). */
175
+ function withEnvAndExports(newEnv, newExports, fn) {
176
+ return runInScopes([{
177
+ scopes: envScopes,
178
+ value: newEnv
179
+ }, {
180
+ scopes: exportsScopes,
181
+ value: newExports
182
+ }], fn);
183
+ }
184
+ function runInScopes(pushes, fn) {
185
+ for (const push of pushes) push.scopes.push(asBindings(push.value));
186
+ try {
187
+ const result = fn();
188
+ if (isThenable(result)) throw new TypeError(WITH_SCOPE_ASYNC_MESSAGE);
189
+ return result;
190
+ } finally {
191
+ for (const push of pushes) push.scopes.pop();
192
+ }
193
+ }
194
+ function asBindings(value) {
195
+ if (value !== null && typeof value === "object") return value;
196
+ throw new TypeError("cloudflare:workers scopes take an object of bindings.");
197
+ }
198
+ function isThenable(value) {
199
+ if (value === null || typeof value !== "object" && typeof value !== "function") return false;
200
+ return typeof value.then === "function";
201
+ }
202
+ /**
203
+ * ← `RpcTarget` (`cloudflare/internal/workers.d.ts`: `export class RpcTarget {}`).
204
+ *
205
+ * Upstream's public type declares it `abstract` with one branding member; the
206
+ * implementation declaration has neither, and this follows the implementation so
207
+ * that a marker instance can exist. See this file's header for the identity
208
+ * constraint capnweb imposes on it.
209
+ */
210
+ var RpcTarget = class {};
211
+ /**
212
+ * ← `DurableObject` (`cloudflare/internal/workers.d.ts`; public shape in
213
+ * `@cloudflare/workers-types`).
214
+ *
215
+ * `extends RpcTarget` is this runtime's, not upstream's: workerd's RPC system
216
+ * knows the three entrypoint classes natively through `Rpc.*Branded`, and
217
+ * capnweb recognises only `RpcTarget`. Same observable behaviour — an instance
218
+ * may be passed by reference over RPC — through the mechanism the substrate has.
219
+ *
220
+ * `ctx` and `env` are `protected` because that is what the published types say,
221
+ * and upstream's comment on `WorkerEntrypoint` says why it matters rather than
222
+ * being style: "`protected` fields don't appear in `keyof`s, so can't be accessed
223
+ * over RPC." The extension shim had them public.
224
+ */
225
+ var DurableObject = class extends RpcTarget {
226
+ ctx;
227
+ env;
228
+ constructor(ctx, env) {
229
+ super();
230
+ this.ctx = ctx;
231
+ this.env = env;
232
+ }
233
+ };
234
+ /** ← `WorkerEntrypoint`. */
235
+ var WorkerEntrypoint = class extends RpcTarget {
236
+ ctx;
237
+ env;
238
+ constructor(ctx, env) {
239
+ super();
240
+ this.ctx = ctx;
241
+ this.env = env;
242
+ }
243
+ };
244
+ /**
245
+ * ← `WorkflowEntrypoint`.
246
+ *
247
+ * The extension shim threw from the constructor. That throw is dropped: the class
248
+ * is a plain base whose `run` a Workflows binding dispatches, and there is no
249
+ * Workflows binding here — so the absent thing is the binding, which nothing in
250
+ * this package offers, rather than the base class. Constructing one and never
251
+ * dispatching it is what happens today either way, and a constructor that throws
252
+ * would take down module evaluation for a consumer that merely declares a
253
+ * subclass.
254
+ */
255
+ var WorkflowEntrypoint = class extends RpcTarget {
256
+ ctx;
257
+ env;
258
+ constructor(ctx, env) {
259
+ super();
260
+ this.ctx = ctx;
261
+ this.env = env;
262
+ }
263
+ run(_event, _step) {
264
+ throw new Error("WorkflowEntrypoint subclasses must implement run().");
265
+ }
266
+ };
267
+ /** ← `RpcStub`. */
268
+ var RpcStub = class {
269
+ constructor(_server) {
270
+ throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);
271
+ }
272
+ };
273
+ /** ← `RpcPromise`. */
274
+ var RpcPromise = class {
275
+ constructor() {
276
+ throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);
277
+ }
278
+ };
279
+ /** ← `RpcProperty`. */
280
+ var RpcProperty = class {
281
+ constructor() {
282
+ throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);
283
+ }
284
+ };
285
+ /** ← `ServiceStub`. */
286
+ var ServiceStub = class {
287
+ constructor() {
288
+ throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);
289
+ }
290
+ };
291
+ /** ← `export const waitUntil = entrypoints.waitUntil.bind(entrypoints)`. */
292
+ function waitUntil(_promise) {
293
+ throw new Error(MODULE_WAIT_UNTIL_UNIMPLEMENTED_MESSAGE);
294
+ }
295
+ /** ← `abortIsolate` (`workers.ts:206-215`). */
296
+ function abortIsolate(_reason) {
297
+ throw new Error(ABORT_ISOLATE_UNIMPLEMENTED_MESSAGE);
298
+ }
299
+ /**
300
+ * ← the `cache` proxy (`workers.ts:152-198`).
301
+ *
302
+ * Upstream's `cache` answers `undefined` when there is no current context —
303
+ * "Used to enable safe no-op access outside module init" — which here would be
304
+ * every access, and `cache.purge(...)` would fail as "purge is not a function"
305
+ * three frames from the cause. A throwing proxy names the boundary at the access.
306
+ *
307
+ * The one assertion in this file, in one place: no value can be a `CacheContext`
308
+ * here, and the object that stands in for one exists precisely so that touching it
309
+ * fails. Same shape as `io/worker.ts`'s `asFacetStub`.
310
+ */
311
+ function boundaryObject(message) {
312
+ const thrower = () => {
313
+ throw new Error(message);
314
+ };
315
+ return new Proxy({}, {
316
+ get: thrower,
317
+ has: thrower,
318
+ ownKeys: thrower,
319
+ getOwnPropertyDescriptor: thrower
320
+ });
321
+ }
322
+ var cache = boundaryObject(CACHE_UNIMPLEMENTED_MESSAGE);
323
+ /**
324
+ * ← `export const tracing = innerTracing`.
325
+ *
326
+ * This one is NOT a boundary. The workerd oracle establishes (§1.12) that
327
+ * `tracing` is an
328
+ * object, `startActiveSpan(name, run)` calls `run` and returns its result, and
329
+ * the span it hands over reports `isTraced: false` with working no-op
330
+ * `setAttribute` and `end`. Untraced is workerd's ORDINARY state when nothing is
331
+ * collecting, not an error — so a `Span` here is a permanently untraced one, which
332
+ * is the same observable behaviour through the only mechanism this package has.
333
+ *
334
+ * A throwing proxy was worse than strict, it was wrong: `agents`' tracing runtime
335
+ * feature-detects with `cloudflareWorkers.tracing ?? noopRuntime`, so a present
336
+ * object that throws on use took down every `new Agent(...)` in the extension —
337
+ * where an absent one would have degraded exactly as that code intends.
338
+ */
339
+ var Span = class {
340
+ /** Always false: nothing in this package collects spans, so no span is sampled. */
341
+ isTraced = false;
342
+ setAttribute(_name, _value) {}
343
+ end() {}
344
+ };
345
+ var tracing = { startActiveSpan(_name, run) {
346
+ return run(new Span());
347
+ } };
348
+ //#endregion
349
+ export { ABORT_ISOLATE_UNIMPLEMENTED_MESSAGE, CACHE_UNIMPLEMENTED_MESSAGE, DurableObject, EXPORTS_READ_ONLY_MESSAGE, MODULE_WAIT_UNTIL_UNIMPLEMENTED_MESSAGE, RPC_STUB_UNIMPLEMENTED_MESSAGE, RpcPromise, RpcProperty, RpcStub, RpcTarget, ServiceStub, WITH_SCOPE_ASYNC_MESSAGE, WorkerEntrypoint, WorkflowEntrypoint, abortIsolate, cache, env, exports, tracing, waitUntil, withEnv, withEnvAndExports, withExports };
350
+
351
+ //# sourceMappingURL=cloudflare-workers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-workers.js","names":[],"sources":["../src/api/cloudflare-workers.ts"],"sourcesContent":["/**\n * ← workerd `src/cloudflare/workers.ts` — the built-in `cloudflare:workers`\n * module.\n *\n * Upstream's own header explains the file's shape: \"C++ built-in modules do not\n * yet support named exports, so we must define this wrapper module that simply\n * re-exports the classes from the built-in module.\" The classes come from\n * `cloudflare-internal:workers` (`src/cloudflare/internal/workers.d.ts`); the\n * behaviour this file owns is the two proxies and the three scope functions.\n *\n * **The export surface was re-derived, not inherited.** The extension shim this\n * replaces (`offscreen/worker/host/shims/cloudflare-workers.ts`, 58 lines)\n * documents its surface as the result of grepping `from \"cloudflare:workers\"`\n * across `vendor/agents/packages/agents/src`. Re-running that grep across all of\n * `vendor/agents` finds six values — `env` (178 imports), `exports` (48),\n * `WorkerEntrypoint` (16), `RpcTarget` (16), `DurableObject` (13),\n * `WorkflowEntrypoint` (3) — and **four types the shim does not have**:\n * `WorkflowEvent` (8), `WorkflowSleepDuration` (4), `WorkflowStep` (3) and\n * `WorkflowStepEvent` (2). `@cloudflare/workers-types` declares only\n * `WorkflowSleepDuration` of those four globally, so the other three are\n * declared here, where the module that exports them lives.\n *\n * Everything else upstream exports is ported too, per the package README's rule\n * that consumer count is not the filter: `RpcStub`, `RpcPromise`, `RpcProperty`,\n * `ServiceStub`, `waitUntil`, `cache`, `tracing` and `abortIsolate`. Each of\n * those is a named throwing boundary, and each throw says which layer owns the\n * thing that is missing rather than that it is missing.\n *\n * **The one thing to know before wiring this in.** `RpcTarget` is declared here,\n * as upstream declares it — capnweb's own documentation says \"on Cloudflare\n * Workers, this `RpcTarget` is an alias for the one exported from the\n * `cloudflare:workers` module, so they can be used interchangably.\" That alias is\n * **unreachable** in capnweb 0.10.0: `let workersModule = globalThis[Symbol(\"workers-module\")]`\n * reads a symbol created fresh inside capnweb's own module and exported nowhere,\n * so it is always `undefined` and capnweb falls back to its private `class {}`.\n * `value instanceof RpcTarget` inside capnweb therefore tests capnweb's class,\n * not this one, which is why today's extension shim re-exports capnweb's. The\n * transport adaptation (`src/transport/`) owns reconciling the two; `api/` may not\n * import a transport library, and inverting the dependency — making the module\n * that defines the base class depend on the library that aliases it — is the\n * layering upstream does not have.\n *\n * Spec: the shim-surface inventory in docs/shim-surface.md and decision 16 in\n * docs/decisions.md.\n */\n\n// =======================================================================================\n// Boundary messages\n\n/**\n * `entrypoints.waitUntil` reaches `IoContext::current()`, a thread-local this\n * package deliberately does not port — `io/io-context.ts`'s invocation stack\n * replaces it, and it is reachable only from inside a gated slice rather than\n * from module scope.\n */\nexport const MODULE_WAIT_UNTIL_UNIMPLEMENTED_MESSAGE =\n \"The module-level waitUntil() from cloudflare:workers has no current request to attach to in \" +\n \"this runtime. Call ctx.waitUntil() on the DurableObjectState or ExecutionContext you were \" +\n \"given instead.\";\n\n/**\n * Upstream: \"In workerd, the handler aborts the process (unless used on a\n * dynamic worker). In the edge runtime it will condemn and terminate the current\n * isolate.\" There is no isolate to condemn, which is the same absence\n * `DurableObjectState.abort()` records for `js.terminateExecutionNow()`.\n */\nexport const ABORT_ISOLATE_UNIMPLEMENTED_MESSAGE =\n \"abortIsolate() is not available in this runtime: there is no isolate to condemn. Break the \" +\n \"actor's output gate instead, which is what DurableObjectState.abort() does.\";\n\n/** The Workers Cache API is an edge facility; `caches` in a browser is a different contract. */\nexport const CACHE_UNIMPLEMENTED_MESSAGE =\n \"The cloudflare:workers cache context is not available in this runtime: CacheContext.purge() \" +\n \"is an edge operation with no browser equivalent.\";\n\n/** The four stub types are the RPC system's, and the RPC system here is the transport adaptation. */\nexport const RPC_STUB_UNIMPLEMENTED_MESSAGE =\n \"RpcStub, RpcPromise, RpcProperty and ServiceStub belong to the RPC system, which in this \" +\n \"runtime is the capnweb transport adaptation rather than this module. Construct one through \" +\n \"the transport.\";\n\n/**\n * Upstream's `exports` proxy defines no `set` trap, so an assignment lands on the\n * empty proxy target and is silently lost — its comment says \"This proxy is\n * read-only - mutations are not supported.\" A silent loss is the failure mode\n * this repository's fail-closed tenet exists to prevent, so it throws instead.\n */\nexport const EXPORTS_READ_ONLY_MESSAGE =\n \"The cloudflare:workers exports object is read-only. Install worker exports with \" +\n \"withExports() or withEnvAndExports().\";\n\n/**\n * Upstream's scopes are `AsyncContext`-propagated, so an `async` callback keeps\n * its bindings across an await. Decision 8's propagation is not built (and Part 4\n * records that this package needs none), so the scope here is the synchronous\n * call — which is exactly what upstream's `fn: () => unknown` signature describes\n * and nothing more. A callback that returns a thenable would silently read the\n * wrong bindings after its first await, so it is refused: the same guard, for the\n * same reason, that `transactionSync` already applies to its callback.\n */\nexport const WITH_SCOPE_ASYNC_MESSAGE =\n \"withEnv(), withExports() and withEnvAndExports() take a synchronous callback in this runtime. \" +\n \"The returned value is a thenable, and everything after its first await would run outside the \" +\n \"scope with the previous bindings installed.\";\n\n// =======================================================================================\n// env and exports\n\n/**\n * ← `export const env: Cloudflare.Env`. `Cloudflare.Env` is generated per project\n * from a `wrangler.jsonc`, and this package has neither, so the value type is the\n * open record the extension shim already used.\n */\nexport type Bindings = Record<string, unknown>;\n\n/**\n * The scope stacks. Upstream's current env comes from\n * `innerEnv.getCurrentEnv()`, which is `kj::none` before the runtime installs\n * one — the branch every trap below guards with `if (inner)`. Here the bottom of\n * each stack is a real object installed at module load, so that branch is\n * unreachable and the guard collapses.\n *\n * The bottom entry is also what makes `Object.assign(env, bindings)` work, which\n * is how a host installs long-lived bindings: upstream's `set` trap forwards into\n * the current env, and here the current env outside any scope is that object.\n */\nconst envScopes: Bindings[] = [{}];\nconst exportsScopes: Bindings[] = [{}];\n\nfunction topOf(scopes: Bindings[]): Bindings {\n const top = scopes.at(-1);\n if (top === undefined) {\n // Unreachable: both stacks are seeded at module load and every push has a matching pop in a\n // `finally`. Written as a throw rather than a `!` because the package has no non-null assertions.\n throw new Error(\"cloudflare:workers scope stack is empty\");\n }\n return top;\n}\n\n/**\n * ← the `env` proxy (`workers.ts:41-104`). Upstream's comment, which is the whole\n * reason this is a proxy rather than an object: \"Since env is imported as a\n * module-level reference, the object identity cannot be changed. The proxy\n * provides indirection, delegating to different underlying env objects based on\n * async context (see withEnv()). Mutations via this proxy modify the current\n * underlying env object in-place - if you're inside a withEnv() scope, mutations\n * affect the override object, not the base environment.\"\n */\nexport const env: Bindings = new Proxy<Bindings>(\n {},\n {\n get(_target, property): unknown {\n return Reflect.get(topOf(envScopes), property);\n },\n set(_target, property, newValue): boolean {\n return Reflect.set(topOf(envScopes), property, newValue);\n },\n has(_target, property): boolean {\n return Reflect.has(topOf(envScopes), property);\n },\n ownKeys(): ArrayLike<string | symbol> {\n return Reflect.ownKeys(topOf(envScopes));\n },\n deleteProperty(_target, property): boolean {\n return Reflect.deleteProperty(topOf(envScopes), property);\n },\n defineProperty(_target, property, attributes): boolean {\n return Reflect.defineProperty(topOf(envScopes), property, attributes);\n },\n getOwnPropertyDescriptor(_target, property): PropertyDescriptor | undefined {\n return Reflect.getOwnPropertyDescriptor(topOf(envScopes), property);\n },\n },\n);\n\n/**\n * ← the `exports` proxy (`workers.ts:109-147`). Same indirection as `env`, minus\n * the mutating traps — with `set` and `defineProperty` throwing where upstream\n * lets them fall through to the dead proxy target.\n */\nexport const exports: Bindings = new Proxy<Bindings>(\n {},\n {\n get(_target, property): unknown {\n return Reflect.get(topOf(exportsScopes), property);\n },\n set(): never {\n throw new TypeError(EXPORTS_READ_ONLY_MESSAGE);\n },\n defineProperty(): never {\n throw new TypeError(EXPORTS_READ_ONLY_MESSAGE);\n },\n deleteProperty(): never {\n throw new TypeError(EXPORTS_READ_ONLY_MESSAGE);\n },\n has(_target, property): boolean {\n return Reflect.has(topOf(exportsScopes), property);\n },\n ownKeys(): ArrayLike<string | symbol> {\n return Reflect.ownKeys(topOf(exportsScopes));\n },\n getOwnPropertyDescriptor(_target, property): PropertyDescriptor | undefined {\n return Reflect.getOwnPropertyDescriptor(topOf(exportsScopes), property);\n },\n },\n);\n\n/** ← `withEnv` (`workers.ts:21-23`). */\nexport function withEnv(newEnv: unknown, fn: () => unknown): unknown {\n return runInScopes([{ scopes: envScopes, value: newEnv }], fn);\n}\n\n/** ← `withExports` (`workers.ts:25-27`). */\nexport function withExports(newExports: unknown, fn: () => unknown): unknown {\n return runInScopes([{ scopes: exportsScopes, value: newExports }], fn);\n}\n\n/** ← `withEnvAndExports` (`workers.ts:29-34`). */\nexport function withEnvAndExports(\n newEnv: unknown,\n newExports: unknown,\n fn: () => unknown,\n): unknown {\n return runInScopes(\n [\n { scopes: envScopes, value: newEnv },\n { scopes: exportsScopes, value: newExports },\n ],\n fn,\n );\n}\n\nfunction runInScopes(\n pushes: readonly { readonly scopes: Bindings[]; readonly value: unknown }[],\n fn: () => unknown,\n): unknown {\n for (const push of pushes) push.scopes.push(asBindings(push.value));\n try {\n const result = fn();\n if (isThenable(result)) throw new TypeError(WITH_SCOPE_ASYNC_MESSAGE);\n return result;\n } finally {\n for (const push of pushes) push.scopes.pop();\n }\n}\n\nfunction asBindings(value: unknown): Bindings {\n if (value !== null && typeof value === \"object\") return value as Bindings;\n throw new TypeError(\"cloudflare:workers scopes take an object of bindings.\");\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// The entrypoint classes\n\n/**\n * ← `RpcTarget` (`cloudflare/internal/workers.d.ts`: `export class RpcTarget {}`).\n *\n * Upstream's public type declares it `abstract` with one branding member; the\n * implementation declaration has neither, and this follows the implementation so\n * that a marker instance can exist. See this file's header for the identity\n * constraint capnweb imposes on it.\n */\nexport class RpcTarget {}\n\n/**\n * ← `DurableObject` (`cloudflare/internal/workers.d.ts`; public shape in\n * `@cloudflare/workers-types`).\n *\n * `extends RpcTarget` is this runtime's, not upstream's: workerd's RPC system\n * knows the three entrypoint classes natively through `Rpc.*Branded`, and\n * capnweb recognises only `RpcTarget`. Same observable behaviour — an instance\n * may be passed by reference over RPC — through the mechanism the substrate has.\n *\n * `ctx` and `env` are `protected` because that is what the published types say,\n * and upstream's comment on `WorkerEntrypoint` says why it matters rather than\n * being style: \"`protected` fields don't appear in `keyof`s, so can't be accessed\n * over RPC.\" The extension shim had them public.\n */\nexport class DurableObject<Env = unknown, Props = unknown> extends RpcTarget {\n protected ctx: DurableObjectState<Props>;\n protected env: Env;\n\n constructor(ctx: DurableObjectState<Props>, env: Env) {\n super();\n this.ctx = ctx;\n this.env = env;\n }\n}\n\n/** ← `WorkerEntrypoint`. */\nexport class WorkerEntrypoint<Env = unknown, Props = unknown> extends RpcTarget {\n protected ctx: ExecutionContext<Props>;\n protected env: Env;\n\n constructor(ctx: ExecutionContext<Props>, env: Env) {\n super();\n this.ctx = ctx;\n this.env = env;\n }\n}\n\n/**\n * ← `WorkflowEntrypoint`.\n *\n * The extension shim threw from the constructor. That throw is dropped: the class\n * is a plain base whose `run` a Workflows binding dispatches, and there is no\n * Workflows binding here — so the absent thing is the binding, which nothing in\n * this package offers, rather than the base class. Constructing one and never\n * dispatching it is what happens today either way, and a constructor that throws\n * would take down module evaluation for a consumer that merely declares a\n * subclass.\n */\nexport class WorkflowEntrypoint<Env = unknown, T = unknown> extends RpcTarget {\n protected ctx: ExecutionContext;\n protected env: Env;\n\n constructor(ctx: ExecutionContext, env: Env) {\n super();\n this.ctx = ctx;\n this.env = env;\n }\n\n run(_event: Readonly<WorkflowEvent<T>>, _step: WorkflowStep): Promise<unknown> {\n throw new Error(\"WorkflowEntrypoint subclasses must implement run().\");\n }\n}\n\n// =======================================================================================\n// The RPC stub types — the transport adaptation's, not this layer's\n\n/** ← `RpcStub`. */\nexport class RpcStub {\n constructor(_server: object) {\n throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);\n }\n}\n\n/** ← `RpcPromise`. */\nexport class RpcPromise {\n constructor() {\n throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);\n }\n}\n\n/** ← `RpcProperty`. */\nexport class RpcProperty {\n constructor() {\n throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);\n }\n}\n\n/** ← `ServiceStub`. */\nexport class ServiceStub {\n constructor() {\n throw new Error(RPC_STUB_UNIMPLEMENTED_MESSAGE);\n }\n}\n\n// =======================================================================================\n// The boundary exports\n\n/** ← `export const waitUntil = entrypoints.waitUntil.bind(entrypoints)`. */\nexport function waitUntil(_promise: Promise<unknown>): never {\n throw new Error(MODULE_WAIT_UNTIL_UNIMPLEMENTED_MESSAGE);\n}\n\n/** ← `abortIsolate` (`workers.ts:206-215`). */\nexport function abortIsolate(_reason?: string): never {\n throw new Error(ABORT_ISOLATE_UNIMPLEMENTED_MESSAGE);\n}\n\n/**\n * ← the `cache` proxy (`workers.ts:152-198`).\n *\n * Upstream's `cache` answers `undefined` when there is no current context —\n * \"Used to enable safe no-op access outside module init\" — which here would be\n * every access, and `cache.purge(...)` would fail as \"purge is not a function\"\n * three frames from the cause. A throwing proxy names the boundary at the access.\n *\n * The one assertion in this file, in one place: no value can be a `CacheContext`\n * here, and the object that stands in for one exists precisely so that touching it\n * fails. Same shape as `io/worker.ts`'s `asFacetStub`.\n */\nfunction boundaryObject<T extends object>(message: string): T {\n const thrower = (): never => {\n throw new Error(message);\n };\n return new Proxy(\n {},\n { get: thrower, has: thrower, ownKeys: thrower, getOwnPropertyDescriptor: thrower },\n ) as T;\n}\n\nexport const cache: CacheContext = boundaryObject(CACHE_UNIMPLEMENTED_MESSAGE);\n\n/**\n * ← `export const tracing = innerTracing`.\n *\n * This one is NOT a boundary. The workerd oracle establishes (§1.12) that\n * `tracing` is an\n * object, `startActiveSpan(name, run)` calls `run` and returns its result, and\n * the span it hands over reports `isTraced: false` with working no-op\n * `setAttribute` and `end`. Untraced is workerd's ORDINARY state when nothing is\n * collecting, not an error — so a `Span` here is a permanently untraced one, which\n * is the same observable behaviour through the only mechanism this package has.\n *\n * A throwing proxy was worse than strict, it was wrong: `agents`' tracing runtime\n * feature-detects with `cloudflareWorkers.tracing ?? noopRuntime`, so a present\n * object that throws on use took down every `new Agent(...)` in the extension —\n * where an absent one would have degraded exactly as that code intends.\n */\nclass Span {\n /** Always false: nothing in this package collects spans, so no span is sampled. */\n readonly isTraced = false;\n setAttribute(_name: string, _value: unknown): void {}\n end(): void {}\n}\n\nexport const tracing: Tracing = {\n startActiveSpan<T>(_name: string, run: (span: Span) => T): T {\n return run(new Span());\n },\n} as unknown as Tracing;\n\n// =======================================================================================\n// The Workflow types\n//\n// `@cloudflare/workers-types` declares `WorkflowSleepDuration`, `WorkflowDurationLabel` and\n// `WorkflowRetentionDuration` globally and the rest of the family only inside the\n// `cloudflare:workers` module, so the rest are declared here — the module that exports them.\n// Ported from that module declaration verbatim; they are types and carry no behaviour.\n\n/**\n * `@cloudflare/workers-types` also declares these two globally, and this module\n * declares its own for the reason upstream's module does: `export type {}` needs\n * a local declaration, and the module is where the names belong.\n */\nexport type WorkflowDurationLabel =\n | \"second\"\n | \"minute\"\n | \"hour\"\n | \"day\"\n | \"week\"\n | \"month\"\n | \"year\";\n\nexport type WorkflowSleepDuration = `${number} ${WorkflowDurationLabel}${\"s\" | \"\"}` | number;\n\nexport type WorkflowRetentionDuration = WorkflowSleepDuration;\nexport type WorkflowDelayDuration = WorkflowSleepDuration;\nexport type WorkflowTimeoutDuration = WorkflowSleepDuration;\nexport type WorkflowBackoff = \"constant\" | \"linear\" | \"exponential\";\nexport type WorkflowStepSensitivity = \"output\";\n\nexport type WorkflowStepConfig = {\n retries?: {\n limit: number;\n delay: WorkflowDelayDuration | number;\n backoff?: WorkflowBackoff;\n };\n timeout?: WorkflowTimeoutDuration | number;\n sensitive?: WorkflowStepSensitivity;\n};\n\nexport type WorkflowStepRollbackConfig = Pick<WorkflowStepConfig, \"retries\" | \"timeout\">;\n\nexport type WorkflowCronSchedule = {\n /** Cron expression that triggered this event. */\n cron: string;\n /** Timestamp of the scheduled trigger, in milliseconds since the Unix epoch. */\n scheduledTime: number;\n};\n\nexport type WorkflowEvent<T> = {\n payload: Readonly<T>;\n timestamp: Date;\n instanceId: string;\n workflowName: string;\n schedule?: WorkflowCronSchedule;\n};\n\nexport type WorkflowStepEvent<T> = {\n payload: Readonly<T>;\n timestamp: Date;\n type: string;\n sensitive?: WorkflowStepSensitivity;\n};\n\nexport type WorkflowStepContext = {\n step: { name: string; count: number };\n attempt: number;\n config: WorkflowStepConfig;\n};\n\nexport type WorkflowRollbackContext<T = unknown> = {\n ctx: WorkflowStepContext;\n error: Error;\n output: T | undefined;\n /** @deprecated Use `ctx.step.name` and `ctx.step.count` instead. */\n stepName: string;\n};\n\nexport type WorkflowRollbackHandler<T = unknown> = (\n ctx: WorkflowRollbackContext<T>,\n) => Promise<void>;\n\nexport type WorkflowStepRollbackOptions<T = unknown> = {\n rollback: WorkflowRollbackHandler<T>;\n rollbackConfig?: WorkflowStepRollbackConfig;\n};\n\n/**\n * ← `WorkflowStep`, an abstract class in the module declaration. Declared and\n * never implemented here for the same reason `WorkflowEntrypoint.run` throws: a\n * `WorkflowStep` is handed to `run()` by a Workflows binding, and there is none.\n */\nexport declare abstract class WorkflowStep {\n do<T>(\n name: string,\n callback: (ctx: WorkflowStepContext) => Promise<T>,\n rollbackOptions?: WorkflowStepRollbackOptions<T>,\n ): Promise<T>;\n do<T>(\n name: string,\n config: WorkflowStepConfig,\n callback: (ctx: WorkflowStepContext) => Promise<T>,\n rollbackOptions?: WorkflowStepRollbackOptions<T>,\n ): Promise<T>;\n sleep: (name: string, duration: WorkflowSleepDuration) => Promise<void>;\n sleepUntil: (name: string, timestamp: Date | number) => Promise<void>;\n waitForEvent<T>(\n name: string,\n options: { type: string; timeout?: WorkflowTimeoutDuration | number },\n ): Promise<WorkflowStepEvent<T>>;\n}\n\nexport type WorkflowInstanceStatus =\n | \"queued\"\n | \"running\"\n | \"paused\"\n | \"errored\"\n | \"terminated\"\n | \"complete\"\n | \"waiting\"\n | \"waitingForPause\"\n | \"unknown\";\n"],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The conformance harness the suite writes against.
3
+ *
4
+ * The workerd lane is the ORACLE, not a third implementation — this package is
5
+ * deliberately absent from it. So a test has exactly one meaning: "workerd does
6
+ * X" and "our runtime does X" are the same assertion, executed twice.
7
+ *
8
+ * Probe classes are dependency-free (see fixtures/probe.ts), which is why the
9
+ * workerd lane needs no vendored-source aliases and CI's filtered vendor
10
+ * install never bites. Anything that would need vendored `think` or `agents`
11
+ * to express is agent-logic testing and belongs in the extension's integration
12
+ * lanes instead.
13
+ */
14
+ export type Capability =
15
+ /** Deterministic clock. Node lane only — a 30s ladder is not assertable on wall time. */
16
+ "fake-time"
17
+ /** Kill without cleanup: worker.terminate() or dropping the container. */
18
+ | "real-crash"
19
+ /** Substrate boundary: no Chrome equivalent lifecycle. */
20
+ | "hibernation"
21
+ /** Substrate boundary: sqlite-wasm lacks the storage capability. */
22
+ | "bookmarks";
23
+ export type LaneName = "workerd" | "node" | "browser";
24
+ export interface ProbeActor {
25
+ /** Durable identity. `respawn` reopens this same actor. */
26
+ readonly name: string;
27
+ call<T = unknown>(method: string, ...args: readonly unknown[]): Promise<T>;
28
+ /** Launch without awaiting — the gate rows need two overlapping entries. */
29
+ post(method: string, ...args: readonly unknown[]): {
30
+ settled: Promise<unknown>;
31
+ };
32
+ }
33
+ export interface ConformanceHost {
34
+ readonly lane: LaneName;
35
+ readonly capabilities: ReadonlySet<Capability>;
36
+ spawn(name?: string): Promise<ProbeActor>;
37
+ /** Same identity, fresh instance. Durable state must survive. */
38
+ respawn(actor: ProbeActor): Promise<ProbeActor>;
39
+ /** Only where "real-crash". */
40
+ crash?(actor: ProbeActor): Promise<void>;
41
+ /** Only where "fake-time". */
42
+ time?: {
43
+ advance(ms: number): Promise<void>;
44
+ };
45
+ }
46
+ /**
47
+ * Substrate boundaries are ASSERTED, never skipped.
48
+ *
49
+ * Where the capability exists, run `native`. Where it does not, run `absent` —
50
+ * which asserts the exact named throwing-stub message. Under the fail-closed
51
+ * tenet the throw IS the specified behaviour for that lane, and asserting it is
52
+ * what stops the stubs regressing to the silent `[]` no-ops the design record
53
+ * orders replaced.
54
+ */
55
+ export declare function substrate(host: ConformanceHost, capability: Capability, branches: {
56
+ native: () => Promise<void>;
57
+ absent: () => Promise<void>;
58
+ }): Promise<void>;
@@ -0,0 +1,18 @@
1
+ //#region conformance/host.ts
2
+ /**
3
+ * Substrate boundaries are ASSERTED, never skipped.
4
+ *
5
+ * Where the capability exists, run `native`. Where it does not, run `absent` —
6
+ * which asserts the exact named throwing-stub message. Under the fail-closed
7
+ * tenet the throw IS the specified behaviour for that lane, and asserting it is
8
+ * what stops the stubs regressing to the silent `[]` no-ops the design record
9
+ * orders replaced.
10
+ */
11
+ async function substrate(host, capability, branches) {
12
+ if (host.capabilities.has(capability)) await branches.native();
13
+ else await branches.absent();
14
+ }
15
+ //#endregion
16
+ export { substrate };
17
+
18
+ //# sourceMappingURL=conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance.js","names":[],"sources":["../conformance/host.ts"],"sourcesContent":["/**\n * The conformance harness the suite writes against.\n *\n * The workerd lane is the ORACLE, not a third implementation — this package is\n * deliberately absent from it. So a test has exactly one meaning: \"workerd does\n * X\" and \"our runtime does X\" are the same assertion, executed twice.\n *\n * Probe classes are dependency-free (see fixtures/probe.ts), which is why the\n * workerd lane needs no vendored-source aliases and CI's filtered vendor\n * install never bites. Anything that would need vendored `think` or `agents`\n * to express is agent-logic testing and belongs in the extension's integration\n * lanes instead.\n */\n\nexport type Capability =\n /** Deterministic clock. Node lane only — a 30s ladder is not assertable on wall time. */\n | \"fake-time\"\n /** Kill without cleanup: worker.terminate() or dropping the container. */\n | \"real-crash\"\n /** Substrate boundary: no Chrome equivalent lifecycle. */\n | \"hibernation\"\n /** Substrate boundary: sqlite-wasm lacks the storage capability. */\n | \"bookmarks\";\n\nexport type LaneName = \"workerd\" | \"node\" | \"browser\";\n\nexport interface ProbeActor {\n /** Durable identity. `respawn` reopens this same actor. */\n readonly name: string;\n call<T = unknown>(method: string, ...args: readonly unknown[]): Promise<T>;\n /** Launch without awaiting — the gate rows need two overlapping entries. */\n post(method: string, ...args: readonly unknown[]): { settled: Promise<unknown> };\n}\n\nexport interface ConformanceHost {\n readonly lane: LaneName;\n readonly capabilities: ReadonlySet<Capability>;\n spawn(name?: string): Promise<ProbeActor>;\n /** Same identity, fresh instance. Durable state must survive. */\n respawn(actor: ProbeActor): Promise<ProbeActor>;\n /** Only where \"real-crash\". */\n crash?(actor: ProbeActor): Promise<void>;\n /** Only where \"fake-time\". */\n time?: { advance(ms: number): Promise<void> };\n}\n\n/**\n * Substrate boundaries are ASSERTED, never skipped.\n *\n * Where the capability exists, run `native`. Where it does not, run `absent` —\n * which asserts the exact named throwing-stub message. Under the fail-closed\n * tenet the throw IS the specified behaviour for that lane, and asserting it is\n * what stops the stubs regressing to the silent `[]` no-ops the design record\n * orders replaced.\n */\nexport async function substrate(\n host: ConformanceHost,\n capability: Capability,\n branches: { native: () => Promise<void>; absent: () => Promise<void> },\n): Promise<void> {\n if (host.capabilities.has(capability)) await branches.native();\n else await branches.absent();\n}\n"],"mappings":";;;;;;;;;;AAuDA,eAAsB,UACpB,MACA,YACA,UACe;CACf,IAAI,KAAK,aAAa,IAAI,UAAU,GAAG,MAAM,SAAS,OAAO;MACxD,MAAM,SAAS,OAAO;AAC7B"}