@yieldstar/core 0.5.0 → 0.6.0
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/dist/base/durable-value.d.ts +71 -0
- package/dist/base/durable-value.d.ts.map +1 -0
- package/dist/base/durable-value.test.d.ts +2 -0
- package/dist/base/durable-value.test.d.ts.map +1 -0
- package/dist/base/effect.d.ts +136 -0
- package/dist/base/effect.d.ts.map +1 -0
- package/dist/base/errors.d.ts +23 -0
- package/dist/base/errors.d.ts.map +1 -0
- package/dist/base/errors.test.d.ts +2 -0
- package/dist/base/errors.test.d.ts.map +1 -0
- package/dist/base/event.d.ts +6 -1
- package/dist/base/event.d.ts.map +1 -1
- package/dist/base/execution.d.ts +244 -0
- package/dist/base/execution.d.ts.map +1 -0
- package/dist/base/heap.d.ts +15 -3
- package/dist/base/heap.d.ts.map +1 -1
- package/dist/base/invoker.d.ts +47 -2
- package/dist/base/invoker.d.ts.map +1 -1
- package/dist/base/runtime.d.ts +27 -4
- package/dist/base/runtime.d.ts.map +1 -1
- package/dist/base/step.d.ts +21 -5
- package/dist/base/step.d.ts.map +1 -1
- package/dist/base/store.d.ts +135 -21
- package/dist/base/store.d.ts.map +1 -1
- package/dist/base/workflow.d.ts +15 -0
- package/dist/base/workflow.d.ts.map +1 -1
- package/dist/index.d.ts +23 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1647 -172
- package/dist/lib/effect-state.d.ts +78 -0
- package/dist/lib/effect-state.d.ts.map +1 -0
- package/dist/lib/execution-dispatcher.d.ts +102 -0
- package/dist/lib/execution-dispatcher.d.ts.map +1 -0
- package/dist/lib/execution-state.d.ts +248 -0
- package/dist/lib/execution-state.d.ts.map +1 -0
- package/dist/lib/execution-state.test.d.ts +2 -0
- package/dist/lib/execution-state.test.d.ts.map +1 -0
- package/dist/lib/wait-for-outcome.d.ts +15 -0
- package/dist/lib/wait-for-outcome.d.ts.map +1 -0
- package/dist/lib/workflow-runner.d.ts +14 -9
- package/dist/lib/workflow-runner.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/base/durable-value.test.ts +285 -0
- package/src/base/durable-value.ts +442 -0
- package/src/base/effect.ts +165 -0
- package/src/base/errors.test.ts +210 -0
- package/src/base/errors.ts +72 -0
- package/src/base/event.ts +6 -1
- package/src/base/execution.ts +303 -0
- package/src/base/heap.ts +17 -3
- package/src/base/invoker.ts +60 -2
- package/src/base/runtime.ts +28 -7
- package/src/base/step.ts +29 -7
- package/src/base/store.ts +339 -49
- package/src/base/workflow.ts +15 -0
- package/src/index.ts +137 -3
- package/src/lib/effect-state.ts +254 -0
- package/src/lib/execution-dispatcher.ts +393 -0
- package/src/lib/execution-state.test.ts +249 -0
- package/src/lib/execution-state.ts +650 -0
- package/src/lib/wait-for-outcome.ts +40 -0
- package/src/lib/workflow-runner.ts +75 -43
- package/src/base/scheduler.ts +0 -8
- package/tsconfig.tsbuildinfo +0 -1
package/src/base/invoker.ts
CHANGED
|
@@ -1,7 +1,65 @@
|
|
|
1
1
|
import type { EventEmitter } from "node:events";
|
|
2
|
-
import type {
|
|
2
|
+
import type { WorkflowEvent } from "./event";
|
|
3
|
+
import type { ExecutionLease, WorkflowRunOutcome } from "./execution";
|
|
4
|
+
|
|
5
|
+
export type DeliveryOptions = {
|
|
6
|
+
/** Every fenced write the delivery makes carries this lease. */
|
|
7
|
+
lease: ExecutionLease;
|
|
8
|
+
/**
|
|
9
|
+
* Aborted when the delivery must stop: the dispatcher aborts it, with a
|
|
10
|
+
* `LeaseLostError` as its reason, when a renewal returns `lost`. The driver
|
|
11
|
+
* checks it before each step function and each fenced write, and ends an
|
|
12
|
+
* aborted delivery without running more workflow code.
|
|
13
|
+
*/
|
|
14
|
+
signal: AbortSignal;
|
|
15
|
+
};
|
|
3
16
|
|
|
4
17
|
export type WorkflowInvoker = {
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated The execution record is the source of truth for outcomes.
|
|
20
|
+
* The dispatcher still emits terminal outcomes here as an in-process fast
|
|
21
|
+
* path; no guarantee depends on it.
|
|
22
|
+
*/
|
|
5
23
|
workflowEndEmitter: EventEmitter;
|
|
6
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Runs one delivery of an execution and resolves with its outcome. Rejects,
|
|
26
|
+
* without an outcome, when the delivery hits an infrastructure error or the
|
|
27
|
+
* worker exits before replying. Once `options.signal` aborts, the delivery runs
|
|
28
|
+
* no more workflow code and makes no more fenced writes; it rejects with an
|
|
29
|
+
* `InfrastructureError` whose cause is the signal's reason. An invoker that
|
|
30
|
+
* can stop a step function already running, as the worker invoker does by
|
|
31
|
+
* killing its worker, should do so and reject at once. The dispatcher
|
|
32
|
+
* abandons a delivery that has not settled within its `abortGracePeriod`
|
|
33
|
+
* of the abort, and frees its slot.
|
|
34
|
+
*
|
|
35
|
+
* A worker that exits before replying rejects with a `WorkerExitedError`:
|
|
36
|
+
* the dispatcher then leaves the lease to expire, because the worker's last
|
|
37
|
+
* writes may still be landing. Every other rejection is a retry reply, and
|
|
38
|
+
* the dispatcher releases the lease.
|
|
39
|
+
*/
|
|
40
|
+
deliver(event: WorkflowEvent, options: DeliveryOptions): Promise<WorkflowRunOutcome>;
|
|
7
41
|
};
|
|
42
|
+
|
|
43
|
+
const WORKER_EXITED = Symbol.for("yieldstar.workerExited");
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Rejects a delivery whose worker exited, or was killed, before replying.
|
|
47
|
+
* The dispatcher does not release the lease: it expires, and the execution is
|
|
48
|
+
* delivered again after the redelivery delay.
|
|
49
|
+
*/
|
|
50
|
+
export class WorkerExitedError extends Error {
|
|
51
|
+
readonly [WORKER_EXITED] = true;
|
|
52
|
+
|
|
53
|
+
constructor(message: string) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = "WorkerExitedError";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static is(value: unknown): value is WorkerExitedError {
|
|
59
|
+
return (
|
|
60
|
+
typeof value === "object" &&
|
|
61
|
+
value !== null &&
|
|
62
|
+
(value as Record<symbol, unknown>)[WORKER_EXITED] === true
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/base/runtime.ts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { EffectClient } from "./effect";
|
|
2
|
+
import type { ExecutionClient } from "./execution";
|
|
3
|
+
import type { HeapClient } from "./heap";
|
|
4
|
+
import type { StoreClient } from "./store";
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export interface RuntimeOptions {
|
|
7
|
+
/** Every client of the runtime reads time from this clock. Defaults to `Date.now`. */
|
|
8
|
+
clock?: () => number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A runtime is defined by the guarantees its clients keep, not by how many
|
|
13
|
+
* databases it uses:
|
|
14
|
+
*
|
|
15
|
+
* - Where one write must accompany another, such as the wakes for a store
|
|
16
|
+
* commit, the second is durable once the first commits and is applied
|
|
17
|
+
* eventually (in one transaction or through an outbox).
|
|
18
|
+
* - A store or effect waiter is deleted atomically with its step's result.
|
|
19
|
+
* - An effect's settlement and the wakes of its waiters are one atomic write.
|
|
20
|
+
* - Every client reads time from the runtime's clock.
|
|
21
|
+
*/
|
|
22
|
+
export abstract class Runtime {
|
|
23
|
+
/** The clock every client, and every step's wake time, reads. */
|
|
24
|
+
abstract readonly clock: () => number;
|
|
25
|
+
abstract readonly executions: ExecutionClient;
|
|
26
|
+
abstract readonly effects: EffectClient;
|
|
27
|
+
abstract readonly heap: HeapClient;
|
|
28
|
+
abstract readonly stores: StoreClient;
|
|
29
|
+
}
|
package/src/base/step.ts
CHANGED
|
@@ -22,13 +22,18 @@ export class StepInvalid extends StepResponse {
|
|
|
22
22
|
readonly type = "step-invalid";
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export type StepSchemaVerdict = "accepted" | "rejected";
|
|
26
|
+
|
|
25
27
|
export class StepResult extends StepResponse {
|
|
26
28
|
static type = "step-result";
|
|
27
29
|
readonly type = "step-result";
|
|
28
30
|
result: any;
|
|
29
|
-
|
|
31
|
+
/** Whether the step's schema accepted its value on the first run. */
|
|
32
|
+
schema?: StepSchemaVerdict;
|
|
33
|
+
constructor(result: any, schema?: StepSchemaVerdict) {
|
|
30
34
|
super();
|
|
31
35
|
this.result = result;
|
|
36
|
+
if (schema !== undefined) this.schema = schema;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -45,10 +50,11 @@ export class WorkflowResult<T extends any> extends StepResponse {
|
|
|
45
50
|
export class WorkflowDelay extends StepResponse {
|
|
46
51
|
static type = "workflow-delay";
|
|
47
52
|
readonly type = "workflow-delay";
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
/** The absolute time the step's pause ends, read from the runtime clock. */
|
|
54
|
+
wakeAt: number;
|
|
55
|
+
constructor(wakeAt: number) {
|
|
50
56
|
super();
|
|
51
|
-
this.
|
|
57
|
+
this.wakeAt = wakeAt;
|
|
52
58
|
}
|
|
53
59
|
}
|
|
54
60
|
|
|
@@ -60,6 +66,21 @@ export class StepStoreWait extends StepResponse {
|
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
|
|
69
|
+
/**
|
|
70
|
+
* An effect step whose outcome is uncertain. The driver records it as an
|
|
71
|
+
* unfinished step after watching the effect, so the next delivery begins the
|
|
72
|
+
* effect again; `wakeAt` is when that delivery is due.
|
|
73
|
+
*/
|
|
74
|
+
export class StepEffectWait extends StepResponse {
|
|
75
|
+
static type = "effect-wait";
|
|
76
|
+
readonly type = "effect-wait";
|
|
77
|
+
wakeAt: number;
|
|
78
|
+
constructor(wakeAt: number) {
|
|
79
|
+
super();
|
|
80
|
+
this.wakeAt = wakeAt;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
63
84
|
export class WorkflowRestart extends StepResponse {
|
|
64
85
|
static type = "workflow-restart";
|
|
65
86
|
readonly type = "workflow-restart";
|
|
@@ -96,9 +117,10 @@ export class StepError extends StepResponse {
|
|
|
96
117
|
export class StepDelay extends StepResponse {
|
|
97
118
|
static type = "step-delay";
|
|
98
119
|
readonly type = "step-delay";
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
/** The absolute time the step's pause ends, read from the runtime clock. */
|
|
121
|
+
wakeAt: number;
|
|
122
|
+
constructor(wakeAt: number) {
|
|
101
123
|
super();
|
|
102
|
-
this.
|
|
124
|
+
this.wakeAt = wakeAt;
|
|
103
125
|
}
|
|
104
126
|
}
|