@voltro/workflow 0.87.0 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +169 -6
  2. package/THIRD-PARTY-NOTICES.md +3 -1346
  3. package/dist/admission.js +1 -2
  4. package/dist/admissionDrainer.js +5 -3
  5. package/dist/admissionGate.js +1 -2
  6. package/dist/admissionStore.js +1 -2
  7. package/dist/admissionSubmission.js +1 -2
  8. package/dist/admissionTables.js +4 -4
  9. package/dist/admissionTransaction.js +1 -2
  10. package/dist/awaitEvent.js +1 -2
  11. package/dist/budgetHold.js +1 -2
  12. package/dist/cancelOnPlan.js +1 -2
  13. package/dist/cancelOnSweep.js +1 -2
  14. package/dist/cancelPendingStart.js +1 -2
  15. package/dist/clusterCron.js +1 -2
  16. package/dist/clusterDiagnostics.js +1 -2
  17. package/dist/clusterDiagnosticsSql.js +1 -2
  18. package/dist/clusterLayer.js +1 -2
  19. package/dist/clusterMigrationGate.js +1 -2
  20. package/dist/clusterRunnerLayer.js +1 -2
  21. package/dist/clusterShardGroups.js +1 -2
  22. package/dist/clusterTestSuite.d.ts +22 -2
  23. package/dist/clusterTestSuite.js +170 -172
  24. package/dist/controlMonitor.js +1 -2
  25. package/dist/controlRequest.js +1 -2
  26. package/dist/executionRefusal.js +1 -2
  27. package/dist/failureHandoff.js +1 -2
  28. package/dist/failureMessage.js +1 -2
  29. package/dist/failureRecovery.js +1 -2
  30. package/dist/failureReportStore.js +1 -2
  31. package/dist/flowControl.js +1 -2
  32. package/dist/forwardStartReceipts.js +1 -2
  33. package/dist/inMemoryLayer.js +1 -2
  34. package/dist/inMemoryRecorder.js +1 -2
  35. package/dist/index.d.ts +3 -1
  36. package/dist/inspectWorkflow.js +2 -3
  37. package/dist/journalEncryption.js +1 -2
  38. package/dist/journalRoutingGuard.js +1 -2
  39. package/dist/journalRoutingLayout.js +1 -2
  40. package/dist/journalRoutingLock.js +1 -2
  41. package/dist/journalRoutingMaintenance.js +1 -2
  42. package/dist/journalRoutingMessageStorage.js +1 -2
  43. package/dist/journalRoutingNamespace.js +1 -2
  44. package/dist/journalRoutingRuntime.js +1 -2
  45. package/dist/journalRoutingSharding.js +1 -2
  46. package/dist/journalRoutingState.js +1 -2
  47. package/dist/journalRoutingTable.js +1 -2
  48. package/dist/journalRoutingTransaction.js +2 -3
  49. package/dist/messages.js +1 -2
  50. package/dist/nondeterminism.js +1 -2
  51. package/dist/parentClosure.js +1 -2
  52. package/dist/parentClosureRecovery.js +1 -2
  53. package/dist/pendingSubmission.js +1 -2
  54. package/dist/prepareSubmissionDispatch.js +1 -2
  55. package/dist/preparedExecution.js +1 -2
  56. package/dist/primitives.js +1 -2
  57. package/dist/queuedCancellationRequest.js +1 -2
  58. package/dist/queuedControl.js +1 -2
  59. package/dist/recorder.js +1 -2
  60. package/dist/residentExecutionEvidence.js +1 -2
  61. package/dist/retryPolicy.js +1 -2
  62. package/dist/runEventsTable.js +1 -2
  63. package/dist/runGeneration.js +1 -2
  64. package/dist/runRecording.js +1 -2
  65. package/dist/runStepsTable.js +1 -2
  66. package/dist/runnerStorageGuard.js +1 -2
  67. package/dist/runsTable.js +1 -2
  68. package/dist/scheduleDeclaration.js +1 -2
  69. package/dist/signalHint.js +1 -2
  70. package/dist/signals.js +1 -2
  71. package/dist/signalsSuspending.js +1 -2
  72. package/dist/sqliteWorkflowOwnership.js +1 -2
  73. package/dist/stalenessSweep.js +1 -2
  74. package/dist/startContextsTable.js +1 -2
  75. package/dist/startReceipt.js +1 -2
  76. package/dist/submissionRecovery.js +1 -2
  77. package/dist/submissionRejection.js +1 -2
  78. package/dist/submissionRetry.js +1 -2
  79. package/dist/suspensionUnavailable.js +1 -2
  80. package/dist/updates.js +1 -2
  81. package/dist/watermarkTable.js +1 -2
  82. package/dist/webCrypto.js +4 -17
  83. package/dist/workflowDelivery.js +1 -2
  84. package/dist/workflowExecutorRouting.js +1 -2
  85. package/dist/workflowJournal.js +1 -2
  86. package/dist/workflowJournalReset.js +1 -2
  87. package/dist/workflowReadSelections.js +1 -2
  88. package/dist/workflowRestartDispatch.js +1 -2
  89. package/dist/workflowRestartObservation.js +1 -2
  90. package/dist/workflowRestartPreparation.js +1 -2
  91. package/dist/workflowRestartReservation.js +4 -4
  92. package/dist/workflowResumeDispatch.js +1 -2
  93. package/dist/workflowRuntimeReadiness.js +1 -2
  94. package/dist/workflowShardRelocation.js +1 -2
  95. package/dist/workflowShardRelocationSql.js +1 -2
  96. package/package.json +5 -11
