@voltro/workflow 0.25.0 → 0.27.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.
@@ -1,11 +1,11 @@
1
- import { C as e, S as t, b as n, x as r } from "./primitives-CWy1iu5w.js";
1
+ import { C as e, S as t, b as n, x as r } from "./primitives-Dgu3O55Q.js";
2
2
  import { Activity as i, DurableClock as a, DurableDeferred as o, Workflow as s, WorkflowEngine as c } from "@effect/workflow";
3
3
  import { Cause as l, Effect as u, Exit as d, FiberRef as f, Layer as p, Schema as m } from "effect";
4
4
  import { and as h, boolean as g, eq as _, id as v, integer as y, json as b, or as x, queryFor as S, reference as C, table as w, text as T, timestamp as E } from "@voltro/database";
5
5
  import { WorkflowInstance as ee } from "@effect/workflow/WorkflowEngine";
6
- import { publishServerError as te } from "@voltro/protocol";
6
+ import { publishServerError as D } from "@voltro/protocol";
7
7
  //#region src/inMemoryLayer.ts
8
- var D = c.layerMemory, O = w("_voltro_workflow_runs", {
8
+ var O = c.layerMemory, k = w("_voltro_workflow_runs", {
9
9
  id: v({ prefix: "wfrun" }),
10
10
  tag: T(),
11
11
  executionId: T().unique(),
@@ -25,6 +25,8 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
25
25
  errorTag: T().nullable(),
26
26
  errorMessage: T().nullable(),
27
27
  cancelled: g().default(!1),
28
+ discardedAt: E().nullable(),
29
+ discardedBy: T().nullable(),
28
30
  startedAt: E().default("now"),
29
31
  completedAt: E().nullable(),
30
32
  durationMs: y().nullable(),
@@ -35,9 +37,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
35
37
  "terminate",
36
38
  "abandon"
37
39
  ]).nullable()
38
- }).index(["tag"]).index(["status"]).index(["source"]).index(["startedAt"]).index(["parentExecutionId"]).index(["parentClosePolicy"]), k = w("_voltro_workflow_run_steps", {
40
+ }).index(["tag"]).index(["status"]).index(["source"]).index(["startedAt"]).index(["parentExecutionId"]).index(["parentClosePolicy"]), A = w("_voltro_workflow_run_steps", {
39
41
  id: v({ prefix: "wfstep" }),
40
- runId: C(() => O, {
42
+ runId: C(() => k, {
41
43
  index: !1,
42
44
  onDelete: "cascade"
43
45
  }),
@@ -57,9 +59,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
57
59
  startedAt: E().default("now"),
58
60
  completedAt: E().nullable(),
59
61
  durationMs: y().nullable()
60
- }).index(["runId", "stepName"]).index(["startedAt"]), A = w("_voltro_workflow_run_events", {
62
+ }).index(["runId", "stepName"]).index(["startedAt"]), j = w("_voltro_workflow_run_events", {
61
63
  id: v({ prefix: "wfev" }),
62
- runId: C(() => O, {
64
+ runId: C(() => k, {
63
65
  index: !1,
64
66
  onDelete: "cascade"
65
67
  }),
@@ -68,7 +70,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
68
70
  occurredAt: E().default("now"),
69
71
  stepName: T().nullable(),
70
72
  attempt: y().nullable()
71
- }).index(["runId", "occurredAt"]).index(["eventType"]), j = w("_voltro_workflow_start_contexts", {
73
+ }).index(["runId", "occurredAt"]).index(["eventType"]), M = w("_voltro_workflow_start_contexts", {
72
74
  id: v({ prefix: "wfctx" }),
73
75
  workflowName: T(),
74
76
  executionId: T().unique(),
@@ -82,16 +84,16 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
82
84
  "abandon"
83
85
  ]).nullable(),
84
86
  createdAt: E().default("now")
85
- }).index(["workflowName"]).index(["executionId"]).index(["parentExecutionId"]), M = async (e, t) => {
87
+ }).index(["workflowName"]).index(["executionId"]).index(["parentExecutionId"]), N = async (e, t) => {
86
88
  if (e) try {
87
89
  await e.recordEvent(t);
88
90
  } catch {}
89
- }, N = (t, n) => {
91
+ }, P = (t, n) => {
90
92
  let a = u.gen(function* () {
91
93
  let i = n.pollIntervalMs ?? 200, a = n.maxPollIntervalMs ?? 5e3, o = n.timeoutMs ?? 1440 * 6e4, s = yield* r, c = yield* u.serviceOption(e), l = c._tag === "Some" ? c.value : void 0;
92
94
  if (s === void 0) return yield* u.die(/* @__PURE__ */ Error("awaitSignal: no active workflow run id in scope"));
93
95
  let d = s;
94
- yield* u.promise(() => M(l, {
96
+ yield* u.promise(() => N(l, {
95
97
  runId: d,
96
98
  eventType: "signal-awaited",
97
99
  payload: { signalName: n.name }
@@ -116,7 +118,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
116
118
  })).find((e) => e.payload?.signalName === n.name);
117
119
  if (i !== void 0) {
118
120
  let e = yield* m.decodeUnknown(n.schema)(i.payload?.value);
119
- return yield* u.promise(() => M(l, {
121
+ return yield* u.promise(() => N(l, {
120
122
  runId: d,
121
123
  eventType: "signal-received",
122
124
  payload: {
@@ -133,7 +135,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
133
135
  success: n.schema,
134
136
  execute: a
135
137
  });
136
- }, P = (e) => new Promise((t) => setTimeout(t, e)), ne = () => {
138
+ }, te = (e) => new Promise((t) => setTimeout(t, e)), ne = () => {
137
139
  let e = globalThis.crypto;
138
140
  return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
139
141
  }, F = () => `wfu_${ne()}`, I = async (e, t) => {
@@ -206,15 +208,15 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
206
208
  }), t;
207
209
  }
208
210
  if (Date.now() - i >= a) throw Error(`Timed out waiting for workflow update '${e.updateName}' (${n})`);
209
- await P(o);
211
+ await te(o);
210
212
  }
211
- }, L = 1440 * 6e4, R = "voltro/suspending-signal", z = (e, t) => `${R}/${e}/${t}`, B = (e) => o.make(e, { success: m.Unknown }), V = async (e, t) => {
213
+ }, ae = 1440 * 6e4, L = "voltro/suspending-signal", R = (e, t) => `${L}/${e}/${t}`, z = (e) => o.make(e, { success: m.Unknown }), B = async (e, t) => {
212
214
  if (e) try {
213
215
  await e.recordEvent(t);
214
216
  } catch {}
215
- }, H = (t, n) => u.gen(function* () {
216
- let t = n.timeoutMs ?? L, i = B(z((yield* c.WorkflowInstance).workflow.name, n.name)), s = yield* r, l = yield* u.serviceOption(e), d = l._tag === "Some" ? l.value : void 0;
217
- s !== void 0 && (yield* u.promise(() => V(d, {
217
+ }, oe = (t, n) => u.gen(function* () {
218
+ let t = n.timeoutMs ?? ae, i = z(R((yield* c.WorkflowInstance).workflow.name, n.name)), s = yield* r, l = yield* u.serviceOption(e), d = l._tag === "Some" ? l.value : void 0;
219
+ s !== void 0 && (yield* u.promise(() => B(d, {
218
220
  runId: s,
219
221
  eventType: "signal-awaited",
220
222
  payload: { signalName: n.name }
@@ -223,7 +225,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
223
225
  name: `await-signal-timeout/${n.name}`,
224
226
  duration: `${t} millis`
225
227
  }).pipe(u.andThen(u.die(/* @__PURE__ */ Error(`awaitSignalSuspending('${n.name}') timed out after ${t}ms`))))) : yield* f, h = yield* m.decodeUnknown(n.schema)(p);
226
- return s !== void 0 && (yield* u.promise(() => V(d, {
228
+ return s !== void 0 && (yield* u.promise(() => B(d, {
227
229
  runId: s,
228
230
  eventType: "signal-received",
229
231
  payload: {
@@ -231,7 +233,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
231
233
  value: h
232
234
  }
233
235
  }))), h;
234
- }), U = (e) => u.gen(function* () {
236
+ }), se = (e) => u.gen(function* () {
235
237
  let t = e.target.executionId, n = e.target.workflowName;
236
238
  if (t === void 0 || n === void 0) {
237
239
  let r = e.store;
@@ -243,7 +245,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
243
245
  t ??= i.executionId, n ??= i.tag;
244
246
  }
245
247
  if (t === void 0 || n === void 0) return { completed: !1 };
246
- let r = z(n, e.signalName), i = B(r), a = new o.TokenParsed({
248
+ let r = R(n, e.signalName), i = z(r), a = new o.TokenParsed({
247
249
  workflowName: n,
248
250
  executionId: t,
249
251
  deferredName: r
@@ -252,17 +254,17 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
252
254
  token: a,
253
255
  exit: d.succeed(e.payload)
254
256
  }), { completed: !0 };
255
- }), W = async (e, t) => {
257
+ }), V = async (e, t) => {
256
258
  if (e) try {
257
259
  await e.recordEvent(t);
258
260
  } catch {}
259
- }, G = (e) => {
261
+ }, H = (e) => {
260
262
  let t = l.failureOption(e), n = Array.from(l.defects(e)), r = t._tag === "Some" ? t.value : n[0] ?? l.squash(e);
261
263
  return {
262
264
  errorTag: r && typeof r == "object" && "_tag" in r ? String(r._tag) : null,
263
265
  errorMessage: r?.message ?? String(r)
264
266
  };
265
- }, ae = (t, n) => {
267
+ }, U = (t, n) => {
266
268
  let a = u.gen(function* () {
267
269
  let i = n.pollIntervalMs ?? 200, a = n.maxPollIntervalMs ?? 5e3, o = n.timeoutMs ?? 3e4, s = yield* r, c = yield* u.serviceOption(e), l = c._tag === "Some" ? c.value : void 0;
268
270
  if (s === void 0) return yield* u.die(/* @__PURE__ */ Error("awaitUpdate: no active workflow run id in scope"));
@@ -286,7 +288,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
286
288
  }), s = new Set(i.filter((e) => e.eventType === "update-completed" || e.eventType === "update-failed").map((e) => e.payload?.updateId).filter((e) => typeof e == "string" && e.length > 0)), c = i.find((e) => e.eventType === "update-requested" && e.payload?.updateName === n.name && typeof e.payload.updateId == "string" && !s.has(e.payload.updateId));
287
289
  if (c !== void 0) {
288
290
  let e = c.payload.updateId;
289
- yield* u.promise(() => W(l, {
291
+ yield* u.promise(() => V(l, {
290
292
  runId: d,
291
293
  eventType: "update-received",
292
294
  payload: {
@@ -294,24 +296,24 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
294
296
  updateName: n.name
295
297
  }
296
298
  }));
297
- let t = yield* m.decodeUnknown(n.schema)(c.payload?.value).pipe(u.tapErrorCause((t) => u.promise(() => W(l, {
299
+ let t = yield* m.decodeUnknown(n.schema)(c.payload?.value).pipe(u.tapErrorCause((t) => u.promise(() => V(l, {
298
300
  runId: d,
299
301
  eventType: "update-failed",
300
302
  payload: {
301
303
  updateId: e,
302
304
  updateName: n.name,
303
- ...G(t)
305
+ ...H(t)
304
306
  }
305
- })))), r = yield* (n.handle ? n.handle(t) : u.succeed(t)).pipe(u.flatMap((e) => n.success ? m.decodeUnknown(n.success)(e) : u.succeed(e))).pipe(u.tapErrorCause((t) => u.promise(() => W(l, {
307
+ })))), r = yield* (n.handle ? n.handle(t) : u.succeed(t)).pipe(u.flatMap((e) => n.success ? m.decodeUnknown(n.success)(e) : u.succeed(e))).pipe(u.tapErrorCause((t) => u.promise(() => V(l, {
306
308
  runId: d,
307
309
  eventType: "update-failed",
308
310
  payload: {
309
311
  updateId: e,
310
312
  updateName: n.name,
311
- ...G(t)
313
+ ...H(t)
312
314
  }
313
315
  }))));
314
- return yield* u.promise(() => W(l, {
316
+ return yield* u.promise(() => V(l, {
315
317
  runId: d,
316
318
  eventType: "update-completed",
317
319
  payload: {
@@ -329,10 +331,10 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
329
331
  success: n.success ?? n.schema,
330
332
  execute: a
331
333
  });
332
- }, K = 8 * 1024, oe = () => {
334
+ }, W = 8 * 1024, G = () => {
333
335
  let e = globalThis.crypto;
334
336
  return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
335
- }, q = (e) => `${e}_${oe()}`, J = (e, t = K) => {
337
+ }, K = (e) => `${e}_${G()}`, q = (e, t = W) => {
336
338
  if (e == null) return e;
337
339
  try {
338
340
  let n = JSON.stringify(e);
@@ -344,12 +346,12 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
344
346
  } catch {
345
347
  return { __unserialisable: String(e) };
346
348
  }
347
- }, Y = (e) => {
349
+ }, J = (e) => {
348
350
  let t = {};
349
351
  for (let [n, r] of Object.entries(e)) t[n] = r instanceof Date ? r.toISOString() : r;
350
352
  return t;
351
- }, X = (e) => {
352
- let t = e.truncateBytes ?? K, n = e.makeId ?? q, r = (t, n) => e.log?.warn(t, n), i = e.emit;
353
+ }, Y = (e) => {
354
+ let t = e.truncateBytes ?? W, n = e.makeId ?? K, r = (t, n) => e.log?.warn(t, n), i = e.emit;
353
355
  return {
354
356
  startStep: async ({ runId: a, stepName: o, attempt: s, stepInput: c, retryPolicy: l }) => {
355
357
  try {
@@ -359,7 +361,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
359
361
  stepName: o,
360
362
  attempt: s,
361
363
  status: "running",
362
- input: c === void 0 ? null : J(c, t),
364
+ input: c === void 0 ? null : q(c, t),
363
365
  retryPolicy: l ?? null,
364
366
  output: null,
365
367
  errorTag: null,
@@ -370,7 +372,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
370
372
  });
371
373
  return i?.("workflowSteps", {
372
374
  op: "insert",
373
- row: Y(r)
375
+ row: J(r)
374
376
  }), r.id;
375
377
  } catch (e) {
376
378
  r("failed to record step start (continuing)", {
@@ -386,13 +388,13 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
386
388
  try {
387
389
  let r = await e.store.update("_voltro_workflow_run_steps", n, {
388
390
  status: "succeeded",
389
- output: J(a, t),
391
+ output: q(a, t),
390
392
  completedAt: /* @__PURE__ */ new Date(),
391
393
  durationMs: o
392
394
  });
393
395
  r && i?.("workflowSteps", {
394
396
  op: "update",
395
- row: Y(r)
397
+ row: J(r)
396
398
  });
397
399
  } catch (e) {
398
400
  r("failed to record step success", {
@@ -407,13 +409,13 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
407
409
  status: "failed",
408
410
  errorTag: a,
409
411
  errorMessage: o,
410
- errorCause: s === void 0 ? null : J(s, t),
412
+ errorCause: s === void 0 ? null : q(s, t),
411
413
  completedAt: /* @__PURE__ */ new Date(),
412
414
  durationMs: c
413
415
  });
414
416
  r && i?.("workflowSteps", {
415
417
  op: "update",
416
- row: Y(r)
418
+ row: J(r)
417
419
  });
418
420
  } catch (e) {
419
421
  r("failed to record step failure", {
@@ -436,7 +438,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
436
438
  });
437
439
  i?.("workflowEvents", {
438
440
  op: "insert",
439
- row: Y(n)
441
+ row: J(n)
440
442
  });
441
443
  } catch (e) {
442
444
  r("failed to record workflow event (continuing)", {
@@ -452,8 +454,8 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
452
454
  return { id: l };
453
455
  }
454
456
  };
455
- }, se = (i, a) => {
456
- let o = i.truncateBytes ?? K, c = i.makeId ?? q, p = i.recorder ?? X(i), m = (e, t) => i.log?.warn(e, t), h = i.emit, g = (e, t, n) => u.promise(async () => {
457
+ }, ce = (i, a) => {
458
+ let o = i.truncateBytes ?? W, c = i.makeId ?? K, p = i.recorder ?? Y(i), m = (e, t) => i.log?.warn(e, t), h = i.emit, g = (e, t, n) => u.promise(async () => {
457
459
  if (i.onParentClose) try {
458
460
  await i.onParentClose({
459
461
  workflowName: i.name,
@@ -485,9 +487,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
485
487
  projection: void 0,
486
488
  skip: void 0,
487
489
  take: 1
488
- })) : [])[0], D = E?.workflowVersion ?? null;
489
- if (E?.id !== void 0 && D !== null && i.workflowCompatibleVersions !== void 0 && i.workflowCompatibleVersions !== null && !i.workflowCompatibleVersions.includes(D)) {
490
- let e = `Workflow '${i.name}' run '${y}' was started on version ${D}, but current code is compatible with ${i.workflowCompatibleVersions.join(", ")}`, t = yield* u.promise(() => i.store.update("_voltro_workflow_runs", E.id, {
490
+ })) : [])[0], O = E?.workflowVersion ?? null;
491
+ if (E?.id !== void 0 && O !== null && i.workflowCompatibleVersions !== void 0 && i.workflowCompatibleVersions !== null && !i.workflowCompatibleVersions.includes(O)) {
492
+ let e = `Workflow '${i.name}' run '${y}' was started on version ${O}, but current code is compatible with ${i.workflowCompatibleVersions.join(", ")}`, t = yield* u.promise(() => i.store.update("_voltro_workflow_runs", E.id, {
491
493
  status: "failed",
492
494
  errorTag: "WorkflowVersionIncompatible",
493
495
  errorMessage: e,
@@ -495,7 +497,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
495
497
  }));
496
498
  return t && h?.("workflowRuns", {
497
499
  op: "update",
498
- row: Y(t)
500
+ row: J(t)
499
501
  }), yield* u.promise(() => p.recordEvent({
500
502
  runId: E.id,
501
503
  eventType: "run-failed",
@@ -504,7 +506,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
504
506
  errorMessage: e,
505
507
  workflowVersion: i.workflowVersion ?? null,
506
508
  compatibleWith: i.workflowCompatibleVersions,
507
- previousVersion: D
509
+ previousVersion: O
508
510
  }
509
511
  })), yield* u.sync(() => i.recordRun?.({
510
512
  name: i.name,
@@ -536,7 +538,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
536
538
  }));
537
539
  if (w = e.id, h?.("workflowRuns", {
538
540
  op: "insert",
539
- row: Y(e)
541
+ row: J(e)
540
542
  }), w) {
541
543
  let e = w;
542
544
  yield* u.promise(() => p.recordEvent({
@@ -554,26 +556,48 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
554
556
  }));
555
557
  }
556
558
  }));
557
- let O = i.subject?.tenantId, k = a(v, y).pipe(u.locally(r, w), u.locally(n, y), u.locally(t, typeof O == "string" ? O : void 0), u.provideService(e, p)), A = i.pluginWorkflowStepLayer ? k.pipe(u.provide(i.pluginWorkflowStepLayer)) : k, j = yield* s.intoResult(A);
558
- if (s.isResult(j) && j._tag === "Suspended") {
559
- w && (yield* T("failed to record workflow suspend", u.gen(function* () {
560
- let e = yield* u.promise(() => i.store.update("_voltro_workflow_runs", w, { status: "suspended" }));
559
+ let k = i.subject?.tenantId, A = a(v, y).pipe(u.locally(r, w), u.locally(n, y), u.locally(t, typeof k == "string" ? k : void 0), u.provideService(e, p)), j = i.pluginWorkflowStepLayer ? A.pipe(u.provide(i.pluginWorkflowStepLayer)) : A, M = yield* s.intoResult(j);
560
+ if (s.isResult(M) && M._tag === "Suspended") {
561
+ let e = M.cause, t = e !== void 0 && !l.isEmpty(e), n = t ? l.squash(e) : void 0, r = n && typeof n == "object" && "_tag" in n ? String(n._tag) : null, a = t ? n?.message ?? String(n) : null;
562
+ t && (yield* u.sync(() => D({
563
+ error: n,
564
+ source: "workflow",
565
+ name: i.name,
566
+ ...i.traceId ? { traceId: i.traceId } : {},
567
+ fields: {
568
+ executionId: y,
569
+ suspendedOnFailure: !0,
570
+ ...r ? { errorTag: r } : {},
571
+ ...w ? { runId: w } : {}
572
+ }
573
+ }))), w && (yield* T("failed to record workflow suspend", u.gen(function* () {
574
+ let e = yield* u.promise(() => i.store.update("_voltro_workflow_runs", w, {
575
+ status: "suspended",
576
+ ...t ? {
577
+ errorTag: r,
578
+ errorMessage: a
579
+ } : {}
580
+ }));
561
581
  e && h?.("workflowRuns", {
562
582
  op: "update",
563
- row: Y(e)
583
+ row: J(e)
564
584
  }), yield* u.promise(() => p.recordEvent({
565
585
  runId: w,
566
586
  eventType: "run-suspended",
567
- payload: { reason: "workflow-suspend" }
587
+ payload: t ? {
588
+ reason: "suspend-on-failure",
589
+ errorTag: r,
590
+ errorMessage: a
591
+ } : { reason: "workflow-suspend" }
568
592
  }));
569
593
  })));
570
- let e = yield* ee;
571
- return yield* s.suspend(e);
594
+ let o = yield* ee;
595
+ return yield* s.suspend(o);
572
596
  }
573
- let M = j;
574
- if (d.isFailure(M.exit)) {
575
- let e = M.exit.cause, t = l.failureOption(e), n = t._tag === "Some" ? t.value : l.squash(e), r = n && typeof n == "object" && "_tag" in n ? String(n._tag) : null, a = n?.message ?? String(n);
576
- return yield* u.sync(() => te({
597
+ let N = M;
598
+ if (d.isFailure(N.exit)) {
599
+ let e = N.exit.cause, t = l.failureOption(e), n = t._tag === "Some" ? t.value : l.squash(e), r = n && typeof n == "object" && "_tag" in n ? String(n._tag) : null, a = n?.message ?? String(n);
600
+ return yield* u.sync(() => D({
577
601
  error: n,
578
602
  source: "workflow",
579
603
  name: i.name,
@@ -593,7 +617,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
593
617
  }));
594
618
  e && h?.("workflowRuns", {
595
619
  op: "update",
596
- row: Y(e)
620
+ row: J(e)
597
621
  }), yield* u.promise(() => p.recordEvent({
598
622
  runId: w,
599
623
  eventType: "run-failed",
@@ -609,17 +633,17 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
609
633
  durationMs: Date.now() - b
610
634
  })), yield* u.failCause(e);
611
635
  }
612
- let N = M.exit.value;
636
+ let P = N.exit.value;
613
637
  return w && (yield* T("failed to record workflow success", u.gen(function* () {
614
638
  let e = yield* u.promise(() => i.store.update("_voltro_workflow_runs", w, {
615
639
  status: "succeeded",
616
- output: J(N, o),
640
+ output: q(P, o),
617
641
  completedAt: /* @__PURE__ */ new Date(),
618
642
  durationMs: Date.now() - b
619
643
  }));
620
644
  e && h?.("workflowRuns", {
621
645
  op: "update",
622
- row: Y(e)
646
+ row: J(e)
623
647
  }), yield* u.promise(() => p.recordEvent({
624
648
  runId: w,
625
649
  eventType: "run-succeeded",
@@ -630,9 +654,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
630
654
  status: "succeeded",
631
655
  durationMs: Date.now() - b,
632
656
  completedAtSec: Date.now() / 1e3
633
- })), N;
657
+ })), P;
634
658
  });
635
- }, ce = (e) => e === "cancel" || e === "terminate", le = (e) => e === "running" || e === "suspended", ue = async (e) => {
659
+ }, X = (e) => e === "cancel" || e === "terminate", le = (e) => e === "running" || e === "suspended", ue = async (e) => {
636
660
  let t = await e.store.query({
637
661
  table: "_voltro_workflow_runs",
638
662
  order: [{
@@ -658,7 +682,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
658
682
  });
659
683
  continue;
660
684
  }
661
- if (!ce(r.parentClosePolicy)) {
685
+ if (!X(r.parentClosePolicy)) {
662
686
  n.push({
663
687
  ...t,
664
688
  action: "skipped",
@@ -683,7 +707,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
683
707
  });
684
708
  i && e.emit?.("workflowRuns", {
685
709
  op: "update",
686
- row: Y(i)
710
+ row: J(i)
687
711
  }), await e.recorder?.recordEvent({
688
712
  runId: r.id,
689
713
  eventType: "run-cancelled",
@@ -759,9 +783,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
759
783
  }
760
784
  return typeof e == "object" ? e : null;
761
785
  }, pe = async (e, t) => {
762
- let n = S(O), r = (await t.query(n.where(x(_("id", e), _("executionId", e))).limit(1).descriptor))[0];
786
+ let n = S(k), r = (await t.query(n.where(x(_("id", e), _("executionId", e))).limit(1).descriptor))[0];
763
787
  if (r === void 0) return null;
764
- let i = String(r.id), a = S(k), o = await t.query(a.where(_("runId", i)).descriptor);
788
+ let i = String(r.id), a = S(A), o = await t.query(a.where(_("runId", i)).descriptor);
765
789
  return {
766
790
  id: i,
767
791
  executionId: $(r.executionId) ?? "",
@@ -827,4 +851,4 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
827
851
  };
828
852
  };
829
853
  //#endregion
830
- export { j as _, Y as a, O as b, ae as c, z as d, F as f, N as g, ie as h, X as i, H as l, re as m, pe as n, J as o, I as p, ue as r, se as s, me as t, U as u, A as v, D as x, k as y };
854
+ export { M as _, J as a, k as b, U as c, R as d, F as f, P as g, ie as h, Y as i, oe as l, re as m, pe as n, q as o, I as p, ue as r, ce as s, me as t, se as u, j as v, O as x, A as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/workflow",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "description": "Durable workflows for Voltro — the workflow() descriptor + step() / awaitSignal primitives over @effect/cluster, with a browser-safe define subpath.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -50,8 +50,8 @@
50
50
  "@effect/cluster": "^0.60.0",
51
51
  "@effect/sql": "^0.52.0",
52
52
  "@effect/workflow": "^0.19.0",
53
- "@voltro/database": "0.25.0",
54
- "@voltro/protocol": "0.25.0"
53
+ "@voltro/database": "0.27.0",
54
+ "@voltro/protocol": "0.27.0"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "effect": "^3.22.0",
@@ -1,58 +0,0 @@
1
- import { Duration as e, Effect as t, Layer as n, Option as r } from "effect";
2
- import { ClusterCron as i, ClusterWorkflowEngine as a, RunnerAddress as o, SingleRunner as s } from "@effect/cluster";
3
- import { SqlClient as c } from "@effect/sql";
4
- //#region src/clusterLayer.ts
5
- var l = 34e3, u = (e) => {
6
- let t = e.runnerListenHost ?? process.env.POD_IP ?? process.env.VOLTRO_WORKFLOW_RUNNER_HOST ?? "localhost";
7
- return {
8
- host: t,
9
- port: e.runnerListenPort ?? 34e3,
10
- localhostRisk: e.runnerStorage === "sql" && (t === "localhost" || t === "127.0.0.1")
11
- };
12
- }, d = (e) => {
13
- let t = e.sqliteFamily ? "memory" : "sql", n = e.override ?? process.env.VOLTRO_WORKFLOW_RUNNER_STORAGE;
14
- if (n === void 0 || n.trim() === "") return t;
15
- let r = n.trim().toLowerCase();
16
- if (r !== "memory" && r !== "sql") throw Error(`VOLTRO_WORKFLOW_RUNNER_STORAGE must be 'memory' or 'sql', got '${n}'.`);
17
- if (r === "sql" && e.sqliteFamily) throw Error("VOLTRO_WORKFLOW_RUNNER_STORAGE='sql' is unsupported on sqlite / turso — @effect/cluster has no sqlite advisory-lock branch. Use 'memory'.");
18
- return r;
19
- }, f = (e = process.env.VOLTRO_WORKFLOW_SHARD_LOCK) => {
20
- if (e === void 0 || e.trim() === "") return "auto";
21
- let t = e.trim().toLowerCase();
22
- if (t === "auto" || t === "row" || t === "advisory") return t;
23
- throw Error(`VOLTRO_WORKFLOW_SHARD_LOCK must be 'auto', 'row', or 'advisory', got '${e}'.`);
24
- }, p = t.gen(function* () {
25
- let e = yield* (yield* c.SqlClient)`SELECT @@wsrep_on AS wsrep`.pipe(t.catchAll(() => t.succeed([])));
26
- if (e.length === 0) return !1;
27
- let n = e[0].wsrep;
28
- return n === 1 || n === "1" || n === !0 || n === "ON" || n === "on";
29
- }), m = (e) => t.gen(function* () {
30
- return e.runnerStorage === "memory" ? !1 : e.mode === "row" ? !0 : e.mode === "advisory" || e.dialectId !== "mysql" && e.dialectId !== "mariadb" ? !1 : yield* p;
31
- }), h = (e) => {
32
- let i = u({
33
- runnerStorage: e.runnerStorage,
34
- runnerListenHost: e.runnerListenHost,
35
- runnerListenPort: e.runnerListenPort
36
- }), c = i.host, l = i.port;
37
- i.localhostRisk && process.stderr.write(`[voltro:workflow] runner host is '${c}' with SQL cluster storage — other pods cannot reach this runner, so a workflow cannot resume on another pod after a reschedule. Inject POD_IP via the K8s downward API (fieldRef: status.podIP) or set runnerListenHost / VOLTRO_WORKFLOW_RUNNER_HOST.
38
- `);
39
- let d = e.shardLockMode ?? f(), p = n.unwrapEffect(m({
40
- dialectId: e.dialectId,
41
- runnerStorage: e.runnerStorage,
42
- mode: d
43
- }).pipe(t.map((t) => (e.runnerStorage === "sql" && process.stderr.write(`[voltro:workflow] shard-lock coordination: ${t ? "row-based" : "advisory"} (dialect=${e.dialectId ?? "unknown"}, mode=${d}` + (t && d === "auto" ? ", wsrep/Galera cluster detected" : "") + ")\n"), s.layer({
44
- runnerStorage: e.runnerStorage,
45
- shardingConfig: {
46
- runnerListenAddress: r.some(o.make(c, l)),
47
- ...t ? { shardLockDisableAdvisory: !0 } : {}
48
- }
49
- }))))).pipe(n.provide(e.sqlClientLayer)), h = e.extraShardingLayers ?? [];
50
- return (h.length === 0 ? a.layer : n.mergeAll(a.layer, ...h)).pipe(n.provide(p));
51
- }, g = (n) => i.make({
52
- name: n.name,
53
- cron: n.cron,
54
- execute: t.promise(() => n.execute()),
55
- skipIfOlderThan: n.skipIfOlderThan ?? e.days(1)
56
- });
57
- //#endregion
58
- export { u as a, h as c, f as i, l as n, d as o, p as r, m as s, g as t };
@@ -1,111 +0,0 @@
1
- import { Activity as e, Activity as t, DurableClock as n, DurableClock as r, DurableQueue as i, DurableQueue as a, DurableRateLimiter as o, DurableRateLimiter as s, Workflow as c, Workflow as l } from "@effect/workflow";
2
- import { Cause as u, Context as d, Duration as f, Effect as p, FiberRef as m } from "effect";
3
- //#region src/recorder.ts
4
- var h = class extends d.Tag("@voltro/WorkflowRunRecorder")() {}, g = m.unsafeMake(void 0), _ = m.unsafeMake(void 0), v = m.unsafeMake(void 0), y = () => m.get(g), b = () => m.get(_), x = class extends d.Tag("@voltro/WorkflowStepInterceptor")() {}, S = Symbol.for("voltro.workflow.workerLayer"), C = Symbol.for("voltro.workflow.version"), w = "__voltroWorkflowMessages", T = (e) => typeof e == "object" && !!e && e[S] === !0, E = (e) => typeof e == "object" && e && e[C] !== void 0 ? e[C] : {
5
- version: "1",
6
- compatibleWith: ["1"],
7
- patches: []
8
- }, D = ((e) => {
9
- let t = c.make(e), n = String(e.version ?? "1"), r = {
10
- version: n,
11
- compatibleWith: (e.compatibleWith ?? [n]).map(String),
12
- patches: [...e.patches ?? []]
13
- }, i = {
14
- signals: { ...e.messages?.signals ?? {} },
15
- updates: { ...e.messages?.updates ?? {} },
16
- queries: { ...e.messages?.queries ?? {} }
17
- };
18
- return Object.defineProperty(t, C, {
19
- value: r,
20
- enumerable: !1
21
- }), Object.defineProperty(t, w, {
22
- value: i,
23
- enumerable: !1
24
- }), t;
25
- }), O = i.make, k = i.process, A = ((...e) => {
26
- let t = i.worker(...e);
27
- return Object.defineProperty(t, S, {
28
- value: !0,
29
- enumerable: !1
30
- }), t;
31
- }), j = o.rateLimit, M = (e) => p.gen(function* () {
32
- let t = yield* g, r = yield* p.serviceOption(h), i = f.toMillis(f.decode(e.duration));
33
- if (t !== void 0 && r._tag === "Some") {
34
- let a = r.value, o = new Date(Date.now() + i).toISOString(), s = yield* v;
35
- yield* p.promise(() => a.recordEvent({
36
- runId: t,
37
- eventType: "timer-set",
38
- payload: {
39
- name: e.name,
40
- durationMs: i,
41
- scheduledWakeAt: o,
42
- ...s === void 0 ? {} : { tenantId: s }
43
- }
44
- }).catch(() => {}));
45
- let c = Date.now();
46
- yield* n.sleep(e), yield* p.promise(() => a.recordEvent({
47
- runId: t,
48
- eventType: "timer-fired",
49
- payload: {
50
- name: e.name,
51
- actualDurationMs: Date.now() - c,
52
- ...s === void 0 ? {} : { tenantId: s }
53
- }
54
- }).catch(() => {}));
55
- return;
56
- }
57
- yield* n.sleep(e);
58
- }), N = (t, n, r, i) => p.gen(function* () {
59
- let a = yield* g, o = yield* e.CurrentAttempt, s = yield* p.serviceOption(h), c = yield* p.serviceOption(x), l = c._tag === "Some" ? c.value.interceptor(n, {
60
- runId: a ?? "unrecorded",
61
- stepName: t,
62
- attempt: o
63
- }) : n, d, f;
64
- if (a !== void 0 && s._tag === "Some") {
65
- f = s.value;
66
- try {
67
- d = yield* p.promise(() => f.startStep({
68
- runId: a,
69
- stepName: t,
70
- attempt: o,
71
- stepInput: r,
72
- ...i === void 0 ? {} : { retryPolicy: i }
73
- }));
74
- } catch {
75
- d = void 0;
76
- }
77
- }
78
- let m = Date.now();
79
- return yield* l.pipe(p.tap((e) => d && f ? p.promise(async () => {
80
- try {
81
- await f.endStepSuccess({
82
- stepRecordId: d,
83
- output: e,
84
- durationMs: Date.now() - m
85
- });
86
- } catch {}
87
- }) : p.void), p.tapErrorCause((e) => d && f && !u.isInterruptedOnly(e) ? p.promise(async () => {
88
- try {
89
- let t = u.failureOption(e), n = Array.from(u.failures(e)), r = Array.from(u.defects(e)), i = t._tag === "Some" ? t.value : r[0] ?? u.squash(e), a = i?.message ?? String(i), o = i && typeof i == "object" && "_tag" in i ? String(i._tag) : null;
90
- await f.endStepFailure({
91
- stepRecordId: d,
92
- errorTag: o,
93
- errorMessage: a,
94
- errorCause: {
95
- pretty: u.pretty(e),
96
- failures: n,
97
- defects: r
98
- },
99
- durationMs: Date.now() - m
100
- });
101
- } catch {}
102
- }) : p.void));
103
- }), P = (t) => {
104
- let { input: n, retry: r, ...i } = t;
105
- return e.make({
106
- ...i,
107
- execute: N(i.name, i.execute, n, r)
108
- });
109
- }, F = c.withCompensation, I = e.idempotencyKey;
110
- //#endregion
111
- export { h as C, y as E, v as S, b as T, F as _, O as a, _ as b, E as c, A as d, j as f, t as g, I as h, r as i, T as l, P as m, C as n, a as o, M as p, S as r, s, w as t, k as u, D as v, x as w, g as x, l as y };