@smithers-orchestrator/scheduler 0.16.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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +190 -0
  3. package/src/ApprovalResolution.ts +7 -0
  4. package/src/CachePolicy.ts +8 -0
  5. package/src/ContinuationRequest.ts +3 -0
  6. package/src/ContinueAsNewTransition.ts +9 -0
  7. package/src/EngineDecision.ts +19 -0
  8. package/src/PlanNode.ts +32 -0
  9. package/src/RalphMeta.ts +7 -0
  10. package/src/RalphState.ts +4 -0
  11. package/src/RalphStateMap.ts +3 -0
  12. package/src/ReadonlyTaskStateMap.ts +3 -0
  13. package/src/RenderContext.ts +14 -0
  14. package/src/RetryPolicy.ts +6 -0
  15. package/src/RetryWaitMap.ts +1 -0
  16. package/src/RunResult.ts +15 -0
  17. package/src/ScheduleResult.ts +15 -0
  18. package/src/ScheduleSnapshot.ts +8 -0
  19. package/src/Scheduler.js +28 -0
  20. package/src/SchedulerLive.js +8 -0
  21. package/src/SmithersWorkflowOptions.ts +43 -0
  22. package/src/TaskFailure.ts +5 -0
  23. package/src/TaskOutput.ts +9 -0
  24. package/src/TaskRecord.ts +10 -0
  25. package/src/TaskState.ts +10 -0
  26. package/src/TaskStateMap.ts +3 -0
  27. package/src/TokenUsage.ts +9 -0
  28. package/src/WaitReason.ts +8 -0
  29. package/src/WorkflowSession.js +10 -0
  30. package/src/WorkflowSessionLive.js +6 -0
  31. package/src/WorkflowSessionOptions.ts +10 -0
  32. package/src/WorkflowSessionService.ts +52 -0
  33. package/src/buildPlanTree.js +273 -0
  34. package/src/buildStateKey.js +8 -0
  35. package/src/cloneTaskStateMap.js +10 -0
  36. package/src/computeRetryDelayMs.js +14 -0
  37. package/src/index.d.ts +437 -0
  38. package/src/index.js +53 -0
  39. package/src/isTerminalState.js +15 -0
  40. package/src/makeWorkflowSession.js +723 -0
  41. package/src/nowMs.js +6 -0
  42. package/src/parseStateKey.js +15 -0
  43. package/src/retryPolicyToSchedule.js +26 -0
  44. package/src/retryScheduleDelayMs.js +23 -0
  45. package/src/scheduleTasks.js +330 -0
