@mokronos/wfkit 0.1.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/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/authoring.d.ts +7 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.js +8 -0
- package/dist/authoring.js.map +1 -0
- package/dist/cli/integrations.d.ts +3 -0
- package/dist/cli/integrations.d.ts.map +1 -0
- package/dist/cli/integrations.js +40 -0
- package/dist/cli/integrations.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +591 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/core.d.ts +198 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +1061 -0
- package/dist/core.js.map +1 -0
- package/dist/errors.d.ts +3 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +154 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +24 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/replay.d.ts +3 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +28 -0
- package/dist/replay.js.map +1 -0
- package/dist/runtime.d.ts +70 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +183 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schema.d.ts +18 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +19 -0
- package/dist/schema.js.map +1 -0
- package/dist/schemas.d.ts +1198 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +383 -0
- package/dist/schemas.js.map +1 -0
- package/dist/sdk/artifact.d.ts +41 -0
- package/dist/sdk/artifact.d.ts.map +1 -0
- package/dist/sdk/artifact.js +94 -0
- package/dist/sdk/artifact.js.map +1 -0
- package/dist/sdk/graph.d.ts +15 -0
- package/dist/sdk/graph.d.ts.map +1 -0
- package/dist/sdk/graph.js +388 -0
- package/dist/sdk/graph.js.map +1 -0
- package/dist/sdk/index.d.ts +14 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +8 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/integrations.d.ts +18 -0
- package/dist/sdk/integrations.d.ts.map +1 -0
- package/dist/sdk/integrations.js +20 -0
- package/dist/sdk/integrations.js.map +1 -0
- package/dist/sdk/json.d.ts +4 -0
- package/dist/sdk/json.d.ts.map +1 -0
- package/dist/sdk/json.js +31 -0
- package/dist/sdk/json.js.map +1 -0
- package/dist/sdk/loader.d.ts +10 -0
- package/dist/sdk/loader.d.ts.map +1 -0
- package/dist/sdk/loader.js +75 -0
- package/dist/sdk/loader.js.map +1 -0
- package/dist/sdk/sdk.d.ts +102 -0
- package/dist/sdk/sdk.d.ts.map +1 -0
- package/dist/sdk/sdk.js +669 -0
- package/dist/sdk/sdk.js.map +1 -0
- package/dist/sdk/sqlite.d.ts +8 -0
- package/dist/sdk/sqlite.d.ts.map +1 -0
- package/dist/sdk/sqlite.js +288 -0
- package/dist/sdk/sqlite.js.map +1 -0
- package/dist/signal.d.ts +17 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +78 -0
- package/dist/signal.js.map +1 -0
- package/dist/testing/index.d.ts +35 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +244 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +67 -0
- package/src/authoring.ts +32 -0
- package/src/cli/integrations.ts +75 -0
- package/src/cli/main.ts +793 -0
- package/src/core.ts +1515 -0
- package/src/errors.ts +19 -0
- package/src/events.ts +37 -0
- package/src/index.ts +109 -0
- package/src/replay.ts +29 -0
- package/src/runtime.ts +314 -0
- package/src/schema.ts +34 -0
- package/src/schemas.ts +473 -0
- package/src/sdk/artifact.ts +176 -0
- package/src/sdk/graph.ts +486 -0
- package/src/sdk/index.ts +64 -0
- package/src/sdk/integrations.ts +49 -0
- package/src/sdk/json.ts +40 -0
- package/src/sdk/loader.ts +99 -0
- package/src/sdk/sdk.ts +911 -0
- package/src/sdk/sqlite.ts +405 -0
- package/src/signal.ts +116 -0
- package/src/testing/index.ts +341 -0
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
import { Schema } from "effect"
|
|
2
|
+
|
|
3
|
+
export const ExecutionId = Schema.String.pipe(Schema.brand("ExecutionId"))
|
|
4
|
+
export type ExecutionId = typeof ExecutionId.Type
|
|
5
|
+
|
|
6
|
+
const OptionalString = Schema.optionalKey(Schema.String)
|
|
7
|
+
const OptionalUnknown = Schema.optionalKey(Schema.Unknown)
|
|
8
|
+
|
|
9
|
+
const JsonSchemaType = Schema.Union([Schema.String, Schema.Array(Schema.String)])
|
|
10
|
+
|
|
11
|
+
export interface JsonSchema {
|
|
12
|
+
readonly type?: string | ReadonlyArray<string>
|
|
13
|
+
readonly const?: Schema.Json
|
|
14
|
+
readonly enum?: ReadonlyArray<Schema.Json>
|
|
15
|
+
readonly anyOf?: ReadonlyArray<JsonSchema>
|
|
16
|
+
readonly oneOf?: ReadonlyArray<JsonSchema>
|
|
17
|
+
readonly items?: JsonSchema
|
|
18
|
+
readonly properties?: { readonly [key: string]: JsonSchema }
|
|
19
|
+
readonly required?: ReadonlyArray<string>
|
|
20
|
+
readonly [key: string]: Schema.Json | JsonSchema | ReadonlyArray<Schema.Json> | ReadonlyArray<JsonSchema> | { readonly [key: string]: JsonSchema } | undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const JsonSchema: Schema.Codec<JsonSchema> = Schema.StructWithRest(
|
|
24
|
+
Schema.Struct({
|
|
25
|
+
type: Schema.optionalKey(JsonSchemaType),
|
|
26
|
+
const: Schema.optionalKey(Schema.Json),
|
|
27
|
+
enum: Schema.optionalKey(Schema.Array(Schema.Json)),
|
|
28
|
+
anyOf: Schema.optionalKey(Schema.Array(Schema.suspend((): Schema.Codec<JsonSchema> => JsonSchema))),
|
|
29
|
+
oneOf: Schema.optionalKey(Schema.Array(Schema.suspend((): Schema.Codec<JsonSchema> => JsonSchema))),
|
|
30
|
+
items: Schema.optionalKey(Schema.suspend((): Schema.Codec<JsonSchema> => JsonSchema)),
|
|
31
|
+
properties: Schema.optionalKey(Schema.Record(Schema.String, Schema.suspend((): Schema.Codec<JsonSchema> => JsonSchema))),
|
|
32
|
+
required: Schema.optionalKey(Schema.Array(Schema.String))
|
|
33
|
+
}),
|
|
34
|
+
[Schema.Record(Schema.String, Schema.Json)]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
export const decodeJsonSchema = (value: unknown): JsonSchema =>
|
|
38
|
+
Schema.decodeUnknownSync(JsonSchema)(value)
|
|
39
|
+
|
|
40
|
+
/** Best-effort JSON Schema for an Effect schema; undefined when the schema
|
|
41
|
+
* has no JSON representation. */
|
|
42
|
+
export const jsonSchemaOf = (schema: unknown): JsonSchema | undefined => {
|
|
43
|
+
try {
|
|
44
|
+
const document = Schema.toJsonSchemaDocument(schema as never) as { readonly schema?: unknown }
|
|
45
|
+
return document.schema === undefined ? undefined : decodeJsonSchema(document.schema)
|
|
46
|
+
} catch {
|
|
47
|
+
return undefined
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const WorkflowStartedEvent = Schema.Struct({
|
|
52
|
+
type: Schema.Literal("workflow.started"),
|
|
53
|
+
workflowName: Schema.String,
|
|
54
|
+
payload: OptionalUnknown
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const WorkflowCompletedEvent = Schema.Struct({
|
|
58
|
+
type: Schema.Literal("workflow.completed"),
|
|
59
|
+
workflowName: Schema.String,
|
|
60
|
+
result: OptionalUnknown
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const WorkflowFailedEvent = Schema.Struct({
|
|
64
|
+
type: Schema.Literal("workflow.failed"),
|
|
65
|
+
workflowName: Schema.String,
|
|
66
|
+
error: OptionalUnknown
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const StepStartedEvent = Schema.Struct({
|
|
70
|
+
type: Schema.Literal("step.started"),
|
|
71
|
+
executionId: ExecutionId,
|
|
72
|
+
stepName: Schema.String,
|
|
73
|
+
invocation: Schema.Number,
|
|
74
|
+
activityName: Schema.String,
|
|
75
|
+
attempt: Schema.Number,
|
|
76
|
+
input: OptionalUnknown
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const StepCompletedEvent = Schema.Struct({
|
|
80
|
+
type: Schema.Literal("step.completed"),
|
|
81
|
+
executionId: ExecutionId,
|
|
82
|
+
stepName: Schema.String,
|
|
83
|
+
invocation: Schema.Number,
|
|
84
|
+
activityName: Schema.String,
|
|
85
|
+
attempt: Schema.Number,
|
|
86
|
+
result: OptionalUnknown
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const StepFailedEvent = Schema.Struct({
|
|
90
|
+
type: Schema.Literal("step.failed"),
|
|
91
|
+
executionId: ExecutionId,
|
|
92
|
+
stepName: Schema.String,
|
|
93
|
+
invocation: Schema.Number,
|
|
94
|
+
activityName: Schema.String,
|
|
95
|
+
error: OptionalUnknown
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const CompensationStartedEvent = Schema.Struct({
|
|
99
|
+
type: Schema.Literal("compensation.started"),
|
|
100
|
+
executionId: ExecutionId,
|
|
101
|
+
stepName: Schema.String,
|
|
102
|
+
invocation: Schema.Number,
|
|
103
|
+
activityName: Schema.String,
|
|
104
|
+
result: OptionalUnknown,
|
|
105
|
+
input: OptionalUnknown,
|
|
106
|
+
reason: OptionalUnknown
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
const CompensationCompletedEvent = Schema.Struct({
|
|
110
|
+
type: Schema.Literal("compensation.completed"),
|
|
111
|
+
executionId: ExecutionId,
|
|
112
|
+
stepName: Schema.String,
|
|
113
|
+
invocation: Schema.Number,
|
|
114
|
+
activityName: Schema.String
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const CompensationFailedEvent = Schema.Struct({
|
|
118
|
+
type: Schema.Literal("compensation.failed"),
|
|
119
|
+
executionId: ExecutionId,
|
|
120
|
+
stepName: Schema.String,
|
|
121
|
+
invocation: Schema.Number,
|
|
122
|
+
activityName: Schema.String,
|
|
123
|
+
error: OptionalUnknown
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
const SleepStartedEvent = Schema.Struct({
|
|
127
|
+
type: Schema.Literal("sleep.started"),
|
|
128
|
+
executionId: ExecutionId,
|
|
129
|
+
name: Schema.String,
|
|
130
|
+
invocation: Schema.Number,
|
|
131
|
+
activityName: Schema.String,
|
|
132
|
+
duration: OptionalUnknown
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
const SleepCompletedEvent = Schema.Struct({
|
|
136
|
+
type: Schema.Literal("sleep.completed"),
|
|
137
|
+
executionId: ExecutionId,
|
|
138
|
+
name: Schema.String,
|
|
139
|
+
invocation: Schema.Number,
|
|
140
|
+
activityName: Schema.String,
|
|
141
|
+
duration: OptionalUnknown
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
const SignalWaitingEvent = Schema.Struct({
|
|
145
|
+
type: Schema.Literal("signal.waiting"),
|
|
146
|
+
executionId: ExecutionId,
|
|
147
|
+
name: Schema.String,
|
|
148
|
+
invocation: Schema.Number,
|
|
149
|
+
activityName: Schema.String,
|
|
150
|
+
timeout: OptionalUnknown,
|
|
151
|
+
/** JSON Schema of the payload the wait expects; lets a human or agent see
|
|
152
|
+
* what to send before delivering the signal. */
|
|
153
|
+
payloadSchema: Schema.optionalKey(JsonSchema)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
const SignalReceivedEvent = Schema.Struct({
|
|
157
|
+
type: Schema.Literal("signal.received"),
|
|
158
|
+
executionId: ExecutionId,
|
|
159
|
+
name: Schema.String,
|
|
160
|
+
invocation: Schema.Number,
|
|
161
|
+
activityName: Schema.String,
|
|
162
|
+
payload: OptionalUnknown
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
const SignalTimeoutEvent = Schema.Struct({
|
|
166
|
+
type: Schema.Literal("signal.timeout"),
|
|
167
|
+
executionId: ExecutionId,
|
|
168
|
+
name: Schema.String,
|
|
169
|
+
invocation: Schema.Number,
|
|
170
|
+
activityName: Schema.String,
|
|
171
|
+
timeout: OptionalUnknown
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
const CodeStartedEvent = Schema.Struct({
|
|
175
|
+
type: Schema.Literal("code.started"),
|
|
176
|
+
executionId: ExecutionId,
|
|
177
|
+
name: Schema.String,
|
|
178
|
+
invocation: Schema.Number,
|
|
179
|
+
activityName: Schema.String,
|
|
180
|
+
reason: OptionalString
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
const CodeCompletedEvent = Schema.Struct({
|
|
184
|
+
type: Schema.Literal("code.completed"),
|
|
185
|
+
executionId: ExecutionId,
|
|
186
|
+
name: Schema.String,
|
|
187
|
+
invocation: Schema.Number,
|
|
188
|
+
activityName: Schema.String,
|
|
189
|
+
reason: OptionalString,
|
|
190
|
+
result: OptionalUnknown
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
const CodeFailedEvent = Schema.Struct({
|
|
194
|
+
type: Schema.Literal("code.failed"),
|
|
195
|
+
executionId: ExecutionId,
|
|
196
|
+
name: Schema.String,
|
|
197
|
+
invocation: Schema.Number,
|
|
198
|
+
activityName: Schema.String,
|
|
199
|
+
reason: OptionalString,
|
|
200
|
+
error: OptionalUnknown
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
const AllStartedEvent = Schema.Struct({
|
|
204
|
+
type: Schema.Literal("all.started"),
|
|
205
|
+
executionId: ExecutionId,
|
|
206
|
+
name: Schema.String,
|
|
207
|
+
invocation: Schema.Number,
|
|
208
|
+
activityName: Schema.String,
|
|
209
|
+
branches: Schema.Number
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
const AllCompletedEvent = Schema.Struct({
|
|
213
|
+
type: Schema.Literal("all.completed"),
|
|
214
|
+
executionId: ExecutionId,
|
|
215
|
+
name: Schema.String,
|
|
216
|
+
invocation: Schema.Number,
|
|
217
|
+
activityName: Schema.String,
|
|
218
|
+
branches: Schema.Number
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
const AllFailedEvent = Schema.Struct({
|
|
222
|
+
type: Schema.Literal("all.failed"),
|
|
223
|
+
executionId: ExecutionId,
|
|
224
|
+
name: Schema.String,
|
|
225
|
+
invocation: Schema.Number,
|
|
226
|
+
activityName: Schema.String,
|
|
227
|
+
branches: Schema.Number,
|
|
228
|
+
error: OptionalUnknown
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
const CancellationReceivedEvent = Schema.Struct({
|
|
232
|
+
type: Schema.Literal("cancellation.received"),
|
|
233
|
+
executionId: ExecutionId,
|
|
234
|
+
compensate: Schema.Boolean,
|
|
235
|
+
actor: OptionalString
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
export const WorkflowEvent = Schema.Union([
|
|
239
|
+
WorkflowStartedEvent,
|
|
240
|
+
WorkflowCompletedEvent,
|
|
241
|
+
WorkflowFailedEvent,
|
|
242
|
+
StepStartedEvent,
|
|
243
|
+
StepCompletedEvent,
|
|
244
|
+
StepFailedEvent,
|
|
245
|
+
CompensationStartedEvent,
|
|
246
|
+
CompensationCompletedEvent,
|
|
247
|
+
CompensationFailedEvent,
|
|
248
|
+
SleepStartedEvent,
|
|
249
|
+
SleepCompletedEvent,
|
|
250
|
+
SignalWaitingEvent,
|
|
251
|
+
SignalReceivedEvent,
|
|
252
|
+
SignalTimeoutEvent,
|
|
253
|
+
CodeStartedEvent,
|
|
254
|
+
CodeCompletedEvent,
|
|
255
|
+
CodeFailedEvent,
|
|
256
|
+
AllStartedEvent,
|
|
257
|
+
AllCompletedEvent,
|
|
258
|
+
AllFailedEvent,
|
|
259
|
+
CancellationReceivedEvent
|
|
260
|
+
])
|
|
261
|
+
export type WorkflowEvent = typeof WorkflowEvent.Type
|
|
262
|
+
export const isWorkflowEvent = Schema.is(WorkflowEvent)
|
|
263
|
+
|
|
264
|
+
export const HistoryExecutionStarted = Schema.Struct({
|
|
265
|
+
type: Schema.Literal("execution.started"),
|
|
266
|
+
executionId: ExecutionId,
|
|
267
|
+
workflowName: Schema.String,
|
|
268
|
+
version: Schema.Number,
|
|
269
|
+
payload: OptionalUnknown,
|
|
270
|
+
actor: OptionalString
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
export const HistorySignalDelivered = Schema.Struct({
|
|
274
|
+
type: Schema.Literal("signal.delivered"),
|
|
275
|
+
executionId: ExecutionId,
|
|
276
|
+
name: Schema.String,
|
|
277
|
+
payload: OptionalUnknown,
|
|
278
|
+
actor: OptionalString
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
export const HistoryExecutionCancelled = Schema.Struct({
|
|
282
|
+
type: Schema.Literal("execution.cancelled"),
|
|
283
|
+
executionId: ExecutionId,
|
|
284
|
+
compensate: Schema.Boolean,
|
|
285
|
+
actor: OptionalString
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
export const WorkflowHistoryEvent = Schema.Union([
|
|
289
|
+
WorkflowEvent,
|
|
290
|
+
HistoryExecutionStarted,
|
|
291
|
+
HistorySignalDelivered,
|
|
292
|
+
HistoryExecutionCancelled
|
|
293
|
+
])
|
|
294
|
+
export type WorkflowHistoryEvent = typeof WorkflowHistoryEvent.Type
|
|
295
|
+
|
|
296
|
+
export const WorkflowRunStatus = Schema.Literals(["running", "completed", "failed"])
|
|
297
|
+
export type WorkflowRunStatus = typeof WorkflowRunStatus.Type
|
|
298
|
+
|
|
299
|
+
export const WorkflowArtifact = Schema.Struct({
|
|
300
|
+
id: Schema.String,
|
|
301
|
+
name: Schema.String,
|
|
302
|
+
version: Schema.String,
|
|
303
|
+
source: Schema.String,
|
|
304
|
+
exportName: OptionalString,
|
|
305
|
+
createdAt: OptionalString
|
|
306
|
+
})
|
|
307
|
+
export type WorkflowArtifact = typeof WorkflowArtifact.Type
|
|
308
|
+
|
|
309
|
+
export const WorkflowManifestEntry = Schema.Struct({
|
|
310
|
+
id: Schema.String,
|
|
311
|
+
name: Schema.String,
|
|
312
|
+
version: Schema.String,
|
|
313
|
+
source: OptionalString,
|
|
314
|
+
entrypoint: OptionalString,
|
|
315
|
+
exportName: OptionalString,
|
|
316
|
+
createdAt: OptionalString
|
|
317
|
+
})
|
|
318
|
+
export type WorkflowManifestEntry = typeof WorkflowManifestEntry.Type
|
|
319
|
+
|
|
320
|
+
export const WorkflowManifest = Schema.Struct({
|
|
321
|
+
workflows: Schema.Array(WorkflowManifestEntry)
|
|
322
|
+
})
|
|
323
|
+
export type WorkflowManifest = typeof WorkflowManifest.Type
|
|
324
|
+
|
|
325
|
+
export const WorkflowRunRecord = Schema.Struct({
|
|
326
|
+
id: ExecutionId,
|
|
327
|
+
workflowId: Schema.String,
|
|
328
|
+
workflowVersion: Schema.String,
|
|
329
|
+
status: WorkflowRunStatus,
|
|
330
|
+
input: Schema.Unknown,
|
|
331
|
+
result: OptionalUnknown,
|
|
332
|
+
error: OptionalUnknown,
|
|
333
|
+
startedAt: Schema.String,
|
|
334
|
+
finishedAt: OptionalString
|
|
335
|
+
})
|
|
336
|
+
export type WorkflowRunRecord = typeof WorkflowRunRecord.Type
|
|
337
|
+
|
|
338
|
+
export const WorkflowRunEventRecord = Schema.Struct({
|
|
339
|
+
id: Schema.Number,
|
|
340
|
+
runId: ExecutionId,
|
|
341
|
+
sequence: Schema.Number,
|
|
342
|
+
type: Schema.String,
|
|
343
|
+
event: WorkflowHistoryEvent,
|
|
344
|
+
createdAt: Schema.String
|
|
345
|
+
})
|
|
346
|
+
export type WorkflowRunEventRecord = typeof WorkflowRunEventRecord.Type
|
|
347
|
+
|
|
348
|
+
export const WorkflowGraphNodeKind = Schema.Literals([
|
|
349
|
+
"step",
|
|
350
|
+
"sleep",
|
|
351
|
+
"signal",
|
|
352
|
+
"now",
|
|
353
|
+
"random",
|
|
354
|
+
"code",
|
|
355
|
+
"all",
|
|
356
|
+
"start",
|
|
357
|
+
"end",
|
|
358
|
+
"error"
|
|
359
|
+
])
|
|
360
|
+
export type WorkflowGraphNodeKind = typeof WorkflowGraphNodeKind.Type
|
|
361
|
+
|
|
362
|
+
export const WorkflowGraphSchemas = Schema.Struct({
|
|
363
|
+
input: Schema.optionalKey(JsonSchema),
|
|
364
|
+
output: Schema.optionalKey(JsonSchema),
|
|
365
|
+
errors: Schema.optionalKey(JsonSchema)
|
|
366
|
+
})
|
|
367
|
+
export type WorkflowGraphSchemas = typeof WorkflowGraphSchemas.Type
|
|
368
|
+
|
|
369
|
+
export const WorkflowGraphNodeSchemas = Schema.Struct({
|
|
370
|
+
input: Schema.optionalKey(JsonSchema),
|
|
371
|
+
output: Schema.optionalKey(JsonSchema),
|
|
372
|
+
errors: Schema.optionalKey(JsonSchema),
|
|
373
|
+
signal: Schema.optionalKey(JsonSchema)
|
|
374
|
+
})
|
|
375
|
+
export type WorkflowGraphNodeSchemas = typeof WorkflowGraphNodeSchemas.Type
|
|
376
|
+
|
|
377
|
+
export const WorkflowGraphNodeMetadata = Schema.Struct({
|
|
378
|
+
activityName: OptionalString,
|
|
379
|
+
input: OptionalUnknown,
|
|
380
|
+
duration: OptionalUnknown,
|
|
381
|
+
timeout: OptionalUnknown,
|
|
382
|
+
branches: Schema.optionalKey(Schema.Number),
|
|
383
|
+
reason: OptionalString,
|
|
384
|
+
retry: Schema.optionalKey(Schema.Struct({
|
|
385
|
+
attempts: Schema.Number,
|
|
386
|
+
backoff: Schema.Literals(["exponential", "none"])
|
|
387
|
+
})),
|
|
388
|
+
concurrency: Schema.optionalKey(Schema.Struct({
|
|
389
|
+
limit: Schema.Number,
|
|
390
|
+
keyed: Schema.Boolean
|
|
391
|
+
})),
|
|
392
|
+
compensates: Schema.optionalKey(Schema.Boolean)
|
|
393
|
+
})
|
|
394
|
+
export type WorkflowGraphNodeMetadata = typeof WorkflowGraphNodeMetadata.Type
|
|
395
|
+
|
|
396
|
+
export const WorkflowGraphNode = Schema.Struct({
|
|
397
|
+
id: Schema.String,
|
|
398
|
+
kind: WorkflowGraphNodeKind,
|
|
399
|
+
label: Schema.String,
|
|
400
|
+
invocation: Schema.optionalKey(Schema.Number),
|
|
401
|
+
repeated: Schema.Boolean,
|
|
402
|
+
description: OptionalString,
|
|
403
|
+
schemas: Schema.optionalKey(WorkflowGraphNodeSchemas),
|
|
404
|
+
metadata: WorkflowGraphNodeMetadata
|
|
405
|
+
})
|
|
406
|
+
export type WorkflowGraphNode = typeof WorkflowGraphNode.Type
|
|
407
|
+
|
|
408
|
+
export const WorkflowGraphEdge = Schema.Struct({
|
|
409
|
+
id: Schema.String,
|
|
410
|
+
source: Schema.String,
|
|
411
|
+
target: Schema.String,
|
|
412
|
+
label: OptionalString
|
|
413
|
+
})
|
|
414
|
+
export type WorkflowGraphEdge = typeof WorkflowGraphEdge.Type
|
|
415
|
+
|
|
416
|
+
export const WorkflowGraphCall = Schema.Struct({
|
|
417
|
+
kind: WorkflowGraphNodeKind,
|
|
418
|
+
name: Schema.String,
|
|
419
|
+
counter: Schema.Number,
|
|
420
|
+
branches: Schema.optionalKey(Schema.Number)
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
export const WorkflowGraph = Schema.Struct({
|
|
424
|
+
workflowName: Schema.String,
|
|
425
|
+
version: Schema.Number,
|
|
426
|
+
engineName: OptionalString,
|
|
427
|
+
sourceHash: OptionalString,
|
|
428
|
+
schemas: Schema.optionalKey(WorkflowGraphSchemas),
|
|
429
|
+
nodes: Schema.Array(WorkflowGraphNode),
|
|
430
|
+
edges: Schema.Array(WorkflowGraphEdge),
|
|
431
|
+
calls: Schema.Array(WorkflowGraphCall),
|
|
432
|
+
diagnostics: Schema.Array(Schema.String)
|
|
433
|
+
})
|
|
434
|
+
export type WorkflowGraph = typeof WorkflowGraph.Type
|
|
435
|
+
|
|
436
|
+
export const WorkflowArtifactGraph = Schema.Struct({
|
|
437
|
+
artifact: WorkflowArtifact,
|
|
438
|
+
exportName: OptionalString,
|
|
439
|
+
graph: Schema.optionalKey(WorkflowGraph),
|
|
440
|
+
diagnostics: Schema.Array(Schema.String)
|
|
441
|
+
})
|
|
442
|
+
export type WorkflowArtifactGraph = typeof WorkflowArtifactGraph.Type
|
|
443
|
+
|
|
444
|
+
export const WorkflowsResponse = Schema.Struct({
|
|
445
|
+
generatedAt: Schema.String,
|
|
446
|
+
workflows: Schema.Array(WorkflowArtifactGraph),
|
|
447
|
+
error: OptionalString
|
|
448
|
+
})
|
|
449
|
+
export type WorkflowsResponse = typeof WorkflowsResponse.Type
|
|
450
|
+
|
|
451
|
+
export const RunsResponse = Schema.Struct({
|
|
452
|
+
generatedAt: Schema.String,
|
|
453
|
+
runs: Schema.Array(WorkflowRunRecord),
|
|
454
|
+
error: OptionalString
|
|
455
|
+
})
|
|
456
|
+
export type RunsResponse = typeof RunsResponse.Type
|
|
457
|
+
|
|
458
|
+
export const RunEventsResponse = Schema.Struct({
|
|
459
|
+
generatedAt: Schema.String,
|
|
460
|
+
run: WorkflowRunRecord,
|
|
461
|
+
events: Schema.Array(WorkflowRunEventRecord),
|
|
462
|
+
error: OptionalString
|
|
463
|
+
})
|
|
464
|
+
export type RunEventsResponse = typeof RunEventsResponse.Type
|
|
465
|
+
|
|
466
|
+
export const decodeWorkflowsResponse = (value: unknown): WorkflowsResponse =>
|
|
467
|
+
Schema.decodeUnknownSync(WorkflowsResponse)(value)
|
|
468
|
+
|
|
469
|
+
export const decodeRunsResponse = (value: unknown): RunsResponse =>
|
|
470
|
+
Schema.decodeUnknownSync(RunsResponse)(value)
|
|
471
|
+
|
|
472
|
+
export const decodeRunEventsResponse = (value: unknown): RunEventsResponse =>
|
|
473
|
+
Schema.decodeUnknownSync(RunEventsResponse)(value)
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs"
|
|
2
|
+
import { readFile } from "node:fs/promises"
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
import { Schema } from "effect"
|
|
5
|
+
import {
|
|
6
|
+
WorkflowArtifact as WorkflowArtifactSchema,
|
|
7
|
+
WorkflowManifest,
|
|
8
|
+
WorkflowManifestEntry,
|
|
9
|
+
type WorkflowArtifact,
|
|
10
|
+
type WorkflowRunEventRecord,
|
|
11
|
+
type WorkflowRunRecord,
|
|
12
|
+
type WorkflowRunStatus
|
|
13
|
+
} from "../schemas.ts"
|
|
14
|
+
|
|
15
|
+
export type { WorkflowArtifact, WorkflowRunEventRecord, WorkflowRunRecord, WorkflowRunStatus }
|
|
16
|
+
|
|
17
|
+
export interface WorkflowStore {
|
|
18
|
+
list(): Promise<ReadonlyArray<WorkflowArtifact>>
|
|
19
|
+
get(id: string): Promise<WorkflowArtifact | undefined>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface WorkflowRunStore {
|
|
23
|
+
getRun(id: string): Promise<WorkflowRunRecord | undefined>
|
|
24
|
+
startRun(options: {
|
|
25
|
+
readonly id: string
|
|
26
|
+
readonly workflow: WorkflowArtifact
|
|
27
|
+
readonly input: unknown
|
|
28
|
+
}): Promise<WorkflowRunRecord>
|
|
29
|
+
appendRunEvent(options: {
|
|
30
|
+
readonly runId: string
|
|
31
|
+
readonly type: string
|
|
32
|
+
readonly event: unknown
|
|
33
|
+
}): Promise<void>
|
|
34
|
+
completeRun(options: {
|
|
35
|
+
readonly runId: string
|
|
36
|
+
readonly result: unknown
|
|
37
|
+
}): Promise<void>
|
|
38
|
+
failRun(options: {
|
|
39
|
+
readonly runId: string
|
|
40
|
+
readonly error: unknown
|
|
41
|
+
}): Promise<void>
|
|
42
|
+
listRuns(): Promise<ReadonlyArray<WorkflowRunRecord>>
|
|
43
|
+
listRunEvents(runId: string): Promise<ReadonlyArray<WorkflowRunEventRecord>>
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface WorkflowRepository extends WorkflowStore, WorkflowRunStore {
|
|
47
|
+
upsertWorkflow(workflow: WorkflowArtifact): Promise<void>
|
|
48
|
+
/** Remove every catalog row for a workflow id (all names/versions). */
|
|
49
|
+
deleteWorkflow(id: string): Promise<void>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface FileWorkflowStoreOptions {
|
|
53
|
+
readonly rootDir?: string
|
|
54
|
+
readonly manifestPath?: string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const defaultManifestPath = (rootDir: string) => path.join(rootDir, ".wf", "workflows.json")
|
|
58
|
+
|
|
59
|
+
interface NormalizedWorkflowManifest {
|
|
60
|
+
readonly workflows: ReadonlyArray<WorkflowArtifact>
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const readManifest = async (rootDir: string, manifestPath: string): Promise<NormalizedWorkflowManifest> => {
|
|
64
|
+
let raw: string
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
raw = await readFile(manifestPath, "utf8")
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
70
|
+
return { workflows: [] }
|
|
71
|
+
}
|
|
72
|
+
throw error
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const parsed: unknown = JSON.parse(raw)
|
|
76
|
+
const manifest = Schema.decodeUnknownSync(WorkflowManifest)(parsed)
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
workflows: manifest.workflows.map((workflow, index) =>
|
|
80
|
+
normalizeArtifact(rootDir, workflow, `workflow manifest entry ${index}`)
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const requiredString = (
|
|
86
|
+
value: WorkflowManifestEntry,
|
|
87
|
+
key: "id" | "name" | "version",
|
|
88
|
+
label: string
|
|
89
|
+
): string => {
|
|
90
|
+
const field = value[key]
|
|
91
|
+
if (typeof field !== "string" || field.length === 0) {
|
|
92
|
+
throw new Error(`${label}.${key} must be a non-empty string`)
|
|
93
|
+
}
|
|
94
|
+
return field
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const nonEmptyOptionalString = (
|
|
98
|
+
field: string | undefined,
|
|
99
|
+
key: keyof WorkflowManifestEntry,
|
|
100
|
+
label: string
|
|
101
|
+
): string | undefined => {
|
|
102
|
+
if (field === undefined) {
|
|
103
|
+
return undefined
|
|
104
|
+
}
|
|
105
|
+
if (typeof field !== "string" || field.length === 0) {
|
|
106
|
+
throw new Error(`${label}.${key} must be a non-empty string when present`)
|
|
107
|
+
}
|
|
108
|
+
return field
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const normalizeArtifact = (rootDir: string, value: unknown, label: string): WorkflowArtifact => {
|
|
112
|
+
const artifact = Schema.decodeUnknownSync(WorkflowManifestEntry)(value)
|
|
113
|
+
const source = nonEmptyOptionalString(artifact.source, "source", label)
|
|
114
|
+
const entrypoint = nonEmptyOptionalString(artifact.entrypoint, "entrypoint", label)
|
|
115
|
+
const exportName = nonEmptyOptionalString(artifact.exportName, "exportName", label)
|
|
116
|
+
const createdAt = nonEmptyOptionalString(artifact.createdAt, "createdAt", label)
|
|
117
|
+
|
|
118
|
+
return Schema.decodeUnknownSync(WorkflowArtifactSchema)({
|
|
119
|
+
id: requiredString(artifact, "id", label),
|
|
120
|
+
name: requiredString(artifact, "name", label),
|
|
121
|
+
version: requiredString(artifact, "version", label),
|
|
122
|
+
source: source ?? readLegacySource(rootDir, entrypoint, label),
|
|
123
|
+
...(exportName === undefined ? {} : { exportName }),
|
|
124
|
+
...(createdAt === undefined ? {} : { createdAt })
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const readLegacySource = (rootDir: string, entrypoint: string | undefined, label: string): string => {
|
|
129
|
+
if (entrypoint === undefined) {
|
|
130
|
+
throw new Error(`${label}.source must be a non-empty string`)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const sourcePath = path.isAbsolute(entrypoint)
|
|
134
|
+
? entrypoint
|
|
135
|
+
: path.resolve(rootDir, entrypoint)
|
|
136
|
+
try {
|
|
137
|
+
return readFileSync(sourcePath, "utf8")
|
|
138
|
+
} catch (error) {
|
|
139
|
+
throw new Error(`${label}.entrypoint could not be read: ${(error as Error).message}`)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const createFileWorkflowStore = (
|
|
144
|
+
options: FileWorkflowStoreOptions = {}
|
|
145
|
+
): WorkflowStore => {
|
|
146
|
+
const rootDir = path.resolve(options.rootDir ?? process.cwd())
|
|
147
|
+
const manifestPath = path.resolve(options.manifestPath ?? defaultManifestPath(rootDir))
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
async list() {
|
|
151
|
+
const manifest = await readManifest(rootDir, manifestPath)
|
|
152
|
+
return manifest.workflows
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
async get(id) {
|
|
156
|
+
const workflows = await this.list()
|
|
157
|
+
return workflows.find((workflow) => workflow.id === id)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const createMemoryWorkflowStore = (
|
|
163
|
+
workflows: ReadonlyArray<WorkflowArtifact>
|
|
164
|
+
): WorkflowStore => {
|
|
165
|
+
const artifacts = workflows.map((workflow) => ({ ...workflow }))
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
async list() {
|
|
169
|
+
return artifacts
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
async get(id) {
|
|
173
|
+
return artifacts.find((workflow) => workflow.id === id)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|