@voltro/workflow 0.85.0 → 0.86.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/CHANGELOG.md +666 -0
- package/THIRD-PARTY-NOTICES.md +5 -33
- package/dist/admission.js +140 -0
- package/dist/admissionDrainer.js +705 -0
- package/dist/admissionGate.js +115 -0
- package/dist/admissionStore.js +347 -0
- package/dist/admissionSubmission.js +297 -0
- package/dist/admissionTables.js +137 -0
- package/dist/admissionTransaction.js +21 -0
- package/dist/awaitEvent.js +82 -0
- package/dist/budgetHold.js +136 -0
- package/dist/cancelOnPlan.js +75 -0
- package/dist/cancelOnSweep.js +188 -0
- package/dist/cancelPendingStart.js +50 -0
- package/dist/cluster.js +8 -2
- package/dist/clusterCron.js +11 -0
- package/dist/clusterDiagnostics.js +20 -0
- package/dist/clusterDiagnosticsSql.js +145 -0
- package/dist/clusterLayer.js +110 -0
- package/dist/clusterMigrationGate.js +61 -0
- package/dist/clusterRunnerLayer.js +21 -0
- package/dist/clusterTestSuite.js +101 -101
- package/dist/controlMonitor.js +13 -0
- package/dist/controlRequest.js +367 -0
- package/dist/executionRefusal.js +162 -0
- package/dist/failureHandoff.js +183 -0
- package/dist/failureMessage.js +12 -0
- package/dist/failureRecovery.js +50 -0
- package/dist/failureReportStore.js +60 -0
- package/dist/flowControl.js +142 -0
- package/dist/forwardStartReceipts.js +41 -0
- package/dist/inMemoryLayer.js +7 -0
- package/dist/inMemoryRecorder.js +56 -0
- package/dist/index.d.ts +82 -8
- package/dist/index.js +49 -5
- package/dist/inspectWorkflow.js +101 -0
- package/dist/{journalEncryption-DTyhUzaS.js → journalEncryption.js} +30 -37
- package/dist/messages.js +92 -0
- package/dist/nondeterminism.js +51 -0
- package/dist/parentClosure.js +141 -0
- package/dist/parentClosureRecovery.js +54 -0
- package/dist/pendingSubmission.js +85 -0
- package/dist/prepareSubmissionDispatch.js +17 -0
- package/dist/preparedExecution.js +14 -0
- package/dist/primitives.js +225 -2
- package/dist/queuedCancellationRequest.js +364 -0
- package/dist/queuedControl.js +21 -0
- package/dist/recorder.js +11 -0
- package/dist/residentExecutionEvidence.js +64 -0
- package/dist/retryPolicy.js +57 -0
- package/dist/runEventsTable.js +17 -0
- package/dist/runGeneration.js +345 -0
- package/dist/runRecording.js +615 -0
- package/dist/runStepsTable.js +28 -0
- package/dist/runnerStorageGuard.js +29 -0
- package/dist/runsTable.js +42 -0
- package/dist/scheduleDeclaration.js +44 -0
- package/dist/signalHint.js +23 -0
- package/dist/signals.js +70 -0
- package/dist/signalsSuspending.js +57 -0
- package/dist/sqliteWorkflowOwnership.js +26 -0
- package/dist/stalenessSweep.js +191 -0
- package/dist/startContextsTable.js +20 -0
- package/dist/startReceipt.js +143 -0
- package/dist/submissionRecovery.js +122 -0
- package/dist/submissionRejection.js +10 -0
- package/dist/submissionRetry.js +71 -0
- package/dist/suspensionUnavailable.js +9 -0
- package/dist/updates.js +87 -0
- package/dist/watermarkTable.js +9 -0
- package/dist/webCrypto.js +17 -0
- package/dist/workflowDelivery.js +24 -0
- package/dist/workflowJournal.js +124 -0
- package/dist/workflowJournalReset.js +111 -0
- package/dist/workflowReadSelections.js +12 -0
- package/dist/workflowRestartDispatch.js +29 -0
- package/dist/workflowRestartObservation.js +60 -0
- package/dist/workflowRestartPreparation.js +109 -0
- package/dist/workflowRestartReservation.js +426 -0
- package/dist/workflowResumeDispatch.js +29 -0
- package/package.json +4 -4
- package/dist/cluster-F_bhqVP7.js +0 -679
- package/dist/primitives-DX04WTWh.js +0 -507
- package/dist/src-C2NEyUM8.js +0 -3925
- package/dist/workflowReadSelections-CZAUjP7f.js +0 -2096
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { FieldBinding } from '@voltro/database';
|
|
|
10
10
|
import { FieldCipher } from '@voltro/database';
|
|
11
11
|
import { FieldDefinitions } from '@voltro/database';
|
|
12
12
|
import { Layer } from 'effect';
|
|
13
|
+
import { Predicate } from '@voltro/database';
|
|
13
14
|
import { QueryDescriptor } from '@voltro/database';
|
|
14
15
|
import { RateLimiter } from 'effect/persistence';
|
|
15
16
|
import { Row } from '@voltro/database';
|
|
@@ -21,6 +22,7 @@ import { Table } from '@voltro/database';
|
|
|
21
22
|
import { TableLike } from '@voltro/database';
|
|
22
23
|
import { WorkflowAccessOptions } from '@voltro/protocol';
|
|
23
24
|
import { WorkflowEngine } from 'effect/workflow';
|
|
25
|
+
import { WorkflowInstance } from 'effect/workflow/WorkflowEngine';
|
|
24
26
|
import { Workflow as workflowModule } from 'effect/workflow';
|
|
25
27
|
import { WorkflowParentClosePolicy } from '@voltro/protocol';
|
|
26
28
|
import { WorkflowQueuedCancellationResult } from '@voltro/protocol';
|
|
@@ -94,8 +96,8 @@ export declare type AdmissionDecision = {
|
|
|
94
96
|
readonly deadlineAt?: number;
|
|
95
97
|
/** `'replace'` — one pending row per key, newest payload wins (debounce).
|
|
96
98
|
* `'append'` — one row per item, they accumulate (batch).
|
|
97
|
-
* `'hold'` — the row
|
|
98
|
-
* (throttle / concurrency / paused re-checks). */
|
|
99
|
+
* `'hold'` — retain the existing row; persist only a changed future
|
|
100
|
+
* deadline (throttle / concurrency / paused re-checks). */
|
|
99
101
|
readonly collapse: 'replace' | 'append' | 'hold';
|
|
100
102
|
readonly keys: AdmissionKeys;
|
|
101
103
|
} | {
|
|
@@ -218,6 +220,11 @@ export declare interface AdmissionKeys {
|
|
|
218
220
|
readonly priority: number;
|
|
219
221
|
}
|
|
220
222
|
|
|
223
|
+
/** Unknown acceptance cannot expire into proof of spare capacity. Only an
|
|
224
|
+
* acknowledged execution uses the ordinary crash backstop. Share this rule
|
|
225
|
+
* between admission decisions and read-only capacity observations. */
|
|
226
|
+
export declare const admissionLeaseHeldPredicate: (now: number) => Predicate;
|
|
227
|
+
|
|
221
228
|
export declare const ADMISSIONS_TABLE = "_voltro_workflow_admissions";
|
|
222
229
|
|
|
223
230
|
/** What the store observed for these keys. Every field optional: the store only
|
|
@@ -255,6 +262,31 @@ export declare interface AdmissionState {
|
|
|
255
262
|
* or a batch that has accumulated additional items. */
|
|
256
263
|
export declare type AdmissionSubmission = typeof SubmissionSchema.Type;
|
|
257
264
|
|
|
265
|
+
export declare type AdmissionSubmissionRetryInspection = {
|
|
266
|
+
readonly kind: 'eligible';
|
|
267
|
+
readonly submissionId: string;
|
|
268
|
+
readonly expected: AdmissionSubmissionRetryToken;
|
|
269
|
+
} | {
|
|
270
|
+
readonly kind: 'refused';
|
|
271
|
+
readonly submissionId: string;
|
|
272
|
+
readonly reason: AdmissionSubmissionRetryRefusal;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
export declare type AdmissionSubmissionRetryRefusal = 'missing-submission' | 'incomplete-transfer' | 'accepted' | 'rejected' | 'prepared-execution' | 'dispatch-attempted' | 'not-stopped' | 'changed-retry' | 'missing-lease' | 'foreign-lease' | 'released-lease' | 'bound-lease';
|
|
276
|
+
|
|
277
|
+
export declare type AdmissionSubmissionRetryResult = {
|
|
278
|
+
readonly kind: 'retried' | 'already-retried';
|
|
279
|
+
readonly submissionId: string;
|
|
280
|
+
readonly expected: AdmissionSubmissionRetryToken;
|
|
281
|
+
} | Extract<AdmissionSubmissionRetryInspection, {
|
|
282
|
+
kind: 'refused';
|
|
283
|
+
}>;
|
|
284
|
+
|
|
285
|
+
export declare interface AdmissionSubmissionRetryToken {
|
|
286
|
+
readonly attempts: number;
|
|
287
|
+
readonly stoppedAt: number;
|
|
288
|
+
}
|
|
289
|
+
|
|
258
290
|
/** What the caller learns about a start that went through flow control. */
|
|
259
291
|
export declare type AdmissionVerdict = {
|
|
260
292
|
/** Start it now. The ledger row is already written; call `linkExecution`
|
|
@@ -555,6 +587,9 @@ export declare interface AwaitUpdateOptions<A, B = A> {
|
|
|
555
587
|
|
|
556
588
|
/** Persist BEFORE calling the engine. Failed acknowledgements and process
|
|
557
589
|
* death must leave evidence that an earlier call could have been accepted.
|
|
590
|
+
* The first dispatch starts the original finite lease interval: time spent
|
|
591
|
+
* waiting before engine I/O must not consume the running crash backstop.
|
|
592
|
+
* Later attempts retain that first deadline, including after a lost ACK.
|
|
558
593
|
* Return null when this source is no longer dispatchable. Database-only;
|
|
559
594
|
* the returned attempt number fences a later permanent-rejection decision. */
|
|
560
595
|
export declare const beginAdmissionSubmissionDispatchInTransaction: (tx: Pick<DataStore, "query" | "update">, id: string, now: number) => Promise<AdmissionSubmission | null>;
|
|
@@ -1825,6 +1860,8 @@ export declare interface InMemoryRecorder {
|
|
|
1825
1860
|
/** `rateLimit()` counts on the `RateLimiter` service; in memory it is per process. */
|
|
1826
1861
|
export declare const inMemoryWorkflowEngineLayer: Layer.Layer<WorkflowEngine.WorkflowEngine | RateLimiter.RateLimiter>;
|
|
1827
1862
|
|
|
1863
|
+
export declare const inspectAdmissionSubmissionRetry: (tx: Pick<DataStore, "query">, id: string) => Promise<AdmissionSubmissionRetryInspection>;
|
|
1864
|
+
|
|
1828
1865
|
export declare interface InspectedStep {
|
|
1829
1866
|
readonly name: string;
|
|
1830
1867
|
/** The attempt number of THIS row (1 on first try, 2+ on retry). When
|
|
@@ -2026,8 +2063,12 @@ export declare const normaliseWorkflowPatches: (value: unknown) => ReadonlyArray
|
|
|
2026
2063
|
* pending row. Missing acknowledgement does NOT prove that the engine rejected
|
|
2027
2064
|
* the call; this record deliberately makes no terminal-execution claim.
|
|
2028
2065
|
* Call inside the owning admission transaction. A reached attempt limit stops
|
|
2029
|
-
* automatic retry but retains the lease and receipt for reconciliation.
|
|
2030
|
-
|
|
2066
|
+
* automatic retry but retains the lease and receipt for reconciliation.
|
|
2067
|
+
* Pass the attempt's observed `retry.recovery?.attempts ?? 0`: an older
|
|
2068
|
+
* in-flight failure must not consume an operator's newly granted budget.
|
|
2069
|
+
* Omission means the original, unrecovered epoch; it cannot change a recovered
|
|
2070
|
+
* submission. An actual dispatch adopts the epoch returned by its begin call. */
|
|
2071
|
+
export declare const noteAdmissionSubmissionFailure: (tx: Pick<DataStore, "query" | "update">, id: string, error: string, now: number, maxAttempts?: number | false, expectedRecoveryAttempts?: number) => Promise<AdmissionSubmission>;
|
|
2031
2072
|
|
|
2032
2073
|
export declare const noteIntentAttempt: (store: AdmissionDataStore, intent: PendingIntent, error: string, now: number) => Promise<void>;
|
|
2033
2074
|
|
|
@@ -2557,6 +2598,17 @@ export declare interface RecordedStepShape {
|
|
|
2557
2598
|
readonly stepName: string;
|
|
2558
2599
|
}
|
|
2559
2600
|
|
|
2601
|
+
/** Record a known caller's pre-body refusal without replay/version/crash guards
|
|
2602
|
+
* treating the refused attempt as application execution. Entry and completion
|
|
2603
|
+
* use the ordinary resident transactions, delivery identity and generation
|
|
2604
|
+
* fences; an unknown identity cannot create a run. The original failure is
|
|
2605
|
+
* returned to the engine after its terminal record commits. */
|
|
2606
|
+
export declare const recordWorkflowExecutionRefusal: (options: WorkflowExecutionRefusalRecordingOptions, input: {
|
|
2607
|
+
readonly executionId: string;
|
|
2608
|
+
readonly payload: unknown;
|
|
2609
|
+
readonly cause: Cause.Cause<unknown>;
|
|
2610
|
+
}) => Effect.Effect<never, unknown, WorkflowInstance>;
|
|
2611
|
+
|
|
2560
2612
|
/** Database-only: call inside the resident admission transaction, together
|
|
2561
2613
|
* with the source's terminal transition. Never notify the handler from here.
|
|
2562
2614
|
* Replaying an identity keeps the first report AND recipient, even after a
|
|
@@ -2571,12 +2623,14 @@ export declare const recordWorkflowStartReceipt: (tx: Pick<DataStore, "insertIgn
|
|
|
2571
2623
|
/** Record proven pre-engine rejection together with its source and lease.
|
|
2572
2624
|
* Attempt 0 means local validation before any engine call. Attempt 1 means the
|
|
2573
2625
|
* first call returned a failure the host guarantees occurs before engine I/O.
|
|
2574
|
-
* A prior or competing attempt makes acceptance unknown, not rejected.
|
|
2626
|
+
* A prior or competing attempt makes acceptance unknown, not rejected.
|
|
2627
|
+
* Pass the same observed recovery epoch as failure bookkeeping: an older
|
|
2628
|
+
* pre-engine error cannot reject an explicitly recovered submission. */
|
|
2575
2629
|
export declare const rejectAdmissionSubmissionInTransaction: (tx: AdmissionDataStore, id: string, attempt: number, failure: {
|
|
2576
2630
|
readonly handler: string | null;
|
|
2577
2631
|
readonly errorMessage: string;
|
|
2578
2632
|
readonly now: number;
|
|
2579
|
-
}) => Promise<WorkflowFailureRecord | undefined>;
|
|
2633
|
+
}, expectedRecoveryAttempts?: number) => Promise<WorkflowFailureRecord | undefined>;
|
|
2580
2634
|
|
|
2581
2635
|
/**
|
|
2582
2636
|
* Resume every run parked on `budget`.
|
|
@@ -2926,6 +2980,12 @@ export declare const resolveWorkflowStartReceipt: (tx: Pick<DataStore, "query">,
|
|
|
2926
2980
|
|
|
2927
2981
|
export declare const resumeWorkflow: (store: AdmissionDataStore, workflowName: string) => Promise<boolean>;
|
|
2928
2982
|
|
|
2983
|
+
/** Call under the SAME resident admission transaction as preparation, dispatch,
|
|
2984
|
+
* cancellation and ACK. The preview is advisory; this locked reread decides.
|
|
2985
|
+
* Keep lifetime attempts monotonic and retain the consumed stop token so a lost
|
|
2986
|
+
* response can be retried without resuming a later exhausted retry budget. */
|
|
2987
|
+
export declare const retryAdmissionSubmissionInTransaction: (tx: Pick<DataStore, "query" | "update">, id: string, expected: AdmissionSubmissionRetryToken, now: number) => Promise<AdmissionSubmissionRetryResult>;
|
|
2988
|
+
|
|
2929
2989
|
/** Re-arm one dead-lettered intent after an operator has deployed a schema or
|
|
2930
2990
|
* handler fix. The payload and its queue-time provenance stay untouched; only
|
|
2931
2991
|
* the terminal classification and retry history are reset. */
|
|
@@ -3270,6 +3330,8 @@ export declare interface StepRetryPolicy {
|
|
|
3270
3330
|
|
|
3271
3331
|
declare type Store = Pick<DataStore, 'query' | 'insert' | 'update'>;
|
|
3272
3332
|
|
|
3333
|
+
export declare const SUBMISSIONS_TABLE = "_voltro_workflow_submissions";
|
|
3334
|
+
|
|
3273
3335
|
declare const SubmissionSchema: Schema.Struct<{
|
|
3274
3336
|
readonly id: Schema.String;
|
|
3275
3337
|
readonly workflowName: Schema.String;
|
|
@@ -3286,6 +3348,11 @@ declare const SubmissionSchema: Schema.Struct<{
|
|
|
3286
3348
|
readonly after: Schema.Number;
|
|
3287
3349
|
readonly lastError: Schema.NullOr<Schema.String>;
|
|
3288
3350
|
readonly stoppedAt: Schema.NullOr<Schema.Number>;
|
|
3351
|
+
readonly recovery: Schema.optional<Schema.Struct<{
|
|
3352
|
+
readonly attempts: Schema.Int;
|
|
3353
|
+
readonly stoppedAt: Schema.Number;
|
|
3354
|
+
readonly retriedAt: Schema.Number;
|
|
3355
|
+
}>>;
|
|
3289
3356
|
}>;
|
|
3290
3357
|
readonly payload: Schema.Unknown;
|
|
3291
3358
|
readonly callerContext: Schema.Unknown;
|
|
@@ -3407,10 +3474,15 @@ export declare const takeAdmittedSubmissionInTransaction: (tx: AdmissionDataStor
|
|
|
3407
3474
|
readonly dispatchAttempts: number;
|
|
3408
3475
|
readonly failureId: string | null;
|
|
3409
3476
|
readonly retry: {
|
|
3410
|
-
readonly attempts: number;
|
|
3411
|
-
readonly after: number;
|
|
3412
3477
|
readonly lastError: string | null;
|
|
3478
|
+
readonly attempts: number;
|
|
3413
3479
|
readonly stoppedAt: number | null;
|
|
3480
|
+
readonly after: number;
|
|
3481
|
+
readonly recovery?: {
|
|
3482
|
+
readonly attempts: number;
|
|
3483
|
+
readonly stoppedAt: number;
|
|
3484
|
+
readonly retriedAt: number;
|
|
3485
|
+
} | undefined;
|
|
3414
3486
|
};
|
|
3415
3487
|
readonly payload: unknown;
|
|
3416
3488
|
readonly callerContext: unknown;
|
|
@@ -3907,6 +3979,8 @@ export declare interface WorkflowExecuteRecordingOptions extends WorkflowRunReco
|
|
|
3907
3979
|
readonly replayShapeLimit?: number;
|
|
3908
3980
|
}
|
|
3909
3981
|
|
|
3982
|
+
export declare type WorkflowExecutionRefusalRecordingOptions = WorkflowExecuteRecordingOptions & Required<Pick<WorkflowExecuteRecordingOptions, 'subject' | 'failureContext'>>;
|
|
3983
|
+
|
|
3910
3984
|
export declare type WorkflowFailureDelivery = WorkflowFailureHandoff | {
|
|
3911
3985
|
readonly kind: 'accepted';
|
|
3912
3986
|
readonly executionId: string;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { failureMessage as e } from "./failureMessage.js";
|
|
2
|
+
import { attachPreparedWorkflowExecution as t, executePreparedWorkflow as n, hasPreparedWorkflowExecution as r } from "./preparedExecution.js";
|
|
3
|
+
import { STEP_JOURNAL_BINDING as i, WORKFLOW_JOURNAL_BINDING as a, getWorkflowJournalCipher as o, isSealedJournalValue as s, isWorkflowEncrypted as c, openErrorText as l, openEventPayload as u, openJournalValue as d, openPayloadFields as f, openWorkflowRow as p, sealJournalValue as m, setWorkflowJournalCipher as h, tryOpenJournalValue as g } from "./journalEncryption.js";
|
|
4
|
+
import { DEFERRING_CONTROLS as _, assertConsistentPools as v, deferringControlsOf as y, hasCancelOn as b, hasFlowControl as x, validateFlowControl as S } from "./flowControl.js";
|
|
5
|
+
import { CurrentWorkflowExecutionId as C, CurrentWorkflowPatches as w, CurrentWorkflowRunId as T, CurrentWorkflowStep as E, WorkflowRunRecorder as D, WorkflowStepInterceptorTag as O, currentWorkflowStep as k, getCurrentWorkflowExecutionId as A, getCurrentWorkflowRunId as j } from "./recorder.js";
|
|
6
|
+
import { DEFAULT_WORKFLOW_SCHEDULE_MAX_RUNTIME_MS as M, WorkflowScheduleProperty as N, getWorkflowSchedule as P, validateWorkflowSchedule as F } from "./scheduleDeclaration.js";
|
|
7
|
+
import { CurrentWorkflowReplayShape as I, makeReplayShapeTracker as L, nondeterminismEventPayload as R, reportNondeterminism as z } from "./nondeterminism.js";
|
|
8
|
+
import { WorkflowFlowControlProperty as B, WorkflowMessagesProperty as V, WorkflowVersionTypeId as H, WorkflowWorkerLayerTypeId as U, durableClock as W, durableQueue as G, durableQueueModule as K, getWorkflowFlowControl as q, getWorkflowVersionMetadata as J, isCarrier as Y, isWorkflowWorkerLayer as X, patch as Z, processQueue as Q, queueWorker as $, rateLimit as ee, sleep as te, sleepUntil as ne, step as re, stepIdempotencyKey as ie, stepModule as ae, withCompensation as oe, workflow as se, workflowModule as ce } from "./primitives.js";
|
|
9
|
+
import { inMemoryWorkflowEngineLayer as le } from "./inMemoryLayer.js";
|
|
10
|
+
import { _voltroWorkflowRunsTable as ue } from "./runsTable.js";
|
|
11
|
+
import { _voltroWorkflowRunStepsTable as de } from "./runStepsTable.js";
|
|
12
|
+
import { _voltroWorkflowRunEventsTable as fe } from "./runEventsTable.js";
|
|
13
|
+
import { _voltroWorkflowStartContextsTable as pe } from "./startContextsTable.js";
|
|
14
|
+
import { _voltroWorkflowAdmissionLocksTable as me, _voltroWorkflowAdmissionsTable as he, _voltroWorkflowControlRequestsTable as ge, _voltroWorkflowFailureReportsTable as _e, _voltroWorkflowParentClosuresTable as ve, _voltroWorkflowPausesTable as ye, _voltroWorkflowPendingTable as be, _voltroWorkflowStartReceiptsTable as xe, _voltroWorkflowSubmissionsTable as Se } from "./admissionTables.js";
|
|
15
|
+
import { withAdmissionTransaction as Ce } from "./admissionTransaction.js";
|
|
16
|
+
import { FlowControlKeyError as we, comparePendingOrder as Te, decideAdmission as Ee, isFinishExpired as De, isStartExpired as Oe, nextSlotAt as ke, pooledConcurrencyKey as Ae, resolveAdmissionKeys as je } from "./admission.js";
|
|
17
|
+
import { readWorkflowFailureRecord as Me, recordWorkflowFailureInTransaction as Ne } from "./failureReportStore.js";
|
|
18
|
+
import { handoffWorkflowFailureInTransaction as Pe, reconcileWorkflowFailureInTransaction as Fe } from "./failureHandoff.js";
|
|
19
|
+
import { ADMISSION_SUBMISSION_ID_PREFIX as Ie, SUBMISSIONS_TABLE as Le, acknowledgeAdmissionSubmission as Re, beginAdmissionSubmissionDispatchInTransaction as ze, newAdmissionSubmissionId as Be, noteAdmissionSubmissionFailure as Ve, pendingAdmissionSubmissions as He, prepareAdmissionSubmissionExecutionInTransaction as Ue, readAdmissionSubmission as We, rejectAdmissionSubmissionInTransaction as Ge, reserveAdmissionSubmission as Ke, reserveAdmissionSubmissionInTransaction as qe } from "./admissionSubmission.js";
|
|
20
|
+
import { WorkflowStartRequestConflictError as Je, bindWorkflowStartReceipts as Ye, readWorkflowStartReceipt as Xe, readWorkflowStartRequest as Ze, recordWorkflowStartReceipt as Qe, resolveWorkflowStartReceipt as $e } from "./startReceipt.js";
|
|
21
|
+
import { ADMISSIONS_TABLE as et, DEFAULT_LEASE_MS as tt, PAUSES_TABLE as nt, PENDING_TABLE as rt, admissionLeaseHeldPredicate as it, allIntents as at, deadLetterIntent as ot, deleteIntent as st, discardIntent as ct, discardIntentInTransaction as lt, dueIntents as ut, evaluateAdmission as dt, noteIntentAttempt as ft, parkDelayedStart as pt, pauseWorkflow as mt, pendingSlotId as ht, pendingWindow as gt, persistDefer as _t, pruneAdmissions as vt, readAdmissionState as yt, readPausedWorkflows as bt, recordAdmission as xt, releaseLease as St, resumeWorkflow as Ct, retryDeadLetterIntent as wt } from "./admissionStore.js";
|
|
22
|
+
import { acceptWorkflowControlInTransaction as Tt, beginWorkflowControlDispatchInTransaction as Et, bindWorkflowResumeJournalInTransaction as Dt, readWorkflowControlInTransaction as Ot } from "./controlRequest.js";
|
|
23
|
+
import { stageWorkflowParentClosureInTransaction as kt } from "./parentClosure.js";
|
|
24
|
+
import { readWorkflowRestartObservationInTransaction as At, reserveWorkflowRestartInTransaction as jt, withdrawWorkflowRestartInTransaction as Mt, workflowRestartRequestsTable as Nt, workflowRestartWithdrawalsTable as Pt } from "./workflowRestartReservation.js";
|
|
25
|
+
import { cancelSuspendedWorkflowRunInTransaction as Ft, completeWorkflowRunGenerationInTransaction as It, enterWorkflowRunGenerationInTransaction as Lt } from "./runGeneration.js";
|
|
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 };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { openJournalValue as e, openPayloadFields as t } from "./journalEncryption.js";
|
|
2
|
+
import { _voltroWorkflowRunsTable as n } from "./runsTable.js";
|
|
3
|
+
import { _voltroWorkflowRunStepsTable as r } from "./runStepsTable.js";
|
|
4
|
+
import { eq as i, or as a, queryFor as o } from "@voltro/database";
|
|
5
|
+
import { types as s } from "node:util";
|
|
6
|
+
//#region src/inspectWorkflow.ts
|
|
7
|
+
var c = (e) => {
|
|
8
|
+
if (e == null) return null;
|
|
9
|
+
if (e instanceof Date) return e;
|
|
10
|
+
if (typeof e == "string" || typeof e == "number") {
|
|
11
|
+
let t = new Date(e);
|
|
12
|
+
return Number.isNaN(t.getTime()) ? null : t;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}, l = (e) => typeof e == "number" ? e : e == null ? null : Number(e), u = (e) => e == null ? null : String(e), d = (e) => {
|
|
16
|
+
if (s.isProxy(e)) return !1;
|
|
17
|
+
let t = Object.getPrototypeOf(e);
|
|
18
|
+
if (t !== null && t !== Object.prototype) return !1;
|
|
19
|
+
for (let t of Reflect.ownKeys(e)) {
|
|
20
|
+
let n = Object.getOwnPropertyDescriptor(e, t);
|
|
21
|
+
if (n === void 0 || !("value" in n)) return !1;
|
|
22
|
+
}
|
|
23
|
+
let n = Object.getOwnPropertyDescriptor(e, "stepName");
|
|
24
|
+
if (n === void 0 || !("value" in n) || typeof n.value != "string") return !1;
|
|
25
|
+
for (let t of [
|
|
26
|
+
"attempt",
|
|
27
|
+
"durationMs",
|
|
28
|
+
"errorTag",
|
|
29
|
+
"errorMessage",
|
|
30
|
+
"startedAt"
|
|
31
|
+
]) {
|
|
32
|
+
let n = Object.getOwnPropertyDescriptor(e, t);
|
|
33
|
+
if (n === void 0) {
|
|
34
|
+
if (t in e) return !1;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
let r = n.value;
|
|
38
|
+
if (typeof r == "object" && r && s.isProxy(r) || !(t === "startedAt" && r instanceof Date && Object.getPrototypeOf(r) === Date.prototype && Reflect.ownKeys(r).length === 0) && r != null && typeof r != "number" && typeof r != "string" && typeof r != "boolean") return !1;
|
|
39
|
+
}
|
|
40
|
+
return !0;
|
|
41
|
+
}, f = (e) => {
|
|
42
|
+
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = !s.isProxy(e) && Object.getPrototypeOf(e) === Array.prototype && !Object.hasOwn(e, Symbol.iterator) && e.find === Array.prototype.find, i = 0;
|
|
43
|
+
for (let a of e) {
|
|
44
|
+
let o = r ? Object.getOwnPropertyDescriptor(e, String(i)) : void 0;
|
|
45
|
+
(o === void 0 || !("value" in o) || !d(a)) && (r = !1), i++;
|
|
46
|
+
let s = String(a.stepName), c = t.get(s);
|
|
47
|
+
c === void 0 ? (t.set(s, [a]), n.set(s, a)) : c.push(a);
|
|
48
|
+
}
|
|
49
|
+
let a = [];
|
|
50
|
+
for (let [e, n] of t) {
|
|
51
|
+
n.sort((e, t) => (l(e.attempt) ?? 0) - (l(t.attempt) ?? 0));
|
|
52
|
+
let t = n[n.length - 1], r = u(t.errorTag), i = u(t.errorMessage), o = r !== null || i !== null ? {
|
|
53
|
+
tag: r,
|
|
54
|
+
message: i ?? ""
|
|
55
|
+
} : null;
|
|
56
|
+
a.push({
|
|
57
|
+
name: e,
|
|
58
|
+
attempt: l(t.attempt) ?? n.length,
|
|
59
|
+
attempts: n.length,
|
|
60
|
+
status: t.status ?? "running",
|
|
61
|
+
input: t.input ?? null,
|
|
62
|
+
output: t.output ?? null,
|
|
63
|
+
error: o,
|
|
64
|
+
durationMs: l(t.durationMs)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return a.sort((t, i) => {
|
|
68
|
+
let a = r ? n.get(t.name) : e.find((e) => String(e.stepName) === t.name), o = r ? n.get(i.name) : e.find((e) => String(e.stepName) === i.name);
|
|
69
|
+
return (c(a?.startedAt)?.getTime() ?? 0) - (c(o?.startedAt)?.getTime() ?? 0);
|
|
70
|
+
}), a;
|
|
71
|
+
}, p = (e) => {
|
|
72
|
+
if (e == null) return null;
|
|
73
|
+
if (typeof e == "string") try {
|
|
74
|
+
return JSON.parse(e);
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return typeof e == "object" ? e : null;
|
|
79
|
+
}, m = async (s, l) => {
|
|
80
|
+
let d = o(n), m = (await l.query(d.where(a(i("id", s), i("executionId", s))).limit(1).descriptor))[0];
|
|
81
|
+
if (m === void 0) return null;
|
|
82
|
+
let h = String(m.id), g = o(r), _ = await l.query(g.where(i("runId", h)).descriptor);
|
|
83
|
+
return {
|
|
84
|
+
id: h,
|
|
85
|
+
executionId: u(m.executionId) ?? "",
|
|
86
|
+
name: u(m.tag) ?? "",
|
|
87
|
+
status: m.status ?? "running",
|
|
88
|
+
input: t(m.payload ?? null, "workflow run payload"),
|
|
89
|
+
output: e(m.output ?? null, "workflow run result"),
|
|
90
|
+
subject: p(m.subject),
|
|
91
|
+
source: u(m.source),
|
|
92
|
+
steps: f(_),
|
|
93
|
+
startedAt: c(m.startedAt) ?? /* @__PURE__ */ new Date(0),
|
|
94
|
+
finishedAt: c(m.completedAt),
|
|
95
|
+
traceId: u(m.traceId),
|
|
96
|
+
parentExecutionId: u(m.parentExecutionId),
|
|
97
|
+
parentClosePolicy: u(m.parentClosePolicy)
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
export { m as inspectWorkflow };
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (typeof t == "string" && t.length > 0) return t;
|
|
7
|
-
if (typeof e == "object" && e && typeof e.toJSON == "function") {
|
|
8
|
-
let { _tag: t, ...n } = e.toJSON(), r = typeof t == "string" ? t : String(e);
|
|
9
|
-
return Object.keys(n).length === 0 ? r : `${r}: ${JSON.stringify(n)}`;
|
|
10
|
-
}
|
|
11
|
-
return String(e);
|
|
12
|
-
}, u = () => void 0, d = (e) => {
|
|
1
|
+
import { failureMessage as e } from "./failureMessage.js";
|
|
2
|
+
import { Activity as t } from "effect/workflow";
|
|
3
|
+
import { Cause as n, Context as r, Effect as i, Effectable as a, Schema as o, SchemaAST as s, SchemaGetter as c, SchemaIssue as l } from "effect";
|
|
4
|
+
//#region src/journalEncryption.ts
|
|
5
|
+
var u = () => void 0, d = (e) => {
|
|
13
6
|
u = typeof e == "function" ? e : () => e;
|
|
14
|
-
}, f = () => u(), p =
|
|
7
|
+
}, f = () => u(), p = r.Reference("@voltro/workflow/CurrentWorkflowEncrypted", { defaultValue: () => !1 }), m = { column: "workflow-journal" }, h = /* @__PURE__ */ new Set(), g = (e) => {
|
|
15
8
|
h.add(e);
|
|
16
9
|
}, _ = /* @__PURE__ */ new Set(), v = (e) => {
|
|
17
10
|
_.add(e);
|
|
@@ -25,21 +18,21 @@ var l = (e) => {
|
|
|
25
18
|
let r = u();
|
|
26
19
|
if (r === void 0) throw S(t);
|
|
27
20
|
return JSON.parse(r.decrypt(e, n));
|
|
28
|
-
}, T = (e) =>
|
|
21
|
+
}, T = (e) => s.isVoid(e) || s.isNever(e) || s.isUndefined(e), E = (e, t) => {
|
|
29
22
|
if (T(e.ast)) return e;
|
|
30
23
|
let n = (e, t) => {
|
|
31
24
|
try {
|
|
32
|
-
return
|
|
25
|
+
return i.succeed(t());
|
|
33
26
|
} catch (t) {
|
|
34
|
-
return
|
|
27
|
+
return i.fail(new l.InvalidValue({ message: t.message }, e));
|
|
35
28
|
}
|
|
36
29
|
};
|
|
37
|
-
return (e.ast.context?.isOptional === !0 ?
|
|
38
|
-
decode:
|
|
39
|
-
encode:
|
|
30
|
+
return (e.ast.context?.isOptional === !0 ? o.optionalKey(o.Unknown) : o.Unknown).pipe(o.decodeTo(e, {
|
|
31
|
+
decode: c.transformEffect((e) => n(e, () => Array.isArray(e) ? e.map((e) => w(e, t)) : w(e, t))),
|
|
32
|
+
encode: c.transformEffect((e) => n(e, () => e === void 0 ? void 0 : C(e, t)))
|
|
40
33
|
}));
|
|
41
34
|
}, D = (e, t) => {
|
|
42
|
-
let n =
|
|
35
|
+
let n = o.isSchema(t) ? t.fields : t, r = `workflow '${e}' payload`, i = {};
|
|
43
36
|
for (let [e, t] of Object.entries(n)) i[e] = E(t, `${r}.${e}`);
|
|
44
37
|
return i;
|
|
45
38
|
}, O = (e) => typeof e == "object" && !!e && !Array.isArray(e), k = (e, t) => {
|
|
@@ -102,21 +95,21 @@ var l = (e) => {
|
|
|
102
95
|
let t = { ...e };
|
|
103
96
|
for (let e of z) x(t[e]) && (t[e] = L(t[e], `workflow event ${e}`));
|
|
104
97
|
return t;
|
|
105
|
-
}, H = (
|
|
106
|
-
let n =
|
|
107
|
-
...
|
|
108
|
-
error:
|
|
109
|
-
}),
|
|
110
|
-
...
|
|
111
|
-
success: E(
|
|
112
|
-
error:
|
|
113
|
-
execute:
|
|
98
|
+
}, H = (e) => {
|
|
99
|
+
let n = t.make({
|
|
100
|
+
...e,
|
|
101
|
+
error: o.Defect()
|
|
102
|
+
}), r, s = `wait '${e.name}'`, c = () => r ??= t.make({
|
|
103
|
+
...e,
|
|
104
|
+
success: E(e.success, `${s} value`),
|
|
105
|
+
error: o.Defect(),
|
|
106
|
+
execute: e.execute.pipe(i.catchDefect((e) => i.die(M(e, `${s} defect`))))
|
|
114
107
|
}), l = n;
|
|
115
108
|
return {
|
|
116
109
|
...n,
|
|
117
|
-
...
|
|
110
|
+
...a.Prototype({
|
|
118
111
|
label: "Activity",
|
|
119
|
-
evaluate: () =>
|
|
112
|
+
evaluate: () => i.flatMap(p, (e) => e ? c().pipe(i.catchDefect((e) => i.die(N(e, `${s} defect`)))) : l)
|
|
120
113
|
})
|
|
121
114
|
};
|
|
122
115
|
}, U = { column: "_voltro_workflow_run_steps:payload" }, W = (e) => {
|
|
@@ -143,12 +136,12 @@ var l = (e) => {
|
|
|
143
136
|
t.payload = k(t.payload, "workflow run payload");
|
|
144
137
|
} catch {}
|
|
145
138
|
return "output" in t && (t.output = L(t.output, "workflow run result")), typeof t.errorMessage == "string" && (t.errorMessage = R(t.errorMessage)), t;
|
|
146
|
-
}, K = (
|
|
147
|
-
if (
|
|
148
|
-
let
|
|
149
|
-
return
|
|
139
|
+
}, K = (t, r) => {
|
|
140
|
+
if (t === void 0 || !b(t)) {
|
|
141
|
+
let t = n.isCause(r) ? n.squash(r) : r;
|
|
142
|
+
return t instanceof Error && t.message.length > 0 ? `${t.name}: ${t.message}` : e(t);
|
|
150
143
|
}
|
|
151
|
-
return `${
|
|
144
|
+
return `${r instanceof Error ? r.name : typeof r}: [withheld — workflow '${t}' is declared encrypted; the full cause is recorded sealed on its row]`;
|
|
152
145
|
};
|
|
153
146
|
//#endregion
|
|
154
|
-
export {
|
|
147
|
+
export { p as CurrentWorkflowEncrypted, j as SEALED_DEFECT_NAME, U as STEP_JOURNAL_BINDING, m as WORKFLOW_JOURNAL_BINDING, F as anyWorkflowEncrypted, H as encryptionAwareActivity, f as getWorkflowJournalCipher, y as isQueueEncrypted, x as isSealedJournalValue, b as isWorkflowEncrypted, K as loggableCause, v as markQueueEncrypted, g as markWorkflowEncrypted, N as openDefect, R as openErrorText, V as openEventPayload, w as openJournalValue, k as openPayloadFields, G as openWorkflowRow, M as sealDefect, I as sealErrorText, B as sealEventPayload, C as sealJournalValue, A as sealPayloadFields, D as sealedPayloadFields, E as sealedSchema, d as setWorkflowJournalCipher, L as tryOpenJournalValue };
|
package/dist/messages.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { openEventPayload as e } from "./journalEncryption.js";
|
|
2
|
+
import { eq as t } from "@voltro/database";
|
|
3
|
+
//#region src/messages.ts
|
|
4
|
+
var n = (e) => new Promise((t) => setTimeout(t, e)), r = () => {
|
|
5
|
+
let e = globalThis.crypto;
|
|
6
|
+
return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
7
|
+
}, i = () => `wfu_${r()}`, a = async (e, n) => {
|
|
8
|
+
let r = n.id ?? n.executionId;
|
|
9
|
+
if (!r) throw Error("workflow message target requires target.id or target.executionId");
|
|
10
|
+
let i = await e.query({
|
|
11
|
+
table: "_voltro_workflow_runs",
|
|
12
|
+
order: [],
|
|
13
|
+
predicate: t("id", r),
|
|
14
|
+
projection: void 0,
|
|
15
|
+
skip: void 0,
|
|
16
|
+
take: 1
|
|
17
|
+
});
|
|
18
|
+
if (i[0]) return i[0];
|
|
19
|
+
let a = (await e.query({
|
|
20
|
+
table: "_voltro_workflow_runs",
|
|
21
|
+
order: [],
|
|
22
|
+
predicate: t("executionId", r),
|
|
23
|
+
projection: void 0,
|
|
24
|
+
skip: void 0,
|
|
25
|
+
take: 1
|
|
26
|
+
}))[0];
|
|
27
|
+
if (!a) throw Error(`workflow message target not found: ${r}`);
|
|
28
|
+
return a;
|
|
29
|
+
}, o = class extends Error {
|
|
30
|
+
runId;
|
|
31
|
+
eventType;
|
|
32
|
+
eventId;
|
|
33
|
+
_tag = "WorkflowMessageNotRecorded";
|
|
34
|
+
constructor(e, t, n) {
|
|
35
|
+
super(`workflow ${t} for run ${e} was NOT recorded (event ${n}): the run will not see it — the store refused the row, see the recorder's warning`), this.runId = e, this.eventType = t, this.eventId = n, this.name = "WorkflowMessageNotRecorded";
|
|
36
|
+
}
|
|
37
|
+
}, s = async (e) => {
|
|
38
|
+
let t = await a(e.store, e.target), n = await e.recorder.recordEvent({
|
|
39
|
+
runId: t.id,
|
|
40
|
+
eventType: "signal-sent",
|
|
41
|
+
payload: {
|
|
42
|
+
signalName: e.signalName,
|
|
43
|
+
value: e.payload
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
if (n.recorded === !1) throw new o(t.id, "signal-sent", n.id);
|
|
47
|
+
return { eventId: n.id };
|
|
48
|
+
}, c = async (r) => {
|
|
49
|
+
let s = await a(r.store, r.target), c = i(), l = await r.recorder.recordEvent({
|
|
50
|
+
runId: s.id,
|
|
51
|
+
eventType: "update-requested",
|
|
52
|
+
payload: {
|
|
53
|
+
updateId: c,
|
|
54
|
+
updateName: r.updateName,
|
|
55
|
+
value: r.payload
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
if (l.recorded === !1) throw new o(s.id, "update-requested", l.id);
|
|
59
|
+
let u = Date.now(), d = r.options?.timeoutMs ?? 3e4, f = r.options?.pollIntervalMs ?? 100;
|
|
60
|
+
for (;;) {
|
|
61
|
+
let i = {
|
|
62
|
+
table: "_voltro_workflow_run_events",
|
|
63
|
+
order: [{
|
|
64
|
+
column: "occurredAt",
|
|
65
|
+
direction: "asc"
|
|
66
|
+
}],
|
|
67
|
+
predicate: t("runId", s.id),
|
|
68
|
+
projection: void 0,
|
|
69
|
+
skip: void 0,
|
|
70
|
+
take: 1e3
|
|
71
|
+
}, a = await r.store.query(i), o = a.find((e) => e.eventType === "update-completed" && e.payload?.updateId === c);
|
|
72
|
+
if (o) return {
|
|
73
|
+
eventId: l.id,
|
|
74
|
+
updateId: c,
|
|
75
|
+
completedEventId: o.id,
|
|
76
|
+
result: e(o.payload)?.result
|
|
77
|
+
};
|
|
78
|
+
let p = a.find((e) => e.eventType === "update-failed" && e.payload?.updateId === c);
|
|
79
|
+
if (p) {
|
|
80
|
+
let t = Error(e(p.payload)?.errorMessage ?? `workflow update '${r.updateName}' failed`);
|
|
81
|
+
throw Object.assign(t, {
|
|
82
|
+
updateId: c,
|
|
83
|
+
eventId: l.id,
|
|
84
|
+
errorTag: p.payload?.errorTag ?? null
|
|
85
|
+
}), t;
|
|
86
|
+
}
|
|
87
|
+
if (Date.now() - u >= d) throw Error(`Timed out waiting for workflow update '${r.updateName}' (${c})`);
|
|
88
|
+
await n(f);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
export { o as WorkflowMessageNotRecorded, i as makeWorkflowUpdateId, a as resolveWorkflowMessageRun, s as sendWorkflowSignal, c as sendWorkflowUpdate };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CurrentWorkflowRunId as e, WorkflowRunRecorder as t } from "./recorder.js";
|
|
2
|
+
import { Context as n, Effect as r } from "effect";
|
|
3
|
+
//#region src/nondeterminism.ts
|
|
4
|
+
var i = (e) => {
|
|
5
|
+
let t = /* @__PURE__ */ new Map();
|
|
6
|
+
for (let n of e) t.set(n.stepName, (t.get(n.stepName) ?? 0) + 1);
|
|
7
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), i = (e) => !r.has(e) && (r.add(e), !0);
|
|
8
|
+
return {
|
|
9
|
+
reach: (e) => {
|
|
10
|
+
let r = (n.get(e) ?? 0) + 1;
|
|
11
|
+
n.set(e, r);
|
|
12
|
+
let a = t.get(e) ?? 0;
|
|
13
|
+
if (a !== 0 && !(r <= a) && i(`extra:${e}`)) return {
|
|
14
|
+
kind: "extra-step-occurrence",
|
|
15
|
+
stepName: e,
|
|
16
|
+
recorded: a,
|
|
17
|
+
reached: r,
|
|
18
|
+
detail: `step '${e}' was reached ${r} time(s) on this attempt but this run only ever recorded ${a} — the body may have changed how often it runs this step (a loop bound), so the journal replays a result for an iteration the code no longer means.`
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
settle: () => {
|
|
22
|
+
let e = [];
|
|
23
|
+
for (let [r, a] of t) (n.get(r) ?? 0) > 0 || i(`unreached:${r}`) && e.push({
|
|
24
|
+
kind: "unreached-step",
|
|
25
|
+
stepName: r,
|
|
26
|
+
recorded: a,
|
|
27
|
+
reached: 0,
|
|
28
|
+
detail: `step '${r}' ran on an earlier attempt of this run but the current code never reaches it — the step was renamed, removed, or moved behind a branch, so its journaled result is orphaned and any step that replaced it executed fresh.`
|
|
29
|
+
});
|
|
30
|
+
return e;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}, a = n.Reference("@voltro/workflow/CurrentWorkflowReplayShape", { defaultValue: () => void 0 }), o = (e) => ({
|
|
34
|
+
kind: e.kind,
|
|
35
|
+
stepName: e.stepName,
|
|
36
|
+
recorded: e.recorded,
|
|
37
|
+
reached: e.reached,
|
|
38
|
+
detail: e.detail
|
|
39
|
+
}), s = (n) => r.gen(function* () {
|
|
40
|
+
if (n.length === 0) return;
|
|
41
|
+
let i = yield* e, a = yield* r.serviceOption(t);
|
|
42
|
+
if (i === void 0 || a._tag !== "Some") return;
|
|
43
|
+
let s = a.value;
|
|
44
|
+
for (let e of n) yield* r.promise(() => s.recordEvent({
|
|
45
|
+
runId: i,
|
|
46
|
+
eventType: "nondeterminism-suspected",
|
|
47
|
+
payload: o(e)
|
|
48
|
+
}).then(() => void 0).catch(() => void 0));
|
|
49
|
+
});
|
|
50
|
+
//#endregion
|
|
51
|
+
export { a as CurrentWorkflowReplayShape, i as makeReplayShapeTracker, o as nondeterminismEventPayload, s as reportNondeterminism };
|