@dudousxd/nestjs-durable-core 0.1.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 (45) hide show
  1. package/dist/duration.d.ts +6 -0
  2. package/dist/duration.d.ts.map +1 -0
  3. package/dist/duration.js +42 -0
  4. package/dist/duration.js.map +1 -0
  5. package/dist/engine.d.ts +115 -0
  6. package/dist/engine.d.ts.map +1 -0
  7. package/dist/engine.js +588 -0
  8. package/dist/engine.js.map +1 -0
  9. package/dist/errors.d.ts +34 -0
  10. package/dist/errors.d.ts.map +1 -0
  11. package/dist/errors.js +59 -0
  12. package/dist/errors.js.map +1 -0
  13. package/dist/index.d.ts +11 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +30 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/interfaces.d.ts +249 -0
  18. package/dist/interfaces.d.ts.map +1 -0
  19. package/dist/interfaces.js +3 -0
  20. package/dist/interfaces.js.map +1 -0
  21. package/dist/protocol.d.ts +12 -0
  22. package/dist/protocol.d.ts.map +1 -0
  23. package/dist/protocol.js +35 -0
  24. package/dist/protocol.js.map +1 -0
  25. package/dist/remote-step-factory.d.ts +15 -0
  26. package/dist/remote-step-factory.d.ts.map +1 -0
  27. package/dist/remote-step-factory.js +15 -0
  28. package/dist/remote-step-factory.js.map +1 -0
  29. package/dist/scheduler.d.ts +19 -0
  30. package/dist/scheduler.d.ts.map +1 -0
  31. package/dist/scheduler.js +24 -0
  32. package/dist/scheduler.js.map +1 -0
  33. package/dist/testing/in-memory-state-store.d.ts +25 -0
  34. package/dist/testing/in-memory-state-store.d.ts.map +1 -0
  35. package/dist/testing/in-memory-state-store.js +88 -0
  36. package/dist/testing/in-memory-state-store.js.map +1 -0
  37. package/dist/testing/in-memory-transport.d.ts +16 -0
  38. package/dist/testing/in-memory-transport.d.ts.map +1 -0
  39. package/dist/testing/in-memory-transport.js +29 -0
  40. package/dist/testing/in-memory-transport.js.map +1 -0
  41. package/dist/tokens.d.ts +8 -0
  42. package/dist/tokens.d.ts.map +1 -0
  43. package/dist/tokens.js +11 -0
  44. package/dist/tokens.js.map +1 -0
  45. package/package.json +31 -0
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryStateStore = void 0;
4
+ /**
5
+ * A non-durable, in-process `StateStore` for tests and local development.
6
+ * The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.
7
+ */
8
+ class InMemoryStateStore {
9
+ runs = new Map();
10
+ checkpoints = new Map();
11
+ signalWaiters = new Map();
12
+ key(runId, seq) {
13
+ return `${runId}:${seq}`;
14
+ }
15
+ async createRun(run) {
16
+ this.runs.set(run.id, { ...run });
17
+ }
18
+ async updateRun(runId, patch) {
19
+ const existing = this.runs.get(runId);
20
+ if (!existing)
21
+ throw new Error(`run ${runId} not found`);
22
+ this.runs.set(runId, { ...existing, ...patch });
23
+ }
24
+ async getRun(runId) {
25
+ const run = this.runs.get(runId);
26
+ return run ? { ...run } : null;
27
+ }
28
+ async getCheckpoint(runId, seq) {
29
+ const cp = this.checkpoints.get(this.key(runId, seq));
30
+ return cp ? { ...cp } : null;
31
+ }
32
+ async saveCheckpoint(checkpoint) {
33
+ this.checkpoints.set(this.key(checkpoint.runId, checkpoint.seq), { ...checkpoint });
34
+ }
35
+ async listIncompleteRuns() {
36
+ return [...this.runs.values()].filter((r) => r.status === 'running').map((r) => ({ ...r }));
37
+ }
38
+ async listDueTimers(nowMs) {
39
+ return [...this.runs.values()]
40
+ .filter((r) => r.status === 'suspended' && r.wakeAt !== undefined && r.wakeAt <= nowMs)
41
+ .map((r) => ({ ...r }));
42
+ }
43
+ async tryLockRun(runId, owner, leaseUntilMs, nowMs) {
44
+ const run = this.runs.get(runId);
45
+ if (!run)
46
+ return false;
47
+ if (run.lockedUntil !== undefined && run.lockedUntil > nowMs)
48
+ return false;
49
+ run.lockedBy = owner;
50
+ run.lockedUntil = leaseUntilMs;
51
+ return true;
52
+ }
53
+ async releaseRunLock(runId) {
54
+ const run = this.runs.get(runId);
55
+ if (run) {
56
+ run.lockedBy = undefined;
57
+ run.lockedUntil = undefined;
58
+ }
59
+ }
60
+ async putSignalWaiter(waiter) {
61
+ this.signalWaiters.set(waiter.token, { ...waiter });
62
+ }
63
+ async takeSignalWaiter(token) {
64
+ const waiter = this.signalWaiters.get(token);
65
+ if (!waiter)
66
+ return null;
67
+ this.signalWaiters.delete(token);
68
+ return { ...waiter };
69
+ }
70
+ async listRuns(query) {
71
+ let runs = [...this.runs.values()];
72
+ if (query.workflow)
73
+ runs = runs.filter((r) => r.workflow === query.workflow);
74
+ if (query.status)
75
+ runs = runs.filter((r) => r.status === query.status);
76
+ const offset = query.offset ?? 0;
77
+ const limit = query.limit ?? runs.length;
78
+ return runs.slice(offset, offset + limit).map((r) => ({ ...r }));
79
+ }
80
+ async listCheckpoints(runId) {
81
+ return [...this.checkpoints.values()]
82
+ .filter((cp) => cp.runId === runId)
83
+ .sort((a, b) => a.seq - b.seq)
84
+ .map((cp) => ({ ...cp }));
85
+ }
86
+ }
87
+ exports.InMemoryStateStore = InMemoryStateStore;
88
+ //# sourceMappingURL=in-memory-state-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-state-store.js","sourceRoot":"","sources":["../../src/testing/in-memory-state-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Heartbeat, RemoteTask, StepResult, Transport } from '../interfaces';
2
+ import { type StepHandler } from '../protocol';
3
+ /**
4
+ * An in-process `Transport` for tests and local development: registered handlers stand in
5
+ * for remote workers, so a whole cross-app workflow runs in a single process.
6
+ */
7
+ export declare class InMemoryTransport implements Transport {
8
+ private readonly handlers;
9
+ private resultHandler?;
10
+ /** Register a fake worker handler for a step name. */
11
+ handle(name: string, fn: StepHandler): void;
12
+ dispatch(task: RemoteTask): Promise<void>;
13
+ onResult(handler: (result: StepResult) => Promise<void>): void;
14
+ onHeartbeat(_handler: (beat: Heartbeat) => Promise<void>): void;
15
+ }
16
+ //# sourceMappingURL=in-memory-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-transport.d.ts","sourceRoot":"","sources":["../../src/testing/in-memory-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,aAAa,CAAC;AAE/D;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,aAAa,CAAC,CAAwC;IAE9D,sDAAsD;IACtD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI;IAIrC,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI9D,WAAW,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAGhE"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryTransport = void 0;
4
+ const protocol_1 = require("../protocol");
5
+ /**
6
+ * An in-process `Transport` for tests and local development: registered handlers stand in
7
+ * for remote workers, so a whole cross-app workflow runs in a single process.
8
+ */
9
+ class InMemoryTransport {
10
+ handlers = new Map();
11
+ resultHandler;
12
+ /** Register a fake worker handler for a step name. */
13
+ handle(name, fn) {
14
+ this.handlers.set(name, fn);
15
+ }
16
+ async dispatch(task) {
17
+ if (!this.resultHandler)
18
+ throw new Error('no result handler registered');
19
+ await this.resultHandler(await (0, protocol_1.runStepHandler)(task, this.handlers.get(task.name)));
20
+ }
21
+ onResult(handler) {
22
+ this.resultHandler = handler;
23
+ }
24
+ onHeartbeat(_handler) {
25
+ // In-process handlers run synchronously; there is no liveness to track.
26
+ }
27
+ }
28
+ exports.InMemoryTransport = InMemoryTransport;
29
+ //# sourceMappingURL=in-memory-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-transport.js","sourceRoot":"","sources":["../../src/testing/in-memory-transport.ts"],"names":[],"mappings":";;;AACA,0CAA+D;AAE/D;;;GAGG;AACH,MAAa,iBAAiB;IACX,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IACnD,aAAa,CAAyC;IAE9D,sDAAsD;IACtD,MAAM,CAAC,IAAY,EAAE,EAAe;QAClC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAgB;QAC7B,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACzE,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,IAAA,yBAAc,EAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC;IAED,QAAQ,CAAC,OAA8C;QACrD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;IAC/B,CAAC;IAED,WAAW,CAAC,QAA4C;QACtD,wEAAwE;IAC1E,CAAC;CACF;AArBD,8CAqBC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Dependency-injection tokens. Adapters bind their implementations to these so `core` and
3
+ * `@dudousxd/nestjs-durable` depend only on the interfaces in `./interfaces`.
4
+ */
5
+ export declare const STATE_STORE: unique symbol;
6
+ export declare const TRANSPORT: unique symbol;
7
+ export declare const DURABLE_OPTIONS: unique symbol;
8
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,WAAW,eAAuC,CAAC;AAChE,eAAO,MAAM,SAAS,eAAqC,CAAC;AAC5D,eAAO,MAAM,eAAe,eAA2C,CAAC"}
package/dist/tokens.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /**
3
+ * Dependency-injection tokens. Adapters bind their implementations to these so `core` and
4
+ * `@dudousxd/nestjs-durable` depend only on the interfaces in `./interfaces`.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.DURABLE_OPTIONS = exports.TRANSPORT = exports.STATE_STORE = void 0;
8
+ exports.STATE_STORE = Symbol('nestjs-durable:STATE_STORE');
9
+ exports.TRANSPORT = Symbol('nestjs-durable:TRANSPORT');
10
+ exports.DURABLE_OPTIONS = Symbol('nestjs-durable:DURABLE_OPTIONS');
11
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEU,QAAA,WAAW,GAAG,MAAM,CAAC,4BAA4B,CAAC,CAAC;AACnD,QAAA,SAAS,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAC/C,QAAA,eAAe,GAAG,MAAM,CAAC,gCAAgC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@dudousxd/nestjs-durable-core",
3
+ "version": "0.1.0",
4
+ "description": "Durable workflows for NestJS — core interfaces, engine and deterministic replay",
5
+ "license": "MIT",
6
+ "author": "Davide Carvalho",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/DavideCarvalho/nestjs-durable.git",
10
+ "directory": "packages/core"
11
+ },
12
+ "type": "commonjs",
13
+ "main": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "peerDependencies": {
19
+ "reflect-metadata": "^0.2.0",
20
+ "zod": "^3.0.0 || ^4.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "reflect-metadata": "0.2.2",
24
+ "typescript": "5.9.3",
25
+ "zod": "3.25.76"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc -p tsconfig.json",
29
+ "typecheck": "tsc -p tsconfig.json --noEmit"
30
+ }
31
+ }