@fluidgrids/workflows 2026.1027.0 → 2026.1028.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 (168) hide show
  1. package/README.md +170 -18
  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-2DP2Y6EU.cjs +832 -0
  7. package/dist/chunk-2J6TF7YI.cjs +86 -0
  8. package/dist/chunk-3FOTFQ3J.js +1622 -0
  9. package/dist/chunk-4LYSEANA.js +199 -0
  10. package/dist/{chunk-KUTMY2IO.cjs → chunk-57MSZ24T.cjs} +162 -98
  11. package/dist/{chunk-BWSLWF2E.js → chunk-5HDSBTBX.js} +99 -32
  12. package/dist/chunk-623FVQSN.cjs +251 -0
  13. package/dist/{chunk-4DPEGDPW.js → chunk-6FSHT5IL.js} +4 -4
  14. package/dist/{chunk-REV7ZOA4.js → chunk-7AAZGVKD.js} +1 -35
  15. package/dist/chunk-7NQ37GZU.js +73 -0
  16. package/dist/chunk-ABFZWYHT.js +612 -0
  17. package/dist/{chunk-SS4LT2IP.js → chunk-BD7ZPG53.js} +5 -10
  18. package/dist/chunk-BO6OVILK.js +79 -0
  19. package/dist/chunk-C5OLWZ42.js +245 -0
  20. package/dist/chunk-CBL5JSCC.cjs +75 -0
  21. package/dist/{chunk-LSKSBVL4.cjs → chunk-CPDK3K5N.cjs} +6 -6
  22. package/dist/chunk-CSNWNFKU.cjs +1635 -0
  23. package/dist/chunk-DJYMDLV5.js +227 -0
  24. package/dist/{chunk-X4HKU3MX.js → chunk-E2VK7J2C.js} +3 -1
  25. package/dist/chunk-FMSW2HDF.cjs +267 -0
  26. package/dist/chunk-FQIHX7YI.cjs +80 -0
  27. package/dist/chunk-FR7KYWRO.cjs +41 -0
  28. package/dist/{chunk-AU3YW7FZ.cjs → chunk-GBQ33SIZ.cjs} +46 -51
  29. package/dist/{chunk-RRQ5HOBF.cjs → chunk-GVTZMA5C.cjs} +4 -4
  30. package/dist/chunk-H7KEVW2M.js +816 -0
  31. package/dist/chunk-HR3BN4C4.cjs +27 -0
  32. package/dist/chunk-IISBRUWJ.js +13 -0
  33. package/dist/chunk-JD2VQIDZ.cjs +15 -0
  34. package/dist/{chunk-PL73GJR4.js → chunk-JZ4TOOLN.js} +1 -1
  35. package/dist/chunk-L24YIZY7.cjs +207 -0
  36. package/dist/chunk-LNUQE6D6.js +39 -0
  37. package/dist/{chunk-BYJ7QTLY.cjs → chunk-NEIUQASE.cjs} +13 -13
  38. package/dist/chunk-P6TA5EZT.cjs +634 -0
  39. package/dist/chunk-PDHLTDZB.js +72 -0
  40. package/dist/chunk-PMCM2OH4.js +46 -0
  41. package/dist/chunk-PZCVF76Q.cjs +868 -0
  42. package/dist/{chunk-GO34UHSY.js → chunk-QAN5MZEM.js} +3 -3
  43. package/dist/{chunk-27HASETB.cjs → chunk-QKZL3ONM.cjs} +3 -1
  44. package/dist/chunk-SAENRNBJ.cjs +52 -0
  45. package/dist/{chunk-LMX35GNQ.js → chunk-SMCANK3F.js} +5 -4
  46. package/dist/{chunk-IZQNUNSU.cjs → chunk-SX2PNKKT.cjs} +18 -17
  47. package/dist/{chunk-LRM6JXJA.cjs → chunk-TBDXTV22.cjs} +0 -37
  48. package/dist/chunk-VOKMAAJP.js +848 -0
  49. package/dist/chunk-XB53G2DK.js +25 -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 +161 -165
  66. package/dist/ir/index.d.cts +32 -12
  67. package/dist/ir/index.d.ts +32 -12
  68. package/dist/ir/index.js +54 -61
  69. package/dist/lower-BuSvAFqi.d.cts +129 -0
  70. package/dist/lower-C_Qv_34S.d.ts +129 -0
  71. package/dist/lower-types-nofRXw9c.d.cts +15 -0
  72. package/dist/lower-types-nofRXw9c.d.ts +15 -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-CJNP4GHX.js +12 -0
  76. package/dist/node-evaluator-DMKPKUWA.cjs +22 -0
  77. package/dist/quickjs/index.cjs +256 -78
  78. package/dist/quickjs/index.d.cts +48 -7
  79. package/dist/quickjs/index.d.ts +48 -7
  80. package/dist/quickjs/index.js +254 -79
  81. package/dist/roundtrip/index.cjs +404 -129
  82. package/dist/roundtrip/index.d.cts +43 -8
  83. package/dist/roundtrip/index.d.ts +43 -8
  84. package/dist/roundtrip/index.js +260 -19
  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-DMOuaxRI.d.ts → workflow-Bpr3vnA_.d.ts} +60 -162
  98. package/dist/workflow-C2a05WUJ.d.ts +444 -0
  99. package/dist/{assemble-BJo9TECS.d.cts → workflow-FXUkpIBc.d.cts} +60 -162
  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 +85 -20
  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-265J2FCH.cjs +0 -33
  162. package/dist/chunk-LUXCXFOE.cjs +0 -269
  163. package/dist/chunk-S34NJE3A.js +0 -262
  164. package/dist/chunk-SRQRLWOS.js +0 -31
  165. package/dist/lower-DcOY8ux0.d.cts +0 -49
  166. package/dist/lower-Dw5grNrI.d.ts +0 -49
  167. package/dist/node-evaluator-2GTUZVPK.cjs +0 -17
  168. package/dist/node-evaluator-RMYEWCXZ.js +0 -8
