@kindgi/runtime 0.0.0-bootstrap.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +65 -1
  3. package/dist/bindings.d.ts +186 -0
  4. package/dist/bindings.d.ts.map +1 -0
  5. package/dist/bindings.js +4 -0
  6. package/dist/bindings.js.map +1 -0
  7. package/dist/derivation.d.ts +123 -0
  8. package/dist/derivation.d.ts.map +1 -0
  9. package/dist/derivation.js +249 -0
  10. package/dist/derivation.js.map +1 -0
  11. package/dist/errors.d.ts +78 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +4 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/event-bus.d.ts +41 -0
  16. package/dist/event-bus.d.ts.map +1 -0
  17. package/dist/event-bus.js +13 -0
  18. package/dist/event-bus.js.map +1 -0
  19. package/dist/index.d.ts +11 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +13 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/inputs.d.ts +160 -0
  24. package/dist/inputs.d.ts.map +1 -0
  25. package/dist/inputs.js +4 -0
  26. package/dist/inputs.js.map +1 -0
  27. package/dist/runs.d.ts +73 -0
  28. package/dist/runs.d.ts.map +1 -0
  29. package/dist/runs.js +4 -0
  30. package/dist/runs.js.map +1 -0
  31. package/dist/schedulers/registry.d.ts +142 -0
  32. package/dist/schedulers/registry.d.ts.map +1 -0
  33. package/dist/schedulers/registry.js +4 -0
  34. package/dist/schedulers/registry.js.map +1 -0
  35. package/dist/schedulers/types.d.ts +99 -0
  36. package/dist/schedulers/types.d.ts.map +1 -0
  37. package/dist/schedulers/types.js +4 -0
  38. package/dist/schedulers/types.js.map +1 -0
  39. package/dist/types.d.ts +317 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +6 -0
  42. package/dist/types.js.map +1 -0
  43. package/dist/versioning.d.ts +59 -0
  44. package/dist/versioning.d.ts.map +1 -0
  45. package/dist/versioning.js +89 -0
  46. package/dist/versioning.js.map +1 -0
  47. package/package.json +50 -4
  48. package/src/bindings.ts +244 -0
  49. package/src/derivation.ts +354 -0
  50. package/src/errors.ts +92 -0
  51. package/src/event-bus.ts +51 -0
  52. package/src/index.ts +13 -0
  53. package/src/inputs.ts +169 -0
  54. package/src/runs.ts +84 -0
  55. package/src/schedulers/registry.ts +197 -0
  56. package/src/schedulers/types.ts +112 -0
  57. package/src/types.ts +378 -0
  58. package/src/versioning.ts +110 -0
