@nestjs/workflows 0.0.1
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/LICENSE +23 -0
- package/README.md +50 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +8 -0
- package/dist/core/codecs/aes-gcm-payload.codec.d.ts +42 -0
- package/dist/core/codecs/aes-gcm-payload.codec.js +119 -0
- package/dist/core/codecs/index.d.ts +2 -0
- package/dist/core/codecs/index.js +2 -0
- package/dist/core/codecs/payload-codecs.d.ts +59 -0
- package/dist/core/codecs/payload-codecs.js +130 -0
- package/dist/core/index.d.ts +16 -0
- package/dist/core/index.js +21 -0
- package/dist/core/interfaces/clock.interface.d.ts +18 -0
- package/dist/core/interfaces/clock.interface.js +1 -0
- package/dist/core/interfaces/index.d.ts +9 -0
- package/dist/core/interfaces/index.js +9 -0
- package/dist/core/interfaces/leased-worker-options.interface.d.ts +94 -0
- package/dist/core/interfaces/leased-worker-options.interface.js +1 -0
- package/dist/core/interfaces/limits.interface.d.ts +92 -0
- package/dist/core/interfaces/limits.interface.js +1 -0
- package/dist/core/interfaces/payload-codec.interface.d.ts +64 -0
- package/dist/core/interfaces/payload-codec.interface.js +1 -0
- package/dist/core/interfaces/result-waiter-options.interface.d.ts +52 -0
- package/dist/core/interfaces/result-waiter-options.interface.js +1 -0
- package/dist/core/interfaces/retry-settings.interface.d.ts +71 -0
- package/dist/core/interfaces/retry-settings.interface.js +1 -0
- package/dist/core/interfaces/schedule-store.interface.d.ts +143 -0
- package/dist/core/interfaces/schedule-store.interface.js +1 -0
- package/dist/core/interfaces/schedule.interface.d.ts +106 -0
- package/dist/core/interfaces/schedule.interface.js +1 -0
- package/dist/core/interfaces/scheduler-options.interface.d.ts +152 -0
- package/dist/core/interfaces/scheduler-options.interface.js +1 -0
- package/dist/core/limits/index.d.ts +1 -0
- package/dist/core/limits/index.js +1 -0
- package/dist/core/limits/limits.d.ts +61 -0
- package/dist/core/limits/limits.js +130 -0
- package/dist/core/results/index.d.ts +1 -0
- package/dist/core/results/index.js +1 -0
- package/dist/core/results/result-waiter.d.ts +54 -0
- package/dist/core/results/result-waiter.js +140 -0
- package/dist/core/retries/index.d.ts +1 -0
- package/dist/core/retries/index.js +1 -0
- package/dist/core/retries/retry.d.ts +60 -0
- package/dist/core/retries/retry.js +107 -0
- package/dist/core/scheduling/cron.util.d.ts +52 -0
- package/dist/core/scheduling/cron.util.js +262 -0
- package/dist/core/scheduling/encoded-schedule.store.d.ts +26 -0
- package/dist/core/scheduling/encoded-schedule.store.js +54 -0
- package/dist/core/scheduling/in-memory-schedule.store.d.ts +20 -0
- package/dist/core/scheduling/in-memory-schedule.store.js +90 -0
- package/dist/core/scheduling/index.d.ts +3 -0
- package/dist/core/scheduling/index.js +3 -0
- package/dist/core/scheduling/rrule.util.d.ts +55 -0
- package/dist/core/scheduling/rrule.util.js +371 -0
- package/dist/core/scheduling/schedule-spec.d.ts +57 -0
- package/dist/core/scheduling/schedule-spec.js +233 -0
- package/dist/core/scheduling/scheduler.d.ts +134 -0
- package/dist/core/scheduling/scheduler.js +450 -0
- package/dist/core/scheduling/time-zone.util.d.ts +18 -0
- package/dist/core/scheduling/time-zone.util.js +88 -0
- package/dist/core/time/clock.d.ts +28 -0
- package/dist/core/time/clock.js +35 -0
- package/dist/core/time/duration.d.ts +21 -0
- package/dist/core/time/duration.js +30 -0
- package/dist/core/time/index.d.ts +2 -0
- package/dist/core/time/index.js +2 -0
- package/dist/core/utils/canonical.util.d.ts +2 -0
- package/dist/core/utils/canonical.util.js +4 -0
- package/dist/core/utils/maybe.util.d.ts +8 -0
- package/dist/core/utils/maybe.util.js +14 -0
- package/dist/core/utils/payload-place.util.d.ts +10 -0
- package/dist/core/utils/payload-place.util.js +32 -0
- package/dist/core/workers/index.d.ts +1 -0
- package/dist/core/workers/index.js +1 -0
- package/dist/core/workers/leased-worker.d.ts +86 -0
- package/dist/core/workers/leased-worker.js +280 -0
- package/dist/cqrs/decorators/index.d.ts +2 -0
- package/dist/cqrs/decorators/index.js +2 -0
- package/dist/cqrs/decorators/signal-on.decorator.d.ts +18 -0
- package/dist/cqrs/decorators/signal-on.decorator.js +34 -0
- package/dist/cqrs/decorators/start-on.decorator.d.ts +18 -0
- package/dist/cqrs/decorators/start-on.decorator.js +49 -0
- package/dist/cqrs/index.d.ts +3 -0
- package/dist/cqrs/index.js +5 -0
- package/dist/cqrs/interfaces/index.d.ts +4 -0
- package/dist/cqrs/interfaces/index.js +4 -0
- package/dist/cqrs/interfaces/signal-on-options.interface.d.ts +22 -0
- package/dist/cqrs/interfaces/signal-on-options.interface.js +1 -0
- package/dist/cqrs/interfaces/start-on-options.interface.d.ts +23 -0
- package/dist/cqrs/interfaces/start-on-options.interface.js +1 -0
- package/dist/cqrs/interfaces/workflow-dispatcher-context.interface.d.ts +10 -0
- package/dist/cqrs/interfaces/workflow-dispatcher-context.interface.js +1 -0
- package/dist/cqrs/interfaces/workflow-event-route.interface.d.ts +20 -0
- package/dist/cqrs/interfaces/workflow-event-route.interface.js +1 -0
- package/dist/cqrs/utils/event-routes.util.d.ts +7 -0
- package/dist/cqrs/utils/event-routes.util.js +22 -0
- package/dist/cqrs/workflow-event.publisher.d.ts +52 -0
- package/dist/cqrs/workflow-event.publisher.js +257 -0
- package/dist/cqrs/workflow-events.explorer.d.ts +27 -0
- package/dist/cqrs/workflow-events.explorer.js +92 -0
- package/dist/cqrs/workflows-cqrs.module.d.ts +10 -0
- package/dist/cqrs/workflows-cqrs.module.js +27 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +1 -0
- package/dist/decorators/workflow.decorator.d.ts +7 -0
- package/dist/decorators/workflow.decorator.js +52 -0
- package/dist/errors/child-workflow-failed.error.d.ts +13 -0
- package/dist/errors/child-workflow-failed.error.js +14 -0
- package/dist/errors/index.d.ts +13 -0
- package/dist/errors/index.js +13 -0
- package/dist/errors/non-retryable-step.error.d.ts +4 -0
- package/dist/errors/non-retryable-step.error.js +7 -0
- package/dist/errors/step-failed.error.d.ts +15 -0
- package/dist/errors/step-failed.error.js +16 -0
- package/dist/errors/step-timeout.error.d.ts +5 -0
- package/dist/errors/step-timeout.error.js +8 -0
- package/dist/errors/workflow-definition.error.d.ts +10 -0
- package/dist/errors/workflow-definition.error.js +13 -0
- package/dist/errors/workflow-failed.error.d.ts +20 -0
- package/dist/errors/workflow-failed.error.js +17 -0
- package/dist/errors/workflow-id-conflict.error.d.ts +6 -0
- package/dist/errors/workflow-id-conflict.error.js +9 -0
- package/dist/errors/workflow-interrupt.error.d.ts +32 -0
- package/dist/errors/workflow-interrupt.error.js +19 -0
- package/dist/errors/workflow-non-determinism.error.d.ts +4 -0
- package/dist/errors/workflow-non-determinism.error.js +7 -0
- package/dist/errors/workflow-not-found.error.d.ts +10 -0
- package/dist/errors/workflow-not-found.error.js +13 -0
- package/dist/errors/workflow-result-timeout.error.d.ts +11 -0
- package/dist/errors/workflow-result-timeout.error.js +13 -0
- package/dist/errors/workflow-state.error.d.ts +11 -0
- package/dist/errors/workflow-state.error.js +14 -0
- package/dist/errors/workflow.error.d.ts +7 -0
- package/dist/errors/workflow.error.js +7 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.js +3 -0
- package/dist/events/workflow-events.interface.d.ts +145 -0
- package/dist/events/workflow-events.interface.js +1 -0
- package/dist/events/workflow-events.service.d.ts +17 -0
- package/dist/events/workflow-events.service.js +38 -0
- package/dist/events/workflows.channels.d.ts +3 -0
- package/dist/events/workflows.channels.js +9 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +23 -0
- package/dist/interfaces/index.d.ts +13 -0
- package/dist/interfaces/index.js +13 -0
- package/dist/interfaces/serialized-workflow-error.interface.d.ts +6 -0
- package/dist/interfaces/serialized-workflow-error.interface.js +1 -0
- package/dist/interfaces/workflow-client.interface.d.ts +156 -0
- package/dist/interfaces/workflow-client.interface.js +1 -0
- package/dist/interfaces/workflow-clock.interface.d.ts +7 -0
- package/dist/interfaces/workflow-clock.interface.js +1 -0
- package/dist/interfaces/workflow-context.interface.d.ts +241 -0
- package/dist/interfaces/workflow-context.interface.js +1 -0
- package/dist/interfaces/workflow-decorator-options.interface.d.ts +101 -0
- package/dist/interfaces/workflow-decorator-options.interface.js +1 -0
- package/dist/interfaces/workflow-instance.interface.d.ts +83 -0
- package/dist/interfaces/workflow-instance.interface.js +1 -0
- package/dist/interfaces/workflow-payload-codec.interface.d.ts +32 -0
- package/dist/interfaces/workflow-payload-codec.interface.js +1 -0
- package/dist/interfaces/workflow-retry-options.interface.d.ts +9 -0
- package/dist/interfaces/workflow-retry-options.interface.js +1 -0
- package/dist/interfaces/workflow-runner.interface.d.ts +11 -0
- package/dist/interfaces/workflow-runner.interface.js +1 -0
- package/dist/interfaces/workflow-schedule.interface.d.ts +104 -0
- package/dist/interfaces/workflow-schedule.interface.js +1 -0
- package/dist/interfaces/workflow-storage.interface.d.ts +4 -0
- package/dist/interfaces/workflow-storage.interface.js +1 -0
- package/dist/interfaces/workflow-store.interface.d.ts +488 -0
- package/dist/interfaces/workflow-store.interface.js +1 -0
- package/dist/interfaces/workflows-module-options.interface.d.ts +80 -0
- package/dist/interfaces/workflows-module-options.interface.js +1 -0
- package/dist/mysql/index.d.ts +5 -0
- package/dist/mysql/index.js +8 -0
- package/dist/mysql/interfaces/index.d.ts +1 -0
- package/dist/mysql/interfaces/index.js +1 -0
- package/dist/mysql/interfaces/mysql-workflow-store-options.interface.d.ts +25 -0
- package/dist/mysql/interfaces/mysql-workflow-store-options.interface.js +1 -0
- package/dist/mysql/key-limits.d.ts +30 -0
- package/dist/mysql/key-limits.js +41 -0
- package/dist/mysql/migrations/index.d.ts +7 -0
- package/dist/mysql/migrations/index.js +16 -0
- package/dist/mysql/migrations/initial.migration.d.ts +9 -0
- package/dist/mysql/migrations/initial.migration.js +104 -0
- package/dist/mysql/mysql-workflow.store.d.ts +197 -0
- package/dist/mysql/mysql-workflow.store.js +828 -0
- package/dist/postgres/errors/index.d.ts +1 -0
- package/dist/postgres/errors/index.js +2 -0
- package/dist/postgres/index.d.ts +5 -0
- package/dist/postgres/index.js +8 -0
- package/dist/postgres/interfaces/index.d.ts +1 -0
- package/dist/postgres/interfaces/index.js +1 -0
- package/dist/postgres/interfaces/postgres-workflow-store-options.interface.d.ts +22 -0
- package/dist/postgres/interfaces/postgres-workflow-store-options.interface.js +1 -0
- package/dist/postgres/migrations/index.d.ts +6 -0
- package/dist/postgres/migrations/index.js +15 -0
- package/dist/postgres/migrations/initial.migration.d.ts +6 -0
- package/dist/postgres/migrations/initial.migration.js +106 -0
- package/dist/postgres/postgres-workflow.store.d.ts +132 -0
- package/dist/postgres/postgres-workflow.store.js +586 -0
- package/dist/services/index.d.ts +6 -0
- package/dist/services/index.js +6 -0
- package/dist/services/workflow-client.service.d.ts +146 -0
- package/dist/services/workflow-client.service.js +436 -0
- package/dist/services/workflow-execution.service.d.ts +267 -0
- package/dist/services/workflow-execution.service.js +1076 -0
- package/dist/services/workflow-registry.service.d.ts +56 -0
- package/dist/services/workflow-registry.service.js +172 -0
- package/dist/services/workflow-scheduler.service.d.ts +54 -0
- package/dist/services/workflow-scheduler.service.js +173 -0
- package/dist/services/workflow-schedules.service.d.ts +60 -0
- package/dist/services/workflow-schedules.service.js +193 -0
- package/dist/services/workflow-worker.service.d.ts +92 -0
- package/dist/services/workflow-worker.service.js +468 -0
- package/dist/signals/index.d.ts +1 -0
- package/dist/signals/index.js +1 -0
- package/dist/signals/workflow.signal.d.ts +17 -0
- package/dist/signals/workflow.signal.js +28 -0
- package/dist/sql/rate-windows.d.ts +41 -0
- package/dist/sql/rate-windows.js +53 -0
- package/dist/sql/workflow-rows.d.ts +16 -0
- package/dist/sql/workflow-rows.js +102 -0
- package/dist/sql/workflow-schema.error.d.ts +21 -0
- package/dist/sql/workflow-schema.error.js +15 -0
- package/dist/storage/encoded-workflow.store.d.ts +71 -0
- package/dist/storage/encoded-workflow.store.js +201 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/workflow.storage.d.ts +55 -0
- package/dist/storage/workflow.storage.js +159 -0
- package/dist/stores/in-memory-workflow.store.d.ts +75 -0
- package/dist/stores/in-memory-workflow.store.js +380 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/stores/index.js +1 -0
- package/dist/testing/assertions.d.ts +10 -0
- package/dist/testing/assertions.js +72 -0
- package/dist/testing/index.d.ts +38 -0
- package/dist/testing/index.js +1089 -0
- package/dist/testing/schedule-store.contract.d.ts +33 -0
- package/dist/testing/schedule-store.contract.js +161 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/journal-limits.util.d.ts +6 -0
- package/dist/utils/journal-limits.util.js +25 -0
- package/dist/utils/new-instance.util.d.ts +26 -0
- package/dist/utils/new-instance.util.js +87 -0
- package/dist/utils/normalize.util.d.ts +5 -0
- package/dist/utils/normalize.util.js +11 -0
- package/dist/utils/run-timeout.util.d.ts +3 -0
- package/dist/utils/run-timeout.util.js +15 -0
- package/dist/utils/schedule-spec.util.d.ts +16 -0
- package/dist/utils/schedule-spec.util.js +9 -0
- package/dist/utils/schedule-store.util.d.ts +15 -0
- package/dist/utils/schedule-store.util.js +44 -0
- package/dist/utils/serialize-error.util.d.ts +7 -0
- package/dist/utils/serialize-error.util.js +22 -0
- package/dist/utils/step-scope.util.d.ts +16 -0
- package/dist/utils/step-scope.util.js +38 -0
- package/dist/workflows.constants.d.ts +10 -0
- package/dist/workflows.constants.js +10 -0
- package/dist/workflows.module-definition.d.ts +4 -0
- package/dist/workflows.module-definition.js +6 -0
- package/dist/workflows.module.d.ts +24 -0
- package/dist/workflows.module.js +68 -0
- package/package.json +123 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Injectable } from '@nestjs/common';
|
|
8
|
+
import { Subject } from 'rxjs';
|
|
9
|
+
import { channelFor } from './workflows.channels.js';
|
|
10
|
+
/**
|
|
11
|
+
* This application's lifecycle events, for logs, metrics and alerts. Every event
|
|
12
|
+
* is also published on its `node:diagnostics_channel` channel
|
|
13
|
+
* (`nestjs:workflows:<type>`), process-wide, where tracing tools (NestJS Observe,
|
|
14
|
+
* OpenTelemetry) subscribe without Nest. An instance maps onto one trace: the
|
|
15
|
+
* instance is the root span, each execution a child span, each step attempt a
|
|
16
|
+
* span inside it (https://docs.nestjs.com/reliability/workflows#events).
|
|
17
|
+
*/
|
|
18
|
+
let WorkflowEvents = class WorkflowEvents {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.subject = new Subject();
|
|
21
|
+
this.events$ = this.subject.asObservable();
|
|
22
|
+
}
|
|
23
|
+
emit(event) {
|
|
24
|
+
const target = channelFor(event.type);
|
|
25
|
+
if (target.hasSubscribers) {
|
|
26
|
+
target.publish(event);
|
|
27
|
+
}
|
|
28
|
+
this.subject.next(event);
|
|
29
|
+
}
|
|
30
|
+
// After onModuleDestroy, where the worker drains and may still emit.
|
|
31
|
+
onApplicationShutdown() {
|
|
32
|
+
this.subject.complete();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
WorkflowEvents = __decorate([
|
|
36
|
+
Injectable()
|
|
37
|
+
], WorkflowEvents);
|
|
38
|
+
export { WorkflowEvents };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { channel } from 'node:diagnostics_channel';
|
|
2
|
+
const channels = new Map();
|
|
3
|
+
export const channelFor = (type) => {
|
|
4
|
+
let target = channels.get(type);
|
|
5
|
+
if (!target) {
|
|
6
|
+
channels.set(type, (target = channel(`nestjs:workflows:${type}`)));
|
|
7
|
+
}
|
|
8
|
+
return target;
|
|
9
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { WorkflowsModule } from './workflows.module.js';
|
|
2
|
+
export { WORKFLOWS_MODULE_OPTIONS } from './workflows.module-definition.js';
|
|
3
|
+
export type { WorkflowsModuleAsyncOptions, WorkflowsModuleOptions, WorkflowJournalLimits, WorkflowsOptionsFactory, WorkflowWorkerOptions, } from './interfaces/index.js';
|
|
4
|
+
export * from './decorators/index.js';
|
|
5
|
+
export { WorkflowSignal } from './signals/index.js';
|
|
6
|
+
export type { ChildWorkflowHandle, Journaled, SignalWaitOptions, StartChildWorkflowOptions, WaitForSignalOptions, WorkflowAnyResult, WorkflowCompensationContext, WorkflowConcurrency, WorkflowCondition, WorkflowContext, WorkflowDecoratorOptions, WorkflowRateLimit, WorkflowRetryOptions, WorkflowRunner, WorkflowStepContext, WorkflowStepOptions, } from './interfaces/index.js';
|
|
7
|
+
export type { Duration } from './core/time/index.js';
|
|
8
|
+
export { WorkflowClient, WorkflowSchedules } from './services/index.js';
|
|
9
|
+
export type { SignalWorkflowOptions, StartWorkflowOptions, WorkflowCancelResult, WorkflowDeleteOptions, WorkflowInstance, WorkflowJournalEntry, WorkflowListFilter, WorkflowParentClose, WorkflowPurgeOptions, WorkflowResultOptions, WorkflowRetryInstanceOptions, UpsertWorkflowScheduleOptions, WorkflowSchedule, WorkflowScheduleDeclaration, WorkflowScheduleListFilter, WorkflowScheduleMissed, WorkflowScheduleOccurrence, WorkflowScheduleOptions, WorkflowScheduleOverlap, WorkflowSchedulePreviewOptions, WorkflowSchedulePreviewSpec, WorkflowScheduleTiming, WorkflowSignalSendResult, WorkflowStartResult, WorkflowStatus, WorkflowWait, } from './interfaces/index.js';
|
|
10
|
+
export { ChildWorkflowFailedError, isWorkflowInterrupt, NonRetryableStepError, StepFailedError, StepTimeoutError, WorkflowDefinitionError, WorkflowError, WorkflowFailedError, WorkflowIdConflictError, WorkflowInterrupt, WorkflowNonDeterminismError, WorkflowNotFoundError, WorkflowResultTimeoutError, WorkflowStateError, type WorkflowFailureStatus, } from './errors/index.js';
|
|
11
|
+
export type { SerializedWorkflowError } from './interfaces/index.js';
|
|
12
|
+
export { WorkflowEvents, type WorkflowCancelledEvent, type WorkflowChildStartedEvent, type WorkflowCompensatingEvent, type WorkflowCompensationFailedEvent, type WorkflowCompletedEvent, type WorkflowCustomStatusEvent, type WorkflowDeletedEvent, type WorkflowEvent, type WorkflowFailedEvent, type WorkflowJournalLargeEvent, type WorkflowResumedEvent, type WorkflowRetriedEvent, type WorkflowScheduleSkippedEvent, type WorkflowSignalReceivedEvent, type WorkflowSignalTimedOutEvent, type WorkflowStartedEvent, type WorkflowStepCompensatedEvent, type WorkflowStepCompletedEvent, type WorkflowStepFailedEvent, type WorkflowSuspendedEvent, } from './events/index.js';
|
|
13
|
+
export { WorkflowStorage } from './storage/index.js';
|
|
14
|
+
export type { NewWorkflowInstance, NewWorkflowSignal, WorkflowCancelRequest, WorkflowClaim, WorkflowClaimRequest, WorkflowConcurrencyLimit, WorkflowInstanceDetails, WorkflowListQuery, WorkflowPurgeQuery, WorkflowPurgeResult, WorkflowRateLimitRule, WorkflowRateWindow, WorkflowRelease, WorkflowReopen, WorkflowScheduleClaimRequest, WorkflowScheduleQuery, WorkflowScheduleRecord, WorkflowScheduleSave, WorkflowScheduleWrite, WorkflowSignalQuery, WorkflowSignalRecord, WorkflowSignalResult, WorkflowStorageRegisterOptions, WorkflowStore, WorkflowWrite, } from './interfaces/index.js';
|
|
15
|
+
export * from './stores/index.js';
|
|
16
|
+
export { AesGcmPayloadCodec, type AesGcmPayloadCodecOptions } from './core/codecs/index.js';
|
|
17
|
+
export type { WorkflowPayloadCodec, WorkflowPayloadContext } from './interfaces/index.js';
|
|
18
|
+
export { ManualClock as ManualWorkflowClock } from './core/time/index.js';
|
|
19
|
+
export type { WorkflowClock } from './interfaces/index.js';
|
|
20
|
+
export { WorkflowWorker } from './services/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Module
|
|
2
|
+
export { WorkflowsModule } from './workflows.module.js';
|
|
3
|
+
export { WORKFLOWS_MODULE_OPTIONS } from './workflows.module-definition.js';
|
|
4
|
+
// Writing workflows
|
|
5
|
+
export * from './decorators/index.js';
|
|
6
|
+
export { WorkflowSignal } from './signals/index.js';
|
|
7
|
+
// Starting, signalling, inspecting and cancelling instances, and the schedules that start them
|
|
8
|
+
export { WorkflowClient, WorkflowSchedules } from './services/index.js';
|
|
9
|
+
// Errors
|
|
10
|
+
export { ChildWorkflowFailedError, isWorkflowInterrupt, NonRetryableStepError, StepFailedError, StepTimeoutError, WorkflowDefinitionError, WorkflowError, WorkflowFailedError, WorkflowIdConflictError, WorkflowInterrupt, WorkflowNonDeterminismError, WorkflowNotFoundError, WorkflowResultTimeoutError, WorkflowStateError, } from './errors/index.js';
|
|
11
|
+
// Observability: each event is also published on its `nestjs:workflows:<type>` diagnostics channel
|
|
12
|
+
export { WorkflowEvents, } from './events/index.js';
|
|
13
|
+
// Storage: the interface your store implements, the registry it registers with in its
|
|
14
|
+
// constructor, and the in-memory default (for development and tests, and the test double).
|
|
15
|
+
// The contract's test suite is `@nestjs/workflows/testing` (lib/testing/index.ts).
|
|
16
|
+
export { WorkflowStorage } from './storage/index.js';
|
|
17
|
+
export * from './stores/index.js';
|
|
18
|
+
// Payloads: encode (encrypt, compress) what the store keeps, with `WorkflowsModule.forRoot({ codec })`
|
|
19
|
+
export { AesGcmPayloadCodec } from './core/codecs/index.js';
|
|
20
|
+
// Testing: a clock that only moves when told to, and `WorkflowWorker.drain()` to run due
|
|
21
|
+
// instances now (with the contract suite in `@nestjs/workflows/testing`)
|
|
22
|
+
export { ManualClock as ManualWorkflowClock } from './core/time/index.js';
|
|
23
|
+
export { WorkflowWorker } from './services/index.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './serialized-workflow-error.interface.js';
|
|
2
|
+
export * from './workflow-client.interface.js';
|
|
3
|
+
export * from './workflow-clock.interface.js';
|
|
4
|
+
export * from './workflow-context.interface.js';
|
|
5
|
+
export * from './workflow-decorator-options.interface.js';
|
|
6
|
+
export * from './workflow-instance.interface.js';
|
|
7
|
+
export * from './workflow-payload-codec.interface.js';
|
|
8
|
+
export * from './workflow-retry-options.interface.js';
|
|
9
|
+
export * from './workflow-runner.interface.js';
|
|
10
|
+
export * from './workflow-schedule.interface.js';
|
|
11
|
+
export * from './workflow-storage.interface.js';
|
|
12
|
+
export * from './workflow-store.interface.js';
|
|
13
|
+
export * from './workflows-module-options.interface.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './serialized-workflow-error.interface.js';
|
|
2
|
+
export * from './workflow-client.interface.js';
|
|
3
|
+
export * from './workflow-clock.interface.js';
|
|
4
|
+
export * from './workflow-context.interface.js';
|
|
5
|
+
export * from './workflow-decorator-options.interface.js';
|
|
6
|
+
export * from './workflow-instance.interface.js';
|
|
7
|
+
export * from './workflow-payload-codec.interface.js';
|
|
8
|
+
export * from './workflow-retry-options.interface.js';
|
|
9
|
+
export * from './workflow-runner.interface.js';
|
|
10
|
+
export * from './workflow-schedule.interface.js';
|
|
11
|
+
export * from './workflow-storage.interface.js';
|
|
12
|
+
export * from './workflow-store.interface.js';
|
|
13
|
+
export * from './workflows-module-options.interface.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SerializedError } from '../core/interfaces/payload-codec.interface.js';
|
|
2
|
+
/** JSON-safe form of an error, as stored in the journal and on the instance. */
|
|
3
|
+
export interface SerializedWorkflowError extends SerializedError {
|
|
4
|
+
/** For `compensation_failed`: the error of the compensation that gave up. */
|
|
5
|
+
compensation?: SerializedWorkflowError;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { Duration } from '../core/time/duration.js';
|
|
2
|
+
import type { WorkflowInstance, WorkflowStatus } from './workflow-instance.interface.js';
|
|
3
|
+
export interface StartWorkflowOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Instance id; default a random UUID. Starting twice with the same id (same
|
|
6
|
+
* workflow and input) returns the existing instance instead of a second one,
|
|
7
|
+
* so derive it from the business key: `order-${orderId}`. Inside a workflow
|
|
8
|
+
* step, a start without an id gets one derived from the step's
|
|
9
|
+
* `idempotencyKey`, the workflow's name and how many instances of it the step
|
|
10
|
+
* started before, so a retried step gets its instances back (with the input
|
|
11
|
+
* they were first started with) instead of starting new ones.
|
|
12
|
+
*/
|
|
13
|
+
id?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Pin a version (a positive integer). Default: the highest version of the
|
|
16
|
+
* workflow's name that this application registers, also when you pass a class.
|
|
17
|
+
* Starting by name a workflow this process does not register requires it.
|
|
18
|
+
*/
|
|
19
|
+
version?: number;
|
|
20
|
+
/**
|
|
21
|
+
* How long the instance may run, overriding the workflow's `@Workflow(name, { timeout })`:
|
|
22
|
+
* past it, the instance compensates and ends as `failed` with a `WorkflowTimeoutError`.
|
|
23
|
+
* Counted from this call; ignored when the instance already exists.
|
|
24
|
+
*/
|
|
25
|
+
timeout?: Duration;
|
|
26
|
+
/**
|
|
27
|
+
* The key the workflow's per-key concurrency limit counts the instance under, instead of the
|
|
28
|
+
* one its `concurrency.key` computes. Needs a limit with a `key`.
|
|
29
|
+
*/
|
|
30
|
+
concurrencyKey?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The key the workflow's per-key rate limit counts the instance under, instead of the one its
|
|
33
|
+
* `rateLimit.key` computes. Needs a rate limit with a `key`.
|
|
34
|
+
*/
|
|
35
|
+
rateLimitKey?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Lower runs first: an integer from 1 to 2,097,151. Due instances are claimed by priority, then most
|
|
38
|
+
* overdue first; instances without one go before every prioritized one. The instance keeps it for every
|
|
39
|
+
* execution (each resumption waits its turn by it), and its children inherit it. Default: none.
|
|
40
|
+
*/
|
|
41
|
+
priority?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Your ORM's transaction: the `tx` (or `EntityManager`, `Transaction`...) your transaction
|
|
44
|
+
* callback receives. The instance is created in it, so it exists if and only if your
|
|
45
|
+
* transaction commits, together with the rows you wrote. The worker picks it up after the
|
|
46
|
+
* commit, at its next poll. Needs a store on your database that implements
|
|
47
|
+
* `createInTransaction()`.
|
|
48
|
+
*/
|
|
49
|
+
transaction?: unknown;
|
|
50
|
+
}
|
|
51
|
+
export interface SignalWorkflowOptions {
|
|
52
|
+
/** Correlation key: only waits with the same key take the signal. */
|
|
53
|
+
key?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Deduplication id, unique per signal name, such as the id of the message or event that
|
|
56
|
+
* causes the signal. A signal with the same name and id stored earlier makes this call a
|
|
57
|
+
* no-op that returns that signal's `signalId` with `created: false`: a sender that runs
|
|
58
|
+
* again (a redelivered message, a retried job) stores its signal once, and the first payload
|
|
59
|
+
* wins. The same name and id with a different key throws `WorkflowIdConflictError`.
|
|
60
|
+
* Inside a workflow step, a signal sent without an id gets one derived from the step's
|
|
61
|
+
* `idempotencyKey`, so a retried step doesn't send it again.
|
|
62
|
+
*/
|
|
63
|
+
id?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Your ORM's transaction, as for `start()`: the signal, and the wake-up of the instances
|
|
66
|
+
* waiting for it, commit with your writes. Signals queue behind it until it ends, so keep
|
|
67
|
+
* it short. On PostgreSQL it must be READ COMMITTED (the default).
|
|
68
|
+
*/
|
|
69
|
+
transaction?: unknown;
|
|
70
|
+
}
|
|
71
|
+
/** What `result()` and `startAndWait()` take. */
|
|
72
|
+
export interface WorkflowResultOptions {
|
|
73
|
+
/**
|
|
74
|
+
* How long to wait. Past it, the call rejects with `WorkflowResultTimeoutError`, and the
|
|
75
|
+
* instance keeps running. Wall-clock time, not the module's clock. Default: no limit.
|
|
76
|
+
*/
|
|
77
|
+
timeout?: Duration;
|
|
78
|
+
/** Stops waiting once aborted (a client that went away), rejecting with the signal's reason. */
|
|
79
|
+
signal?: AbortSignal;
|
|
80
|
+
}
|
|
81
|
+
/** What `signal()` returns. */
|
|
82
|
+
export interface WorkflowSignalSendResult {
|
|
83
|
+
/** The stored signal's id: the new one, or with `created: false` the one stored earlier with the same `id`. */
|
|
84
|
+
signalId: number;
|
|
85
|
+
/** Instances parked on a matching wait that this call woke. */
|
|
86
|
+
woken: number;
|
|
87
|
+
/** `false` if a signal with the same name and `id` was stored earlier: nothing was written. */
|
|
88
|
+
created: boolean;
|
|
89
|
+
}
|
|
90
|
+
/** What `start()` returns: safe to send to a client (no input, no lease details). */
|
|
91
|
+
export interface WorkflowStartResult {
|
|
92
|
+
id: string;
|
|
93
|
+
workflow: string;
|
|
94
|
+
version: number;
|
|
95
|
+
/** False if an instance with this id already existed. */
|
|
96
|
+
created: boolean;
|
|
97
|
+
status: WorkflowStatus;
|
|
98
|
+
}
|
|
99
|
+
export interface WorkflowCancelResult extends WorkflowInstance {
|
|
100
|
+
/**
|
|
101
|
+
* True if this call requested the cancellation. False if the instance was
|
|
102
|
+
* already compensating or had finished, or a cancel was already requested
|
|
103
|
+
* (the first reason is kept). For `terminate()`: false if the instance had
|
|
104
|
+
* finished or a terminate was already requested.
|
|
105
|
+
*/
|
|
106
|
+
accepted: boolean;
|
|
107
|
+
}
|
|
108
|
+
export interface WorkflowListFilter {
|
|
109
|
+
status?: WorkflowStatus | WorkflowStatus[];
|
|
110
|
+
/** Workflow name. */
|
|
111
|
+
workflow?: string;
|
|
112
|
+
/** With `workflow`: only instances on this version (to see whether an old version has drained). */
|
|
113
|
+
version?: number;
|
|
114
|
+
/** Only the children this instance started with `ctx.startChild()`. */
|
|
115
|
+
parentId?: string;
|
|
116
|
+
/** Only the instances this schedule started. */
|
|
117
|
+
scheduleId?: string;
|
|
118
|
+
/** Default 100. */
|
|
119
|
+
limit?: number;
|
|
120
|
+
offset?: number;
|
|
121
|
+
}
|
|
122
|
+
/** What `purge()` takes. */
|
|
123
|
+
export interface WorkflowPurgeOptions {
|
|
124
|
+
/**
|
|
125
|
+
* How long finished instances are kept, such as `'30d'`: instances that finished longer ago
|
|
126
|
+
* go, with their journals, and so do signals older than this that no unfinished instance can
|
|
127
|
+
* take, and rate-limit windows that ended that long ago. A signal's `id` deduplicates until its
|
|
128
|
+
* signal is purged, so keep this longer than any sender's redelivery window, and longer than
|
|
129
|
+
* your longest transaction.
|
|
130
|
+
*/
|
|
131
|
+
olderThan: Duration;
|
|
132
|
+
/**
|
|
133
|
+
* The finished statuses to purge. Default `completed`, `failed` and `cancelled`:
|
|
134
|
+
* `compensation_failed` instances wait for a person, so they go only when listed.
|
|
135
|
+
*/
|
|
136
|
+
status?: WorkflowStatus | WorkflowStatus[];
|
|
137
|
+
/** Instances, and signals, deleted per statement. Default 500. */
|
|
138
|
+
batchSize?: number;
|
|
139
|
+
}
|
|
140
|
+
/** What `retry()` takes. */
|
|
141
|
+
export interface WorkflowRetryInstanceOptions {
|
|
142
|
+
/**
|
|
143
|
+
* A new run timeout, counted from now; `false` removes it. Required to retry a `failed`
|
|
144
|
+
* instance whose deadline has passed, which would otherwise time out again at once. Default:
|
|
145
|
+
* the deadline it has.
|
|
146
|
+
*/
|
|
147
|
+
timeout?: Duration | false;
|
|
148
|
+
}
|
|
149
|
+
/** What `delete()` takes. */
|
|
150
|
+
export interface WorkflowDeleteOptions {
|
|
151
|
+
/**
|
|
152
|
+
* Delete an unfinished instance too, without running its compensations. A worker running it
|
|
153
|
+
* stops recording at its next write. Default `false`: only finished instances.
|
|
154
|
+
*/
|
|
155
|
+
force?: boolean;
|
|
156
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Clock } from '../core/interfaces/clock.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Every timestamp the engine reads (sleep deadlines, signal timeouts, retry
|
|
4
|
+
* times, lease expiry, `ctx.now()`) comes from this clock, so tests can move
|
|
5
|
+
* time without fake timers.
|
|
6
|
+
*/
|
|
7
|
+
export type WorkflowClock = Clock;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import type { Type } from '@nestjs/common';
|
|
2
|
+
import type { Duration } from '../core/time/duration.js';
|
|
3
|
+
import type { WorkflowParentClose } from './workflow-instance.interface.js';
|
|
4
|
+
import type { WorkflowInput, WorkflowOutput } from './workflow-runner.interface.js';
|
|
5
|
+
import type { SerializedWorkflowError } from './serialized-workflow-error.interface.js';
|
|
6
|
+
import type { WorkflowSignal } from '../signals/workflow.signal.js';
|
|
7
|
+
import type { WorkflowRetryOptions } from './workflow-retry-options.interface.js';
|
|
8
|
+
import type { WorkflowScheduleOccurrence } from './workflow-schedule.interface.js';
|
|
9
|
+
/**
|
|
10
|
+
* What a journaled value looks like after its JSON round-trip: step results,
|
|
11
|
+
* signal payloads and checkpoints come back this way on the first run and on
|
|
12
|
+
* every replay (a `Date` is a string, methods and `undefined` fields are gone,
|
|
13
|
+
* `undefined` in an array is `null`, a `Map` or `Set` is `{}`).
|
|
14
|
+
*/
|
|
15
|
+
export type Journaled<T> = unknown extends T ? T : T extends {
|
|
16
|
+
toJSON(...args: any[]): infer R;
|
|
17
|
+
} ? Journaled<R> : T extends string | number | boolean | null | undefined | void ? T : T extends bigint | symbol | ((...args: any[]) => unknown) ? never : T extends ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> ? Record<string, never> : T extends readonly unknown[] ? {
|
|
18
|
+
[K in keyof T]: JournaledElement<T[K]>;
|
|
19
|
+
} : {
|
|
20
|
+
[K in keyof T as T[K] extends (...args: any[]) => unknown ? never : K]: Journaled<T[K]>;
|
|
21
|
+
};
|
|
22
|
+
/** In arrays, `JSON.stringify` writes `undefined`, functions and symbols as `null`. */
|
|
23
|
+
type JournaledElement<T> = T extends undefined | void | symbol | ((...args: any[]) => unknown) ? null : Journaled<T>;
|
|
24
|
+
/** Handed to every step (and compensation) attempt. */
|
|
25
|
+
export interface WorkflowStepContext<P = unknown> {
|
|
26
|
+
/**
|
|
27
|
+
* `${workflowId}:${stepName}`. Identical for every attempt and every worker
|
|
28
|
+
* that runs this step, so pass it to the API you call (`Idempotency-Key`,
|
|
29
|
+
* a unique column) to make the side effect exactly-once.
|
|
30
|
+
*/
|
|
31
|
+
readonly idempotencyKey: string;
|
|
32
|
+
/** 1 for the first attempt. Interrupted attempts (crash, lost lease) count. */
|
|
33
|
+
readonly attempt: number;
|
|
34
|
+
/** Aborted on shutdown, on a lost lease, and on `timeout`/`heartbeatTimeout`. */
|
|
35
|
+
readonly signal: AbortSignal;
|
|
36
|
+
/**
|
|
37
|
+
* The last value passed to `heartbeat(progress)` by an earlier attempt of
|
|
38
|
+
* this step, or `undefined`. Type it by annotating the step function's
|
|
39
|
+
* parameter: `async ({ progress }: WorkflowStepContext<Checkpoint>) => ...`.
|
|
40
|
+
*/
|
|
41
|
+
readonly progress: Journaled<P> | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Proves the step is alive (resets `heartbeatTimeout`). With an argument,
|
|
44
|
+
* the value is also checkpointed to the journal and handed to the next
|
|
45
|
+
* attempt as `progress` if this one dies.
|
|
46
|
+
*/
|
|
47
|
+
heartbeat(progress?: P): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
export interface WorkflowCompensationContext extends WorkflowStepContext {
|
|
50
|
+
/** Why the workflow is being compensated. */
|
|
51
|
+
readonly reason: SerializedWorkflowError;
|
|
52
|
+
}
|
|
53
|
+
export interface WorkflowStepOptions<T> {
|
|
54
|
+
/** Default: the module's `retry` (3 attempts, 1s doubling up to 5m). */
|
|
55
|
+
retry?: number | false | WorkflowRetryOptions;
|
|
56
|
+
/** Fail the attempt (retryably) after this long. */
|
|
57
|
+
timeout?: Duration;
|
|
58
|
+
/** Fail the attempt (retryably) if `heartbeat()` is not called this often. */
|
|
59
|
+
heartbeatTimeout?: Duration;
|
|
60
|
+
/**
|
|
61
|
+
* Undo this step, once it completed, if the workflow later fails or is
|
|
62
|
+
* cancelled. Compensations run in reverse order of the `ctx.step()` calls
|
|
63
|
+
* (parallel steps included), each one journaled and retried like a step. Its
|
|
64
|
+
* return value is discarded. A later `ctx.commit()` discards it.
|
|
65
|
+
*/
|
|
66
|
+
compensate?: (result: Journaled<T>, ctx: WorkflowCompensationContext) => unknown;
|
|
67
|
+
/** How `compensate` retries. Default: the step's `retry`, else the module's. */
|
|
68
|
+
compensateRetry?: number | false | WorkflowRetryOptions;
|
|
69
|
+
}
|
|
70
|
+
export interface WaitForSignalOptions<T> {
|
|
71
|
+
/**
|
|
72
|
+
* Correlation key: only signals sent with the same key match (see
|
|
73
|
+
* `WorkflowClient.signal()`). Without one, the wait only matches signals sent
|
|
74
|
+
* without a key.
|
|
75
|
+
*/
|
|
76
|
+
key?: string;
|
|
77
|
+
/** Extra filter over the payload. Must be a pure function of it. */
|
|
78
|
+
match?: (payload: Journaled<T>) => boolean;
|
|
79
|
+
/** Resolve with `null` if no matching signal was sent before this deadline. */
|
|
80
|
+
timeout?: Duration;
|
|
81
|
+
}
|
|
82
|
+
declare const conditionValue: unique symbol;
|
|
83
|
+
/**
|
|
84
|
+
* Something `ctx.waitForAny()` waits for, made by `ctx.signalWait()` or `ctx.timer()`, or a
|
|
85
|
+
* child's handle (`ctx.startChild()`). Only a
|
|
86
|
+
* description: nothing is waited for, and nothing journaled, until it is passed to `waitForAny()`.
|
|
87
|
+
*/
|
|
88
|
+
export interface WorkflowCondition<T = unknown> {
|
|
89
|
+
/** Type-only: the `value` `waitForAny()` returns when this condition wins. Never set at runtime. */
|
|
90
|
+
readonly [conditionValue]?: T;
|
|
91
|
+
}
|
|
92
|
+
/** What `ctx.startChild()` and `ctx.executeChild()` take. */
|
|
93
|
+
export interface StartChildWorkflowOptions {
|
|
94
|
+
/**
|
|
95
|
+
* The child's id. Default: `${parentId}/${workflow}#${n}`, where `n` counts the children of
|
|
96
|
+
* that workflow this run started before it, so a replay gets the same child back. The id also
|
|
97
|
+
* names the journal entry: pass one (derived from your data) for children started from
|
|
98
|
+
* parallel branches, which can reach `startChild()` in another order on a replay.
|
|
99
|
+
*/
|
|
100
|
+
id?: string;
|
|
101
|
+
/** Pin a version, as in `WorkflowClient.start()`. Default: the highest this application registers. */
|
|
102
|
+
version?: number;
|
|
103
|
+
/** The child's run timeout, overriding its `@Workflow(name, { timeout })`. */
|
|
104
|
+
timeout?: Duration;
|
|
105
|
+
/**
|
|
106
|
+
* What happens to the child if it is still running when this instance ends (completes,
|
|
107
|
+
* fails, is cancelled or terminated), or starts compensating: `'cancel'` (the default)
|
|
108
|
+
* cancels it, and its compensations run; `'terminate'` stops it without compensating;
|
|
109
|
+
* `'abandon'` leaves it running on its own.
|
|
110
|
+
*/
|
|
111
|
+
parentClose?: WorkflowParentClose;
|
|
112
|
+
/** As in `WorkflowClient.start()`: the child's key for its workflow's per-key concurrency limit. */
|
|
113
|
+
concurrencyKey?: string;
|
|
114
|
+
/** As in `WorkflowClient.start()`: the child's key for its workflow's per-key rate limit. */
|
|
115
|
+
rateLimitKey?: string;
|
|
116
|
+
/** As in `WorkflowClient.start()`. Default: this instance's priority. */
|
|
117
|
+
priority?: number;
|
|
118
|
+
}
|
|
119
|
+
/** A started child workflow (`ctx.startChild()`). Also a condition for `ctx.waitForAny()`. */
|
|
120
|
+
export interface ChildWorkflowHandle<O = unknown> extends WorkflowCondition<Journaled<O>> {
|
|
121
|
+
readonly id: string;
|
|
122
|
+
readonly workflow: string;
|
|
123
|
+
readonly version: number;
|
|
124
|
+
/**
|
|
125
|
+
* Durable wait for the child to end: resolves with its output, or throws a
|
|
126
|
+
* `ChildWorkflowFailedError` (with the child's status and error) if it failed, was cancelled
|
|
127
|
+
* or terminated. Journaled, like a signal wait. Calling it again returns the same promise.
|
|
128
|
+
*/
|
|
129
|
+
result(): Promise<Journaled<O>>;
|
|
130
|
+
}
|
|
131
|
+
/** What `ctx.signalWait()` takes: `waitForSignal()`'s options, without a timeout (race a `ctx.timer()` instead). */
|
|
132
|
+
export type SignalWaitOptions<T> = Omit<WaitForSignalOptions<T>, 'timeout'>;
|
|
133
|
+
/**
|
|
134
|
+
* What `ctx.waitForAny(name, conditions)` resolves with: the key of the condition that won, and
|
|
135
|
+
* its value, typed per key (check `key` to narrow `value`).
|
|
136
|
+
*/
|
|
137
|
+
export type WorkflowAnyResult<C extends Record<string, WorkflowCondition<unknown>>> = {
|
|
138
|
+
[K in keyof C & string]: {
|
|
139
|
+
key: K;
|
|
140
|
+
value: C[K] extends WorkflowCondition<infer T> ? T : never;
|
|
141
|
+
};
|
|
142
|
+
}[keyof C & string];
|
|
143
|
+
/**
|
|
144
|
+
* The API a workflow's `run()` receives. `run()` executes again from the top every time an instance
|
|
145
|
+
* resumes: https://docs.nestjs.com/reliability/workflows#rules-for-workflow-code.
|
|
146
|
+
*/
|
|
147
|
+
export interface WorkflowContext {
|
|
148
|
+
readonly workflowId: string;
|
|
149
|
+
readonly workflowName: string;
|
|
150
|
+
readonly version: number;
|
|
151
|
+
/** The schedule occurrence that started this instance (`{ id, at }`: the schedule's id and the occurrence's time), or `null`. */
|
|
152
|
+
readonly schedule: WorkflowScheduleOccurrence | null;
|
|
153
|
+
/**
|
|
154
|
+
* Runs `fn` once and journals its result; replays return the journaled
|
|
155
|
+
* result without running it. `name` is unique per run and part of the
|
|
156
|
+
* contract with running instances. Don't call `ctx` methods inside `fn`.
|
|
157
|
+
*/
|
|
158
|
+
step<T, P = unknown>(name: string, fn: (ctx: WorkflowStepContext<P>) => T | Promise<T>, options?: WorkflowStepOptions<T>): Promise<Journaled<T>>;
|
|
159
|
+
/** Durable timer. The instance is parked and resumed by any worker after the deadline. */
|
|
160
|
+
sleep(name: string, duration: Duration | {
|
|
161
|
+
until: Date | number;
|
|
162
|
+
}): Promise<void>;
|
|
163
|
+
/**
|
|
164
|
+
* Durable wait for a signal sent with `WorkflowClient.signal()`, including
|
|
165
|
+
* one sent after the instance started but before it reached this wait.
|
|
166
|
+
* Resolves with the payload, or `null` once `timeout` passes (compare with
|
|
167
|
+
* `=== null` when the payload itself can be falsy).
|
|
168
|
+
*/
|
|
169
|
+
waitForSignal<T>(name: string, signal: WorkflowSignal<T> | string, options?: WaitForSignalOptions<T>): Promise<Journaled<T> | null>;
|
|
170
|
+
/**
|
|
171
|
+
* Durable wait for whichever of several conditions happens first: a signal
|
|
172
|
+
* (`ctx.signalWait()`), a timer (`ctx.timer()`) or a child's end (its handle). Resolves with the
|
|
173
|
+
* key of the winner and its value (a signal's payload, `null` for a timer, a child's output; a
|
|
174
|
+
* child that failed throws its `ChildWorkflowFailedError`), journaled under `name` as one entry, so a
|
|
175
|
+
* replay returns the same winner. Only the winning signal is taken: a signal that matched
|
|
176
|
+
* another condition stays for a later wait. When several are ready at once, the earliest
|
|
177
|
+
* signal (lowest id) wins, then the earliest timer; a signal sent after a timer's deadline
|
|
178
|
+
* doesn't count. Timers count from when the wait is first reached.
|
|
179
|
+
*
|
|
180
|
+
* ```ts
|
|
181
|
+
* const outcome = await ctx.waitForAny('delivery-or-cancel', {
|
|
182
|
+
* delivered: ctx.signalWait(shipmentDelivered, { key: order.id }),
|
|
183
|
+
* cancelled: ctx.signalWait(orderCancelled, { key: order.id }),
|
|
184
|
+
* timeout: ctx.timer('3d'),
|
|
185
|
+
* });
|
|
186
|
+
* if (outcome.key === 'delivered') {
|
|
187
|
+
* await ctx.step('thank', () => this.mail.thank(order, outcome.value));
|
|
188
|
+
* }
|
|
189
|
+
* ```
|
|
190
|
+
*
|
|
191
|
+
* To wait for all of several signals, await several `waitForSignal()` calls with
|
|
192
|
+
* `Promise.all()`: each is journaled on its own, and the instance parks once for all of them.
|
|
193
|
+
*/
|
|
194
|
+
waitForAny<C extends Record<string, WorkflowCondition<unknown>>>(name: string, conditions: C): Promise<WorkflowAnyResult<C>>;
|
|
195
|
+
/**
|
|
196
|
+
* Starts a child instance of another workflow, linked to this one: `getStatus()` shows the
|
|
197
|
+
* link, `list({ parentId })` finds the children, and `parentClose` decides what happens to a
|
|
198
|
+
* child still running when this instance ends. Journaled: a replay returns the same child
|
|
199
|
+
* instead of starting another. Resolves with a handle to wait for the child's result.
|
|
200
|
+
* Starting a child with an id that another workflow, another parent or another input already
|
|
201
|
+
* uses throws `WorkflowIdConflictError`.
|
|
202
|
+
*/
|
|
203
|
+
startChild<W>(workflow: Type<W> | string, input: WorkflowInput<W>, options?: StartChildWorkflowOptions): Promise<ChildWorkflowHandle<WorkflowOutput<W>>>;
|
|
204
|
+
/** `startChild()`, then its handle's `result()`. */
|
|
205
|
+
executeChild<W>(workflow: Type<W> | string, input: WorkflowInput<W>, options?: StartChildWorkflowOptions): Promise<Journaled<WorkflowOutput<W>>>;
|
|
206
|
+
/** A signal for `waitForAny()`: its value is the payload. */
|
|
207
|
+
signalWait<T>(signal: WorkflowSignal<T> | string, options?: SignalWaitOptions<T>): WorkflowCondition<Journaled<T>>;
|
|
208
|
+
/** A durable timer for `waitForAny()`: `duration` after the wait is first reached, or at `until`. Its value is `null`. */
|
|
209
|
+
timer(duration: Duration | {
|
|
210
|
+
until: Date | number;
|
|
211
|
+
}): WorkflowCondition<null>;
|
|
212
|
+
/**
|
|
213
|
+
* Journaled `Date.now()`: the same value on every replay. Helpers are
|
|
214
|
+
* numbered in call order, so call them from sequential code, not from
|
|
215
|
+
* parallel branches that reach them in a different order on a replay.
|
|
216
|
+
*/
|
|
217
|
+
now(): number;
|
|
218
|
+
/** Journaled `Math.random()`. */
|
|
219
|
+
random(): number;
|
|
220
|
+
/** Journaled `crypto.randomUUID()`. */
|
|
221
|
+
uuid(): string;
|
|
222
|
+
/**
|
|
223
|
+
* Point of no return. Compensations of the steps called before it are
|
|
224
|
+
* discarded: a later failure or cancel runs only the compensations of steps
|
|
225
|
+
* called after it. Journaled under `name`, so it replays like a step and
|
|
226
|
+
* shows in `getStatus(id, { journal: true })`.
|
|
227
|
+
*/
|
|
228
|
+
commit(name: string): void;
|
|
229
|
+
/**
|
|
230
|
+
* Sets the instance's custom status, a JSON value of up to 16 KiB that the outside world
|
|
231
|
+
* reads as `WorkflowClient.getStatus(id).customStatus` (a progress report, the stage an
|
|
232
|
+
* order is in). It is written with the instance's next journal write, suspension or end,
|
|
233
|
+
* and emitted as a `custom-status` event then. Every execution replays `run()`, and with it
|
|
234
|
+
* the `setStatus()` calls, so the status needs no journal entry of its own and is never
|
|
235
|
+
* read back by the workflow. `undefined` clears it (`null`).
|
|
236
|
+
*/
|
|
237
|
+
setStatus(status: unknown): void;
|
|
238
|
+
/** Fail the instance on purpose. Compensations run (only those after a `commit()`). */
|
|
239
|
+
fail(message: string): never;
|
|
240
|
+
}
|
|
241
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|