@voyant-travel/workflows-orchestrator 0.107.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.
Files changed (61) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +52 -0
  3. package/README.md +76 -0
  4. package/dist/abort-registry.d.ts +6 -0
  5. package/dist/abort-registry.d.ts.map +1 -0
  6. package/dist/abort-registry.js +37 -0
  7. package/dist/concurrency.d.ts +31 -0
  8. package/dist/concurrency.d.ts.map +1 -0
  9. package/dist/concurrency.js +145 -0
  10. package/dist/drive.d.ts +67 -0
  11. package/dist/drive.d.ts.map +1 -0
  12. package/dist/drive.js +373 -0
  13. package/dist/driver-inmemory.d.ts +30 -0
  14. package/dist/driver-inmemory.d.ts.map +1 -0
  15. package/dist/driver-inmemory.js +394 -0
  16. package/dist/event-router.d.ts +51 -0
  17. package/dist/event-router.d.ts.map +1 -0
  18. package/dist/event-router.js +68 -0
  19. package/dist/http-step-handler.d.ts +25 -0
  20. package/dist/http-step-handler.d.ts.map +1 -0
  21. package/dist/http-step-handler.js +78 -0
  22. package/dist/in-memory-store.d.ts +5 -0
  23. package/dist/in-memory-store.d.ts.map +1 -0
  24. package/dist/in-memory-store.js +41 -0
  25. package/dist/index.d.ts +13 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +22 -0
  28. package/dist/journal-helpers.d.ts +3 -0
  29. package/dist/journal-helpers.d.ts.map +1 -0
  30. package/dist/journal-helpers.js +9 -0
  31. package/dist/orchestrator.d.ts +116 -0
  32. package/dist/orchestrator.d.ts.map +1 -0
  33. package/dist/orchestrator.js +411 -0
  34. package/dist/resume-run.d.ts +40 -0
  35. package/dist/resume-run.d.ts.map +1 -0
  36. package/dist/resume-run.js +119 -0
  37. package/dist/schedule.d.ts +51 -0
  38. package/dist/schedule.d.ts.map +1 -0
  39. package/dist/schedule.js +243 -0
  40. package/dist/testing/driver-compliance.d.ts +58 -0
  41. package/dist/testing/driver-compliance.d.ts.map +1 -0
  42. package/dist/testing/driver-compliance.js +667 -0
  43. package/dist/types.d.ts +182 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +4 -0
  46. package/package.json +51 -0
  47. package/src/__tests__/orchestrator-test-support.ts +18 -0
  48. package/src/abort-registry.ts +41 -0
  49. package/src/concurrency.ts +217 -0
  50. package/src/drive.ts +477 -0
  51. package/src/driver-inmemory.ts +511 -0
  52. package/src/event-router.ts +120 -0
  53. package/src/http-step-handler.ts +112 -0
  54. package/src/in-memory-store.ts +44 -0
  55. package/src/index.ts +73 -0
  56. package/src/journal-helpers.ts +11 -0
  57. package/src/orchestrator.ts +527 -0
  58. package/src/resume-run.ts +162 -0
  59. package/src/schedule.ts +310 -0
  60. package/src/testing/driver-compliance.ts +800 -0
  61. package/src/types.ts +201 -0
