@fluidgrids/workflows 2026.1029.1 → 2026.1030.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 (118) hide show
  1. package/README.md +112 -4
  2. package/dist/{activation-CESehfYi.d.cts → activation-DqUfpHzk.d.cts} +1 -1
  3. package/dist/{activation-BnVQMv9y.d.ts → activation-xpx1oWuo.d.ts} +1 -1
  4. package/dist/{chunk-MJ5TGYVG.js → chunk-2D3MYIIF.js} +969 -153
  5. package/dist/{chunk-2B37XAFQ.cjs → chunk-3U2NU7YC.cjs} +24 -11
  6. package/dist/{chunk-NEIUQASE.cjs → chunk-4QKB4ARC.cjs} +3 -3
  7. package/dist/{chunk-GBQ33SIZ.cjs → chunk-54FLQNUM.cjs} +12 -1
  8. package/dist/{chunk-2DDULZFM.js → chunk-5HIVIV53.js} +86 -75
  9. package/dist/chunk-5MFVJM76.js +1222 -0
  10. package/dist/{chunk-EWYADREB.cjs → chunk-672KMMBK.cjs} +2 -2
  11. package/dist/{chunk-KXJDRQ6G.js → chunk-6A2FGSUS.js} +22 -2
  12. package/dist/{chunk-OIX4O6UR.js → chunk-6OLN6BMB.js} +16 -3
  13. package/dist/{chunk-6FSHT5IL.js → chunk-7EZIANC7.js} +1 -1
  14. package/dist/chunk-A5SXCA62.cjs +93 -0
  15. package/dist/chunk-AC6ZEXVR.js +85 -0
  16. package/dist/{chunk-FWBRQWRX.js → chunk-AE5Q6ZAJ.js} +167 -10
  17. package/dist/{chunk-7ILGCUI6.js → chunk-C4F5KJTI.js} +142 -3
  18. package/dist/{chunk-WXXNCHUY.js → chunk-G5H32GIG.js} +1 -1
  19. package/dist/{chunk-OMY3CKUZ.cjs → chunk-GEQDGUGB.cjs} +1042 -226
  20. package/dist/{chunk-25BKWR2O.js → chunk-HCM7ZC7Q.js} +1 -1
  21. package/dist/{chunk-I47EENR4.cjs → chunk-HMZUGSMU.cjs} +673 -156
  22. package/dist/{chunk-NXFBVDOI.cjs → chunk-IQPXHQQQ.cjs} +8 -4
  23. package/dist/{chunk-RUQIMTN5.cjs → chunk-ISOIA7NV.cjs} +178 -15
  24. package/dist/chunk-JSC75O5C.cjs +167 -0
  25. package/dist/{chunk-BD7ZPG53.js → chunk-NWQ5WRLE.js} +10 -2
  26. package/dist/chunk-ODZ2IAR2.cjs +1247 -0
  27. package/dist/{chunk-FQSJI5NV.js → chunk-SR7TR5KX.js} +6 -2
  28. package/dist/{chunk-OKX3FYIM.cjs → chunk-TCTE7DX5.cjs} +3 -3
  29. package/dist/{chunk-3FIDHONL.cjs → chunk-TYF56RGB.cjs} +99 -80
  30. package/dist/{chunk-J3PYFGKA.cjs → chunk-VA4OFR72.cjs} +162 -4
  31. package/dist/chunk-VU5S5A7V.js +150 -0
  32. package/dist/{chunk-A36CCOWS.js → chunk-YEHR4NNE.js} +633 -128
  33. package/dist/{chunk-ELL2RBML.cjs → chunk-ZCGKGDCL.cjs} +23 -1
  34. package/dist/codegen/index.d.cts +2 -2
  35. package/dist/codegen/index.d.ts +2 -2
  36. package/dist/{collect-BTHjQaSp.d.ts → collect-6NIEufHd.d.ts} +20 -3
  37. package/dist/{collect-CSyOg5XC.d.cts → collect-CcTCKqx6.d.cts} +20 -3
  38. package/dist/{file-cgL9l9l8.d.cts → file-BxYpwjRQ.d.cts} +250 -15
  39. package/dist/{file-olQudcx5.d.ts → file-CFdPQJI9.d.ts} +250 -15
  40. package/dist/history/index.cjs +283 -106
  41. package/dist/history/index.d.cts +549 -10
  42. package/dist/history/index.d.ts +549 -10
  43. package/dist/history/index.js +5 -4
  44. package/dist/index.cjs +146 -53
  45. package/dist/index.d.cts +38 -14
  46. package/dist/index.d.ts +38 -14
  47. package/dist/index.js +6 -5
  48. package/dist/interceptors-CNcr2dlk.d.ts +159 -0
  49. package/dist/interceptors-CqkNZVfI.d.cts +159 -0
  50. package/dist/ir/index.cjs +339 -36
  51. package/dist/ir/index.d.cts +244 -8
  52. package/dist/ir/index.d.ts +244 -8
  53. package/dist/ir/index.js +306 -21
  54. package/dist/{lower-3S6PsqjJ.d.cts → lower-BtRfIW2A.d.cts} +23 -9
  55. package/dist/{lower-DmZpQ8hJ.d.ts → lower-CpsMFOFX.d.ts} +23 -9
  56. package/dist/{manifest-BJjrQt77.d.ts → manifest-D-I_twys.d.ts} +1 -1
  57. package/dist/{manifest-gRI2Q5Fj.d.cts → manifest-DahBQVM8.d.cts} +1 -1
  58. package/dist/node-evaluator-DGQDPSPI.cjs +24 -0
  59. package/dist/node-evaluator-LEEVD7H7.js +14 -0
  60. package/dist/payload-fields-BVRQn2yH.d.cts +122 -0
  61. package/dist/payload-fields-oOBWxDiG.d.ts +122 -0
  62. package/dist/quickjs/index.cjs +27 -27
  63. package/dist/quickjs/index.d.cts +6 -6
  64. package/dist/quickjs/index.d.ts +6 -6
  65. package/dist/quickjs/index.js +9 -9
  66. package/dist/roundtrip/index.cjs +72 -66
  67. package/dist/roundtrip/index.d.cts +25 -11
  68. package/dist/roundtrip/index.d.ts +25 -11
  69. package/dist/roundtrip/index.js +13 -11
  70. package/dist/runtime/index.cjs +19 -19
  71. package/dist/runtime/index.d.cts +139 -12
  72. package/dist/runtime/index.d.ts +139 -12
  73. package/dist/runtime/index.js +6 -6
  74. package/dist/testing/index.cjs +688 -121
  75. package/dist/testing/index.d.cts +174 -10
  76. package/dist/testing/index.d.ts +174 -10
  77. package/dist/testing/index.js +646 -82
  78. package/dist/{types-CnIOinoz.d.ts → types-Bv2i4cBX.d.cts} +126 -23
  79. package/dist/{types-CQKOhPTa.d.cts → types-DGx-b9eq.d.ts} +126 -23
  80. package/dist/{types-Bb2wRnJ5.d.cts → types-V7jEEUaL.d.cts} +1 -1
  81. package/dist/{types-Bb2wRnJ5.d.ts → types-V7jEEUaL.d.ts} +1 -1
  82. package/dist/{workflow-8uRU9rhL.d.ts → workflow-B18OeF7g.d.ts} +2 -2
  83. package/dist/{workflow-DWTPHFbt.d.ts → workflow-BGnv8SS6.d.ts} +261 -14
  84. package/dist/{workflow-CZOXUlQ5.d.cts → workflow-BJPFv3cp.d.cts} +2 -2
  85. package/dist/{workflow-O6e64ZcG.d.cts → workflow-DS32Gtws.d.cts} +261 -14
  86. package/fixtures/histories/activity-options-updated.history.json +159 -0
  87. package/fixtures/histories/activity-paused-unpaused.history.json +160 -0
  88. package/fixtures/histories/codec-opaque.history.json +229 -0
  89. package/fixtures/histories/dynamic-workflow.history.json +150 -0
  90. package/fixtures/histories/interceptor-headers.history.json +339 -0
  91. package/fixtures/histories/query-custom.history.json +213 -0
  92. package/fixtures/histories/query-default-handler.history.json +120 -0
  93. package/fixtures/histories/reset-forked-reapplied-signals.history.json +239 -0
  94. package/fixtures/histories/reset-reapplied-update-admitted.history.json +228 -0
  95. package/fixtures/histories/search-attributes-upserted.history.json +177 -0
  96. package/fixtures/histories/update-accepted-completed.history.json +45 -30
  97. package/fixtures/histories/update-default-handler.history.json +246 -0
  98. package/fixtures/histories/update-handler-awaits-activity.history.json +196 -0
  99. package/fixtures/histories/update-not-handled.history.json +138 -0
  100. package/fixtures/histories/update-rejected-no-event.history.json +190 -0
  101. package/fixtures/histories/update-with-start-admitted.history.json +150 -0
  102. package/fixtures/histories/user-activity-cancel.history.json +149 -0
  103. package/fixtures/histories/user-activity-retry.history.json +143 -0
  104. package/fixtures/histories/user-activity.history.json +149 -0
  105. package/package.json +1 -1
  106. package/schema/bridge-v2.schema.json +1062 -0
  107. package/schema/history-file.schema.json +255 -81
  108. package/schema/ir-v2.schema.json +246 -1
  109. package/schema/payload-fields.json +162 -0
  110. package/schema/run-event.schema.json +239 -80
  111. package/schema/workflow-command.schema.json +210 -84
  112. package/schema/workflow-task.schema.json +532 -167
  113. package/dist/chunk-6QPOJZT6.cjs +0 -1180
  114. package/dist/chunk-A2OHX3UQ.js +0 -1156
  115. package/dist/chunk-PWIUEWC3.js +0 -81
  116. package/dist/chunk-YHBVMOMK.cjs +0 -87
  117. package/dist/node-evaluator-SOADN23V.js +0 -14
  118. package/dist/node-evaluator-YGDEXK4U.cjs +0 -24
