@voltro/workflow 0.86.0 → 0.87.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,50 +1,51 @@
1
1
  import { resolveAdmissionKeys as e } from "./admission.js";
2
2
  import { decodePendingPayload as t, evaluateAdmission as n, recordAdmission as r } from "./admissionStore.js";
3
- import { resetExpectedWorkflowReplies as i } from "./workflowJournalReset.js";
4
- import { Effect as a, Schema as o } from "effect";
5
- import { WorkflowRestartObservationSchema as s, WorkflowRestartSelectionSchema as c, WorkflowRestartTargetSchema as l } from "@voltro/protocol";
6
- import { and as u, derivedRowId as d, eq as f, id as p, integer as m, json as h, or as g, table as _, text as v, timestamp as y } from "@voltro/database";
3
+ import { ownedJournalRoutingPromise as i } from "./journalRoutingGuard.js";
4
+ import { resetExpectedWorkflowReplies as a } from "./workflowJournalReset.js";
5
+ import { Effect as o, Schema as s } from "effect";
6
+ import { WorkflowRestartObservationSchema as c, WorkflowRestartSelectionSchema as l, WorkflowRestartTargetSchema as u } from "@voltro/protocol";
7
+ import { and as d, derivedRowId as f, eq as p, id as m, integer as h, json as g, or as _, table as v, text as y, timestamp as b } from "@voltro/database";
7
8
  //#region src/workflowRestartReservation.ts
