@dudousxd/nestjs-durable 0.15.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.cjs +790 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +411 -0
  5. package/dist/index.d.ts +411 -8
  6. package/dist/index.js +744 -21
  7. package/dist/index.js.map +1 -1
  8. package/package.json +21 -7
  9. package/dist/context-accessor.d.ts +0 -31
  10. package/dist/context-accessor.d.ts.map +0 -1
  11. package/dist/context-accessor.js +0 -3
  12. package/dist/context-accessor.js.map +0 -1
  13. package/dist/decorators.d.ts +0 -146
  14. package/dist/decorators.d.ts.map +0 -1
  15. package/dist/decorators.js +0 -103
  16. package/dist/decorators.js.map +0 -1
  17. package/dist/durable-step.registrar.d.ts +0 -30
  18. package/dist/durable-step.registrar.d.ts.map +0 -1
  19. package/dist/durable-step.registrar.js +0 -85
  20. package/dist/durable-step.registrar.js.map +0 -1
  21. package/dist/durable.module.d.ts +0 -108
  22. package/dist/durable.module.d.ts.map +0 -1
  23. package/dist/durable.module.js +0 -207
  24. package/dist/durable.module.js.map +0 -1
  25. package/dist/entity.d.ts +0 -43
  26. package/dist/entity.d.ts.map +0 -1
  27. package/dist/entity.js +0 -94
  28. package/dist/entity.js.map +0 -1
  29. package/dist/index.d.ts.map +0 -1
  30. package/dist/input-validation.d.ts +0 -9
  31. package/dist/input-validation.d.ts.map +0 -1
  32. package/dist/input-validation.js +0 -30
  33. package/dist/input-validation.js.map +0 -1
  34. package/dist/step-interceptor.d.ts +0 -20
  35. package/dist/step-interceptor.d.ts.map +0 -1
  36. package/dist/step-interceptor.js +0 -22
  37. package/dist/step-interceptor.js.map +0 -1
  38. package/dist/timer-poller.d.ts +0 -20
  39. package/dist/timer-poller.d.ts.map +0 -1
  40. package/dist/timer-poller.js +0 -81
  41. package/dist/timer-poller.js.map +0 -1
  42. package/dist/tokens.d.ts +0 -13
  43. package/dist/tokens.d.ts.map +0 -1
  44. package/dist/tokens.js +0 -16
  45. package/dist/tokens.js.map +0 -1
  46. package/dist/workflow.registrar.d.ts +0 -33
  47. package/dist/workflow.registrar.d.ts.map +0 -1
  48. package/dist/workflow.registrar.js +0 -169
  49. package/dist/workflow.registrar.js.map +0 -1
  50. package/dist/workflow.service.d.ts +0 -55
  51. package/dist/workflow.service.d.ts.map +0 -1
  52. package/dist/workflow.service.js +0 -58
  53. package/dist/workflow.service.js.map +0 -1