@@ -1,5 +1,5 @@
1
- import { J as Json, a as JsonObject, b as WorkflowInterface } from './types-Bb2wRnJ5.cjs';
2
- import { ai as WorkflowInfoSnapshot, R as RetryPolicy, d as ActivityCancellationType, x as Headers, P as ParentClosePolicy, C as ChildCancellationType, ac as VersioningBehavior, ah as WorkflowIdReusePolicy, ag as WorkflowIdConflictPolicy, b as RunRetryPolicy } from './types-CQKOhPTa.cjs';
1
+ import { a as Json, J as JsonObject, b as WorkflowInterface } from './types-V7jEEUaL.cjs';
2
+ import { M as Headers, e as RetryPolicy, i as ActivityCancellationType, b as WorkflowInfoSnapshot, P as ParentClosePolicy, C as ChildCancellationType, at as VersioningBehavior, ay as WorkflowIdReusePolicy, ax as WorkflowIdConflictPolicy, f as RunRetryPolicy } from './types-Bv2i4cBX.cjs';
3
3
 
4
4
  /**
5
5
  * Node operation descriptors: what a builder call needs to know about the node
@@ -86,6 +86,10 @@ declare const internalNodes: {
86
86
  readonly sendAndWait: Operation<Record<string, Json>, Json>;
87
87
  readonly codeWorkflow: Operation<Record<string, Json>, Json>;
88
88
  readonly waitForSignal: Operation<Record<string, Json>, Json>;
89
+ /** Phase C: signal another run (`fluidgrids.run-control`). */
90
+ readonly signalRun: Operation<Record<string, Json>, Json>;
91
+ /** Phase C: upsert the run's search attributes (`fluidgrids.search-attributes`). */
92
+ readonly setSearchAttributes: Operation<Record<string, Json>, Json>;
89
93
  };
