@dudousxd/nestjs-durable 0.14.0 → 0.16.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/LICENSE +21 -0
- package/dist/index.cjs +790 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +411 -0
- package/dist/index.d.ts +411 -6
- package/dist/index.js +744 -19
- package/dist/index.js.map +1 -1
- package/package.json +25 -7
- package/dist/decorators.d.ts +0 -146
- package/dist/decorators.d.ts.map +0 -1
- package/dist/decorators.js +0 -103
- package/dist/decorators.js.map +0 -1
- package/dist/durable-step.registrar.d.ts +0 -18
- package/dist/durable-step.registrar.d.ts.map +0 -1
- package/dist/durable-step.registrar.js +0 -73
- package/dist/durable-step.registrar.js.map +0 -1
- package/dist/durable.module.d.ts +0 -102
- package/dist/durable.module.d.ts.map +0 -1
- package/dist/durable.module.js +0 -98
- package/dist/durable.module.js.map +0 -1
- package/dist/entity.d.ts +0 -43
- package/dist/entity.d.ts.map +0 -1
- package/dist/entity.js +0 -94
- package/dist/entity.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/input-validation.d.ts +0 -9
- package/dist/input-validation.d.ts.map +0 -1
- package/dist/input-validation.js +0 -30
- package/dist/input-validation.js.map +0 -1
- package/dist/step-interceptor.d.ts +0 -20
- package/dist/step-interceptor.d.ts.map +0 -1
- package/dist/step-interceptor.js +0 -22
- package/dist/step-interceptor.js.map +0 -1
- package/dist/timer-poller.d.ts +0 -20
- package/dist/timer-poller.d.ts.map +0 -1
- package/dist/timer-poller.js +0 -81
- package/dist/timer-poller.js.map +0 -1
- package/dist/workflow.registrar.d.ts +0 -33
- package/dist/workflow.registrar.d.ts.map +0 -1
- package/dist/workflow.registrar.js +0 -169
- package/dist/workflow.registrar.js.map +0 -1
- package/dist/workflow.service.d.ts +0 -55
- package/dist/workflow.service.d.ts.map +0 -1
- package/dist/workflow.service.js +0 -58
- package/dist/workflow.service.js.map +0 -1
package/dist/durable.module.d.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { type ControlPlane, type NamedTransport, type QueueConfig, type ScheduledWorkflow, type StateStore, type Transport, type WorkflowRef } from '@dudousxd/nestjs-durable-core';
|
|
2
|
-
import { type DynamicModule, type InjectionToken } from '@nestjs/common';
|
|
3
|
-
export interface DurableModuleOptions {
|
|
4
|
-
store: StateStore;
|
|
5
|
-
transport?: Transport;
|
|
6
|
-
/**
|
|
7
|
-
* An ordered pool of named transports for failover / multi-broker setups. The engine dispatches on
|
|
8
|
-
* the first and fails over to the next; a step pins one via `ctx.call(step, input, { transport })`.
|
|
9
|
-
* Use instead of `transport`.
|
|
10
|
-
*/
|
|
11
|
-
transports?: NamedTransport[];
|
|
12
|
-
/**
|
|
13
|
-
* Cross-instance broadcast pub/sub (lifecycle events + cancellation). Defaults to the (first)
|
|
14
|
-
* transport when it can broadcast (event-emitter, BullMQ); set explicitly to use a dedicated one.
|
|
15
|
-
*/
|
|
16
|
-
controlPlane?: ControlPlane;
|
|
17
|
-
/** Interval (ms) for the durable-timer poller. `0` disables it. Defaults to 1000. */
|
|
18
|
-
timerPollMs?: number;
|
|
19
|
-
/**
|
|
20
|
-
* Auto-create the durable tables on boot via `store.ensureSchema()`. Defaults to true. Turn
|
|
21
|
-
* off in production and call the store adapter's `ensure*DurableSchema()` from a migration.
|
|
22
|
-
*/
|
|
23
|
-
autoSchema?: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Multi-instance recovery lease, in ms — how long an instance owns a run it picked up before
|
|
26
|
-
* another may take over. Defaults to 30000. Set above your longest synchronous run.
|
|
27
|
-
*/
|
|
28
|
-
leaseMs?: number;
|
|
29
|
-
/** Unique id for this instance (for leases). Defaults to a random id. */
|
|
30
|
-
instanceId?: string;
|
|
31
|
-
/**
|
|
32
|
-
* Cap recovery attempts before a still-`running` run is moved to the `dead` dead-letter state
|
|
33
|
-
* (a poison pill that crashes the process every boot). Omit for unlimited.
|
|
34
|
-
*/
|
|
35
|
-
maxRecoveryAttempts?: number;
|
|
36
|
-
/**
|
|
37
|
-
* The **default** workflow to route dead-lettered runs to, for workflows that don't declare their
|
|
38
|
-
* own. When a run is moved to `dead` (exceeded `maxRecoveryAttempts`), the started handler gets a
|
|
39
|
-
* `DeadLetter` payload `{ deadRunId, workflow, input, error }` (idempotent by a `dlq:<runId>` id) —
|
|
40
|
-
* it can alert, compensate, or queue for review. Resolution per dead run: the workflow's inline
|
|
41
|
-
* `@DeadLetter()` method → its `@Workflow({ deadLetterWorkflow })` reference → this default. Omit
|
|
42
|
-
* everything to just leave dead runs parked (inspectable + retriable from the dashboard). Accepts a
|
|
43
|
-
* workflow class (refactor-safe) or a name (cross-runtime).
|
|
44
|
-
*/
|
|
45
|
-
deadLetterWorkflow?: WorkflowRef;
|
|
46
|
-
/**
|
|
47
|
-
* Whether this instance plays the **worker** role: register `@DurableStep` handlers (consume the
|
|
48
|
-
* transport), recover incomplete runs on boot, and poll due timers. Defaults to `true`. Set
|
|
49
|
-
* `false` for a **dashboard/dispatch-only** instance (e.g. an API pod) that mounts the control
|
|
50
|
-
* plane and reads the store but must not process or recover workflows — leave that to the workers.
|
|
51
|
-
*/
|
|
52
|
-
worker?: boolean;
|
|
53
|
-
/** Max ms to wait for in-flight runs on shutdown before exiting. Defaults to 10000. */
|
|
54
|
-
shutdownTimeoutMs?: number;
|
|
55
|
-
/**
|
|
56
|
-
* Recurring workflows to start on a schedule (fixed interval or cron). The timer poller fires
|
|
57
|
-
* them each tick on **worker** instances only; `engine.start` is idempotent by the schedule's
|
|
58
|
-
* time-bucket run id, so racing instances start each window exactly once. Cron schedules need the
|
|
59
|
-
* optional `cron-parser` peer dependency.
|
|
60
|
-
*/
|
|
61
|
-
schedules?: ScheduledWorkflow[];
|
|
62
|
-
/**
|
|
63
|
-
* Build the public callback URL for a `ctx.webhook()` token, e.g.
|
|
64
|
-
* ``(t) => `https://api.example.com/durable/api/webhooks/${t}` ``. Populates `DurableWebhook.url`
|
|
65
|
-
* so a step can hand the URL to a third party. The dashboard's `POST webhooks/:token` receives the
|
|
66
|
-
* callback. Omit to build URLs yourself from the token.
|
|
67
|
-
*/
|
|
68
|
-
webhookUrl?: (token: string) => string;
|
|
69
|
-
/**
|
|
70
|
-
* Flow-control queues for remote steps, registered on the engine at startup. Reference one from a
|
|
71
|
-
* workflow with `ctx.call(step, input, { queue: name })` to cap its concurrency / admission rate.
|
|
72
|
-
*/
|
|
73
|
-
queues?: QueueConfig[];
|
|
74
|
-
/**
|
|
75
|
-
* Provide the current W3C `traceparent` to stamp on dispatched remote tasks, so workers continue
|
|
76
|
-
* the distributed trace. Pass `otelTraceparent` from `@dudousxd/nestjs-durable-otel`.
|
|
77
|
-
*/
|
|
78
|
-
traceparent?: () => string | undefined;
|
|
79
|
-
/**
|
|
80
|
-
* Provide an opaque context carrier (tenant / user / correlation ids) to stamp on dispatched remote
|
|
81
|
-
* tasks, so workers re-expose it to the step handler alongside the `traceparent`. Pass a reader from
|
|
82
|
-
* `@dudousxd/nestjs-context` or your own request-scoped source. The engine never inspects its shape.
|
|
83
|
-
*
|
|
84
|
-
* Re-evaluated at each (re)dispatch — including a retry or a crash/scale-down resume that the engine
|
|
85
|
-
* drives OUTSIDE the originating request scope, where this reader may return empty or stale values.
|
|
86
|
-
* Treat the carrier as best-effort correlation/propagation metadata only — do NOT treat it as an
|
|
87
|
-
* authorization boundary.
|
|
88
|
-
*/
|
|
89
|
-
context?: () => Record<string, unknown> | undefined;
|
|
90
|
-
/** Attempts for each saga compensation when a run fails. Default 1 (no retry). Idempotent undos. */
|
|
91
|
-
compensationRetries?: number;
|
|
92
|
-
}
|
|
93
|
-
export interface DurableModuleAsyncOptions {
|
|
94
|
-
useFactory: (...args: never[]) => DurableModuleOptions | Promise<DurableModuleOptions>;
|
|
95
|
-
inject?: InjectionToken[];
|
|
96
|
-
}
|
|
97
|
-
export declare class DurableModule {
|
|
98
|
-
static forRoot(options: DurableModuleOptions): DynamicModule;
|
|
99
|
-
static forRootAsync(options: DurableModuleAsyncOptions): DynamicModule;
|
|
100
|
-
private static build;
|
|
101
|
-
}
|
|
102
|
-
//# sourceMappingURL=durable.module.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"durable.module.d.ts","sourceRoot":"","sources":["../src/durable.module.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAEhB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAEf,KAAK,SAAS,EAEd,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAyB,MAAM,gBAAgB,CAAC;AAiBhG,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,WAAW,CAAC;IACjC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACvC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACpD,oGAAoG;IACpG,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACvF,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,qBACa,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa;IAI5D,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,yBAAyB,GAAG,aAAa;IAQtE,OAAO,CAAC,MAAM,CAAC,KAAK;CA4DrB"}
|
package/dist/durable.module.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
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;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var DurableModule_1;
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.DurableModule = void 0;
|
|
11
|
-
const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
|
|
12
|
-
const common_1 = require("@nestjs/common");
|
|
13
|
-
const core_1 = require("@nestjs/core");
|
|
14
|
-
const durable_step_registrar_1 = require("./durable-step.registrar");
|
|
15
|
-
const entity_1 = require("./entity");
|
|
16
|
-
const timer_poller_1 = require("./timer-poller");
|
|
17
|
-
const workflow_registrar_1 = require("./workflow.registrar");
|
|
18
|
-
const workflow_service_1 = require("./workflow.service");
|
|
19
|
-
/** True when `x` can act as a control plane (broadcast pub/sub) — e.g. a broadcast-capable transport. */
|
|
20
|
-
function isControlPlane(x) {
|
|
21
|
-
return (!!x &&
|
|
22
|
-
typeof x.publishControl === 'function' &&
|
|
23
|
-
typeof x.onControl === 'function');
|
|
24
|
-
}
|
|
25
|
-
let DurableModule = DurableModule_1 = class DurableModule {
|
|
26
|
-
static forRoot(options) {
|
|
27
|
-
return DurableModule_1.build({ provide: nestjs_durable_core_1.DURABLE_OPTIONS, useValue: options });
|
|
28
|
-
}
|
|
29
|
-
static forRootAsync(options) {
|
|
30
|
-
return DurableModule_1.build({
|
|
31
|
-
provide: nestjs_durable_core_1.DURABLE_OPTIONS,
|
|
32
|
-
useFactory: options.useFactory,
|
|
33
|
-
inject: options.inject ?? [],
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
static build(optionsProvider) {
|
|
37
|
-
return {
|
|
38
|
-
module: DurableModule_1,
|
|
39
|
-
global: true,
|
|
40
|
-
imports: [core_1.DiscoveryModule],
|
|
41
|
-
providers: [
|
|
42
|
-
optionsProvider,
|
|
43
|
-
{
|
|
44
|
-
provide: nestjs_durable_core_1.STATE_STORE,
|
|
45
|
-
useFactory: (options) => options.store,
|
|
46
|
-
inject: [nestjs_durable_core_1.DURABLE_OPTIONS],
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
provide: nestjs_durable_core_1.TRANSPORT,
|
|
50
|
-
useFactory: (options) => options.transport ?? null,
|
|
51
|
-
inject: [nestjs_durable_core_1.DURABLE_OPTIONS],
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
provide: nestjs_durable_core_1.WorkflowEngine,
|
|
55
|
-
useFactory: (store, transport, opts) => {
|
|
56
|
-
// The control-plane default is the primary task transport (single, or the pool's first)
|
|
57
|
-
// when it can broadcast.
|
|
58
|
-
const primary = transport ?? opts.transports?.[0]?.transport;
|
|
59
|
-
const engine = new nestjs_durable_core_1.WorkflowEngine({
|
|
60
|
-
store,
|
|
61
|
-
transport: transport ?? undefined,
|
|
62
|
-
transports: opts.transports,
|
|
63
|
-
controlPlane: opts.controlPlane ?? (isControlPlane(primary) ? primary : undefined),
|
|
64
|
-
leaseMs: opts.leaseMs,
|
|
65
|
-
maxRecoveryAttempts: opts.maxRecoveryAttempts,
|
|
66
|
-
instanceId: opts.instanceId,
|
|
67
|
-
webhookUrl: opts.webhookUrl,
|
|
68
|
-
traceparent: opts.traceparent,
|
|
69
|
-
context: opts.context,
|
|
70
|
-
compensationRetries: opts.compensationRetries,
|
|
71
|
-
// A non-worker (API/dashboard) instance must not run workflows: enqueue-only, leaving
|
|
72
|
-
// each `pending` run in the store for a worker's `runPending` poll. Workers use the
|
|
73
|
-
// default in-process dispatcher (execute locally).
|
|
74
|
-
runDispatcher: opts.worker === false ? { dispatch: () => { } } : undefined,
|
|
75
|
-
});
|
|
76
|
-
for (const queue of opts.queues ?? [])
|
|
77
|
-
engine.registerQueue(queue);
|
|
78
|
-
// Dead-letter routing (per-workflow `@DeadLetter()` / `deadLetterWorkflow` + this global
|
|
79
|
-
// default) is wired by the WorkflowRegistrar, which owns the `@Workflow` metadata.
|
|
80
|
-
return engine;
|
|
81
|
-
},
|
|
82
|
-
inject: [nestjs_durable_core_1.STATE_STORE, nestjs_durable_core_1.TRANSPORT, nestjs_durable_core_1.DURABLE_OPTIONS],
|
|
83
|
-
},
|
|
84
|
-
workflow_service_1.WorkflowService,
|
|
85
|
-
entity_1.EntityService,
|
|
86
|
-
workflow_registrar_1.WorkflowRegistrar,
|
|
87
|
-
durable_step_registrar_1.DurableStepRegistrar,
|
|
88
|
-
timer_poller_1.TimerPoller,
|
|
89
|
-
],
|
|
90
|
-
exports: [workflow_service_1.WorkflowService, entity_1.EntityService, nestjs_durable_core_1.WorkflowEngine, nestjs_durable_core_1.STATE_STORE, nestjs_durable_core_1.TRANSPORT],
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
exports.DurableModule = DurableModule;
|
|
95
|
-
exports.DurableModule = DurableModule = DurableModule_1 = __decorate([
|
|
96
|
-
(0, common_1.Module)({})
|
|
97
|
-
], DurableModule);
|
|
98
|
-
//# sourceMappingURL=durable.module.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"durable.module.js","sourceRoot":"","sources":["../src/durable.module.ts"],"names":[],"mappings":"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"}
|
package/dist/entity.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { type EntityHandler, WorkflowEngine } from '@dudousxd/nestjs-durable-core';
|
|
2
|
-
import 'reflect-metadata';
|
|
3
|
-
export declare const ENTITY_METADATA: unique symbol;
|
|
4
|
-
export declare const ENTITY_ON_METADATA: unique symbol;
|
|
5
|
-
/**
|
|
6
|
-
* Marks an `@Injectable()` class as a **durable entity** (a virtual object): its `@On(op)` methods run
|
|
7
|
-
* serialized per key over the instance's fields as durable state. e.g.
|
|
8
|
-
*
|
|
9
|
-
* ```ts
|
|
10
|
-
* @Entity({ name: 'cart' }) @Injectable()
|
|
11
|
-
* class Cart { items: Item[] = []; @On('add') add(i: Item) { this.items.push(i); } @On('list') list() { return this.items; } }
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* The class must be **constructible with no arguments** (a fresh instance is the initial state per key)
|
|
15
|
-
* — keep entities pure state, no DI. Drive them with `EntityService` or `ctx.signalEntity`/`callEntity`.
|
|
16
|
-
*/
|
|
17
|
-
export declare function Entity(options: {
|
|
18
|
-
name: string;
|
|
19
|
-
}): ClassDecorator;
|
|
20
|
-
/** Marks an entity method as the handler for operation `op`. */
|
|
21
|
-
export declare function On(op: string): MethodDecorator;
|
|
22
|
-
export declare function getEntityMeta(target: Function): {
|
|
23
|
-
name: string;
|
|
24
|
-
} | undefined;
|
|
25
|
-
/**
|
|
26
|
-
* Build the engine `EntityConfig` for a discovered `@Entity` class: a fresh instance per key, and
|
|
27
|
-
* handlers that rehydrate the class prototype onto the (serialized) state before dispatching the op,
|
|
28
|
-
* so methods work after replay.
|
|
29
|
-
*/
|
|
30
|
-
export declare function entityConfigFor(ctor: Function): {
|
|
31
|
-
initialState: () => object;
|
|
32
|
-
handlers: Record<string, EntityHandler>;
|
|
33
|
-
};
|
|
34
|
-
/** Inject this to drive durable entities from outside a workflow. */
|
|
35
|
-
export declare class EntityService {
|
|
36
|
-
private readonly engine;
|
|
37
|
-
constructor(engine: WorkflowEngine);
|
|
38
|
-
/** Send an operation to an entity (fire-and-forget; ordered + exactly-once per key). */
|
|
39
|
-
signal(name: string, key: string, op: string, arg?: unknown): Promise<void>;
|
|
40
|
-
/** Read an entity's current durable state (or undefined if it has none yet). */
|
|
41
|
-
getState<S = unknown>(name: string, key: string): Promise<S | undefined>;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=entity.d.ts.map
|
package/dist/entity.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEnF,OAAO,kBAAkB,CAAC;AAE1B,eAAO,MAAM,eAAe,eAAkC,CAAC;AAC/D,eAAO,MAAM,kBAAkB,eAAqC,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAIhE;AAED,gEAAgE;AAChE,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,CAQ9C;AAGD,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAE5E;AAED;;;;GAIG;AAEH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG;IAC/C,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACzC,CAaA;AAED,qEAAqE;AACrE,qBACa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAEnD,wFAAwF;IACxF,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3E,gFAAgF;IAChF,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CAGzE"}
|
package/dist/entity.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
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;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.EntityService = exports.ENTITY_ON_METADATA = exports.ENTITY_METADATA = void 0;
|
|
13
|
-
exports.Entity = Entity;
|
|
14
|
-
exports.On = On;
|
|
15
|
-
exports.getEntityMeta = getEntityMeta;
|
|
16
|
-
exports.entityConfigFor = entityConfigFor;
|
|
17
|
-
const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
|
|
18
|
-
const common_1 = require("@nestjs/common");
|
|
19
|
-
require("reflect-metadata");
|
|
20
|
-
exports.ENTITY_METADATA = Symbol('nestjs-durable:entity');
|
|
21
|
-
exports.ENTITY_ON_METADATA = Symbol('nestjs-durable:entity-on');
|
|
22
|
-
/**
|
|
23
|
-
* Marks an `@Injectable()` class as a **durable entity** (a virtual object): its `@On(op)` methods run
|
|
24
|
-
* serialized per key over the instance's fields as durable state. e.g.
|
|
25
|
-
*
|
|
26
|
-
* ```ts
|
|
27
|
-
* @Entity({ name: 'cart' }) @Injectable()
|
|
28
|
-
* class Cart { items: Item[] = []; @On('add') add(i: Item) { this.items.push(i); } @On('list') list() { return this.items; } }
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* The class must be **constructible with no arguments** (a fresh instance is the initial state per key)
|
|
32
|
-
* — keep entities pure state, no DI. Drive them with `EntityService` or `ctx.signalEntity`/`callEntity`.
|
|
33
|
-
*/
|
|
34
|
-
function Entity(options) {
|
|
35
|
-
return (target) => {
|
|
36
|
-
Reflect.defineMetadata(exports.ENTITY_METADATA, options, target);
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
/** Marks an entity method as the handler for operation `op`. */
|
|
40
|
-
function On(op) {
|
|
41
|
-
return (target, propertyKey) => {
|
|
42
|
-
// biome-ignore lint/complexity/noBannedTypes: reflect-metadata keys on the class constructor
|
|
43
|
-
const ctor = target.constructor;
|
|
44
|
-
const ops = Reflect.getMetadata(exports.ENTITY_ON_METADATA, ctor) ?? new Map();
|
|
45
|
-
ops.set(op, propertyKey);
|
|
46
|
-
Reflect.defineMetadata(exports.ENTITY_ON_METADATA, ops, ctor);
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
// biome-ignore lint/complexity/noBannedTypes: matches reflect-metadata's class target type
|
|
50
|
-
function getEntityMeta(target) {
|
|
51
|
-
return Reflect.getMetadata(exports.ENTITY_METADATA, target);
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Build the engine `EntityConfig` for a discovered `@Entity` class: a fresh instance per key, and
|
|
55
|
-
* handlers that rehydrate the class prototype onto the (serialized) state before dispatching the op,
|
|
56
|
-
* so methods work after replay.
|
|
57
|
-
*/
|
|
58
|
-
// biome-ignore lint/complexity/noBannedTypes: a class constructor
|
|
59
|
-
function entityConfigFor(ctor) {
|
|
60
|
-
const ops = Reflect.getMetadata(exports.ENTITY_ON_METADATA, ctor) ?? new Map();
|
|
61
|
-
const Cls = ctor;
|
|
62
|
-
const handlers = {};
|
|
63
|
-
for (const [op, method] of ops) {
|
|
64
|
-
handlers[op] = (state, arg) => {
|
|
65
|
-
Object.setPrototypeOf(state, Cls.prototype); // re-attach methods to the plain state
|
|
66
|
-
const fn = state[method];
|
|
67
|
-
if (typeof fn !== 'function')
|
|
68
|
-
throw new Error(`entity handler "${method}" is not a method`);
|
|
69
|
-
return fn.call(state, arg);
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
return { initialState: () => new Cls(), handlers };
|
|
73
|
-
}
|
|
74
|
-
/** Inject this to drive durable entities from outside a workflow. */
|
|
75
|
-
let EntityService = class EntityService {
|
|
76
|
-
engine;
|
|
77
|
-
constructor(engine) {
|
|
78
|
-
this.engine = engine;
|
|
79
|
-
}
|
|
80
|
-
/** Send an operation to an entity (fire-and-forget; ordered + exactly-once per key). */
|
|
81
|
-
signal(name, key, op, arg) {
|
|
82
|
-
return this.engine.signalEntity(name, key, op, arg);
|
|
83
|
-
}
|
|
84
|
-
/** Read an entity's current durable state (or undefined if it has none yet). */
|
|
85
|
-
getState(name, key) {
|
|
86
|
-
return this.engine.getEntityState(name, key);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
exports.EntityService = EntityService;
|
|
90
|
-
exports.EntityService = EntityService = __decorate([
|
|
91
|
-
(0, common_1.Injectable)(),
|
|
92
|
-
__metadata("design:paramtypes", [nestjs_durable_core_1.WorkflowEngine])
|
|
93
|
-
], EntityService);
|
|
94
|
-
//# sourceMappingURL=entity.js.map
|
package/dist/entity.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
type ClassCtor = new (...args: any[]) => object;
|
|
2
|
-
/**
|
|
3
|
-
* Build a `validateInput` from a class-validator DTO class — the same `plainToInstance` + `validate`
|
|
4
|
-
* NestJS runs in controllers. `class-validator` and `class-transformer` are lazy-required optional
|
|
5
|
-
* peers (only needed if you use `@Workflow({ inputSchema })`), so they stay out of the type graph.
|
|
6
|
-
*/
|
|
7
|
-
export declare function classValidatorInput(cls: ClassCtor): (input: unknown) => Promise<void>;
|
|
8
|
-
export {};
|
|
9
|
-
//# sourceMappingURL=input-validation.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input-validation.d.ts","sourceRoot":"","sources":["../src/input-validation.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAqBrF"}
|
package/dist/input-validation.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.classValidatorInput = classValidatorInput;
|
|
4
|
-
/**
|
|
5
|
-
* Build a `validateInput` from a class-validator DTO class — the same `plainToInstance` + `validate`
|
|
6
|
-
* NestJS runs in controllers. `class-validator` and `class-transformer` are lazy-required optional
|
|
7
|
-
* peers (only needed if you use `@Workflow({ inputSchema })`), so they stay out of the type graph.
|
|
8
|
-
*/
|
|
9
|
-
function classValidatorInput(cls) {
|
|
10
|
-
let cv;
|
|
11
|
-
let ct;
|
|
12
|
-
try {
|
|
13
|
-
cv = require('class-validator');
|
|
14
|
-
ct = require('class-transformer');
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
throw new Error('@Workflow({ inputSchema }) needs the optional peers "class-validator" and "class-transformer" — install them, or pass a `validateInput` function instead.');
|
|
18
|
-
}
|
|
19
|
-
return async (input) => {
|
|
20
|
-
const instance = ct.plainToInstance(cls, input);
|
|
21
|
-
const errors = await cv.validate(instance, { whitelist: true });
|
|
22
|
-
if (errors.length > 0) {
|
|
23
|
-
const message = errors
|
|
24
|
-
.map((e) => Object.values(e.constraints ?? { _: e.property }).join(', '))
|
|
25
|
-
.join('; ');
|
|
26
|
-
throw new Error(`invalid input for workflow: ${message}`);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=input-validation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input-validation.js","sourceRoot":"","sources":["../src/input-validation.ts"],"names":[],"mappings":";;AAOA,kDAqBC;AA1BD;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,GAAc;IAChD,IAAI,EAAO,CAAC;IACZ,IAAI,EAAO,CAAC;IACZ,IAAI,CAAC;QACH,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChC,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,2JAA2J,CAC5J,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,EAAE,KAAc,EAAE,EAAE;QAC9B,MAAM,QAAQ,GAAG,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,MAAM;iBACnB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBAC7E,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { StepInvocation } from '@dudousxd/nestjs-durable-core';
|
|
2
|
-
import 'reflect-metadata';
|
|
3
|
-
export declare const STEP_INTERCEPTOR_METADATA: unique symbol;
|
|
4
|
-
/**
|
|
5
|
-
* The shape a `@StepInterceptor()` provider must implement: `intercept(invocation, next)` wraps the
|
|
6
|
-
* real execution of every local `ctx.step` (call `next()` to run the step body / next interceptor,
|
|
7
|
-
* and return — or transform — its result). The engine-level {@link StepInterceptor} primitive, with
|
|
8
|
-
* NestJS dependency injection.
|
|
9
|
-
*/
|
|
10
|
-
export interface DurableStepInterceptor {
|
|
11
|
-
intercept(invocation: StepInvocation, next: () => Promise<unknown>): Promise<unknown>;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Marks an `@Injectable()` class as a durable step interceptor. The module discovers it on boot and
|
|
15
|
-
* registers its `intercept` method with the engine (so it can inject loggers/tracers/etc.). First
|
|
16
|
-
* declared is outermost. Interceptors fire only when a step actually executes, never on replay.
|
|
17
|
-
*/
|
|
18
|
-
export declare function StepInterceptor(): ClassDecorator;
|
|
19
|
-
export declare function isStepInterceptor(target: Function): boolean;
|
|
20
|
-
//# sourceMappingURL=step-interceptor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"step-interceptor.d.ts","sourceRoot":"","sources":["../src/step-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,kBAAkB,CAAC;AAE1B,eAAO,MAAM,yBAAyB,eAA4C,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,UAAU,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,cAAc,CAIhD;AAGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAE3D"}
|
package/dist/step-interceptor.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.STEP_INTERCEPTOR_METADATA = void 0;
|
|
4
|
-
exports.StepInterceptor = StepInterceptor;
|
|
5
|
-
exports.isStepInterceptor = isStepInterceptor;
|
|
6
|
-
require("reflect-metadata");
|
|
7
|
-
exports.STEP_INTERCEPTOR_METADATA = Symbol('nestjs-durable:step-interceptor');
|
|
8
|
-
/**
|
|
9
|
-
* Marks an `@Injectable()` class as a durable step interceptor. The module discovers it on boot and
|
|
10
|
-
* registers its `intercept` method with the engine (so it can inject loggers/tracers/etc.). First
|
|
11
|
-
* declared is outermost. Interceptors fire only when a step actually executes, never on replay.
|
|
12
|
-
*/
|
|
13
|
-
function StepInterceptor() {
|
|
14
|
-
return (target) => {
|
|
15
|
-
Reflect.defineMetadata(exports.STEP_INTERCEPTOR_METADATA, true, target);
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
// biome-ignore lint/complexity/noBannedTypes: matches reflect-metadata's class target type
|
|
19
|
-
function isStepInterceptor(target) {
|
|
20
|
-
return Reflect.getMetadata(exports.STEP_INTERCEPTOR_METADATA, target) === true;
|
|
21
|
-
}
|
|
22
|
-
//# sourceMappingURL=step-interceptor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"step-interceptor.js","sourceRoot":"","sources":["../src/step-interceptor.ts"],"names":[],"mappings":";;;AAoBA,0CAIC;AAGD,8CAEC;AA5BD,4BAA0B;AAEb,QAAA,yBAAyB,GAAG,MAAM,CAAC,iCAAiC,CAAC,CAAC;AAYnF;;;;GAIG;AACH,SAAgB,eAAe;IAC7B,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,OAAO,CAAC,cAAc,CAAC,iCAAyB,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,SAAgB,iBAAiB,CAAC,MAAgB;IAChD,OAAO,OAAO,CAAC,WAAW,CAAC,iCAAyB,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;AACzE,CAAC"}
|
package/dist/timer-poller.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { WorkflowEngine } from '@dudousxd/nestjs-durable-core';
|
|
2
|
-
import { type OnApplicationBootstrap, type OnModuleDestroy } from '@nestjs/common';
|
|
3
|
-
import type { DurableModuleOptions } from './durable.module';
|
|
4
|
-
/**
|
|
5
|
-
* Resumes suspended runs whose durable timer (`ctx.sleep`) is due, and fires any configured
|
|
6
|
-
* recurring `schedules` — once on boot, then on an interval. Set `timerPollMs` to `0` to disable
|
|
7
|
-
* the interval (e.g. when an external scheduler drives `WorkflowEngine.resumeDueTimers`).
|
|
8
|
-
*/
|
|
9
|
-
export declare class TimerPoller implements OnApplicationBootstrap, OnModuleDestroy {
|
|
10
|
-
private readonly engine;
|
|
11
|
-
private readonly options;
|
|
12
|
-
private timer?;
|
|
13
|
-
private polling;
|
|
14
|
-
private unsubscribeEnqueued?;
|
|
15
|
-
constructor(engine: WorkflowEngine, options: DurableModuleOptions);
|
|
16
|
-
onApplicationBootstrap(): Promise<void>;
|
|
17
|
-
onModuleDestroy(): void;
|
|
18
|
-
private poll;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=timer-poller.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timer-poller.d.ts","sourceRoot":"","sources":["../src/timer-poller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,cAAc,EAAgB,MAAM,+BAA+B,CAAC;AAC9F,OAAO,EAGL,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;;GAIG;AACH,qBACa,WAAY,YAAW,sBAAsB,EAAE,eAAe;IAMvE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACE,OAAO,CAAC,QAAQ,CAAC,OAAO;IANnD,OAAO,CAAC,KAAK,CAAC,CAAiC;IAC/C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,mBAAmB,CAAC,CAAa;gBAGtB,MAAM,EAAE,cAAc,EACG,OAAO,EAAE,oBAAoB;IAGnE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAe7C,eAAe,IAAI,IAAI;YAKT,IAAI;CAmBnB"}
|
package/dist/timer-poller.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
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;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.TimerPoller = void 0;
|
|
16
|
-
const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
|
|
17
|
-
const common_1 = require("@nestjs/common");
|
|
18
|
-
/**
|
|
19
|
-
* Resumes suspended runs whose durable timer (`ctx.sleep`) is due, and fires any configured
|
|
20
|
-
* recurring `schedules` — once on boot, then on an interval. Set `timerPollMs` to `0` to disable
|
|
21
|
-
* the interval (e.g. when an external scheduler drives `WorkflowEngine.resumeDueTimers`).
|
|
22
|
-
*/
|
|
23
|
-
let TimerPoller = class TimerPoller {
|
|
24
|
-
engine;
|
|
25
|
-
options;
|
|
26
|
-
timer;
|
|
27
|
-
polling = false;
|
|
28
|
-
unsubscribeEnqueued;
|
|
29
|
-
constructor(engine, options) {
|
|
30
|
-
this.engine = engine;
|
|
31
|
-
this.options = options;
|
|
32
|
-
}
|
|
33
|
-
async onApplicationBootstrap() {
|
|
34
|
-
// Only the worker role drives suspended runs forward. A dashboard-only instance
|
|
35
|
-
// (`worker: false`) must not resume timers — leave that to the workers.
|
|
36
|
-
if (this.options.worker === false)
|
|
37
|
-
return;
|
|
38
|
-
// Low-latency dispatch: when a run is enqueued elsewhere (e.g. an API pod), pick it up at once
|
|
39
|
-
// over the control plane instead of waiting for the next poll tick. Leasing dedups across workers.
|
|
40
|
-
this.unsubscribeEnqueued = this.engine.onEnqueued((runId) => void this.engine.runOne(runId));
|
|
41
|
-
await this.poll();
|
|
42
|
-
const intervalMs = this.options.timerPollMs ?? 1_000;
|
|
43
|
-
if (intervalMs > 0) {
|
|
44
|
-
this.timer = setInterval(() => void this.poll(), intervalMs);
|
|
45
|
-
this.timer.unref?.();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
onModuleDestroy() {
|
|
49
|
-
if (this.timer)
|
|
50
|
-
clearInterval(this.timer);
|
|
51
|
-
this.unsubscribeEnqueued?.();
|
|
52
|
-
}
|
|
53
|
-
async poll() {
|
|
54
|
-
if (this.polling)
|
|
55
|
-
return; // never overlap two sweeps
|
|
56
|
-
this.polling = true;
|
|
57
|
-
try {
|
|
58
|
-
// Pick up runs enqueued elsewhere (an API pod's `start`, or another worker) still `pending`,
|
|
59
|
-
// reclaim runs orphaned by a crashed worker (lease expired — a live worker renews its lease so
|
|
60
|
-
// only dead ones are reclaimed), then resume due timers and sweep execution timeouts.
|
|
61
|
-
await this.engine.runPending();
|
|
62
|
-
await this.engine.recoverIncomplete();
|
|
63
|
-
await this.engine.resumeDueTimers();
|
|
64
|
-
await this.engine.sweepTimeouts();
|
|
65
|
-
const schedules = this.options.schedules;
|
|
66
|
-
if (schedules && schedules.length > 0) {
|
|
67
|
-
await (0, nestjs_durable_core_1.runSchedules)(this.engine, schedules, Date.now());
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
finally {
|
|
71
|
-
this.polling = false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
exports.TimerPoller = TimerPoller;
|
|
76
|
-
exports.TimerPoller = TimerPoller = __decorate([
|
|
77
|
-
(0, common_1.Injectable)(),
|
|
78
|
-
__param(1, (0, common_1.Inject)(nestjs_durable_core_1.DURABLE_OPTIONS)),
|
|
79
|
-
__metadata("design:paramtypes", [nestjs_durable_core_1.WorkflowEngine, Object])
|
|
80
|
-
], TimerPoller);
|
|
81
|
-
//# sourceMappingURL=timer-poller.js.map
|
package/dist/timer-poller.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timer-poller.js","sourceRoot":"","sources":["../src/timer-poller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uEAA8F;AAC9F,2CAKwB;AAGxB;;;;GAIG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAW;IAMH;IACyB;IANpC,KAAK,CAAkC;IACvC,OAAO,GAAG,KAAK,CAAC;IAChB,mBAAmB,CAAc;IAEzC,YACmB,MAAsB,EACG,OAA6B;QADtD,WAAM,GAAN,MAAM,CAAgB;QACG,YAAO,GAAP,OAAO,CAAsB;IACtE,CAAC;IAEJ,KAAK,CAAC,sBAAsB;QAC1B,gFAAgF;QAChF,wEAAwE;QACxE,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK;YAAE,OAAO;QAC1C,+FAA+F;QAC/F,mGAAmG;QACnG,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7F,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC;QACrD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;YAC7D,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED,eAAe;QACb,IAAI,IAAI,CAAC,KAAK;YAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,2BAA2B;QACrD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC;YACH,6FAA6F;YAC7F,+FAA+F;YAC/F,sFAAsF;YACtF,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACtC,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YACpC,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YACzC,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtC,MAAM,IAAA,kCAAY,EAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;CACF,CAAA;AAjDY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;IAQR,WAAA,IAAA,eAAM,EAAC,qCAAe,CAAC,CAAA;qCADC,oCAAc;GAN9B,WAAW,CAiDvB"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { type StateStore, WorkflowEngine } from '@dudousxd/nestjs-durable-core';
|
|
2
|
-
import { type OnApplicationBootstrap, type OnApplicationShutdown, type OnModuleInit } from '@nestjs/common';
|
|
3
|
-
import { DiscoveryService, MetadataScanner } from '@nestjs/core';
|
|
4
|
-
import type { DurableModuleOptions } from './durable.module';
|
|
5
|
-
/**
|
|
6
|
-
* Ensures the schema (auto-schema) and registers `@Workflow` providers on init, resumes runs left
|
|
7
|
-
* incomplete by a previous process once booted, and drains in-flight runs on shutdown.
|
|
8
|
-
*
|
|
9
|
-
* For the shutdown drain to fire, enable Nest's shutdown hooks: `app.enableShutdownHooks()`.
|
|
10
|
-
*/
|
|
11
|
-
export declare class WorkflowRegistrar implements OnModuleInit, OnApplicationBootstrap, OnApplicationShutdown {
|
|
12
|
-
private readonly discovery;
|
|
13
|
-
private readonly metadataScanner;
|
|
14
|
-
private readonly engine;
|
|
15
|
-
private readonly store;
|
|
16
|
-
private readonly options;
|
|
17
|
-
constructor(discovery: DiscoveryService, metadataScanner: MetadataScanner, engine: WorkflowEngine, store: StateStore, options: DurableModuleOptions);
|
|
18
|
-
onApplicationBootstrap(): Promise<void>;
|
|
19
|
-
/** On deploy/shutdown: stop picking up new runs and wait for in-flight ones to settle, then close
|
|
20
|
-
* the transport(s) so the broker workers stop consuming and connections are released. Closing
|
|
21
|
-
* AFTER the drain keeps the transport alive while in-flight runs dispatch/await their remote steps. */
|
|
22
|
-
onApplicationShutdown(): Promise<void>;
|
|
23
|
-
onModuleInit(): Promise<void>;
|
|
24
|
-
/** Returns the instance's `@DeadLetter()` method bound to the instance, or undefined if none. */
|
|
25
|
-
private findDeadLetterHandler;
|
|
26
|
-
/**
|
|
27
|
-
* Installs a single onDead listener that routes a dead run to its workflow's handler (from the
|
|
28
|
-
* map) or the module-level `deadLetterWorkflow` default. The handler is started idempotently with
|
|
29
|
-
* a `dlq:<runId>` id, so re-recovery never double-dispatches.
|
|
30
|
-
*/
|
|
31
|
-
private installDeadLetterRouting;
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=workflow.registrar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.registrar.d.ts","sourceRoot":"","sources":["../src/workflow.registrar.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,UAAU,EAEf,cAAc,EAIf,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAGL,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAW7D;;;;;GAKG;AACH,qBACa,iBACX,YAAW,YAAY,EAAE,sBAAsB,EAAE,qBAAqB;IAGpE,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACF,OAAO,CAAC,QAAQ,CAAC,KAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAJhC,SAAS,EAAE,gBAAgB,EAC3B,eAAe,EAAE,eAAe,EAChC,MAAM,EAAE,cAAc,EACD,KAAK,EAAE,UAAU,EACb,OAAO,EAAE,oBAAoB;IAGnE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAO7C;;4GAEwG;IAClG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAStC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAwEnC,iGAAiG;IACjG,OAAO,CAAC,qBAAqB;IAW7B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;CAiBjC"}
|