package/dist/admission.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/admission.ts
1
+ // src/admission.ts
2
2
  var e = class extends Error {
3
3
  workflowName;
4
4
  field;
@@ -136,5 +136,4 @@ var e = class extends Error {
136
136
  let r = e.timeouts?.finishMs;
137
137
  return r === void 0 || t.terminal ? !1 : n - t.startedAt >= r;
138
138
  }, u = (e, t) => e.priority === t.priority ? e.firstSeenAt === t.firstSeenAt ? e.id < t.id ? -1 : +(e.id > t.id) : e.firstSeenAt - t.firstSeenAt : t.priority - e.priority;
139
- //#endregion
140
139
  export { e as FlowControlKeyError, u as comparePendingOrder, a as decideAdmission, l as isFinishExpired, c as isStartExpired, i as nextSlotAt, n as pooledConcurrencyKey, r as resolveAdmissionKeys };
@@ -16,7 +16,7 @@ import { forwardStartReceipts as L } from "./forwardStartReceipts.js";
16
16
  import { Schema as R } from "effect";
17
17
  import { eq as z } from "@voltro/database";
18
18
  import { randomUUID as B } from "node:crypto";
19
- //#region src/admissionDrainer.ts
19
+ // src/admissionDrainer.ts
20
20
  var V = {
21
21
  scanned: 0,
22
22
  admitted: 0,
@@ -604,7 +604,10 @@ var V = {
604
604
  evicted: 0
605
605
  }, i, n.batch !== void 0, r);
606
606
  let o = await e.transaction((e) => f(e, t.id));
607
- if (o?.executionId == null || o.executionId !== o.preparedExecutionId) throw Error("Admission submission has no confirmed engine acceptance");
607
+ if (o?.executionId == null || o.executionId !== o.preparedExecutionId) {
608
+ let e = /* @__PURE__ */ Error("Admission submission has no confirmed engine acceptance");
609
+ throw o !== void 0 && o.receiptsBound && o.failureId === null && o.executionId === null && o.runId === null && (o.preparedExecutionId === null ? o.dispatchAttempts === 0 : o.preparedExecutionId.length > 0) && o.workflowName === a.workflowName && o.tenantId === a.tenantId && o.ledgerId === a.ledgerId ? new U(t.id, e) : e;
610
+ }
608
611
  return o.executionId;
609
612
  }, $ = async (e, t, n, r, i, a, o) => {
610
613
  let s = t.dispatchAttempts === 0 ? 0 : void 0, u = t.retry.recovery?.attempts ?? 0;
@@ -701,5 +704,4 @@ var V = {
701
704
  ...i === void 0 ? {} : { nextDeadlineAt: i }
702
705
  };
703
706
  };
