@webda/workflow 0.0.0-stage → 4.0.0-beta.14

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 (48) hide show
  1. package/LICENSE +166 -0
  2. package/README.md +54 -2
  3. package/lib/authoring.d.ts +115 -0
  4. package/lib/authoring.d.ts.map +1 -0
  5. package/lib/authoring.js +107 -0
  6. package/lib/authoring.js.map +1 -0
  7. package/lib/expression.d.ts +21 -0
  8. package/lib/expression.d.ts.map +1 -0
  9. package/lib/expression.js +196 -0
  10. package/lib/expression.js.map +1 -0
  11. package/lib/graph.d.ts +429 -0
  12. package/lib/graph.d.ts.map +1 -0
  13. package/lib/graph.js +72 -0
  14. package/lib/graph.js.map +1 -0
  15. package/lib/hooks.d.ts +38 -0
  16. package/lib/hooks.d.ts.map +1 -0
  17. package/lib/hooks.js +23 -0
  18. package/lib/hooks.js.map +1 -0
  19. package/lib/index.d.ts +11 -0
  20. package/lib/index.d.ts.map +1 -0
  21. package/lib/index.js +15 -0
  22. package/lib/index.js.map +1 -0
  23. package/lib/interpreter.d.ts +69 -0
  24. package/lib/interpreter.d.ts.map +1 -0
  25. package/lib/interpreter.js +332 -0
  26. package/lib/interpreter.js.map +1 -0
  27. package/lib/models/workflow.model.d.ts +71 -0
  28. package/lib/models/workflow.model.d.ts.map +1 -0
  29. package/lib/models/workflow.model.js +70 -0
  30. package/lib/models/workflow.model.js.map +1 -0
  31. package/lib/models/workflowinstance.model.d.ts +132 -0
  32. package/lib/models/workflowinstance.model.d.ts.map +1 -0
  33. package/lib/models/workflowinstance.model.js +168 -0
  34. package/lib/models/workflowinstance.model.js.map +1 -0
  35. package/lib/models/workflowsignal.model.d.ts +51 -0
  36. package/lib/models/workflowsignal.model.d.ts.map +1 -0
  37. package/lib/models/workflowsignal.model.js +53 -0
  38. package/lib/models/workflowsignal.model.js.map +1 -0
  39. package/lib/models/workflowtask.model.d.ts +103 -0
  40. package/lib/models/workflowtask.model.d.ts.map +1 -0
  41. package/lib/models/workflowtask.model.js +104 -0
  42. package/lib/models/workflowtask.model.js.map +1 -0
  43. package/lib/workflow.service.d.ts +685 -0
  44. package/lib/workflow.service.d.ts.map +1 -0
  45. package/lib/workflow.service.js +1951 -0
  46. package/lib/workflow.service.js.map +1 -0
  47. package/package.json +68 -3
  48. package/webda.module.json +2688 -0
