@orkestrel/workflow 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/src/browser/index.d.ts +23 -38
- package/dist/src/browser/index.js +51 -122
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +595 -250
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +151 -65
- package/dist/src/core/index.d.ts +151 -65
- package/dist/src/core/index.js +595 -252
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +21 -43
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +12 -17
- package/dist/src/server/index.d.ts +12 -17
- package/dist/src/server/index.js +21 -43
- package/dist/src/server/index.js.map +1 -1
- package/package.json +8 -8
|
@@ -92,6 +92,27 @@ export declare function buildWorkflowContext(node: WorkflowContext): WorkflowCon
|
|
|
92
92
|
*/
|
|
93
93
|
export declare function canTransitionTask(from: TaskStatus, to: TaskStatus): boolean;
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Capture every top-level {@link WorkflowOptions} value exactly once into an owned plain bag.
|
|
97
|
+
*
|
|
98
|
+
* @remarks
|
|
99
|
+
* Direct property reads preserve inherited and non-enumerable option values while preventing
|
|
100
|
+
* accessor-backed caller bags from shifting policy, handlers, hooks, or nested options between
|
|
101
|
+
* construction stages. Nested bags and the functions registry retain their original identities so
|
|
102
|
+
* entity constructors can snapshot keyed child options and live additions can resolve against the
|
|
103
|
+
* same registry.
|
|
104
|
+
*
|
|
105
|
+
* @param options - The caller-owned workflow construction options
|
|
106
|
+
* @returns An owned top-level options bag containing the captured values
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const captured = captureWorkflowOptions(options)
|
|
111
|
+
* const workflow = createWorkflow(definition, captured)
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function captureWorkflowOptions(options?: WorkflowOptions): WorkflowOptions;
|
|
115
|
+
|
|
95
116
|
/**
|
|
96
117
|
* Validate and clone one complete task activity frame.
|
|
97
118
|
*
|
|
@@ -113,9 +134,11 @@ export declare function cloneTaskActivity(input: unknown, updated?: number): Tas
|
|
|
113
134
|
* Validate and own a workflow snapshot before live construction.
|
|
114
135
|
*
|
|
115
136
|
* @param input - The hostile snapshot boundary
|
|
137
|
+
* @param id - The optional storage key the owned snapshot must match
|
|
116
138
|
* @returns A deeply owned frozen snapshot
|
|
139
|
+
* @throws {WorkflowError} With `RESTORE` when the snapshot is invalid or does not match `id`
|
|
117
140
|
*/
|
|
118
|
-
export declare function cloneWorkflowSnapshot(input: unknown): WorkflowSnapshot;
|
|
141
|
+
export declare function cloneWorkflowSnapshot(input: unknown, id?: string): WorkflowSnapshot;
|
|
119
142
|
|
|
120
143
|
/**
|
|
121
144
|
* Flatten a nested list of per-phase {@link TaskResult} lists into one positional list
|
|
@@ -242,7 +265,7 @@ export declare interface ControllerInterface<TInput, TResult> {
|
|
|
242
265
|
* @remarks
|
|
243
266
|
* Builds a one-table database (`snapshots`, keyed by `id`) over the supplied driver, the snapshot
|
|
244
267
|
* held as ONE OPAQUE JSON COLUMN — the column map is `{ id; snapshot }` where `snapshot` is a
|
|
245
|
-
* `rawShape` (a JSON blob), exactly as
|
|
268
|
+
* `rawShape` (a JSON blob), exactly as `createDatabaseQueueStore` stores its `input`. The
|
|
246
269
|
* snapshot is already a COMPLETE, self-contained, pure-JSON payload, so storing it whole is lossless
|
|
247
270
|
* AND keeps the row type FLAT — a structured multi-column snapshot table would force the contract to
|
|
248
271
|
* `Infer` the deeply-nested snapshot shape (workflow → phases → tasks → results) and trip TS2589;
|
|
@@ -258,7 +281,8 @@ export declare interface ControllerInterface<TInput, TResult> {
|
|
|
258
281
|
*
|
|
259
282
|
* @example
|
|
260
283
|
* ```ts
|
|
261
|
-
* import {
|
|
284
|
+
* import { createMemoryDriver } from '@orkestrel/database'
|
|
285
|
+
* import { createDatabaseWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
|
|
262
286
|
*
|
|
263
287
|
* const store = createDatabaseWorkflowStore(createMemoryDriver()) // a durable driver swaps in here
|
|
264
288
|
* const workflow = createWorkflow(definition)
|
|
@@ -285,7 +309,7 @@ export declare function createDeferred<T>(): DeferredInterface<T>;
|
|
|
285
309
|
*
|
|
286
310
|
* @remarks
|
|
287
311
|
* The snapshot analogue of the server package's `createMemorySessionStore`
|
|
288
|
-
* (and the
|
|
312
|
+
* (and the `createMemoryQueueStore` family), but LEANER — there is no idle-TTL, so no
|
|
289
313
|
* options bag (AGENTS §21 minimal): a persisted run-state lives until an explicit `delete`. This is
|
|
290
314
|
* the zero-plumbing DEFAULT (a plain `Map`); its driver-pluggable twin is
|
|
291
315
|
* {@link createDatabaseWorkflowStore} (the snapshot as one opaque JSON column over a `databases`
|
|
@@ -297,7 +321,7 @@ export declare function createDeferred<T>(): DeferredInterface<T>;
|
|
|
297
321
|
*
|
|
298
322
|
* @example
|
|
299
323
|
* ```ts
|
|
300
|
-
* import { createMemoryWorkflowStore, createWorkflow, restoreWorkflow } from '@
|
|
324
|
+
* import { createMemoryWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
|
|
301
325
|
*
|
|
302
326
|
* const store = createMemoryWorkflowStore()
|
|
303
327
|
* const workflow = createWorkflow(definition)
|
|
@@ -337,7 +361,7 @@ export declare function createMemoryWorkflowStore(): WorkflowStoreInterface;
|
|
|
337
361
|
*
|
|
338
362
|
* @example
|
|
339
363
|
* ```ts
|
|
340
|
-
* import { createRunner } from '@
|
|
364
|
+
* import { createRunner } from '@orkestrel/workflow'
|
|
341
365
|
*
|
|
342
366
|
* // A handler that fans out one sibling per declared unit, then returns its own value.
|
|
343
367
|
* const runner = createRunner<number, number>({
|
|
@@ -363,7 +387,8 @@ export declare function createRunner<TInput, TResult>(options: RunnerOptions<TIn
|
|
|
363
387
|
* `yield()` gives the host a turn via a zero-delay macrotask (so pending I/O,
|
|
364
388
|
* timers, and rendering actually run — a microtask would not); `delay(ms)` resumes
|
|
365
389
|
* after at least `ms`. Pass `options.signal` to make a pending yield/delay reject
|
|
366
|
-
* with the signal's `reason
|
|
390
|
+
* with the signal's exact `reason`; the shared owned-signal lifecycle clears the timer
|
|
391
|
+
* without invoking caller-owned listener methods.
|
|
367
392
|
* `options.priority` is accepted for contract compliance but treated uniformly by
|
|
368
393
|
* this default — environment backends honour it.
|
|
369
394
|
*
|
|
@@ -371,7 +396,8 @@ export declare function createRunner<TInput, TResult>(options: RunnerOptions<TIn
|
|
|
371
396
|
*
|
|
372
397
|
* @example
|
|
373
398
|
* ```ts
|
|
374
|
-
* import { createAbort
|
|
399
|
+
* import { createAbort } from '@orkestrel/abort'
|
|
400
|
+
* import { createScheduler } from '@orkestrel/workflow'
|
|
375
401
|
*
|
|
376
402
|
* const abort = createAbort()
|
|
377
403
|
* const scheduler = createScheduler()
|
|
@@ -385,7 +411,7 @@ export declare function createRunner<TInput, TResult>(options: RunnerOptions<TIn
|
|
|
385
411
|
*
|
|
386
412
|
* @example
|
|
387
413
|
* ```ts
|
|
388
|
-
* import { createScheduler } from '@
|
|
414
|
+
* import { createScheduler } from '@orkestrel/workflow'
|
|
389
415
|
*
|
|
390
416
|
* // A backoff: wait a growing interval between retries.
|
|
391
417
|
* const scheduler = createScheduler()
|
|
@@ -424,7 +450,7 @@ export declare function createScheduler(): SchedulerInterface;
|
|
|
424
450
|
*
|
|
425
451
|
* @example
|
|
426
452
|
* ```ts
|
|
427
|
-
* import { createWorkflow } from '@
|
|
453
|
+
* import { createWorkflow } from '@orkestrel/workflow'
|
|
428
454
|
*
|
|
429
455
|
* const workflow = createWorkflow(definition, { on: { complete: () => done() } })
|
|
430
456
|
* const phase = workflow.phase('phase-build')
|
|
@@ -452,7 +478,7 @@ export declare function createWorkflow(definition: WorkflowDefinition, options?:
|
|
|
452
478
|
*
|
|
453
479
|
* @example
|
|
454
480
|
* ```ts
|
|
455
|
-
* import { createWorkflowContract } from '@
|
|
481
|
+
* import { createWorkflowContract } from '@orkestrel/workflow'
|
|
456
482
|
*
|
|
457
483
|
* const contract = createWorkflowContract()
|
|
458
484
|
* const definition = contract.generate() // a valid WorkflowDefinition
|
|
@@ -482,7 +508,7 @@ export declare function createWorkflowContract(): ContractInterface<WorkflowDefi
|
|
|
482
508
|
*
|
|
483
509
|
* @example
|
|
484
510
|
* ```ts
|
|
485
|
-
* import { createMemoryWorkflowStore, createWorkflowManager } from '@
|
|
511
|
+
* import { createMemoryWorkflowStore, createWorkflowManager } from '@orkestrel/workflow'
|
|
486
512
|
*
|
|
487
513
|
* const manager = createWorkflowManager({
|
|
488
514
|
* store: createMemoryWorkflowStore(),
|
|
@@ -527,7 +553,7 @@ export declare function createWorkflowManager(options?: WorkflowManagerOptions):
|
|
|
527
553
|
*
|
|
528
554
|
* @example
|
|
529
555
|
* ```ts
|
|
530
|
-
* import { createWorkflowRunner } from '@
|
|
556
|
+
* import { createWorkflowRunner } from '@orkestrel/workflow'
|
|
531
557
|
*
|
|
532
558
|
* const runner = createWorkflowRunner()
|
|
533
559
|
* const definition = { id: 'w', name: 'W', phases: [{ id: 'p', name: 'P', tasks: [
|
|
@@ -569,7 +595,8 @@ export declare function createWorkflowRunner(options?: WorkflowRunnerOptions): W
|
|
|
569
595
|
* the row `{ id: snapshot.id, snapshot }`.
|
|
570
596
|
* - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
|
|
571
597
|
* a {@link WorkflowSnapshot} ({@link import('../helpers.js').isWorkflowSnapshot} — the AGENTS §14
|
|
572
|
-
* boundary narrow for an untrusted storage read), or `undefined` if none is stored.
|
|
598
|
+
* boundary narrow for an untrusted storage read), or `undefined` if none is stored. A present
|
|
599
|
+
* snapshot whose own id differs from the requested key rejects with normalized `RESTORE` evidence.
|
|
573
600
|
* - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
|
|
574
601
|
*
|
|
575
602
|
* UNLIKE the server package's `SessionStoreInterface` there is NO
|
|
@@ -580,7 +607,8 @@ export declare function createWorkflowRunner(options?: WorkflowRunnerOptions): W
|
|
|
580
607
|
*
|
|
581
608
|
* @example
|
|
582
609
|
* ```ts
|
|
583
|
-
* import {
|
|
610
|
+
* import { createMemoryDriver } from '@orkestrel/database'
|
|
611
|
+
* import { createDatabaseWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
|
|
584
612
|
*
|
|
585
613
|
* const store = createDatabaseWorkflowStore(createMemoryDriver()) // a durable driver swaps in here
|
|
586
614
|
* const workflow = createWorkflow(definition)
|
|
@@ -599,7 +627,7 @@ export declare class DatabaseWorkflowStore implements WorkflowStoreInterface {
|
|
|
599
627
|
* {@link WorkflowSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)
|
|
600
628
|
*/
|
|
601
629
|
constructor(table: TableInterface<WorkflowSnapshotRow>);
|
|
602
|
-
/** Resolve the
|
|
630
|
+
/** Resolve and key-check the snapshot for `id`, narrowing the opaque column to `WorkflowSnapshot`. */
|
|
603
631
|
get(id: string): Promise<WorkflowSnapshot | undefined>;
|
|
604
632
|
/** Insert or replace under the snapshot's OWN `id` (no separate id param) — the row is `{ id, snapshot }`. */
|
|
605
633
|
set(snapshot: WorkflowSnapshot): Promise<void>;
|
|
@@ -799,8 +827,19 @@ export declare function failure<E>(error: E): Failure<E>;
|
|
|
799
827
|
*/
|
|
800
828
|
export declare function findFailure(results: readonly TaskResult[]): TaskResult | undefined;
|
|
801
829
|
|
|
802
|
-
/**
|
|
803
|
-
|
|
830
|
+
/**
|
|
831
|
+
* Test that every named task has a callable runtime handler before dispatch.
|
|
832
|
+
*
|
|
833
|
+
* @remarks
|
|
834
|
+
* A snapshot lookup reads each unique `run` binding at most once from `functions`. A live workflow
|
|
835
|
+
* validates its tasks' already-resolved handlers without consulting the retained registry again.
|
|
836
|
+
*
|
|
837
|
+
* @param workflow - The persisted snapshot or constructed live workflow to validate
|
|
838
|
+
* @returns Whether every named task resolves to a callable handler
|
|
839
|
+
*/
|
|
840
|
+
export declare function hasWorkflowHandlers(workflow: WorkflowInterface): boolean;
|
|
841
|
+
|
|
842
|
+
export declare function hasWorkflowHandlers(workflow: WorkflowSnapshot, functions: WorkflowFunctions | undefined): boolean;
|
|
804
843
|
|
|
805
844
|
/**
|
|
806
845
|
* Insert one `[key, value]` entry at a positional index into a readonly entries array —
|
|
@@ -945,7 +984,7 @@ export declare const MAX_TIMER_MS = 2147483647;
|
|
|
945
984
|
*
|
|
946
985
|
* @example
|
|
947
986
|
* ```ts
|
|
948
|
-
* import { createMemoryWorkflowStore, createWorkflow, restoreWorkflow } from '@
|
|
987
|
+
* import { createMemoryWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
|
|
949
988
|
*
|
|
950
989
|
* const store = createMemoryWorkflowStore()
|
|
951
990
|
* const workflow = createWorkflow(definition)
|
|
@@ -1017,9 +1056,9 @@ export declare function parkSignal(signal: AbortSignal): Promise<void>;
|
|
|
1017
1056
|
*
|
|
1018
1057
|
* @remarks
|
|
1019
1058
|
* - **Derived status.** `status` is `#override` when one is in force, else
|
|
1020
|
-
* {@link derivePhaseStatus} over the live tasks' statuses.
|
|
1059
|
+
* {@link derivePhaseStatus} over the live tasks' statuses. `#recompute` (passed to
|
|
1021
1060
|
* each child {@link Task}) re-derives on every child transition; a CHANGE emits the matching
|
|
1022
|
-
* event AND escalates to the workflow (
|
|
1061
|
+
* event AND escalates to the workflow (`#escalate`, the upward step of the cascade).
|
|
1023
1062
|
* - **Override (AGENTS §10).** `skip` / `stop` FORCE the phase's status (e.g. skipping a whole
|
|
1024
1063
|
* phase), overriding the derived value; the override is PERSISTED in the snapshot's own
|
|
1025
1064
|
* `override` field and restored DIRECTLY (no divergence guess), so a forced phase round-trips.
|
|
@@ -1050,10 +1089,12 @@ export declare function parkSignal(signal: AbortSignal): Promise<void>;
|
|
|
1050
1089
|
* construction path {@link #append} uses at build time, so a live mint and a restored/built
|
|
1051
1090
|
* task are wired IDENTICALLY. At construction, the workflow-level
|
|
1052
1091
|
* {@link import('../types.js').WorkflowFunctions} registry (threaded from
|
|
1053
|
-
* {@link import('../types.js').WorkflowOptions.functions}) resolves
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
1092
|
+
* {@link import('../types.js').WorkflowOptions.functions}) resolves every unique initial `run`
|
|
1093
|
+
* name ONCE before any task is built; siblings sharing a name receive the exact same captured
|
|
1094
|
+
* runtime {@link import('../types.js').TaskInterface.handler}. A later live {@link add} reads
|
|
1095
|
+
* that name once from the retained registry at its own mint moment. An omitted or unregistered
|
|
1096
|
+
* `run` resolves to no handler; only omission is a no-op, while an unresolved present name makes
|
|
1097
|
+
* the containing tree non-drivable.
|
|
1057
1098
|
* - **Runtime lifecycle (AGENTS §10).** `pause` / `resume` / `wait` mirror the workflow's own
|
|
1058
1099
|
* quartet, scoped to this phase — a driving
|
|
1059
1100
|
* {@link import('../types.js').WorkflowRunnerInterface.execute} gates a task's own
|
|
@@ -1649,6 +1690,11 @@ export declare const phaseUpdateShape: ObjectShape<{
|
|
|
1649
1690
|
/**
|
|
1650
1691
|
* Rebuild an interrupted workflow at its remaining retry budget.
|
|
1651
1692
|
*
|
|
1693
|
+
* @remarks
|
|
1694
|
+
* Each phase captures every unique initial `run` binding once before constructing tasks. Recovery
|
|
1695
|
+
* validates those live tasks' captured callable handlers without rereading the registry, while the
|
|
1696
|
+
* retained registry identity remains available to resolve future live additions at their mint time.
|
|
1697
|
+
*
|
|
1652
1698
|
* @param snapshot - The hostile persisted snapshot
|
|
1653
1699
|
* @param options - Runtime handlers and entity options
|
|
1654
1700
|
* @returns A recoverable live workflow
|
|
@@ -1699,7 +1745,7 @@ export declare function resolveTaskSilence(value: number | undefined, fallback:
|
|
|
1699
1745
|
*
|
|
1700
1746
|
* @example
|
|
1701
1747
|
* ```ts
|
|
1702
|
-
* import { restoreWorkflow } from '@
|
|
1748
|
+
* import { restoreWorkflow } from '@orkestrel/workflow'
|
|
1703
1749
|
*
|
|
1704
1750
|
* const restored = restoreWorkflow(workflow.snapshot()) // bail comes from the snapshot
|
|
1705
1751
|
* restored.status === workflow.status // true
|
|
@@ -1794,7 +1840,7 @@ export declare class Runner<TInput, TResult> implements RunnerInterface<TInput,
|
|
|
1794
1840
|
*/
|
|
1795
1841
|
spawn(input: TInput): Promise<TResult> | undefined;
|
|
1796
1842
|
execute(inputs: readonly TInput[]): Promise<readonly TResult[]>;
|
|
1797
|
-
abort(reason?: unknown): void
|
|
1843
|
+
abort(reason?: unknown): Promise<void>;
|
|
1798
1844
|
/**
|
|
1799
1845
|
* Suspend dispatch (AGENTS §10 — resumable): delegates to the backing queue's own
|
|
1800
1846
|
* `pause`, which holds the NEXT dispatch while any in-flight unit finishes.
|
|
@@ -1824,8 +1870,8 @@ export declare class Runner<TInput, TResult> implements RunnerInterface<TInput,
|
|
|
1824
1870
|
* gate, no recorded failure, no fail-fast trip) rather than a genuine failure — a
|
|
1825
1871
|
* dispatched unit's rejection while stopping is still a real failure. Idempotent.
|
|
1826
1872
|
*/
|
|
1827
|
-
stop(): void
|
|
1828
|
-
destroy(): void
|
|
1873
|
+
stop(): Promise<void>;
|
|
1874
|
+
destroy(): Promise<void>;
|
|
1829
1875
|
}
|
|
1830
1876
|
|
|
1831
1877
|
/**
|
|
@@ -1957,8 +2003,9 @@ export declare interface RunnerInterface<TInput, TResult> {
|
|
|
1957
2003
|
* `execute` reject.
|
|
1958
2004
|
*
|
|
1959
2005
|
* @param reason - An optional cancellation reason propagated to every unit's signal
|
|
2006
|
+
* @returns The stable cleanup barrier
|
|
1960
2007
|
*/
|
|
1961
|
-
abort(reason?: unknown): void
|
|
2008
|
+
abort(reason?: unknown): Promise<void>;
|
|
1962
2009
|
/**
|
|
1963
2010
|
* Suspend dispatch (AGENTS §10 — resumable): the backing queue holds the NEXT dispatch
|
|
1964
2011
|
* while any in-flight unit finishes; idempotent.
|
|
@@ -1995,10 +2042,15 @@ export declare interface RunnerInterface<TInput, TResult> {
|
|
|
1995
2042
|
* runner.stop() // the in-flight unit finishes; the rest are gracefully dropped
|
|
1996
2043
|
* await results // resolves with whatever settled — never rejects
|
|
1997
2044
|
* ```
|
|
2045
|
+
* @returns The stable graceful-cleanup barrier
|
|
1998
2046
|
*/
|
|
1999
|
-
stop(): void
|
|
2000
|
-
/**
|
|
2001
|
-
|
|
2047
|
+
stop(): Promise<void>;
|
|
2048
|
+
/**
|
|
2049
|
+
* Tear the runner down, awaiting backing-queue cleanup before destroying the emitter last.
|
|
2050
|
+
*
|
|
2051
|
+
* @returns The stable teardown barrier
|
|
2052
|
+
*/
|
|
2053
|
+
destroy(): Promise<void>;
|
|
2002
2054
|
}
|
|
2003
2055
|
|
|
2004
2056
|
/**
|
|
@@ -2008,11 +2060,11 @@ export declare interface RunnerInterface<TInput, TResult> {
|
|
|
2008
2060
|
* - `handler` — runs each unit's work against its {@link ControllerInterface};
|
|
2009
2061
|
* rejecting fails the unit (and, after retries are exhausted, fails the run).
|
|
2010
2062
|
* - `concurrency` — the maximum units in flight at once; defaults to `1` (ordered,
|
|
2011
|
-
* one-at-a-time)
|
|
2063
|
+
* one-at-a-time) and must be a positive safe integer.
|
|
2012
2064
|
* - `retries` — the default extra attempts per unit on failure (or a per-attempt
|
|
2013
|
-
* timeout); defaults to `0
|
|
2014
|
-
* - `timeout` — the per-attempt deadline in milliseconds; defaults to
|
|
2015
|
-
*
|
|
2065
|
+
* timeout); defaults to `0` and must be a nonnegative safe integer.
|
|
2066
|
+
* - `timeout` — the per-attempt deadline in milliseconds; defaults to `0`, must be
|
|
2067
|
+
* an integer in `0..2_147_483_647`, and `0` disables the deadline.
|
|
2016
2068
|
* - `entries` — per-entry `retries` / `timeout` overrides, resolved from each
|
|
2017
2069
|
* input; falls back to the runner-level `retries` / `timeout` defaults.
|
|
2018
2070
|
* - `on` — the reserved {@link EmitterHooks} key (§8): initial listeners for the runner's
|
|
@@ -2048,6 +2100,25 @@ export declare interface RunnerUnit<TInput> {
|
|
|
2048
2100
|
readonly input: TInput;
|
|
2049
2101
|
}
|
|
2050
2102
|
|
|
2103
|
+
/**
|
|
2104
|
+
* Schedule one cancellable host operation behind an owned settlement signal.
|
|
2105
|
+
*
|
|
2106
|
+
* @remarks
|
|
2107
|
+
* The completion and failure paths each own an {@link AbortController}; their native composite is
|
|
2108
|
+
* linked to the optional caller signal before `start` can arm host work. Scheduler backends attach
|
|
2109
|
+
* only to that safe composite, so caller mutation of `addEventListener` or `removeEventListener`
|
|
2110
|
+
* cannot strand the operation. The first completion resolves, the first host failure rejects with
|
|
2111
|
+
* its exact value, and caller abort rejects with its exact linked reason. Caller abort and host
|
|
2112
|
+
* failure cancel an armed handle; synchronous settlement also cancels the handle immediately after
|
|
2113
|
+
* `start` returns it. Cancellation is secondary cleanup: if its closure throws, the already-winning
|
|
2114
|
+
* completion, exact host failure, or exact caller reason still settles without escape or replacement.
|
|
2115
|
+
*
|
|
2116
|
+
* @param start - Arm host work and return its cancellation closure
|
|
2117
|
+
* @param signal - Optional caller cancellation signal
|
|
2118
|
+
* @returns A promise settled exactly once by completion, host failure, or caller abort
|
|
2119
|
+
*/
|
|
2120
|
+
export declare function scheduleHost(start: (complete: () => void, failure: (error: unknown) => void) => () => void, signal?: AbortSignal): Promise<void>;
|
|
2121
|
+
|
|
2051
2122
|
/**
|
|
2052
2123
|
* The safe cross-environment cooperative-yield default — a {@link SchedulerInterface}
|
|
2053
2124
|
* built on `setTimeout` / `clearTimeout` alone, so it runs unchanged in both the
|
|
@@ -2064,11 +2135,10 @@ export declare interface RunnerUnit<TInput> {
|
|
|
2064
2135
|
* regains control, so it would not actually let pending I/O, timers, or
|
|
2065
2136
|
* rendering run — it only defers within the current task. A zero-delay timer is
|
|
2066
2137
|
* the correct cross-environment "give the host a turn".
|
|
2067
|
-
* - **Abort-aware.** A pending `yield` / `delay` rejects with `signal.reason`
|
|
2068
|
-
*
|
|
2069
|
-
*
|
|
2070
|
-
*
|
|
2071
|
-
* listener, and no double-settle.
|
|
2138
|
+
* - **Abort-aware.** A pending `yield` / `delay` rejects with `signal.reason` exactly.
|
|
2139
|
+
* {@link scheduleHost} links an owned settlement composite to the caller before arming
|
|
2140
|
+
* the timer, so pre-abort schedules nothing, caller signal method mutation is harmless,
|
|
2141
|
+
* cancellation clears the handle, and native first-settlement wins exactly once.
|
|
2072
2142
|
* - **Priority is accepted but uniform.** `options.priority` is part of the
|
|
2073
2143
|
* contract, but a `setTimeout`-based default cannot act on urgency, so it treats
|
|
2074
2144
|
* every priority the same. Environment backends honour it.
|
|
@@ -2956,11 +3026,11 @@ export declare type UnitOutcome<TResult> = {
|
|
|
2956
3026
|
* - **Construction.** Built from a {@link WorkflowSnapshot} (the unified input —
|
|
2957
3027
|
* {@link import('./factories.js').createWorkflow} seeds an initial snapshot from a
|
|
2958
3028
|
* {@link import('./types.js').WorkflowDefinition}, {@link import('./factories.js').restoreWorkflow}
|
|
2959
|
-
* passes a persisted one). Each child {@link Phase} is wired to escalate to
|
|
3029
|
+
* passes a persisted one). Each child {@link Phase} is wired to escalate to `#recompute`.
|
|
2960
3030
|
* - **Derived status.** `status` is `#override` when forced, else
|
|
2961
3031
|
* {@link deriveWorkflowStatus} over the live phases' statuses feeding `bail`. `failed` is
|
|
2962
3032
|
* reachable ONLY under `bail: true` (a single failed task halts the workflow); under
|
|
2963
|
-
* `bail: false` a failed phase folds into `completed`.
|
|
3033
|
+
* `bail: false` a failed phase folds into `completed`. `#recompute` diffs on each phase
|
|
2964
3034
|
* change; a CHANGE emits.
|
|
2965
3035
|
* - **Override (AGENTS §10).** `skip` / `stop` FORCE the status; an executed task-free pending tree
|
|
2966
3036
|
* may also be force-completed vacuously. The override is PERSISTED in the snapshot's own
|
|
@@ -3414,12 +3484,11 @@ export declare interface WorkflowInterface {
|
|
|
3414
3484
|
* `functions` registry in) and stores it under `definition.id` — an already-present id
|
|
3415
3485
|
* OVERWRITES (last write wins). `count` is the map size, `workflow(id)` looks one up,
|
|
3416
3486
|
* `workflows()` lists them in insertion order.
|
|
3417
|
-
* - **Durable open / save.** `open(id)` returns an already-registered workflow directly;
|
|
3418
|
-
*
|
|
3419
|
-
*
|
|
3420
|
-
*
|
|
3421
|
-
*
|
|
3422
|
-
* unknown id.
|
|
3487
|
+
* - **Durable open / save.** `open(id)` returns an already-registered workflow directly; same-id
|
|
3488
|
+
* misses share one hydration. A concurrent `add` wins, while `remove` / `clear` invalidate
|
|
3489
|
+
* earlier reads; wrong-key payloads reject with `RESTORE`. `save(id)` captures a registered
|
|
3490
|
+
* workflow's snapshot at invocation and serializes same-id writes without coupling other ids.
|
|
3491
|
+
* Both remain lenient without a store or registered id.
|
|
3423
3492
|
* - **Removal.** `remove` drops one by id, or a batch (§9.2, array overload FIRST) — `true` when
|
|
3424
3493
|
* any was removed. `clear` empties the registry.
|
|
3425
3494
|
* - **No active pointer.** Unlike its `ConversationManager` / `WorkspaceManager` twins, there is
|
|
@@ -3469,10 +3538,17 @@ export declare class WorkflowManager implements WorkflowManagerInterface {
|
|
|
3469
3538
|
* `workflows()` lists them in insertion order.
|
|
3470
3539
|
* - **Durable open / save (the optional `store` seam).** When a {@link WorkflowStoreInterface}
|
|
3471
3540
|
* is supplied (the `store` option), `open(id)` resolves an already-registered workflow
|
|
3472
|
-
* directly (no store hit);
|
|
3541
|
+
* directly (no store hit); same-id registry misses share one in-flight hydration. On a MISS
|
|
3542
|
+
* it HYDRATES one from `store.get(id)` through
|
|
3473
3543
|
* {@link import('./factories.js').restoreWorkflow} — flowing this manager's `functions`
|
|
3474
|
-
* registry in so the rehydrated tree is RUNNABLE — registers it, and returns it.
|
|
3475
|
-
*
|
|
3544
|
+
* registry in so the rehydrated tree is RUNNABLE — registers it, and returns it. Registry
|
|
3545
|
+
* mutation wins over an earlier pending hydration: `add` supplies the live result, while
|
|
3546
|
+
* `remove` (even for an absent id) and `clear` invalidate the earlier read. Missed and failed
|
|
3547
|
+
* reads leave no stale in-flight entry, and a payload whose own id differs from the requested
|
|
3548
|
+
* key rejects with `RESTORE` instead of registering under either id. `save(id)` captures a
|
|
3549
|
+
* registered workflow's {@link WorkflowInterface.snapshot} at invocation, then PERSISTS it.
|
|
3550
|
+
* Same-id writes run serially in invocation order; different ids remain independent, and an
|
|
3551
|
+
* earlier rejection reaches its caller without preventing a later queued write. Both are
|
|
3476
3552
|
* LENIENT without a store — `open` resolves only registered ids, `save` is a no-op
|
|
3477
3553
|
* (`false`) — never a throw. The EXACT analogue of
|
|
3478
3554
|
* `ConversationManagerInterface.open` / `.save` and `WorkspaceManagerInterface.open` /
|
|
@@ -3486,7 +3562,7 @@ export declare class WorkflowManager implements WorkflowManagerInterface {
|
|
|
3486
3562
|
*
|
|
3487
3563
|
* @example
|
|
3488
3564
|
* ```ts
|
|
3489
|
-
* import { createWorkflowManager } from '@
|
|
3565
|
+
* import { createWorkflowManager } from '@orkestrel/workflow'
|
|
3490
3566
|
*
|
|
3491
3567
|
* const manager = createWorkflowManager({
|
|
3492
3568
|
* functions: { compile: async (controller) => `built ${controller.task.id}` },
|
|
@@ -3520,11 +3596,17 @@ export declare interface WorkflowManagerInterface {
|
|
|
3520
3596
|
*
|
|
3521
3597
|
* @remarks
|
|
3522
3598
|
* - If `id` is ALREADY registered, it is returned directly — no store hit.
|
|
3523
|
-
* -
|
|
3599
|
+
* - Same-id registry misses share one in-flight `store.get(id)` and resolve to the same live
|
|
3600
|
+
* object. On a HIT the snapshot is
|
|
3524
3601
|
* rehydrated into a fresh {@link WorkflowInterface} via
|
|
3525
3602
|
* {@link import('./factories.js').restoreWorkflow}, flowing this manager's `functions`
|
|
3526
3603
|
* registry in (so the rehydrated tree carries real resolved `handler`s and can RESUME
|
|
3527
|
-
* real work), registers it, and returns it.
|
|
3604
|
+
* real work), registers it, and returns it. A payload whose own id differs from `id` rejects
|
|
3605
|
+
* with a normalized `RESTORE` error carrying the requested and payload ids.
|
|
3606
|
+
* - Registry mutation after the store read starts has precedence: `add(definition)` for the
|
|
3607
|
+
* same id wins and becomes every pending caller's result; `remove(id)` invalidates that read
|
|
3608
|
+
* even when the id was absent; `clear()` invalidates every earlier read. A miss or rejection
|
|
3609
|
+
* clears the in-flight entry so a later call retries.
|
|
3528
3610
|
* - Else (no store, or a store MISS) ⇒ `undefined` (lenient — no throw).
|
|
3529
3611
|
*
|
|
3530
3612
|
* @param id - The workflow id to open
|
|
@@ -3536,9 +3618,10 @@ export declare interface WorkflowManagerInterface {
|
|
|
3536
3618
|
* {@link WorkflowStoreInterface} (`store`).
|
|
3537
3619
|
*
|
|
3538
3620
|
* @remarks
|
|
3539
|
-
*
|
|
3540
|
-
*
|
|
3541
|
-
*
|
|
3621
|
+
* When a `store` is set AND `id` is registered, the snapshot is captured synchronously at
|
|
3622
|
+
* invocation. Same-id `store.set` calls are serialized in invocation order; different ids are
|
|
3623
|
+
* independent. A rejected write reaches that caller unchanged but does not poison a later
|
|
3624
|
+
* queued write. Otherwise (no store, OR an unknown id) it is a NO-OP returning `false`.
|
|
3542
3625
|
*
|
|
3543
3626
|
* @param id - The id of the registered workflow to persist
|
|
3544
3627
|
* @returns `true` when the snapshot was persisted; `false` when no store / unknown id
|
|
@@ -3716,8 +3799,9 @@ export declare interface WorkflowResult {
|
|
|
3716
3799
|
* - **Composes, never re-implements.** Per-phase bounded concurrency is one
|
|
3717
3800
|
* {@link createRunner} per phase (the substrate {@link RunnerInterface} over the workers
|
|
3718
3801
|
* `Queue`); `bail` maps onto that Runner's fail-fast vs settle-all; the run-level abort /
|
|
3719
|
-
* timeout / budget / entity `signal` fold through
|
|
3720
|
-
* `AbortSignal.any` (exactly as the agent runtime folds its bounds);
|
|
3802
|
+
* timeout / budget / entity `signal` fold through the `@orkestrel/abort` signal contract,
|
|
3803
|
+
* {@link createTimeout}, and `AbortSignal.any` (exactly as the agent runtime folds its bounds);
|
|
3804
|
+
* pacing is the shipped
|
|
3721
3805
|
* {@link SchedulerInterface}. The runner writes ZERO concurrency / retry / abort logic of
|
|
3722
3806
|
* its own — it only sequences phases, dispatches a task's own handler, and drives the live
|
|
3723
3807
|
* entity. The workflow layer owns per-task deadlines because timeout settlement must
|
|
@@ -4115,8 +4199,8 @@ export declare type WorkflowStatus = LifecycleStatus;
|
|
|
4115
4199
|
/**
|
|
4116
4200
|
* The durable persistence seam for a {@link WorkflowSnapshot} — three async primitives
|
|
4117
4201
|
* (`get` / `set` / `delete`) keyed by a workflow id, the snapshot analogue of
|
|
4118
|
-
* the server package's `SessionStoreInterface` (and the
|
|
4119
|
-
*
|
|
4202
|
+
* the server package's `SessionStoreInterface` (and the `@orkestrel/queue`
|
|
4203
|
+
* `QueueStoreInterface` driver-swap pattern).
|
|
4120
4204
|
*
|
|
4121
4205
|
* @remarks
|
|
4122
4206
|
* The store persists the W-a {@link WorkflowSnapshot} — the COMPLETE, self-contained,
|
|
@@ -4129,7 +4213,7 @@ export declare type WorkflowStatus = LifecycleStatus;
|
|
|
4129
4213
|
*
|
|
4130
4214
|
* Every primitive is async (a `Promise`), so a durable backend (a database round-trip) fits the
|
|
4131
4215
|
* same shape as the memory one. The snapshot carries its OWN id, so `set` takes no separate id
|
|
4132
|
-
* param (mirroring
|
|
4216
|
+
* param (mirroring `QueueStoreInterface.save` from `@orkestrel/queue` / the server package's
|
|
4133
4217
|
* `SessionStoreInterface.set`, which key off the value's own
|
|
4134
4218
|
* `id`). UNLIKE a session store there is NO idle-TTL / eviction — a persisted workflow run-state
|
|
4135
4219
|
* lives until an explicit `delete`, never silently expiring (it is durable orchestration state,
|
|
@@ -4139,6 +4223,8 @@ export declare type WorkflowStatus = LifecycleStatus;
|
|
|
4139
4223
|
export declare interface WorkflowStoreInterface {
|
|
4140
4224
|
/**
|
|
4141
4225
|
* Resolve the persisted snapshot for `id`, or `undefined` if none is stored.
|
|
4226
|
+
* A present payload whose own `id` differs from the requested storage key is corrupt and
|
|
4227
|
+
* rejects with a normalized `RESTORE` error carrying both ids.
|
|
4142
4228
|
*
|
|
4143
4229
|
* @param id - The workflow id to resolve (a {@link WorkflowSnapshot.id})
|
|
4144
4230
|
* @returns The persisted snapshot, or `undefined` if absent
|
|
@@ -4146,7 +4232,7 @@ export declare interface WorkflowStoreInterface {
|
|
|
4146
4232
|
get(id: string): Promise<WorkflowSnapshot | undefined>;
|
|
4147
4233
|
/**
|
|
4148
4234
|
* Insert or replace a snapshot under its own `snapshot.id` (no separate id param —
|
|
4149
|
-
* mirroring
|
|
4235
|
+
* mirroring `QueueStoreInterface.save` from `@orkestrel/queue`).
|
|
4150
4236
|
*
|
|
4151
4237
|
* @param snapshot - The snapshot to store (keyed by its `id`)
|
|
4152
4238
|
*/
|