package/src/types.ts ADDED
@@ -0,0 +1,201 @@
1
+ // Types the orchestrator core uses. Decoupled from any transport:
2
+ // the same RunRecord/Store shapes underpin the in-memory test store,
3
+ // the Durable-Object-backed production store, and any future adapters.
4
+
5
+ import type { RunTrigger, WaitpointKind } from "@voyant-travel/workflows"
6
+ import type {
7
+ StepHandlerError,
8
+ WorkflowStepRequest,
9
+ WorkflowStepResponse,
10
+ } from "@voyant-travel/workflows/handler"
11
+ import type {
12
+ CompensationJournalEntry,
13
+ JournalSlice,
14
+ StepJournalEntry,
15
+ WaitpointResolutionEntry,
16
+ } from "@voyant-travel/workflows/protocol"
17
+
18
+ export type {
19
+ CompensationJournalEntry,
20
+ JournalSlice,
21
+ RunTrigger,
22
+ StepJournalEntry,
23
+ WaitpointKind,
24
+ WaitpointResolutionEntry,
25
+ WorkflowStepRequest,
26
+ WorkflowStepResponse,
27
+ }
28
+
29
+ /**
30
+ * Terminal and non-terminal run statuses. Mirrors the wire statuses
31
+ * from docs/runtime-protocol.md §5 but only the states the orchestrator
32
+ * itself cares about.
33
+ */
34
+ export type OrchestratorRunStatus =
35
+ | "running"
36
+ | "waiting"
37
+ | "completed"
38
+ | "failed"
39
+ | "cancelled"
40
+ | "compensated"
41
+ | "compensation_failed"
42
+
43
+ export interface PendingWaitpoint {
44
+ clientWaitpointId: string
45
+ kind: WaitpointKind
46
+ meta: Record<string, unknown>
47
+ timeoutMs?: number
48
+ }
49
+
50
+ export interface StreamChunk {
51
+ streamId: string
52
+ seq: number
53
+ encoding: "text" | "json" | "base64"
54
+ chunk: unknown
55
+ final: boolean
56
+ at: number
57
+ }
58
+
59
+ export interface RunRecord {
60
+ id: string
61
+ workflowId: string
62
+ workflowVersion: string
63
+ status: OrchestratorRunStatus
64
+ input: unknown
65
+ /** Output on "completed" runs. */
66
+ output?: unknown
67
+ /** SerializedError for failed / compensation_failed. */
68
+ error?: { category: string; code: string; message: string }
69
+ /** Journal accumulated across every tenant invocation. */
70
+ journal: JournalSlice
71
+ /** Number of tenant invocations performed so far. */
72
+ invocationCount: number
73
+ /**
74
+ * Positional dedup cursor for `metadataUpdates`. Each executor
75
+ * response re-emits every metadata mutation the body made (including
76
+ * those from prior invocations, since the body replays from the
77
+ * start). The orchestrator applies only the delta beyond what it's
78
+ * seen to avoid double-counting increments / duplicate appends.
79
+ */
80
+ metadataAppliedCount: number
81
+ /**
82
+ * Cumulative ms spent inside tenant invocations, excluding parked
83
+ * time. Used to enforce workflow-level timeouts — a run that
84
+ * parks for a week on a waitpoint should not count that week
85
+ * against its compute budget.
86
+ */
87
+ computeTimeMs: number
88
+ /** ms budget from WorkflowConfig.timeout. Zero / undefined = no limit. */
89
+ timeoutMs?: number
90
+ /**
91
+ * Trigger-time scheduling priority. Higher numbers are claimed first
92
+ * by store-backed time wheels when multiple runs are due.
93
+ */
94
+ priority?: number
95
+ /**
96
+ * Cross-run lineage. Present on child runs created by
97
+ * `ctx.invoke`; set by the orchestrator when the child parks so
98
+ * its eventual terminal transition can cascade-resume the parent.
99
+ */
100
+ parent?: {
101
+ runId: string
102
+ waitpointId: string
103
+ }
104
+ /** Pending waitpoints, only populated when status === "waiting". */
105
+ pendingWaitpoints: PendingWaitpoint[]
106
+ /** Stream chunks accumulated across every tenant invocation, keyed by streamId. */
107
+ streams: Record<string, StreamChunk[]>
108
+ /** Wall-clock fields, all ms-since-epoch. */
109
+ startedAt: number
110
+ completedAt?: number
111
+ /** Trigger metadata. */
112
+ triggeredBy: RunTrigger
113
+ tags: string[]
114
+ /** Optional environment metadata. */
115
+ environment: "production" | "preview" | "development"
116
+ /** Tenant identity flows through every step request. */
117
+ tenantMeta: {
118
+ tenantId: string
119
+ projectId: string
120
+ organizationId: string
121
+ projectSlug?: string
122
+ organizationSlug?: string
123
+ /**
124
+ * Identifier the runtime adapter uses to locate the tenant's
125
+ * code. On Cloudflare this is the dispatch-namespace script name;
126
+ * on other targets it may be a container image tag or Node script
127
+ * path. Optional so local/in-process drivers aren't forced to set it.
128
+ */
129
+ tenantScript?: string
130
+ }
131
+ runMeta: {
132
+ number: number
133
+ attempt: number
134
+ }
135
+ /**
136
+ * Caller-supplied idempotency token, mirrored from `TriggerArgs.idempotencyKey`.
137
+ * Persistent stores use this column to enforce dedup natively (e.g. unique
138
+ * partial index in `voyant_snapshot_runs`); in-process stores ignore it.
139
+ */
140
+ idempotencyKey?: string
141
+ }
142
+
143
+ export interface RunRecordStore {
144
+ get(id: string): Promise<RunRecord | undefined>
145
+ save(record: RunRecord): Promise<RunRecord>
146
+ /**
147
+ * Atomically insert a new run record, OR return the existing one if
148
+ * a record with the same `id` already exists. Used by `trigger()` to
149
+ * close the get-then-save race window when an idempotency-derived
150
+ * runId could collide across concurrent callers.
151
+ *
152
+ * Stores must implement this with a single atomic operation:
153
+ * - Postgres: `INSERT … ON CONFLICT (id) DO NOTHING RETURNING …`,
154
+ * with a fallback SELECT when no row is returned.
155
+ * - InMemory / FS: check-then-set in a single microtask.
156
+ * - DO storage: get-then-save is naturally atomic per DO instance.
157
+ *
158
+ * The returned `created: true` means this caller's record was the
159
+ * winner — drive it. `created: false` means another caller raced in
160
+ * first; return the existing record without re-driving (per
161
+ * architecture doc §15.2).
162
+ */
163
+ tryInsert(record: RunRecord): Promise<{ record: RunRecord; created: boolean }>
164
+ list(filter?: {
165
+ workflowId?: string
166
+ status?: OrchestratorRunStatus
167
+ limit?: number
168
+ }): Promise<RunRecord[]>
169
+ }
170
+
171
+ /**
172
+ * The tenant-side step handler. In-process for tests / local dev via
173
+ * `handleStepRequest` from @voyant-travel/workflows/handler; HTTP in
174
+ * production (via a fetch to the tenant Worker). The optional
175
+ * per-invocation `signal` aborts in-flight step bodies when the run
176
+ * is cancelled mid-execution.
177
+ */
178
+ export type StepHandler = (
179
+ req: WorkflowStepRequest,
180
+ opts?: {
181
+ signal?: AbortSignal
182
+ /**
183
+ * Fires synchronously from `ctx.stream.*` as each chunk is
184
+ * produced. In-process only; HTTP transport drops it (chunks
185
+ * still arrive in the response body). Used by orchestrators to
186
+ * broadcast chunks to dashboards before the invocation returns.
187
+ */
188
+ onStreamChunk?: (chunk: StreamChunk) => void
189
+ },
190
+ ) => Promise<
191
+ { status: number; body: WorkflowStepResponse } | { status: number; body: StepHandlerError }
192
+ >
193
+
194
+ /**
195
+ * Injection delivered by an external signal (dashboard, API, inbox).
196
+ * Same shape used by the dashboard inject endpoints.
197
+ */
198
+ export type WaitpointInjection =
199
+ | { kind: "EVENT"; eventType: string; payload?: unknown }
200
+ | { kind: "SIGNAL"; name: string; payload?: unknown }
201
+ | { kind: "MANUAL"; tokenId: string; payload?: unknown }