@fluidgrids/workflows 2026.1027.1 → 2026.1028.2

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 (166) hide show
  1. package/README.md +144 -13
  2. package/dist/activation-BBh1p82z.d.cts +57 -0
  3. package/dist/activation-DnhG7SmF.d.ts +57 -0
  4. package/dist/assemble-BLqQ8lSu.d.cts +39 -0
  5. package/dist/assemble-DWgaXHd-.d.ts +39 -0
  6. package/dist/chunk-2J6TF7YI.cjs +86 -0
  7. package/dist/chunk-4LYSEANA.js +199 -0
  8. package/dist/chunk-623FVQSN.cjs +251 -0
  9. package/dist/{chunk-W32BSO3M.js → chunk-6FSHT5IL.js} +2 -2
  10. package/dist/{chunk-E3APHA6O.cjs → chunk-7AAZGVKD.js} +1 -64
  11. package/dist/chunk-ABFZWYHT.js +612 -0
  12. package/dist/{chunk-6U446SKY.js → chunk-BD7ZPG53.js} +2 -2
  13. package/dist/chunk-BO6OVILK.js +79 -0
  14. package/dist/chunk-C5OLWZ42.js +245 -0
  15. package/dist/{chunk-OSPTJCDI.cjs → chunk-CPDK3K5N.cjs} +6 -6
  16. package/dist/chunk-DHTLALBL.cjs +80 -0
  17. package/dist/chunk-DJYMDLV5.js +227 -0
  18. package/dist/{chunk-IHKXLG6I.js → chunk-E2VK7J2C.js} +1 -1
  19. package/dist/{chunk-3M34AUIY.cjs → chunk-FEW3JBYA.cjs} +3 -3
  20. package/dist/chunk-FMSW2HDF.cjs +267 -0
  21. package/dist/chunk-FR7KYWRO.cjs +41 -0
  22. package/dist/{chunk-7YR7DI7B.cjs → chunk-GBQ33SIZ.cjs} +44 -44
  23. package/dist/{chunk-6AIAC2FP.cjs → chunk-GVTZMA5C.cjs} +4 -4
  24. package/dist/{chunk-EEAIM35V.js → chunk-HWJZVOG7.js} +64 -23
  25. package/dist/chunk-I5LR3D2K.js +869 -0
  26. package/dist/chunk-IISBRUWJ.js +13 -0
  27. package/dist/chunk-JD2VQIDZ.cjs +15 -0
  28. package/dist/{chunk-UB2BHU2M.js → chunk-JZ4TOOLN.js} +1 -1
  29. package/dist/chunk-L24YIZY7.cjs +207 -0
  30. package/dist/chunk-LNUQE6D6.js +39 -0
  31. package/dist/chunk-M4BBAERY.cjs +1635 -0
  32. package/dist/chunk-N23SKIG4.js +73 -0
  33. package/dist/{chunk-TWOYB4Y7.cjs → chunk-NEIUQASE.cjs} +13 -13
  34. package/dist/chunk-P6TA5EZT.cjs +634 -0
  35. package/dist/chunk-PMCM2OH4.js +46 -0
  36. package/dist/chunk-PZCVF76Q.cjs +868 -0
  37. package/dist/{chunk-6BEW4QD6.js → chunk-QAN5MZEM.js} +1 -1
  38. package/dist/{chunk-CSYBNN3V.cjs → chunk-QKZL3ONM.cjs} +2 -2
  39. package/dist/chunk-QQ6ULXHI.cjs +885 -0
  40. package/dist/chunk-SAENRNBJ.cjs +52 -0
  41. package/dist/{chunk-TQF7MYEN.cjs → chunk-SAOBPYYJ.cjs} +134 -96
  42. package/dist/{chunk-XBIID5DY.js → chunk-SMCANK3F.js} +5 -4
  43. package/dist/{chunk-UWQWD7BP.cjs → chunk-SX2PNKKT.cjs} +18 -17
  44. package/dist/{chunk-UJNHTS6D.js → chunk-TBDXTV22.cjs} +8 -45
  45. package/dist/chunk-UK3WM7YZ.cjs +75 -0
  46. package/dist/chunk-VOKMAAJP.js +848 -0
  47. package/dist/chunk-VRHHBPT6.js +1622 -0
  48. package/dist/{chunk-5AW745OG.js → chunk-XHXIDVEC.js} +1 -1
  49. package/dist/chunk-XKJA7KX3.js +72 -0
  50. package/dist/chunk-Z2Y65YOY.cjs +7 -0
  51. package/dist/codegen/index.cjs +9 -7
  52. package/dist/codegen/index.d.cts +2 -2
  53. package/dist/codegen/index.d.ts +2 -2
  54. package/dist/codegen/index.js +6 -5
  55. package/dist/file-BOoHZgoQ.d.cts +1557 -0
  56. package/dist/file-yuPCFU5b.d.ts +1557 -0
  57. package/dist/history/index.cjs +287 -0
  58. package/dist/history/index.d.cts +157 -0
  59. package/dist/history/index.d.ts +157 -0
  60. package/dist/history/index.js +5 -0
  61. package/dist/index.cjs +134 -36
  62. package/dist/index.d.cts +137 -9
  63. package/dist/index.d.ts +137 -9
  64. package/dist/index.js +8 -3
  65. package/dist/ir/index.cjs +152 -158
  66. package/dist/ir/index.d.cts +14 -4
  67. package/dist/ir/index.d.ts +14 -4
  68. package/dist/ir/index.js +41 -50
  69. package/dist/lower-BzmUz0sq.d.cts +129 -0
  70. package/dist/lower-_-iT4HYs.d.ts +129 -0
  71. package/dist/lower-types-DQNBfWQn.d.cts +37 -0
  72. package/dist/lower-types-DQNBfWQn.d.ts +37 -0
  73. package/dist/{manifest-Duf-gHdO.d.cts → manifest-0OLw0i7k.d.cts} +1 -1
  74. package/dist/{manifest-Bp9ZJlav.d.ts → manifest-C8N6HDYl.d.ts} +1 -1
  75. package/dist/node-evaluator-4MSDKWOG.cjs +22 -0
  76. package/dist/node-evaluator-SX4LEYQC.js +12 -0
  77. package/dist/quickjs/index.cjs +236 -12
  78. package/dist/quickjs/index.d.cts +46 -5
  79. package/dist/quickjs/index.d.ts +46 -5
  80. package/dist/quickjs/index.js +230 -9
  81. package/dist/roundtrip/index.cjs +333 -131
  82. package/dist/roundtrip/index.d.cts +39 -7
  83. package/dist/roundtrip/index.d.ts +39 -7
  84. package/dist/roundtrip/index.js +185 -13
  85. package/dist/runtime/index.cjs +90 -0
  86. package/dist/runtime/index.d.cts +297 -0
  87. package/dist/runtime/index.d.ts +297 -0
  88. package/dist/runtime/index.js +8 -0
  89. package/dist/testing/index.cjs +1057 -0
  90. package/dist/testing/index.d.cts +305 -0
  91. package/dist/testing/index.d.ts +305 -0
  92. package/dist/testing/index.js +1037 -0
  93. package/dist/{types-Dr2Fn1Ax.d.ts → types-BGoPzgcl.d.cts} +1 -1
  94. package/dist/{types-Dr2Fn1Ax.d.cts → types-BGoPzgcl.d.ts} +1 -1
  95. package/dist/types-CpBBjaGX.d.cts +380 -0
  96. package/dist/types-DV-HX_Gt.d.ts +380 -0
  97. package/dist/{assemble-CrpUyd_3.d.ts → workflow-Bpr3vnA_.d.ts} +40 -160
  98. package/dist/workflow-C2a05WUJ.d.ts +444 -0
  99. package/dist/{assemble-DEf3znGD.d.cts → workflow-FXUkpIBc.d.cts} +40 -160
  100. package/dist/workflow-J-yYixny.d.cts +444 -0
  101. package/fixtures/README.md +128 -0
  102. package/fixtures/histories/activity-failure-fails-run.history.json +163 -0
  103. package/fixtures/histories/activity-retry-then-success.history.json +147 -0
  104. package/fixtures/histories/cancel-activity-abandon.history.json +126 -0
  105. package/fixtures/histories/cancel-activity-compensate.history.json +307 -0
  106. package/fixtures/histories/cancel-concurrent-non-cancellable.history.json +234 -0
  107. package/fixtures/histories/cancel-concurrent-scope-timeout.history.json +184 -0
  108. package/fixtures/histories/cancel-condition-after-cancel.history.json +200 -0
  109. package/fixtures/histories/cancel-during-timer.history.json +123 -0
  110. package/fixtures/histories/cancel-saga-compensations.history.json +325 -0
  111. package/fixtures/histories/cancel-scope-timeout.history.json +148 -0
  112. package/fixtures/histories/child-abandon-outlives-parent.history.json +191 -0
  113. package/fixtures/histories/child-cancel-default.history.json +234 -0
  114. package/fixtures/histories/child-cancel-request.history.json +206 -0
  115. package/fixtures/histories/child-durable-child-side.history.json +124 -0
  116. package/fixtures/histories/child-durable-result.history.json +163 -0
  117. package/fixtures/histories/child-failure-caught.history.json +166 -0
  118. package/fixtures/histories/child-graph-by-key.history.json +138 -0
  119. package/fixtures/histories/child-terminated-by-parent-close.history.json +85 -0
  120. package/fixtures/histories/continue-as-new-first-run.history.json +146 -0
  121. package/fixtures/histories/continue-as-new-history-limit.history.json +489 -0
  122. package/fixtures/histories/continue-as-new-last-run.history.json +147 -0
  123. package/fixtures/histories/continue-as-new-suggested.history.json +352 -0
  124. package/fixtures/histories/details-and-context.history.json +176 -0
  125. package/fixtures/histories/deterministic-values.history.json +128 -0
  126. package/fixtures/histories/engine-builtins.history.json +172 -0
  127. package/fixtures/histories/gather-activities.history.json +291 -0
  128. package/fixtures/histories/gather-all-settled.history.json +219 -0
  129. package/fixtures/histories/gather-mixed.history.json +281 -0
  130. package/fixtures/histories/input-during-running-task.history.json +111 -0
  131. package/fixtures/histories/nondeterminism-reordered.history.json +218 -0
  132. package/fixtures/histories/patched-deprecated.history.json +271 -0
  133. package/fixtures/histories/patched-new-run.history.json +270 -0
  134. package/fixtures/histories/patched-old-history.history.json +190 -0
  135. package/fixtures/histories/race-activity-wins.history.json +152 -0
  136. package/fixtures/histories/race-signal-beats-child.history.json +161 -0
  137. package/fixtures/histories/race-timeout-wins.history.json +118 -0
  138. package/fixtures/histories/side-effect-recorded.history.json +153 -0
  139. package/fixtures/histories/signal-buffered-at-start.history.json +157 -0
  140. package/fixtures/histories/signal-default-handler.history.json +187 -0
  141. package/fixtures/histories/signal-handler.history.json +191 -0
  142. package/fixtures/histories/signal-parent-child-side.history.json +132 -0
  143. package/fixtures/histories/signal-parent.history.json +202 -0
  144. package/fixtures/histories/signal-run-delivered.history.json +128 -0
  145. package/fixtures/histories/signal-run-undelivered.history.json +134 -0
  146. package/fixtures/histories/signal-wait.history.json +111 -0
  147. package/fixtures/histories/task-failure-code-error.history.json +137 -0
  148. package/fixtures/histories/task-failure-then-transient-attempt.history.json +140 -0
  149. package/fixtures/histories/timer-condition-met.history.json +201 -0
  150. package/fixtures/histories/timer-condition-timeout.history.json +118 -0
  151. package/fixtures/histories/timer-sleep-once.history.json +118 -0
  152. package/fixtures/histories/timer-sleep-sequence.history.json +210 -0
  153. package/fixtures/histories/update-accepted-completed.history.json +149 -0
  154. package/fixtures/histories/update-with-start-rejected-validation.history.json +91 -0
  155. package/package.json +44 -5
  156. package/schema/history-file.schema.json +2544 -0
  157. package/schema/ir-v2.schema.json +16 -0
  158. package/schema/run-event.schema.json +2374 -0
  159. package/schema/workflow-command.schema.json +1095 -0
  160. package/schema/workflow-task.schema.json +3560 -0
  161. package/dist/chunk-MBBKGD7K.js +0 -440
  162. package/dist/chunk-Y7NWR3WH.cjs +0 -450
  163. package/dist/lower-CXggJTIo.d.ts +0 -67
  164. package/dist/lower-DAzvsJCo.d.cts +0 -67
  165. package/dist/node-evaluator-CH3XCJND.cjs +0 -17
  166. package/dist/node-evaluator-TULXA3WE.js +0 -8