90
94
  /** Node clients that need no registry: the internal nodes and `custom()`. */
91
95
  declare const nodes: {
@@ -116,6 +120,10 @@ declare const nodes: {
116
120
  readonly sendAndWait: Operation<Record<string, Json>, Json>;
117
121
  readonly codeWorkflow: Operation<Record<string, Json>, Json>;
118
122
  readonly waitForSignal: Operation<Record<string, Json>, Json>;
123
+ /** Phase C: signal another run (`fluidgrids.run-control`). */
124
+ readonly signalRun: Operation<Record<string, Json>, Json>;
125
+ /** Phase C: upsert the run's search attributes (`fluidgrids.search-attributes`). */
126
+ readonly setSearchAttributes: Operation<Record<string, Json>, Json>;
119
127
  };
120
128
  /**
121
129
  * Any node type, including ones the registry snapshot does not know. Typed
@@ -124,6 +132,145 @@ declare const nodes: {
124
132
  readonly custom: (nodeType: string, operation?: string, version?: string) => Operation<Record<string, Json>, Json>;
125
133
  };
126
134
 
135
+ /**
136
+ * User activities (Phase C, 11 §2.2, §2.29, CWD9): functions a self-hosted
137
+ * worker runs for workflow code.
138
+ *
139
+ * - {@link declareActivity} names an activity and its default task queue. The
140
+ * declaration is all workflow code needs: `ctx.activity(decl, { args })`
141
+ * issues `SCHEDULE_ACTIVITY` of kind `user`.
142
+ * - {@link implementActivity} attaches the function to a declaration, for the
143
+ * worker. {@link defineActivity} does both in one step.
144
+ * - {@link dynamicActivity} handles every activity name the worker has no
145
+ * implementation for.
146
+ *
147
+ * Implementations belong to the worker, not to the workflow bundle: `lower()`
148
+ * reports `durable.activityImplInBundle` when a workflow module pulls one in.
149
+ *
150
+ * Pure JavaScript; declarations run inside the isolate.
151
+ */
152
+
153
+ declare const ACTIVITY_MARKER = "fluidgrids.activity";
154
+ declare const ACTIVITY_IMPL_MARKER = "fluidgrids.activity-impl";
155
+ declare const ACTIVITY_TYPES: unique symbol;
156
+ /** The name `*` a dynamic activity is registered under. */
157
+ declare const DYNAMIC_ACTIVITY_NAME = "*";
158
+ interface ActivityDeclarationOptions {
159
+ /** The task queue the activity runs on unless the call names another; default the workflow's. */
160
+ taskQueue?: string;
161
+ input?: SchemaLike;
162
+ output?: SchemaLike;
163
+ description?: string;
164
+ }
165
+ /** A declared user activity. */
166
+ interface ActivityDefinition<In = Json, Out = Json> {
167
+ readonly __fluidgrids: typeof ACTIVITY_MARKER;
168
+ readonly name: string;
169
+ readonly options: ActivityDeclarationOptions;
170
+ /** Type-level only (functions, so any definition is assignable to the `never`/`unknown` one). */
171
+ readonly [ACTIVITY_TYPES]?: {
172
+ args: (args: In) => void;
173
+ result: () => Out;
174
+ };
175
+ }
176
+ /** What a running activity attempt knows. */
177
+ interface ActivityInfo {
178
+ readonly runId: string;
179
+ readonly workspaceId?: string;
180
+ readonly workflowKey?: string;
181
+ readonly activityId: string;
182
+ /** The activity name (for a dynamic activity, the requested one). */
183
+ readonly activityName: string;
184
+ readonly taskQueue: string;
185
+ /** 1-based. */
186
+ readonly attempt: number;
187
+ /** Details the previous attempt recorded with `heartbeat` (11 §2.4). */
188
+ readonly heartbeatDetails?: Json;
189
+ readonly headers: Headers;
190
+ }
191
+ /** The context an activity function receives. */
192
+ interface ActivityContext {
193
+ readonly info: ActivityInfo;
194
+ /**
195
+ * Record progress (at most 32 KiB of details, kept for the next attempt)
196
+ * and learn whether to stop. When the attempt was paused (`pauseActivity`,
197
+ * 11 §2.28) `paused` is true; the activity should then throw
198
+ * `ActivityPausedError`, which is not retried while the activity is paused.
199
+ */
200
+ heartbeat(details?: unknown): Promise<{
201
+ cancelRequested: boolean;
202
+ paused: boolean;
203
+ }>;
204
+ /** Aborted when the workflow requests cancellation or the worker shuts down. */
205
+ readonly cancellationSignal: AbortSignalLike;
206
+ /**
207
+ * Hand completion to an outside system (11 §2.2): returns a task token and
208
+ * ends this attempt without completing it. The outside system finishes it
209
+ * with `completeActivityAsync(token, result)` or the activity webhook.
210
+ */
211
+ completeAsync(): Promise<string>;
212
+ /** Credentials of a connection the activity declares (H2 rules apply on self-hosted workers). */
213
+ connection(name: string): Promise<Record<string, Json>>;
214
+ }
215
+ /** The part of `AbortSignal` activities may rely on. */
216
+ interface AbortSignalLike {
217
+ readonly aborted: boolean;
218
+ readonly reason?: unknown;
219
+ addEventListener(type: 'abort', listener: () => void): void;
220
+ removeEventListener(type: 'abort', listener: () => void): void;
221
+ }
222
+ type ActivityFunction<In = Json, Out = Json> = (ctx: ActivityContext, args: In) => Out | Promise<Out>;
223
+ /** A user activity's implementation, for a worker. */
224
+ interface ActivityImplementation<In = Json, Out = Json> extends ActivityDefinition<In, Out> {
225
+ readonly implementation: typeof ACTIVITY_IMPL_MARKER;
226
+ readonly fn: ActivityFunction<In, Out>;
227
+ /** True for {@link dynamicActivity}: `fn` receives `(ctx, args)` for any name. */
228
+ readonly dynamic: boolean;
229
+ }
230
+ /** Throw a `TypeError` unless `name` is a valid activity name. */
231
+ declare function checkActivityName(name: string): void;
232
+ /** Throw a `TypeError` unless `queue` is a valid task queue name. */
233
+ declare function checkTaskQueueName(queue: string, what?: string): void;
234
+ /** Declare a user activity for workflow code. */
235
+ declare function declareActivity<In = Json, Out = Json>(name: string, options?: ActivityDeclarationOptions): ActivityDefinition<In, Out>;
236
+ /** Attach the worker-side function to a declaration. */
237
+ declare function implementActivity<In, Out>(definition: ActivityDefinition<In, Out>, fn: ActivityFunction<In, Out>): ActivityImplementation<In, Out>;
238
+ /** Declare and implement a user activity in one step. */
239
+ declare function defineActivity<In = Json, Out = Json>(name: string, options: ActivityDeclarationOptions, fn: ActivityFunction<In, Out>): ActivityImplementation<In, Out>;
240
+ declare function defineActivity<In = Json, Out = Json>(name: string, fn: ActivityFunction<In, Out>): ActivityImplementation<In, Out>;
241
+ /**
242
+ * Handle every activity name the worker has no implementation for (11
243
+ * §2.29); `ctx.info.activityName` is the requested name.
244
+ */
245
+ declare function dynamicActivity<Out = Json>(fn: ActivityFunction<Json, Out>, options?: Pick<ActivityDeclarationOptions, 'taskQueue' | 'description'>): ActivityImplementation<Json, Out>;
246
+ /** True for a value made by {@link declareActivity} (or an implementation). */
247
+ declare function isActivityDefinition(value: unknown): value is ActivityDefinition<never, unknown>;
248
+ /** True for a value made by {@link implementActivity}, {@link defineActivity} or {@link dynamicActivity}. */
249
+ declare function isActivityImplementation(value: unknown): value is ActivityImplementation<never, unknown>;
250
+ /** An activity attempt is about to run its function. */
251
+ interface ActivityExecuteInput {
252
+ args: Json;
253
+ readonly headers: Headers;
254
+ readonly info: ActivityInfo;
255
+ }
256
+ /** Interceptors around an activity's execution, on the worker (11 §2.10). */
257
+ interface ActivityInboundInterceptor {
258
+ execute?(input: ActivityExecuteInput, next: (input: ActivityExecuteInput) => Promise<unknown>): Promise<unknown>;
259
+ }
260
+ /** Interceptors of what an activity issues, on the worker. */
261
+ interface ActivityOutboundInterceptor {
262
+ heartbeat?(details: unknown, next: (details: unknown) => Promise<unknown>): Promise<unknown>;
263
+ getLogAttributes?(input: Record<string, Json>, next: (input: Record<string, Json>) => Record<string, Json>): Record<string, Json>;
264
+ getMetricTags?(input: Record<string, string>, next: (input: Record<string, string>) => Record<string, string>): Record<string, string>;
265
+ }
266
+ /** The implementation that serves `name`: an exact one, else a dynamic one. */
267
+ declare function findActivityImplementation(implementations: readonly ActivityImplementation<never, unknown>[], name: string): ActivityImplementation<never, unknown> | undefined;
268
+ /**
269
+ * Run one activity attempt through the inbound interceptors (first
270
+ * outermost). Workers and the test environment use it.
271
+ */
272
+ declare function executeActivity(implementation: ActivityImplementation<never, unknown>, ctx: ActivityContext, args: Json, interceptors?: readonly ActivityInboundInterceptor[]): Promise<unknown>;
273
+
127
274
  /**
128
275
  * Signal, query and update definitions (spec 02 §4, 05). Signals work in Phase
129
276
  * B; queries and updates can be declared (they appear in the interface) but
@@ -204,7 +351,58 @@ interface RunOptions<In> {
204
351
  /** Overrides the node version the descriptor carries. */
205
352
  nodeVersion?: string;
206
353
  headers?: Headers;
354
+ /** Fairness within the queue (11 §2.11); default the workspace id. */
355
+ fairnessKey?: string;
356
+ /** 0.1 to 10; default 1. */
357
+ fairnessWeight?: number;
207
358
  }
