@voltro/workflow 0.86.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 (99) hide show
  1. package/CHANGELOG.md +5484 -0
  2. package/THIRD-PARTY-NOTICES.md +3 -227
  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/cluster.d.ts +111 -27
  16. package/dist/cluster.js +12 -8
  17. package/dist/clusterCron.js +18 -11
  18. package/dist/clusterDiagnostics.js +1 -2
  19. package/dist/clusterDiagnosticsSql.js +1 -2
  20. package/dist/clusterLayer.js +105 -71
  21. package/dist/clusterMigrationGate.js +1 -2
  22. package/dist/clusterRunnerLayer.js +27 -18
  23. package/dist/clusterShardGroups.js +32 -0
  24. package/dist/clusterTestSuite.d.ts +45 -2
  25. package/dist/clusterTestSuite.js +225 -197
  26. package/dist/controlMonitor.js +1 -2
  27. package/dist/controlRequest.js +1 -2
  28. package/dist/executionRefusal.js +1 -2
  29. package/dist/failureHandoff.js +1 -2
  30. package/dist/failureMessage.js +1 -2
  31. package/dist/failureRecovery.js +1 -2
  32. package/dist/failureReportStore.js +1 -2
  33. package/dist/flowControl.js +1 -2
  34. package/dist/forwardStartReceipts.js +1 -2
  35. package/dist/inMemoryLayer.js +1 -2
  36. package/dist/inMemoryRecorder.js +1 -2
  37. package/dist/index.d.ts +50 -23
  38. package/dist/index.js +24 -23
  39. package/dist/inspectWorkflow.js +2 -3
  40. package/dist/journalEncryption.js +1 -2
  41. package/dist/journalRoutingGuard.js +49 -0
  42. package/dist/journalRoutingLayout.js +46 -0
  43. package/dist/journalRoutingLock.js +38 -0
  44. package/dist/journalRoutingMaintenance.js +23 -0
  45. package/dist/journalRoutingMessageStorage.js +31 -0
  46. package/dist/journalRoutingNamespace.js +22 -0
  47. package/dist/journalRoutingRuntime.js +32 -0
  48. package/dist/journalRoutingSharding.js +27 -0
  49. package/dist/journalRoutingState.js +92 -0
  50. package/dist/journalRoutingTable.js +10 -0
  51. package/dist/journalRoutingTransaction.js +15 -0
  52. package/dist/messages.js +1 -2
  53. package/dist/nondeterminism.js +1 -2
  54. package/dist/parentClosure.js +1 -2
  55. package/dist/parentClosureRecovery.js +1 -2
  56. package/dist/pendingSubmission.js +1 -2
  57. package/dist/prepareSubmissionDispatch.js +1 -2
  58. package/dist/preparedExecution.js +1 -2
  59. package/dist/primitives.js +1 -2
  60. package/dist/queuedCancellationRequest.js +1 -2
  61. package/dist/queuedControl.js +1 -2
  62. package/dist/recorder.js +1 -2
  63. package/dist/residentExecutionEvidence.js +1 -2
  64. package/dist/retryPolicy.js +1 -2
  65. package/dist/runEventsTable.js +1 -2
  66. package/dist/runGeneration.js +1 -2
  67. package/dist/runRecording.js +1 -2
  68. package/dist/runStepsTable.js +1 -2
  69. package/dist/runnerStorageGuard.js +1 -2
  70. package/dist/runsTable.js +1 -2
  71. package/dist/scheduleDeclaration.js +1 -2
  72. package/dist/signalHint.js +1 -2
  73. package/dist/signals.js +1 -2
  74. package/dist/signalsSuspending.js +1 -2
  75. package/dist/sqliteWorkflowOwnership.js +1 -2
  76. package/dist/stalenessSweep.js +1 -2
  77. package/dist/startContextsTable.js +1 -2
  78. package/dist/startReceipt.js +1 -2
  79. package/dist/submissionRecovery.js +1 -2
  80. package/dist/submissionRejection.js +1 -2
  81. package/dist/submissionRetry.js +1 -2
  82. package/dist/suspensionUnavailable.js +1 -2
  83. package/dist/updates.js +1 -2
  84. package/dist/watermarkTable.js +1 -2
  85. package/dist/webCrypto.js +4 -17
  86. package/dist/workflowDelivery.js +1 -2
  87. package/dist/workflowExecutorRouting.js +32 -0
  88. package/dist/workflowJournal.js +1 -2
  89. package/dist/workflowJournalReset.js +1 -2
  90. package/dist/workflowReadSelections.js +1 -2
  91. package/dist/workflowRestartDispatch.js +30 -25
  92. package/dist/workflowRestartObservation.js +1 -2
  93. package/dist/workflowRestartPreparation.js +1 -2
  94. package/dist/workflowRestartReservation.js +158 -157
  95. package/dist/workflowResumeDispatch.js +18 -18
  96. package/dist/workflowRuntimeReadiness.js +11 -0
  97. package/dist/workflowShardRelocation.js +57 -0
  98. package/dist/workflowShardRelocationSql.js +71 -0
  99. package/package.json +5 -11