@@ -1,85 +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.DurableStepRegistrar = void 0;
16
- const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
17
- const common_1 = require("@nestjs/common");
18
- const core_1 = require("@nestjs/core");
19
- const decorators_1 = require("./decorators");
20
- function supportsHandle(transport) {
21
- return typeof transport?.handle === 'function';
22
- }
23
- /**
24
- * Discovers `@DurableStep` methods and registers them as step handlers on the configured
25
- * transport, when that transport runs handlers in-process. With a queue/remote transport the
26
- * handlers live in the worker process instead, so there is nothing to wire here.
27
- *
28
- * **Context re-hydration (consume side) is the consumer's responsibility.** DurableModule's
29
- * produce side auto-feeds an opaque carrier (`{ traceId, tenantId, userRef }`) from
30
- * `@dudousxd/nestjs-context` onto each dispatched `RemoteTask.context` (see DurableModule). A worker
31
- * that wants its `@DurableStep` reads to SEE the originating context must re-establish it from
32
- * `task.context`. We do NOT do this here because: (a) re-hydration needs nestjs-context's module-level
33
- * `Context.deserialize(carrier, fn)` at runtime, and it is an OPTIONAL peer we must not hard-import;
34
- * and (b) the in-process `StepHandler` contract is `(input, log)` — the engine never surfaces
35
- * `task.context` to the handler closure, so wrapping it here would require widening the core
36
- * transport/handler signature (a non-additive cross-cutting change). Instead, a worker that consumes
37
- * the carrier should wrap its handler with `Context.deserialize(task.context, () => handler(...))`
38
- * from its own transport/worker bootstrap, where `task` is in scope.
39
- */
40
- let DurableStepRegistrar = class DurableStepRegistrar {
41
- discovery;
42
- metadataScanner;
43
- transport;
44
- options;
45
- constructor(discovery, metadataScanner, transport, options) {
46
- this.discovery = discovery;
47
- this.metadataScanner = metadataScanner;
48
- this.transport = transport;
49
- this.options = options;
50
- }
51
- onModuleInit() {
52
- // A dashboard/dispatch-only instance (`worker: false`) must not consume the queue — receiving
53
- // and running step tasks is exactly the worker role we're switching off here.
54
- if (this.options.worker === false)
55
- return;
56
- if (!supportsHandle(this.transport))
57
- return;
58
- const transport = this.transport;
59
- for (const wrapper of this.discovery.getProviders()) {
60
- const { instance } = wrapper;
61
- if (!instance || typeof instance !== 'object')
62
- continue;
63
- const prototype = Object.getPrototypeOf(instance);
64
- for (const methodName of this.metadataScanner.getAllMethodNames(prototype)) {
65
- const method = instance[methodName];
66
- if (typeof method !== 'function')
67
- continue;
68
- const meta = (0, decorators_1.getDurableStepMeta)(method);
69
- if (!meta)
70
- continue;
71
- // Forward the step logger as a second arg; methods that only declare `(input)` ignore it.
72
- transport.handle(meta.name, (input, log) => instance[methodName](input, log));
73
- }
74
- }
75
- }
76
- };
77
- exports.DurableStepRegistrar = DurableStepRegistrar;
78
- exports.DurableStepRegistrar = DurableStepRegistrar = __decorate([
79
- (0, common_1.Injectable)(),
80
- __param(2, (0, common_1.Inject)(nestjs_durable_core_1.TRANSPORT)),
81
- __param(3, (0, common_1.Inject)(nestjs_durable_core_1.DURABLE_OPTIONS)),
82
- __metadata("design:paramtypes", [core_1.DiscoveryService,
83
- core_1.MetadataScanner, Object, Object])
84
- ], DurableStepRegistrar);
85
- //# sourceMappingURL=durable-step.registrar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"durable-step.registrar.js","sourceRoot":"","sources":["../src/durable-step.registrar.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uEAKuC;AACvC,2CAAuE;AACvE,uCAAiE;AACjE,6CAAkD;AAQlD,SAAS,cAAc,CAAC,SAAkB;IACxC,OAAO,OAAQ,SAAsC,EAAE,MAAM,KAAK,UAAU,CAAC;AAC/E,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ;IACA;IACmB;IACM;IAJ5C,YACmB,SAA2B,EAC3B,eAAgC,EACb,SAA2B,EACrB,OAA6B;QAHtD,cAAS,GAAT,SAAS,CAAkB;QAC3B,oBAAe,GAAf,eAAe,CAAiB;QACb,cAAS,GAAT,SAAS,CAAkB;QACrB,YAAO,GAAP,OAAO,CAAsB;IACtE,CAAC;IAEJ,YAAY;QACV,8FAA8F;QAC9F,8EAA8E;QAC9E,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK;YAAE,OAAO;QAC1C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,CAAC;YACpD,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;YAC7B,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ;gBAAE,SAAS;YACxD,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAClD,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3E,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;gBACpC,IAAI,OAAO,MAAM,KAAK,UAAU;oBAAE,SAAS;gBAC3C,MAAM,IAAI,GAAG,IAAA,+BAAkB,EAAC,MAAM,CAAC,CAAC;gBACxC,IAAI,CAAC,IAAI;oBAAE,SAAS;gBACpB,0FAA0F;gBAC1F,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAA;AA7BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,eAAM,EAAC,+BAAS,CAAC,CAAA;IACjB,WAAA,IAAA,eAAM,EAAC,qCAAe,CAAC,CAAA;qCAHI,uBAAgB;QACV,sBAAe;GAHxC,oBAAoB,CA6BhC"}
@@ -1,108 +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`. The engine never
82
- * inspects its shape.
83
- *
84
- * **Auto-feed**: if you omit this AND `@dudousxd/nestjs-context` is installed (its accessor is bound
85
- * to the shared `CONTEXT_ACCESSOR` token), DurableModule defaults this to a reader that builds
86
- * `{ traceId, tenantId, userRef }` from the accessor — so a workflow dispatched within a request
87
- * automatically carries the originating context across process boundaries. Pass your own reader to
88
- * override the auto-feed; with neither, the carrier is omitted (unchanged behavior).
89
- *
90
- * Re-evaluated at each (re)dispatch — including a retry or a crash/scale-down resume that the engine
91
- * drives OUTSIDE the originating request scope, where this reader may return empty or stale values.
92
- * Treat the carrier as best-effort correlation/propagation metadata only — do NOT treat it as an
93
- * authorization boundary.
94
- */
95
- context?: () => Record<string, unknown> | undefined;
96
- /** Attempts for each saga compensation when a run fails. Default 1 (no retry). Idempotent undos. */
97
- compensationRetries?: number;
98
- }
99
- export interface DurableModuleAsyncOptions {
100
- useFactory: (...args: never[]) => DurableModuleOptions | Promise<DurableModuleOptions>;
101
- inject?: InjectionToken[];
102
- }
103
- export declare class DurableModule {
104
- static forRoot(options: DurableModuleOptions): DynamicModule;
105
- static forRootAsync(options: DurableModuleAsyncOptions): DynamicModule;
106
- private static build;
107
- }
108
- //# 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;AAoFhG,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;;;;;;;;;;;;;;;OAeG;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;CAmFrB"}
@@ -1,207 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
- 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;
22
- return c > 3 && r && Object.defineProperty(target, key, r), r;
23
- };
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
- var DurableModule_1;
42
- Object.defineProperty(exports, "__esModule", { value: true });
43
- exports.DurableModule = void 0;
44
- const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
45
- const common_1 = require("@nestjs/common");
46
- const core_1 = require("@nestjs/core");
47
- const durable_step_registrar_1 = require("./durable-step.registrar");
48
- const entity_1 = require("./entity");
49
- const timer_poller_1 = require("./timer-poller");
50
- const tokens_1 = require("./tokens");
51
- const workflow_registrar_1 = require("./workflow.registrar");
52
- const workflow_service_1 = require("./workflow.service");
53
- /**
54
- * Locate the context accessor non-strictly: an accessor provided by ANY module (a global
55
- * `ContextModule` from `@dudousxd/nestjs-context`, or the app root) is found via {@link ModuleRef},
56
- * because DurableModule is `global` and its engine factory can't see another module's local
57
- * providers directly. Returns undefined when the optional peer isn't installed/bound.
58
- */
59
- function resolveAccessor(moduleRef) {
60
- try {
61
- return moduleRef.get(tokens_1.CONTEXT_ACCESSOR, { strict: false });
62
- }
63
- catch {
64
- return undefined;
65
- }
66
- }
67
- /**
68
- * Build an opaque context carrier from a {@link ContextAccessor} — the auto-feed default for the
69
- * engine's `context` option when `@dudousxd/nestjs-context` is present and the app passed no own
70
- * reader. Drops fields the accessor doesn't populate, so an empty/anonymous request yields `{}`.
71
- */
72
- function carrierFromAccessor(accessor) {
73
- const carrier = {};
74
- const traceId = accessor.traceId();
75
- if (traceId !== undefined)
76
- carrier.traceId = traceId;
77
- const tenantId = accessor.tenantId();
78
- if (tenantId !== undefined)
79
- carrier.tenantId = tenantId;
80
- const userRef = accessor.userRef();
81
- if (userRef !== undefined)
82
- carrier.userRef = userRef;
83
- return carrier;
84
- }
85
- function isContextRuntime(x) {
86
- return !!x && typeof x.deserialize === 'function';
87
- }
88
- /**
89
- * Resolve `@dudousxd/nestjs-context`'s runtime `Context` singleton via a GUARDED dynamic import — used
90
- * to build the engine's `rehydrate` bridge. The runtime `Context` (its `deserialize`/ALS `run`) is a
91
- * module-level singleton, NOT a DI provider behind {@link CONTEXT_ACCESSOR}, so it can't be resolved
92
- * through ModuleRef — we import it directly. We do NOT add a hard/static import (the peer is optional):
93
- * a failure (peer not installed) returns undefined and the engine falls back to passthrough re-hydration.
94
- */
95
- async function resolveContextRuntime() {
96
- try {
97
- // Indirect the specifier through a variable so the compiler does not try to STATICALLY resolve
98
- // the optional peer (it may be uninstalled). This stays a runtime guarded import — a missing
99
- // module rejects and is caught below.
100
- const specifier = '@dudousxd/nestjs-context';
101
- const mod = (await Promise.resolve(`${specifier}`).then(s => __importStar(require(s))));
102
- return isContextRuntime(mod.Context) ? mod.Context : undefined;
103
- }
104
- catch {
105
- return undefined;
106
- }
107
- }
108
- /** True when `x` can act as a control plane (broadcast pub/sub) — e.g. a broadcast-capable transport. */
109
- function isControlPlane(x) {
110
- return (!!x &&
111
- typeof x.publishControl === 'function' &&
112
- typeof x.onControl === 'function');
113
- }
114
- let DurableModule = DurableModule_1 = class DurableModule {
115
- static forRoot(options) {
116
- return DurableModule_1.build({ provide: nestjs_durable_core_1.DURABLE_OPTIONS, useValue: options });
117
- }
118
- static forRootAsync(options) {
119
- return DurableModule_1.build({
120
- provide: nestjs_durable_core_1.DURABLE_OPTIONS,
121
- useFactory: options.useFactory,
122
- inject: options.inject ?? [],
123
- });
124
- }
125
- static build(optionsProvider) {
126
- return {
127
- module: DurableModule_1,
128
- global: true,
129
- imports: [core_1.DiscoveryModule],
130
- providers: [
131
- optionsProvider,
132
- {
133
- provide: nestjs_durable_core_1.STATE_STORE,
134
- useFactory: (options) => options.store,
135
- inject: [nestjs_durable_core_1.DURABLE_OPTIONS],
136
- },
137
- {
138
- provide: nestjs_durable_core_1.TRANSPORT,
139
- useFactory: (options) => options.transport ?? null,
140
- inject: [nestjs_durable_core_1.DURABLE_OPTIONS],
141
- },
142
- {
143
- provide: nestjs_durable_core_1.WorkflowEngine,
144
- useFactory: async (store, transport, opts,
145
- // The accessor from `@dudousxd/nestjs-context` is resolved at construction via ModuleRef
146
- // (shared CONTEXT_ACCESSOR symbol — no hard import). Absent → unchanged behavior.
147
- moduleRef) => {
148
- // The control-plane default is the primary task transport (single, or the pool's first)
149
- // when it can broadcast.
150
- const primary = transport ?? opts.transports?.[0]?.transport;
151
- // Auto-feed the carrier from nestjs-context when an accessor is present AND the app didn't
152
- // pass its own `context` reader. The app's own reader always wins; with no accessor the
153
- // carrier stays `undefined` (unchanged behavior — `traceparent` etc. still work).
154
- const accessor = resolveAccessor(moduleRef);
155
- const context = opts.context ?? (accessor ? () => carrierFromAccessor(accessor) : undefined);
156
- // Consume side: when nestjs-context is present (an accessor is bound), re-hydrate the
157
- // originating context AROUND each local step body, so a `@DurableStep` reader sees the
158
- // tenant/user/trace ids ambiently via nestjs-context's ALS — no consumer wrapping needed.
159
- // The runtime `Context` is a module-level singleton (not the accessor token), resolved
160
- // ONCE here via a guarded dynamic import (optional peer — failure leaves the default
161
- // passthrough). Best-effort: an empty/undefined carrier just runs the handler normally.
162
- const runtime = accessor ? await resolveContextRuntime() : undefined;
163
- const rehydrate = runtime &&
164
- ((carrier, fn) => carrier && Object.keys(carrier).length > 0
165
- ? runtime.deserialize(carrier, fn)
166
- : fn());
167
- const engine = new nestjs_durable_core_1.WorkflowEngine({
168
- store,
169
- transport: transport ?? undefined,
170
- transports: opts.transports,
171
- controlPlane: opts.controlPlane ?? (isControlPlane(primary) ? primary : undefined),
172
- leaseMs: opts.leaseMs,
173
- maxRecoveryAttempts: opts.maxRecoveryAttempts,
174
- instanceId: opts.instanceId,
175
- webhookUrl: opts.webhookUrl,
176
- traceparent: opts.traceparent,
177
- context,
178
- rehydrate: rehydrate || undefined,
179
- compensationRetries: opts.compensationRetries,
180
- // A non-worker (API/dashboard) instance must not run workflows: enqueue-only, leaving
181
- // each `pending` run in the store for a worker's `runPending` poll. Workers use the
182
- // default in-process dispatcher (execute locally).
183
- runDispatcher: opts.worker === false ? { dispatch: () => { } } : undefined,
184
- });
185
- for (const queue of opts.queues ?? [])
186
- engine.registerQueue(queue);
187
- // Dead-letter routing (per-workflow `@DeadLetter()` / `deadLetterWorkflow` + this global
188
- // default) is wired by the WorkflowRegistrar, which owns the `@Workflow` metadata.
189
- return engine;
190
- },
191
- inject: [nestjs_durable_core_1.STATE_STORE, nestjs_durable_core_1.TRANSPORT, nestjs_durable_core_1.DURABLE_OPTIONS, core_1.ModuleRef],
192
- },
193
- workflow_service_1.WorkflowService,
194
- entity_1.EntityService,
195
- workflow_registrar_1.WorkflowRegistrar,
196
- durable_step_registrar_1.DurableStepRegistrar,
197
- timer_poller_1.TimerPoller,
198
- ],
199
- exports: [workflow_service_1.WorkflowService, entity_1.EntityService, nestjs_durable_core_1.WorkflowEngine, nestjs_durable_core_1.STATE_STORE, nestjs_durable_core_1.TRANSPORT],
200
- };
201
- }
202
- };
203
- exports.DurableModule = DurableModule;
204
- exports.DurableModule = DurableModule = DurableModule_1 = __decorate([
205
- (0, common_1.Module)({})
206
- ], DurableModule);
207
- //# sourceMappingURL=durable.module.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"durable.module.js","sourceRoot":"","sources":["../src/durable.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uEAYuC;AACvC,2CAAgG;AAChG,uCAA0D;AAE1D,qEAAgE;AAChE,qCAAyC;AACzC,iDAA6C;AAC7C,qCAA4C;AAC5C,6DAAyD;AACzD,yDAAqD;AAErD;;;;;GAKG;AACH,SAAS,eAAe,CAAC,SAAoB;IAC3C,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,GAAG,CAAkB,yBAAgB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,QAAyB;IACpD,MAAM,OAAO,GAA4B,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IACnC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;IACrC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IACnC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;IACrD,OAAO,OAAO,CAAC;AACjB,CAAC;AAaD,SAAS,gBAAgB,CAAC,CAAU;IAClC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAQ,CAAoB,CAAC,WAAW,KAAK,UAAU,CAAC;AACxE,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,qBAAqB;IAClC,IAAI,CAAC;QACH,+FAA+F;QAC/F,6FAA6F;QAC7F,sCAAsC;QACtC,MAAM,SAAS,GAAG,0BAA0B,CAAC;QAC7C,MAAM,GAAG,GAAG,CAAC,yBAAa,SAAS,uCAAC,CAA0B,CAAC;QAC/D,OAAO,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,yGAAyG;AACzG,SAAS,cAAc,CAAC,CAAU;IAChC,OAAO,CACL,CAAC,CAAC,CAAC;QACH,OAAQ,CAAkB,CAAC,cAAc,KAAK,UAAU;QACxD,OAAQ,CAAkB,CAAC,SAAS,KAAK,UAAU,CACpD,CAAC;AACJ,CAAC;AAyGM,IAAM,aAAa,qBAAnB,MAAM,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,OAA6B;QAC1C,OAAO,eAAa,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,qCAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAkC;QACpD,OAAO,eAAa,CAAC,KAAK,CAAC;YACzB,OAAO,EAAE,qCAAe;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,eAAyB;QAC5C,OAAO;YACL,MAAM,EAAE,eAAa;YACrB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,CAAC,sBAAe,CAAC;YAC1B,SAAS,EAAE;gBACT,eAAe;gBACf;oBACE,OAAO,EAAE,iCAAW;oBACpB,UAAU,EAAE,CAAC,OAA6B,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK;oBAC5D,MAAM,EAAE,CAAC,qCAAe,CAAC;iBAC1B;gBACD;oBACE,OAAO,EAAE,+BAAS;oBAClB,UAAU,EAAE,CAAC,OAA6B,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI;oBACxE,MAAM,EAAE,CAAC,qCAAe,CAAC;iBAC1B;gBACD;oBACE,OAAO,EAAE,oCAAc;oBACvB,UAAU,EAAE,KAAK,EACf,KAAiB,EACjB,SAA2B,EAC3B,IAA0B;oBAC1B,yFAAyF;oBACzF,kFAAkF;oBAClF,SAAoB,EACpB,EAAE;wBACF,wFAAwF;wBACxF,yBAAyB;wBACzB,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;wBAC7D,2FAA2F;wBAC3F,wFAAwF;wBACxF,kFAAkF;wBAClF,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;wBAC5C,MAAM,OAAO,GACX,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;wBAC/E,sFAAsF;wBACtF,uFAAuF;wBACvF,0FAA0F;wBAC1F,uFAAuF;wBACvF,qFAAqF;wBACrF,wFAAwF;wBACxF,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,qBAAqB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;wBACrE,MAAM,SAAS,GACb,OAAO;4BACP,CAAC,CAAI,OAA4C,EAAE,EAAW,EAAK,EAAE,CACnE,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;gCACxC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gCAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACd,MAAM,MAAM,GAAG,IAAI,oCAAc,CAAC;4BAChC,KAAK;4BACL,SAAS,EAAE,SAAS,IAAI,SAAS;4BACjC,UAAU,EAAE,IAAI,CAAC,UAAU;4BAC3B,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;4BAClF,OAAO,EAAE,IAAI,CAAC,OAAO;4BACrB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;4BAC7C,UAAU,EAAE,IAAI,CAAC,UAAU;4BAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;4BAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;4BAC7B,OAAO;4BACP,SAAS,EAAE,SAAS,IAAI,SAAS;4BACjC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;4BAC7C,sFAAsF;4BACtF,oFAAoF;4BACpF,mDAAmD;4BACnD,aAAa,EAAE,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;yBAC1E,CAAC,CAAC;wBACH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;4BAAE,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;wBACnE,yFAAyF;wBACzF,mFAAmF;wBACnF,OAAO,MAAM,CAAC;oBAChB,CAAC;oBACD,MAAM,EAAE,CAAC,iCAAW,EAAE,+BAAS,EAAE,qCAAe,EAAE,gBAAS,CAAC;iBAC7D;gBACD,kCAAe;gBACf,sBAAa;gBACb,sCAAiB;gBACjB,6CAAoB;gBACpB,0BAAW;aACZ;YACD,OAAO,EAAE,CAAC,kCAAe,EAAE,sBAAa,EAAE,oCAAc,EAAE,iCAAW,EAAE,+BAAS,CAAC;SAClF,CAAC;IACJ,CAAC;CACF,CAAA;AAhGY,sCAAa;wBAAb,aAAa;IADzB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,aAAa,CAgGzB"}
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
@@ -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
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,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"}
@@ -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