@@ -0,0 +1,444 @@
1
+ import { a as Json, J as JsonObject, W as WorkflowInterface } from './types-BGoPzgcl.cjs';
2
+ import { a6 as WorkflowInfoSnapshot, R as RetryPolicy, c as ActivityCancellationType, w as Headers, P as ParentClosePolicy, C as ChildCancellationType } from './types-CpBBjaGX.cjs';
3
+
4
+ /**
5
+ * Node operation descriptors: what a builder call needs to know about the node
6
+ * it emits. Generated clients (`.fluidgrids/nodes.ts`) are lists of these;
7
+ * the built-in internal nodes and triggers ship here so `nodes.internal.*` and
8
+ * `triggers.*` work without a registry.
9
+ */
10
+
11
+ /** A file reference in node inputs and outputs. */
12
+ interface FileRef {
13
+ fileId: string;
14
+ name?: string;
15
+ mimeType?: string;
16
+ size?: number;
17
+ }
18
+ declare const OPERATION_TYPES: unique symbol;
19
+ /** One node operation. `In` and `Out` type the arguments and the output. */
20
+ interface Operation<In = Record<string, Json>, Out = Json> {
21
+ readonly kind: 'operation';
22
+ readonly nodeType: string;
23
+ /** Written as the node's `version` unless the call overrides it. */
24
+ readonly version?: string;
25
+ /** Written as the node's `operation_name` unless the call overrides it. */
26
+ readonly operation?: string;
27
+ readonly role?: 'trigger';
28
+ /** Type-level only; never present at run time. */
29
+ readonly [OPERATION_TYPES]?: {
30
+ input: In;
31
+ output: Out;
32
+ };
33
+ }
34
+ /** A trigger operation. */
35
+ type TriggerOperation<In = Record<string, Json>, Out = Json> = Operation<In, Out> & {
36
+ readonly role: 'trigger';
37
+ };
38
+ /** Describe a node operation (generated clients call this). */
39
+ declare function op<In = Record<string, Json>, Out = Json>(nodeType: string, version?: string, operation?: string): Operation<In, Out>;
40
+ /** Describe a trigger operation (generated clients call this). */
41
+ declare function trigger<In = Record<string, Json>, Out = Json>(nodeType: string, version?: string, operation?: string): TriggerOperation<In, Out>;
42
+ /** True for a value made by {@link op} or {@link trigger}. */
43
+ declare function isOperation(value: unknown): value is Operation<unknown, unknown>;
44
+ /** Built-in trigger nodes (`wspace-workflow-svc` `triggers/manifests`). */
45
+ declare const triggers: {
46
+ readonly api: TriggerOperation<Record<string, Json>, Json>;
47
+ readonly manual: TriggerOperation<Record<string, Json>, Json>;
48
+ readonly schedule: TriggerOperation<Record<string, Json>, Json>;
49
+ readonly webhook: TriggerOperation<Record<string, Json>, Json>;
50
+ readonly form: TriggerOperation<Record<string, Json>, Json>;
51
+ readonly errorTrigger: TriggerOperation<Record<string, Json>, Json>;
52
+ readonly workflowCall: TriggerOperation<Record<string, Json>, Json>;
53
+ readonly rssFeed: TriggerOperation<Record<string, Json>, Json>;
54
+ readonly httpPoll: TriggerOperation<Record<string, Json>, Json>;
55
+ readonly databasePoll: TriggerOperation<Record<string, Json>, Json>;
56
+ readonly emailImap: TriggerOperation<Record<string, Json>, Json>;
57
+ readonly fileUpload: TriggerOperation<Record<string, Json>, Json>;
58
+ readonly recordChange: TriggerOperation<Record<string, Json>, Json>;
59
+ readonly stateChange: TriggerOperation<Record<string, Json>, Json>;
60
+ };
61
+ /** Built-in internal nodes (`wspace-workflow-svc` `internalnodes/manifests`, plus the two IR v2 nodes). */
62
+ declare const internalNodes: {
63
+ readonly merge: Operation<Record<string, Json>, Json>;
64
+ readonly if: Operation<Record<string, Json>, Json>;
65
+ readonly switch: Operation<Record<string, Json>, Json>;
66
+ readonly loop: Operation<Record<string, Json>, Json>;
67
+ readonly set: Operation<Record<string, Json>, Json>;
68
+ readonly filter: Operation<Record<string, Json>, Json>;
69
+ readonly aggregate: Operation<Record<string, Json>, Json>;
70
+ readonly wait: Operation<Record<string, Json>, Json>;
71
+ readonly noop: Operation<Record<string, Json>, Json>;
72
+ readonly code: Operation<Record<string, Json>, Json>;
73
+ readonly http: Operation<Record<string, Json>, Json>;
74
+ readonly transform: Operation<Record<string, Json>, Json>;
75
+ readonly validate: Operation<Record<string, Json>, Json>;
76
+ readonly log: Operation<Record<string, Json>, Json>;
77
+ readonly error: Operation<Record<string, Json>, Json>;
78
+ readonly subworkflow: Operation<Record<string, Json>, Json>;
79
+ readonly compareDatasets: Operation<Record<string, Json>, Json>;
80
+ readonly splitOut: Operation<Record<string, Json>, Json>;
81
+ readonly limit: Operation<Record<string, Json>, Json>;
82
+ readonly dedupe: Operation<Record<string, Json>, Json>;
83
+ readonly sort: Operation<Record<string, Json>, Json>;
84
+ readonly dataTable: Operation<Record<string, Json>, Json>;
85
+ readonly respondToWebhook: Operation<Record<string, Json>, Json>;
86
+ readonly sendAndWait: Operation<Record<string, Json>, Json>;
87
+ readonly codeWorkflow: Operation<Record<string, Json>, Json>;
88
+ readonly waitForSignal: Operation<Record<string, Json>, Json>;
89
+ };
90
+ /** Node clients that need no registry: the internal nodes and `custom()`. */
91
+ declare const nodes: {
92
+ readonly internal: {
93
+ readonly merge: Operation<Record<string, Json>, Json>;
94
+ readonly if: Operation<Record<string, Json>, Json>;
95
+ readonly switch: Operation<Record<string, Json>, Json>;
96
+ readonly loop: Operation<Record<string, Json>, Json>;
97
+ readonly set: Operation<Record<string, Json>, Json>;
98
+ readonly filter: Operation<Record<string, Json>, Json>;
99
+ readonly aggregate: Operation<Record<string, Json>, Json>;
100
+ readonly wait: Operation<Record<string, Json>, Json>;
101
+ readonly noop: Operation<Record<string, Json>, Json>;
102
+ readonly code: Operation<Record<string, Json>, Json>;
103
+ readonly http: Operation<Record<string, Json>, Json>;
104
+ readonly transform: Operation<Record<string, Json>, Json>;
105
+ readonly validate: Operation<Record<string, Json>, Json>;
106
+ readonly log: Operation<Record<string, Json>, Json>;
107
+ readonly error: Operation<Record<string, Json>, Json>;
108
+ readonly subworkflow: Operation<Record<string, Json>, Json>;
109
+ readonly compareDatasets: Operation<Record<string, Json>, Json>;
110
+ readonly splitOut: Operation<Record<string, Json>, Json>;
111
+ readonly limit: Operation<Record<string, Json>, Json>;
112
+ readonly dedupe: Operation<Record<string, Json>, Json>;
113
+ readonly sort: Operation<Record<string, Json>, Json>;
114
+ readonly dataTable: Operation<Record<string, Json>, Json>;
115
+ readonly respondToWebhook: Operation<Record<string, Json>, Json>;
116
+ readonly sendAndWait: Operation<Record<string, Json>, Json>;
117
+ readonly codeWorkflow: Operation<Record<string, Json>, Json>;
118
+ readonly waitForSignal: Operation<Record<string, Json>, Json>;
119
+ };
120
+ /**
121
+ * Any node type, including ones the registry snapshot does not know. Typed
122
+ * as JSON in and out.
123
+ */
124
+ readonly custom: (nodeType: string, operation?: string, version?: string) => Operation<Record<string, Json>, Json>;
125
+ };
126
+
127
+ /**
128
+ * Signal, query and update definitions (spec 02 §4, 05). Signals work in Phase
129
+ * B; queries and updates can be declared (they appear in the interface) but
130
+ * custom handlers are Phase C.
131
+ */
132
+ declare const PAYLOAD: unique symbol;
133
+ interface SignalDefinition<Payload = unknown> {
134
+ readonly kind: 'signal';
135
+ readonly name: string;
136
+ readonly description?: string;
137
+ /** JSON Schema of the payload, written into the workflow interface. */
138
+ readonly schema?: Record<string, unknown>;
139
+ /** Type-level only. */
140
+ readonly [PAYLOAD]?: Payload;
141
+ }
142
+ interface QueryDefinition<Result = unknown, Args = unknown> {
143
+ readonly kind: 'query';
144
+ readonly name: string;
145
+ readonly description?: string;
146
+ readonly [PAYLOAD]?: {
147
+ result: Result;
148
+ args: Args;
149
+ };
150
+ }
151
+ interface UpdateDefinition<Args = unknown, Result = unknown> {
152
+ readonly kind: 'update';
153
+ readonly name: string;
154
+ readonly description?: string;
155
+ readonly [PAYLOAD]?: {
156
+ result: Result;
157
+ args: Args;
158
+ };
159
+ }
160
+ interface DefinitionOptions {
161
+ description?: string;
162
+ schema?: Record<string, unknown>;
163
+ }
164
+ /** Declare a signal. */
165
+ declare function defineSignal<Payload = unknown>(name: string, options?: DefinitionOptions): SignalDefinition<Payload>;
166
+ /** Declare a query. Handlers are Phase C; the declaration appears in the interface. */
167
+ declare function defineQuery<Result = unknown, Args = unknown>(name: string, options?: {
168
+ description?: string;
169
+ }): QueryDefinition<Result, Args>;
170
+ /** Declare an update. Handlers are Phase C; the declaration appears in the interface. */
171
+ declare function defineUpdate<Args = unknown, Result = unknown>(name: string, options?: {
172
+ description?: string;
173
+ }): UpdateDefinition<Args, Result>;
174
+
175
+ /** A duration: milliseconds, or a string such as `'30s'` or `'PT2H'`. */
176
+ type Duration = number | string;
177
+ /** Milliseconds of `value`; throws a `TypeError` naming `what` when it is not a duration. */
178
+ declare function toMs(value: Duration, what?: string): number;
179
+
180
+ /**
181
+ * The `WorkflowContext` a tier-2 workflow function receives (spec 02 §4). The
182
+ * runtime (`src/runtime/`) implements it; this module is types only.
183
+ */
184
+
185
+ /** Options of `ctx.run`. */
186
+ interface RunOptions<In> {
187
+ args: In;
188
+ /** Connection name, resolved by the service at `SCHEDULE_ACTIVITY`. */
189
+ connection?: string;
190
+ /** Default: 1 s, x2, at most 100 s, unlimited attempts (Temporal's policy). */
191
+ retry?: Partial<RetryPolicy>;
192
+ startToCloseTimeout?: Duration;
193
+ scheduleToCloseTimeout?: Duration;
194
+ scheduleToStartTimeout?: Duration;
195
+ heartbeatTimeout?: Duration;
196
+ cancellationType?: ActivityCancellationType;
197
+ /** 1 (highest) to 5; default 3. */
198
+ priority?: number;
199
+ /** Label in the History tab (at most 200 characters). */
200
+ summary?: string;
201
+ runOn?: string;
202
+ /** Overrides the operation name the descriptor carries. */
203
+ operation?: string;
204
+ /** Overrides the node version the descriptor carries. */
205
+ nodeVersion?: string;
206
+ headers?: Headers;
207
+ }
208
+ /** Options of `ctx.child` and `ctx.startChild` (11 §2.35). */
209
+ interface ChildOptions {
210
+ input?: unknown;
211
+ /** `active` (default), `vN` or `@alias`. */
212
+ version?: string;
213
+ taskQueue?: string;
214
+ /** Default `TERMINATE` for `ctx.child`, `ABANDON` for `ctx.startChild` (DB13). */
215
+ parentClosePolicy?: ParentClosePolicy;
216
+ /**
217
+ * How the awaitable reacts when its scope is cancelled. Unset, it rejects at
218
+ * once and the child is left to the parent-close policy; set, the SDK sends
219
+ * a cancel request to the child (`REQUEST_CANCEL_EXTERNAL_RUN`, a parity
220
+ * command).
221
+ */
222
+ cancellationType?: ChildCancellationType;
223
+ workflowId?: string;
224
+ priority?: number;
225
+ summary?: string;
226
+ details?: string;
227
+ context?: JsonObject;
228
+ startDelay?: Duration;
229
+ executionTimeout?: Duration;
230
+ runTimeout?: Duration;
231
+ workflowTaskTimeout?: Duration;
232
+ headers?: Headers;
233
+ }
234
+ /** A started child run. */
235
+ interface ChildHandle<Out = Json> {
236
+ readonly childId: string;
237
+ readonly runId: string;
238
+ result(): Promise<Out>;
239
+ signal<P>(signal: SignalDefinition<P> | string, payload?: P): Promise<void>;
240
+ /** Request cancellation of the child (parity command `REQUEST_CANCEL_EXTERNAL_RUN`). */
241
+ cancel(): Promise<void>;
242
+ }
243
+ /** A handle to another run of the workspace (11 §2.24). */
244
+ interface ExternalRunHandle {
245
+ readonly runId: string;
246
+ signal<P>(signal: SignalDefinition<P> | string, payload?: P): Promise<void>;
247
+ /** Resolves when the cancel request was delivered, not when the run ends. */
248
+ cancel(): Promise<void>;
249
+ }
250
+ /** A cancellation scope (11 §2.24). */
251
+ interface CancellationScope {
252
+ /** Rejects with `CancelledFailure` when the scope is cancelled. */
253
+ readonly cancelRequested: Promise<never>;
254
+ readonly consideredCancelled: boolean;
255
+ cancel(): void;
256
+ }
257
+ interface CancellationScopeOptions {
258
+ /** A durable timer that cancels the scope when it fires. */
259
+ timeout?: Duration;
260
+ nonCancellable?: boolean;
261
+ }
262
+ /** `ctx.cancellationScope(fn, options)` and `ctx.cancellationScope.current()`. */
263
+ interface CancellationScopeFunction {
264
+ <T>(fn: (ctx: WorkflowContext) => Promise<T>, options?: CancellationScopeOptions): Promise<T>;
265
+ current(): CancellationScope;
266
+ }
267
+ /** What workflow code knows about its run. */
268
+ interface WorkflowInfo extends WorkflowInfoSnapshot {
269
+ readonly workflowFn: string;
270
+ /** Events in the history when the current workflow task started. */
271
+ readonly historyLength: number;
272
+ /** UTF-8 bytes of their payloads. */
273
+ readonly historyBytes: number;
274
+ /** True from 80 % of the history cap; continue as new soon. */
275
+ readonly continueAsNewSuggested: boolean;
276
+ readonly isReplaying: boolean;
277
+ }
278
+ /** Logging from workflow code; lines are emitted once, never during replay. */
279
+ interface WorkflowLogger {
280
+ debug(message: string, data?: Json): void;
281
+ info(message: string, data?: Json): void;
282
+ warn(message: string, data?: Json): void;
283
+ error(message: string, data?: Json): void;
284
+ }
285
+ /**
286
+ * Compensations run in reverse order, each in its own non-cancellable scope,
287
+ * so they still run after a cancel request. A compensation receives that
288
+ * scope's `ctx`; use it for every call after the compensation's first await.
289
+ */
290
+ interface Saga {
291
+ add(compensation: (ctx: WorkflowContext) => unknown): void;
292
+ compensate(): Promise<void>;
293
+ }
294
+ interface ContinueAsNewOptions {
295
+ taskQueue?: string;
296
+ retry?: Partial<RetryPolicy>;
297
+ workflowTaskTimeout?: Duration;
298
+ context?: JsonObject;
299
+ versioningBehavior?: 'PINNED' | 'AUTO_UPGRADE';
300
+ }
301
+ /** A child target: a workflow key (graph or durable) or a tier-2 function of the same bundle. */
302
+ type ChildTarget<Out> = string | DurableWorkflow<never, Out> | DurableWorkflow<Json, Out>;
303
+ /** The context of a tier-2 workflow function. */
304
+ interface WorkflowContext {
305
+ readonly info: WorkflowInfo;
306
+ readonly log: WorkflowLogger;
307
+ /** Run a canvas node operation as a durable activity (`SCHEDULE_ACTIVITY`, kind `node`). */
308
+ run<In, Out>(operation: Operation<In, Out>, options: RunOptions<In>): Promise<Out>;
309
+ /** A durable timer. */
310
+ sleep(duration: Duration, options?: {
311
+ summary?: string;
312
+ }): Promise<void>;
313
+ /** Resolves `true` once `predicate` holds after an event, or `false` when `timeout` passes first. */
314
+ condition(predicate: () => boolean, timeout?: Duration): Promise<boolean>;
315
+ /** The next signal of this name (buffered signals first). */
316
+ signalReceived<P>(signal: SignalDefinition<P> | string): Promise<P>;
317
+ /** Handle every signal of this name, buffered ones first. */
318
+ onSignal<P>(signal: SignalDefinition<P> | string, handler: (payload: P) => unknown): void;
319
+ /** Handle signals no other handler or waiter takes. */
320
+ setDefaultSignalHandler(handler: (name: string, payload: unknown) => unknown): void;
321
+ /** Start a child run and wait for its result. */
322
+ child<Out = Json>(target: ChildTarget<Out>, options?: ChildOptions): Promise<Out>;
323
+ /** Start a child run; resolves once it has started. */
324
+ startChild<Out = Json>(target: ChildTarget<Out>, options?: ChildOptions): Promise<ChildHandle<Out>>;
325
+ /** Signal another run of the workspace; resolves on delivery. */
326
+ signalRun<P>(runId: string, signal: SignalDefinition<P> | string, payload?: P): Promise<void>;
327
+ /** Signal the parent run. */
328
+ signalParent<P>(signal: SignalDefinition<P> | string, payload?: P): Promise<void>;
329
+ getRunHandle(runId: string): ExternalRunHandle;
330
+ /** Shorthand for `getRunHandle(runId).cancel()`. */
331
+ cancelRun(runId: string): Promise<void>;
332
+ /** The workflow clock (the task's start time), in epoch milliseconds. */
333
+ now(): number;
334
+ /** A deterministic random number in [0, 1), seeded per run. */
335
+ random(): number;
336
+ /** A deterministic version-4 UUID. */
337
+ uuid(): string;
338
+ /** Record a value once (`RECORD_SIDE_EFFECT`); replays return the recorded value. */
339
+ sideEffect<T extends Json>(fn: () => T): T;
340
+ /** In-place versioning (spec 06 §4). */
341
+ patched(patchId: string): boolean;
342
+ deprecatePatch(patchId: string): void;
343
+ /** Live Markdown status for the run page and `__metadata` (at most 20 KiB). */
344
+ setCurrentDetails(markdown: string): void;
345
+ /** Merge keys into the run's context (parity command `UPSERT_CONTEXT`). */
346
+ upsertContext(entries: JsonObject): void;
347
+ /** End this run and start a fresh history (parity command `CONTINUE_AS_NEW`). */
348
+ continueAsNew(input: unknown, options?: ContinueAsNewOptions): Promise<never>;
349
+ /**
350
+ * Run `fn` in a new cancellation scope. `fn` gets a `ctx` bound to the
351
+ * scope: use it inside `fn`. This outer `ctx` joins the scope only while
352
+ * `fn` runs synchronously; after an await it is back in its own scope, so
353
+ * concurrent branches never share a scope by accident.
354
+ */
355
+ readonly cancellationScope: CancellationScopeFunction;
356
+ /** `cancellationScope(fn, { nonCancellable: true })`; the same `ctx` rule applies. */
357
+ nonCancellable<T>(fn: (ctx: WorkflowContext) => Promise<T>): Promise<T>;
358
+ /**
359
+ * Run `fn` when the current scope is cancelled. An error thrown by `fn` is
360
+ * handled like an error thrown by the workflow; the other handlers still run.
361
+ */
362
+ onCancel(fn: () => void): void;
363
+ isCancellation(error: unknown): boolean;
364
+ saga(): Saga;
365
+ /** Resolves when no asynchronous signal handler is running; cancellation does not interrupt the wait. */
366
+ allHandlersFinished(): Promise<void>;
367
+ /** Phase C: user activities. Throws `PhaseCFeatureError`. */
368
+ activity(...args: unknown[]): Promise<never>;
369
+ /** Phase B parity: local activities. Throws `PhaseCFeatureError` in this release. */
370
+ localActivity(...args: unknown[]): Promise<never>;
371
+ /** Phase C: custom queries. Throws `PhaseCFeatureError`. */
372
+ handleQuery(...args: unknown[]): void;
373
+ /** Phase C: updates. Throws `PhaseCFeatureError`. */
374
+ handleUpdate(...args: unknown[]): void;
375
+ /** Phase C: search attributes. Throws `PhaseCFeatureError`. */
376
+ upsertSearchAttributes(...args: unknown[]): void;
377
+ }
378
+
379
+ /**
380
+ * `workflow()`: declare a tier-2 durable workflow function (spec 02 §4).
381
+ *
382
+ * The value is inert data plus the function: nothing runs at module load.
383
+ * `lower()` reads it to report `code.exports.workflows[exportName]`, and the
384
+ * runtime (`src/runtime/`) calls the function by export name inside a
385
+ * workflow task.
386
+ */
387
+
388
+ declare const DURABLE_MARKER = "fluidgrids.durable-workflow";
389
+ /**
390
+ * A payload schema: a JSON Schema object, or a schema library value with a
391
+ * `toJSONSchema()` method. Anything else (a zod schema without one, for
392
+ * example) types the code but leaves the interface without that schema.
393
+ */
394
+ type SchemaLike = Record<string, unknown> | {
395
+ toJSONSchema(): unknown;
396
+ };
397
+ /** How a standalone tier-2 workflow starts (lowered to its trigger node). */
398
+ type TriggerSpec = Operation<never, unknown> | Operation<Record<string, Json>, Json> | {
399
+ operation: Operation<never, unknown> | Operation<Record<string, Json>, Json>;
400
+ args?: JsonObject;
401
+ id?: string;
402
+ };
403
+ interface DurableWorkflowOptions {
404
+ /** Display name of the standalone workflow. */
405
+ title?: string;
406
+ description?: string;
407
+ input?: SchemaLike;
408
+ output?: SchemaLike;
409
+ signals?: ReadonlyArray<SignalDefinition<never> | SignalDefinition<unknown>>;
410
+ /** Declared only; handlers are Phase C. */
411
+ queries?: ReadonlyArray<QueryDefinition<unknown, unknown>>;
412
+ /** Declared only; handlers are Phase C. */
413
+ updates?: ReadonlyArray<UpdateDefinition<unknown, unknown>>;
414
+ /** Default `managed`. */
415
+ taskQueue?: string;
416
+ /** Lowers to the trigger node of the standalone workflow (default `internal:api`). */
417
+ trigger?: TriggerSpec;
418
+ /**
419
+ * Whether the function is a workflow of its own (07 §4): by default, when it
420
+ * declares a trigger or nothing in the project embeds it with `wf.codeWorkflow`.
421
+ */
422
+ standalone?: boolean;
423
+ /** Error classes that fail the run instead of the workflow task (11 §2.25). */
424
+ failureErrorTypes?: ReadonlyArray<abstract new (...args: never[]) => Error>;
425
+ }
426
+ /** A declared tier-2 workflow. */
427
+ interface DurableWorkflow<In = Json, Out = Json> {
428
+ readonly __fluidgrids: typeof DURABLE_MARKER;
429
+ /** The workflow key it gets when it is standalone. */
430
+ readonly name: string;
431
+ readonly options: DurableWorkflowOptions;
432
+ readonly fn: (ctx: WorkflowContext, input: In) => Promise<Out>;
433
+ }
434
+ /** Declare a tier-2 workflow. `name` is its workflow key when it is standalone. */
435
+ declare function workflow<In = Json, Out = Json>(name: string, options: DurableWorkflowOptions, fn: (ctx: WorkflowContext, input: In) => Promise<Out>): DurableWorkflow<In, Out>;
436
+ declare function workflow<In = Json, Out = Json>(name: string, fn: (ctx: WorkflowContext, input: In) => Promise<Out>): DurableWorkflow<In, Out>;
437
+ /** True for a value made by {@link workflow}. */
438
+ declare function isDurableWorkflow(value: unknown): value is DurableWorkflow<never, unknown>;
439
+ /** The JSON Schema of a {@link SchemaLike}, or undefined when it has none. */
440
+ declare function jsonSchemaOf(schema: SchemaLike | undefined): JsonObject | undefined;
441
+ /** The workflow `interface` (spec 01 §4) a tier-2 declaration describes. */
442
+ declare function interfaceOf(definition: DurableWorkflow<never, unknown>): WorkflowInterface;
443
+
444
+ export { trigger as A, triggers as B, type CancellationScope as C, DURABLE_MARKER as D, type ExternalRunHandle as E, type FileRef as F, workflow as G, type Operation as O, type QueryDefinition as Q, type RunOptions as R, type Saga as S, type TriggerOperation as T, type UpdateDefinition as U, type WorkflowContext as W, type CancellationScopeFunction as a, type CancellationScopeOptions as b, type ChildHandle as c, type ChildOptions as d, type ChildTarget as e, type ContinueAsNewOptions as f, type DefinitionOptions as g, type DurableWorkflow as h, type DurableWorkflowOptions as i, type Duration as j, type SchemaLike as k, type SignalDefinition as l, type TriggerSpec as m, type WorkflowInfo as n, type WorkflowLogger as o, defineQuery as p, defineSignal as q, defineUpdate as r, interfaceOf as s, internalNodes as t, isDurableWorkflow as u, isOperation as v, jsonSchemaOf as w, nodes as x, op as y, toMs as z };
@@ -0,0 +1,128 @@
1
+ # Shared round-trip fixtures
2
+
3
+ These fixtures are the conformance suite for the tier-1 builders in
4
+ `@fluidgrids/workflows` (TypeScript, this repo) and `fluidgrids-workflows`
5
+ (Python, `fluidgrids-workflows-sdk-python`). Spec 03 §2 and spec 10 §2 require
6
+ both SDKs to lower the same graph to byte-identical IR; this directory is where
7
+ that is checked.
8
+
9
+ Everything except `ir.json`, `index.json`, `registry.json` and
10
+ `connections.json` is generated. Regenerate with `bun run check:fixtures --write`
11
+ and check with `bun run check:fixtures --ruff` (CI does both checks).
12
+
13
+ ## Layout
14
+
15
+ ```
16
+ fixtures/
17
+ index.json every fixture: name, source, what it covers
18
+ registry.json node registry snapshot (9 store nodes from fluidgrids-nodes, contract fields only)
19
+ connections.json connectionId -> { name, adapter }
20
+ .fluidgrids/nodes.ts generated clients for registry.json (generateNodeClients(..., 'ts'))
21
+ .fluidgrids/nodes.py generated clients for registry.json (generateNodeClients(..., 'py'))
22
+ <fixture>/
23
+ ir.json the input definition, as stored (not normalised)
24
+ expected.ir.json normalizeDefinition(ir) with the workflow key and without authoring:
25
+ what lowering the code must reproduce
26
+ fixture.json { key, irHash, fidelity, items }
27
+ workflows/<key>.ts lifted tier-1 TypeScript (Prettier, pinned options)
28
+ workflows/<key_snake>.py lifted tier-1 Python (Ruff-stable, line length 88)
29
+ workflows/<key>.layout.json positions, sticky notes and meta.layout
30
+ .fluidgrids -> ../.fluidgrids so each fixture directory is a complete project
31
+ ```
32
+
33
+ ## The conformance check
34
+
35
+ For every fixture, lowering `workflows/<key_snake>.py` (with the layout sidecar
36
+ and `connections.json` resolving connection names to `{ connectionId, adapter }`)
37
+ must give a definition whose `irHash` equals `fixture.json` `irHash`. That is
38
+ the same check the TypeScript suite runs on `workflows/<key>.ts`
39
+ (`tests/fixtures.test.ts`, invariants 1 and 2 of spec 07 §5).
40
+
41
+ `irHash` is `sha256:` + the SHA-256 of the RFC 8785 canonical JSON of the
42
+ normalised definition without its `authoring` block. Provenance
43
+ (`authoring.generator` is `sdk-ts` or `sdk-py`) is not content, so the two SDKs
44
+ hash equally. Implement RFC 8785 exactly (keys sorted by UTF-16 code units,
45
+ ECMAScript number formatting, no whitespace) and `normalizeDefinition` as
46
+ `src/ir/normalize.ts` documents it.
47
+
48
+ ## The Python tier-1 surface the fixtures pin
49
+
50
+ The Python files are printed from the same lift plan as the TypeScript files,
51
+ so they define the Python builder's surface:
52
+
53
+ - Imports: `from fluidgrids_workflows import and_, define_workflow, edge, expr, nodes, or_, triggers`
54
+ and `from fluidgrids_workflows.project import nodes as n`, which resolves to the
55
+ project's `.fluidgrids/nodes.py`.
56
+ - `@define_workflow(key=..., name=..., description=..., config=..., interface=..., code=..., tags=..., meta=..., extra=...)`
57
+ on `def <key_snake>(wf):`.
58
+ - Builder methods: `wf.trigger(op, ...)`, `wf.step(op, ...)` and the helpers
59
+ `if_`, `switch`, `loop`, `merge`, `wait`, `wait_for_signal`, `send_and_wait`,
60
+ `subworkflow`, `validate`, `compare_datasets`, `set`, `filter`, `aggregate`,
61
+ `split_out`, `limit`, `dedupe`, `sort`, `data_table`, `http`, `code`,
62
+ `transform`, `log`, `respond_to_webhook`, `stop_and_error`, `noop`; plus
63
+ `wf.ref(id)`, `wf.connect(source, target_id, **edge_options)`,
64
+ `wf.edge_order_is([...])`, `wf.json`, `wf.vars`, `wf.now`, `wf.execution`.
65
+ - Keyword options are the TypeScript option names in snake_case: `id`, `label`,
66
+ `after`, `args`, `operation`, `version`, `connection`, `connections`,
67
+ `credentials`, `context`, `retry`, `timeout`, `on_error`, `error_config`,
68
+ `execution_settings`, `disabled`, `extra`, `condition`; edge options `id`,
69
+ `type`, `target_handle`, `label`, `data`, `mapping`, `extra`.
70
+ - Option values are never converted: `args`, `retry`, `timeout`, `config`,
71
+ `extra` and every other dictionary keep the IR's own keys (`maxRetries`,
72
+ `channelId`, `link_names`), so they lower byte for byte. This is a deliberate
73
+ difference from the snake_case `retry` keys sketched in spec 03 §2.
74
+ - `False` for `operation`, `version` and edge `id` / `type` means "write no
75
+ such field"; leaving the option out means "write the default" (the
76
+ descriptor's operation and version, the default edge id
77
+ `e-<source>-<target>[-<sourceHandle>][-<targetHandle>]`, edge type `deletable`).
78
+ Default ids are given after the callback returns: explicit ids are claimed
79
+ first, and a default id that is already taken gets `-2`, `-3`, … in
80
+ declaration order. Only a repeated explicit id is an error.
81
+ - References: `node.output.a.b`, `["key"]` for keys that are not identifiers,
82
+ Python keywords, names starting with `_`, or reference method names, and
83
+ `[0]` for indices. They lower to `{{ $node["<id>"].item.<path> }}`;
84
+ `wf.json.x` lowers to `{{ $json.x }}`.
85
+ - Conditions: `>=`, `>`, `<=`, `<`, `==`, `!=` on a reference, the methods
86
+ `contains`, `not_contains`, `starts_with`, `ends_with`, `matches` (operator
87
+ `regex`), `has_property`, `is_empty`, `is_not_empty`, `is_null`,
88
+ `is_not_null`, `is_true`, `is_false`, the generic `is_(operator[, value])`,
89
+ and `and_()` / `or_()`. A condition field is `WorkflowState.<id>.<path>` for a
90
+ node output and `output.<path>` for `wf.json`; one top-level rule is wrapped
91
+ in an `AND` group.
92
+ - `expr("text ", ref, " more")` concatenates its parts; references render as
93
+ `{{ … }}`.
94
+ - Typed handles: `if_` → `.true`, `.false`; `loop` → `.body`, `.done`;
95
+ `validate` → `.valid`, `.invalid`; `send_and_wait` → `.approved`,
96
+ `.declined`, `.timed_out`; `wait_for_signal` → `.received`, `.timed_out`;
97
+ `compare_datasets` → `.in_a_only`, `.in_b_only`, `.same`, `.different`;
98
+ `switch` → `.case("h")`, `.default`; any node → `.handle("h")`.
99
+ - Generated clients: `op(node_type, version, operation, InputTypedDict, OutputTypedDict)`
100
+ and `trigger(...)` with the same arguments; `nodes.<group>.<operation>` and
101
+ `triggers.<group>.<operation>` use snake_case names (`n.slack.send_message`).
102
+ `fluidgrids_workflows` must export `op`, `trigger`, `Json` and `FileRef`.
103
+
104
+ ## Substitutions and corrections in the fixtures
105
+
106
+ - **Real nodes only.** `store/clearbit` (example 02) is replaced by
107
+ `internal:http` calling the Clearbit API with a saved connection;
108
+ `store/warehouse-erp` (example 01) by `store/postgresql` `executeQuery`; the
109
+ `store/slack` `sendAndWait` operation (example 01), which does not exist, by
110
+ `internal:send-and-wait`. Store operations and argument names are the ones in
111
+ `registry.json` (for example Slack `channelId`, Stripe `createRefund`
112
+ `charge`).
113
+ - **The expression form the workers evaluate.** The examples write
114
+ `{{ $node["x"].json.path }}`; the expression language exposes
115
+ `$node["x"].item` (there is no `.json`), so the fixtures use `.item`.
116
+ - **The condition tree the IF node evaluates.** The examples write
117
+ `{ op, left, right }`; `internal:if` evaluates
118
+ `{ type: "group", combinator, children: [{ type: "rule", field, operator, value }] }`.
119
+ - **Example 01** routed both `declined` and `timedOut` from `approve` to
120
+ `refund`. Two edges between the same pair of nodes are rejected by the
121
+ service validator, so the fixture keeps the `declined` edge only.
122
+ - **Examples 03, 04 and 05** have no canvas JSON in the spec. Their `ir.json`
123
+ was produced by writing the example's tier-1 code against the real nodes and
124
+ lowering it once; the lifted `workflows/*.ts` is that code in canonical form.
125
+ - **Doctor samples** (`fg-uc-*`, `doctor-*`) are the `definitionJson` of the
126
+ fluidgrids-doctor samples, with `key` added from the file name. They keep
127
+ their legacy `${…}` templates, `config` parameters and `store:<name>` types,
128
+ which is the point: they are what stored definitions look like.