package/dist/cluster.d.ts CHANGED
@@ -13,6 +13,7 @@ import { QueryDescriptor } from '@voltro/database';
13
13
  import { RateLimiter } from 'effect/persistence';
14
14
  import { Row } from '@voltro/database';
15
15
  import { Schema } from 'effect';
16
+ import { Scope } from 'effect/Scope';
16
17
  import { Sharding } from 'effect/cluster';
17
18
  import { SqlClient } from 'effect/sql';
18
19
  import { SqlClient as SqlClient_2 } from 'effect/sql/SqlClient';
@@ -80,9 +81,10 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
80
81
  kind: "settled";
81
82
  request: {
82
83
  readonly id: string;
84
+ readonly operation: "resume" | "cancel" | "terminate";
83
85
  readonly result: {
84
86
  readonly kind: "confirmed" | "already-terminal";
85
- readonly status: "failed" | "cancelled" | "succeeded";
87
+ readonly status: "failed" | "succeeded" | "cancelled";
86
88
  readonly completedAt: number;
87
89
  readonly output: unknown;
88
90
  readonly errorTag: string | null;
@@ -93,7 +95,6 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
93
95
  readonly enteredAt: number;
94
96
  readonly generation: string;
95
97
  } | null;
96
- readonly operation: "resume" | "cancel" | "terminate";
97
98
  readonly generation: string;
98
99
  readonly runId: string;
99
100
  readonly requestedAt: number;
@@ -119,9 +120,10 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
119
120
  kind: "unknown";
120
121
  request: {
121
122
  readonly id: string;
123
+ readonly operation: "resume" | "cancel" | "terminate";
122
124
  readonly result: {
123
125
  readonly kind: "confirmed" | "already-terminal";
124
- readonly status: "failed" | "cancelled" | "succeeded";
126
+ readonly status: "failed" | "succeeded" | "cancelled";
125
127
  readonly completedAt: number;
126
128
  readonly output: unknown;
127
129
  readonly errorTag: string | null;
@@ -132,7 +134,6 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
132
134
  readonly enteredAt: number;
133
135
  readonly generation: string;
134
136
  } | null;
135
- readonly operation: "resume" | "cancel" | "terminate";
136
137
  readonly generation: string;
137
138
  readonly runId: string;
138
139
  readonly requestedAt: number;
@@ -158,9 +159,10 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
158
159
  kind: "superseded";
159
160
  request: {
160
161
  readonly id: string;
162
+ readonly operation: "resume" | "cancel" | "terminate";
161
163
  readonly result: {
162
164
  readonly kind: "confirmed" | "already-terminal";
163
- readonly status: "failed" | "cancelled" | "succeeded";
165
+ readonly status: "failed" | "succeeded" | "cancelled";
164
166
  readonly completedAt: number;
165
167
  readonly output: unknown;
166
168
  readonly errorTag: string | null;
@@ -171,7 +173,6 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
171
173
  readonly enteredAt: number;
172
174
  readonly generation: string;
173
175
  } | null;
174
- readonly operation: "resume" | "cancel" | "terminate";
175
176
  readonly generation: string;
176
177
  readonly runId: string;
177
178
  readonly requestedAt: number;
@@ -197,9 +198,10 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
197
198
  kind: "not-suspended";
198
199
  request: {
199
200
  readonly id: string;
201
+ readonly operation: "resume" | "cancel" | "terminate";
200
202
  readonly result: {
201
203
  readonly kind: "confirmed" | "already-terminal";
202
- readonly status: "failed" | "cancelled" | "succeeded";
204
+ readonly status: "failed" | "succeeded" | "cancelled";
203
205
  readonly completedAt: number;
204
206
  readonly output: unknown;
205
207
  readonly errorTag: string | null;
@@ -210,7 +212,6 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
210
212
  readonly enteredAt: number;
211
213
  readonly generation: string;
212
214
  } | null;
213
- readonly operation: "resume" | "cancel" | "terminate";
214
215
  readonly generation: string;
215
216
  readonly runId: string;
216
217
  readonly requestedAt: number;
@@ -236,9 +237,10 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
236
237
  kind: "bound";
237
238
  request: {
238
239
  readonly id: string;
240
+ readonly operation: "resume" | "cancel" | "terminate";
239
241
  readonly result: {
240
242
  readonly kind: "confirmed" | "already-terminal";
241
- readonly status: "failed" | "cancelled" | "succeeded";
243
+ readonly status: "failed" | "succeeded" | "cancelled";
242
244
  readonly completedAt: number;
243
245
  readonly output: unknown;
244
246
  readonly errorTag: string | null;
@@ -249,7 +251,6 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
249
251
  readonly enteredAt: number;
250
252
  readonly generation: string;
251
253
  } | null;
252
- readonly operation: "resume" | "cancel" | "terminate";
253
254
  readonly generation: string;
254
255
  readonly runId: string;
255
256
  readonly requestedAt: number;
@@ -275,9 +276,10 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
275
276
  kind: "waiting-journal";
276
277
  request: {
277
278
  readonly id: string;
279
+ readonly operation: "resume" | "cancel" | "terminate";
278
280
  readonly result: {
279
281
  readonly kind: "confirmed" | "already-terminal";
280
- readonly status: "failed" | "cancelled" | "succeeded";
282
+ readonly status: "failed" | "succeeded" | "cancelled";
281
283
  readonly completedAt: number;
282
284
  readonly output: unknown;
283
285
  readonly errorTag: string | null;
@@ -288,7 +290,6 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
288
290
  readonly enteredAt: number;
289
291
  readonly generation: string;
290
292
  } | null;
291
- readonly operation: "resume" | "cancel" | "terminate";
292
293
  readonly generation: string;
293
294
  readonly runId: string;
294
295
  readonly requestedAt: number;
@@ -312,9 +313,15 @@ declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, ob
312
313
  };
313
314
  }>;
314
315
 
316
+ /** The standard Sharding implementation exposes isShutdown as a synchronous
317
+ * local read. No database probe, monitor or new promise is started per request. */
318
+ export declare const captureWorkflowRuntimeReadiness: Effect.Effect<() => boolean, never, never>;
319
+
315
320
  export declare interface ClusterCronSpec {
316
321
  /** Stable schedule name — used as the cluster cron's identity. */
317
322
  readonly name: string;
323
+ /** Stable persistent routing group. Omitted retains the existing default. */
324
+ readonly shardGroup?: string;
318
325
  /** Compiled cron (timezone already baked in by `Cron.parse`). */
319
326
  readonly cron: Cron.Cron;
320
327
  /** The wrapped firing — records the run row + invokes the user
@@ -481,9 +488,10 @@ declare const dispatchWorkflowResume: (options: {
481
488
  kind: "settled";
482
489
  request: {
483
490
  readonly id: string;
491
+ readonly operation: "resume" | "cancel" | "terminate";
484
492
  readonly result: {
485
493
  readonly kind: "confirmed" | "already-terminal";
486
- readonly status: "failed" | "cancelled" | "succeeded";
494
+ readonly status: "failed" | "succeeded" | "cancelled";
487
495
  readonly completedAt: number;
488
496
  readonly output: unknown;
489
497
  readonly errorTag: string | null;
@@ -494,7 +502,6 @@ declare const dispatchWorkflowResume: (options: {
494
502
  readonly enteredAt: number;
495
503
  readonly generation: string;
496
504
  } | null;
497
- readonly operation: "resume" | "cancel" | "terminate";
498
505
  readonly generation: string;
499
506
  readonly runId: string;
500
507
  readonly requestedAt: number;
@@ -520,9 +527,10 @@ declare const dispatchWorkflowResume: (options: {
520
527
  kind: "unknown";
521
528
  request: {
522
529
  readonly id: string;
530
+ readonly operation: "resume" | "cancel" | "terminate";
523
531
  readonly result: {
524
532
  readonly kind: "confirmed" | "already-terminal";
525
- readonly status: "failed" | "cancelled" | "succeeded";
533
+ readonly status: "failed" | "succeeded" | "cancelled";
526
534
  readonly completedAt: number;
527
535
  readonly output: unknown;
528
536
  readonly errorTag: string | null;
@@ -533,7 +541,6 @@ declare const dispatchWorkflowResume: (options: {
533
541
  readonly enteredAt: number;
534
542
  readonly generation: string;
535
543
  } | null;
536
- readonly operation: "resume" | "cancel" | "terminate";
537
544
  readonly generation: string;
538
545
  readonly runId: string;
539
546
  readonly requestedAt: number;
@@ -559,9 +566,10 @@ declare const dispatchWorkflowResume: (options: {
559
566
  kind: "superseded";
560
567
  request: {
561
568
  readonly id: string;
569
+ readonly operation: "resume" | "cancel" | "terminate";
562
570
  readonly result: {
563
571
  readonly kind: "confirmed" | "already-terminal";
564
- readonly status: "failed" | "cancelled" | "succeeded";
572
+ readonly status: "failed" | "succeeded" | "cancelled";
565
573
  readonly completedAt: number;
566
574
  readonly output: unknown;
567
575
  readonly errorTag: string | null;
@@ -572,7 +580,6 @@ declare const dispatchWorkflowResume: (options: {
572
580
  readonly enteredAt: number;
573
581
  readonly generation: string;
574
582
  } | null;
575
- readonly operation: "resume" | "cancel" | "terminate";
576
583
  readonly generation: string;
577
584
  readonly runId: string;
578
585
  readonly requestedAt: number;
@@ -598,9 +605,10 @@ declare const dispatchWorkflowResume: (options: {
598
605
  kind: "not-suspended";
599
606
  request: {
600
607
  readonly id: string;
608
+ readonly operation: "resume" | "cancel" | "terminate";
601
609
  readonly result: {
602
610
  readonly kind: "confirmed" | "already-terminal";
603
- readonly status: "failed" | "cancelled" | "succeeded";
611
+ readonly status: "failed" | "succeeded" | "cancelled";
604
612
  readonly completedAt: number;
605
613
  readonly output: unknown;
606
614
  readonly errorTag: string | null;
@@ -611,7 +619,6 @@ declare const dispatchWorkflowResume: (options: {
611
619
  readonly enteredAt: number;
612
620
  readonly generation: string;
613
621
  } | null;
614
- readonly operation: "resume" | "cancel" | "terminate";
615
622
  readonly generation: string;
616
623
  readonly runId: string;
617
624
  readonly requestedAt: number;
@@ -637,9 +644,10 @@ declare const dispatchWorkflowResume: (options: {
637
644
  kind: "waiting-journal";
638
645
  request: {
639
646
  readonly id: string;
647
+ readonly operation: "resume" | "cancel" | "terminate";
640
648
  readonly result: {
641
649
  readonly kind: "confirmed" | "already-terminal";
642
- readonly status: "failed" | "cancelled" | "succeeded";
650
+ readonly status: "failed" | "succeeded" | "cancelled";
643
651
  readonly completedAt: number;
644
652
  readonly output: unknown;
645
653
  readonly errorTag: string | null;
@@ -650,7 +658,6 @@ declare const dispatchWorkflowResume: (options: {
650
658
  readonly enteredAt: number;
651
659
  readonly generation: string;
652
660
  } | null;
653
- readonly operation: "resume" | "cancel" | "terminate";
654
661
  readonly generation: string;
655
662
  readonly runId: string;
656
663
  readonly requestedAt: number;
@@ -676,9 +683,10 @@ declare const dispatchWorkflowResume: (options: {
676
683
  kind: "already-terminal";
677
684
  request: {
678
685
  readonly id: string;
686
+ readonly operation: "resume" | "cancel" | "terminate";
679
687
  readonly result: {
680
688
  readonly kind: "confirmed" | "already-terminal";
681
- readonly status: "failed" | "cancelled" | "succeeded";
689
+ readonly status: "failed" | "succeeded" | "cancelled";
682
690
  readonly completedAt: number;
683
691
  readonly output: unknown;
684
692
  readonly errorTag: string | null;
@@ -689,7 +697,6 @@ declare const dispatchWorkflowResume: (options: {
689
697
  readonly enteredAt: number;
690
698
  readonly generation: string;
691
699
  } | null;
692
- readonly operation: "resume" | "cancel" | "terminate";
693
700
  readonly generation: string;
694
701
  readonly runId: string;
695
702
  readonly requestedAt: number;
@@ -717,9 +724,10 @@ declare const dispatchWorkflowResume: (options: {
717
724
  request: {
718
725
  dispatchAttempts: number;
719
726
  id: string;
727
+ operation: "resume" | "cancel" | "terminate";
720
728
  result: {
721
729
  readonly kind: "confirmed" | "already-terminal";
722
- readonly status: "failed" | "cancelled" | "succeeded";
730
+ readonly status: "failed" | "succeeded" | "cancelled";
723
731
  readonly completedAt: number;
724
732
  readonly output: unknown;
725
733
  readonly errorTag: string | null;
@@ -730,7 +738,6 @@ declare const dispatchWorkflowResume: (options: {
730
738
  readonly enteredAt: number;
731
739
  readonly generation: string;
732
740
  } | null;
733
- operation: "resume" | "cancel" | "terminate";
734
741
  generation: string;
735
742
  runId: string;
736
743
  requestedAt: number;
@@ -778,6 +785,15 @@ export declare interface FailedActivityRef {
778
785
  readonly attempt: number;
779
786
  }
780
787
 
788
+ export declare const journalExecutorGroups: (layout: string, selected: {
789
+ readonly workflows: boolean;
790
+ readonly schedules: boolean;
791
+ readonly webhooks: boolean;
792
+ }) => Readonly<{
793
+ available: readonly string[];
794
+ assigned: readonly string[];
795
+ }>;
796
+
781
797
  /** The exit as the cluster journals it: the rpc WIRE form (`RpcMessage.ExitEncoded`),
782
798
  * whose failure carries the cause as a list of reasons — not `Schema.Exit`'s
783
799
  * own `_id`-tagged encoding. */
@@ -798,6 +814,20 @@ export declare const JournalExit: Schema.Union<readonly [Schema.Struct<{
798
814
  }>]>>;
799
815
  }>]>;
800
816
 
817
+ /** One routing contract for migration and every submitting/executing replica. */
818
+ export declare const journalRoutingLayout: (id: string) => Readonly<{
819
+ id: "default" | "api-workloads-v1";
820
+ workflowGroup: "default";
821
+ webhookGroup: "default" | "voltro.webhooks";
822
+ cronGroup: "default" | "voltro.schedules";
823
+ available: readonly string[];
824
+ }>;
825
+
826
+ declare interface JournalRoutingState {
827
+ readonly generation: number;
828
+ readonly layout: string;
829
+ }
830
+
801
831
  /**
802
832
  * Build the cluster-cron layer for one schedule. Returns a
803
833
  * `Layer<never, never, Sharding>` — the framework provides `Sharding`
@@ -1012,6 +1042,13 @@ declare const prepareWorkflowRestartCommand: (options: Omit<Parameters<typeof pr
1012
1042
  readonly reason: string;
1013
1043
  }>;
1014
1044
 
1045
+ /** Read-only operational snapshot, including baseline state before transition.
1046
+ * The caller's scope releases the shared lock; this is not a liveness report. */
1047
+ export declare const readPostgresJournalRoutingState: Effect.Effect<{
1048
+ namespace: `pg:${string}:cluster_messages`;
1049
+ state: JournalRoutingState;
1050
+ }, Error | SqlError_2, SqlClient.SqlClient | Scope>;
1051
+
1015
1052
  /** Read an accepted command before observing the journal again. Its captured
1016
1053
  * replies remain authoritative after reset or body entry. This grants no new
1017
1054
  * dispatch permission: dispatch must still recheck the resident generation. */
@@ -1347,7 +1384,10 @@ export declare const resolveRunnerStorage: (opts: {
1347
1384
  * `'memory'` runner storage never builds `SqlRunnerStorage`, so the choice is
1348
1385
  * moot there (returns `false`, no probe). For `'sql'` storage it honors the
1349
1386
  * mode: `'row'`/`'advisory'` are explicit; `'auto'` probes the live connection
1350
- * for wsrep on MySQL/MariaDB and stays advisory on every other dialect.
1387
+ * for wsrep on MySQL/MariaDB. PostgreSQL uses row leases in non-public
1388
+ * schemas: advisory lock namespaces are database-wide and keyed only by the
1389
+ * library table prefix, so separate schemas would otherwise compete for shards.
1390
+ * Public-schema PostgreSQL journals retain advisory coordination.
1351
1391
  */
1352
1392
  export declare const resolveShardLockDisableAdvisory: (opts: {
1353
1393
  readonly dialectId: string | undefined;
@@ -1478,14 +1518,42 @@ export declare type ShardLockMode = 'auto' | 'row' | 'advisory';
1478
1518
 
1479
1519
  declare type Store = Pick<DataStore, 'query' | 'insert' | 'update'>;
1480
1520
 
1521
+ /** Internal stop-all transition. Routing state and journal changes share the
1522
+ * maintenance owner's pinned PostgreSQL transaction. Legacy processes must be
1523
+ * excluded externally; they do not honor this new admission contract. */
1524
+ export declare const transitionPostgresJournalRouting: (options: {
1525
+ readonly expected: JournalRoutingState;
1526
+ readonly nextLayout: string;
1527
+ }) => Effect.Effect<{
1528
+ state: JournalRoutingState;
1529
+ moved: number;
1530
+ }, Error | SqlError_2, SqlClient.SqlClient>;
1531
+
1481
1532
  declare interface UnreadMessage extends ClusterMessageState {
1482
1533
  /** How long ago the last runner read it. */
1483
1534
  readonly unreadForMs: number;
1484
1535
  }
1485
1536
 
1537
+ /** Require matching built-engine ownership before registering host executors.
1538
+ * Composed layers retain the contract; replacing the engine cannot borrow it. */
1539
+ export declare const withWorkflowExecutorSelection: <Out, E, In>(engineLayer: Layer.Layer<Out, E, In>, selected: {
1540
+ readonly workflows: boolean;
1541
+ readonly schedules: boolean;
1542
+ readonly webhooks: boolean;
1543
+ }) => Layer.Layer<Out, E, In>;
1544
+
1486
1545
  export declare const workflowEngineLayer: (options: WorkflowEngineLayerOptions) => Layer.Layer<WorkflowEngine.WorkflowEngine | RateLimiter.RateLimiter | Sharding.Sharding | MessageStorage.MessageStorage | ClusterDiagnostics | WorkflowResumeDispatcher | WorkflowRestartDispatcher>;
1487
1546
 
1488
1547
  export declare interface WorkflowEngineLayerOptions {
1548
+ /** Client mode submits/polls durable work without registering an executor,
1549
+ * runner heartbeat or shard owner. Requires shared SQL runner storage. */
1550
+ readonly runnerMode?: 'worker' | 'client';
1551
+ /** Opt into the persisted PostgreSQL routing generation and guarded journal.
1552
+ * Requires a completed stop-all routing transition before split ownership. */
1553
+ readonly journalRouting?: JournalRoutingState;
1554
+ /** Explicit cluster-wide routing inventory and this runner's ownership.
1555
+ * Omitted preserves existing routing. Does not migrate persisted addresses. */
1556
+ readonly shardGroups?: WorkflowShardGroups;
1489
1557
  /**
1490
1558
  * The dialect's SqlClient layer (postgres / mysql / mariadb / mssql).
1491
1559
  * For `runnerStorage: 'memory'` it's still required so the cluster's
@@ -1613,4 +1681,20 @@ export declare type WorkflowRunReplyObservation = {
1613
1681
  readonly exit: unknown;
1614
1682
  };
1615
1683
 
1684
+ export declare class WorkflowRuntimeReadiness extends WorkflowRuntimeReadiness_base {
1685
+ }
1686
+
1687
+ declare const WorkflowRuntimeReadiness_base: Context.ServiceClass<WorkflowRuntimeReadiness, "@voltro/workflow/WorkflowRuntimeReadiness", {
1688
+ readonly isReady: () => boolean;
1689
+ }>;
1690
+
1691
+ /** Explicit routing inventory shared by every runner in one cluster. Changing
1692
+ * groups changes persistent addresses; this is not a journal migration. */
1693
+ /** Group names are at most 32 ASCII characters: group + colon + a safe integer
1694
+ * slot fits the existing SQL journal shard_id VARCHAR(50) on every dialect. */
1695
+ declare interface WorkflowShardGroups {
1696
+ readonly available: ReadonlyArray<string>;
1697
+ readonly assigned: ReadonlyArray<string>;
1698
+ }
1699
+
1616
1700
  export { }
package/dist/cluster.js CHANGED
@@ -1,8 +1,12 @@
1
- import { WorkflowResumeDispatcher as e } from "./workflowResumeDispatch.js";
2
- import { JournalExit as t, activityPrimaryKey as n, readWorkflowRunReply as r, redriveFailedRun as i, resumeRunFromStep as a } from "./workflowJournal.js";
3
- import { WorkflowRestartDispatcher as o } from "./workflowRestartDispatch.js";
4
- import { clusterMigrationGateLayer as s } from "./clusterMigrationGate.js";
5
- import { clusterLockNamespaceOid as c, makeClusterDiagnostics as l } from "./clusterDiagnosticsSql.js";
6
- import { DEFAULT_RUNNER_LISTEN_PORT as u, detectWsrepCluster as d, parseShardLockMode as f, pollWorkflowStorage as p, resolveFailoverTuning as m, resolveRunnerIdentity as h, resolveRunnerStorage as g, resolveShardLockDisableAdvisory as _, workflowEngineLayer as v } from "./clusterLayer.js";
7
- import { makeClusterCronLayer as y } from "./clusterCron.js";
8
- export { u as DEFAULT_RUNNER_LISTEN_PORT, t as JournalExit, o as WorkflowRestartDispatcher, e as WorkflowResumeDispatcher, n as activityPrimaryKey, c as clusterLockNamespaceOid, s as clusterMigrationGateLayer, d as detectWsrepCluster, y as makeClusterCronLayer, l as makeClusterDiagnostics, f as parseShardLockMode, p as pollWorkflowStorage, r as readWorkflowRunReply, i as redriveFailedRun, m as resolveFailoverTuning, h as resolveRunnerIdentity, g as resolveRunnerStorage, _ as resolveShardLockDisableAdvisory, a as resumeRunFromStep, v as workflowEngineLayer };
1
+ import { WorkflowRuntimeReadiness as e, captureWorkflowRuntimeReadiness as t } from "./workflowRuntimeReadiness.js";
2
+ import { journalExecutorGroups as n, journalRoutingLayout as r } from "./journalRoutingLayout.js";
3
+ import { withWorkflowExecutorSelection as i } from "./workflowExecutorRouting.js";
4
+ import { readPostgresJournalRoutingState as a, transitionPostgresJournalRouting as o } from "./journalRoutingState.js";
5
+ import { WorkflowResumeDispatcher as s } from "./workflowResumeDispatch.js";
6
+ import { JournalExit as c, activityPrimaryKey as l, readWorkflowRunReply as u, redriveFailedRun as d, resumeRunFromStep as f } from "./workflowJournal.js";
7
+ import { WorkflowRestartDispatcher as p } from "./workflowRestartDispatch.js";
8
+ import { clusterMigrationGateLayer as m } from "./clusterMigrationGate.js";
9
+ import { clusterLockNamespaceOid as h, makeClusterDiagnostics as g } from "./clusterDiagnosticsSql.js";
10
+ import { DEFAULT_RUNNER_LISTEN_PORT as _, detectWsrepCluster as v, parseShardLockMode as y, pollWorkflowStorage as b, resolveFailoverTuning as x, resolveRunnerIdentity as S, resolveRunnerStorage as C, resolveShardLockDisableAdvisory as w, workflowEngineLayer as T } from "./clusterLayer.js";
11
+ import { makeClusterCronLayer as E } from "./clusterCron.js";
12
+ export { _ as DEFAULT_RUNNER_LISTEN_PORT, c as JournalExit, p as WorkflowRestartDispatcher, s as WorkflowResumeDispatcher, e as WorkflowRuntimeReadiness, l as activityPrimaryKey, t as captureWorkflowRuntimeReadiness, h as clusterLockNamespaceOid, m as clusterMigrationGateLayer, v as detectWsrepCluster, n as journalExecutorGroups, r as journalRoutingLayout, E as makeClusterCronLayer, g as makeClusterDiagnostics, y as parseShardLockMode, b as pollWorkflowStorage, a as readPostgresJournalRoutingState, u as readWorkflowRunReply, d as redriveFailedRun, x as resolveFailoverTuning, S as resolveRunnerIdentity, C as resolveRunnerStorage, w as resolveShardLockDisableAdvisory, f as resumeRunFromStep, o as transitionPostgresJournalRouting, i as withWorkflowExecutorSelection, T as workflowEngineLayer };
@@ -1,11 +1,18 @@
1
- import { Duration as e, Effect as t } from "effect";
2
- import { ClusterCron as n } from "effect/cluster";
3
- //#region src/clusterCron.ts
4
- var r = (r) => n.make({
5
- name: r.name,
6
- cron: r.cron,
7
- execute: t.promise(() => r.execute()),
8
- skipIfOlderThan: r.skipIfOlderThan ?? e.days(1)
9
- });
10
- //#endregion
11
- export { r as makeClusterCronLayer };
1
+ import { captureWorkflowShardGroups as e } from "./clusterShardGroups.js";
2
+ import { Duration as t, Effect as n } from "effect";
3
+ import { ClusterCron as r } from "effect/cluster";
4
+ // src/clusterCron.ts
5
+ var i = (i) => {
6
+ let a = i.shardGroup;
7
+ return a !== void 0 && e({
8
+ available: [a],
9
+ assigned: [a]
10
+ }, !1), r.make({
11
+ name: i.name,
12
+ shardGroup: a,
13
+ cron: i.cron,
14
+ execute: n.promise(() => i.execute()),
15
+ skipIfOlderThan: i.skipIfOlderThan ?? t.days(1)
16
+ });
17
+ };
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 };