704
- //#endregion
705
707
  export { H as DEFAULT_DRAIN_BATCH, ee as acceptAdmissionSubmission, G as drainTick, W as isUnacknowledgedSubmission };
@@ -1,7 +1,7 @@
1
1
  import { resolveAdmissionKeys as e } from "./admission.js";
2
2
  import { decodePendingPayload as t, evaluateAdmission as n, persistDefer as r, recordAdmission as i } from "./admissionStore.js";
3
3
  import { and as a, eq as o } from "@voltro/database";
4
- //#region src/admissionGate.ts
4
+ // src/admissionGate.ts
5
5
  var s = async (t) => {
6
6
  let { store: a, control: o, now: s } = t, l = e(o, t.payload), u = await n({
7
7
  store: a,
@@ -111,5 +111,4 @@ var s = async (t) => {
111
111
  runId: r
112
112
  });
113
113
  };
114
- //#endregion
115
114
  export { s as admitStart, l as linkExecution };
@@ -4,7 +4,7 @@ import { comparePendingOrder as r, decideAdmission as i } from "./admission.js";
4
4
  import { settlePendingStartReceipts as a } from "./startReceipt.js";
5
5
  import { and as o, eq as s, gt as c, isNull as l, or as u } from "@voltro/database";
6
6
  import { createHash as d, randomUUID as f } from "node:crypto";
7
- //#region src/admissionStore.ts
7
+ // src/admissionStore.ts
8
8
  var p = "_voltro_workflow_pending", m = "_voltro_workflow_admissions", h = "_voltro_workflow_pauses", g = (e) => o(l("releasedAt"), u(l("executionId"), c("expiresAt", new Date(e)))), _ = (e, t, n) => e.encodeWorkflowPayload === void 0 ? n : e.encodeWorkflowPayload(t, n), v = (e, t, n) => e.decodeWorkflowPayload === void 0 ? n : e.decodeWorkflowPayload(t, n), y = 864e5, b = (e, t, n) => `wfp_${d("sha256").update(`${e}\u0000${t}\u0000${n}`).digest("hex").slice(0, 40)}`, x = (e) => {
9
9
  if (e instanceof Date) return e.getTime();
10
10
  if (typeof e == "number") return e;
@@ -343,5 +343,4 @@ var p = "_voltro_workflow_pending", m = "_voltro_workflow_admissions", h = "_vol
343
343
  }], n)), i = t.getTime(), a = r.filter((e) => e.releasedAt != null && x(e.admittedAt) < i);
344
344
  return await Promise.all(a.map((t) => e.delete(m, String(t.id)))), a.length;
345
345
  };
346
- //#endregion
347
346
  export { m as ADMISSIONS_TABLE, y as DEFAULT_LEASE_MS, h as PAUSES_TABLE, p as PENDING_TABLE, g as admissionLeaseHeldPredicate, L as allIntents, U as deadLetterIntent, v as decodePendingPayload, R as deleteIntent, z as discardIntent, B as discardIntentInTransaction, F as dueIntents, _ as encodePendingPayload, G as evaluateAdmission, H as noteIntentAttempt, j as parkDelayedStart, E as pauseWorkflow, b as pendingSlotId, I as pendingWindow, A as persistDefer, K as pruneAdmissions, O as readAdmissionState, T as readPausedWorkflows, N as recordAdmission, P as releaseLease, D as resumeWorkflow, V as retryBackoffMs, W as retryDeadLetterIntent, C as toPendingIntent };
@@ -9,7 +9,7 @@ import { Schema as f } from "effect";
9
9
  import { and as p, eq as m, gt as h, isNull as g } from "@voltro/database";
10
10
  import { createHash as _, randomUUID as v } from "node:crypto";
11
11
  import { isDeepStrictEqual as y } from "node:util";