359
+ /**
360
+ * Options of `ctx.activity` (Phase C, user activities). The task queue is
361
+ * the option, else the declaration's, else the workflow's own queue.
362
+ */
363
+ interface ActivityOptions<In> {
364
+ args: In;
365
+ taskQueue?: string;
366
+ /** Default: 1 s, x2, at most 100 s, unlimited attempts (Temporal's policy). */
367
+ retry?: Partial<RetryPolicy>;
368
+ startToCloseTimeout?: Duration;
369
+ scheduleToCloseTimeout?: Duration;
370
+ scheduleToStartTimeout?: Duration;
371
+ heartbeatTimeout?: Duration;
372
+ cancellationType?: ActivityCancellationType;
373
+ /** 1 (highest) to 5; default 3. */
374
+ priority?: number;
375
+ fairnessKey?: string;
376
+ fairnessWeight?: number;
377
+ /** Label in the History tab (at most 200 characters). */
378
+ summary?: string;
379
+ /** Connections the worker may resolve for this activity (at most 16, H2). */
380
+ connections?: string[];
381
+ headers?: Headers;
382
+ }
383
+ /** Options of `ctx.handleUpdate` and `ctx.setDefaultUpdateHandler` (05 §6, 11 §2.39). */
384
+ interface UpdateHandlerOptions<Args> {
385
+ /**
386
+ * Runs before the update is accepted, without changing the run; throw to
387
+ * reject it (nothing is written to history and the caller gets the error).
388
+ * It is skipped when a replay re-delivers an update that history accepted.
389
+ */
390
+ validate?: (args: Args) => void;
391
+ /** Default `WARN_AND_ABANDON`. */
392
+ unfinishedPolicy?: HandlerUnfinishedPolicy;
393
+ description?: string;
394
+ }
395
+ /** Options of `ctx.setDefaultUpdateHandler`. */
396
+ interface DefaultUpdateHandlerOptions {
397
+ validate?: (name: string, args: unknown) => void;
398
+ unfinishedPolicy?: HandlerUnfinishedPolicy;
399
+ }
400
+ /**
401
+ * Fire-and-forget calls to worker-side code (11 §2.31, self-hosted workers):
402
+ * `ctx.sinks.<sink>.<fn>(...args)`. Calls are reported once, when the task
403
+ * completes, never during replay or in a query. Managed runs ignore them.
404
+ */
405
+ type WorkflowSinks = Readonly<Record<string, Readonly<Record<string, (...args: Json[]) => void>>>>;
208
406
  /** Options of `ctx.localActivity` (11 §2.12). */