package/src/index.d.ts ADDED
@@ -0,0 +1,437 @@
1
+ import * as effect from 'effect';
2
+ import { Context, Layer, Effect, Schedule } from 'effect';
3
+ import * as _smithers_graph from '@smithers-orchestrator/graph';
4
+ import { TaskDescriptor as TaskDescriptor$3, WorkflowGraph } from '@smithers-orchestrator/graph';
5
+
6
+ type TaskState$2 = "pending" | "waiting-approval" | "waiting-event" | "waiting-timer" | "in-progress" | "finished" | "failed" | "cancelled" | "skipped";
7
+
8
+ type TaskStateMap$4 = Map<string, TaskState$2>;
9
+
10
+ type ApprovalResolution$1 = {
11
+ readonly approved: boolean;
12
+ readonly note?: string;
13
+ readonly decidedBy?: string;
14
+ readonly optionKey?: string;
15
+ readonly payload?: unknown;
16
+ };
17
+
18
+ type PlanNode$4 = {
19
+ readonly kind: "task";
20
+ readonly nodeId: string;
21
+ } | {
22
+ readonly kind: "sequence";
23
+ readonly children: readonly PlanNode$4[];
24
+ } | {
25
+ readonly kind: "parallel";
26
+ readonly children: readonly PlanNode$4[];
27
+ } | {
28
+ readonly kind: "ralph";
29
+ readonly id: string;
30
+ readonly children: readonly PlanNode$4[];
31
+ readonly until: boolean;
32
+ readonly maxIterations: number;
33
+ readonly onMaxReached: "fail" | "return-last";
34
+ readonly continueAsNewEvery?: number;
35
+ } | {
36
+ readonly kind: "continue-as-new";
37
+ readonly stateJson?: string;
38
+ } | {
39
+ readonly kind: "group";
40
+ readonly children: readonly PlanNode$4[];
41
+ } | {
42
+ readonly kind: "saga";
43
+ readonly id: string;
44
+ readonly actionChildren: readonly PlanNode$4[];
45
+ readonly compensationChildren: readonly PlanNode$4[];
46
+ readonly onFailure: "compensate" | "compensate-and-fail" | "fail";
47
+ } | {
48
+ readonly kind: "try-catch-finally";
49
+ readonly id: string;
50
+ readonly tryChildren: readonly PlanNode$4[];
51
+ readonly catchChildren: readonly PlanNode$4[];
52
+ readonly finallyChildren: readonly PlanNode$4[];
53
+ };
54
+
55
+ type ContinuationRequest$1 = {
56
+ readonly stateJson?: string;
57
+ };
58
+
59
+ type RalphMeta$2 = {
60
+ readonly id: string;
61
+ readonly until: boolean;
62
+ readonly maxIterations: number;
63
+ readonly onMaxReached: "fail" | "return-last";
64
+ readonly continueAsNewEvery?: number;
65
+ };
66
+
67
+ type ScheduleResult$3 = {
68
+ readonly runnable: readonly TaskDescriptor$3[];
69
+ readonly pendingExists: boolean;
70
+ readonly waitingApprovalExists: boolean;
71
+ readonly waitingEventExists: boolean;
72
+ readonly waitingTimerExists: boolean;
73
+ readonly readyRalphs: readonly RalphMeta$2[];
74
+ readonly continuation?: ContinuationRequest$1;
75
+ readonly nextRetryAtMs?: number;
76
+ readonly fatalError?: string;
77
+ };
78
+
79
+ type ScheduleSnapshot$1 = {
80
+ readonly plan: PlanNode$4 | null;
81
+ readonly result: ScheduleResult$3;
82
+ readonly computedAtMs: number;
83
+ };
84
+
85
+ type ContinueAsNewTransition$1 = {
86
+ readonly reason: "explicit" | "loop-threshold" | "driver";
87
+ readonly iteration?: number;
88
+ readonly statePayload?: unknown;
89
+ readonly stateJson?: string;
90
+ readonly newRunId?: string;
91
+ readonly carriedStateBytes?: number;
92
+ readonly ancestryDepth?: number;
93
+ };
94
+
95
+ type TokenUsage$1 = {
96
+ readonly inputTokens?: number;
97
+ readonly outputTokens?: number;
98
+ readonly cacheReadTokens?: number;
99
+ readonly cacheWriteTokens?: number;
100
+ readonly reasoningTokens?: number;
101
+ readonly totalTokens?: number;
102
+ readonly [key: string]: unknown;
103
+ };
104
+
105
+ type TaskOutput$1 = {
106
+ readonly nodeId: string;
107
+ readonly iteration: number;
108
+ readonly output: unknown;
109
+ readonly text?: string | null;
110
+ readonly usage?: TokenUsage$1 | null;
111
+ };
112
+
113
+ type RenderContext$1 = {
114
+ readonly runId: string;
115
+ readonly graph?: WorkflowGraph | null;
116
+ readonly iteration?: number;
117
+ readonly iterations?: Record<string, number> | ReadonlyMap<string, number>;
118
+ readonly input?: unknown;
119
+ readonly outputs?: Record<string, unknown[]> | ReadonlyMap<string, TaskOutput$1>;
120
+ readonly auth?: unknown;
121
+ readonly taskStates?: unknown;
122
+ readonly ralphIterations?: ReadonlyMap<string, number>;
123
+ };
124
+
125
+ type RunResult$1 = {
126
+ readonly runId: string;
127
+ readonly status: "running" | "finished" | "failed" | "cancelled" | "continued" | "waiting-approval" | "waiting-event" | "waiting-timer";
128
+ readonly output?: unknown;
129
+ readonly error?: unknown;
130
+ readonly nextRunId?: string;
131
+ };
132
+
133
+ type WaitReason$1 = {
134
+ readonly _tag: "Approval";
135
+ readonly nodeId: string;
136
+ } | {
137
+ readonly _tag: "Event";
138
+ readonly eventName: string;
139
+ } | {
140
+ readonly _tag: "Timer";
141
+ readonly resumeAtMs: number;
142
+ } | {
143
+ readonly _tag: "RetryBackoff";
144
+ readonly waitMs: number;
145
+ } | {
146
+ readonly _tag: "HotReload";
147
+ } | {
148
+ readonly _tag: "OrphanRecovery";
149
+ readonly count: number;
150
+ } | {
151
+ readonly _tag: "ExternalTrigger";
152
+ };
153
+
154
+ type EngineDecision$1 = {
155
+ readonly _tag: "Execute";
156
+ readonly tasks: readonly TaskDescriptor$3[];
157
+ } | {
158
+ readonly _tag: "ReRender";
159
+ readonly context: RenderContext$1;
160
+ } | {
161
+ readonly _tag: "Wait";
162
+ readonly reason: WaitReason$1;
163
+ } | {
164
+ readonly _tag: "ContinueAsNew";
165
+ readonly transition: ContinueAsNewTransition$1;
166
+ } | {
167
+ readonly _tag: "Finished";
168
+ readonly result: RunResult$1;
169
+ } | {
170
+ readonly _tag: "Failed";
171
+ readonly error: unknown;
172
+ };
173
+
174
+ type TaskFailure$1 = {
175
+ readonly nodeId: string;
176
+ readonly iteration: number;
177
+ readonly error: unknown;
178
+ };
179
+
180
+ type WorkflowSessionService$2 = {
181
+ readonly submitGraph: (graph: WorkflowGraph) => Effect.Effect<EngineDecision$1>;
182
+ readonly taskCompleted: (output: TaskOutput$1) => Effect.Effect<EngineDecision$1>;
183
+ readonly taskFailed: (failure: TaskFailure$1) => Effect.Effect<EngineDecision$1>;
184
+ readonly approvalResolved: (nodeId: string, resolution: ApprovalResolution$1) => Effect.Effect<EngineDecision$1>;
185
+ readonly approvalTimedOut: (nodeId: string) => Effect.Effect<EngineDecision$1>;
186
+ readonly eventReceived: (eventName: string, payload: unknown, correlationId?: string | null) => Effect.Effect<EngineDecision$1>;
187
+ readonly signalReceived: (signalName: string, payload: unknown, correlationId?: string | null) => Effect.Effect<EngineDecision$1>;
188
+ readonly timerFired: (nodeId: string, firedAtMs?: number) => Effect.Effect<EngineDecision$1>;
189
+ readonly hotReloaded: (graph: WorkflowGraph) => Effect.Effect<EngineDecision$1>;
190
+ readonly heartbeatTimedOut: (nodeId: string, iteration?: number, details?: Record<string, unknown>) => Effect.Effect<EngineDecision$1>;
191
+ readonly cacheResolved: (output: TaskOutput$1, cached: boolean) => Effect.Effect<EngineDecision$1>;
192
+ readonly cacheMissed: (nodeId: string, iteration?: number) => Effect.Effect<EngineDecision$1>;
193
+ readonly recoverOrphanedTasks: () => Effect.Effect<EngineDecision$1>;
194
+ readonly cancelRequested: () => Effect.Effect<EngineDecision$1>;
195
+ readonly getTaskStates: () => Effect.Effect<TaskStateMap$4>;
196
+ readonly getSchedule: () => Effect.Effect<ScheduleSnapshot$1 | null>;
197
+ readonly getCurrentGraph: () => Effect.Effect<WorkflowGraph | null>;
198
+ };
199
+
200
+ type WorkflowSessionOptions$2 = {
201
+ readonly runId?: string;
202
+ readonly nowMs?: () => number;
203
+ readonly requireStableFinish?: boolean;
204
+ readonly requireRerenderOnOutputChange?: boolean;
205
+ readonly initialRalphState?: ReadonlyMap<string, {
206
+ readonly iteration: number;
207
+ readonly done: boolean;
208
+ }>;
209
+ };
210
+
211
+ type TaskRecord$1 = {
212
+ readonly descriptor: TaskDescriptor$3;
213
+ readonly state: TaskState$2;
214
+ readonly output?: unknown;
215
+ readonly error?: unknown;
216
+ readonly updatedAtMs: number;
217
+ };
218
+
219
+ type SmithersAlertSeverity = "info" | "warning" | "critical";
220
+ type SmithersAlertLabels = Record<string, string>;
221
+ type SmithersAlertReactionKind = "emit-only" | "pause" | "cancel" | "open-approval" | "deliver";
222
+ type SmithersAlertReaction = {
223
+ kind: "emit-only";
224
+ } | {
225
+ kind: "pause";
226
+ } | {
227
+ kind: "cancel";
228
+ } | {
229
+ kind: "open-approval";
230
+ } | {
231
+ kind: "deliver";
232
+ destination: string;
233
+ };
234
+ type SmithersAlertReactionRef = string | SmithersAlertReaction;
235
+ type SmithersAlertPolicyDefaults = {
236
+ owner?: string;
237
+ severity?: SmithersAlertSeverity;
238
+ runbook?: string;
239
+ labels?: SmithersAlertLabels;
240
+ };
241
+ type SmithersAlertPolicyRule = SmithersAlertPolicyDefaults & {
242
+ afterMs?: number;
243
+ reaction?: SmithersAlertReactionRef;
244
+ };
245
+ type SmithersAlertPolicy = {
246
+ defaults?: SmithersAlertPolicyDefaults;
247
+ rules?: Record<string, SmithersAlertPolicyRule>;
248
+ reactions?: Record<string, SmithersAlertReaction>;
249
+ };
250
+ type SmithersWorkflowOptions$1 = {
251
+ alertPolicy?: SmithersAlertPolicy;
252
+ cache?: boolean;
253
+ workflowHash?: string;
254
+ };
255
+
256
+ type RetryWaitMap$3 = Map<string, number>;
257
+
258
+ type RetryBackoff$1 = "fixed" | "linear" | "exponential";
259
+ type RetryPolicy$3 = {
260
+ backoff?: RetryBackoff$1;
261
+ initialDelayMs?: number;
262
+ };
263
+
264
+ type ReadonlyTaskStateMap$2 = ReadonlyMap<string, TaskState$2>;
265
+
266
+ type RalphState$1 = {
267
+ readonly iteration: number;
268
+ readonly done: boolean;
269
+ };
270
+
271
+ type RalphStateMap$4 = Map<string, RalphState$1>;
272
+
273
+ type CachePolicy$1<Ctx = any> = {
274
+ by?: (ctx: Ctx) => unknown;
275
+ version?: string;
276
+ key?: string;
277
+ ttlMs?: number;
278
+ scope?: "run" | "workflow" | "global";
279
+ [key: string]: unknown;
280
+ };
281
+
282
+ /**
283
+ * @param {string} nodeId
284
+ * @param {number} iteration
285
+ * @returns {string}
286
+ */
287
+ declare function buildStateKey(nodeId: string, iteration: number): string;
288
+
289
+ /**
290
+ * @param {string} key
291
+ * @returns {{ readonly nodeId: string; readonly iteration: number; }}
292
+ */
293
+ declare function parseStateKey(key: string): {
294
+ readonly nodeId: string;
295
+ readonly iteration: number;
296
+ };
297
+
298
+ /** @typedef {import("./ReadonlyTaskStateMap.ts").ReadonlyTaskStateMap} ReadonlyTaskStateMap */
299
+ /** @typedef {import("./TaskStateMap.ts").TaskStateMap} TaskStateMap */
300
+ /**
301
+ * @param {ReadonlyTaskStateMap} states
302
+ * @returns {TaskStateMap}
303
+ */
304
+ declare function cloneTaskStateMap(states: ReadonlyTaskStateMap$1): TaskStateMap$3;
305
+ type ReadonlyTaskStateMap$1 = ReadonlyTaskStateMap$2;
306
+ type TaskStateMap$3 = TaskStateMap$4;
307
+
308
+ /** @typedef {import("@smithers-orchestrator/graph").TaskDescriptor} TaskDescriptor */
309
+ /** @typedef {import("./TaskState.ts").TaskState} TaskState */
310
+ /**
311
+ * @param {TaskState} state
312
+ * @param {Pick<TaskDescriptor, "continueOnFail">} [descriptor]
313
+ * @returns {boolean}
314
+ */
315
+ declare function isTerminalState(state: TaskState$1, descriptor?: Pick<TaskDescriptor$2, "continueOnFail">): boolean;
316
+ type TaskDescriptor$2 = _smithers_graph.TaskDescriptor;
317
+ type TaskState$1 = TaskState$2;
318
+
319
+ declare class Scheduler extends Context.TagClassShape<"Scheduler", SchedulerService> {
320
+ }
321
+ type TaskDescriptor$1 = _smithers_graph.TaskDescriptor;
322
+ type TaskStateMap$2 = TaskStateMap$4;
323
+ type PlanNode$3 = PlanNode$4;
324
+ type RalphStateMap$3 = RalphStateMap$4;
325
+ type RetryWaitMap$2 = RetryWaitMap$3;
326
+ type ScheduleResult$2 = ScheduleResult$3;
327
+ type SchedulerService = {
328
+ readonly schedule: (plan: PlanNode$3 | null, states: TaskStateMap$2, descriptors: Map<string, TaskDescriptor$1>, ralphState: RalphStateMap$3, retryWait: RetryWaitMap$2, nowMs: number) => effect.Effect.Effect<ScheduleResult$2>;
329
+ };
330
+
331
+ /** @type {Layer.Layer<Scheduler, never, never>} */
332
+ declare const SchedulerLive: Layer.Layer<Scheduler, never, never>;
333
+
334
+ /**
335
+ * @param {XmlNode | null} xml
336
+ * @param {RalphStateMap} [ralphState]
337
+ * @returns {{ readonly plan: PlanNode | null; readonly ralphs: readonly RalphMeta[]; }}
338
+ */
339
+ declare function buildPlanTree(xml: XmlNode | null, ralphState?: RalphStateMap$2): {
340
+ readonly plan: PlanNode$2 | null;
341
+ readonly ralphs: readonly RalphMeta$1[];
342
+ };
343
+ type PlanNode$2 = PlanNode$4;
344
+ type RalphMeta$1 = RalphMeta$2;
345
+ type RalphStateMap$2 = RalphStateMap$4;
346
+ type XmlNode = _smithers_graph.XmlNode;
347
+
348
+ /**
349
+ * @param {PlanNode | null} plan
350
+ * @param {TaskStateMap} states
351
+ * @param {Map<string, TaskDescriptor>} descriptors
352
+ * @param {RalphStateMap} ralphState
353
+ * @param {RetryWaitMap} retryWait
354
+ * @param {number} nowMs
355
+ * @returns {ScheduleResult}
356
+ */
357
+ declare function scheduleTasks(plan: PlanNode$1 | null, states: TaskStateMap$1, descriptors: Map<string, TaskDescriptor>, ralphState: RalphStateMap$1, retryWait: RetryWaitMap$1, nowMs: number): ScheduleResult$1;
358
+ type PlanNode$1 = PlanNode$4;
359
+ type RalphStateMap$1 = RalphStateMap$4;
360
+ type RetryWaitMap$1 = RetryWaitMap$3;
361
+ type ScheduleResult$1 = ScheduleResult$3;
362
+ type TaskDescriptor = _smithers_graph.TaskDescriptor;
363
+ type TaskStateMap$1 = TaskStateMap$4;
364
+
365
+ declare class WorkflowSession extends Context.TagClassShape<"WorkflowSession", WorkflowSessionService$2> {
366
+ }
367
+
368
+ /**
369
+ * @param {WorkflowSessionOptions} [options]
370
+ * @returns {WorkflowSessionService}
371
+ */
372
+ declare function makeWorkflowSession(options?: WorkflowSessionOptions$1): WorkflowSessionService$1;
373
+ type WorkflowSessionOptions$1 = WorkflowSessionOptions$2;
374
+ type WorkflowSessionService$1 = WorkflowSessionService$2;
375
+
376
+ /** @type {Layer.Layer<WorkflowSession, never, never>} */
377
+ declare const WorkflowSessionLive: Layer.Layer<WorkflowSession, never, never>;
378
+
379
+ /**
380
+ * @returns {number}
381
+ */
382
+ declare function nowMs(): number;
383
+
384
+ /**
385
+ * Convert a RetryPolicy to an Effect Schedule for use with Effect.retry.
386
+ *
387
+ * @param {RetryPolicy} policy
388
+ * @returns {Schedule.Schedule<unknown>}
389
+ */
390
+ declare function retryPolicyToSchedule(policy: RetryPolicy$2): Schedule.Schedule<unknown>;
391
+ type RetryPolicy$2 = RetryPolicy$3;
392
+
393
+ /**
394
+ * @param {Schedule.Schedule<unknown>} schedule
395
+ * @param {number} attempt
396
+ * @returns {number}
397
+ */
398
+ declare function retryScheduleDelayMs(schedule: Schedule.Schedule<unknown>, attempt: number): number;
399
+
400
+ /** @typedef {import("./RetryPolicy.ts").RetryPolicy} RetryPolicy */
401
+ /**
402
+ * @param {RetryPolicy | undefined} policy
403
+ * @param {number} attempt
404
+ * @returns {number}
405
+ */
406
+ declare function computeRetryDelayMs(policy: RetryPolicy$1 | undefined, attempt: number): number;
407
+ type RetryPolicy$1 = RetryPolicy$3;
408
+
409
+ type ApprovalResolution = ApprovalResolution$1;
410
+ type CachePolicy = CachePolicy$1;
411
+ type ContinuationRequest = ContinuationRequest$1;
412
+ type ContinueAsNewTransition = ContinueAsNewTransition$1;
413
+ type EngineDecision = EngineDecision$1;
414
+ type PlanNode = PlanNode$4;
415
+ type RalphMeta = RalphMeta$2;
416
+ type RalphState = RalphState$1;
417
+ type RalphStateMap = RalphStateMap$4;
418
+ type ReadonlyTaskStateMap = ReadonlyTaskStateMap$2;
419
+ type RenderContext = RenderContext$1;
420
+ type RetryBackoff = RetryBackoff$1;
421
+ type RetryPolicy = RetryPolicy$3;
422
+ type RetryWaitMap = RetryWaitMap$3;
423
+ type RunResult = RunResult$1;
424
+ type ScheduleResult = ScheduleResult$3;
425
+ type ScheduleSnapshot = ScheduleSnapshot$1;
426
+ type SmithersWorkflowOptions = SmithersWorkflowOptions$1;
427
+ type TaskFailure = TaskFailure$1;
428
+ type TaskOutput = TaskOutput$1;
429
+ type TaskRecord = TaskRecord$1;
430
+ type TaskState = TaskState$2;
431
+ type TaskStateMap = TaskStateMap$4;
432
+ type TokenUsage = TokenUsage$1;
433
+ type WaitReason = WaitReason$1;
434
+ type WorkflowSessionOptions = WorkflowSessionOptions$2;
435
+ type WorkflowSessionService = WorkflowSessionService$2;
436
+
437
+ export { type ApprovalResolution, type CachePolicy, type ContinuationRequest, type ContinueAsNewTransition, type EngineDecision, type PlanNode, type RalphMeta, type RalphState, type RalphStateMap, type ReadonlyTaskStateMap, type RenderContext, type RetryBackoff, type RetryPolicy, type RetryWaitMap, type RunResult, type ScheduleResult, type ScheduleSnapshot, Scheduler, SchedulerLive, type SmithersAlertLabels, type SmithersAlertPolicy, type SmithersAlertPolicyDefaults, type SmithersAlertPolicyRule, type SmithersAlertReaction, type SmithersAlertReactionKind, type SmithersAlertReactionRef, type SmithersAlertSeverity, type SmithersWorkflowOptions, type TaskFailure, type TaskOutput, type TaskRecord, type TaskState, type TaskStateMap, type TokenUsage, type WaitReason, WorkflowSession, WorkflowSessionLive, type WorkflowSessionOptions, type WorkflowSessionService, buildPlanTree, buildStateKey, cloneTaskStateMap, computeRetryDelayMs, isTerminalState, makeWorkflowSession, nowMs, parseStateKey, retryPolicyToSchedule, retryScheduleDelayMs, scheduleTasks };
package/src/index.js ADDED
@@ -0,0 +1,53 @@
1
+ // @smithers-type-exports-begin
2
+ /** @typedef {import("./ApprovalResolution.ts").ApprovalResolution} ApprovalResolution */
3
+ /** @typedef {import("./CachePolicy.ts").CachePolicy} CachePolicy */
4
+ /** @typedef {import("./ContinuationRequest.ts").ContinuationRequest} ContinuationRequest */
5
+ /** @typedef {import("./ContinueAsNewTransition.ts").ContinueAsNewTransition} ContinueAsNewTransition */
6
+ /** @typedef {import("./EngineDecision.ts").EngineDecision} EngineDecision */
7
+ /** @typedef {import("./PlanNode.ts").PlanNode} PlanNode */
8
+ /** @typedef {import("./RalphMeta.ts").RalphMeta} RalphMeta */
9
+ /** @typedef {import("./RalphState.ts").RalphState} RalphState */
10
+ /** @typedef {import("./RalphStateMap.ts").RalphStateMap} RalphStateMap */
11
+ /** @typedef {import("./ReadonlyTaskStateMap.ts").ReadonlyTaskStateMap} ReadonlyTaskStateMap */
12
+ /** @typedef {import("./RenderContext.ts").RenderContext} RenderContext */
13
+ /** @typedef {import("./RetryPolicy.ts").RetryBackoff} RetryBackoff */
14
+ /** @typedef {import("./RetryPolicy.ts").RetryPolicy} RetryPolicy */
15
+ /** @typedef {import("./RetryWaitMap.ts").RetryWaitMap} RetryWaitMap */
16
+ /** @typedef {import("./RunResult.ts").RunResult} RunResult */
17
+ /** @typedef {import("./ScheduleResult.ts").ScheduleResult} ScheduleResult */
18
+ /** @typedef {import("./ScheduleSnapshot.ts").ScheduleSnapshot} ScheduleSnapshot */
19
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertLabels} SmithersAlertLabels */
20
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertPolicy} SmithersAlertPolicy */
21
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertPolicyDefaults} SmithersAlertPolicyDefaults */
22
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertPolicyRule} SmithersAlertPolicyRule */
23
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertReaction} SmithersAlertReaction */
24
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertReactionKind} SmithersAlertReactionKind */
25
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertReactionRef} SmithersAlertReactionRef */
26
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersAlertSeverity} SmithersAlertSeverity */
27
+ /** @typedef {import("./SmithersWorkflowOptions.ts").SmithersWorkflowOptions} SmithersWorkflowOptions */
28
+ /** @typedef {import("./TaskFailure.ts").TaskFailure} TaskFailure */
29
+ /** @typedef {import("./TaskOutput.ts").TaskOutput} TaskOutput */
30
+ /** @typedef {import("./TaskRecord.ts").TaskRecord} TaskRecord */
31
+ /** @typedef {import("./TaskState.ts").TaskState} TaskState */
32
+ /** @typedef {import("./TaskStateMap.ts").TaskStateMap} TaskStateMap */
33
+ /** @typedef {import("./TokenUsage.ts").TokenUsage} TokenUsage */
34
+ /** @typedef {import("./WaitReason.ts").WaitReason} WaitReason */
35
+ /** @typedef {import("./WorkflowSessionOptions.ts").WorkflowSessionOptions} WorkflowSessionOptions */
36
+ /** @typedef {import("./WorkflowSessionService.ts").WorkflowSessionService} WorkflowSessionService */
37
+ // @smithers-type-exports-end
38
+
39
+ export { buildStateKey } from "./buildStateKey.js";
40
+ export { parseStateKey } from "./parseStateKey.js";
41
+ export { cloneTaskStateMap } from "./cloneTaskStateMap.js";
42
+ export { isTerminalState } from "./isTerminalState.js";
43
+ export { Scheduler } from "./Scheduler.js";
44
+ export { SchedulerLive } from "./SchedulerLive.js";
45
+ export { buildPlanTree } from "./buildPlanTree.js";
46
+ export { scheduleTasks } from "./scheduleTasks.js";
47
+ export { WorkflowSession } from "./WorkflowSession.js";
48
+ export { makeWorkflowSession } from "./makeWorkflowSession.js";
49
+ export { WorkflowSessionLive } from "./WorkflowSessionLive.js";
50
+ export { nowMs } from "./nowMs.js";
51
+ export { retryPolicyToSchedule } from "./retryPolicyToSchedule.js";
52
+ export { retryScheduleDelayMs } from "./retryScheduleDelayMs.js";
53
+ export { computeRetryDelayMs } from "./computeRetryDelayMs.js";
@@ -0,0 +1,15 @@
1
+
2
+ /** @typedef {import("@smithers-orchestrator/graph").TaskDescriptor} TaskDescriptor */
3
+ /** @typedef {import("./TaskState.ts").TaskState} TaskState */
4
+ /**
5
+ * @param {TaskState} state
6
+ * @param {Pick<TaskDescriptor, "continueOnFail">} [descriptor]
7
+ * @returns {boolean}
8
+ */
9
+ export function isTerminalState(state, descriptor) {
10
+ if (state === "finished" || state === "skipped")
11
+ return true;
12
+ if (state === "failed")
13
+ return Boolean(descriptor?.continueOnFail);
14
+ return false;
15
+ }