12
- //#region src/admissionSubmission.ts
12
+ // src/admissionSubmission.ts
13
13
  var b = "_voltro_workflow_submissions", x = "wfsub", S = () => `${x}_${v()}`, C = f.Struct({
14
14
  id: f.String,
15
15
  workflowName: f.String,
@@ -293,5 +293,4 @@ var E = async (e, t, n) => (await D(e, t, n)).map((e) => w(e)), D = async (e, t,
293
293
  if (await e.update("_voltro_workflow_submissions", t, { failureId: u }) === null) throw Error("Admission submission disappeared during rejection");
294
294
  return await a(e, d.id, s.now), d;
295
295
  };
296
- //#endregion
297
296
  export { x as ADMISSION_SUBMISSION_ID_PREFIX, b as SUBMISSIONS_TABLE, M as acknowledgeAdmissionSubmission, N as acknowledgeAdmissionSubmissionInTransaction, I as beginAdmissionSubmissionDispatchInTransaction, w as decodeAdmissionSubmission, T as dispatchedExecutionSubmissions, S as newAdmissionSubmissionId, F as noteAdmissionSubmissionFailure, E as pendingAdmissionSubmissions, j as persistReservedSubmission, P as prepareAdmissionSubmissionExecutionInTransaction, O as readAdmissionSubmission, D as readPendingAdmissionSubmissionRows, L as rejectAdmissionSubmissionInTransaction, k as reserveAdmissionSubmission, A as reserveAdmissionSubmissionInTransaction };
@@ -1,5 +1,5 @@
1
1
  import { boolean as e, id as t, integer as n, json as r, real as i, table as a, text as o, timestamp as s } from "@voltro/database";
2
- //#region src/admissionTables.ts
2
+ // src/admissionTables.ts
3
3
  var c = a("_voltro_workflow_admission_locks", {
4
4
  id: t({ prefix: "wfalk" }),
5
5
  nonce: o()
@@ -67,8 +67,9 @@ var c = a("_voltro_workflow_admission_locks", {
67
67
  payload: r(),
68
68
  callerContext: r().nullable(),
69
69
  intentIds: r(),
70
- eviction: r().nullable()
71
- }).nonReactive(), p = a("_voltro_workflow_start_receipts", {
70
+ eviction: r().nullable(),
71
+ poolReleaseSettledAt: s().nullable()
72
+ }).index("_voltro_workflow_submissions_pool_settlement_idx", ["poolReleaseSettledAt", "id"]).nonReactive(), p = a("_voltro_workflow_start_receipts", {
72
73
  id: t({ prefix: "wfrc" }),
73
74
  workflowName: o(),
74
75
  tenantId: o().nullable(),
@@ -133,5 +134,4 @@ var c = a("_voltro_workflow_admission_locks", {
133
134
  pausedBy: o().nullable(),
134
135
  reason: o().nullable()
135
136
  });
136
- //#endregion
137
137
  export { c as _voltroWorkflowAdmissionLocksTable, h as _voltroWorkflowAdmissionsTable, u as _voltroWorkflowControlRequestsTable, d as _voltroWorkflowFailureReportsTable, l as _voltroWorkflowParentClosuresTable, g as _voltroWorkflowPausesTable, m as _voltroWorkflowPendingTable, p as _voltroWorkflowStartReceiptsTable, f as _voltroWorkflowSubmissionsTable };
@@ -1,6 +1,6 @@
1
1
  import { eq as e } from "@voltro/database";
2
2
  import { randomUUID as t } from "node:crypto";
3
- //#region src/admissionTransaction.ts
3
+ // src/admissionTransaction.ts
4
4
  var n = "_voltro_workflow_admission_locks", r = "deployment", i = async (i, a) => (await i.insertIgnoreWithOutcome(n, {
5
5
  id: r,
6
6
  nonce: t()
@@ -17,5 +17,4 @@ var n = "_voltro_workflow_admission_locks", r = "deployment", i = async (i, a) =
17
17
  if (await n.update("_voltro_workflow_admission_locks", r, { nonce: t() }) === null) throw Error("Admission coordinator row disappeared; refusing an unlocked decision");
18
18
  return a(n);
19
19
  }));
20
- //#endregion
21
20
  export { n as ADMISSION_LOCKS_TABLE, i as withAdmissionTransaction };
@@ -2,7 +2,7 @@ import { encryptionAwareActivity as e } from "./journalEncryption.js";
2
2
  import { CurrentWorkflowRunId as t, WorkflowRunRecorder as n } from "./recorder.js";
3
3
  import { Effect as r, Schema as i } from "effect";
4
4
  import { and as a, eq as o, gte as s } from "@voltro/database";
5
- //#region src/awaitEvent.ts
5
+ // src/awaitEvent.ts
6
6
  var c = async (e, t) => {
7
7
  if (e !== void 0) try {
8
8
  await e.recordEvent(t);
@@ -78,5 +78,4 @@ var c = async (e, t) => {
78
78
  }
79
79
  return /* @__PURE__ */ new Date(0);
80
80
  });
81
- //#endregion
82
81
  export { l as awaitEvent };
@@ -1,7 +1,7 @@
1
1
  import { awaitSignalSuspending as e, completeSuspendingSignal as t } from "./signalsSuspending.js";
2
2
  import { Cause as n, Effect as r, Schema as i } from "effect";
3
3
  import { and as a, eq as o, generateId as s, id as c, isNull as l, registerRetention as u, retentionTtlMsFromEnv as d, table as f, text as p, timestamp as m } from "@voltro/database";
4
- //#region src/budgetHold.ts
4
+ // src/budgetHold.ts
5
5
  var h = "_voltro_budget_holds", g = "budget-hold", _ = (e) => `${g}:${e}`, v = (e) => `${e.executionId}/${e.stepName}/${e.budget}#${e.generation}`, y = async (e, t) => (await e.query({
6
6
  table: h,
7
7
  predicate: a(o("executionId", t.executionId), o("stepName", t.stepName), o("budget", t.budget)),
@@ -132,5 +132,4 @@ var h = "_voltro_budget_holds", g = "budget-hold", _ = (e) => `${g}:${e}`, v = (
132
132
  }
133
133
  return [...n.values()];
134
134
  };
135
- //#endregion
136
135
  export { h as BUDGET_HOLDS_TABLE, S as BudgetHoldExpired, C as DEFAULT_BUDGET_HOLD_TIMEOUT_MS, w as DEFAULT_BUDGET_RECHECK_MS, b as _voltroBudgetHoldsTable, y as budgetHoldGeneration, v as budgetHoldKey, _ as budgetHoldSignalName, j as heldBudgets, A as pendingBudgetHolds, k as releaseBudgetHolds, T as suspendForBudget };
@@ -1,5 +1,5 @@
1
1
  import { Result as e, Schema as t } from "effect";
2
- //#region src/cancelOnPlan.ts
2
+ // src/cancelOnPlan.ts
3
3
  var n = (e) => {
4
4
  let t = e instanceof Error ? e.message : String(e);
5
5
  return t.length > 400 ? `${t.slice(0, 400)}…` : t;
@@ -71,5 +71,4 @@ var n = (e) => {
71
71
  for (let n of e) (t === void 0 || n.occurredAt.getTime() > t.getTime()) && (t = n.occurredAt);
72
72
  return t;
73
73
  };
74
- //#endregion
75
74
  export { i as newestEventAt, r as planCancellations };
@@ -1,6 +1,6 @@
1
1
  import { newestEventAt as e, planCancellations as t } from "./cancelOnPlan.js";
2
2
  import { and as n, eq as r, gte as i } from "@voltro/database";
3
- //#region src/cancelOnSweep.ts
3
+ // src/cancelOnSweep.ts
4
4
  var a = "_voltro_workflow_watermarks", o = "_voltro_workflow_events", s = "cancelOn", c = 36e5, l = 500, u = 2e3, d = (e) => {
5
5
  if (e instanceof Date) return e;
6
6
  if (typeof e == "number") return new Date(e);
@@ -184,5 +184,4 @@ var a = "_voltro_workflow_watermarks", o = "_voltro_workflow_events", s = "cance
184
184
  watermark: A
185
185
  };
186
186
  };
187
- //#endregion
188
187
  export { s as CANCEL_ON_WATERMARK, c as DEFAULT_COLD_LOOKBACK_MS, l as DEFAULT_EVENT_BATCH, u as DEFAULT_RUN_PAGE, o as EVENTS_TABLE, a as WATERMARKS_TABLE, p as readWatermark, _ as sweepCancelOn, m as writeWatermark };
@@ -2,7 +2,7 @@ import { readAdmissionSubmission as e } from "./admissionSubmission.js";
2
2
  import { readWorkflowStartReceipt as t, settlePendingStartReceipts as n } from "./startReceipt.js";
3
3
  import { PENDING_TABLE as r, toPendingIntent as i } from "./admissionStore.js";
4
4
  import { eq as a } from "@voltro/database";
5
- //#region src/cancelPendingStart.ts
5
+ // src/cancelPendingStart.ts
6
6
  var o = async (o, s) => {
7
7
  if (!Number.isFinite(s.now) || !Number.isFinite(new Date(s.now).getTime())) throw Error("Queued cancellation requires a valid timestamp");
8
8
  let c = await t(o, s.receiptId);
@@ -46,5 +46,4 @@ var o = async (o, s) => {
46
46
  outcome: d
47
47
  };
48
48
  };
49
- //#endregion
50
49
  export { o as cancelPendingWorkflowStartInTransaction };
@@ -1,7 +1,7 @@
1
1
  import { captureWorkflowShardGroups as e } from "./clusterShardGroups.js";
2
2
  import { Duration as t, Effect as n } from "effect";
3
3
  import { ClusterCron as r } from "effect/cluster";
4
- //#region src/clusterCron.ts
4
+ // src/clusterCron.ts
5
5
  var i = (i) => {
6
6
  let a = i.shardGroup;
7
7
  return a !== void 0 && e({
@@ -15,5 +15,4 @@ var i = (i) => {
15
15
  skipIfOlderThan: i.skipIfOlderThan ?? t.days(1)
16
16
  });
17
17
  };
18
- //#endregion
19
18
  export { i as makeClusterCronLayer };
@@ -1,5 +1,5 @@
1
1
  import { Context as e, Effect as t } from "effect";
2
- //#region src/clusterDiagnostics.ts
2
+ // src/clusterDiagnostics.ts
3
3
  var n = 6e5, r = class extends e.Service()("@voltro/workflow/ClusterDiagnostics") {}, i = (e, n, r = Date.now()) => t.flatMap(e.messagesFor(n), (n) => {
4
4
  if (n.length === 0) return t.succeed(void 0);
5
5
  let i = [...new Set(n.filter((e) => !e.processed).map((e) => e.shardId))], a = i.length === 0 ? t.succeed([]) : e.shardLockHolders(i);
@@ -16,5 +16,4 @@ var n = 6e5, r = class extends e.Service()("@voltro/workflow/ClusterDiagnostics"
16
16
  shardLocks: t
17
17
  }));
18
18
  });
19
- //#endregion
20
19
  export { n as CLUSTER_REREAD_WINDOW_MS, r as ClusterDiagnostics, i as describeStalledRun };
@@ -1,7 +1,7 @@
1
1
  import { CLUSTER_REREAD_WINDOW_MS as e } from "./clusterDiagnostics.js";
2
2
  import { Effect as t } from "effect";
3
3
  import { SqlClient as n } from "effect/sql";
4
- //#region src/clusterDiagnosticsSql.ts
4
+ // src/clusterDiagnosticsSql.ts
5
5
  var r = (e) => {
6
6
  if (e instanceof Date) return Number.isNaN(e.getTime()) ? null : e;
7
7
  if (typeof e == "string" || typeof e == "number") {
@@ -141,5 +141,4 @@ var r = (e) => {
141
141
  }
142
142
  };
143
143
  });
144
- //#endregion
145
144
  export { o as clusterLockNamespaceOid, c as makeClusterDiagnostics };
@@ -20,7 +20,7 @@ import { SqlClient as w } from "effect/sql";
20
20
  import { ClusterWorkflowEngine as T, MessageStorage as E, RunnerAddress as D, ShardId as O, Sharding as k } from "effect/cluster";
21
21
  import { sqlPoolCapacity as A } from "@voltro/database/sql";
22
22
  import { createLogger as j } from "@voltro/logger";
23
- //#region src/clusterLayer.ts
23
+ // src/clusterLayer.ts
24
24
  var M = j({ scope: "voltro:workflow" }), N = 34e3, P = (e) => {
25
25
  let t = e.runnerListenHost ?? process.env.POD_IP ?? process.env.VOLTRO_WORKFLOW_RUNNER_HOST ?? "localhost";
26
26
  return {
@@ -141,5 +141,4 @@ var M = j({ scope: "voltro:workflow" }), N = 34e3, P = (e) => {
141
141
  }), oe = v.layer.pipe(S.provide(v.layerStoreMemory));
142
142
  return S.merge(ie, oe).pipe(S.provideMerge(ae), S.flatMap((e) => S.succeedContext(o(e, y.get(e, _.WorkflowEngine), N, L, V))));
143
143
  };
144
- //#endregion
145
144
  export { N as DEFAULT_RUNNER_LISTEN_PORT, L as detectWsrepCluster, I as parseShardLockMode, V as pollWorkflowStorage, B as resolveFailoverTuning, P as resolveRunnerIdentity, F as resolveRunnerStorage, R as resolveShardLockDisableAdvisory, z as shardLockLogFields, W as workflowEngineLayer };
@@ -3,7 +3,7 @@ import { Effect as t, Layer as n } from "effect";
3
3
  import { SqlClient as r } from "effect/sql";
4
4
  import { ShardingConfig as i, SqlMessageStorage as a, SqlRunnerStorage as o } from "effect/cluster";
5
5
  import { applyUndeclaredCharsetWork as s, fnv1a64 as c, readUndeclaredCharsetColumns as l, resolveMigrationLockSchema as u, sqlPoolCapacity as d, undeclaredCharsetWork as f } from "@voltro/database/sql";
6
- //#region src/clusterMigrationGate.ts
6
+ // src/clusterMigrationGate.ts
7
7
  var p = 6322741009312601n, m = () => {
8
8
  let e = u();
9
9
  return e === void 0 ? p : c(`voltro_cluster_migration_lock:${e}`) & 9223372036854775807n;
@@ -57,5 +57,4 @@ var p = 6322741009312601n, m = () => {
57
57
  let n = yield* r.SqlClient, i = k(e.runnerStorage), a = d(n);
58
58
  return a !== void 0 && a < i ? yield* t.die(/* @__PURE__ */ Error(`the workflow runtime needs ${i} database connections at once and the pool has ${a}: ` + (e.runnerStorage === "sql" ? "on a first boot it holds its migration lock and its runner lock while the migration runs on a third, and once running it keeps the runner lock and needs one more to work. " : "on a first boot it holds its migration lock while the migration runs on a second. ") + `Set DB_MAX_CONNECTIONS (or PG_MAX_CONNECTIONS) to at least ${i}` + (e.runnerStorage === "sql" ? ", or VOLTRO_WORKFLOW_RUNNER_STORAGE=memory for a single-process runtime that needs 2 (no cross-pod shard handoff)." : "."))) : ((yield* w(n, e.runnerStorage)) || (yield* x(n, O(n, e.runnerStorage, e.charset))), n);
59
59
  }));
60
- //#endregion
61
60
  export { k as clusterConnectionFloor, A as clusterMigrationGateLayer, C as tableExists, x as withClusterMigrationLock };
@@ -7,7 +7,7 @@ import { guardRunnerStorage as o } from "./runnerStorageGuard.js";
7
7
  import { Effect as s, Layer as c, Option as l, Semaphore as u } from "effect";
8
8
  import { SqlClient as d } from "effect/sql";
9
9
  import { MessageStorage as f, RunnerHealth as p, RunnerStorage as m, Runners as h, Sharding as g, ShardingConfig as _, SqlMessageStorage as v, SqlRunnerStorage as y } from "effect/cluster";
10
- //#region src/clusterRunnerLayer.ts
10
+ // src/clusterRunnerLayer.ts
11
11
  var b = (e) => s.map(u.make(1), (t) => ({
12
12
  ...e,
13
13
  release: (n, r) => t.withPermits(1)(s.suspend(() => e.release(n, r)))
@@ -27,5 +27,4 @@ var b = (e) => s.map(u.make(1), (t) => ({
27
27
  let r = yield* g.Sharding, a = yield* s.serviceOption(e), o = yield* s.serviceOption(t), c = l.isSome(o) ? n(r, o.value) : r;
28
28
  return l.isSome(a) ? i(c, a.value) : c;
29
29
  })).pipe(c.provide(g.layer)), T = (e) => w.pipe(c.provideMerge(h.layerNoop), c.provideMerge(C), c.provide([e.runnerStorage === "memory" ? m.layerMemory : e.clientOnly ? c.orDie(x) : S(e.guard), p.layerNoop]), c.provide(_.layerFromEnv(e.shardingConfig)), c.provide(r));
30
- //#endregion
31
30
  export { T as clusterRunnerLayer, b as limitSqliteShardReleases };
@@ -1,4 +1,4 @@
1
- //#region src/clusterShardGroups.ts
1
+ // src/clusterShardGroups.ts
2
2
  var e = (e, t) => {
3
3
  if (e === void 0) return;
4
4
  if (!e || typeof e != "object" || Array.isArray(e) || ![Object.prototype, null].includes(Object.getPrototypeOf(e))) throw Error("Workflow shard groups require a plain data object");
@@ -29,5 +29,4 @@ var e = (e, t) => {
29
29
  assigned: a
30
30
  });
31
31
  };
32
- //#endregion
33
32
  export { e as captureWorkflowShardGroups };
@@ -36,6 +36,26 @@ export declare interface ClusterEngineFixture {
36
36
  readonly reachable: () => Promise<boolean>;
37
37
  }
38
38
 
39
+ /** Test-runner operations supplied by the suite caller, outside the runtime graph. */
40
+ export declare interface ClusterSuiteTestApi {
41
+ readonly describe: (name: string, body: () => void) => unknown;
42
+ readonly test: (name: string, body: (context: {
43
+ readonly skip: () => void;
44
+ }) => Promise<void>, timeoutMs?: number) => unknown;
45
+ readonly beforeAll: (body: () => Promise<void>, timeoutMs?: number) => unknown;
46
+ readonly afterEach: (body: () => void | Promise<void>) => unknown;
47
+ readonly expect: (actual: unknown, message?: string) => {
48
+ readonly toBe: (expected: unknown) => unknown;
49
+ readonly toEqual: (expected: unknown) => unknown;
50
+ readonly toContain: (expected: unknown) => unknown;
51
+ readonly toBeGreaterThan: (expected: number) => unknown;
52
+ readonly toBeGreaterThanOrEqual: (expected: number) => unknown;
53
+ readonly rejects: {
54
+ readonly toThrow: () => Promise<unknown>;
55
+ };
56
+ };
57
+ }
58
+
39
59
  declare interface JournalRoutingState {
40
60
  readonly generation: number;
41
61
  readonly layout: string;
@@ -75,9 +95,9 @@ export declare const purgeClusterState: (fixture: ClusterEngineFixture) => Promi
75
95
  * `@voltro/sql-*` (or the workflow package) calls this from a thin
76
96
  * `cluster.<dialect>.integration.test.ts` with its fixture.
77
97
  */
78
- export declare const runClusterEngineSuite: (fixture: ClusterEngineFixture) => void;
98
+ export declare const runClusterEngineSuite: (fixture: ClusterEngineFixture, tests: ClusterSuiteTestApi) => void;
79
99
 
80
- export declare const runJournalEncryptionSuite: (fixture: ClusterEngineFixture) => void;
100
+ export declare const runJournalEncryptionSuite: (fixture: ClusterEngineFixture, tests: ClusterSuiteTestApi) => void;
81
101
 
82
102
  /**
83
103
  * Runner-storage backend for `effect/cluster.SingleRunner`.