209
407
  interface LocalActivityOptions<In> {
210
408
  args: In;
@@ -286,6 +484,9 @@ interface ChildOptions {
286
484
  idReusePolicy?: WorkflowIdReusePolicy;
287
485
  idConflictPolicy?: WorkflowIdConflictPolicy;
288
486
  headers?: Headers;
487
+ /** Fairness of the child's tasks (11 §2.11). */
488
+ fairnessKey?: string;
489
+ fairnessWeight?: number;
289
490
  }
290
491
  /** A started child run. */
291
492
  interface ChildHandle<Out = Json> {
@@ -437,10 +638,14 @@ interface WorkflowContext {
437
638
  onCancel(fn: () => void): void;
438
639
  isCancellation(error: unknown): boolean;
439
640
  saga(): Saga;
440
- /** Resolves when no asynchronous signal handler is running; cancellation does not interrupt the wait. */
641
+ /** Resolves when no asynchronous signal or update handler is running; cancellation does not interrupt the wait. */
441
642
  allHandlersFinished(): Promise<void>;
442
- /** Phase C: user activities. Throws `PhaseCFeatureError`. */
443
- activity(...args: unknown[]): Promise<never>;
643
+ /**
644
+ * Run a user activity on a self-hosted worker (Phase C,
645
+ * `SCHEDULE_ACTIVITY` of kind `user`). Needs `fluidgrids.self-hosted-workers`;
646
+ * the `managed` queue refuses user activities.
647
+ */
648
+ activity<In, Out>(activity: ActivityDefinition<In, Out> | string, options: ActivityOptions<In>): Promise<Out>;
444
649
  /**
445
650
  * Run a short, idempotent node operation inside the workflow task (11
446
651
  * §2.12): the worker that runs the task executes it and the task records one
@@ -452,12 +657,31 @@ interface WorkflowContext {
452
657
  */
453
658
  localActivity<In, Out>(operation: Operation<In, Out>, options: LocalActivityOptions<In>): Promise<Out>;
454
659
  localActivity(fn: (...args: never[]) => unknown, options?: unknown): Promise<never>;
455
- /** Phase C: custom queries. Throws `PhaseCFeatureError`. */
456
- handleQuery(...args: unknown[]): void;
457
- /** Phase C: updates. Throws `PhaseCFeatureError`. */
458
- handleUpdate(...args: unknown[]): void;
459
- /** Phase C: search attributes. Throws `PhaseCFeatureError`. */
460
- upsertSearchAttributes(...args: unknown[]): void;
660
+ /**
661
+ * Answer a custom query (Phase C): `handler` runs after the history is
662
+ * replayed and must return a value without changing the run (commands and
663
+ * sinks throw `QueryHandlerSideEffect`).
664
+ */
665
+ handleQuery<Result, Args>(query: QueryDefinition<Result, Args> | string, handler: (args: Args) => Result): void;
666
+ /** Answer queries no handler takes (Phase C). */
667
+ setDefaultQueryHandler(handler: (name: string, args: unknown) => unknown): void;
668
+ /**
669
+ * Handle an update (Phase C, 05 §6): `validate` may reject it (no history),
670
+ * the handler's result or failure completes it (`UPDATE_COMPLETED`). The
671
+ * handler may await activities, timers and children.
672
+ */
673
+ handleUpdate<Args, Result>(update: UpdateDefinition<Args, Result> | string, handler: (args: Args) => Result | Promise<Result>, options?: UpdateHandlerOptions<Args>): void;
674
+ /** Handle updates no handler takes (Phase C, 11 §2.29). */
675
+ setDefaultUpdateHandler(handler: (name: string, args: unknown) => unknown, options?: DefaultUpdateHandlerOptions): void;
676
+ setDefaultUpdateHandler(options: DefaultUpdateHandlerOptions, handler: (name: string, args: unknown) => unknown): void;
677
+ /**
678
+ * Upsert the run's search attributes (Phase C, 11 §2.8,
679
+ * `UPSERT_SEARCH_ATTRIBUTES`); a null value removes one. The service
680
+ * validates the values against the workspace definitions.
681
+ */
682
+ upsertSearchAttributes(attributes: JsonObject): void;
683
+ /** Worker-side sinks (Phase C, self-hosted workers). */
684
+ readonly sinks: WorkflowSinks;
461
685
  }
462
686
 
463
687
  /**
@@ -491,10 +715,20 @@ interface DurableWorkflowOptions {
491
715
  input?: SchemaLike;
492
716
  output?: SchemaLike;
493
717
  signals?: ReadonlyArray<SignalDefinition<never> | SignalDefinition<unknown>>;
494
- /** Declared only; handlers are Phase C. */
718
+ /** Declared queries; `ctx.handleQuery` answers them (Phase C). */
495
719
  queries?: ReadonlyArray<QueryDefinition<unknown, unknown>>;
496
- /** Declared only; handlers are Phase C. */
720
+ /** Declared updates; `ctx.handleUpdate` handles them (Phase C). */
497
721
  updates?: ReadonlyArray<UpdateDefinition<unknown, unknown>>;
722
+ /**
723
+ * Accept names the interface does not declare (11 §2.29), written as
724
+ * `interface.open`. `lower()` also sets a kind open when the declaring
725
+ * module registers a default handler for it.
726
+ */
727
+ open?: {
728
+ signals?: boolean;
729
+ queries?: boolean;
730
+ updates?: boolean;
731
+ };
498
732
  /** Default `managed`. */
499
733
  taskQueue?: string;
500
734
  /** Lowers to the trigger node of the standalone workflow (default `internal:api`). */
@@ -526,10 +760,23 @@ interface DurableWorkflow<In = Json, Out = Json> {
526
760
  readonly name: string;
527
761
  readonly options: DurableWorkflowOptions;
528
762
  readonly fn: (ctx: WorkflowContext, input: In) => Promise<Out>;
763
+ /**
764
+ * True for {@link dynamicWorkflow}: it serves every function name the
765
+ * bundle does not export (`code.exports.workflows["*"]`, 11 §2.29).
766
+ */
767
+ readonly dynamic?: boolean;
529
768
  }
530
769
  /** Declare a tier-2 workflow. `name` is its workflow key when it is standalone. */
531
770
  declare function workflow<In = Json, Out = Json>(name: string, options: DurableWorkflowOptions, fn: (ctx: WorkflowContext, input: In) => Promise<Out>): DurableWorkflow<In, Out>;
532
771
  declare function workflow<In = Json, Out = Json>(name: string, fn: (ctx: WorkflowContext, input: In) => Promise<Out>): DurableWorkflow<In, Out>;
772
+ /**
773
+ * Declare a dynamic workflow (Phase C, 11 §2.29): it runs for every
774
+ * `workflowFn` the bundle does not export, and receives the requested name.
775
+ * `lower()` writes it to `code.exports.workflows["*"]`, so a start or a child
776
+ * naming any function of the workflow key reaches it. One per bundle.
777
+ */
778
+ declare function dynamicWorkflow<Out = Json>(name: string, options: DurableWorkflowOptions, fn: (ctx: WorkflowContext, workflowFn: string, input: Json) => Promise<Out>): DurableWorkflow<Json, Out>;
779
+ declare function dynamicWorkflow<Out = Json>(name: string, fn: (ctx: WorkflowContext, workflowFn: string, input: Json) => Promise<Out>): DurableWorkflow<Json, Out>;
533
780
  /** True for a value made by {@link workflow}. */
534
781
  declare function isDurableWorkflow(value: unknown): value is DurableWorkflow<never, unknown>;
535
782
  /** The JSON Schema of a {@link SchemaLike}, or undefined when it has none. */
@@ -553,4 +800,4 @@ declare function runRetryPolicyOf(retry: WorkflowRetryOptions): RunRetryPolicy;
553
800
  */
554
801
  declare function continueAsNewRetryOf(retry: WorkflowRetryOptions | LegacyContinueAsNewRetry): RunRetryPolicy | RetryPolicy;
555
802
 
556
- export { isDurableWorkflow as A, isOperation as B, type CancellationScope as C, DURABLE_MARKER as D, type ExternalRunHandle as E, type FileRef as F, jsonSchemaOf as G, type HandlerUnfinishedPolicy as H, nodes as I, op as J, runRetryPolicyOf as K, type LegacyContinueAsNewRetry as L, MAX_WORKFLOW_TASK_TIMEOUT_MS as M, toMs as N, type Operation as O, trigger as P, type QueryDefinition as Q, type RunOptions as R, type Saga as S, type TriggerOperation as T, type UpdateDefinition as U, triggers as V, type WorkflowContext as W, workflow as X, 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 ExternalRunTarget as k, type LocalActivityOptions as l, type SchemaLike as m, type SignalDefinition as n, type SignalHandlerOptions as o, type TriggerSpec as p, type WorkflowIdTarget as q, type WorkflowInfo as r, type WorkflowLogger as s, type WorkflowRetryOptions as t, continueAsNewRetryOf as u, defineQuery as v, defineSignal as w, defineUpdate as x, interfaceOf as y, internalNodes as z };
803
+ export { continueAsNewRetryOf as $, ACTIVITY_IMPL_MARKER as A, type SchemaLike as B, type CancellationScope as C, DURABLE_MARKER as D, type ExternalRunHandle as E, type FileRef as F, type SignalDefinition as G, type HandlerUnfinishedPolicy as H, type SignalHandlerOptions as I, type TriggerSpec as J, type UpdateHandlerOptions as K, type LegacyContinueAsNewRetry as L, MAX_WORKFLOW_TASK_TIMEOUT_MS as M, type WorkflowIdTarget as N, type Operation as O, type WorkflowInfo as P, type QueryDefinition as Q, type RunOptions as R, type Saga as S, type TriggerOperation as T, type UpdateDefinition as U, type WorkflowLogger as V, type WorkflowContext as W, type WorkflowRetryOptions as X, type WorkflowSinks as Y, checkActivityName as Z, checkTaskQueueName as _, ACTIVITY_MARKER as a, declareActivity as a0, defineActivity as a1, defineQuery as a2, defineSignal as a3, defineUpdate as a4, dynamicActivity as a5, dynamicWorkflow as a6, executeActivity as a7, findActivityImplementation as a8, implementActivity as a9, interfaceOf as aa, internalNodes as ab, isActivityDefinition as ac, isActivityImplementation as ad, isDurableWorkflow as ae, isOperation as af, jsonSchemaOf as ag, nodes as ah, op as ai, runRetryPolicyOf as aj, toMs as ak, trigger as al, triggers as am, workflow as an, type AbortSignalLike as b, type ActivityContext as c, type ActivityDeclarationOptions as d, type ActivityDefinition as e, type ActivityExecuteInput as f, type ActivityFunction as g, type ActivityImplementation as h, type ActivityInboundInterceptor as i, type ActivityInfo as j, type ActivityOptions as k, type ActivityOutboundInterceptor as l, type CancellationScopeFunction as m, type CancellationScopeOptions as n, type ChildHandle as o, type ChildOptions as p, type ChildTarget as q, type ContinueAsNewOptions as r, DYNAMIC_ACTIVITY_NAME as s, type DefaultUpdateHandlerOptions as t, type DefinitionOptions as u, type DurableWorkflow as v, type DurableWorkflowOptions as w, type Duration as x, type ExternalRunTarget as y, type LocalActivityOptions as z };
@@ -0,0 +1,159 @@
1
+ {
2
+ "format": "fluidgrids.history",
3
+ "formatVersion": 1,
4
+ "name": "activity-options-updated",
5
+ "description": "updateActivityOptions changes the retry policy of a pending activity in place (ACTIVITY_OPTIONS_UPDATED); replay is unaffected.",
6
+ "source": "src/phase-c-control.ts",
7
+ "info": {
8
+ "workspaceId": "test-workspace",
9
+ "taskQueue": "managed",
10
+ "attempt": 1,
11
+ "startedAt": "2026-01-01T00:00:00.000Z",
12
+ "runStartedAt": "2026-01-01T00:00:00.000Z",
13
+ "runId": "run-1"
14
+ },
15
+ "nowMs": 1767225600000,
16
+ "workflowFn": "controlled",
17
+ "events": [
18
+ {
19
+ "seq": 1,
20
+ "type": "WORKFLOW_STARTED",
21
+ "payload": {
22
+ "workflowFn": "controlled",
23
+ "input": null,
24
+ "taskQueue": "managed",
25
+ "randomnessSeed": "run-1"
26
+ },
27
+ "createdAt": "2026-01-01T00:00:00.000Z"
28
+ },
29
+ {
30
+ "seq": 2,
31
+ "type": "WORKFLOW_TASK_SCHEDULED",
32
+ "payload": {
33
+ "taskId": "run-1-task-1"
34
+ },
35
+ "createdAt": "2026-01-01T00:00:00.000Z"
36
+ },
37
+ {
38
+ "seq": 3,
39
+ "type": "WORKFLOW_TASK_STARTED",
40
+ "payload": {
41
+ "taskId": "run-1-task-1",
42
+ "attempt": 1
43
+ },
44
+ "createdAt": "2026-01-01T00:00:00.000Z"
45
+ },
46
+ {
47
+ "seq": 4,
48
+ "type": "WORKFLOW_TASK_COMPLETED",
49
+ "payload": {
50
+ "taskId": "run-1-task-1"
51
+ },
52
+ "createdAt": "2026-01-01T00:00:00.000Z",
53
+ "taskId": "run-1-task-1"
54
+ },
55
+ {
56
+ "seq": 5,
57
+ "type": "ACTIVITY_SCHEDULED",
58
+ "payload": {
59
+ "activityId": "a1",
60
+ "kind": "node",
61
+ "nodeType": "internal:http",
62
+ "operation": "execute",
63
+ "args": {
64
+ "url": "https://example.test/flaky"
65
+ },
66
+ "retry": {
67
+ "retryDelay": 1000,
68
+ "backoffMultiplier": 2,
69
+ "maxDelay": 100000,
70
+ "maxRetries": 5
71
+ }
72
+ },
73
+ "createdAt": "2026-01-01T00:00:00.000Z",
74
+ "taskId": "run-1-task-1"
75
+ },
76
+ {
77
+ "seq": 6,
78
+ "type": "ACTIVITY_OPTIONS_UPDATED",
79
+ "payload": {
80
+ "activityId": "a1",
81
+ "options": {
82
+ "retry": {
83
+ "retryDelay": 5000,
84
+ "maxRetries": 2
85
+ }
86
+ }
87
+ },
88
+ "createdAt": "2026-01-01T00:00:00.000Z"
89
+ },
90
+ {
91
+ "seq": 7,
92
+ "type": "ACTIVITY_STARTED",
93
+ "payload": {
94
+ "activityId": "a1",
95
+ "attempt": 1
96
+ },
97
+ "createdAt": "2026-01-01T00:00:00.000Z"
98
+ },
99
+ {
100
+ "seq": 8,
101
+ "type": "ACTIVITY_COMPLETED",
102
+ "payload": {
103
+ "activityId": "a1",
104
+ "attempt": 1,
105
+ "result": {
106
+ "status": 200,
107
+ "url": "https://example.test/flaky"
108
+ }
109
+ },
110
+ "createdAt": "2026-01-01T00:00:00.000Z"
111
+ },
112
+ {
113
+ "seq": 9,
114
+ "type": "WORKFLOW_TASK_SCHEDULED",
115
+ "payload": {
116
+ "taskId": "run-1-task-2"
117
+ },
118
+ "createdAt": "2026-01-01T00:00:00.000Z"
119
+ },
120
+ {
121
+ "seq": 10,
122
+ "type": "WORKFLOW_TASK_STARTED",
123
+ "payload": {
124
+ "taskId": "run-1-task-2",
125
+ "attempt": 1
126
+ },
127
+ "createdAt": "2026-01-01T00:00:00.000Z"
128
+ },
129
+ {
130
+ "seq": 11,
131
+ "type": "WORKFLOW_TASK_COMPLETED",
132
+ "payload": {
133
+ "taskId": "run-1-task-2"
134
+ },
135
+ "createdAt": "2026-01-01T00:00:00.000Z",
136
+ "taskId": "run-1-task-2"
137
+ },
138
+ {
139
+ "seq": 12,
140
+ "type": "WORKFLOW_COMPLETED",
141
+ "payload": {
142
+ "output": {
143
+ "first": {
144
+ "status": 200,
145
+ "url": "https://example.test/flaky"
146
+ }
147
+ }
148
+ },
149
+ "createdAt": "2026-01-01T00:00:00.000Z",
150
+ "taskId": "run-1-task-2"
151
+ }
152
+ ],
153
+ "expected": {
154
+ "protocol": 1,
155
+ "outcome": "commands",
156
+ "commands": [],
157
+ "logs": []
158
+ }
159
+ }
@@ -0,0 +1,160 @@
1
+ {
2
+ "format": "fluidgrids.history",
3
+ "formatVersion": 1,
4
+ "name": "activity-paused-unpaused",
5
+ "description": "An operator pauses and unpauses an activity between its attempts (ACTIVITY_PAUSED, ACTIVITY_UNPAUSED); the workflow sees only the result.",
6
+ "source": "src/phase-c-control.ts",
7
+ "info": {
8
+ "workspaceId": "test-workspace",
9
+ "taskQueue": "managed",
10
+ "attempt": 1,
11
+ "startedAt": "2026-01-01T00:00:00.000Z",
12
+ "runStartedAt": "2026-01-01T00:00:00.000Z",
13
+ "runId": "run-1"
14
+ },
15
+ "nowMs": 1767225601000,
16
+ "workflowFn": "controlled",
17
+ "events": [
18
+ {
19
+ "seq": 1,
20
+ "type": "WORKFLOW_STARTED",
21
+ "payload": {
22
+ "workflowFn": "controlled",
23
+ "input": null,
24
+ "taskQueue": "managed",
25
+ "randomnessSeed": "run-1"
26
+ },
27
+ "createdAt": "2026-01-01T00:00:00.000Z"
28
+ },
29
+ {
30
+ "seq": 2,
31
+ "type": "WORKFLOW_TASK_SCHEDULED",
32
+ "payload": {
33
+ "taskId": "run-1-task-1"
34
+ },
35
+ "createdAt": "2026-01-01T00:00:00.000Z"
36
+ },
37
+ {
38
+ "seq": 3,
39
+ "type": "WORKFLOW_TASK_STARTED",
40
+ "payload": {
41
+ "taskId": "run-1-task-1",
42
+ "attempt": 1
43
+ },
44
+ "createdAt": "2026-01-01T00:00:00.000Z"
45
+ },
46
+ {
47
+ "seq": 4,
48
+ "type": "WORKFLOW_TASK_COMPLETED",
49
+ "payload": {
50
+ "taskId": "run-1-task-1"
51
+ },
52
+ "createdAt": "2026-01-01T00:00:00.000Z",
53
+ "taskId": "run-1-task-1"
54
+ },
55
+ {
56
+ "seq": 5,
57
+ "type": "ACTIVITY_SCHEDULED",
58
+ "payload": {
59
+ "activityId": "a1",
60
+ "kind": "node",
61
+ "nodeType": "internal:http",
62
+ "operation": "execute",
63
+ "args": {
64
+ "url": "https://example.test/flaky"
65
+ },
66
+ "retry": {
67
+ "retryDelay": 1000,
68
+ "backoffMultiplier": 2,
69
+ "maxDelay": 100000,
70
+ "maxRetries": 5
71
+ }
72
+ },
73
+ "createdAt": "2026-01-01T00:00:00.000Z",
74
+ "taskId": "run-1-task-1"
75
+ },
76
+ {
77
+ "seq": 6,
78
+ "type": "ACTIVITY_PAUSED",
79
+ "payload": {
80
+ "activityId": "a1",
81
+ "reason": "downstream outage"
82
+ },
83
+ "createdAt": "2026-01-01T00:00:00.000Z"
84
+ },
85
+ {
86
+ "seq": 7,
87
+ "type": "ACTIVITY_UNPAUSED",
88
+ "payload": {
89
+ "activityId": "a1"
90
+ },
91
+ "createdAt": "2026-01-01T00:00:00.000Z"
92
+ },
93
+ {
94
+ "seq": 8,
95
+ "type": "ACTIVITY_STARTED",
96
+ "payload": {
97
+ "activityId": "a1",
98
+ "attempt": 2
99
+ },
100
+ "createdAt": "2026-01-01T00:00:01.000Z"
101
+ },
102
+ {
103
+ "seq": 9,
104
+ "type": "ACTIVITY_COMPLETED",
105
+ "payload": {
106
+ "activityId": "a1",
107
+ "attempt": 2,
108
+ "result": {
109
+ "status": 200
110
+ }
111
+ },
112
+ "createdAt": "2026-01-01T00:00:01.000Z"
113
+ },
114
+ {
115
+ "seq": 10,
116
+ "type": "WORKFLOW_TASK_SCHEDULED",
117
+ "payload": {
118
+ "taskId": "run-1-task-2"
119
+ },
120
+ "createdAt": "2026-01-01T00:00:01.000Z"
121
+ },
122
+ {
123
+ "seq": 11,
124
+ "type": "WORKFLOW_TASK_STARTED",
125
+ "payload": {
126
+ "taskId": "run-1-task-2",
127
+ "attempt": 1
128
+ },
129
+ "createdAt": "2026-01-01T00:00:01.000Z"
130
+ },
131
+ {
132
+ "seq": 12,
133
+ "type": "WORKFLOW_TASK_COMPLETED",
134
+ "payload": {
135
+ "taskId": "run-1-task-2"
136
+ },
137
+ "createdAt": "2026-01-01T00:00:01.000Z",
138
+ "taskId": "run-1-task-2"
139
+ },
140
+ {
141
+ "seq": 13,
142
+ "type": "WORKFLOW_COMPLETED",
143
+ "payload": {
144
+ "output": {
145
+ "first": {
146
+ "status": 200
147
+ }
148
+ }
149
+ },
150
+ "createdAt": "2026-01-01T00:00:01.000Z",
151
+ "taskId": "run-1-task-2"
152
+ }
153
+ ],
154
+ "expected": {
155
+ "protocol": 1,
156
+ "outcome": "commands",
157
+ "commands": [],
158
+ "logs": []
159
+ }
160
+ }