@@ -0,0 +1,305 @@
1
+ import { h as DurableWorkflow, O as Operation, j as Duration, l as SignalDefinition } from '../workflow-J-yYixny.cjs';
2
+ import { i as HistoryFile, m as RunState } from '../file-BOoHZgoQ.cjs';
3
+ import { a6 as WorkflowInfoSnapshot, a7 as WorkflowTaskRequest, a8 as WorkflowTaskResult, U as RunEventRecord, F as Failure, V as RunEventType } from '../types-CpBBjaGX.cjs';
4
+ import { a as Json, b as WorkflowDefinition, m as WorkflowNode } from '../types-BGoPzgcl.cjs';
5
+ import { x as Tier1Workflow } from '../workflow-FXUkpIBc.cjs';
6
+ import { E as EsbuildApi } from '../lower-types-DQNBfWQn.cjs';
7
+ import { WorkflowRegistry } from '../runtime/index.cjs';
8
+ import 'esbuild';
9
+ import '../activation-BBh1p82z.cjs';
10
+
11
+ /**
12
+ * `TestWorkflowEnvironment` (spec 10 §1): an in-process engine for tier-2
13
+ * workflows. It keeps histories in memory, runs workflow tasks through the
14
+ * real runtime ABI, appends exactly the events `history/apply.ts` prescribes,
15
+ * runs activities against mocks with the shared retry policy, fires timers on
16
+ * a fake clock, and runs child workflows, signals, cancellation and the
17
+ * parent-close policy. The histories it records are valid service histories:
18
+ * the conformance fixtures are recorded with it and then replayed in QuickJS
19
+ * and in `vm`.
20
+ *
21
+ * Divergences from the service (documented, accepted for Phase B):
22
+ * - Workflow tasks run in this process without the determinism shims.
23
+ * - A failed workflow task is not retried forever: the run stops, and
24
+ * `result()` rejects with {@link WorkflowTaskFailedError}.
25
+ * - Every task is a first attempt (no transient attempts), and activity
26
+ * start-to-close and heartbeat timeouts are not timed; a mock may throw a
27
+ * `TimeoutFailure` to simulate one. Schedule-to-close is honoured.
28
+ * - Graph child runs are mocks (`mockChild`).
29
+ */
30
+
31
+ /** What a mock receives besides the activity's args. */
32
+ interface ActivityMockInfo {
33
+ runId: string;
34
+ activityId: string;
35
+ attempt: number;
36
+ nodeType: string;
37
+ operation: string;
38
+ connection?: string;
39
+ }
40
+ type ActivityMock = (args: Json, info: ActivityMockInfo) => unknown;
41
+ type ChildMock = (input: Json, info: {
42
+ runId: string;
43
+ childId: string;
44
+ }) => unknown;
45
+ interface TestEnvironmentOptions {
46
+ /** Advance the clock to the next timer whenever every run is idle (default true). */
47
+ timeSkipping?: boolean;
48
+ /** Start of the fake clock. Default 2026-01-01T00:00:00.000Z. */
49
+ startTime?: number | string | Date;
50
+ /** Tier-2 functions by export name, for `ctx.child(fn)` and by-name starts. */
51
+ workflows?: Readonly<Record<string, DurableWorkflow<never, unknown>>>;
52
+ /** Command set the environment accepts; default `parity`. */
53
+ enabled?: 'core' | 'parity';
54
+ /** Workspace id written into run info. */
55
+ workspaceId?: string;
56
+ /**
57
+ * Run workflow tasks somewhere else than in this process, for example in
58
+ * an isolate over a built bundle (`runWorkflowTaskInVm`, the QuickJS
59
+ * runner). Start runs by export name then.
60
+ */
61
+ taskExecutor?: (request: WorkflowTaskRequest) => Promise<WorkflowTaskResult> | WorkflowTaskResult;
62
+ /** Workflow keys of tier-2 functions (key -> export name), for `ctx.child('<key>')` with a task executor. */
63
+ workflowKeys?: Readonly<Record<string, string>>;
64
+ }
65
+ interface StartOptions {
66
+ input?: unknown;
67
+ runId?: string;
68
+ /** Signals delivered right after the start (signal-with-start). */
69
+ signals?: Array<{
70
+ name: string;
71
+ payload?: unknown;
72
+ }>;
73
+ info?: Partial<WorkflowInfoSnapshot>;
74
+ }
75
+ /** A run's workflow failed (`WORKFLOW_FAILED`). */
76
+ declare class WorkflowFailedError extends Error {
77
+ readonly runId: string;
78
+ readonly failure: Failure;
79
+ constructor(runId: string, failure: Failure);
80
+ }
81
+ /** A workflow task failed; the test environment stops the run instead of retrying forever. */
82
+ declare class WorkflowTaskFailedError extends Error {
83
+ readonly runId: string;
84
+ readonly result: WorkflowTaskResult;
85
+ constructor(runId: string, result: WorkflowTaskResult);
86
+ }
87
+ /** The run is still open and nothing more can happen without outside input. */
88
+ declare class RunBlockedError extends Error {
89
+ readonly runId: string;
90
+ constructor(runId: string);
91
+ }
92
+ /** A handle to a run of the test environment. */
93
+ declare class TestRunHandle<Out = Json> {
94
+ private readonly env;
95
+ readonly runId: string;
96
+ constructor(env: TestWorkflowEnvironment, runId: string);
97
+ /** The run's history so far. */
98
+ history(): RunEventRecord[];
99
+ /** The history as a history file. */
100
+ historyFile(extra?: Partial<Omit<HistoryFile, 'format' | 'formatVersion' | 'workflowFn' | 'events'>>): HistoryFile;
101
+ /** Deliver a signal and run until idle (without skipping time). */
102
+ signal<P>(signal: SignalDefinition<P> | string, payload?: P): Promise<void>;
103
+ /** Request cancellation and run until idle (without skipping time). */
104
+ cancel(reason?: string): Promise<void>;
105
+ /** Terminate the run without running code. */
106
+ terminate(reason?: string): Promise<void>;
107
+ /** Run until this run (or the last run of its continue-as-new chain) ends; its output. */
108
+ result(): Promise<Out>;
109
+ /** The projected state of the run. */
110
+ state(): RunState;
111
+ }
112
+ /** The in-process test engine. */
113
+ declare class TestWorkflowEnvironment {
114
+ private clock;
115
+ private readonly timeSkipping;
116
+ private readonly enabled;
117
+ private readonly workspaceId;
118
+ private readonly runs;
119
+ private readonly runOrder;
120
+ private readonly mocks;
121
+ private readonly childMocks;
122
+ private readonly workflows;
123
+ private registry;
124
+ private attempts;
125
+ private timers;
126
+ private mockedChildren;
127
+ private runCounter;
128
+ private readonly executor;
129
+ private readonly workflowKeys;
130
+ private constructor();
131
+ /** Create an environment. */
132
+ static create(options?: TestEnvironmentOptions): Promise<TestWorkflowEnvironment>;
133
+ /** The fake clock, in epoch milliseconds. */
134
+ now(): number;
135
+ /** Mock a node operation (by node type, and operation when given). */
136
+ mock<In, Out>(operation: Operation<In, Out> | string, impl: (args: In, info: ActivityMockInfo) => Out | Promise<Out>, operationName?: string): void;
137
+ /** Mock a child workflow started by key (graph or durable). */
138
+ mockChild(workflowKey: string, impl: ChildMock): void;
139
+ /** Start a run of a tier-2 function (by declaration, or by export name with a task executor). */
140
+ start<In, Out>(definition: DurableWorkflow<In, Out> | string, options?: StartOptions): Promise<TestRunHandle<Out>>;
141
+ /** Advance the clock by `duration`, firing timers and running work as it comes due. */
142
+ sleep(duration: Duration): Promise<void>;
143
+ /** Every run, in start order. */
144
+ runIds(): string[];
145
+ historyOf(runId: string): RunEventRecord[];
146
+ historyFileOf(runId: string, extra?: Partial<Omit<HistoryFile, 'format' | 'formatVersion' | 'workflowFn' | 'events'>>): HistoryFile;
147
+ /** The failed workflow task that stopped a run, if one did. */
148
+ taskFailureOf(runId: string): WorkflowTaskResult | undefined;
149
+ stateOf(runId: string): RunState;
150
+ private ensureRegistered;
151
+ private run;
152
+ private createRun;
153
+ private append;
154
+ deliverSignal(runId: string, name: string, payload: unknown): boolean;
155
+ requestCancel(runId: string, reason?: string): boolean;
156
+ terminate(runId: string, reason: string): void;
157
+ /** Run every runnable task and activity; skip time when allowed and idle. */
158
+ runUntilIdle(skipTime: boolean): Promise<void>;
159
+ private nextDue;
160
+ private fireDue;
161
+ private runTask;
162
+ private afterCommand;
163
+ private resolveTarget;
164
+ private startChild;
165
+ private runMockedChild;
166
+ private runAttempt;
167
+ private onClosed;
168
+ resultOf(runId: string): Promise<Json>;
169
+ /** Every tier-2 function registered, by export name. */
170
+ registered(): Readonly<Record<string, DurableWorkflow<never, unknown>>>;
171
+ }
172
+
173
+ /** A history to replay: a history file, its text, or the events. */
174
+ type ReplayInput = HistoryFile | string | RunEventRecord[];
175
+ /** A replay that did not pass. */
176
+ declare class ReplayError extends Error {
177
+ readonly result: WorkflowTaskResult;
178
+ constructor(result: WorkflowTaskResult);
179
+ }
180
+ /** The task request that replays `history` (kind `verify`). */
181
+ declare function replayRequest(workflowFn: string, history: RunEventRecord[], info?: Partial<WorkflowInfoSnapshot>, nowMs?: number): WorkflowTaskRequest;
182
+ /**
183
+ * Replay a history against tier-2 functions in process. `workflows` is one
184
+ * function or a map by export name. Returns the task result; throws
185
+ * `DeterminismViolation` on a mismatch and {@link ReplayError} on any other
186
+ * task failure.
187
+ */
188
+ declare function replay(workflows: DurableWorkflow<never, unknown> | Readonly<Record<string, DurableWorkflow<never, unknown>>>, input: ReplayInput, options?: {
189
+ workflowFn?: string;
190
+ info?: Partial<WorkflowInfoSnapshot>;
191
+ nowMs?: number;
192
+ }): Promise<WorkflowTaskResult>;
193
+
194
+ /** One expected event: its type and, optionally, a subset of its payload. */
195
+ interface ExpectedEvent {
196
+ type: RunEventType;
197
+ payload?: Record<string, unknown>;
198
+ }
199
+ /** An assertion that did not hold. */
200
+ declare class HistoryAssertionError extends Error {
201
+ constructor(message: string);
202
+ }
203
+ /**
204
+ * Assert that `expected` appears in `history` in order (other events may be
205
+ * in between, unless `exact`). Payloads match when they contain the expected
206
+ * fields.
207
+ */
208
+ declare function assertHistory(history: readonly RunEventRecord[] | {
209
+ history(): RunEventRecord[];
210
+ }, expected: readonly ExpectedEvent[], options?: {
211
+ exact?: boolean;
212
+ ignore?: readonly RunEventType[];
213
+ }): void;
214
+ /** The IR of a tier-1 workflow or a definition, normalised, with its `irHash`. */
215
+ interface IRSnapshot {
216
+ definition: WorkflowDefinition;
217
+ irHash: string;
218
+ /** Throws unless `other` has the same `irHash`. */
219
+ toEqualIR(other: Tier1Workflow | WorkflowDefinition): void;
220
+ }
221
+ /** Snapshot helper for tier-1 workflows: `expect(expectIR(wf).definition).toMatchSnapshot()`. */
222
+ declare function expectIR(value: Tier1Workflow | WorkflowDefinition): IRSnapshot;
223
+ /** A JSON copy, for comparing results across engines. */
224
+ declare function jsonCopy(value: unknown): Json;
225
+
226
+ /**
227
+ * `simulate(ir, { trigger, mocks })`: walk a tier-1 graph without a cluster
228
+ * (spec 10 §1, reduced form accepted for Phase B, PLAN-B §9.1 item 5).
229
+ *
230
+ * It starts at the trigger node(s), passes each node's output to the nodes its
231
+ * edges lead to, and calls a mock for every node (by node id first, then by
232
+ * node type). Documented divergences from the engine:
233
+ * - No expressions are evaluated and no node runs for real: a node without a
234
+ * mock passes its input through.
235
+ * - Routing nodes follow the handle a mock returns (`{ handle: 'true' }`);
236
+ * without one, every outgoing edge is followed. Loops run their body once.
237
+ * - `internal:code-workflow` nodes run the tier-2 function in a
238
+ * `TestWorkflowEnvironment` when it is registered in `workflows`, else they
239
+ * need a mock.
240
+ * - Error policies, retries, waits and merges are not modelled; a node is
241
+ * visited at most `maxVisits` times (default 1).
242
+ */
243
+
244
+ /** What a node mock returns: an output, or an output and the handle to follow. */
245
+ type NodeMockResult = Json | {
246
+ output: Json;
247
+ handle?: string;
248
+ };
249
+ type NodeMock = (input: Json, node: WorkflowNode) => NodeMockResult | Promise<NodeMockResult>;
250
+ interface SimulateOptions {
251
+ /** The trigger output (the first node's output). */
252
+ trigger?: Json;
253
+ /** Mocks by node id or node type. */
254
+ mocks?: Readonly<Record<string, NodeMock>>;
255
+ /** Tier-2 functions by export name, for code-workflow nodes. */
256
+ workflows?: Readonly<Record<string, DurableWorkflow<never, unknown>>>;
257
+ /** Visits per node. Default 1. */
258
+ maxVisits?: number;
259
+ }
260
+ interface SimulatedStep {
261
+ nodeId: string;
262
+ type: string;
263
+ input: Json;
264
+ output: Json;
265
+ handle?: string;
266
+ }
267
+ interface SimulationResult {
268
+ steps: SimulatedStep[];
269
+ /** Output of every visited node by id (the last visit). */
270
+ outputs: Record<string, Json>;
271
+ }
272
+ /** Simulate a definition. */
273
+ declare function simulate(definition: WorkflowDefinition, options?: SimulateOptions): Promise<SimulationResult>;
274
+
275
+ /** Turn an ES module bundle into a script for `vm` (the exports land on `__fluidgridsBundle`). */
276
+ declare function bundleToScript(bundle: string, esbuild?: EsbuildApi): Promise<string>;
277
+ /**
278
+ * Run one task; `script` comes from {@link bundleToScript}. Node drains the
279
+ * context's promise jobs after every call (`microtaskMode: 'afterEvaluate'`);
280
+ * Bun has no such mode and runs them on the host queue, so the loop also
281
+ * yields to the host between calls. The result is the same on both.
282
+ */
283
+ declare function runWorkflowTaskInVm(script: string, request: WorkflowTaskRequest, options?: {
284
+ timeoutMs?: number;
285
+ }): Promise<WorkflowTaskResult>;
286
+
287
+ /**
288
+ * Run a workflow task in this process through the same runtime ABI the
289
+ * isolate uses: `start`, `step` until `done` with the promise jobs drained in
290
+ * between, `complete`. The test environment and `replay()` use it.
291
+ *
292
+ * In-process execution does not install the determinism shims (`Date.now()`
293
+ * and `Math.random()` are the real ones here); replay a recorded history in
294
+ * the isolate (`createWorkflowTaskRunner`) or with `runWorkflowTaskInVm` for
295
+ * that check.
296
+ */
297
+
298
+ /** Let every queued promise job run. */
299
+ declare function drainJobs(): Promise<void>;
300
+ /** A registry from export names to workflow functions. */
301
+ declare function registryOf(workflows: Readonly<Record<string, DurableWorkflow<never, unknown>>>): WorkflowRegistry;
302
+ /** Run one workflow task in process. */
303
+ declare function runWorkflowTaskInProcess(registry: WorkflowRegistry, request: WorkflowTaskRequest): Promise<WorkflowTaskResult>;
304
+
305
+ export { type ActivityMock, type ActivityMockInfo, type ChildMock, type ExpectedEvent, HistoryAssertionError, type IRSnapshot, type NodeMock, type NodeMockResult, ReplayError, type ReplayInput, RunBlockedError, type SimulateOptions, type SimulatedStep, type SimulationResult, type StartOptions, type TestEnvironmentOptions, TestRunHandle, TestWorkflowEnvironment, WorkflowFailedError, WorkflowTaskFailedError, assertHistory, bundleToScript, drainJobs, expectIR, jsonCopy, registryOf, replay, replayRequest, runWorkflowTaskInProcess, runWorkflowTaskInVm, simulate };
@@ -0,0 +1,305 @@
1
+ import { h as DurableWorkflow, O as Operation, j as Duration, l as SignalDefinition } from '../workflow-C2a05WUJ.js';
2
+ import { i as HistoryFile, m as RunState } from '../file-yuPCFU5b.js';
3
+ import { a6 as WorkflowInfoSnapshot, a7 as WorkflowTaskRequest, a8 as WorkflowTaskResult, U as RunEventRecord, F as Failure, V as RunEventType } from '../types-DV-HX_Gt.js';
4
+ import { a as Json, b as WorkflowDefinition, m as WorkflowNode } from '../types-BGoPzgcl.js';
5
+ import { x as Tier1Workflow } from '../workflow-Bpr3vnA_.js';
6
+ import { E as EsbuildApi } from '../lower-types-DQNBfWQn.js';
7
+ import { WorkflowRegistry } from '../runtime/index.js';
8
+ import 'esbuild';
9
+ import '../activation-DnhG7SmF.js';
10
+
11
+ /**
12
+ * `TestWorkflowEnvironment` (spec 10 §1): an in-process engine for tier-2
13
+ * workflows. It keeps histories in memory, runs workflow tasks through the
14
+ * real runtime ABI, appends exactly the events `history/apply.ts` prescribes,
15
+ * runs activities against mocks with the shared retry policy, fires timers on
16
+ * a fake clock, and runs child workflows, signals, cancellation and the
17
+ * parent-close policy. The histories it records are valid service histories:
18
+ * the conformance fixtures are recorded with it and then replayed in QuickJS
19
+ * and in `vm`.
20
+ *
21
+ * Divergences from the service (documented, accepted for Phase B):
22
+ * - Workflow tasks run in this process without the determinism shims.
23
+ * - A failed workflow task is not retried forever: the run stops, and
24
+ * `result()` rejects with {@link WorkflowTaskFailedError}.
25
+ * - Every task is a first attempt (no transient attempts), and activity
26
+ * start-to-close and heartbeat timeouts are not timed; a mock may throw a
27
+ * `TimeoutFailure` to simulate one. Schedule-to-close is honoured.
28
+ * - Graph child runs are mocks (`mockChild`).
29
+ */
30
+
31
+ /** What a mock receives besides the activity's args. */
32
+ interface ActivityMockInfo {
33
+ runId: string;
34
+ activityId: string;
35
+ attempt: number;
36
+ nodeType: string;
37
+ operation: string;
38
+ connection?: string;
39
+ }
40
+ type ActivityMock = (args: Json, info: ActivityMockInfo) => unknown;
41
+ type ChildMock = (input: Json, info: {
42
+ runId: string;
43
+ childId: string;
44
+ }) => unknown;
45
+ interface TestEnvironmentOptions {
46
+ /** Advance the clock to the next timer whenever every run is idle (default true). */
47
+ timeSkipping?: boolean;
48
+ /** Start of the fake clock. Default 2026-01-01T00:00:00.000Z. */
49
+ startTime?: number | string | Date;
50
+ /** Tier-2 functions by export name, for `ctx.child(fn)` and by-name starts. */
51
+ workflows?: Readonly<Record<string, DurableWorkflow<never, unknown>>>;
52
+ /** Command set the environment accepts; default `parity`. */
53
+ enabled?: 'core' | 'parity';
54
+ /** Workspace id written into run info. */
55
+ workspaceId?: string;
56
+ /**
57
+ * Run workflow tasks somewhere else than in this process, for example in
58
+ * an isolate over a built bundle (`runWorkflowTaskInVm`, the QuickJS
59
+ * runner). Start runs by export name then.
60
+ */
61
+ taskExecutor?: (request: WorkflowTaskRequest) => Promise<WorkflowTaskResult> | WorkflowTaskResult;
62
+ /** Workflow keys of tier-2 functions (key -> export name), for `ctx.child('<key>')` with a task executor. */
63
+ workflowKeys?: Readonly<Record<string, string>>;
64
+ }
65
+ interface StartOptions {
66
+ input?: unknown;
67
+ runId?: string;
68
+ /** Signals delivered right after the start (signal-with-start). */
69
+ signals?: Array<{
70
+ name: string;
71
+ payload?: unknown;
72
+ }>;
73
+ info?: Partial<WorkflowInfoSnapshot>;
74
+ }
75
+ /** A run's workflow failed (`WORKFLOW_FAILED`). */
76
+ declare class WorkflowFailedError extends Error {
77
+ readonly runId: string;
78
+ readonly failure: Failure;
79
+ constructor(runId: string, failure: Failure);
80
+ }
81
+ /** A workflow task failed; the test environment stops the run instead of retrying forever. */
82
+ declare class WorkflowTaskFailedError extends Error {
83
+ readonly runId: string;
84
+ readonly result: WorkflowTaskResult;
85
+ constructor(runId: string, result: WorkflowTaskResult);
86
+ }
87
+ /** The run is still open and nothing more can happen without outside input. */
88
+ declare class RunBlockedError extends Error {
89
+ readonly runId: string;
90
+ constructor(runId: string);
91
+ }
92
+ /** A handle to a run of the test environment. */
93
+ declare class TestRunHandle<Out = Json> {
94
+ private readonly env;
95
+ readonly runId: string;
96
+ constructor(env: TestWorkflowEnvironment, runId: string);
97
+ /** The run's history so far. */
98
+ history(): RunEventRecord[];
99
+ /** The history as a history file. */
100
+ historyFile(extra?: Partial<Omit<HistoryFile, 'format' | 'formatVersion' | 'workflowFn' | 'events'>>): HistoryFile;
101
+ /** Deliver a signal and run until idle (without skipping time). */
102
+ signal<P>(signal: SignalDefinition<P> | string, payload?: P): Promise<void>;
103
+ /** Request cancellation and run until idle (without skipping time). */
104
+ cancel(reason?: string): Promise<void>;
105
+ /** Terminate the run without running code. */
106
+ terminate(reason?: string): Promise<void>;
107
+ /** Run until this run (or the last run of its continue-as-new chain) ends; its output. */
108
+ result(): Promise<Out>;
109
+ /** The projected state of the run. */
110
+ state(): RunState;
111
+ }
112
+ /** The in-process test engine. */
113
+ declare class TestWorkflowEnvironment {
114
+ private clock;
115
+ private readonly timeSkipping;
116
+ private readonly enabled;
117
+ private readonly workspaceId;
118
+ private readonly runs;
119
+ private readonly runOrder;
120
+ private readonly mocks;
121
+ private readonly childMocks;
122
+ private readonly workflows;
123
+ private registry;
124
+ private attempts;
125
+ private timers;
126
+ private mockedChildren;
127
+ private runCounter;
128
+ private readonly executor;
129
+ private readonly workflowKeys;
130
+ private constructor();
131
+ /** Create an environment. */
132
+ static create(options?: TestEnvironmentOptions): Promise<TestWorkflowEnvironment>;
133
+ /** The fake clock, in epoch milliseconds. */
134
+ now(): number;
135
+ /** Mock a node operation (by node type, and operation when given). */
136
+ mock<In, Out>(operation: Operation<In, Out> | string, impl: (args: In, info: ActivityMockInfo) => Out | Promise<Out>, operationName?: string): void;
137
+ /** Mock a child workflow started by key (graph or durable). */
138
+ mockChild(workflowKey: string, impl: ChildMock): void;
139
+ /** Start a run of a tier-2 function (by declaration, or by export name with a task executor). */
140
+ start<In, Out>(definition: DurableWorkflow<In, Out> | string, options?: StartOptions): Promise<TestRunHandle<Out>>;
141
+ /** Advance the clock by `duration`, firing timers and running work as it comes due. */
142
+ sleep(duration: Duration): Promise<void>;
143
+ /** Every run, in start order. */
144
+ runIds(): string[];
145
+ historyOf(runId: string): RunEventRecord[];
146
+ historyFileOf(runId: string, extra?: Partial<Omit<HistoryFile, 'format' | 'formatVersion' | 'workflowFn' | 'events'>>): HistoryFile;
147
+ /** The failed workflow task that stopped a run, if one did. */
148
+ taskFailureOf(runId: string): WorkflowTaskResult | undefined;
149
+ stateOf(runId: string): RunState;
150
+ private ensureRegistered;
151
+ private run;
152
+ private createRun;
153
+ private append;
154
+ deliverSignal(runId: string, name: string, payload: unknown): boolean;
155
+ requestCancel(runId: string, reason?: string): boolean;
156
+ terminate(runId: string, reason: string): void;
157
+ /** Run every runnable task and activity; skip time when allowed and idle. */
158
+ runUntilIdle(skipTime: boolean): Promise<void>;
159
+ private nextDue;
160
+ private fireDue;
161
+ private runTask;
162
+ private afterCommand;
163
+ private resolveTarget;
164
+ private startChild;
165
+ private runMockedChild;
166
+ private runAttempt;
167
+ private onClosed;
168
+ resultOf(runId: string): Promise<Json>;
169
+ /** Every tier-2 function registered, by export name. */
170
+ registered(): Readonly<Record<string, DurableWorkflow<never, unknown>>>;
171
+ }
172
+
173
+ /** A history to replay: a history file, its text, or the events. */
174
+ type ReplayInput = HistoryFile | string | RunEventRecord[];
175
+ /** A replay that did not pass. */
176
+ declare class ReplayError extends Error {
177
+ readonly result: WorkflowTaskResult;
178
+ constructor(result: WorkflowTaskResult);
179
+ }
180
+ /** The task request that replays `history` (kind `verify`). */
181
+ declare function replayRequest(workflowFn: string, history: RunEventRecord[], info?: Partial<WorkflowInfoSnapshot>, nowMs?: number): WorkflowTaskRequest;
182
+ /**
183
+ * Replay a history against tier-2 functions in process. `workflows` is one
184
+ * function or a map by export name. Returns the task result; throws
185
+ * `DeterminismViolation` on a mismatch and {@link ReplayError} on any other
186
+ * task failure.
187
+ */
188
+ declare function replay(workflows: DurableWorkflow<never, unknown> | Readonly<Record<string, DurableWorkflow<never, unknown>>>, input: ReplayInput, options?: {
189
+ workflowFn?: string;
190
+ info?: Partial<WorkflowInfoSnapshot>;
191
+ nowMs?: number;
192
+ }): Promise<WorkflowTaskResult>;
193
+
194
+ /** One expected event: its type and, optionally, a subset of its payload. */
195
+ interface ExpectedEvent {
196
+ type: RunEventType;
197
+ payload?: Record<string, unknown>;
198
+ }
199
+ /** An assertion that did not hold. */
200
+ declare class HistoryAssertionError extends Error {
201
+ constructor(message: string);
202
+ }
203
+ /**
204
+ * Assert that `expected` appears in `history` in order (other events may be
205
+ * in between, unless `exact`). Payloads match when they contain the expected
206
+ * fields.
207
+ */
208
+ declare function assertHistory(history: readonly RunEventRecord[] | {
209
+ history(): RunEventRecord[];
210
+ }, expected: readonly ExpectedEvent[], options?: {
211
+ exact?: boolean;
212
+ ignore?: readonly RunEventType[];
213
+ }): void;
214
+ /** The IR of a tier-1 workflow or a definition, normalised, with its `irHash`. */
215
+ interface IRSnapshot {
216
+ definition: WorkflowDefinition;
217
+ irHash: string;
218
+ /** Throws unless `other` has the same `irHash`. */
219
+ toEqualIR(other: Tier1Workflow | WorkflowDefinition): void;
220
+ }
221
+ /** Snapshot helper for tier-1 workflows: `expect(expectIR(wf).definition).toMatchSnapshot()`. */
222
+ declare function expectIR(value: Tier1Workflow | WorkflowDefinition): IRSnapshot;
223
+ /** A JSON copy, for comparing results across engines. */
224
+ declare function jsonCopy(value: unknown): Json;
225
+
226
+ /**
227
+ * `simulate(ir, { trigger, mocks })`: walk a tier-1 graph without a cluster
228
+ * (spec 10 §1, reduced form accepted for Phase B, PLAN-B §9.1 item 5).
229
+ *
230
+ * It starts at the trigger node(s), passes each node's output to the nodes its
231
+ * edges lead to, and calls a mock for every node (by node id first, then by
232
+ * node type). Documented divergences from the engine:
233
+ * - No expressions are evaluated and no node runs for real: a node without a
234
+ * mock passes its input through.
235
+ * - Routing nodes follow the handle a mock returns (`{ handle: 'true' }`);
236
+ * without one, every outgoing edge is followed. Loops run their body once.
237
+ * - `internal:code-workflow` nodes run the tier-2 function in a
238
+ * `TestWorkflowEnvironment` when it is registered in `workflows`, else they
239
+ * need a mock.
240
+ * - Error policies, retries, waits and merges are not modelled; a node is
241
+ * visited at most `maxVisits` times (default 1).
242
+ */
243
+
244
+ /** What a node mock returns: an output, or an output and the handle to follow. */
245
+ type NodeMockResult = Json | {
246
+ output: Json;
247
+ handle?: string;
248
+ };
249
+ type NodeMock = (input: Json, node: WorkflowNode) => NodeMockResult | Promise<NodeMockResult>;
250
+ interface SimulateOptions {
251
+ /** The trigger output (the first node's output). */
252
+ trigger?: Json;
253
+ /** Mocks by node id or node type. */
254
+ mocks?: Readonly<Record<string, NodeMock>>;
255
+ /** Tier-2 functions by export name, for code-workflow nodes. */
256
+ workflows?: Readonly<Record<string, DurableWorkflow<never, unknown>>>;
257
+ /** Visits per node. Default 1. */
258
+ maxVisits?: number;
259
+ }
260
+ interface SimulatedStep {
261
+ nodeId: string;
262
+ type: string;
263
+ input: Json;
264
+ output: Json;
265
+ handle?: string;
266
+ }
267
+ interface SimulationResult {
268
+ steps: SimulatedStep[];
269
+ /** Output of every visited node by id (the last visit). */
270
+ outputs: Record<string, Json>;
271
+ }
272
+ /** Simulate a definition. */
273
+ declare function simulate(definition: WorkflowDefinition, options?: SimulateOptions): Promise<SimulationResult>;
274
+
275
+ /** Turn an ES module bundle into a script for `vm` (the exports land on `__fluidgridsBundle`). */
276
+ declare function bundleToScript(bundle: string, esbuild?: EsbuildApi): Promise<string>;
277
+ /**
278
+ * Run one task; `script` comes from {@link bundleToScript}. Node drains the
279
+ * context's promise jobs after every call (`microtaskMode: 'afterEvaluate'`);
280
+ * Bun has no such mode and runs them on the host queue, so the loop also
281
+ * yields to the host between calls. The result is the same on both.
282
+ */
283
+ declare function runWorkflowTaskInVm(script: string, request: WorkflowTaskRequest, options?: {
284
+ timeoutMs?: number;
285
+ }): Promise<WorkflowTaskResult>;
286
+
287
+ /**
288
+ * Run a workflow task in this process through the same runtime ABI the
289
+ * isolate uses: `start`, `step` until `done` with the promise jobs drained in
290
+ * between, `complete`. The test environment and `replay()` use it.
291
+ *
292
+ * In-process execution does not install the determinism shims (`Date.now()`
293
+ * and `Math.random()` are the real ones here); replay a recorded history in
294
+ * the isolate (`createWorkflowTaskRunner`) or with `runWorkflowTaskInVm` for
295
+ * that check.
296
+ */
297
+
298
+ /** Let every queued promise job run. */
299
+ declare function drainJobs(): Promise<void>;
300
+ /** A registry from export names to workflow functions. */
301
+ declare function registryOf(workflows: Readonly<Record<string, DurableWorkflow<never, unknown>>>): WorkflowRegistry;
302
+ /** Run one workflow task in process. */
303
+ declare function runWorkflowTaskInProcess(registry: WorkflowRegistry, request: WorkflowTaskRequest): Promise<WorkflowTaskResult>;
304
+
305
+ export { type ActivityMock, type ActivityMockInfo, type ChildMock, type ExpectedEvent, HistoryAssertionError, type IRSnapshot, type NodeMock, type NodeMockResult, ReplayError, type ReplayInput, RunBlockedError, type SimulateOptions, type SimulatedStep, type SimulationResult, type StartOptions, type TestEnvironmentOptions, TestRunHandle, TestWorkflowEnvironment, WorkflowFailedError, WorkflowTaskFailedError, assertHistory, bundleToScript, drainJobs, expectIR, jsonCopy, registryOf, replay, replayRequest, runWorkflowTaskInProcess, runWorkflowTaskInVm, simulate };