@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.
package/dist/index.d.ts CHANGED
@@ -603,9 +603,10 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
603
603
  kind: "settled";
604
604
  request: {
605
605
  readonly id: string;
606
+ readonly operation: "resume" | "cancel" | "terminate";
606
607
  readonly result: {
607
608
  readonly kind: "confirmed" | "already-terminal";
608
- readonly status: "failed" | "cancelled" | "succeeded";
609
+ readonly status: "failed" | "succeeded" | "cancelled";
609
610
  readonly completedAt: number;
610
611
  readonly output: unknown;
611
612
  readonly errorTag: string | null;
@@ -616,7 +617,6 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
616
617
  readonly enteredAt: number;
617
618
  readonly generation: string;
618
619
  } | null;
619
- readonly operation: "resume" | "cancel" | "terminate";
620
620
  readonly generation: string;
621
621
  readonly runId: string;
622
622
  readonly requestedAt: number;
@@ -643,9 +643,10 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
643
643
  kind: "unknown";
644
644
  request: {
645
645
  readonly id: string;
646
+ readonly operation: "resume" | "cancel" | "terminate";
646
647
  readonly result: {
647
648
  readonly kind: "confirmed" | "already-terminal";
648
- readonly status: "failed" | "cancelled" | "succeeded";
649
+ readonly status: "failed" | "succeeded" | "cancelled";
649
650
  readonly completedAt: number;
650
651
  readonly output: unknown;
651
652
  readonly errorTag: string | null;
@@ -656,7 +657,6 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
656
657
  readonly enteredAt: number;
657
658
  readonly generation: string;
658
659
  } | null;
659
- readonly operation: "resume" | "cancel" | "terminate";
660
660
  readonly generation: string;
661
661
  readonly runId: string;
662
662
  readonly requestedAt: number;
@@ -683,9 +683,10 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
683
683
  kind: "superseded";
684
684
  request: {
685
685
  readonly id: string;
686
+ readonly operation: "resume" | "cancel" | "terminate";
686
687
  readonly result: {
687
688
  readonly kind: "confirmed" | "already-terminal";
688
- readonly status: "failed" | "cancelled" | "succeeded";
689
+ readonly status: "failed" | "succeeded" | "cancelled";
689
690
  readonly completedAt: number;
690
691
  readonly output: unknown;
691
692
  readonly errorTag: string | null;
@@ -696,7 +697,6 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
696
697
  readonly enteredAt: number;
697
698
  readonly generation: string;
698
699
  } | null;
699
- readonly operation: "resume" | "cancel" | "terminate";
700
700
  readonly generation: string;
701
701
  readonly runId: string;
702
702
  readonly requestedAt: number;
@@ -723,9 +723,10 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
723
723
  kind: "already-terminal";
724
724
  request: {
725
725
  readonly id: string;
726
+ readonly operation: "resume" | "cancel" | "terminate";
726
727
  readonly result: {
727
728
  readonly kind: "confirmed" | "already-terminal";
728
- readonly status: "failed" | "cancelled" | "succeeded";
729
+ readonly status: "failed" | "succeeded" | "cancelled";
729
730
  readonly completedAt: number;
730
731
  readonly output: unknown;
731
732
  readonly errorTag: string | null;
@@ -736,7 +737,6 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
736
737
  readonly enteredAt: number;
737
738
  readonly generation: string;
738
739
  } | null;
739
- readonly operation: "resume" | "cancel" | "terminate";
740
740
  readonly generation: string;
741
741
  readonly runId: string;
742
742
  readonly requestedAt: number;
@@ -764,9 +764,10 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
764
764
  request: {
765
765
  dispatchAttempts: number;
766
766
  id: string;
767
+ operation: "resume" | "cancel" | "terminate";
767
768
  result: {
768
769
  readonly kind: "confirmed" | "already-terminal";
769
- readonly status: "failed" | "cancelled" | "succeeded";
770
+ readonly status: "failed" | "succeeded" | "cancelled";
770
771
  readonly completedAt: number;
771
772
  readonly output: unknown;
772
773
  readonly errorTag: string | null;
@@ -777,7 +778,6 @@ export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id:
777
778
  readonly enteredAt: number;
778
779
  readonly generation: string;
779
780
  } | null;
780
- operation: "resume" | "cancel" | "terminate";
781
781
  generation: string;
782
782
  runId: string;
783
783
  requestedAt: number;
@@ -814,9 +814,10 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
814
814
  kind: "settled";
815
815
  request: {
816
816
  readonly id: string;
817
+ readonly operation: "resume" | "cancel" | "terminate";
817
818
  readonly result: {
818
819
  readonly kind: "confirmed" | "already-terminal";
819
- readonly status: "failed" | "cancelled" | "succeeded";
820
+ readonly status: "failed" | "succeeded" | "cancelled";
820
821
  readonly completedAt: number;
821
822
  readonly output: unknown;
822
823
  readonly errorTag: string | null;
@@ -827,7 +828,6 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
827
828
  readonly enteredAt: number;
828
829
  readonly generation: string;
829
830
  } | null;
830
- readonly operation: "resume" | "cancel" | "terminate";
831
831
  readonly generation: string;
832
832
  readonly runId: string;
833
833
  readonly requestedAt: number;
@@ -853,9 +853,10 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
853
853
  kind: "unknown";
854
854
  request: {
855
855
  readonly id: string;
856
+ readonly operation: "resume" | "cancel" | "terminate";
856
857
  readonly result: {
857
858
  readonly kind: "confirmed" | "already-terminal";
858
- readonly status: "failed" | "cancelled" | "succeeded";
859
+ readonly status: "failed" | "succeeded" | "cancelled";
859
860
  readonly completedAt: number;
860
861
  readonly output: unknown;
861
862
  readonly errorTag: string | null;
@@ -866,7 +867,6 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
866
867
  readonly enteredAt: number;
867
868
  readonly generation: string;
868
869
  } | null;
869
- readonly operation: "resume" | "cancel" | "terminate";
870
870
  readonly generation: string;
871
871
  readonly runId: string;
872
872
  readonly requestedAt: number;
@@ -892,9 +892,10 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
892
892
  kind: "superseded";
893
893
  request: {
894
894
  readonly id: string;
895
+ readonly operation: "resume" | "cancel" | "terminate";
895
896
  readonly result: {
896
897
  readonly kind: "confirmed" | "already-terminal";
897
- readonly status: "failed" | "cancelled" | "succeeded";
898
+ readonly status: "failed" | "succeeded" | "cancelled";
898
899
  readonly completedAt: number;
899
900
  readonly output: unknown;
900
901
  readonly errorTag: string | null;
@@ -905,7 +906,6 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
905
906
  readonly enteredAt: number;
906
907
  readonly generation: string;
907
908
  } | null;
908
- readonly operation: "resume" | "cancel" | "terminate";
909
909
  readonly generation: string;
910
910
  readonly runId: string;
911
911
  readonly requestedAt: number;
@@ -931,9 +931,10 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
931
931
  kind: "not-suspended";
932
932
  request: {
933
933
  readonly id: string;
934
+ readonly operation: "resume" | "cancel" | "terminate";
934
935
  readonly result: {
935
936
  readonly kind: "confirmed" | "already-terminal";
936
- readonly status: "failed" | "cancelled" | "succeeded";
937
+ readonly status: "failed" | "succeeded" | "cancelled";
937
938
  readonly completedAt: number;
938
939
  readonly output: unknown;
939
940
  readonly errorTag: string | null;
@@ -944,7 +945,6 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
944
945
  readonly enteredAt: number;
945
946
  readonly generation: string;
946
947
  } | null;
947
- readonly operation: "resume" | "cancel" | "terminate";
948
948
  readonly generation: string;
949
949
  readonly runId: string;
950
950
  readonly requestedAt: number;
@@ -970,9 +970,10 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
970
970
  kind: "bound";
971
971
  request: {
972
972
  readonly id: string;
973
+ readonly operation: "resume" | "cancel" | "terminate";
973
974
  readonly result: {
974
975
  readonly kind: "confirmed" | "already-terminal";
975
- readonly status: "failed" | "cancelled" | "succeeded";
976
+ readonly status: "failed" | "succeeded" | "cancelled";
976
977
  readonly completedAt: number;
977
978
  readonly output: unknown;
978
979
  readonly errorTag: string | null;
@@ -983,7 +984,6 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
983
984
  readonly enteredAt: number;
984
985
  readonly generation: string;
985
986
  } | null;
986
- readonly operation: "resume" | "cancel" | "terminate";
987
987
  readonly generation: string;
988
988
  readonly runId: string;
989
989
  readonly requestedAt: number;
@@ -1009,9 +1009,10 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
1009
1009
  kind: "waiting-journal";
1010
1010
  request: {
1011
1011
  readonly id: string;
1012
+ readonly operation: "resume" | "cancel" | "terminate";
1012
1013
  readonly result: {
1013
1014
  readonly kind: "confirmed" | "already-terminal";
1014
- readonly status: "failed" | "cancelled" | "succeeded";
1015
+ readonly status: "failed" | "succeeded" | "cancelled";
1015
1016
  readonly completedAt: number;
1016
1017
  readonly output: unknown;
1017
1018
  readonly errorTag: string | null;
@@ -1022,7 +1023,6 @@ export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: str
1022
1023
  readonly enteredAt: number;
1023
1024
  readonly generation: string;
1024
1025
  } | null;
1025
- readonly operation: "resume" | "cancel" | "terminate";
1026
1026
  readonly generation: string;
1027
1027
  readonly runId: string;
1028
1028
  readonly requestedAt: number;
@@ -1961,6 +1961,11 @@ export declare const isWorkflowEncrypted: (name: string) => boolean;
1961
1961
 
1962
1962
  export declare const isWorkflowWorkerLayer: (value: unknown) => value is WorkflowWorkerLayerBrand;
1963
1963
 
1964
+ export declare interface JournalRoutingState {
1965
+ readonly generation: number;
1966
+ readonly layout: string;
1967
+ }
1968
+
1964
1969
  /**
1965
1970
  * Attach the engine's execution id to the ledger row written by
1966
1971
  * {@link admitStart}.
@@ -4159,6 +4164,17 @@ declare type WorkflowFn = <const Name extends string, Payload extends WorkflowPa
4159
4164
  readonly name: Name;
4160
4165
  } & WorkflowMessagesCarrier<NormaliseWorkflowMessages<Messages>>;
4161
4166
 
4167
+ /** Journal routing generation per PostgreSQL journal namespace. Declared, so the
4168
+ * schema owns it (plan, fingerprint, backup); the maintenance transition only
4169
+ * reads and writes it inside its pinned journal transaction. */
4170
+ export declare const workflowJournalRoutingTable: Table<"_voltro_workflow_journal_routing", FieldDefinitions<{
4171
+ readonly id: ColumnBuilder<string, "id", boolean>;
4172
+ readonly namespace: ColumnBuilder<string, "text", boolean>;
4173
+ readonly generation: ColumnBuilder<string, "bigint", boolean>;
4174
+ readonly layout: ColumnBuilder<string, "text", boolean>;
4175
+ readonly relocation: ColumnBuilder<string, "text", boolean>;
4176
+ }>, false, never>;
4177
+
4162
4178
  declare type WorkflowMake = typeof workflowModule.make;
4163
4179
 
4164
4180
  export declare interface WorkflowMessagePairSchemas {
@@ -4584,6 +4600,15 @@ export declare type WorkflowScheduleOverlap = 'skip' | 'buffer' | 'cancelOther';
4584
4600
  * that crossed a bundler boundary, and symbols do not survive every one. */
4585
4601
  export declare const WorkflowScheduleProperty = "__voltroWorkflowSchedule";
4586
4602
 
4603
+ /** Explicit routing inventory shared by every runner in one cluster. Changing
4604
+ * groups changes persistent addresses; this is not a journal migration. */
4605
+ /** Group names are at most 32 ASCII characters: group + colon + a safe integer
4606
+ * slot fits the existing SQL journal shard_id VARCHAR(50) on every dialect. */
4607
+ export declare interface WorkflowShardGroups {
4608
+ readonly available: ReadonlyArray<string>;
4609
+ readonly assigned: ReadonlyArray<string>;
4610
+ }
4611
+
4587
4612
  /**
4588
4613
  * At most one run per key. The newcomer either stands down or evicts.
4589
4614
  *
package/dist/index.js CHANGED
@@ -24,26 +24,27 @@ import { stageWorkflowParentClosureInTransaction as kt } from "./parentClosure.j
24
24
  import { readWorkflowRestartObservationInTransaction as At, reserveWorkflowRestartInTransaction as jt, withdrawWorkflowRestartInTransaction as Mt, workflowRestartRequestsTable as Nt, workflowRestartWithdrawalsTable as Pt } from "./workflowRestartReservation.js";
25
25
  import { cancelSuspendedWorkflowRunInTransaction as Ft, completeWorkflowRunGenerationInTransaction as It, enterWorkflowRunGenerationInTransaction as Lt } from "./runGeneration.js";
26
26
  import { queuedCancellationRequestsTable as Rt } from "./queuedCancellationRequest.js";
27
- import { cancelQueuedWorkflowStartInTransaction as zt, readQueuedWorkflowCancellationInTransaction as Bt } from "./queuedControl.js";
28
- import { inspectAdmissionSubmissionRetry as Vt, retryAdmissionSubmissionInTransaction as Ht } from "./submissionRetry.js";
29
- import { takeAdmittedSubmissionInTransaction as Ut, takePendingAdmissionSubmission as Wt } from "./pendingSubmission.js";
30
- import { admitStart as Gt, linkExecution as Kt } from "./admissionGate.js";
31
- import { _voltroWorkflowWatermarksTable as qt } from "./watermarkTable.js";
32
- import { newestEventAt as Jt, planCancellations as Yt } from "./cancelOnPlan.js";
33
- import { CANCEL_ON_WATERMARK as Xt, DEFAULT_COLD_LOOKBACK_MS as Zt, DEFAULT_EVENT_BATCH as Qt, EVENTS_TABLE as $t, WATERMARKS_TABLE as en, readWatermark as tn, sweepCancelOn as nn, writeWatermark as rn } from "./cancelOnSweep.js";
34
- import { DEFAULT_STALL_AFTER_MS as an, DEFAULT_STALL_EVENT_LOOKBACK as on, DEFAULT_STALL_RUN_PAGE as sn, sweepStalledRuns as cn } from "./stalenessSweep.js";
35
- import { CLUSTER_REREAD_WINDOW_MS as ln, ClusterDiagnostics as un, describeStalledRun as dn } from "./clusterDiagnostics.js";
36
- import { DEFAULT_DRAIN_BATCH as fn, acceptAdmissionSubmission as pn, drainTick as mn, isUnacknowledgedSubmission as hn } from "./admissionDrainer.js";
37
- import { DEFAULT_SUSPEND_HINT_MS as gn, maybeHintSuspendingSignal as _n, resetSuspendHintsForTest as vn, resolveSuspendHintMs as yn, setSuspendSignalHintMs as bn } from "./signalHint.js";
38
- import { awaitSignal as xn } from "./signals.js";
39
- import { awaitEvent as Sn } from "./awaitEvent.js";
40
- import { SuspensionUnavailable as Cn, WorkflowCannotPark as wn } from "./suspensionUnavailable.js";
41
- import { makeWorkflowUpdateId as Tn, resolveWorkflowMessageRun as En, sendWorkflowSignal as Dn, sendWorkflowUpdate as On } from "./messages.js";
42
- import { awaitSignalSuspending as kn, completeSuspendingSignal as An, suspendingSignalDeferredName as jn } from "./signalsSuspending.js";
43
- import { BUDGET_HOLDS_TABLE as Mn, BudgetHoldExpired as Nn, DEFAULT_BUDGET_HOLD_TIMEOUT_MS as Pn, _voltroBudgetHoldsTable as Fn, budgetHoldGeneration as In, budgetHoldKey as Ln, budgetHoldSignalName as Rn, heldBudgets as zn, pendingBudgetHolds as Bn, releaseBudgetHolds as Vn, suspendForBudget as Hn } from "./budgetHold.js";
44
- import { awaitUpdate as Un } from "./updates.js";
45
- import { inspectWorkflow as Wn } from "./inspectWorkflow.js";
46
- import { makeInMemoryRecorder as Gn } from "./inMemoryRecorder.js";
47
- import { DEFAULT_MAX_RUN_RECLAIMS as Kn, DEFAULT_REPLAY_SHAPE_LIMIT as qn, makeWorkflowRunRecorder as Jn, normaliseWorkflowPatches as Yn, resolveRunGuardTuning as Xn, serialiseWorkflowRowForWire as Zn, truncateWorkflowValue as Qn, wrapWorkflowExecuteWithRunRecording as $n } from "./runRecording.js";
48
- import { recordWorkflowExecutionRefusal as er } from "./executionRefusal.js";
49
- export { et as ADMISSIONS_TABLE, Ie as ADMISSION_SUBMISSION_ID_PREFIX, Mn as BUDGET_HOLDS_TABLE, Nn as BudgetHoldExpired, Xt as CANCEL_ON_WATERMARK, ln as CLUSTER_REREAD_WINDOW_MS, un as ClusterDiagnostics, C as CurrentWorkflowExecutionId, w as CurrentWorkflowPatches, I as CurrentWorkflowReplayShape, T as CurrentWorkflowRunId, E as CurrentWorkflowStep, Pn as DEFAULT_BUDGET_HOLD_TIMEOUT_MS, Zt as DEFAULT_COLD_LOOKBACK_MS, fn as DEFAULT_DRAIN_BATCH, Qt as DEFAULT_EVENT_BATCH, tt as DEFAULT_LEASE_MS, Kn as DEFAULT_MAX_RUN_RECLAIMS, qn as DEFAULT_REPLAY_SHAPE_LIMIT, an as DEFAULT_STALL_AFTER_MS, on as DEFAULT_STALL_EVENT_LOOKBACK, sn as DEFAULT_STALL_RUN_PAGE, gn as DEFAULT_SUSPEND_HINT_MS, M as DEFAULT_WORKFLOW_SCHEDULE_MAX_RUNTIME_MS, _ as DEFERRING_CONTROLS, $t as EVENTS_TABLE, we as FlowControlKeyError, nt as PAUSES_TABLE, rt as PENDING_TABLE, i as STEP_JOURNAL_BINDING, Le as SUBMISSIONS_TABLE, Cn as SuspensionUnavailable, en as WATERMARKS_TABLE, a as WORKFLOW_JOURNAL_BINDING, wn as WorkflowCannotPark, B as WorkflowFlowControlProperty, V as WorkflowMessagesProperty, D as WorkflowRunRecorder, N as WorkflowScheduleProperty, Je as WorkflowStartRequestConflictError, O as WorkflowStepInterceptorTag, H as WorkflowVersionTypeId, U as WorkflowWorkerLayerTypeId, Fn as _voltroBudgetHoldsTable, me as _voltroWorkflowAdmissionLocksTable, he as _voltroWorkflowAdmissionsTable, ge as _voltroWorkflowControlRequestsTable, _e as _voltroWorkflowFailureReportsTable, ve as _voltroWorkflowParentClosuresTable, ye as _voltroWorkflowPausesTable, be as _voltroWorkflowPendingTable, fe as _voltroWorkflowRunEventsTable, de as _voltroWorkflowRunStepsTable, ue as _voltroWorkflowRunsTable, pe as _voltroWorkflowStartContextsTable, xe as _voltroWorkflowStartReceiptsTable, Se as _voltroWorkflowSubmissionsTable, qt as _voltroWorkflowWatermarksTable, pn as acceptAdmissionSubmission, Tt as acceptWorkflowControlInTransaction, Re as acknowledgeAdmissionSubmission, it as admissionLeaseHeldPredicate, Gt as admitStart, at as allIntents, v as assertConsistentPools, t as attachPreparedWorkflowExecution, Sn as awaitEvent, xn as awaitSignal, kn as awaitSignalSuspending, Un as awaitUpdate, ze as beginAdmissionSubmissionDispatchInTransaction, Et as beginWorkflowControlDispatchInTransaction, Dt as bindWorkflowResumeJournalInTransaction, Ye as bindWorkflowStartReceipts, In as budgetHoldGeneration, Ln as budgetHoldKey, Rn as budgetHoldSignalName, zt as cancelQueuedWorkflowStartInTransaction, Ft as cancelSuspendedWorkflowRunInTransaction, Te as comparePendingOrder, An as completeSuspendingSignal, It as completeWorkflowRunGenerationInTransaction, k as currentWorkflowStep, ot as deadLetterIntent, Ee as decideAdmission, y as deferringControlsOf, st as deleteIntent, dn as describeStalledRun, ct as discardIntent, lt as discardIntentInTransaction, mn as drainTick, ut as dueIntents, W as durableClock, G as durableQueue, K as durableQueueModule, Lt as enterWorkflowRunGenerationInTransaction, dt as evaluateAdmission, n as executePreparedWorkflow, e as failureMessage, A as getCurrentWorkflowExecutionId, j as getCurrentWorkflowRunId, q as getWorkflowFlowControl, o as getWorkflowJournalCipher, P as getWorkflowSchedule, J as getWorkflowVersionMetadata, Pe as handoffWorkflowFailureInTransaction, b as hasCancelOn, x as hasFlowControl, r as hasPreparedWorkflowExecution, zn as heldBudgets, le as inMemoryWorkflowEngineLayer, Vt as inspectAdmissionSubmissionRetry, Wn as inspectWorkflow, Y as isCarrier, De as isFinishExpired, s as isSealedJournalValue, Oe as isStartExpired, hn as isUnacknowledgedSubmission, c as isWorkflowEncrypted, X as isWorkflowWorkerLayer, Kt as linkExecution, Gn as makeInMemoryRecorder, L as makeReplayShapeTracker, Jn as makeWorkflowRunRecorder, Tn as makeWorkflowUpdateId, _n as maybeHintSuspendingSignal, Be as newAdmissionSubmissionId, Jt as newestEventAt, ke as nextSlotAt, R as nondeterminismEventPayload, Yn as normaliseWorkflowPatches, Ve as noteAdmissionSubmissionFailure, ft as noteIntentAttempt, l as openErrorText, u as openEventPayload, d as openJournalValue, f as openPayloadFields, p as openWorkflowRow, pt as parkDelayedStart, Z as patch, mt as pauseWorkflow, He as pendingAdmissionSubmissions, Bn as pendingBudgetHolds, ht as pendingSlotId, gt as pendingWindow, _t as persistDefer, Yt as planCancellations, Ae as pooledConcurrencyKey, Ue as prepareAdmissionSubmissionExecutionInTransaction, Q as processQueue, vt as pruneAdmissions, $ as queueWorker, Rt as queuedCancellationRequestsTable, ee as rateLimit, yt as readAdmissionState, We as readAdmissionSubmission, bt as readPausedWorkflows, Bt as readQueuedWorkflowCancellationInTransaction, tn as readWatermark, Ot as readWorkflowControlInTransaction, Me as readWorkflowFailureRecord, At as readWorkflowRestartObservationInTransaction, Xe as readWorkflowStartReceipt, Ze as readWorkflowStartRequest, Fe as reconcileWorkflowFailureInTransaction, xt as recordAdmission, er as recordWorkflowExecutionRefusal, Ne as recordWorkflowFailureInTransaction, Qe as recordWorkflowStartReceipt, Ge as rejectAdmissionSubmissionInTransaction, Vn as releaseBudgetHolds, St as releaseLease, z as reportNondeterminism, Ke as reserveAdmissionSubmission, qe as reserveAdmissionSubmissionInTransaction, jt as reserveWorkflowRestartInTransaction, vn as resetSuspendHintsForTest, je as resolveAdmissionKeys, Xn as resolveRunGuardTuning, yn as resolveSuspendHintMs, En as resolveWorkflowMessageRun, $e as resolveWorkflowStartReceipt, Ct as resumeWorkflow, Ht as retryAdmissionSubmissionInTransaction, wt as retryDeadLetterIntent, m as sealJournalValue, Dn as sendWorkflowSignal, On as sendWorkflowUpdate, Zn as serialiseWorkflowRowForWire, bn as setSuspendSignalHintMs, h as setWorkflowJournalCipher, te as sleep, ne as sleepUntil, kt as stageWorkflowParentClosureInTransaction, re as step, ie as stepIdempotencyKey, ae as stepModule, Hn as suspendForBudget, jn as suspendingSignalDeferredName, nn as sweepCancelOn, cn as sweepStalledRuns, Ut as takeAdmittedSubmissionInTransaction, Wt as takePendingAdmissionSubmission, Qn as truncateWorkflowValue, g as tryOpenJournalValue, S as validateFlowControl, F as validateWorkflowSchedule, Ce as withAdmissionTransaction, oe as withCompensation, Mt as withdrawWorkflowRestartInTransaction, se as workflow, ce as workflowModule, Nt as workflowRestartRequestsTable, Pt as workflowRestartWithdrawalsTable, $n as wrapWorkflowExecuteWithRunRecording, rn as writeWatermark };
27
+ import { workflowJournalRoutingTable as zt } from "./journalRoutingTable.js";
28
+ import { cancelQueuedWorkflowStartInTransaction as Bt, readQueuedWorkflowCancellationInTransaction as Vt } from "./queuedControl.js";
29
+ import { inspectAdmissionSubmissionRetry as Ht, retryAdmissionSubmissionInTransaction as Ut } from "./submissionRetry.js";
30
+ import { takeAdmittedSubmissionInTransaction as Wt, takePendingAdmissionSubmission as Gt } from "./pendingSubmission.js";
31
+ import { admitStart as Kt, linkExecution as qt } from "./admissionGate.js";
32
+ import { _voltroWorkflowWatermarksTable as Jt } from "./watermarkTable.js";
33
+ import { newestEventAt as Yt, planCancellations as Xt } from "./cancelOnPlan.js";
34
+ import { CANCEL_ON_WATERMARK as Zt, DEFAULT_COLD_LOOKBACK_MS as Qt, DEFAULT_EVENT_BATCH as $t, EVENTS_TABLE as en, WATERMARKS_TABLE as tn, readWatermark as nn, sweepCancelOn as rn, writeWatermark as an } from "./cancelOnSweep.js";
35
+ import { DEFAULT_STALL_AFTER_MS as on, DEFAULT_STALL_EVENT_LOOKBACK as sn, DEFAULT_STALL_RUN_PAGE as cn, sweepStalledRuns as ln } from "./stalenessSweep.js";
36
+ import { CLUSTER_REREAD_WINDOW_MS as un, ClusterDiagnostics as dn, describeStalledRun as fn } from "./clusterDiagnostics.js";
37
+ import { DEFAULT_DRAIN_BATCH as pn, acceptAdmissionSubmission as mn, drainTick as hn, isUnacknowledgedSubmission as gn } from "./admissionDrainer.js";
38
+ import { DEFAULT_SUSPEND_HINT_MS as _n, maybeHintSuspendingSignal as vn, resetSuspendHintsForTest as yn, resolveSuspendHintMs as bn, setSuspendSignalHintMs as xn } from "./signalHint.js";
39
+ import { awaitSignal as Sn } from "./signals.js";
40
+ import { awaitEvent as Cn } from "./awaitEvent.js";
41
+ import { SuspensionUnavailable as wn, WorkflowCannotPark as Tn } from "./suspensionUnavailable.js";
42
+ import { makeWorkflowUpdateId as En, resolveWorkflowMessageRun as Dn, sendWorkflowSignal as On, sendWorkflowUpdate as kn } from "./messages.js";
43
+ import { awaitSignalSuspending as An, completeSuspendingSignal as jn, suspendingSignalDeferredName as Mn } from "./signalsSuspending.js";
44
+ import { BUDGET_HOLDS_TABLE as Nn, BudgetHoldExpired as Pn, DEFAULT_BUDGET_HOLD_TIMEOUT_MS as Fn, _voltroBudgetHoldsTable as In, budgetHoldGeneration as Ln, budgetHoldKey as Rn, budgetHoldSignalName as zn, heldBudgets as Bn, pendingBudgetHolds as Vn, releaseBudgetHolds as Hn, suspendForBudget as Un } from "./budgetHold.js";
45
+ import { awaitUpdate as Wn } from "./updates.js";
46
+ import { inspectWorkflow as Gn } from "./inspectWorkflow.js";
47
+ import { makeInMemoryRecorder as Kn } from "./inMemoryRecorder.js";
48
+ import { DEFAULT_MAX_RUN_RECLAIMS as qn, DEFAULT_REPLAY_SHAPE_LIMIT as Jn, makeWorkflowRunRecorder as Yn, normaliseWorkflowPatches as Xn, resolveRunGuardTuning as Zn, serialiseWorkflowRowForWire as Qn, truncateWorkflowValue as $n, wrapWorkflowExecuteWithRunRecording as er } from "./runRecording.js";
49
+ import { recordWorkflowExecutionRefusal as tr } from "./executionRefusal.js";
50
+ export { et as ADMISSIONS_TABLE, Ie as ADMISSION_SUBMISSION_ID_PREFIX, Nn as BUDGET_HOLDS_TABLE, Pn as BudgetHoldExpired, Zt as CANCEL_ON_WATERMARK, un as CLUSTER_REREAD_WINDOW_MS, dn as ClusterDiagnostics, C as CurrentWorkflowExecutionId, w as CurrentWorkflowPatches, I as CurrentWorkflowReplayShape, T as CurrentWorkflowRunId, E as CurrentWorkflowStep, Fn as DEFAULT_BUDGET_HOLD_TIMEOUT_MS, Qt as DEFAULT_COLD_LOOKBACK_MS, pn as DEFAULT_DRAIN_BATCH, $t as DEFAULT_EVENT_BATCH, tt as DEFAULT_LEASE_MS, qn as DEFAULT_MAX_RUN_RECLAIMS, Jn as DEFAULT_REPLAY_SHAPE_LIMIT, on as DEFAULT_STALL_AFTER_MS, sn as DEFAULT_STALL_EVENT_LOOKBACK, cn as DEFAULT_STALL_RUN_PAGE, _n as DEFAULT_SUSPEND_HINT_MS, M as DEFAULT_WORKFLOW_SCHEDULE_MAX_RUNTIME_MS, _ as DEFERRING_CONTROLS, en as EVENTS_TABLE, we as FlowControlKeyError, nt as PAUSES_TABLE, rt as PENDING_TABLE, i as STEP_JOURNAL_BINDING, Le as SUBMISSIONS_TABLE, wn as SuspensionUnavailable, tn as WATERMARKS_TABLE, a as WORKFLOW_JOURNAL_BINDING, Tn as WorkflowCannotPark, B as WorkflowFlowControlProperty, V as WorkflowMessagesProperty, D as WorkflowRunRecorder, N as WorkflowScheduleProperty, Je as WorkflowStartRequestConflictError, O as WorkflowStepInterceptorTag, H as WorkflowVersionTypeId, U as WorkflowWorkerLayerTypeId, In as _voltroBudgetHoldsTable, me as _voltroWorkflowAdmissionLocksTable, he as _voltroWorkflowAdmissionsTable, ge as _voltroWorkflowControlRequestsTable, _e as _voltroWorkflowFailureReportsTable, ve as _voltroWorkflowParentClosuresTable, ye as _voltroWorkflowPausesTable, be as _voltroWorkflowPendingTable, fe as _voltroWorkflowRunEventsTable, de as _voltroWorkflowRunStepsTable, ue as _voltroWorkflowRunsTable, pe as _voltroWorkflowStartContextsTable, xe as _voltroWorkflowStartReceiptsTable, Se as _voltroWorkflowSubmissionsTable, Jt as _voltroWorkflowWatermarksTable, mn as acceptAdmissionSubmission, Tt as acceptWorkflowControlInTransaction, Re as acknowledgeAdmissionSubmission, it as admissionLeaseHeldPredicate, Kt as admitStart, at as allIntents, v as assertConsistentPools, t as attachPreparedWorkflowExecution, Cn as awaitEvent, Sn as awaitSignal, An as awaitSignalSuspending, Wn as awaitUpdate, ze as beginAdmissionSubmissionDispatchInTransaction, Et as beginWorkflowControlDispatchInTransaction, Dt as bindWorkflowResumeJournalInTransaction, Ye as bindWorkflowStartReceipts, Ln as budgetHoldGeneration, Rn as budgetHoldKey, zn as budgetHoldSignalName, Bt as cancelQueuedWorkflowStartInTransaction, Ft as cancelSuspendedWorkflowRunInTransaction, Te as comparePendingOrder, jn as completeSuspendingSignal, It as completeWorkflowRunGenerationInTransaction, k as currentWorkflowStep, ot as deadLetterIntent, Ee as decideAdmission, y as deferringControlsOf, st as deleteIntent, fn as describeStalledRun, ct as discardIntent, lt as discardIntentInTransaction, hn as drainTick, ut as dueIntents, W as durableClock, G as durableQueue, K as durableQueueModule, Lt as enterWorkflowRunGenerationInTransaction, dt as evaluateAdmission, n as executePreparedWorkflow, e as failureMessage, A as getCurrentWorkflowExecutionId, j as getCurrentWorkflowRunId, q as getWorkflowFlowControl, o as getWorkflowJournalCipher, P as getWorkflowSchedule, J as getWorkflowVersionMetadata, Pe as handoffWorkflowFailureInTransaction, b as hasCancelOn, x as hasFlowControl, r as hasPreparedWorkflowExecution, Bn as heldBudgets, le as inMemoryWorkflowEngineLayer, Ht as inspectAdmissionSubmissionRetry, Gn as inspectWorkflow, Y as isCarrier, De as isFinishExpired, s as isSealedJournalValue, Oe as isStartExpired, gn as isUnacknowledgedSubmission, c as isWorkflowEncrypted, X as isWorkflowWorkerLayer, qt as linkExecution, Kn as makeInMemoryRecorder, L as makeReplayShapeTracker, Yn as makeWorkflowRunRecorder, En as makeWorkflowUpdateId, vn as maybeHintSuspendingSignal, Be as newAdmissionSubmissionId, Yt as newestEventAt, ke as nextSlotAt, R as nondeterminismEventPayload, Xn as normaliseWorkflowPatches, Ve as noteAdmissionSubmissionFailure, ft as noteIntentAttempt, l as openErrorText, u as openEventPayload, d as openJournalValue, f as openPayloadFields, p as openWorkflowRow, pt as parkDelayedStart, Z as patch, mt as pauseWorkflow, He as pendingAdmissionSubmissions, Vn as pendingBudgetHolds, ht as pendingSlotId, gt as pendingWindow, _t as persistDefer, Xt as planCancellations, Ae as pooledConcurrencyKey, Ue as prepareAdmissionSubmissionExecutionInTransaction, Q as processQueue, vt as pruneAdmissions, $ as queueWorker, Rt as queuedCancellationRequestsTable, ee as rateLimit, yt as readAdmissionState, We as readAdmissionSubmission, bt as readPausedWorkflows, Vt as readQueuedWorkflowCancellationInTransaction, nn as readWatermark, Ot as readWorkflowControlInTransaction, Me as readWorkflowFailureRecord, At as readWorkflowRestartObservationInTransaction, Xe as readWorkflowStartReceipt, Ze as readWorkflowStartRequest, Fe as reconcileWorkflowFailureInTransaction, xt as recordAdmission, tr as recordWorkflowExecutionRefusal, Ne as recordWorkflowFailureInTransaction, Qe as recordWorkflowStartReceipt, Ge as rejectAdmissionSubmissionInTransaction, Hn as releaseBudgetHolds, St as releaseLease, z as reportNondeterminism, Ke as reserveAdmissionSubmission, qe as reserveAdmissionSubmissionInTransaction, jt as reserveWorkflowRestartInTransaction, yn as resetSuspendHintsForTest, je as resolveAdmissionKeys, Zn as resolveRunGuardTuning, bn as resolveSuspendHintMs, Dn as resolveWorkflowMessageRun, $e as resolveWorkflowStartReceipt, Ct as resumeWorkflow, Ut as retryAdmissionSubmissionInTransaction, wt as retryDeadLetterIntent, m as sealJournalValue, On as sendWorkflowSignal, kn as sendWorkflowUpdate, Qn as serialiseWorkflowRowForWire, xn as setSuspendSignalHintMs, h as setWorkflowJournalCipher, te as sleep, ne as sleepUntil, kt as stageWorkflowParentClosureInTransaction, re as step, ie as stepIdempotencyKey, ae as stepModule, Un as suspendForBudget, Mn as suspendingSignalDeferredName, rn as sweepCancelOn, ln as sweepStalledRuns, Wt as takeAdmittedSubmissionInTransaction, Gt as takePendingAdmissionSubmission, $n as truncateWorkflowValue, g as tryOpenJournalValue, S as validateFlowControl, F as validateWorkflowSchedule, Ce as withAdmissionTransaction, oe as withCompensation, Mt as withdrawWorkflowRestartInTransaction, se as workflow, zt as workflowJournalRoutingTable, ce as workflowModule, Nt as workflowRestartRequestsTable, Pt as workflowRestartWithdrawalsTable, er as wrapWorkflowExecuteWithRunRecording, an as writeWatermark };
@@ -0,0 +1,50 @@
1
+ import { Context as e, Deferred as t, Effect as n, Option as r, Schedule as i, Semaphore as a } from "effect";
2
+ //#region src/journalRoutingGuard.ts
3
+ var o = (e) => n.gen(function* () {
4
+ let r = e.pollMs ?? 1e3, o = e.verify;
5
+ if (!Number.isSafeInteger(r) || r < 1 || r > 3e4) return yield* n.fail(/* @__PURE__ */ Error("Invalid journal routing probe interval"));
6
+ let s = yield* t.make(), c = /* @__PURE__ */ new Set(), l = yield* a.make(1), u = !1, d = (e) => n.gen(function* () {
7
+ u = !0, yield* t.fail(s, Error(e));
8
+ }), f = l.withPermits(1)(n.gen(function* () {
9
+ if (u) return yield* t.await(s);
10
+ let e = yield* n.interruptible(o).pipe(n.timeout(r), n.isSuccess);
11
+ if (u) return yield* t.await(s);
12
+ if (!e) return yield* d("Journal routing lock ownership was lost"), yield* t.await(s);
13
+ })), p = (e) => n.uninterruptibleMask((r) => n.gen(function* () {
14
+ if (u) return yield* t.await(s);
15
+ let i = yield* t.make();
16
+ return c.add(i), yield* r(f.pipe(n.andThen(n.suspend(() => u ? t.await(s) : n.raceFirst(e, n.interruptible(t.await(s))))))).pipe(n.ensuring(n.gen(function* () {
17
+ c.delete(i), yield* t.succeed(i, void 0);
18
+ })));
19
+ })), m = (e) => n.uninterruptibleMask((r) => n.gen(function* () {
20
+ if (u) return yield* t.await(s);
21
+ let i = yield* t.make();
22
+ c.add(i);
23
+ let a = new AbortController(), o = Promise.resolve().then(() => {
24
+ if (u) throw Error("Journal routing admission is closed");
25
+ return e(a.signal);
26
+ });
27
+ return yield* r(n.tryPromise({
28
+ try: () => o,
29
+ catch: (e) => e
30
+ })).pipe(n.ensuring(n.gen(function* () {
31
+ a.abort(), yield* n.promise(() => o.then(() => void 0, () => void 0)), c.delete(i), yield* t.succeed(i, void 0);
32
+ })));
33
+ })), h = n.gen(function* () {
34
+ yield* d("Journal routing admission is closed"), yield* n.forEach([...c], (e) => t.await(e), { discard: !0 });
35
+ });
36
+ return yield* n.addFinalizer(() => h), yield* f.pipe(n.ignore, n.repeat(i.spaced(r)), n.forkScoped), {
37
+ run: p,
38
+ ownPromise: m,
39
+ check: f,
40
+ close: h,
41
+ isClosed: () => u
42
+ };
43
+ }), s = e.Service("@voltro/workflow/JournalRoutingGuard"), c = (e, t) => e === void 0 ? t : n.gen(function* () {
44
+ return yield* yield* e.run(n.exit(t.pipe(n.provideService(s, e)))).pipe(n.orDie);
45
+ }), l = (e) => n.flatMap(n.serviceOption(s), (t) => r.isSome(t) ? t.value.ownPromise(e).pipe(n.orDie) : n.promise(e)), u = (e) => n.flatMap(n.serviceOption(s), (t) => r.isSome(t) ? t.value.ownPromise(e) : n.tryPromise({
46
+ try: e,
47
+ catch: (e) => e
48
+ }));
49
+ //#endregion
50
+ export { s as JournalRoutingGuard, o as makeJournalRoutingGuard, l as ownedJournalRoutingPromise, c as protectJournalRoutingEffect, u as tryOwnedJournalRoutingPromise };
@@ -0,0 +1,47 @@
1
+ //#region src/journalRoutingLayout.ts
2
+ var e = (e) => {
3
+ if (e !== "default" && e !== "api-workloads-v1") throw Error("Unknown journal routing layout");
4
+ let t = e === "api-workloads-v1";
5
+ return Object.freeze({
6
+ id: e,
7
+ workflowGroup: "default",
8
+ webhookGroup: t ? "voltro.webhooks" : "default",
9
+ cronGroup: t ? "voltro.schedules" : "default",
10
+ available: Object.freeze(t ? [
11
+ "default",
12
+ "voltro.webhooks",
13
+ "voltro.schedules"
14
+ ] : ["default"])
15
+ });
16
+ }, t = (t, n) => {
17
+ let r = e(t), i = e(n), a = [];
18
+ return r.webhookGroup !== i.webhookGroup && a.push({
19
+ entity: "workflow",
20
+ name: "voltro.deliverWebhook",
21
+ from: r.webhookGroup,
22
+ to: i.webhookGroup
23
+ }), r.cronGroup !== i.cronGroup && a.push({
24
+ entity: "cron",
25
+ name: "*",
26
+ from: r.cronGroup,
27
+ to: i.cronGroup
28
+ }), Object.freeze(a.map((e) => Object.freeze(e)));
29
+ }, n = (t, n) => {
30
+ let r = e(t);
31
+ return n === "voltro.deliverWebhook" ? r.webhookGroup : r.workflowGroup;
32
+ }, r = (t, n) => {
33
+ let r = e(t), i = [
34
+ n.workflows,
35
+ n.schedules,
36
+ n.webhooks
37
+ ];
38
+ if (i.some((e) => typeof e != "boolean")) throw Error("Explicit executor selection is required");
39
+ if (t === "default" && i.some(Boolean) && !i.every(Boolean)) throw Error("Separate executor roles require the api-workloads-v1 journal routing transition");
40
+ let a = /* @__PURE__ */ new Set();
41
+ return n.workflows && a.add(r.workflowGroup), n.schedules && a.add(r.cronGroup), n.webhooks && a.add(r.webhookGroup), Object.freeze({
42
+ available: r.available,
43
+ assigned: Object.freeze([...a])
44
+ });
45
+ };
46
+ //#endregion
47
+ export { r as journalExecutorGroups, e as journalRoutingLayout, t as journalRoutingTransitions, n as journalWorkflowGroup };
@@ -0,0 +1,39 @@
1
+ import { Effect as e } from "effect";
2
+ import { SqlClient as t } from "effect/sql";
3
+ import { fnv1a64 as n } from "@voltro/database/sql";
4
+ //#region src/journalRoutingLock.ts
5
+ var r = (r) => e.gen(function* () {
6
+ let i = r.namespace, a = r.mode, o = r.timeoutMs ?? 3e4;
7
+ if (!i || i.length > 256 || !["shared", "exclusive"].includes(a) || !Number.isSafeInteger(o) || o < 1 || o > 3e5) return yield* e.fail(/* @__PURE__ */ Error("Invalid journal routing lock options"));
8
+ let s = yield* t.SqlClient, c = s.onDialectOrElse({
9
+ pg: () => "pg",
10
+ mssql: () => "mssql",
11
+ orElse: () => "unsupported"
12
+ });
13
+ if (c === "unsupported") return yield* e.fail(/* @__PURE__ */ Error("Journal routing locks require PostgreSQL or SQL Server"));
14
+ let l = (n("voltro:journal-routing:" + i) & 9223372036854775807n).toString(), u = "voltro-journal-routing-" + l, d = yield* s.reserve, f = a === "shared" ? "_shared" : "", p = c === "pg" ? `SELECT pg_try_advisory_lock${f}(${l}::bigint)` : `DECLARE @res int; EXEC @res = sp_getapplock @Resource = '${u}', @LockMode = '${a === "shared" ? "Shared" : "Exclusive"}', @LockOwner = 'Session', @LockTimeout = 0; SELECT @res`, m = c === "pg" ? `SELECT pg_advisory_unlock${f}(${l}::bigint)` : `DECLARE @res int; EXEC @res = sp_releaseapplock @Resource = '${u}', @LockOwner = 'Session'; SELECT @res`, h = performance.now(), g = e.gen(function* () {
15
+ for (;;) {
16
+ let t = (yield* d.executeValues(p, []))[0]?.[0];
17
+ if (c === "pg" ? t === !0 || t === "t" || t === 1 : typeof t == "number" && t >= 0) return;
18
+ if (c === "mssql" && t !== -1) return yield* e.fail(/* @__PURE__ */ Error("Journal routing application lock failed"));
19
+ let n = o - (performance.now() - h);
20
+ if (n <= 0) return yield* e.fail(/* @__PURE__ */ Error("Journal routing lock acquisition timed out"));
21
+ yield* e.sleep(Math.min(n, 100));
22
+ }
23
+ });
24
+ yield* e.acquireRelease(g, () => d.executeValues(m, []).pipe(e.flatMap((t) => {
25
+ let n = t[0]?.[0];
26
+ return (c === "pg" ? n === !0 || n === "t" || n === 1 : typeof n == "number" && n >= 0) ? e.void : e.die(/* @__PURE__ */ Error("Journal routing lock was lost before release"));
27
+ }), e.orDie));
28
+ let _ = c === "pg" ? `SELECT EXISTS (SELECT 1 FROM pg_locks WHERE locktype = 'advisory' AND pid = pg_backend_pid() AND granted AND classid = (${l}::bigint >> 32)::oid AND objid = (${l}::bigint & 4294967295)::oid AND objsubid = 1 AND mode = '${a === "shared" ? "ShareLock" : "ExclusiveLock"}')` : `SELECT APPLOCK_MODE('public', '${u}', 'Session')`;
29
+ return {
30
+ connection: d,
31
+ dialect: c,
32
+ verify: d.executeValues(_, []).pipe(e.flatMap((t) => {
33
+ let n = t[0]?.[0];
34
+ return (c === "pg" ? n === !0 || n === "t" || n === 1 : n === (a === "shared" ? "Shared" : "Exclusive")) ? e.void : e.fail(/* @__PURE__ */ Error("Journal routing lock ownership was lost"));
35
+ }))
36
+ };
37
+ });
38
+ //#endregion
39
+ export { r as acquireJournalRoutingLock };
@@ -0,0 +1,24 @@
1
+ import { withJournalRoutingTransaction as e } from "./journalRoutingTransaction.js";
2
+ import { acquireJournalRoutingLock as t } from "./journalRoutingLock.js";
3
+ import { JournalRoutingMaintenance as n } from "./workflowShardRelocationSql.js";
4
+ import { Effect as r, Option as i } from "effect";
5
+ import { SqlClient as a } from "effect/sql";
6
+ //#region src/journalRoutingMaintenance.ts
7
+ var o = (o, s = 3e4) => r.gen(function* () {
8
+ let c = yield* a.SqlClient;
9
+ return c.onDialectOrElse({
10
+ pg: () => !0,
11
+ orElse: () => !1
12
+ }) ? n.of({ exclusive: (n) => r.scoped(r.gen(function* () {
13
+ let a = yield* r.serviceOption(c.transactionService);
14
+ if (i.isSome(a)) return yield* r.fail(/* @__PURE__ */ Error("Journal maintenance cannot enter an ambient transaction"));
15
+ let { connection: l } = yield* t({
16
+ namespace: o,
17
+ mode: "exclusive",
18
+ timeoutMs: s
19
+ });
20
+ return yield* e(c, l, n);
21
+ })).pipe(r.provideService(a.SqlClient, c)) }) : yield* r.fail(/* @__PURE__ */ Error("Pinned journal maintenance currently requires PostgreSQL"));
22
+ });
23
+ //#endregion
24
+ export { o as makePostgresJournalRoutingMaintenance };
@@ -0,0 +1,32 @@
1
+ import { protectJournalRoutingEffect as e } from "./journalRoutingGuard.js";
2
+ import { Effect as t } from "effect";
3
+ import { MessageStorage as n } from "effect/cluster";
4
+ import { PersistenceError as r } from "effect/cluster/ClusterError";
5
+ //#region src/journalRoutingMessageStorage.ts
6
+ var i = (i, a) => {
7
+ let o = (e) => t.gen(function* () {
8
+ return yield* yield* a.run(t.exit(e)).pipe(t.mapError((e) => new r({ cause: e })));
9
+ });
10
+ return n.MessageStorage.of({
11
+ saveRequest: (e) => o(t.suspend(() => i.saveRequest(e))),
12
+ saveEnvelope: (e) => o(t.suspend(() => i.saveEnvelope(e))),
13
+ saveReply: (e) => o(t.suspend(() => i.saveReply(e))),
14
+ clearReplies: (e) => o(t.suspend(() => i.clearReplies(e))),
15
+ repliesFor: (e) => o(t.suspend(() => i.repliesFor(e))),
16
+ repliesForUnfiltered: (e) => o(t.suspend(() => i.repliesForUnfiltered(e))),
17
+ requestIdForPrimaryKey: (e) => o(t.suspend(() => i.requestIdForPrimaryKey(e))),
18
+ unprocessedMessages: (e) => o(t.suspend(() => i.unprocessedMessages(e))),
19
+ unprocessedMessagesById: (e) => o(t.suspend(() => i.unprocessedMessagesById(e))),
20
+ resetShards: (e) => o(t.suspend(() => i.resetShards(e))),
21
+ resetRequests: (e) => o(t.suspend(() => i.resetRequests(e))),
22
+ resetAddresses: (e) => o(t.suspend(() => i.resetAddresses(e))),
23
+ withTransaction: (t) => e(a, i.withTransaction(t)),
24
+ resetAddress: (e) => o(t.suspend(() => i.resetAddress(e))),
25
+ clearAddress: (e) => o(t.suspend(() => i.clearAddress(e))),
26
+ registerReplyHandler: (e) => i.registerReplyHandler(e),
27
+ unregisterReplyHandler: (e) => i.unregisterReplyHandler(e),
28
+ unregisterShardReplyHandlers: (e) => i.unregisterShardReplyHandlers(e)
29
+ });
30
+ };
31
+ //#endregion
32
+ export { i as guardJournalMessageStorage };
@@ -0,0 +1,23 @@
1
+ import { workflowJournalRoutingTable as e } from "./journalRoutingTable.js";
2
+ import { Effect as t } from "effect";
3
+ import { SqlClient as n } from "effect/sql";
4
+ //#region src/journalRoutingNamespace.ts
5
+ var r = t.gen(function* () {
6
+ let r = (yield* n.SqlClient).withoutTransforms();
7
+ if (!r.onDialectOrElse({
8
+ pg: () => !0,
9
+ orElse: () => !1
10
+ })) return yield* t.fail(/* @__PURE__ */ Error("Journal namespace resolution requires PostgreSQL"));
11
+ let i = yield* r`
12
+ SELECT n.nspname AS schema_name, current_schema() AS active_schema, c.relkind AS kind,
13
+ format('%I.%I', n.nspname, ${e.tableName}::text) AS routing_table
14
+ FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
15
+ WHERE c.oid = to_regclass('cluster_messages')`, a = i[0];
16
+ return i.length !== 1 || !a || a.kind !== "r" || a.schema_name !== a.active_schema ? yield* t.fail(/* @__PURE__ */ Error("Journal table must exist in the active PostgreSQL schema without search-path fallback")) : Object.freeze({
17
+ namespace: `pg:${a.schema_name}:cluster_messages`,
18
+ schema: a.schema_name,
19
+ routingTable: r.literal(a.routing_table)
20
+ });
21
+ }), i = r.pipe(t.map((e) => e.namespace));
22
+ //#endregion
23
+ export { r as resolvePostgresJournalLocation, i as resolvePostgresJournalNamespace };
@@ -0,0 +1,33 @@
1
+ import { journalRoutingLayout as e, journalWorkflowGroup as t } from "./journalRoutingLayout.js";
2
+ import { Context as n } from "effect";
3
+ import { ClusterSchema as r } from "effect/cluster";
4
+ //#region src/journalRoutingRuntime.ts
5
+ var i = class extends n.Service()("@voltro/workflow/JournalRoutingLayout") {}, a = (e, i) => {
6
+ let a = n.add(e.annotations, r.ShardGroup, () => t(i, e._tag));
7
+ return new Proxy(e, { get(e, t, n) {
8
+ return t === "annotations" ? a : Reflect.get(e, t, n);
9
+ } });
10
+ }, o = (t, n) => (e(n), {
11
+ ...t,
12
+ register: (e, r) => t.register(a(e, n), r),
13
+ execute: (e, r) => t.execute(a(e, n), r),
14
+ poll: (e, r) => t.poll(a(e, n), r),
15
+ interrupt: (e, r) => t.interrupt(a(e, n), r),
16
+ resume: (e, r) => t.resume(a(e, n), r),
17
+ scheduleClock: (e, r) => t.scheduleClock(a(e, n), r)
18
+ }), s = (n, i) => {
19
+ let a = e(i), o = (e) => e.startsWith("Workflow/") && !e.startsWith("Workflow/-/") ? t(i, e.slice(9)) : e.startsWith("ClusterCron/") ? a.cronGroup : void 0;
20
+ return {
21
+ ...n,
22
+ makeClient: (e) => {
23
+ let t = o(e.type);
24
+ return n.makeClient(t === void 0 ? e : e.annotate(r.ShardGroup, () => t));
25
+ },
26
+ registerEntity: (e, t, i) => {
27
+ let a = o(e.type);
28
+ return n.registerEntity(a === void 0 ? e : e.annotate(r.ShardGroup, () => a), t, i);
29
+ }
30
+ };
31
+ };
32
+ //#endregion
33
+ export { i as JournalRoutingLayout, a as routeJournalWorkflow, s as withJournalEntityRouting, o as withJournalWorkflowRouting };
@@ -0,0 +1,28 @@
1
+ import { protectJournalRoutingEffect as e } from "./journalRoutingGuard.js";
2
+ import { Effect as t, Stream as n } from "effect";
3
+ import { Rpc as r, RpcSchema as i } from "effect/rpc";
4
+ //#region src/journalRoutingSharding.ts
5
+ var a = (a, o) => {
6
+ let s = (i) => {
7
+ if (typeof i == "object" && i && r.isWrapper(i)) return {
8
+ ...i,
9
+ value: s(i.value)
10
+ };
11
+ if (t.isEffect(i)) return e(o, i);
12
+ if (n.isStream(i)) {
13
+ let r = i;
14
+ return n.unwrap(t.map(e(o, n.toPull(r)), (r) => n.fromPull(t.succeed(e(o, r)))));
15
+ }
16
+ throw Error("Cluster handler must return an Effect, Stream or RPC wrapper");
17
+ };
18
+ return {
19
+ ...a,
20
+ registerEntity: (r, c, l) => e(o, t.suspend(() => a.registerEntity(r, c.pipe(t.map((e) => new Proxy(e, { get(e, a, c) {
21
+ let l = Reflect.get(e, a, c), u = typeof a == "string" ? r.protocol.requests.get(a) : void 0;
22
+ return !u || typeof l != "function" ? l : (...r) => o.isClosed() ? i.isStreamSchema(u.successSchema) ? n.fromEffect(t.interrupt) : t.interrupt : s(Reflect.apply(l, e, r));
23
+ } }))), l))),
24
+ registerSingleton: (n, r, i) => e(o, t.suspend(() => a.registerSingleton(n, e(o, r), i)))
25
+ };
26
+ };
27
+ //#endregion
28
+ export { a as withJournalRoutingGuard };