package/src/types.ts ADDED
@@ -0,0 +1,378 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { LoopContext } from '@kindgi/handler';
5
+ import type { NodeId, ProjectId, RunId, TenantId, Timestamp } from '@kindgi/types';
6
+
7
+ /** Terminal states are `completed`, `failed`, `cancelled`. */
8
+ export type RunStatus = 'pending' | 'running' | 'suspended' | 'completed' | 'failed' | 'cancelled';
9
+
10
+ export interface RunResult<TOutput = unknown> {
11
+ readonly runId: RunId;
12
+ readonly status: RunStatus;
13
+ /**
14
+ * For completed runs: the flow's declared output (`Flow.output`) when the
15
+ * flow has one; otherwise the output of the node whose edge reached
16
+ * `$end`. When multiple `$end`-terminating edges fire, one is picked
17
+ * deterministically (lowest edge id in traversal order).
18
+ */
19
+ readonly output?: TOutput;
20
+ readonly failureMessage?: string;
21
+ /** Free-form projectId echoed back if the run was bound to one. */
22
+ readonly projectId?: ProjectId;
23
+ readonly tenantId: TenantId;
24
+ }
25
+
26
+ /** Kernel journal entry kinds. */
27
+ export type JournalKind =
28
+ | 'run.started'
29
+ | 'step.started'
30
+ | 'step.completed'
31
+ | 'step.failed'
32
+ | 'step.retry-scheduled'
33
+ | 'step.concurrency-deferred'
34
+ | 'edge.evaluated'
35
+ | 'iteration.started'
36
+ | 'iteration.completed'
37
+ | 'fanout.dispatched'
38
+ | 'fanout.branch-completed'
39
+ | 'fanout.branch-failed'
40
+ | 'fanout.converged'
41
+ | 'fanout.cancelled-siblings'
42
+ | 'subgraph.dispatched'
43
+ | 'subgraph.completed'
44
+ | 'subgraph.failed'
45
+ | 'subgraph.cancelled'
46
+ | 'run.completed'
47
+ | 'run.failed'
48
+ | 'run.cancelled'
49
+ | 'wait.suspended'
50
+ | 'wait.resumed'
51
+ | 'wait.cancelled'
52
+ | 'clock.read';
53
+
54
+ /**
55
+ * Journal payload for `step.retry-scheduled`. Emitted when a node handler
56
+ * fails but the destination's sole incoming edge carries a `retry` policy
57
+ * with attempts remaining. The executor waits `nextDelayMs` (subject to the
58
+ * backoff shape) then re-dispatches the node.
59
+ *
60
+ * `attempt` is 1-based: `1` means the first retry (following the initial
61
+ * failure), `2` the second, etc. The number of `step.retry-scheduled`
62
+ * entries for a given node is the attempt count at derivation time.
63
+ */
64
+ export interface StepRetryScheduledPayload {
65
+ readonly nodeId: NodeId;
66
+ readonly attempt: number;
67
+ readonly nextDelayMs: number;
68
+ readonly previousError: string;
69
+ }
70
+
71
+ /**
72
+ * Journal payload for `step.concurrency-deferred`. Emitted when the
73
+ * dispatcher attempts to acquire a `policy.concurrencyKey` lease for a
74
+ * ready node and the lease is already held. The node stays in the ready
75
+ * set (from the scheduler's POV) but is deferred for the current tick;
76
+ * on the next tick, after the current holder releases, one waiter
77
+ * acquires and dispatches.
78
+ *
79
+ * `holderRunId` + `holderNodeId` attribute the current holder so an
80
+ * operator can debug "why is my node stuck?" without looking up other runs.
81
+ * `holderRunId` may equal the deferred node's run (self-contention) or a
82
+ * different run in the same tenant.
83
+ *
84
+ * Multiple `step.concurrency-deferred` entries for the same node are
85
+ * expected under long-held leases — derivation records only that the
86
+ * node is in the deferred bucket, not the count.
87
+ */
88
+ export interface StepConcurrencyDeferredPayload {
89
+ readonly nodeId: NodeId;
90
+ readonly concurrencyKey: string;
91
+ readonly holderRunId: RunId;
92
+ readonly holderNodeId: NodeId;
93
+ }
94
+
95
+ /**
96
+ * Journal payload doc shape for `iteration.started`.
97
+ *
98
+ * `bodyExecuted` is `false` only when a `while` loop with
99
+ * `evaluationTiming: 'before'` short-circuits its exit check before the
100
+ * body runs — in that case `exitConditionResult` is populated on
101
+ * `iteration.started` (and `iteration.completed` isn't emitted for the
102
+ * skipped iteration).
103
+ */
104
+ export interface IterationStartedPayload {
105
+ readonly iteration: number;
106
+ readonly bodyExecuted: boolean;
107
+ readonly exitConditionResult?: boolean | undefined;
108
+ readonly loopContext?: LoopContext | undefined;
109
+ }
110
+
111
+ /**
112
+ * Journal payload doc shape for `iteration.completed`.
113
+ *
114
+ * `outputSchemaValid` records whether the iteration's `$loop-end` output
115
+ * validated against the loop's `outputSchema`. On failure, `stopReason`
116
+ * is `'output-schema-violation'` and `schemaErrors` is populated.
117
+ *
118
+ * For `while` loops with `evaluationTiming: 'after'`, `exitConditionResult`
119
+ * is populated. For `while+before`, the check happens on the NEXT
120
+ * iteration's `iteration.started` and is absent here. For `foreach`, no
121
+ * exit condition — absent.
122
+ *
123
+ * `stopReason` is only populated on the FINAL iteration (the one that
124
+ * caused the loop to exit). Intermediate iterations have it as undefined.
125
+ */
126
+ export interface IterationCompletedPayload {
127
+ readonly iteration: number;
128
+ readonly output: unknown;
129
+ readonly outputSchemaValid: boolean;
130
+ readonly schemaErrors?: readonly unknown[] | undefined;
131
+ readonly exitConditionResult?: boolean | undefined;
132
+ readonly stopReason?:
133
+ | 'exit-condition'
134
+ | 'max-iterations'
135
+ | 'array-exhausted'
136
+ | 'output-schema-violation'
137
+ | 'body-failure'
138
+ | 'cancelled'
139
+ | 'iterate-over-not-array'
140
+ | undefined;
141
+ readonly loopContext?: LoopContext | undefined;
142
+ }
143
+
144
+ /**
145
+ * Journal payload for `fanout.dispatched`. Emitted once per branch, before
146
+ * the branch handler is invoked. `input` is the same value every branch of
147
+ * the fanout receives (the fanout node's own resolved input).
148
+ */
149
+ export interface FanoutDispatchedPayload {
150
+ readonly fanoutNodeId: NodeId;
151
+ readonly branchId: string;
152
+ readonly handler: string;
153
+ readonly input: unknown;
154
+ }
155
+
156
+ /**
157
+ * Journal payload for `fanout.branch-completed`. Emitted when a branch's
158
+ * handler returns AND the resulting output validates against the branch's
159
+ * declared `outputSchema`.
160
+ */
161
+ export interface FanoutBranchCompletedPayload {
162
+ readonly fanoutNodeId: NodeId;
163
+ readonly branchId: string;
164
+ readonly output: unknown;
165
+ }
166
+
167
+ /**
168
+ * Journal payload for `fanout.branch-failed`. Emitted when a branch fails.
169
+ * `reason` narrows the failure attribution so consumers do not have to
170
+ * match on the message. `schemaErrors` is populated when
171
+ * `reason === 'output-schema-violation'`.
172
+ */
173
+ export interface FanoutBranchFailedPayload {
174
+ readonly fanoutNodeId: NodeId;
175
+ readonly branchId: string;
176
+ readonly message: string;
177
+ readonly reason: 'handler-throw' | 'output-schema-violation' | 'cancelled';
178
+ readonly schemaErrors?: readonly unknown[];
179
+ }
180
+
181
+ /**
182
+ * Journal payload for `fanout.converged`. Emitted once, after the fanout
183
+ * finalizes on a successful convergence. Carries the fan-in-shaped output
184
+ * that will be handed to downstream consumers via `nodeOutputs`.
185
+ */
186
+ export interface FanoutConvergedPayload {
187
+ readonly fanoutNodeId: NodeId;
188
+ readonly convergence: 'all-succeed' | 'any-succeed' | 'settle-all';
189
+ readonly output: unknown;
190
+ }
191
+
192
+ /**
193
+ * Journal payload for `fanout.cancelled-siblings`. Emitted once, when the
194
+ * convergence mode short-circuits (all-succeed on first failure OR
195
+ * any-succeed on first success) and in-flight sibling branches are
196
+ * cancelled. `reason` records which convergence trigger fired;
197
+ * `cancelledBranchIds` enumerates every branch that received the abort
198
+ * signal (whether or not it had already settled — the journal captures
199
+ * intent).
200
+ */
201
+ export interface FanoutCancelledSiblingsPayload {
202
+ readonly fanoutNodeId: NodeId;
203
+ readonly cancelledBranchIds: readonly string[];
204
+ readonly reason: 'first-failure' | 'first-success';
205
+ }
206
+
207
+ /**
208
+ * Fan-in shape emitted by a fanout node whose convergence mode is
209
+ * `'all-succeed'`. Object keyed by every branchId, mapping to that
210
+ * branch's validated output.
211
+ */
212
+ export interface FanoutAllSucceedOutput {
213
+ readonly [branchId: string]: unknown;
214
+ }
215
+
216
+ /**
217
+ * Fan-in shape emitted by a fanout node whose convergence mode is
218
+ * `'any-succeed'`. Records the identity of the winning branch and its
219
+ * validated output. In-flight siblings were cancelled and do not appear.
220
+ */
221
+ export interface FanoutAnySucceedOutput {
222
+ readonly winnerBranchId: string;
223
+ readonly output: unknown;
224
+ }
225
+
226
+ /**
227
+ * Per-branch outcome inside a `'settle-all'` fan-in output. `status` is
228
+ * `'succeeded'` when the branch handler returned a schema-valid output
229
+ * (present in `output`), `'failed'` when the branch failed (handler
230
+ * threw OR output schema violation, message in `error`).
231
+ */
232
+ export interface FanoutSettleAllBranchOutcome {
233
+ readonly status: 'succeeded' | 'failed';
234
+ readonly output?: unknown;
235
+ readonly error?: string;
236
+ }
237
+
238
+ /**
239
+ * Fan-in shape emitted by a fanout node whose convergence mode is
240
+ * `'settle-all'`. Object keyed by every branchId, mapping to that
241
+ * branch's terminal outcome.
242
+ */
243
+ export interface FanoutSettleAllOutput {
244
+ readonly [branchId: string]: FanoutSettleAllBranchOutcome;
245
+ }
246
+
247
+ /**
248
+ * Journal payload for `subgraph.dispatched`. Emitted before the child
249
+ * kernel run is started, so restarts observe consistent parent-journal
250
+ * state. Carries the child `runId` so replay can resolve back to the
251
+ * exact sub-run (rather than re-dispatching a fresh one).
252
+ */
253
+ export interface SubflowDispatchedPayload {
254
+ readonly subgraphNodeId: NodeId;
255
+ readonly subRunId: RunId;
256
+ readonly flowRef: { readonly flowId: string; readonly version: string };
257
+ readonly subInput: unknown;
258
+ readonly depth: number;
259
+ }
260
+
261
+ /**
262
+ * Journal payload for `subgraph.completed`. Emitted when the child kernel
263
+ * run reaches `status: 'completed'` AND its terminal output validates
264
+ * against the parent's declared `outputSchema`. `validatedOutput` is the
265
+ * schema-valid value; the parent node's own `step.completed` follows,
266
+ * with an output shape decided by the parent's `convergence` mode.
267
+ */
268
+ export interface SubflowCompletedPayload {
269
+ readonly subgraphNodeId: NodeId;
270
+ readonly subRunId: RunId;
271
+ readonly output: unknown;
272
+ }
273
+
274
+ /**
275
+ * Journal payload for `subgraph.failed`. Emitted when the child run
276
+ * failed OR its terminal output failed schema validation. Attribution:
277
+ * - `child-failed` → child kernel run terminated with `failed` status.
278
+ * - `output-schema-violation` → child completed but its output did not
279
+ * match the parent's declared `outputSchema`.
280
+ * - `subgraph-flow-not-found` → resolver returned null at dispatch.
281
+ * - `subgraph-depth-exceeded` → parent's `RunOptions.maxSubflowDepth`
282
+ * was hit at dispatch.
283
+ * - `subgraph-cross-tenant` → attempted lookup of a flow registered
284
+ * under a different tenant (reserved — cannot happen with the current
285
+ * resolver contract but journaled defensively).
286
+ * - `resolver-missing` → the run was started without a `flowResolver`
287
+ * dependency wired in, so the subgraph node cannot dispatch.
288
+ */
289
+ export interface SubflowFailedPayload {
290
+ readonly subgraphNodeId: NodeId;
291
+ readonly subRunId?: RunId;
292
+ readonly flowRef?: { readonly flowId: string; readonly version: string };
293
+ readonly reason:
294
+ | 'child-failed'
295
+ | 'output-schema-violation'
296
+ | 'subgraph-flow-not-found'
297
+ | 'subgraph-depth-exceeded'
298
+ | 'subgraph-cross-tenant'
299
+ | 'resolver-missing';
300
+ readonly message: string;
301
+ readonly schemaErrors?: readonly unknown[];
302
+ }
303
+
304
+ /**
305
+ * Journal payload for `subgraph.cancelled`. Emitted when the parent run is
306
+ * being torn down (external `cancelRun`) OR when a sibling handler failed
307
+ * and the composed abort signal cascades to the child. Under `settle-all`
308
+ * convergence, the parent step still transitions to `step.completed` with
309
+ * an `error` envelope; under `success-only`, the parent step transitions
310
+ * to `step.failed`.
311
+ */
312
+ export interface SubflowCancelledPayload {
313
+ readonly subgraphNodeId: NodeId;
314
+ readonly subRunId: RunId;
315
+ readonly stopReason: 'cancelled';
316
+ }
317
+
318
+ /**
319
+ * Fan-in shape emitted by a `subgraph` node whose convergence mode is
320
+ * `'success-only'`. When the child run succeeded and its output
321
+ * validated, the parent node's output IS the validated child output.
322
+ * No wrapping envelope. When the child fails, the parent step
323
+ * transitions to `step.failed` (no output written).
324
+ */
325
+ export type SubflowSuccessOnlyOutput = unknown;
326
+
327
+ /**
328
+ * Fan-in shape emitted by a `subgraph` node whose convergence mode is
329
+ * `'settle-all'`. Always a settled envelope: on success the `output`
330
+ * carries the schema-valid child output; on failure the `error` names
331
+ * the attribution.
332
+ */
333
+ export interface SubflowSettleAllOutput {
334
+ readonly status: 'succeeded' | 'failed';
335
+ readonly output?: unknown;
336
+ readonly error?: string;
337
+ }
338
+
339
+ export interface JournalEntry {
340
+ readonly sequence: number;
341
+ readonly kind: JournalKind;
342
+ readonly nodeId?: NodeId;
343
+ readonly payload?: unknown;
344
+ readonly timestamp: Timestamp;
345
+ }
346
+
347
+ /** Kernel run-configuration knobs. */
348
+ export interface RunOptions {
349
+ /**
350
+ * Maximum number of node handlers dispatched concurrently in a single
351
+ * tick. Prevents accidental self-DoS on downstream systems from wide
352
+ * fan-outs. Default: 8.
353
+ */
354
+ readonly maxParallelism?: number;
355
+ /**
356
+ * When `true`, the run executes in dry-run mode: `NodeContext.dryRun`
357
+ * is exposed to every handler so they can self-mock side-effecting
358
+ * calls (tool invocation, model calls, DB writes). The run record is
359
+ * marked `dryRun: true` (`KernelRunRecord.dryRun`); the journal shape is
360
+ * unchanged. Consumers (the client's `runs.dryRun`, cost estimators,
361
+ * plan viewers) filter on that flag. Default: `false`.
362
+ */
363
+ readonly dryRun?: boolean;
364
+ /**
365
+ * Maximum sub-flow invocation depth. A parent run at depth 0 that
366
+ * dispatches a `subgraph` node produces a child at depth 1; the child
367
+ * dispatching its own subgraph node produces a grandchild at depth 2;
368
+ * and so on. Exceeding this cap fails the subgraph node at dispatch
369
+ * with `subgraph-depth-exceeded`. Default: 10. Configured on the
370
+ * outermost `RunBinding.runGraph` call — children inherit the same cap.
371
+ */
372
+ readonly maxSubflowDepth?: number;
373
+ }
374
+
375
+ export const DEFAULT_MAX_PARALLELISM = 8;
376
+
377
+ /** Default cap on nested sub-flow depth. See `RunOptions.maxSubflowDepth`. */
378
+ export const DEFAULT_MAX_SUBGRAPH_DEPTH = 10;
@@ -0,0 +1,110 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { Result } from '@kindgi/types';
5
+
6
+ /**
7
+ * Payload versioning for the documents the runtime stores (journal
8
+ * payloads, run input / output, …).
9
+ *
10
+ * Every stored payload is a nested envelope `{ v: 1, doc: <content> }`.
11
+ * Wrapping under a dedicated `doc` key means the envelope's version
12
+ * marker cannot collide with any user field named `version`,
13
+ * `schemaVersion`, etc. Readers switch on `v` and return the inner `doc`,
14
+ * so consumer code sees the same content shape as if no envelope
15
+ * existed.
16
+ *
17
+ * Newer versions than this reader knows about are a hard error — a
18
+ * writer/reader skew would silently drop v2 data otherwise. No implicit
19
+ * versioning: every payload must carry an explicit envelope.
20
+ */
21
+
22
+ export const CURRENT_KERNEL_PAYLOAD_VERSION = 1;
23
+
24
+ /** Discriminated error surfaced when a stored payload's version exceeds the reader's. */
25
+ export interface UnsupportedPayloadVersionError {
26
+ readonly code: 'unsupported-payload-version';
27
+ readonly message: string;
28
+ readonly version: number;
29
+ readonly currentVersion: number;
30
+ }
31
+
32
+ /** Emitted when a stored payload lacks the envelope entirely. */
33
+ export interface MalformedEnvelopeError {
34
+ readonly code: 'malformed-envelope';
35
+ readonly message: string;
36
+ }
37
+
38
+ export type EnvelopeError = UnsupportedPayloadVersionError | MalformedEnvelopeError;
39
+
40
+ /**
41
+ * Thrown by `*OrThrow` helpers when a stored payload can't be unwrapped.
42
+ * Catch at the operation boundary (e.g. `readJournal`) and surface
43
+ * as a KernelError.
44
+ */
45
+ export class EnvelopeThrown extends Error {
46
+ readonly error: EnvelopeError;
47
+ constructor(error: EnvelopeError) {
48
+ super(error.message);
49
+ this.error = error;
50
+ this.name = 'EnvelopeThrown';
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Wrap any value in the current-version envelope. The stored payload is
56
+ * always `{ v: 1, doc: value }` regardless of whether `value` is an
57
+ * object, array, primitive, or null.
58
+ */
59
+ export function wrap<T>(value: T): { readonly v: number; readonly doc: T } {
60
+ return { v: CURRENT_KERNEL_PAYLOAD_VERSION, doc: value };
61
+ }
62
+
63
+ /**
64
+ * Unwrap a stored envelope and return the inner document. Handles:
65
+ * - null / undefined: returned as-is (nothing was stored).
66
+ * - `{ v: 1, doc: X }`: returns `X`.
67
+ * - `{ v: N, doc: X }` with any other numeric N:
68
+ * `unsupported-payload-version` error.
69
+ * - Anything else: `malformed-envelope` error.
70
+ */
71
+ export function unwrap<T = unknown>(raw: unknown): Result<T | null | undefined, EnvelopeError> {
72
+ if (raw === null || raw === undefined) return { kind: 'ok', value: raw };
73
+ if (typeof raw !== 'object' || Array.isArray(raw)) {
74
+ return {
75
+ kind: 'err',
76
+ error: {
77
+ code: 'malformed-envelope',
78
+ message: `Expected { v, doc } envelope, got ${typeof raw === 'object' ? 'array' : typeof raw}`,
79
+ },
80
+ };
81
+ }
82
+ const envelope = raw as { readonly v?: unknown; readonly doc?: unknown };
83
+ if (typeof envelope.v !== 'number' || !('doc' in envelope)) {
84
+ return {
85
+ kind: 'err',
86
+ error: {
87
+ code: 'malformed-envelope',
88
+ message: 'Payload is missing v or doc field',
89
+ },
90
+ };
91
+ }
92
+ if (envelope.v === CURRENT_KERNEL_PAYLOAD_VERSION) {
93
+ return { kind: 'ok', value: envelope.doc as T };
94
+ }
95
+ return {
96
+ kind: 'err',
97
+ error: {
98
+ code: 'unsupported-payload-version',
99
+ message: `Unsupported payload version ${envelope.v} (this reader handles version ${CURRENT_KERNEL_PAYLOAD_VERSION})`,
100
+ version: envelope.v,
101
+ currentVersion: CURRENT_KERNEL_PAYLOAD_VERSION,
102
+ },
103
+ };
104
+ }
105
+
106
+ export function unwrapOrThrow<T = unknown>(raw: unknown): T | null | undefined {
107
+ const r = unwrap<T>(raw);
108
+ if (r.kind === 'err') throw new EnvelopeThrown(r.error);
109
+ return r.value;
110
+ }