8
- var b = _("_voltro_workflow_restart_requests", {
9
- id: p({ prefix: "wfrs" }),
10
- runId: v(),
11
- workflowName: v(),
12
- executionId: v(),
13
- generation: v(),
14
- token: v(),
15
- ledgerId: v(),
16
- tenantId: v().nullable(),
17
- delivery: h(),
18
- replies: h(),
19
- selection: h().nullable(),
20
- eviction: h().nullable(),
21
- requestedAt: y(),
22
- dispatchAttempts: m().default(0),
23
- enteredGeneration: v().nullable()
24
- }).unique(["runId", "generation"]).unique(["runId", "token"]).nonReactive(), x = o.NonEmptyString, S = o.Struct({
25
- requestId: x,
26
- restartToken: o.NullOr(x)
27
- }), C = o.Struct({
28
- requestId: x,
29
- replyId: x
30
- }), w = c, T = _("_voltro_workflow_restart_withdrawals", {
31
- id: p({ prefix: "wfrw" }),
32
- runId: v(),
33
- workflowName: v(),
34
- tenantId: v().nullable(),
35
- selection: h(),
36
- withdrawnAt: y()
37
- }).nonReactive(), E = o.Struct({
38
- id: o.NonEmptyString,
39
- runId: o.NonEmptyString,
40
- workflowName: o.NonEmptyString,
41
- tenantId: o.NullOr(o.NonEmptyString),
42
- selection: w,
43
- withdrawnAt: o.Date
44
- }), D = async (e, t) => {
45
- let n = o.decodeUnknownSync(l)(t), [r] = await e.query({
46
- table: T.tableName,
47
- predicate: f("id", n.requestId),
9
+ var x = v("_voltro_workflow_restart_requests", {
10
+ id: m({ prefix: "wfrs" }),
11
+ runId: y(),
12
+ workflowName: y(),
13
+ executionId: y(),
14
+ generation: y(),
15
+ token: y(),
16
+ ledgerId: y(),
17
+ tenantId: y().nullable(),
18
+ delivery: g(),
19
+ replies: g(),
20
+ selection: g().nullable(),
21
+ eviction: g().nullable(),
22
+ requestedAt: b(),
23
+ dispatchAttempts: h().default(0),
24
+ enteredGeneration: y().nullable()
25
+ }).unique(["runId", "generation"]).unique(["runId", "token"]).nonReactive(), S = s.NonEmptyString, C = s.Struct({
26
+ requestId: S,
27
+ restartToken: s.NullOr(S)
28
+ }), w = s.Struct({
29
+ requestId: S,
30
+ replyId: S
31
+ }), T = l, E = v("_voltro_workflow_restart_withdrawals", {
32
+ id: m({ prefix: "wfrw" }),
33
+ runId: y(),
34
+ workflowName: y(),
35
+ tenantId: y().nullable(),
36
+ selection: g(),
37
+ withdrawnAt: b()
38
+ }).nonReactive(), D = s.Struct({
39
+ id: s.NonEmptyString,
40
+ runId: s.NonEmptyString,
41
+ workflowName: s.NonEmptyString,
42
+ tenantId: s.NullOr(s.NonEmptyString),
43
+ selection: T,
44
+ withdrawnAt: s.Date
45
+ }), O = async (e, t) => {
46
+ let n = s.decodeUnknownSync(u)(t), [r] = await e.query({
47
+ table: E.tableName,
48
+ predicate: p("id", n.requestId),
48
49
  lock: "update",
49
50
  order: [],
50
51
  take: 1,
@@ -52,35 +53,35 @@ var b = _("_voltro_workflow_restart_requests", {
52
53
  projection: void 0
53
54
  });
54
55
  if (r === void 0) return;
55
- let i = o.decodeUnknownSync(E)(r);
56
+ let i = s.decodeUnknownSync(D)(r);
56
57
  if (i.runId !== n.runId) throw Error("Restart identity belongs to a different command");
57
58
  if (!Number.isFinite(i.withdrawnAt.getTime())) throw Error("Invalid restart withdrawal timestamp");
58
59
  return i;
59
- }, O = async (e, t) => {
60
- if (await D(e, t) !== void 0) throw Error("Restart request was permanently withdrawn");
61
- }, k = o.Struct({
62
- id: x,
63
- runId: x,
64
- workflowName: x,
65
- executionId: x,
66
- generation: x,
67
- token: x,
68
- ledgerId: x,
69
- tenantId: o.NullOr(x),
70
- delivery: S,
71
- replies: o.Array(C),
72
- selection: w,
73
- eviction: o.NullOr(o.Struct({
74
- executionId: x,
75
- runId: o.String
60
+ }, k = async (e, t) => {
61
+ if (await O(e, t) !== void 0) throw Error("Restart request was permanently withdrawn");
62
+ }, A = s.Struct({
63
+ id: S,
64
+ runId: S,
65
+ workflowName: S,
66
+ executionId: S,
67
+ generation: S,
68
+ token: S,
69
+ ledgerId: S,
70
+ tenantId: s.NullOr(S),
71
+ delivery: C,
72
+ replies: s.Array(w),
73
+ selection: T,
74
+ eviction: s.NullOr(s.Struct({
75
+ executionId: S,
76
+ runId: s.String
76
77
  })),
77
- requestedAt: o.Date,
78
- dispatchAttempts: o.Number.check(o.isInt(), o.isGreaterThanOrEqualTo(0)),
79
- enteredGeneration: o.NullOr(x)
80
- }), A = (e, t) => e.kind === t.kind && (e.kind === "failed-steps" || t.kind === "from-step" && e.stepName === t.stepName), j = async (e, t) => {
81
- let n = o.decodeUnknownSync(l)(t), [r] = await e.query({
82
- table: b.tableName,
83
- predicate: f("id", n.requestId),
78
+ requestedAt: s.Date,
79
+ dispatchAttempts: s.Number.check(s.isInt(), s.isGreaterThanOrEqualTo(0)),
80
+ enteredGeneration: s.NullOr(S)
81
+ }), j = (e, t) => e.kind === t.kind && (e.kind === "failed-steps" || t.kind === "from-step" && e.stepName === t.stepName), M = async (e, t) => {
82
+ let n = s.decodeUnknownSync(u)(t), [r] = await e.query({
83
+ table: x.tableName,
84
+ predicate: p("id", n.requestId),
84
85
  lock: "update",
85
86
  order: [],
86
87
  take: 1,
@@ -88,20 +89,20 @@ var b = _("_voltro_workflow_restart_requests", {
88
89
  projection: void 0
89
90
  });
90
91
  if (r === void 0) return;
91
- let i = o.decodeUnknownSync(k)(r);
92
+ let i = s.decodeUnknownSync(A)(r);
92
93
  if (i.runId !== n.runId) throw Error("Restart identity belongs to a different command");
93
94
  return i;
94
- }, M = async (e, t) => {
95
- let n = await D(e, t);
96
- if (n !== void 0) return o.decodeUnknownSync(s)({
95
+ }, N = async (e, t) => {
96
+ let n = await O(e, t);
97
+ if (n !== void 0) return s.decodeUnknownSync(c)({
97
98
  ...t,
98
99
  kind: "withdrawn",
99
100
  workflowName: n.workflowName,
100
101
  selection: n.selection,
101
102
  withdrawnAt: n.withdrawnAt.getTime()
102
103
  });
103
- let r = await j(e, t);
104
- if (r === void 0) return o.decodeUnknownSync(s)({
104
+ let r = await M(e, t);
105
+ if (r === void 0) return s.decodeUnknownSync(c)({
105
106
  ...t,
106
107
  kind: "not-found"
107
108
  });
@@ -115,7 +116,7 @@ var b = _("_voltro_workflow_restart_requests", {
115
116
  requestedAt: r.requestedAt.getTime(),
116
117
  dispatchAttempts: r.dispatchAttempts
117
118
  };
118
- return o.decodeUnknownSync(s)(r.enteredGeneration === null ? {
119
+ return s.decodeUnknownSync(c)(r.enteredGeneration === null ? {
119
120
  ...i,
120
121
  kind: "pending"
121
122
  } : {
@@ -123,56 +124,56 @@ var b = _("_voltro_workflow_restart_requests", {
123
124
  kind: "entered",
124
125
  enteredGeneration: r.enteredGeneration
125
126
  });
126
- }, N = async (e, t) => {
127
+ }, P = async (e, t) => {
127
128
  for (let e of [
128
129
  t.id,
129
130
  t.runId,
130
131
  t.workflowName
131
- ]) o.decodeUnknownSync(x)(e);
132
+ ]) s.decodeUnknownSync(S)(e);
132
133
  if (t.id.length > 64) throw Error("Invalid restart request identity");
133
- o.decodeUnknownSync(o.NullOr(x))(t.tenantId);
134
- let n = o.decodeUnknownSync(w)(t.selection);
135
- await O(e, {
134
+ s.decodeUnknownSync(s.NullOr(S))(t.tenantId);
135
+ let n = s.decodeUnknownSync(T)(t.selection);
136
+ await k(e, {
136
137
  requestId: t.id,
137
138
  runId: t.runId
138
139
  });
139
- let r = await j(e, {
140
+ let r = await M(e, {
140
141
  requestId: t.id,
141
142
  runId: t.runId
142
143
  });
143
144
  if (r !== void 0) {
144
- if (r.runId !== t.runId || r.workflowName !== t.workflowName || r.tenantId !== t.tenantId || !A(r.selection, n)) throw Error("Restart identity belongs to a different command");
145
+ if (r.runId !== t.runId || r.workflowName !== t.workflowName || r.tenantId !== t.tenantId || !j(r.selection, n)) throw Error("Restart identity belongs to a different command");
145
146
  return r;
146
147
  }
147
- }, P = async (e, t) => {
148
- let n = o.decodeUnknownSync(E)({
148
+ }, F = async (e, t) => {
149
+ let n = s.decodeUnknownSync(D)({
149
150
  ...t,
150
151
  withdrawnAt: new Date(t.now)
151
152
  });
152
- if (o.decodeUnknownSync(l)({
153
+ if (s.decodeUnknownSync(u)({
153
154
  requestId: n.id,
154
155
  runId: n.runId
155
156
  }), !Number.isFinite(n.withdrawnAt.getTime())) throw Error("Invalid restart withdrawal timestamp");
156
- let r = await D(e, {
157
+ let r = await O(e, {
157
158
  requestId: n.id,
158
159
  runId: n.runId
159
160
  });
160
161
  if (r !== void 0) {
161
- if (r.workflowName !== n.workflowName || r.tenantId !== n.tenantId || !A(r.selection, n.selection)) throw Error("Restart identity belongs to a different command");
162
+ if (r.workflowName !== n.workflowName || r.tenantId !== n.tenantId || !j(r.selection, n.selection)) throw Error("Restart identity belongs to a different command");
162
163
  return {
163
164
  kind: "withdrawn",
164
165
  withdrawal: r,
165
166
  reused: !0
166
167
  };
167
168
  }
168
- let i = await N(e, n);
169
+ let i = await P(e, n);
169
170
  if (i !== void 0) return {
170
171
  kind: "reserved",
171
172
  request: i
172
173
  };
173
174
  let [a] = await e.query({
174
175
  table: "_voltro_workflow_runs",
175
- predicate: f("id", n.runId),
176
+ predicate: p("id", n.runId),
176
177
  lock: "update",
177
178
  order: [],
178
179
  take: 1,
@@ -180,49 +181,49 @@ var b = _("_voltro_workflow_restart_requests", {
180
181
  projection: void 0
181
182
  });
182
183
  if (a === void 0 || a.tag !== n.workflowName) throw Error("Restart withdrawal requires its resident workflow");
183
- if ((o.decodeUnknownSync(o.NullOr(o.Struct({ tenantId: o.NullOr(x) })))(a.subject ?? null)?.tenantId ?? null) !== n.tenantId) throw Error("Restart withdrawal belongs to another resident tenant");
184
- return await e.insert(T.tableName, n), {
184
+ if ((s.decodeUnknownSync(s.NullOr(s.Struct({ tenantId: s.NullOr(S) })))(a.subject ?? null)?.tenantId ?? null) !== n.tenantId) throw Error("Restart withdrawal belongs to another resident tenant");
185
+ return await e.insert(E.tableName, n), {
185
186
  kind: "withdrawn",
186
187
  withdrawal: n,
187
188
  reused: !1
188
189
  };
189
- }, F = async (e, t) => {
190
- o.decodeUnknownSync(x)(t.generation);
191
- let n = await N(e, t);
190
+ }, I = async (e, t) => {
191
+ s.decodeUnknownSync(S)(t.generation);
192
+ let n = await P(e, t);
192
193
  if (n !== void 0 && n.generation !== t.generation) throw Error("Restart identity belongs to a different command");
193
194
  return n;
194
- }, I = async (i, a) => {
195
+ }, L = async (i, a) => {
195
196
  for (let e of [
196
197
  a.id,
197
198
  a.runId,
198
199
  a.generation,
199
200
  a.token
200
- ]) o.decodeUnknownSync(x)(e);
201
+ ]) s.decodeUnknownSync(S)(e);
201
202
  if (a.id.length > 64 || !Number.isFinite(new Date(a.now).getTime())) throw Error("Invalid restart request identity or timestamp");
202
- await O(i, {
203
+ await k(i, {
203
204
  requestId: a.id,
204
205
  runId: a.runId
205
206
  });
206
- let s = o.decodeUnknownSync(S)(a.delivery), c = o.decodeUnknownSync(w)(a.selection);
207
- if (s.restartToken === a.token) throw Error("Restart requires a new delivery token");
208
- let l = o.decodeUnknownSync(o.Array(C))(a.replies), d = /* @__PURE__ */ new Map();
207
+ let o = s.decodeUnknownSync(C)(a.delivery), c = s.decodeUnknownSync(T)(a.selection);
208
+ if (o.restartToken === a.token) throw Error("Restart requires a new delivery token");
209
+ let l = s.decodeUnknownSync(s.Array(w))(a.replies), u = /* @__PURE__ */ new Map();
209
210
  for (let e of l) {
210
- if (!/^[1-9]\d*$/.test(e.requestId) || !/^[1-9]\d*$/.test(e.replyId) || d.has(e.requestId)) throw Error("Restart requires distinct, exact journal reply identities");
211
- d.set(e.requestId, e.replyId);
211
+ if (!/^[1-9]\d*$/.test(e.requestId) || !/^[1-9]\d*$/.test(e.replyId) || u.has(e.requestId)) throw Error("Restart requires distinct, exact journal reply identities");
212
+ u.set(e.requestId, e.replyId);
212
213
  }
213
- if (!d.has(s.requestId)) throw Error("Restart selection must include its run reply");
214
- let [p] = await i.query({
215
- table: b.tableName,
216
- predicate: f("id", a.id),
214
+ if (!u.has(o.requestId)) throw Error("Restart selection must include its run reply");
215
+ let [f] = await i.query({
216
+ table: x.tableName,
217
+ predicate: p("id", a.id),
217
218
  lock: "update",
218
219
  order: [],
219
220
  take: 1,
220
221
  skip: void 0,
221
222
  projection: void 0
222
223
  });
223
- if (p !== void 0) {
224
- let e = o.decodeUnknownSync(k)(p);
225
- if (e.runId !== a.runId || e.generation !== a.generation || e.token !== a.token || e.workflowName !== a.control.workflowName || e.tenantId !== a.tenantId || e.delivery.requestId !== s.requestId || e.delivery.restartToken !== s.restartToken || !A(e.selection, c) || e.replies.length !== d.size || e.replies.some((e) => d.get(e.requestId) !== e.replyId)) throw Error("Restart identity belongs to a different request");
224
+ if (f !== void 0) {
225
+ let e = s.decodeUnknownSync(A)(f);
226
+ if (e.runId !== a.runId || e.generation !== a.generation || e.token !== a.token || e.workflowName !== a.control.workflowName || e.tenantId !== a.tenantId || e.delivery.requestId !== o.requestId || e.delivery.restartToken !== o.restartToken || !j(e.selection, c) || e.replies.length !== u.size || e.replies.some((e) => u.get(e.requestId) !== e.replyId)) throw Error("Restart identity belongs to a different request");
226
227
  return {
227
228
  kind: "reserved",
228
229
  request: e,
@@ -231,7 +232,7 @@ var b = _("_voltro_workflow_restart_requests", {
231
232
  }
232
233
  let [m] = await i.query({
233
234
  table: "_voltro_workflow_runs",
234
- predicate: f("id", a.runId),
235
+ predicate: p("id", a.runId),
235
236
  lock: "update",
236
237
  order: [],
237
238
  take: 1,
@@ -239,23 +240,23 @@ var b = _("_voltro_workflow_restart_requests", {
239
240
  projection: void 0
240
241
  });
241
242
  if (m === void 0 || m.tag !== a.control.workflowName || m.runnerGeneration !== a.generation || m.status !== "failed" || m.discardedAt != null || typeof m.executionId != "string" || m.executionId.length === 0) throw Error("Restart requires its undiscarded failed resident generation");
242
- if ((o.decodeUnknownSync(o.NullOr(o.Struct({ tenantId: o.NullOr(x) })))(m.subject ?? null)?.tenantId ?? null) !== a.tenantId) throw Error("Restart belongs to another resident tenant");
243
- let h = o.decodeUnknownSync(S)(m.engineDelivery);
244
- if (h.requestId !== s.requestId || h.restartToken !== s.restartToken) throw Error("Restart journal delivery does not belong to its resident generation");
245
- let [_] = await i.query({
246
- table: b.tableName,
247
- predicate: u(f("runId", a.runId), g(f("generation", a.generation), f("token", a.token))),
243
+ if ((s.decodeUnknownSync(s.NullOr(s.Struct({ tenantId: s.NullOr(S) })))(m.subject ?? null)?.tenantId ?? null) !== a.tenantId) throw Error("Restart belongs to another resident tenant");
244
+ let h = s.decodeUnknownSync(C)(m.engineDelivery);
245
+ if (h.requestId !== o.requestId || h.restartToken !== o.restartToken) throw Error("Restart journal delivery does not belong to its resident generation");
246
+ let [g] = await i.query({
247
+ table: x.tableName,
248
+ predicate: d(p("runId", a.runId), _(p("generation", a.generation), p("token", a.token))),
248
249
  lock: "update",
249
250
  order: [],
250
251
  take: 1,
251
252
  skip: void 0,
252
253
  projection: ["id", "generation"]
253
254
  });
254
- if (_ !== void 0) {
255
- if (_.generation !== a.generation) throw Error("Restart delivery token was already used by this run");
255
+ if (g !== void 0) {
256
+ if (g.generation !== a.generation) throw Error("Restart delivery token was already used by this run");
256
257
  return { kind: "already-requested" };
257
258
  }
258
- let v = t(i, a.control.workflowName, m.payload), y = e(a.control, v), T = await n({
259
+ let v = t(i, a.control.workflowName, m.payload), y = e(a.control, v), b = await n({
259
260
  store: i,
260
261
  control: a.control,
261
262
  keys: y,
@@ -263,9 +264,9 @@ var b = _("_voltro_workflow_restart_requests", {
263
264
  now: a.now,
264
265
  reconsidering: !0
265
266
  });
266
- if (T.kind !== "admit") return {
267
+ if (b.kind !== "admit") return {
267
268
  kind: "not-admitted",
268
- decision: T
269
+ decision: b
269
270
  };
270
271
  let E = await r({
271
272
  store: i,
@@ -273,7 +274,7 @@ var b = _("_voltro_workflow_restart_requests", {
273
274
  keys: y,
274
275
  outcome: "admitted",
275
276
  mode: "restart",
276
- reason: T.reason,
277
+ reason: b.reason,
277
278
  collapsed: 1,
278
279
  waitedMs: 0,
279
280
  executionId: null,
@@ -282,7 +283,7 @@ var b = _("_voltro_workflow_restart_requests", {
282
283
  now: a.now
283
284
  });
284
285
  if (E === void 0) throw Error("Restart has no admission reservation");
285
- let D = o.decodeUnknownSync(k)({
286
+ let D = s.decodeUnknownSync(A)({
286
287
  id: a.id,
287
288
  runId: a.runId,
288
289
  workflowName: a.control.workflowName,
@@ -291,23 +292,23 @@ var b = _("_voltro_workflow_restart_requests", {
291
292
  token: a.token,
292
293
  ledgerId: E,
293
294
  tenantId: a.tenantId,
294
- delivery: s,
295
+ delivery: o,
295
296
  replies: l,
296
297
  selection: c,
297
- eviction: T.evict ?? null,
298
+ eviction: b.evict ?? null,
298
299
  requestedAt: new Date(a.now),
299
300
  dispatchAttempts: 0,
300
301
  enteredGeneration: null
301
302
  });
302
- return await i.insert(b.tableName, D), {
303
+ return await i.insert(x.tableName, D), {
303
304
  kind: "reserved",
304
305
  request: D,
305
306
  reused: !1
306
307
  };
307
- }, L = async (e, t) => {
308
+ }, R = async (e, t) => {
308
309
  let [n] = await e.query({
309
- table: b.tableName,
310
- predicate: f("id", t),
310
+ table: x.tableName,
311
+ predicate: p("id", t),
311
312
  lock: "update",
312
313
  order: [],
313
314
  take: 1,
@@ -315,11 +316,11 @@ var b = _("_voltro_workflow_restart_requests", {
315
316
  projection: void 0
316
317
  });
317
318
  if (n === void 0) throw Error("Restart dispatch has no resident request");
318
- let r = o.decodeUnknownSync(k)(n);
319
+ let r = s.decodeUnknownSync(A)(n);
319
320
  if (r.enteredGeneration !== null) throw Error("Restart request has already entered its resident generation");
320
321
  let [i] = await e.query({
321
322
  table: "_voltro_workflow_admissions",
322
- predicate: f("id", r.ledgerId),
323
+ predicate: p("id", r.ledgerId),
323
324
  lock: "update",
324
325
  order: [],
325
326
  take: 1,
@@ -329,7 +330,7 @@ var b = _("_voltro_workflow_restart_requests", {
329
330
  if (i === void 0 || i.outcome !== "admitted" || i.releasedAt !== null || i.workflowName !== r.workflowName || i.tenantId !== r.tenantId || i.executionId !== null || i.runId !== null) throw Error("Restart dispatch has no matching held resident reservation");
330
331
  let [a] = await e.query({
331
332
  table: "_voltro_workflow_runs",
332
- predicate: f("id", r.runId),
333
+ predicate: p("id", r.runId),
333
334
  lock: "update",
334
335
  order: [],
335
336
  take: 1,
@@ -337,44 +338,44 @@ var b = _("_voltro_workflow_restart_requests", {
337
338
  projection: void 0
338
339
  });
339
340
  if (a === void 0 || a.tag !== r.workflowName || a.executionId !== r.executionId || a.runnerGeneration !== r.generation || a.status !== "failed" || a.discardedAt != null) throw Error("Restart dispatch no longer owns its failed resident generation");
340
- let s = o.decodeUnknownSync(S)(a.engineDelivery);
341
- if (s.requestId !== r.delivery.requestId || s.restartToken !== r.delivery.restartToken) throw Error("Restart dispatch no longer owns its journal delivery");
341
+ let o = s.decodeUnknownSync(C)(a.engineDelivery);
342
+ if (o.requestId !== r.delivery.requestId || o.restartToken !== r.delivery.restartToken) throw Error("Restart dispatch no longer owns its journal delivery");
342
343
  return {
343
344
  request: r,
344
345
  run: a
345
346
  };
346
- }, R = async (e, t) => {
347
- let { request: n } = await L(e, t), r = n.dispatchAttempts + 1;
347
+ }, z = async (e, t) => {
348
+ let { request: n } = await R(e, t), r = n.dispatchAttempts + 1;
348
349
  if (!Number.isSafeInteger(r)) throw Error("Restart dispatch attempt counter exhausted");
349
- if (await e.update(b.tableName, t, { dispatchAttempts: r }) === null) throw Error("Restart request disappeared before dispatch");
350
+ if (await e.update(x.tableName, t, { dispatchAttempts: r }) === null) throw Error("Restart request disappeared before dispatch");
350
351
  return {
351
352
  ...n,
352
353
  dispatchAttempts: r
353
354
  };
354
- }, z = (e) => a.gen(function* () {
355
- let { request: t } = yield* a.promise(() => e.transaction((t) => L(t, e.requestId)));
356
- if (!(yield* a.promise(() => e.acquireCapacity(t)))) return { kind: "waiting-capacity" };
357
- let n = yield* a.promise(() => e.transaction((e) => R(e, t.id)));
358
- return yield* i(n.replies, {
355
+ }, B = (e) => o.gen(function* () {
356
+ let { request: t } = yield* i(() => e.transaction((t) => R(t, e.requestId)));
357
+ if (!(yield* i(() => e.acquireCapacity(t)))) return { kind: "waiting-capacity" };
358
+ let n = yield* i(() => e.transaction((e) => z(e, t.id)));
359
+ return yield* a(n.replies, {
359
360
  requestId: n.delivery.requestId,
360
361
  previousToken: n.delivery.restartToken,
361
362
  token: n.token,
362
363
  workflowName: n.workflowName,
363
364
  executionId: n.executionId
364
365
  });
365
- }), B = async (e, t) => {
366
+ }), V = async (e, t) => {
366
367
  for (let e of [
367
368
  t.runId,
368
369
  t.workflowName,
369
370
  t.executionId,
370
371
  t.generation
371
- ]) o.decodeUnknownSync(x)(e);
372
+ ]) s.decodeUnknownSync(S)(e);
372
373
  if (!Number.isFinite(new Date(t.now).getTime())) throw Error("Restart entry requires a valid timestamp");
373
- let n = o.decodeUnknownSync(S)(t.delivery);
374
+ let n = s.decodeUnknownSync(C)(t.delivery);
374
375
  if (n.restartToken === null) throw Error("Restart entry has no delivery token");
375
376
  let [r] = await e.query({
376
- table: b.tableName,
377
- predicate: u(f("runId", t.runId), f("token", n.restartToken)),
377
+ table: x.tableName,
378
+ predicate: d(p("runId", t.runId), p("token", n.restartToken)),
378
379
  lock: "update",
379
380
  order: [],
380
381
  take: 1,
@@ -382,15 +383,15 @@ var b = _("_voltro_workflow_restart_requests", {
382
383
  projection: ["id"]
383
384
  });
384
385
  if (r === void 0) throw Error("Restart delivery has no matching resident request");
385
- let { request: i, run: a } = await L(e, o.decodeUnknownSync(x)(r.id));
386
+ let { request: i, run: a } = await R(e, s.decodeUnknownSync(S)(r.id));
386
387
  if (i.runId !== t.runId || i.workflowName !== t.workflowName || i.executionId !== t.executionId || i.generation === t.generation || i.delivery.requestId !== n.requestId || i.token !== n.restartToken) throw Error("Restart entry does not match its reserved delivery");
387
388
  if (i.dispatchAttempts === 0) throw Error("Restart entry has no committed dispatch attempt");
388
389
  if (await e.update("_voltro_workflow_admissions", i.ledgerId, {
389
390
  executionId: i.executionId,
390
391
  runId: i.runId
391
392
  }) === null) throw Error("Restart reservation disappeared during entry");
392
- if (await e.update(b.tableName, i.id, { enteredGeneration: t.generation }) === null) throw Error("Restart request disappeared during entry");
393
- let s = await e.update("_voltro_workflow_runs", i.runId, {
393
+ if (await e.update(x.tableName, i.id, { enteredGeneration: t.generation }) === null) throw Error("Restart request disappeared during entry");
394
+ let o = await e.update("_voltro_workflow_runs", i.runId, {
394
395
  runnerGeneration: t.generation,
395
396
  engineDelivery: n,
396
397
  runnerEnteredAt: new Date(t.now),
@@ -402,12 +403,12 @@ var b = _("_voltro_workflow_restart_requests", {
402
403
  completedAt: null,
403
404
  durationMs: null
404
405
  });
405
- if (s === null) throw Error("Restart run disappeared during entry");
406
+ if (o === null) throw Error("Restart run disappeared during entry");
406
407
  return {
407
- row: s,
408
+ row: o,
408
409
  previous: a,
409
410
  event: await e.insert("_voltro_workflow_run_events", {
410
- id: d("wfev", JSON.stringify(["restart", i.id])),
411
+ id: f("wfev", JSON.stringify(["restart", i.id])),
411
412
  runId: i.runId,
412
413
  eventType: "run-redriven",
413
414
  occurredAt: new Date(t.now),
@@ -423,4 +424,4 @@ var b = _("_voltro_workflow_restart_requests", {
423
424
  };
424
425
  };
425
426
  //#endregion
426
- export { R as beginWorkflowRestartDispatchInTransaction, B as consumeWorkflowRestartInTransaction, N as readWorkflowRestartCommandInTransaction, M as readWorkflowRestartObservationInTransaction, F as readWorkflowRestartReservationInTransaction, I as reserveWorkflowRestartInTransaction, z as resetReservedWorkflowJournal, P as withdrawWorkflowRestartInTransaction, b as workflowRestartRequestsTable, T as workflowRestartWithdrawalsTable };
427
+ export { z as beginWorkflowRestartDispatchInTransaction, V as consumeWorkflowRestartInTransaction, P as readWorkflowRestartCommandInTransaction, N as readWorkflowRestartObservationInTransaction, I as readWorkflowRestartReservationInTransaction, L as reserveWorkflowRestartInTransaction, B as resetReservedWorkflowJournal, F as withdrawWorkflowRestartInTransaction, x as workflowRestartRequestsTable, E as workflowRestartWithdrawalsTable };
@@ -1,29 +1,30 @@
1
1
  import { beginWorkflowControlDispatchInTransaction as e, bindWorkflowResumeJournalInTransaction as t } from "./controlRequest.js";
2
- import { observeWorkflowSuspension as n, resetExpectedWorkflowSuspension as r } from "./workflowJournalReset.js";
3
- import { Context as i, Effect as a } from "effect";
4
- import { SqlClient as o } from "effect/sql";
5
- import { Sharding as s } from "effect/cluster";
2
+ import { JournalRoutingGuard as n, ownedJournalRoutingPromise as r, protectJournalRoutingEffect as i } from "./journalRoutingGuard.js";
3
+ import { observeWorkflowSuspension as a, resetExpectedWorkflowSuspension as o } from "./workflowJournalReset.js";
4
+ import { Context as s, Effect as c, Option as l } from "effect";
5
+ import { SqlClient as u } from "effect/sql";
6
+ import { Sharding as d } from "effect/cluster";
6
7
  //#region src/workflowResumeDispatch.ts
7
- var c = (i) => a.gen(function* () {
8
- let o = yield* a.context(), c = yield* a.promise(() => i.transaction((e) => t(e, i.requestId, (e) => a.runPromiseWith(o)(n(e)))));
9
- if (c.kind !== "bound") return c;
10
- let l = yield* a.promise(() => i.transaction((t) => e(t, i.requestId)));
8
+ var f = (n) => c.gen(function* () {
9
+ let i = yield* c.context(), s = yield* r(() => n.transaction((e) => t(e, n.requestId, (e) => c.runPromiseWith(i)(a(e)))));
10
+ if (s.kind !== "bound") return s;
11
+ let l = yield* r(() => n.transaction((t) => e(t, n.requestId)));
11
12
  if (l.kind !== "dispatch") return l;
12
13
  let { request: u } = l;
13
- if (u.operation !== "resume" || u.resumeJournal === null) return yield* a.die(/* @__PURE__ */ Error("Resume dispatch requires its committed suspension binding"));
14
- let d = yield* r({
14
+ if (u.operation !== "resume" || u.resumeJournal === null) return yield* c.die(/* @__PURE__ */ Error("Resume dispatch requires its committed suspension binding"));
15
+ let f = yield* o({
15
16
  workflowName: u.workflowName,
16
17
  executionId: u.executionId,
17
18
  ...u.resumeJournal
18
19
  });
19
- return yield* (yield* s.Sharding).pollStorage, {
20
+ return yield* (yield* d.Sharding).pollStorage, {
20
21
  kind: "attempted",
21
22
  request: u,
22
- journal: d
23
+ journal: f
23
24
  };
24
- }), l = class extends i.Service()("@voltro/workflow/WorkflowResumeDispatcher") {}, u = a.gen(function* () {
25
- let e = yield* o.SqlClient, t = yield* s.Sharding;
26
- return l.of({ dispatch: (n) => c(n).pipe(a.provideService(o.SqlClient, e), a.provideService(s.Sharding, t)) });
25
+ }), p = class extends s.Service()("@voltro/workflow/WorkflowResumeDispatcher") {}, m = c.gen(function* () {
26
+ let e = l.getOrUndefined(yield* c.serviceOption(n)), t = yield* u.SqlClient, r = yield* d.Sharding;
27
+ return p.of({ dispatch: (n) => i(e, f(n)).pipe(c.provideService(u.SqlClient, t), c.provideService(d.Sharding, r)) });
27
28
  });
28
29
  //#endregion
29
- export { l as WorkflowResumeDispatcher, c as dispatchWorkflowResume, u as makeWorkflowResumeDispatcher };
30
+ export { p as WorkflowResumeDispatcher, f as dispatchWorkflowResume, m as makeWorkflowResumeDispatcher };
@@ -0,0 +1,12 @@
1
+ import { JournalRoutingGuard as e } from "./journalRoutingGuard.js";
2
+ import { Context as t, Effect as n, Option as r } from "effect";
3
+ import { Sharding as i } from "effect/cluster";
4
+ //#region src/workflowRuntimeReadiness.ts
5
+ var a = class extends t.Service()("@voltro/workflow/WorkflowRuntimeReadiness") {}, o = n.gen(function* () {
6
+ let t = yield* i.Sharding, a = r.getOrUndefined(yield* n.serviceOption(e)), o = !0;
7
+ return yield* n.addFinalizer(() => n.sync(() => {
8
+ o = !1;
9
+ })), { isReady: () => o && !a?.isClosed() && !n.runSync(t.isShutdown) };
10
+ }), s = n.map(n.serviceOption(a), (e) => r.isSome(e) ? e.value.isReady : () => !0);
11
+ //#endregion
12
+ export { a as WorkflowRuntimeReadiness, s as captureWorkflowRuntimeReadiness, o as makeWorkflowRuntimeReadiness };