fyflow-orchestration 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1800 -200
- package/README.md +88 -104
- package/dist/browser/chunks/{chunk-YVOP3DIN.js → chunk-EUU44PHD.js} +2104 -283
- package/dist/browser/index.js +19 -9
- package/dist/browser/scheduler/index.js +101 -58
- package/dist/node/chunks/{chunk-YVOP3DIN.js → chunk-EUU44PHD.js} +2104 -283
- package/dist/node/index.js +19 -9
- package/dist/node/scheduler/index.js +101 -58
- package/dist/types/src/definition/assist.d.ts +29 -5
- package/dist/types/src/definition/condition.d.ts +49 -0
- package/dist/types/src/definition/regions.d.ts +12 -1
- package/dist/types/src/definition/registry.d.ts +52 -10
- package/dist/types/src/definition/schema.d.ts +20 -8
- package/dist/types/src/definition/types.d.ts +152 -23
- package/dist/types/src/definition/validate.d.ts +68 -20
- package/dist/types/src/definition/wiring.d.ts +58 -10
- package/dist/types/src/definition/witness.d.ts +12 -4
- package/dist/types/src/driver/driver.d.ts +772 -40
- package/dist/types/src/driver/listener.d.ts +7 -1
- package/dist/types/src/driver/log.d.ts +20 -5
- package/dist/types/src/driver/routing.d.ts +10 -5
- package/dist/types/src/fold/policies.d.ts +4 -5
- package/dist/types/src/fold/run-state.d.ts +245 -14
- package/dist/types/src/scheduler/bootstrap.d.ts +18 -26
- package/dist/types/src/scheduler/envelope-worker.d.ts +6 -5
- package/dist/types/src/scheduler/index.d.ts +2 -2
- package/dist/types/src/scheduler/runtime.d.ts +105 -32
- package/package.json +3 -3
|
@@ -6,6 +6,11 @@ export interface TaskDetailLike {
|
|
|
6
6
|
result?: unknown;
|
|
7
7
|
error?: string;
|
|
8
8
|
attempts?: number;
|
|
9
|
+
/**
|
|
10
|
+
* The scheduler's 1-based number of the attempt, read on `task.running` ONLY — `RN-R40`, W186, by the driver while its
|
|
11
|
+
* listener runs. Never on a record: the record's `attempts` is the scheduler's count (`OR-R4`, P36 (i)).
|
|
12
|
+
*/
|
|
13
|
+
attemptNumber?: number;
|
|
9
14
|
timestamp?: number;
|
|
10
15
|
startTime?: number;
|
|
11
16
|
endTime?: number;
|
|
@@ -15,7 +20,7 @@ export interface TaskDetailLike {
|
|
|
15
20
|
* `OR-R6`'s refusal. **It sets its own `name`**, as `BoundaryRefused` and `ResumeRefused` do, so the
|
|
16
21
|
* error's own render — `String(e)`, a stack's first line — reads `UncloneableResult: <message>`. Since
|
|
17
22
|
* W133 the MESSAGE no longer carries the class name (Q63), and without this the error itself would
|
|
18
|
-
* say `Error:` everywhere but `RunFailure.kind` and `
|
|
23
|
+
* say `Error:` everywhere but `RunFailure.kind` and `haltedBy`.
|
|
19
24
|
*/
|
|
20
25
|
export declare class UncloneableResult extends Error {
|
|
21
26
|
constructor(message?: string, options?: ErrorOptions);
|
|
@@ -29,6 +34,7 @@ export declare class UncloneableResult extends Error {
|
|
|
29
34
|
* done task.completed -> 1 record
|
|
30
35
|
* failed (optional task) task.failed -> 1 record
|
|
31
36
|
* user_action task.failed, task.user_action -> 1 record, on the SECOND
|
|
37
|
+
* cancelled task.cancelled -> 1 record (ADR 0094)
|
|
32
38
|
*
|
|
33
39
|
* The third row is why this exists. `task.failed` fires for a task that did not
|
|
34
40
|
* fail, its detail already reads `state: 'user_action'`, and a driver keying on
|
|
@@ -15,7 +15,12 @@ export interface OutcomeRecord {
|
|
|
15
15
|
result: CloneableValue | null;
|
|
16
16
|
error: string | null;
|
|
17
17
|
attempts: number;
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* The scheduler's stamp — and **`null` for an ASK's effective outcome** (`spec/outcome-record.md` v0.18, P35 (e),
|
|
20
|
+
* [ADR 0109](../../doc/decisions/0109-an-ask-parks-with-nothing-dispatched-and-its-answer-is-its-result.md)): no
|
|
21
|
+
* scheduler was involved. A SETTLEMENT always carries a number. **BREAKING in 0.8.0** for a consumer typed on `number`.
|
|
22
|
+
*/
|
|
23
|
+
schedulerTimestamp: number | null;
|
|
19
24
|
observedAt: number;
|
|
20
25
|
startTime: number | null;
|
|
21
26
|
endTime: number | null;
|
|
@@ -39,8 +44,14 @@ export type LogRecord = OutcomeRecord | ResolutionRecord;
|
|
|
39
44
|
* second resolution refusable.
|
|
40
45
|
*/
|
|
41
46
|
export declare function lastRecordFor(log: readonly LogRecord[], taskId: string): LogRecord | undefined;
|
|
42
|
-
/**
|
|
43
|
-
|
|
47
|
+
/**
|
|
48
|
+
* `RS-R1` — a task is suspended when its last record is an outcome in `user_action`; **or, since v0.18, when it was
|
|
49
|
+
* ASKED and has no record at all** (P35 (b), ADR 0109): an ask parks with an `asked` fold input — not a log record,
|
|
50
|
+
* since section 1 fixes the log at two kinds — and the person's answer is the first record its id ever gets, so a
|
|
51
|
+
* second answer is refused as a second resolution is. `asked` is the caller's: whether the fold-input sequence holds an
|
|
52
|
+
* `asked` element for the id, which this function cannot see.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isSuspended(log: readonly LogRecord[], taskId: string, asked?: boolean): boolean;
|
|
44
55
|
/**
|
|
45
56
|
* `spec/outcome-record.md` section 6 — the record ROUTING reads, which is never
|
|
46
57
|
* the log directly.
|
|
@@ -52,8 +63,12 @@ export declare function isSuspended(log: readonly LogRecord[], taskId: string):
|
|
|
52
63
|
* `OR-R8`: derived, never appended. Appending it would make the log contain its
|
|
53
64
|
* own conclusions, and a second fold would derive a third record from the second.
|
|
54
65
|
*
|
|
66
|
+
* **An ASK's** — a resolution with NO settlement before it, which `RS-R1` admits only for an asked task — is DERIVED
|
|
67
|
+
* from the resolution alone (`spec/outcome-record.md` section 7, v0.18, P35 (e), ADR 0109): the answer is the node's
|
|
68
|
+
* result, `attempts` `0` and every scheduler field `null`, because no dispatch happened for those fields to describe.
|
|
69
|
+
*
|
|
55
70
|
* @returns `null` when the task has not settled, or has settled `user_action` and
|
|
56
|
-
* has no resolution — a suspended node has no
|
|
57
|
-
* exactly right: it has not finished and nothing routes.
|
|
71
|
+
* has no resolution, or was asked and has no answer — a suspended node has no
|
|
72
|
+
* effective outcome, which is exactly right: it has not finished and nothing routes.
|
|
58
73
|
*/
|
|
59
74
|
export declare function effectiveOutcome(log: readonly LogRecord[], taskId: string): OutcomeRecord | null;
|
|
@@ -21,12 +21,16 @@ import type { OutcomeRecord } from './log.js';
|
|
|
21
21
|
export interface DecisionContext {
|
|
22
22
|
/**
|
|
23
23
|
* `OR-R9` — ALWAYS the node's effective outcome, so a predicate sees one shape
|
|
24
|
-
* whether the node settled or was resolved, and `terminalState` is never undefined.
|
|
24
|
+
* whether the node settled or was resolved, and `terminalState` is never undefined. **For an ASK it is derived from
|
|
25
|
+
* the person's answer** (`spec/outcome-record.md` section 7, v0.18): `result` the answer, `attempts` `0`, and
|
|
26
|
+
* `schedulerTimestamp` and the timing fields `null` — no scheduler was involved.
|
|
25
27
|
*/
|
|
26
28
|
outcome: OutcomeRecord;
|
|
27
29
|
/**
|
|
28
30
|
* **What this EDGE declared it needs** — the object its `needs` describes, resolved
|
|
29
|
-
* against the run's own outputs exactly as a node's is (`FD-C1`, `FD-C2`)
|
|
31
|
+
* against the run's own outputs exactly as a node's is (`FD-C1`, `FD-C2`) — and, since
|
|
32
|
+
* v0.44, against the value the RUN entered with, for a `"$payload"` key (`FD-C3`,
|
|
33
|
+
* ADR 0117): so a predicate routes on `needs.run.amount` with no task before it.
|
|
30
34
|
*
|
|
31
35
|
* **`{}` when the edge declares none, never `undefined`**, for rule 4's own reason
|
|
32
36
|
* one level out: *a predicate written `ctx.needs.flag` must mean one thing*, and a
|
|
@@ -58,9 +62,10 @@ export declare function eligibleEdges(node: FlowNode, terminalState: TerminalSta
|
|
|
58
62
|
* **The ONE edge a gate takes for a route** — `spec/flow-definition.md` section 2's gate,
|
|
59
63
|
* [ADR 0066](../../doc/decisions/0066-a-gate-is-a-decision-with-memory-that-names-a-registered-type-and-wires-every-route-exactly-once.md)
|
|
60
64
|
* rule 4, [W93](../../doc/work-items/w93-what-a-gate-does-in-a-run.md). An edge carries the route it names,
|
|
61
|
-
* and **an edge with no `route` carries the
|
|
62
|
-
*
|
|
63
|
-
* `
|
|
65
|
+
* and **an edge with no `route` carries the gate's DEFAULT route** — never every route, and not the first.
|
|
66
|
+
* `defaultRoute` is the GATE's resolved set's (`routesOf`, ADR 0092 rule 3), never read off the type here.
|
|
67
|
+
* Pure, as `selectEdge` is: the caller has already held `route` to the gate's resolved routes (`FD-R5`), and
|
|
68
|
+
* `FD-V41` wires every route of that set by exactly one edge, so this is total over what reaches it — `null` is
|
|
64
69
|
* the assertion that `FD-V41` held, and the driver stops the run on it rather than routing nowhere.
|
|
65
70
|
*/
|
|
66
71
|
export declare function gateEdge(node: GateNode, defaultRoute: string, route: string): Edge | null;
|
|
@@ -91,11 +91,10 @@ export interface ArrivalCountState {
|
|
|
91
91
|
* That rule's own section says *"`arrival-count` is immune, because its `N` comes
|
|
92
92
|
* from `region.branches.length` at `open`"* — true until this change and false
|
|
93
93
|
* after it. Every `branch.opened` for a region precedes any other event for it, so
|
|
94
|
-
* `need` is final before any arrival can be counted against it.
|
|
95
|
-
*
|
|
96
|
-
* `
|
|
97
|
-
*
|
|
98
|
-
* policies rather than one.
|
|
94
|
+
* `need` is final before any arrival can be counted against it. *(This read "the clause remains unfalsifiable through
|
|
95
|
+
* a conformant driver" until W180: since `spec/flow-definition.md` v0.42 a branch entry or a map's branch may be an
|
|
96
|
+
* `ask`, which EMITS on entry, so the clause's guarantor is the driver's two-pass emission — `spec/join-policy.md`
|
|
97
|
+
* v0.23.)* What RESTS on it is now both counting policies rather than one.
|
|
99
98
|
*/
|
|
100
99
|
export declare const arrivalCount: JoinPolicy<ArrivalCountState>;
|
|
101
100
|
export interface LiveTokenState {
|
|
@@ -10,14 +10,19 @@
|
|
|
10
10
|
import type { LogRecord, OutcomeRecord } from '../driver/log.js';
|
|
11
11
|
import type { RegionEvent } from '../driver/events.js';
|
|
12
12
|
/**
|
|
13
|
-
* `spec/run-state.md` section 4.
|
|
13
|
+
* `spec/run-state.md` section 4. Five, not the scheduler's six.
|
|
14
14
|
*
|
|
15
15
|
* `user_action` is `suspended` here — it is not terminal at flow level. And there
|
|
16
16
|
* is **no `pending`**: `OR-R4` says `task.running` writes no record, so the only
|
|
17
17
|
* signal the fold has is the dispatch itself, and a task is `running` from that
|
|
18
|
-
* moment. A state nothing can produce is not a state.
|
|
18
|
+
* moment. A state nothing can produce is not a state. *(Since v0.26 `task.running` produces a FOLD INPUT, `attempted`
|
|
19
|
+
* (`RN-R40`, W186) — still no record, and it moves no state: a task is `running` from its dispatch either way.)*
|
|
20
|
+
*
|
|
21
|
+
* **`cancelled` is W158's** ([ADR 0094](../../doc/decisions/0094-a-cancelled-task-is-a-terminal-state-that-routes-no-edge-and-ends-its-run-cancelled.md)),
|
|
22
|
+
* copied verbatim from the settlement as `done` and `failed` are. **Widening this union is BREAKING for a
|
|
23
|
+
* consumer switching on it exhaustively** — `resumed`'s and `gated`'s precedent.
|
|
19
24
|
*/
|
|
20
|
-
export type NodeState = 'running' | 'done' | 'failed' | 'suspended';
|
|
25
|
+
export type NodeState = 'running' | 'done' | 'failed' | 'suspended' | 'cancelled';
|
|
21
26
|
/**
|
|
22
27
|
* `spec/run-state.md` section 3. Closed, and ours — an author labels why a path
|
|
23
28
|
* ended, not what the run is.
|
|
@@ -26,17 +31,93 @@ export type NodeState = 'running' | 'done' | 'failed' | 'suspended';
|
|
|
26
31
|
* [ADR 0015](../../doc/decisions/0015-a-run-whose-join-can-no-longer-fire-is-stuck.md):
|
|
27
32
|
* nothing is live, nothing waits on a person, and a region's join has not fired,
|
|
28
33
|
* so nothing will ever move again. v0.2 called that run **`completed`**.
|
|
34
|
+
*
|
|
35
|
+
* **`cancelled` is v0.15's seventh**, added by W158 under
|
|
36
|
+
* [ADR 0094](../../doc/decisions/0094-a-cancelled-task-is-a-terminal-state-that-routes-no-edge-and-ends-its-run-cancelled.md):
|
|
37
|
+
* a task of the run settled `cancelled`, so the driver halted it (`RN-R28`). **Widening this union is BREAKING
|
|
38
|
+
* for a consumer switching on it exhaustively** — `resumed`'s and `gated`'s precedent; a consumer comparing
|
|
39
|
+
* strings sees a value it never named, and `isTerminal` already calls it terminal.
|
|
40
|
+
*
|
|
41
|
+
* **`halted` is v0.16's NAME for the outcome 0.7.0 called `stopped`** — W171,
|
|
42
|
+
* [ADR 0102](../../doc/decisions/0102-a-run-the-driver-halts-is-halted-and-a-stored-stopped-reads-as-one.md), P34
|
|
43
|
+
* decision 2 and stop-and-ask (f): a refusal terminated the run (`OR-R10`, `RN-R8`). *Stop* is P34's resumable stop
|
|
44
|
+
* of a run (W174), so the old name leaves this union ENTIRELY: **BREAKING**, and loudly — a consumer's
|
|
45
|
+
* `outcome === 'stopped'` no longer compiles, rather than silently changing what it means. The count does not move.
|
|
46
|
+
*
|
|
47
|
+
* **`cancelling` is v0.18's EIGHTH**, added by W173 under
|
|
48
|
+
* [ADR 0104](../../doc/decisions/0104-a-run-its-owner-cancels-is-cancelling-until-its-last-task-has-stopped.md): the
|
|
49
|
+
* run's OWNER cancelled it (`driver.cancel`, a `cancelRequested` element) and a task is still stopping (`RN-R30`).
|
|
50
|
+
* **NOT terminal** — the third outcome {@link isTerminal} calls unfinished — so a runtime's `done` waits for the last
|
|
51
|
+
* task to stop. **BREAKING in 0.8.0** (P34 decision 10): a consumer switching on it exhaustively, or keying a
|
|
52
|
+
* `Record<RunOutcome, …>`, fails to compile; one comparing strings sees a value it never named.
|
|
53
|
+
*
|
|
54
|
+
* **`interrupted` is v0.19's NINTH**, added by W174 under
|
|
55
|
+
* [ADR 0105](../../doc/decisions/0105-a-run-its-owner-stops-goes-deaf-before-it-cancels-and-resumes-elsewhere.md): the
|
|
56
|
+
* run's OWNER stopped it to resume it elsewhere (`driver.stop`, an `interrupted` element), and no `resumed` element has
|
|
57
|
+
* followed (`RN-R32`). **Terminal** — {@link isTerminal} needs no change, and a runtime's `done` settles on it once the
|
|
58
|
+
* stop's cancels have resolved — **and the one terminal outcome a resume ACCEPTS**. **BREAKING in 0.8.0** (P34 decision
|
|
59
|
+
* 10), as `cancelling` is.
|
|
29
60
|
*/
|
|
30
|
-
export type RunOutcome = 'running' | 'completed' | 'failed' | 'awaiting_action' | '
|
|
61
|
+
export type RunOutcome = 'running' | 'completed' | 'failed' | 'awaiting_action' | 'halted' | 'stuck' | 'cancelled' | 'cancelling' | 'interrupted';
|
|
62
|
+
/**
|
|
63
|
+
* **Who cancelled the run, and why** — `RunState.cancelRequest`, `RN-R30`, v0.18. What the `cancelRequested` element
|
|
64
|
+
* carried: `actor` as the caller gave it, `reason` the caller's or `null` when it gave none.
|
|
65
|
+
*/
|
|
66
|
+
export interface CancelRequest {
|
|
67
|
+
actor: string;
|
|
68
|
+
reason: string | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* **Who stopped the run, and why** — `RunState.interruption`, `RN-R32`, v0.19. What the `interrupted` element carried:
|
|
72
|
+
* `actor` as the caller gave it, `reason` the caller's or `null` when it gave none.
|
|
73
|
+
*/
|
|
74
|
+
export interface Interruption {
|
|
75
|
+
actor: string;
|
|
76
|
+
reason: string | null;
|
|
77
|
+
}
|
|
31
78
|
/** How a branch left its region. `null` while it is still live. */
|
|
32
79
|
export type BranchSettlement = 'arrived' | 'exited' | 'lost';
|
|
80
|
+
/**
|
|
81
|
+
* **One task's entry in `RunState.nodes`** — `RN-R5`, and since v0.27 its ATTRIBUTION as fields (`RN-R41`,
|
|
82
|
+
* [ADR 0114](../../doc/decisions/0114-a-tasks-attribution-is-fields-and-its-messages-and-progress-are-passed-through.md), P36
|
|
83
|
+
* stop-and-ask (j)): the run, the flow-level attempt and the scheduler's attempt number, so a reader holding an entry on
|
|
84
|
+
* its own needs no parse of its key. **`runId`, `flowAttempt` and `attemptNumber` are REQUIRED, and that is BREAKING in
|
|
85
|
+
* 0.8.0 for code that builds a `NodeRun` literal** (P36 (p)); a reader is unaffected. Fold OUTPUT only: no fold input
|
|
86
|
+
* carries a field derived from the task id (`spec/outcome-record.md` section 2), and none moves.
|
|
87
|
+
*/
|
|
33
88
|
export interface NodeRun {
|
|
89
|
+
/**
|
|
90
|
+
* **The run the task belongs to** — v0.27, `RN-R41`: the task id's first segment (`spec/task-id.md` section 1), equal to
|
|
91
|
+
* `RunState.runId` on every entry of a run's fold. On the entry so it travels with it.
|
|
92
|
+
*/
|
|
93
|
+
runId: string;
|
|
34
94
|
nodeId: string;
|
|
35
95
|
/** `'-'` when the node is in no fan-out region. */
|
|
36
96
|
branchPath: string;
|
|
97
|
+
/**
|
|
98
|
+
* **The FLOW-LEVEL attempt** — v0.27, `RN-R41`: the task id's fourth segment, `0` on every id this library mints today
|
|
99
|
+
* ([Q16](../../doc/questions/q16.md)'s flow half mints nothing above it). NOT the scheduler's attempt number: that is
|
|
100
|
+
* {@link NodeRun.attemptNumber}, named apart so the two cannot be confused (P36 (j)).
|
|
101
|
+
*/
|
|
102
|
+
flowAttempt: number;
|
|
103
|
+
/**
|
|
104
|
+
* **The SCHEDULER's attempt number** — v0.27, `RN-R41`: the 1-based `attemptNumber` the LATEST `attempted` element for this
|
|
105
|
+
* task carried (`RN-R40`), so a retried task reads the attempt it is on, or settled on. **`null`** before its first
|
|
106
|
+
* attempt starts, on an ASK (never handed to a scheduler), and on every entry of a log written before 0.8.0, which holds
|
|
107
|
+
* no `attempted` element — never derived from a settlement's `attempts`.
|
|
108
|
+
*/
|
|
109
|
+
attemptNumber: number | null;
|
|
37
110
|
state: NodeState;
|
|
38
111
|
result: unknown;
|
|
39
112
|
error: string | null;
|
|
113
|
+
/**
|
|
114
|
+
* **What REACHED an ask** — `RN-R36`, v0.22, P35 (f),
|
|
115
|
+
* [ADR 0109](../../doc/decisions/0109-an-ask-parks-with-nothing-dispatched-and-its-answer-is-its-result.md): the value
|
|
116
|
+
* its `needs` composed (or the edge's value without one), as its `asked` element carried it, and KEPT after the answer.
|
|
117
|
+
* **Present only on an ask's node**, so every other node's entry has the five fields it always had — OPTIONAL, and
|
|
118
|
+
* additive: a consumer building a `NodeRun` literal is unaffected.
|
|
119
|
+
*/
|
|
120
|
+
input?: unknown;
|
|
40
121
|
}
|
|
41
122
|
export interface RegionRun {
|
|
42
123
|
/** Branch paths opened, in the order the driver emitted them (`JP-R5`). */
|
|
@@ -95,8 +176,37 @@ export interface RunState {
|
|
|
95
176
|
reason: 'end' | 'no-eligible-edge';
|
|
96
177
|
at: string;
|
|
97
178
|
}[];
|
|
98
|
-
/**
|
|
99
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Set when a refusal HALTED the run (`OR-R10`, `RN-R8`): the refusal's class, `: `, and its message. *(0.7.0's
|
|
181
|
+
* `stoppedBy` — renamed with the outcome by ADR 0102; BREAKING, and a consumer reading the old name fails to compile.)*
|
|
182
|
+
*/
|
|
183
|
+
haltedBy: string | null;
|
|
184
|
+
/**
|
|
185
|
+
* **Set when the run's OWNER cancelled it** — `RN-R30`, v0.18, W173,
|
|
186
|
+
* [ADR 0104](../../doc/decisions/0104-a-run-its-owner-cancels-is-cancelling-until-its-last-task-has-stopped.md): the
|
|
187
|
+
* FIRST `cancelRequested` element's `{ actor, reason }`, and `null` for a run nobody cancelled — including one a cancel
|
|
188
|
+
* the scheduler made on its own ended (`RN-R28`), which carries no actor. **A new cell, BREAKING in 0.8.0 for a
|
|
189
|
+
* consumer that builds a `RunState` literal** (P34 decision 10).
|
|
190
|
+
*/
|
|
191
|
+
cancelRequest: CancelRequest | null;
|
|
192
|
+
/**
|
|
193
|
+
* **Set while the run's OWNER has STOPPED it** — `RN-R32`, v0.19, W174,
|
|
194
|
+
* [ADR 0105](../../doc/decisions/0105-a-run-its-owner-stops-goes-deaf-before-it-cancels-and-resumes-elsewhere.md): the
|
|
195
|
+
* `interrupted` element's `{ actor, reason }`, and `null` again once a `resumed` element follows it. **CURRENT, not
|
|
196
|
+
* cumulative** — `regions[*].suspended`'s precedent (`RN-R6`): that a resumed run was ever stopped is in the input
|
|
197
|
+
* sequence, not here. **A new cell, BREAKING in 0.8.0 for a consumer that builds a `RunState` literal** (P34 decision 10).
|
|
198
|
+
*/
|
|
199
|
+
interruption: Interruption | null;
|
|
200
|
+
/**
|
|
201
|
+
* **Whether the run's OWNER has paused it NOW** — `RN-R34`, v0.20, W175,
|
|
202
|
+
* [ADR 0106](../../doc/decisions/0106-a-run-its-owner-pauses-routes-on-and-holds-every-dispatch-until-unpaused.md): `true`
|
|
203
|
+
* from a `paused` element until an `unpaused` one. **A flag, NOT an outcome** (P34 (e)): a paused run still routes, and
|
|
204
|
+
* each dispatch it holds is `dispatched` and so `running` in `nodes` — so `outcome` is exactly what it would be without
|
|
205
|
+
* the pause, and no precedence moves. **CURRENT, not cumulative**: that a run was ever paused is in the input sequence.
|
|
206
|
+
* Neither a stop, a cancel nor a resume lifts it — only an `unpaused` element does, so a run stopped while paused
|
|
207
|
+
* resumes paused. **A new cell, BREAKING in 0.8.0 for a consumer that builds a `RunState` literal** (P34 decision 10).
|
|
208
|
+
*/
|
|
209
|
+
paused: boolean;
|
|
100
210
|
/**
|
|
101
211
|
* **Every resume this run has had, in order, each the task ids it handed a scheduler AGAIN** —
|
|
102
212
|
* `RN-R22`, [ADR 0065](../../doc/decisions/0065-a-resume-replays-the-stored-stimuli-refuses-what-it-cannot-regenerate-and-re-dispatches-what-was-in-flight.md),
|
|
@@ -167,7 +277,7 @@ export interface GateDecision {
|
|
|
167
277
|
*
|
|
168
278
|
* Neither is a log record, and neither belongs in one: `spec/outcome-record.md`
|
|
169
279
|
* section 1 fixes the log at two kinds. This is the fold's input sequence, which
|
|
170
|
-
* already carried region events and a
|
|
280
|
+
* already carried region events and a halt for the same reason.
|
|
171
281
|
*
|
|
172
282
|
* **`joinSettled` is W5's, and it is the third fact of this shape**
|
|
173
283
|
* ([ADR 0015](../../doc/decisions/0015-a-run-whose-join-can-no-longer-fire-is-stuck.md)):
|
|
@@ -221,6 +331,25 @@ export type FoldInput = {
|
|
|
221
331
|
} | {
|
|
222
332
|
kind: 'dispatched';
|
|
223
333
|
taskId: string;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* **A branch reached an ASK, which parked** — `RN-R36`, `RN-R37`, v0.22,
|
|
337
|
+
* [W180](../../doc/work-items/w180-asking-and-answering-in-a-run.md),
|
|
338
|
+
* [ADR 0109](../../doc/decisions/0109-an-ask-parks-with-nothing-dispatched-and-its-answer-is-its-result.md), P35
|
|
339
|
+
* stop-and-ask (b): appended by the driver where a branch ENTERS an ask, with NOTHING handed to the scheduler — `taskId`
|
|
340
|
+
* the ask's own (`spec/task-id.md`'s scheme, attempt `0`) and `input` what reached it, composed through its `needs`
|
|
341
|
+
* (P35 (f)). The fold reads the node `suspended` from here, its `input` kept, until the person's `resolution`.
|
|
342
|
+
*
|
|
343
|
+
* **A structural fact, not a terminal state** (P35 decision 5, fact 13): `dispatched`'s precedent — no outcome record is
|
|
344
|
+
* ever written for an ask, and its only terminal fact is the person's answer. **REGENERATED on resume, never FED**
|
|
345
|
+
* (`RN-R19`): the replay re-enters the ask and compares the input it composes with the stored one (`RN-R20`). **The
|
|
346
|
+
* first kind whose payload is a value of ANY shape**, so it is deep-copied on the way out (`freezeInput`, `RN-R17`).
|
|
347
|
+
* **A new kind, BREAKING in 0.8.0 for a consumer switching on `kind` exhaustively** (P35 decision 8).
|
|
348
|
+
*/
|
|
349
|
+
| {
|
|
350
|
+
kind: 'asked';
|
|
351
|
+
taskId: string;
|
|
352
|
+
input: unknown;
|
|
224
353
|
} | {
|
|
225
354
|
kind: 'pathEnded';
|
|
226
355
|
reason: 'end' | 'no-eligible-edge';
|
|
@@ -231,10 +360,77 @@ export type FoldInput = {
|
|
|
231
360
|
regionPath: string;
|
|
232
361
|
joinId: string;
|
|
233
362
|
fired: boolean;
|
|
234
|
-
}
|
|
235
|
-
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* **A refusal HALTED the run** — `OR-R10`, `RN-R8`; appended by the driver's `failRun`, `reason` the refusal's class,
|
|
366
|
+
* `: ` and its message. **0.7.0 wrote this element as `{ kind: 'stopped', reason }`** and ADR 0102 renamed it
|
|
367
|
+
* (W171, P34 stop-and-ask (f)). **The old kind is READ, never written, and is not a member of this union**: a stored
|
|
368
|
+
* sequence is data from before the rename, so {@link step} folds an element whose `kind` is `'stopped'` exactly as
|
|
369
|
+
* this one and `resumeRefusal` refuses it `halted` at its position — `CHECKPOINT_FORMAT` stays `1`, and a 0.7.0
|
|
370
|
+
* checkpoint of a halted run is refused for the right reason while one of a live run still resumes. Nothing in this
|
|
371
|
+
* library writes `'stopped'` again, and the type says so: a consumer's `kind === 'stopped'` no longer compiles.
|
|
372
|
+
* **BREAKING in 0.8.0** (P34 decision 10): a consumer that switched on, compared or CONSTRUCTED the old kind fails
|
|
373
|
+
* to compile.
|
|
374
|
+
*/
|
|
375
|
+
| {
|
|
376
|
+
kind: 'halted';
|
|
236
377
|
reason: string;
|
|
237
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* **The run's OWNER cancelled it** — `RN-R30`, `RN-R31`, v0.18,
|
|
381
|
+
* [W173](../../doc/work-items/w173-cancelling-a-run.md),
|
|
382
|
+
* [ADR 0104](../../doc/decisions/0104-a-run-its-owner-cancels-is-cancelling-until-its-last-task-has-stopped.md), P34
|
|
383
|
+
* decision 4: appended ONCE by `Driver.cancel`, after the hold and BEFORE the scheduler is asked to cancel anything,
|
|
384
|
+
* so every `task.cancelled` it causes folds under it. `reason` is `null` when the caller gave none. The fold reads the
|
|
385
|
+
* run `cancelling` from here while a dispatched task is unsettled, and `cancelled` once none is.
|
|
386
|
+
*
|
|
387
|
+
* **Never fed to a replay**: a resume refuses a stored one `cancelled` before replaying anything (`RN-R23`). **A new
|
|
388
|
+
* kind, BREAKING in 0.8.0 for a consumer switching on `kind` exhaustively** (P34 decision 10).
|
|
389
|
+
*/
|
|
390
|
+
| {
|
|
391
|
+
kind: 'cancelRequested';
|
|
392
|
+
actor: string;
|
|
393
|
+
reason: string | null;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* **The run's OWNER stopped it, to resume it elsewhere** — `RN-R32`, `RN-R33`, v0.19,
|
|
397
|
+
* [W174](../../doc/work-items/w174-stopping-a-run-to-resume-it-elsewhere.md),
|
|
398
|
+
* [ADR 0105](../../doc/decisions/0105-a-run-its-owner-stops-goes-deaf-before-it-cancels-and-resumes-elsewhere.md), P34
|
|
399
|
+
* decision 3 and stop-and-ask (d): appended ONCE by `Driver.stop`, after the hold and the driver going DEAF and BEFORE
|
|
400
|
+
* it asks the scheduler to cancel anything, so no `task.cancelled` the stop causes — nor any settlement at all — follows it. `reason` is `null` when the
|
|
401
|
+
* caller gave none. The fold reads the run `interrupted` from here until a `resumed` element.
|
|
402
|
+
*
|
|
403
|
+
* **FED to a replay** (`RN-R19`), at its own position — the one terminal element a resume does not refuse. **A new
|
|
404
|
+
* kind, BREAKING in 0.8.0 for a consumer switching on `kind` exhaustively** (P34 decision 10).
|
|
405
|
+
*/
|
|
406
|
+
| {
|
|
407
|
+
kind: 'interrupted';
|
|
408
|
+
actor: string;
|
|
409
|
+
reason: string | null;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* **The run's OWNER paused it** — `RN-R34`, `RN-R35`, v0.20,
|
|
413
|
+
* [W175](../../doc/work-items/w175-pausing-a-run.md),
|
|
414
|
+
* [ADR 0106](../../doc/decisions/0106-a-run-its-owner-pauses-routes-on-and-holds-every-dispatch-until-unpaused.md), P34
|
|
415
|
+
* stop-and-ask (e): appended ONCE by `Driver.pause`, at rest — between two of the driver's steps — and from it on every
|
|
416
|
+
* dispatch is appended and HELD. The fold sets `RunState.paused`; no outcome moves.
|
|
417
|
+
*
|
|
418
|
+
* **FED to a replay** (`RN-R19`), at its own position, so a run stopped while paused resumes paused. **A new kind,
|
|
419
|
+
* BREAKING in 0.8.0 for a consumer switching on `kind` exhaustively** (P34 decision 10).
|
|
420
|
+
*/
|
|
421
|
+
| {
|
|
422
|
+
kind: 'paused';
|
|
423
|
+
actor: string;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* **The run's OWNER unpaused it** — `RN-R34`, `RN-R35`, v0.20, W175, ADR 0106: appended ONCE by `Driver.unpause`, at
|
|
427
|
+
* rest, BEFORE the held tasks are handed on, in dispatch order. The fold clears `RunState.paused`. **FED to a replay**;
|
|
428
|
+
* **a new kind, BREAKING in 0.8.0** (P34 decision 10).
|
|
429
|
+
*/
|
|
430
|
+
| {
|
|
431
|
+
kind: 'unpaused';
|
|
432
|
+
actor: string;
|
|
433
|
+
}
|
|
238
434
|
/**
|
|
239
435
|
* **The run was RESUMED, and these are the tasks handed to a scheduler again** — `RN-R22`,
|
|
240
436
|
* [W89](../../doc/work-items/w89-what-resuming-is.md), P23 stop-and-ask (a), answered: *a resume
|
|
@@ -269,7 +465,30 @@ export type FoldInput = {
|
|
|
269
465
|
*/
|
|
270
466
|
| ({
|
|
271
467
|
kind: 'gated';
|
|
272
|
-
} & GateDecision)
|
|
468
|
+
} & GateDecision)
|
|
469
|
+
/**
|
|
470
|
+
* **An ATTEMPT of a task started** — `RN-R40`, v0.26,
|
|
471
|
+
* [W186](../../doc/work-items/w186-attempts-recorded-and-carried-across-a-resume.md),
|
|
472
|
+
* [ADR 0113](../../doc/decisions/0113-a-tasks-attempts-are-recorded-and-carried-across-a-resume.md), P36 stop-and-ask (f):
|
|
473
|
+
* appended by the driver for the scheduler's `task.running` of a task THIS run dispatched, carrying the scheduler's
|
|
474
|
+
* 1-based `attemptNumber` — and ONLY when that number EXCEEDS the last one recorded for the task, so a requeue (which
|
|
475
|
+
* repeats its number) appends nothing. For every task, with or without a `retryPolicy`. **Appended at REST**: a
|
|
476
|
+
* `task.running` heard on the driver's own step — an inline pool fires it INSIDE `addTask` — is appended when that step
|
|
477
|
+
* ends, so the element always lies BETWEEN two steps, where a resume's replay feeds it (`RN-R19`).
|
|
478
|
+
*
|
|
479
|
+
* **FED to a replay** (`RN-R19`'s seventh kind): only the scheduler can produce it, so the replay cannot regenerate it;
|
|
480
|
+
* the highest number the replay was fed for a task is what a resume re-hands it with as `attemptsSpent` (`RN-R21`), so a
|
|
481
|
+
* task's retry budget is NOT reset by a crash (Q365). **Moved nothing in `RunState` at v0.26; since v0.27 it sets ONE
|
|
482
|
+
* cell, its task's `NodeRun.attemptNumber`** (`RN-R41`, W187) — the run's outcome, every state and every other cell are
|
|
483
|
+
* what they would be without it. **Never a log record**
|
|
484
|
+
* (`OR-R4`: `task.running` writes none) — `cancelRequested`'s precedent. **A new kind, BREAKING in 0.8.0 for a consumer
|
|
485
|
+
* switching on `kind` exhaustively** (P36 decision 8, (p)).
|
|
486
|
+
*/
|
|
487
|
+
| {
|
|
488
|
+
kind: 'attempted';
|
|
489
|
+
taskId: string;
|
|
490
|
+
attemptNumber: number;
|
|
491
|
+
};
|
|
273
492
|
export declare function emptyState(): RunState;
|
|
274
493
|
/**
|
|
275
494
|
* One step. **Returns a new state; never mutates the one it was given** — which is
|
|
@@ -292,14 +511,26 @@ export declare function foldLog(log: readonly LogRecord[]): RunState;
|
|
|
292
511
|
* Whether a run can still change — the predicate an L6 harness resolves on, and
|
|
293
512
|
* the reason it needs no clock.
|
|
294
513
|
*
|
|
295
|
-
* `running` and `awaiting_action` are the
|
|
296
|
-
* coming: a dispatched node has not settled, or a person has
|
|
297
|
-
*
|
|
298
|
-
*
|
|
514
|
+
* `running` and `awaiting_action` are two of the three outcomes that say more input is
|
|
515
|
+
* coming that can MOVE the run (`cancelling`, the third, below): a dispatched node has not settled, or a person has
|
|
516
|
+
* not answered. `completed`, `failed` and `stuck` are reached only when nothing is
|
|
517
|
+
* live. `halted` and — since W158 — `cancelled` are reached with dispatched nodes
|
|
518
|
+
* possibly still unsettled: the driver has HALTED the run, so what is in flight
|
|
519
|
+
* settles into `nodes` routed nowhere and moves no outcome. Either way the run is
|
|
520
|
+
* over. **This is `stuck`'s point:** before
|
|
299
521
|
* [ADR 0015](../../doc/decisions/0015-a-run-whose-join-can-no-longer-fire-is-stuck.md)
|
|
300
522
|
* a permanently stuck run was `completed`, so a harness waiting on this predicate
|
|
301
523
|
* would have reported the hang as a success rather than waiting forever — which
|
|
302
524
|
* is the worse of the two failures.
|
|
525
|
+
*
|
|
526
|
+
* **`cancelling` is the THIRD unfinished outcome since v0.18** (`RN-R12`, `RN-R30`, ADR 0104): the run's owner
|
|
527
|
+
* cancelled it and a task is still stopping, so its `task.cancelled` is still coming and moves the outcome to
|
|
528
|
+
* `cancelled`. Calling it terminal would settle a runtime's `done` at the request — before the tasks have stopped,
|
|
529
|
+
* the app's #1 complaint (P34 fact 6).
|
|
530
|
+
*
|
|
531
|
+
* **`interrupted` is TERMINAL, unchanged by v0.19** (`RN-R12`, `RN-R32`, ADR 0105): the run's owner stopped it and the
|
|
532
|
+
* driver went deaf, so nothing more can move it on THIS runtime — its in-flight set is moved by a resume on another,
|
|
533
|
+
* which is not this driver's input. A runtime's `done` settles on it once the stop's cancels have resolved (`RN-R33`).
|
|
303
534
|
*/
|
|
304
535
|
export declare function isTerminal(s: RunState): boolean;
|
|
305
536
|
/** A node's entry, or `null`. Not an outcome record: it has no `attempts` and no timing fields. */
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* decision 5, [W59](../../doc/work-items/w59-what-a-node-type-is.md), [W65](../../doc/work-items/w65-the-registry-document-and-a-node-type-is-a-derivation.md);
|
|
9
9
|
* **and since v0.18 the place a language adapter's WORKER half reaches a typed pool** —
|
|
10
10
|
* [ADR 0051](../../doc/decisions/0051-a-transform-is-a-declared-expression-in-a-registered-language-applied-in-the-types-worker-wrapper.md)
|
|
11
|
-
* rule 4, [W61](../../doc/work-items/w61-what-a-transform-is.md).
|
|
11
|
+
* rule 4, [W61](../../doc/work-items/w61-what-a-transform-is.md) — into EVERY typed pool since ADR 0096 (W162).
|
|
12
12
|
*
|
|
13
13
|
* **This sub-path is the one place the published package CONSTRUCTS a scheduler object** (`RT-R13`;
|
|
14
14
|
* `createRuntime` in `./runtime.ts` is the other module in it, and it constructs the groups and the
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* **Since W65 the helper takes the REGISTRY's three sections — `workers`, `nodeTypes`, `pools` —
|
|
22
22
|
* and builds one pool per INSTANCE**: the default instance of every type, keyed by the type's name,
|
|
23
23
|
* and every named instance in `pools`, keyed as declared. Each is the type's derivation run over the
|
|
24
|
-
* instance's config
|
|
24
|
+
* instance's config — and, since v0.37, a document type's instance's own `pool` options merged over the type's
|
|
25
|
+
* (ADR 0099) — (`derivePool`, the same checks `resolveRegistry` makes), turned into
|
|
25
26
|
* `WorkerManagerOptions` by `poolOptionsOf` — the type's `inline`, the derived pool fields and
|
|
26
27
|
* groups, and the envelope pool config `{ worker: <the worker entry's url>, config: <the derived
|
|
27
28
|
* config> }` — and handed to the pool factory with the package's envelope worker as its script.
|
|
@@ -35,21 +36,23 @@
|
|
|
35
36
|
* nothing. Since W65 a POOL's groups are what its derivation returned (`groups` and `residentGroups`),
|
|
36
37
|
* which for a document type is what the type declared.
|
|
37
38
|
*
|
|
38
|
-
* **
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* to a thread and a URL can (P17 fact 7).
|
|
43
|
-
*
|
|
44
|
-
*
|
|
39
|
+
* **Every pool carries every language it is given** — [ADR 0096](../../doc/decisions/0096-a-runtime-is-its-registry-and-start-refuses-from-runtime-check.md)
|
|
40
|
+
* rule 2, [W162](../../doc/work-items/w162-a-runtimes-languages-are-its-registrys-and-runtime-check.md),
|
|
41
|
+
* superseding ADR 0051 rule 4. The helper writes each adapter's WORKER-side module URL
|
|
42
|
+
* (`LanguageAdapter.worker`) into EVERY pool it builds, under the language's name — a FUNCTION could
|
|
43
|
+
* not cross to a thread and a URL can (P17 fact 7). It reads no flow: a runtime's pools are built once
|
|
44
|
+
* and a flow published later may transform on any type, so which types transform is not knowable here.
|
|
45
|
+
* Given no language, every pool config is the two-key one it had at v0.17 (P18 fact 5).
|
|
45
46
|
*/
|
|
46
47
|
import { WorkerManager } from 'fyflow-scheduler';
|
|
47
48
|
import type { ResourceGroup, WorkerManagerOptions } from 'fyflow-scheduler';
|
|
48
|
-
import type {
|
|
49
|
+
import type { Languages, NodeTypes, Pools, ResolvedPool, Workers } from '../definition/types.js';
|
|
49
50
|
/**
|
|
50
|
-
* The script every typed pool loads
|
|
51
|
-
*
|
|
52
|
-
*
|
|
51
|
+
* The script every typed pool loads; the type's real worker is loaded from inside it
|
|
52
|
+
* (`EnvelopeWorker.setup`). In the source it resolves against THIS module, the package's own file
|
|
53
|
+
* wherever it is installed — so a bundle built from the JSR source must serve it beside itself. The
|
|
54
|
+
* npm dist replaces it at build time with the worker itself: a `data:` URL on Node, a `Blob` URL in
|
|
55
|
+
* the browser (`scripts/build.mjs`, Q580).
|
|
53
56
|
*/
|
|
54
57
|
export declare const ENVELOPE_WORKER_URL: string;
|
|
55
58
|
/** A registry that cannot be bootstrapped, and why — thrown before any pool is built. A registry SHAPE defect is a `RegistryError` instead, from `checkRegistry`. */
|
|
@@ -70,15 +73,10 @@ export interface BootstrapOptions {
|
|
|
70
73
|
createPool?: PoolFactory;
|
|
71
74
|
/**
|
|
72
75
|
* **The registry's languages — the same object the driver is handed** (W61). Read for ONE field,
|
|
73
|
-
* `worker`, and
|
|
76
|
+
* `worker`, and written into EVERY pool (ADR 0096 rule 2). Omitted or empty, no pool config carries
|
|
77
|
+
* a `languages` key. *(A `flows` option sat beside this until W162 and is removed — ADR 0096 rule 3.)*
|
|
74
78
|
*/
|
|
75
79
|
languages?: Languages;
|
|
76
|
-
/**
|
|
77
|
-
* **The flows these pools will run**, read for WHICH types transform in WHICH languages. Omitted,
|
|
78
|
-
* or naming no transform, every pool config is exactly what it was at v0.17. A node naming a
|
|
79
|
-
* type this registry lacks is skipped here — it is the driver's `FD-V32`, not this helper's.
|
|
80
|
-
*/
|
|
81
|
-
flows?: readonly FlowDefinition[];
|
|
82
80
|
}
|
|
83
81
|
export interface BootstrapResult {
|
|
84
82
|
/** One per pool INSTANCE — every type's default instance under the type's name, every named instance under its key — spread into `new FyflowScheduler(...)`'s first argument. */
|
|
@@ -88,10 +86,4 @@ export interface BootstrapResult {
|
|
|
88
86
|
/** What each pool was DERIVED as — the checked spec every pool above was built from, for a caller that reads pools back (ladder L6's observers). */
|
|
89
87
|
derived: Record<string, ResolvedPool>;
|
|
90
88
|
}
|
|
91
|
-
/**
|
|
92
|
-
* **Which languages each type's nodes transform in, over the flows given** — the one reading of a
|
|
93
|
-
* definition this helper makes. Exported so a test can compare what the helper WROTE into pool
|
|
94
|
-
* configs against what the flows DECLARE, both ways (rule 8 obligation (e) on `Registry.languages`).
|
|
95
|
-
*/
|
|
96
|
-
export declare function transformLanguagesByType(flows: readonly FlowDefinition[]): ReadonlyMap<string, ReadonlySet<string>>;
|
|
97
89
|
export declare function bootstrap(registry: BootstrapRegistry, groups?: Readonly<Record<string, ResourceGroup>>, options?: BootstrapOptions): BootstrapResult;
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* A `WorkerManager` loads its worker from a script URL and instantiates the module's default
|
|
11
11
|
* export, so a wrapper cannot be a function around a class — it has to BE the script the pool
|
|
12
12
|
* loads. This module is that script: its pool config names the type's real worker (`worker`, a
|
|
13
|
-
* module URL), that worker's own config (`config`), and
|
|
14
|
-
*
|
|
13
|
+
* module URL), that worker's own config (`config`), and the worker-side module URL of every language
|
|
14
|
+
* the registry names (`languages` — every typed pool's since ADR 0096, W162); this
|
|
15
15
|
* class loads the inner worker and the language modules in `setup()`, evaluates the envelope's
|
|
16
16
|
* `transform` in `run()` when one is present, hands the inner worker **exactly `{ settings, input }`**
|
|
17
17
|
* with `input` REPLACED by the evaluation's result, and tears the inner worker down with itself.
|
|
@@ -74,8 +74,8 @@ export interface EnvelopePoolConfig {
|
|
|
74
74
|
config?: unknown;
|
|
75
75
|
/**
|
|
76
76
|
* **Language name → worker-side module URL** (`LanguageAdapter.worker`), written by the bootstrap
|
|
77
|
-
* helper
|
|
78
|
-
*
|
|
77
|
+
* helper into EVERY pool, for every language it is given — ADR 0096 rule 2 (W162), superseding
|
|
78
|
+
* ADR 0051 rule 4's *only for a type some node of which declares a transform*. Loaded in `setup()`,
|
|
79
79
|
* once per worker instance; each module's default export is `compile(expr) => { evaluate(input,
|
|
80
80
|
* settings) }`.
|
|
81
81
|
*/
|
|
@@ -188,7 +188,8 @@ export default class EnvelopeWorker {
|
|
|
188
188
|
/** One language's worker half, or the Error that stands in for it — never a throw (see `setup()`). */
|
|
189
189
|
private loadLanguage;
|
|
190
190
|
/**
|
|
191
|
-
* `FD-C5`: the inner worker receives `{ settings, input }` and
|
|
191
|
+
* `FD-C5`: the inner worker receives `{ settings, input }` as its payload, and the scheduler's task context as its
|
|
192
|
+
* second argument, passed through untouched (W159). `FD-C6`: when the
|
|
192
193
|
* envelope carries a `transform`, `input` is the evaluation of that expression over the value
|
|
193
194
|
* received, with the node's settings bound as `$settings`, and the third key is consumed here.
|
|
194
195
|
*/
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* for everything else. Since v0.18 (W61, ADR 0051) the envelope worker here also evaluates a
|
|
6
6
|
* node's declared `transform`, and `TransformFailed` is what a task fails with when it cannot.
|
|
7
7
|
*/
|
|
8
|
-
export { bootstrap, BootstrapError, ENVELOPE_WORKER_URL
|
|
8
|
+
export { bootstrap, BootstrapError, ENVELOPE_WORKER_URL } from './bootstrap.js';
|
|
9
9
|
export type { BootstrapOptions, BootstrapRegistry, BootstrapResult, PoolFactory } from './bootstrap.js';
|
|
10
|
-
export { BUILT_IN_GROUP_FACTORIES, createRuntime, GROUP_MEMBERS, GroupNotBuildable, GroupUnusable,
|
|
10
|
+
export { BUILT_IN_GROUP_FACTORIES, createRuntime, GROUP_MEMBERS, GroupNotBuildable, GroupUnusable, LimitKeyMissing, RunIdInUse, RuntimeError } from './runtime.js';
|
|
11
11
|
export type { ResumeOptions, RunHandle, Runtime, RuntimeOptions, RuntimeRegistry, StartOptions } from './runtime.js';
|
|
12
12
|
export { default as EnvelopeWorker, NotAnEnvelope, TransformFailed, unpackEnvelope } from './envelope-worker.js';
|
|
13
13
|
export type { Envelope, EnvelopePoolConfig } from './envelope-worker.js';
|