@@ -0,0 +1,685 @@
1
+ import { Service, ServiceParameters, SimpleOperationContext, type OperationContext } from "@webda/core";
2
+ import { type FlowDefinition, type FlowDefinitionData, type FlowError, type JournalEntry } from "./graph.js";
3
+ import { type ScheduledTask } from "./interpreter.js";
4
+ import { type WorkflowControls } from "./hooks.js";
5
+ import { WorkflowInstance, type WorkflowLauncher } from "./models/workflowinstance.model.js";
6
+ import { WorkflowTask } from "./models/workflowtask.model.js";
7
+ import { WorkflowSignal } from "./models/workflowsignal.model.js";
8
+ import { Workflow as StoredWorkflow } from "./models/workflow.model.js";
9
+ /**
10
+ * Output schema of every flow launch operation
11
+ */
12
+ export declare const LAUNCH_OUTPUT_SCHEMA = "Webda/WorkflowLaunch.output";
13
+ /**
14
+ * `runAt` of a wait without timeout (JSON has no Infinity)
15
+ */
16
+ export declare const NO_TIMEOUT: number;
17
+ /**
18
+ * A stored workflow registered on this replica
19
+ */
20
+ interface RegisteredStoredFlow {
21
+ /**
22
+ * Flow ID
23
+ */
24
+ flowId: string;
25
+ /**
26
+ * Version
27
+ */
28
+ version: string;
29
+ /**
30
+ * Updated by
31
+ */
32
+ updatedBy?: string;
33
+ /**
34
+ * JSON of its crons, to notice a change
35
+ */
36
+ crons: string;
37
+ /**
38
+ * Export ids of the crons registered for it: only those are removed
39
+ */
40
+ cronIds: string[];
41
+ }
42
+ /**
43
+ * Abort signal of the current workflow task attempt
44
+ *
45
+ * It is aborted on timeout, when the worker loses the task lease, and when the service stops. An operation run by a
46
+ * workflow should observe it to stop early: an attempt that keeps running is ignored, and the task may run again
47
+ * (operations are assumed idempotent).
48
+ * @returns the signal, undefined outside a workflow task
49
+ */
50
+ export declare function useAbortSignal(): AbortSignal | undefined;
51
+ /**
52
+ * An attempt running on this replica
53
+ */
54
+ interface RunningAttempt {
55
+ /**
56
+ * Task
57
+ */
58
+ task: WorkflowTask;
59
+ /**
60
+ * Controller
61
+ */
62
+ controller: AbortController;
63
+ }
64
+ /**
65
+ * Parameters of the {@link WorkflowService}
66
+ */
67
+ export declare class WorkflowServiceParameters extends ServiceParameters {
68
+ /**
69
+ * Interval between two polls of the worker (ms)
70
+ * @default 1000
71
+ */
72
+ pollInterval: number;
73
+ /**
74
+ * Maximum number of tasks running at once on this replica
75
+ * @default 10
76
+ */
77
+ concurrency: number;
78
+ /**
79
+ * Lease of a claimed task (ms), renewed while it runs
80
+ * @default 60000
81
+ */
82
+ leaseDuration: number;
83
+ /**
84
+ * Maximum size of the journal and input of an instance (bytes of JSON)
85
+ * @default 262144
86
+ */
87
+ maxContextSize: number;
88
+ /**
89
+ * Run the worker loop on this replica
90
+ * @default true
91
+ */
92
+ worker: boolean;
93
+ /**
94
+ * Allow `useSystem` tasks in stored workflows
95
+ * @default false
96
+ */
97
+ allowStoredSystem: boolean;
98
+ /**
99
+ * How long a signal sent before any wait is kept (Duration syntax)
100
+ * @default "1d"
101
+ */
102
+ signalTtl: string;
103
+ /**
104
+ * Interval of the recovery sweep (ms): an active instance not updated for this long and without a live task is
105
+ * replayed
106
+ * @default 60000
107
+ */
108
+ sweepInterval: number;
109
+ /**
110
+ * Grace period of stop() for the running attempts (ms), then they are aborted and their outcome dropped
111
+ * @default 30000
112
+ */
113
+ stopTimeout: number;
114
+ /**
115
+ * Flows to register
116
+ */
117
+ flows?: FlowDefinitionData[];
118
+ /**
119
+ * Maximum size of a signal payload (bytes of JSON)
120
+ * @default 65536
121
+ */
122
+ maxSignalPayload: number;
123
+ /**
124
+ * Maximum number of unexpired buffered signals per `(event, key)`: a new one past it is refused
125
+ * @default 100
126
+ */
127
+ maxBufferedSignals: number;
128
+ /**
129
+ * Role needed to create, update or delete a stored workflow
130
+ * @default "workflow-admin"
131
+ */
132
+ storedWorkflowRole: string;
133
+ /**
134
+ * PubSub service announcing the stored workflow changes to the other replicas
135
+ */
136
+ syncPubSub?: string;
137
+ /**
138
+ * Without `syncPubSub`, interval between two reloads of the stored workflows (ms)
139
+ * @default 60000
140
+ */
141
+ syncInterval: number;
142
+ /**
143
+ * @override
144
+ * @param params - the input parameters
145
+ * @returns this
146
+ */
147
+ load(params?: any): this;
148
+ }
149
+ /**
150
+ * Runs durable workflows: registers each flow as an operation, launches instances and runs their tasks
151
+ *
152
+ * Every replica runs the worker loop: a task is claimed with a lease (a conditional patch on `leaseUntil`), so it
153
+ * runs on one replica at a time. Its outcome goes to the instance journal (a conditional patch on `revision`), then
154
+ * the flow is replayed to find the next tasks.
155
+ *
156
+ * @WebdaModda WorkflowService
157
+ */
158
+ export declare class WorkflowService<T extends WorkflowServiceParameters = WorkflowServiceParameters> extends Service<T> implements WorkflowControls {
159
+ /**
160
+ * Flows registered on this service, by flow id
161
+ */
162
+ protected flows: Map<string, FlowDefinition>;
163
+ /**
164
+ * Every version registered of each flow, for migrate
165
+ */
166
+ protected versions: Map<string, Map<string, FlowDefinition>>;
167
+ /**
168
+ * Flows of the modules (compiled `.flow.ts`) registered by this service
169
+ */
170
+ protected moduleFlows: Set<string>;
171
+ /**
172
+ * Worker id, the lease owner of the tasks it claims
173
+ */
174
+ protected workerId: `${string}-${string}-${string}-${string}-${string}`;
175
+ /**
176
+ * Attempts running on this replica, by task uuid
177
+ */
178
+ protected running: Map<string, RunningAttempt>;
179
+ /**
180
+ * Tasks reclaimed after too many crashes: they fail without running
181
+ */
182
+ protected crashed: WeakSet<WorkflowTask>;
183
+ /**
184
+ * The service is stopping: nothing more is claimed
185
+ */
186
+ protected stopping: boolean;
187
+ /**
188
+ * Poll in progress
189
+ */
190
+ protected pollPromise?: Promise<void>;
191
+ /**
192
+ * Last recovery sweep (ms)
193
+ */
194
+ protected lastSweep: number;
195
+ /**
196
+ * Executions started by the worker loop
197
+ */
198
+ protected executions: Set<Promise<void>>;
199
+ /**
200
+ * Worker loop timer
201
+ */
202
+ protected timer?: NodeJS.Timeout;
203
+ /**
204
+ * Stored workflows registered here, by workflow uuid
205
+ */
206
+ protected storedFlows: Map<string, RegisteredStoredFlow>;
207
+ /**
208
+ * Stored workflows reload timer
209
+ */
210
+ protected syncTimer?: NodeJS.Timeout;
211
+ /**
212
+ * Subscription to the stored workflow changes
213
+ */
214
+ protected syncConsumer?: {
215
+ cancel: () => any;
216
+ };
217
+ /**
218
+ * @override
219
+ */
220
+ resolve(): this;
221
+ /**
222
+ * Register the flows compiled from the `.flow.ts` files (`flows` of the modules), with their crons
223
+ *
224
+ * The first WorkflowService to resolve registers them; the typed calls are resolved in {@link init}, once every
225
+ * service registered its operations.
226
+ */
227
+ protected registerModuleFlows(): void;
228
+ /**
229
+ * The operation a typed call (`target: { class, method }`) runs: the operation of the configured service whose
230
+ * instance is of that class (matched by constructor name, the class or an ancestor)
231
+ * @param target - the target of the task
232
+ * @param target.class - the service class name
233
+ * @param target.method - the method name
234
+ * @returns the operation id, or why there is none: no service (missing) or several (ambiguous)
235
+ */
236
+ resolveTarget(target: {
237
+ class: string;
238
+ method: string;
239
+ }): {
240
+ operation?: string;
241
+ missing?: string;
242
+ ambiguous?: string;
243
+ };
244
+ /**
245
+ * Resolve the typed calls of a flow body in place
246
+ * @param body - the statements
247
+ * @returns the problems, by statement id
248
+ */
249
+ protected resolveTargets(body: any[]): {
250
+ missing: string[];
251
+ ambiguous: string[];
252
+ };
253
+ /**
254
+ * Point every typed call of the compiled flows at the operation of the configured service of its class
255
+ *
256
+ * A flow whose service is not configured (a packaged unit without it) is removed with its crons; a call that several
257
+ * services serve, or a flow whose operation was taken over, stops the startup.
258
+ * @throws FatalInitError on an ambiguous call, or a flow id taken by another operation
259
+ */
260
+ protected resolveModuleTargets(): void;
261
+ /**
262
+ * Remove a module flow: its operation and its crons
263
+ * @param id - the flow id
264
+ */
265
+ protected unregisterModuleFlow(id: string): void;
266
+ /**
267
+ * @override
268
+ */
269
+ init(): Promise<this>;
270
+ /**
271
+ * Stop the worker loop
272
+ *
273
+ * Running attempts get `stopTimeout` to finish, then they are aborted and their outcome dropped: their lease
274
+ * expires and another worker runs them again.
275
+ * @override
276
+ */
277
+ stop(): Promise<void>;
278
+ /**
279
+ * Register a schema in the validator and the application
280
+ * @param name - schema name
281
+ * @param schema - the JSON schema
282
+ */
283
+ protected registerSchema(name: string, schema: any): void;
284
+ /**
285
+ * Register a flow as an operation `<flow id>` served by {@link launch}
286
+ * @param def - the flow definition
287
+ */
288
+ registerFlow(def: FlowDefinition): void;
289
+ /**
290
+ * Get a registered flow
291
+ * @param flowId - the flow id
292
+ * @returns the definition
293
+ */
294
+ getFlow(flowId: string): FlowDefinition | undefined;
295
+ /**
296
+ * Find a flow registered on any WorkflowService, by its operation
297
+ * @param flowId - the flow id
298
+ * @returns the current definition, undefined when the operation is not a flow
299
+ */
300
+ resolveFlow(flowId: string | undefined): FlowDefinition | undefined;
301
+ /**
302
+ * Find a version of a flow
303
+ * @param flowId - the flow id
304
+ * @param version - the version
305
+ * @returns the definition
306
+ */
307
+ getFlowVersion(flowId: string, version: string): FlowDefinition | undefined;
308
+ /**
309
+ * Role needed to write a stored workflow
310
+ * @returns the role
311
+ */
312
+ getStoredWorkflowRole(): string;
313
+ /**
314
+ * Validate and stamp stored workflows on save, and register them once saved
315
+ */
316
+ protected listenStored(): void;
317
+ /**
318
+ * Validate a stored workflow about to be saved and stamp its version and last saver
319
+ * @param workflow - the workflow as it will be saved
320
+ * @param target - the data written: receives `version` and `updatedBy`
321
+ */
322
+ protected prepareStored(workflow: any, target: any): void;
323
+ /**
324
+ * Validate a stored workflow
325
+ * @param workflow - the workflow
326
+ * @throws BadRequest when its name, graph or options are refused
327
+ */
328
+ validateStored(workflow: any): void;
329
+ /**
330
+ * The flow served by an operation, if it is a flow
331
+ * @param flowId - the operation id
332
+ * @returns the flow of the WorkflowService serving the operation
333
+ */
334
+ protected operationFlow(flowId: string): FlowDefinition | undefined;
335
+ /**
336
+ * User a stored flow runs as when the system launches it: its last saver
337
+ * @param flowId - the flow id
338
+ * @returns the user id, undefined when unknown
339
+ */
340
+ storedRunAs(flowId: string): string | undefined;
341
+ /**
342
+ * Identity of a new instance: a stored flow never runs as the system, it runs as its last saver
343
+ * @param def - the flow
344
+ * @param launcher - the identity of the caller (launch) or of the parent instance (child flows)
345
+ * @returns the launcher of the instance
346
+ * @throws Forbidden when a stored flow launched by the system has no user to run as
347
+ */
348
+ protected instanceLauncher(def: FlowDefinition, launcher: WorkflowLauncher): WorkflowLauncher;
349
+ /**
350
+ * Identity of a child flow, which must be allowed to call the flow operation like a launch
351
+ * @param def - the child flow
352
+ * @param launcher - the launcher of the parent
353
+ * @param input - the child input
354
+ * @returns the launcher of the child
355
+ * @throws TaskError Forbidden when the child may not be started
356
+ */
357
+ protected childLauncher(def: FlowDefinition, launcher: WorkflowLauncher, input: any): Promise<WorkflowLauncher>;
358
+ /**
359
+ * A stored workflow changed on this replica: register it here and tell the others
360
+ * @param uuid - the workflow uuid
361
+ */
362
+ protected storedChanged(uuid: string): Promise<void>;
363
+ /**
364
+ * Register, re-register or remove a stored workflow from the store
365
+ * @param uuid - the workflow uuid
366
+ */
367
+ protected syncStored(uuid: string): Promise<void>;
368
+ /**
369
+ * Validate then register a stored workflow; an invalid one is removed and logged
370
+ * @param workflow - the stored workflow
371
+ * @returns true when registered
372
+ */
373
+ protected registerStored(workflow: StoredWorkflow): boolean;
374
+ /**
375
+ * Register a stored workflow as a flow, with its crons
376
+ * @param workflow - the stored workflow
377
+ */
378
+ protected applyStored(workflow: StoredWorkflow): void;
379
+ /**
380
+ * Remove a stored workflow: its operation and its crons (running instances keep their pinned definition)
381
+ * @param uuid - the workflow uuid
382
+ */
383
+ protected unregisterStored(uuid: string): void;
384
+ /**
385
+ * Load every stored workflow: register the new and changed ones, remove the deleted ones
386
+ */
387
+ protected reloadStored(): Promise<void>;
388
+ /**
389
+ * Follow the stored workflow changes of the other replicas: through `syncPubSub`, or a reload every
390
+ * `syncInterval`
391
+ */
392
+ protected startSync(): void;
393
+ /**
394
+ * Launch the flow of the current operation, as the caller
395
+ * @param args - the flow parameters, in order
396
+ * @returns the instance uuid
397
+ */
398
+ launch(...args: any[]): Promise<{
399
+ uuid: string;
400
+ }>;
401
+ /**
402
+ * Create an instance and run it to its first tasks
403
+ * @param def - the flow definition, pinned in the instance
404
+ * @param input - the flow input
405
+ * @param launcher - the identity of the steps
406
+ * @param options - the parent of an awaited child, a fixed uuid (created once)
407
+ * @param options.parent - parent instance and task key
408
+ * @param options.parent.instance - parent instance uuid
409
+ * @param options.parent.key - task key in the parent
410
+ * @param options.uuid - uuid of the instance: an existing one is not created again
411
+ * @returns the instance
412
+ */
413
+ protected createInstance(def: FlowDefinition, input: Record<string, any>, launcher: WorkflowLauncher, options?: {
414
+ parent?: {
415
+ instance: string;
416
+ key: string;
417
+ };
418
+ uuid?: string;
419
+ }): Promise<WorkflowInstance>;
420
+ /**
421
+ * Start the worker loop
422
+ */
423
+ protected startWorker(): void;
424
+ /**
425
+ * One iteration of the worker loop: claim due tasks and run them in the background
426
+ * @returns the poll in progress, it ends when the tasks are claimed and started
427
+ */
428
+ protected poll(): Promise<void>;
429
+ /**
430
+ * Run the recovery sweep when `sweepInterval` passed since the last one
431
+ */
432
+ protected maybeSweep(): Promise<void>;
433
+ /**
434
+ * Replay the stranded instances: active, not updated for `sweepInterval`, without a PENDING or RUNNING task
435
+ *
436
+ * A crash between two steps leaves such an instance: replay is idempotent, and the revision CAS of
437
+ * {@link advance} guards against a concurrent writer.
438
+ * @returns the number of instances replayed
439
+ */
440
+ protected sweep(): Promise<number>;
441
+ /**
442
+ * One poll: claim the due tasks and run them
443
+ * @returns the number of tasks claimed
444
+ */
445
+ protected tick(): Promise<number>;
446
+ /**
447
+ * Claim the due tasks, up to the free slots of this replica
448
+ *
449
+ * The PENDING tasks due now, and the RUNNING ones whose lease expired (their worker crashed)
450
+ * @returns the tasks claimed
451
+ */
452
+ protected claimDue(): Promise<WorkflowTask[]>;
453
+ /**
454
+ * Claim a task with a lease: a conditional patch on its `leaseUntil`
455
+ *
456
+ * Reclaiming an expired lease counts as a new attempt.
457
+ * @param task - the task, as queried
458
+ * @param extra - other fields to set with the claim
459
+ * @returns true when this worker holds the task
460
+ */
461
+ protected claim(task: WorkflowTask, extra?: Partial<WorkflowTask>): Promise<boolean>;
462
+ /**
463
+ * Run a claimed task, write its outcome and advance its instance
464
+ *
465
+ * Every write of the attempt is conditional on the lease this worker holds: an attempt whose lease was lost (its
466
+ * worker was too slow and another one reclaimed it) drops its outcome.
467
+ * @param task - the task
468
+ * @param advance - advance the instance after the outcome is journaled
469
+ */
470
+ protected execute(task: WorkflowTask, advance?: boolean): Promise<void>;
471
+ /**
472
+ * Conditional patch of a task row on the lease this worker holds
473
+ * @param task - the task, with the lease this worker holds
474
+ * @param data - the changes
475
+ * @returns false when another worker holds the lease now
476
+ */
477
+ protected patchLeased(task: WorkflowTask, data: Partial<WorkflowTask>): Promise<boolean>;
478
+ /**
479
+ * Check this worker still holds the lease of a task, and extend it
480
+ * @param task - the task
481
+ * @returns false when the lease was lost
482
+ */
483
+ protected holdsLease(task: WorkflowTask): Promise<boolean>;
484
+ /**
485
+ * Extend the lease of a running task, abort the attempt when the lease was lost
486
+ * @param task - the task
487
+ */
488
+ protected renewLease(task: WorkflowTask): Promise<void>;
489
+ /**
490
+ * Record the end of an attempt, if this worker still holds its lease
491
+ *
492
+ * `leaseUntil` becomes the end time, never 0: a worker that queried the task before cannot claim it again.
493
+ * @param task - the task
494
+ * @param data - status and outcome
495
+ * @returns false when the lease was lost
496
+ */
497
+ protected finishTask(task: WorkflowTask, data: Partial<WorkflowTask>): Promise<boolean>;
498
+ /**
499
+ * Create the next attempt of a failed task, after the backoff delay
500
+ * @param task - the failed attempt
501
+ */
502
+ protected scheduleRetry(task: WorkflowTask): Promise<void>;
503
+ /**
504
+ * Run the operation (or built-in) of a task
505
+ * @param task - the task
506
+ * @param instance - its instance
507
+ * @param controller - aborted on timeout
508
+ * @returns the result
509
+ */
510
+ protected runTask(task: WorkflowTask, instance: WorkflowInstance, controller: AbortController): Promise<any>;
511
+ /**
512
+ * Build the context of the launcher: the session is rebuilt from the user id, so the permissions are fresh
513
+ * @param launcher - the launcher
514
+ * @param input - the operation input
515
+ * @returns the context
516
+ */
517
+ protected launcherContext(launcher: WorkflowLauncher, input: any): SimpleOperationContext;
518
+ /**
519
+ * Convert an error to the data the flow sees
520
+ * @param err - the error
521
+ * @param operation - the operation of the task
522
+ * @returns the flow error
523
+ */
524
+ protected toFlowError(err: any, operation: string): FlowError;
525
+ /**
526
+ * Write a task outcome to the instance journal: a conditional patch on `revision`, retried on conflict
527
+ *
528
+ * The first outcome of a key wins. A journal over `maxContextSize` fails the instance.
529
+ * @param instanceId - the instance uuid
530
+ * @param key - the task key
531
+ * @param entry - the outcome
532
+ * @returns true when the outcome is in the journal
533
+ */
534
+ protected writeJournal(instanceId: string, key: string, entry: JournalEntry): Promise<boolean>;
535
+ /**
536
+ * Patch an instance if its revision did not change
537
+ * @param instance - the instance as read
538
+ * @param data - the changes
539
+ * @returns false when another writer changed it first
540
+ */
541
+ protected patchInstance(instance: WorkflowInstance, data: Partial<WorkflowInstance>): Promise<boolean>;
542
+ /**
543
+ * Replay an instance and act on the result: finish it, or create its missing tasks
544
+ * @param instanceId - the instance uuid
545
+ */
546
+ protected advance(instanceId: string): Promise<void>;
547
+ /**
548
+ * Create the task of a scheduled key, unless a PENDING or RUNNING one exists
549
+ * @param instance - the instance
550
+ * @param scheduled - the task to run
551
+ * @returns true when the task was resolved at once (a buffered signal): the journal changed
552
+ */
553
+ protected scheduleTask(instance: WorkflowInstance, scheduled: ScheduledTask): Promise<boolean>;
554
+ /**
555
+ * Start an awaited child flow: the task waits for the child instance, which runs as the same launcher
556
+ * @param instance - the parent instance
557
+ * @param scheduled - the task, its operation is a flow id
558
+ * @param index - row index of the key
559
+ * @returns true when the child finished at once: the parent journal changed
560
+ */
561
+ protected scheduleChild(instance: WorkflowInstance, scheduled: ScheduledTask, index: number): Promise<boolean>;
562
+ /**
563
+ * Journal the end of a child into its parent: its output, its error, or `Cancelled`
564
+ * @param childId - the child instance uuid
565
+ */
566
+ protected deliverToParent(childId: string): Promise<void>;
567
+ /**
568
+ * Cancel an instance, its live tasks and the children it waits on
569
+ * @param uuid - the instance uuid
570
+ */
571
+ cancelInstance(uuid: string): Promise<void>;
572
+ /**
573
+ * Cancel an instance and, recursively, the children it waits on
574
+ * @param uuid - the instance uuid
575
+ * @returns false when the instance was not running
576
+ */
577
+ protected cancelTree(uuid: string): Promise<boolean>;
578
+ /**
579
+ * Mark a task row CANCELLED, conditionally on its lease: whoever holds it can no longer write its outcome
580
+ * @param row - the task row, as read
581
+ */
582
+ protected supersede(row: WorkflowTask): Promise<void>;
583
+ /**
584
+ * Restart a failed instance: drop the outcome that failed it and every outcome journaled after it, then replay
585
+ * @param uuid - the instance uuid
586
+ */
587
+ retryInstance(uuid: string): Promise<void>;
588
+ /**
589
+ * Move a running instance to another version of its flow
590
+ *
591
+ * Refused when a journaled or live task key has no statement in the target graph.
592
+ * @param uuid - the instance uuid
593
+ * @param version - the target version, the latest registered when undefined
594
+ */
595
+ migrateInstance(uuid: string, version?: string): Promise<void>;
596
+ /**
597
+ * Deliver a signal: resolve the waits on `(event, key)` whose instance accepts the caller, or buffer it when
598
+ * nothing waits
599
+ * @param event - event name
600
+ * @param key - business key
601
+ * @param payload - the result of the waits
602
+ * @returns the number of waits resolved
603
+ */
604
+ signal(event: string, key: string, payload?: any): Promise<{
605
+ delivered: number;
606
+ }>;
607
+ /**
608
+ * The waits on `(event, key)` of active instances
609
+ * @param event - event name
610
+ * @param key - business key
611
+ * @returns the waits and their instance
612
+ */
613
+ protected waitsFor(event: string, key: string): Promise<{
614
+ instance: WorkflowInstance;
615
+ task: WorkflowTask;
616
+ }[]>;
617
+ /**
618
+ * Whether a sender may signal a wait: the launcher, the system, and the users in the `allow` of the wait
619
+ * @param context - the sender
620
+ * @param instance - the instance waiting
621
+ * @param task - the wait
622
+ * @returns true when allowed
623
+ */
624
+ protected canSignal(context: OperationContext, instance: WorkflowInstance, task: WorkflowTask): Promise<boolean>;
625
+ /**
626
+ * Save a signal nothing waits for yet
627
+ * @param context - the sender
628
+ * @param event - event name
629
+ * @param key - business key
630
+ * @param payload - the payload
631
+ * @returns the buffered signal
632
+ */
633
+ protected bufferSignal(context: OperationContext, event: string, key: string, payload: any): Promise<WorkflowSignal>;
634
+ /**
635
+ * Deliver a just buffered signal to a wait created while it was being saved
636
+ * @param signal - the buffered signal
637
+ * @returns true when a wait consumed it
638
+ */
639
+ protected deliverBuffered(signal: WorkflowSignal): Promise<boolean>;
640
+ /**
641
+ * Resolve a new wait with the oldest unexpired buffered signal its instance accepts
642
+ * @param instance - the instance
643
+ * @param task - the wait
644
+ * @returns true when a signal was consumed
645
+ */
646
+ protected consumeBuffered(instance: WorkflowInstance, task: WorkflowTask): Promise<boolean>;
647
+ /**
648
+ * Consume a buffered signal for a wait: its sender is checked now, against this instance
649
+ * @param signal - the buffered signal
650
+ * @param instance - the instance waiting
651
+ * @param task - the wait
652
+ * @param advance - advance the instance once the payload is journaled
653
+ * @returns true when consumed and delivered
654
+ */
655
+ protected consumeSignal(signal: WorkflowSignal, instance: WorkflowInstance, task: WorkflowTask, advance: boolean): Promise<boolean>;
656
+ /**
657
+ * Resolve a wait with a payload: claimed like a task, so it resolves once
658
+ * @param task - the wait
659
+ * @param payload - its result
660
+ * @param advance - advance the instance once the payload is journaled
661
+ * @returns false when the wait was already resolved or timed out
662
+ */
663
+ protected resolveWait(task: WorkflowTask, payload: any, advance?: boolean): Promise<boolean>;
664
+ /**
665
+ * End of a `Workflow.Sleep`
666
+ * @param input - `{ duration?: string, until?: number }`
667
+ * @param now - the current time
668
+ * @returns when the timer fires
669
+ */
670
+ protected sleepUntil(input: any, now: number): number;
671
+ /**
672
+ * Create a task row, unless another worker created the same row first
673
+ * @param instance - the instance uuid
674
+ * @param scheduled - the task
675
+ * @param launcherId - user id of the launcher
676
+ * @param runAt - when it becomes runnable
677
+ * @param attempt - attempt number
678
+ * @param index - row index of the key, when known
679
+ * @param extra - other fields of the row
680
+ * @returns the task created, undefined when another worker created it
681
+ */
682
+ protected createTask(instance: string, scheduled: ScheduledTask, launcherId: string | undefined, runAt: number, attempt: number, index?: number, extra?: Partial<WorkflowTask>): Promise<WorkflowTask | undefined>;
683
+ }
684
+ export default WorkflowService;
685
+ //# sourceMappingURL=workflow.service.d.ts.map