@dudousxd/nestjs-durable 0.26.0 → 0.28.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/dist/index.cjs +998 -310
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +482 -223
- package/dist/index.d.ts +482 -223
- package/dist/index.js +960 -280
- package/dist/index.js.map +1 -1
- package/package.json +11 -4
- package/skills/durable-determinism/SKILL.md +45 -31
- package/skills/durable-setup/SKILL.md +23 -15
- package/skills/durable-signals-and-timers/SKILL.md +25 -9
- package/skills/durable-testing/SKILL.md +85 -28
- package/skills/durable-workflows/SKILL.md +138 -83
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
// src/decorators.ts
|
|
11
|
-
import { WORKFLOW_NAME_KEY } from "@dudousxd/nestjs-durable-core";
|
|
11
|
+
import { DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, WORKFLOW_NAME_KEY } from "@dudousxd/nestjs-durable-core";
|
|
12
12
|
import "reflect-metadata";
|
|
13
13
|
var WORKFLOW_METADATA = Symbol("nestjs-durable:workflow");
|
|
14
14
|
function Workflow(options) {
|
|
@@ -39,12 +39,36 @@ function getWorkflowMeta(target) {
|
|
|
39
39
|
}
|
|
40
40
|
__name(getWorkflowMeta, "getWorkflowMeta");
|
|
41
41
|
var DURABLE_STEP_METADATA = Symbol("nestjs-durable:step-handler");
|
|
42
|
-
function
|
|
43
|
-
|
|
42
|
+
function stepConfigFrom(options) {
|
|
43
|
+
const config = {
|
|
44
|
+
retries: options.retries,
|
|
45
|
+
backoff: options.backoff,
|
|
46
|
+
backoffMs: options.backoffMs,
|
|
47
|
+
backoffMaxMs: options.backoffMaxMs,
|
|
48
|
+
jitter: options.jitter,
|
|
49
|
+
timeoutMs: options.timeoutMs
|
|
50
|
+
};
|
|
51
|
+
const hasAnyField = Object.values(config).some((value) => value !== void 0);
|
|
52
|
+
return hasAnyField ? config : void 0;
|
|
53
|
+
}
|
|
54
|
+
__name(stepConfigFrom, "stepConfigFrom");
|
|
55
|
+
function Step(nameOrOptions) {
|
|
56
|
+
return (target, propertyKey, descriptor) => {
|
|
57
|
+
const options = typeof nameOrOptions === "string" ? {
|
|
58
|
+
name: nameOrOptions
|
|
59
|
+
} : nameOrOptions ?? {};
|
|
60
|
+
const derivedName = options.name ?? `${target.constructor.name}.${String(propertyKey)}`;
|
|
44
61
|
const meta = {
|
|
45
|
-
name
|
|
62
|
+
name: derivedName,
|
|
63
|
+
input: options.input,
|
|
64
|
+
output: options.output
|
|
46
65
|
};
|
|
47
66
|
Reflect.defineMetadata(DURABLE_STEP_METADATA, meta, descriptor.value);
|
|
67
|
+
descriptor.value[DURABLE_STEP_NAME] = derivedName;
|
|
68
|
+
const config = stepConfigFrom(options);
|
|
69
|
+
if (config !== void 0) {
|
|
70
|
+
descriptor.value[DURABLE_STEP_CONFIG] = config;
|
|
71
|
+
}
|
|
48
72
|
return descriptor;
|
|
49
73
|
};
|
|
50
74
|
}
|
|
@@ -67,7 +91,7 @@ function isDeadLetterHandler(method) {
|
|
|
67
91
|
}
|
|
68
92
|
__name(isDeadLetterHandler, "isDeadLetterHandler");
|
|
69
93
|
var ON_EVENT_METADATA = Symbol("nestjs-durable:on-event");
|
|
70
|
-
function
|
|
94
|
+
function OnDurableEvent(...events) {
|
|
71
95
|
return (target) => {
|
|
72
96
|
const existing = Reflect.getMetadata(ON_EVENT_METADATA, target) ?? [];
|
|
73
97
|
Reflect.defineMetadata(ON_EVENT_METADATA, [
|
|
@@ -76,7 +100,8 @@ function OnEvent(...events) {
|
|
|
76
100
|
], target);
|
|
77
101
|
};
|
|
78
102
|
}
|
|
79
|
-
__name(
|
|
103
|
+
__name(OnDurableEvent, "OnDurableEvent");
|
|
104
|
+
var OnEvent = OnDurableEvent;
|
|
80
105
|
function getOnEvents(meta, target) {
|
|
81
106
|
const fromDecorator = Reflect.getMetadata(ON_EVENT_METADATA, target) ?? [];
|
|
82
107
|
return [
|
|
@@ -88,10 +113,106 @@ function getOnEvents(meta, target) {
|
|
|
88
113
|
}
|
|
89
114
|
__name(getOnEvents, "getOnEvents");
|
|
90
115
|
|
|
116
|
+
// src/durable-start-client.ts
|
|
117
|
+
import { startRun } from "@dudousxd/durable-worker";
|
|
118
|
+
import { workflowName } from "@dudousxd/nestjs-durable-core";
|
|
119
|
+
import { Injectable } from "@nestjs/common";
|
|
120
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
121
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
122
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
123
|
+
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;
|
|
124
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
125
|
+
}
|
|
126
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
127
|
+
function _ts_metadata(k, v) {
|
|
128
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
129
|
+
}
|
|
130
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
131
|
+
var DurableStartClient = class {
|
|
132
|
+
static {
|
|
133
|
+
__name(this, "DurableStartClient");
|
|
134
|
+
}
|
|
135
|
+
options;
|
|
136
|
+
deps;
|
|
137
|
+
tenant;
|
|
138
|
+
constructor(options, deps) {
|
|
139
|
+
this.options = options;
|
|
140
|
+
this.deps = deps;
|
|
141
|
+
this.tenant = options.partition ?? "default";
|
|
142
|
+
}
|
|
143
|
+
async start(workflow, input, runId = globalThis.crypto.randomUUID(), opts) {
|
|
144
|
+
const name = workflowName(workflow);
|
|
145
|
+
await startRun(this.options.connection, {
|
|
146
|
+
tenant: this.tenant,
|
|
147
|
+
workflow: name,
|
|
148
|
+
input,
|
|
149
|
+
runId,
|
|
150
|
+
// Option B: DO NOT pass `namespace` — the start-run queue stays the shared
|
|
151
|
+
// `durable-start-run` the operator consumes; tenant rides only as message data.
|
|
152
|
+
...this.options.prefix !== void 0 ? {
|
|
153
|
+
prefix: this.options.prefix
|
|
154
|
+
} : {},
|
|
155
|
+
...opts?.tags !== void 0 ? {
|
|
156
|
+
tags: opts.tags
|
|
157
|
+
} : {},
|
|
158
|
+
...opts?.searchAttributes !== void 0 ? {
|
|
159
|
+
searchAttributes: opts.searchAttributes
|
|
160
|
+
} : {},
|
|
161
|
+
...this.deps !== void 0 ? {
|
|
162
|
+
deps: this.deps
|
|
163
|
+
} : {}
|
|
164
|
+
});
|
|
165
|
+
return {
|
|
166
|
+
runId,
|
|
167
|
+
status: "pending"
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
cancel(_runId) {
|
|
171
|
+
return tenantUnsupported("cancel");
|
|
172
|
+
}
|
|
173
|
+
deleteRun(_runId) {
|
|
174
|
+
return tenantUnsupported("deleteRun");
|
|
175
|
+
}
|
|
176
|
+
// — everything below rejects: a tenant worker holds no store/driver, only the start channel. —
|
|
177
|
+
// The remaining WorkflowEngine surface WorkflowService delegates to (resume/waitForRun/signal/
|
|
178
|
+
// signalWithStart/publishEvent) all need the store or driver a tenant does not have. A tenant only
|
|
179
|
+
// ever calls `start`; these exist so a mistaken call fails with a CLEAR, named tenant error instead
|
|
180
|
+
// of a cryptic `this.engine.X is not a function` — the facade is honest about what it cannot do.
|
|
181
|
+
// Params mirror the WorkflowEngine surface being faced; every method rejects without reading them.
|
|
182
|
+
resume(_runId) {
|
|
183
|
+
return tenantUnsupported("resume");
|
|
184
|
+
}
|
|
185
|
+
waitForRun(_runId, _opts) {
|
|
186
|
+
return tenantUnsupported("waitForRun");
|
|
187
|
+
}
|
|
188
|
+
signal(_token, _payload) {
|
|
189
|
+
return tenantUnsupported("signal");
|
|
190
|
+
}
|
|
191
|
+
signalWithStart(_workflow, _input, _runId, _signal, _opts) {
|
|
192
|
+
return tenantUnsupported("signalWithStart");
|
|
193
|
+
}
|
|
194
|
+
publishEvent(_name, _payload, _opts) {
|
|
195
|
+
return tenantUnsupported("publishEvent");
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
DurableStartClient = _ts_decorate([
|
|
199
|
+
Injectable(),
|
|
200
|
+
_ts_metadata("design:type", Function),
|
|
201
|
+
_ts_metadata("design:paramtypes", [
|
|
202
|
+
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions,
|
|
203
|
+
typeof StartRunDeps === "undefined" ? Object : StartRunDeps
|
|
204
|
+
])
|
|
205
|
+
], DurableStartClient);
|
|
206
|
+
function tenantUnsupported(method) {
|
|
207
|
+
return Promise.reject(new Error(`${method}() is not available on a tenant worker (no store). Use the control plane for it.`));
|
|
208
|
+
}
|
|
209
|
+
__name(tenantUnsupported, "tenantUnsupported");
|
|
210
|
+
|
|
91
211
|
// src/durable-worker.module.ts
|
|
92
212
|
import { DurableWorkerRuntime, runRedisWorker as defaultRunRedisWorker } from "@dudousxd/durable-worker";
|
|
93
|
-
import {
|
|
94
|
-
import {
|
|
213
|
+
import { DURABLE_OPTIONS_CANONICAL } from "@dudousxd/nestjs-durable-core";
|
|
214
|
+
import { Inject, Injectable as Injectable2 } from "@nestjs/common";
|
|
215
|
+
import { DiscoveryService, MetadataScanner } from "@nestjs/core";
|
|
95
216
|
|
|
96
217
|
// src/discovery-helpers.ts
|
|
97
218
|
function scanWorkflows(discovery, register) {
|
|
@@ -118,7 +239,12 @@ function scanSteps(discovery, scanner, register) {
|
|
|
118
239
|
if (typeof method !== "function") continue;
|
|
119
240
|
const meta = getDurableStepMeta(method);
|
|
120
241
|
if (!meta) continue;
|
|
121
|
-
const
|
|
242
|
+
const boundMethod = method;
|
|
243
|
+
const handler = /* @__PURE__ */ __name(async (input, log) => {
|
|
244
|
+
const validInput = meta.input ? meta.input.parse(input) : input;
|
|
245
|
+
const output = await boundMethod.call(instance, validInput, log);
|
|
246
|
+
return meta.output ? meta.output.parse(output) : output;
|
|
247
|
+
}, "handler");
|
|
122
248
|
register(meta, handler);
|
|
123
249
|
}
|
|
124
250
|
}
|
|
@@ -126,46 +252,54 @@ function scanSteps(discovery, scanner, register) {
|
|
|
126
252
|
__name(scanSteps, "scanSteps");
|
|
127
253
|
|
|
128
254
|
// src/durable-worker.module.ts
|
|
129
|
-
function
|
|
255
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
130
256
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
131
257
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
132
258
|
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;
|
|
133
259
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
134
260
|
}
|
|
135
|
-
__name(
|
|
136
|
-
function
|
|
261
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
262
|
+
function _ts_metadata2(k, v) {
|
|
137
263
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
138
264
|
}
|
|
139
|
-
__name(
|
|
265
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
140
266
|
function _ts_param(paramIndex, decorator) {
|
|
141
267
|
return function(target, key) {
|
|
142
268
|
decorator(target, key, paramIndex);
|
|
143
269
|
};
|
|
144
270
|
}
|
|
145
271
|
__name(_ts_param, "_ts_param");
|
|
146
|
-
var DURABLE_WORKER_OPTIONS = Symbol("nestjs-durable:worker-options");
|
|
147
272
|
var RUN_REDIS_WORKER = Symbol("nestjs-durable:run-redis-worker");
|
|
148
273
|
var DURABLE_WORKER_RUNNERS = Symbol("nestjs-durable:worker-runners");
|
|
274
|
+
function isPureThinWorker(options) {
|
|
275
|
+
return options.store === void 0 && options.connection !== void 0;
|
|
276
|
+
}
|
|
277
|
+
__name(isPureThinWorker, "isPureThinWorker");
|
|
149
278
|
var ThinWorkflowRegistrar = class {
|
|
150
279
|
static {
|
|
151
280
|
__name(this, "ThinWorkflowRegistrar");
|
|
152
281
|
}
|
|
153
282
|
discovery;
|
|
154
283
|
runtime;
|
|
155
|
-
|
|
284
|
+
options;
|
|
285
|
+
constructor(discovery, runtime, options) {
|
|
156
286
|
this.discovery = discovery;
|
|
157
287
|
this.runtime = runtime;
|
|
288
|
+
this.options = options;
|
|
158
289
|
}
|
|
159
290
|
onModuleInit() {
|
|
291
|
+
if (!isPureThinWorker(this.options)) return;
|
|
160
292
|
scanWorkflows(this.discovery, (meta, instance) => this.runtime.registerWorkflow(meta.name, (ctx, input) => instance.run(ctx, input)));
|
|
161
293
|
}
|
|
162
294
|
};
|
|
163
|
-
ThinWorkflowRegistrar =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
295
|
+
ThinWorkflowRegistrar = _ts_decorate2([
|
|
296
|
+
Injectable2(),
|
|
297
|
+
_ts_param(2, Inject(DURABLE_OPTIONS_CANONICAL)),
|
|
298
|
+
_ts_metadata2("design:type", Function),
|
|
299
|
+
_ts_metadata2("design:paramtypes", [
|
|
167
300
|
typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
|
|
168
|
-
typeof DurableWorkerRuntime === "undefined" ? Object : DurableWorkerRuntime
|
|
301
|
+
typeof DurableWorkerRuntime === "undefined" ? Object : DurableWorkerRuntime,
|
|
302
|
+
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
|
|
169
303
|
])
|
|
170
304
|
], ThinWorkflowRegistrar);
|
|
171
305
|
var ThinStepRegistrar = class {
|
|
@@ -175,22 +309,27 @@ var ThinStepRegistrar = class {
|
|
|
175
309
|
discovery;
|
|
176
310
|
metadataScanner;
|
|
177
311
|
runtime;
|
|
178
|
-
|
|
312
|
+
options;
|
|
313
|
+
constructor(discovery, metadataScanner, runtime, options) {
|
|
179
314
|
this.discovery = discovery;
|
|
180
315
|
this.metadataScanner = metadataScanner;
|
|
181
316
|
this.runtime = runtime;
|
|
317
|
+
this.options = options;
|
|
182
318
|
}
|
|
183
319
|
onModuleInit() {
|
|
320
|
+
if (!isPureThinWorker(this.options)) return;
|
|
184
321
|
scanSteps(this.discovery, this.metadataScanner, (meta, handler) => this.runtime.registerStep(meta.name, handler));
|
|
185
322
|
}
|
|
186
323
|
};
|
|
187
|
-
ThinStepRegistrar =
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
324
|
+
ThinStepRegistrar = _ts_decorate2([
|
|
325
|
+
Injectable2(),
|
|
326
|
+
_ts_param(3, Inject(DURABLE_OPTIONS_CANONICAL)),
|
|
327
|
+
_ts_metadata2("design:type", Function),
|
|
328
|
+
_ts_metadata2("design:paramtypes", [
|
|
191
329
|
typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
|
|
192
330
|
typeof MetadataScanner === "undefined" ? Object : MetadataScanner,
|
|
193
|
-
typeof DurableWorkerRuntime === "undefined" ? Object : DurableWorkerRuntime
|
|
331
|
+
typeof DurableWorkerRuntime === "undefined" ? Object : DurableWorkerRuntime,
|
|
332
|
+
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
|
|
194
333
|
])
|
|
195
334
|
], ThinStepRegistrar);
|
|
196
335
|
var ThinWorkerBootstrap = class {
|
|
@@ -209,113 +348,139 @@ var ThinWorkerBootstrap = class {
|
|
|
209
348
|
this.runnersSink = runnersSink;
|
|
210
349
|
}
|
|
211
350
|
async onApplicationBootstrap() {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
351
|
+
const options = this.options;
|
|
352
|
+
if (!isPureThinWorker(options) || options.connection === void 0) return;
|
|
353
|
+
const handle = await this.runRedisWorker({
|
|
354
|
+
runtime: this.runtime,
|
|
355
|
+
connection: options.connection,
|
|
356
|
+
...options.partition !== void 0 ? {
|
|
357
|
+
partition: options.partition
|
|
358
|
+
} : {},
|
|
359
|
+
...options.prefix !== void 0 ? {
|
|
360
|
+
prefix: options.prefix
|
|
361
|
+
} : {},
|
|
362
|
+
...options.instanceId !== void 0 ? {
|
|
363
|
+
instanceId: options.instanceId
|
|
364
|
+
} : {},
|
|
365
|
+
...options.concurrency !== void 0 ? {
|
|
366
|
+
concurrency: options.concurrency
|
|
367
|
+
} : {}
|
|
368
|
+
});
|
|
369
|
+
this.runners.push(handle);
|
|
370
|
+
this.runnersSink.push(handle);
|
|
230
371
|
}
|
|
231
372
|
async onApplicationShutdown() {
|
|
232
373
|
await Promise.allSettled(this.runners.map((h) => h.close()));
|
|
233
374
|
}
|
|
234
375
|
};
|
|
235
|
-
ThinWorkerBootstrap =
|
|
236
|
-
|
|
237
|
-
_ts_param(1, Inject(
|
|
376
|
+
ThinWorkerBootstrap = _ts_decorate2([
|
|
377
|
+
Injectable2(),
|
|
378
|
+
_ts_param(1, Inject(DURABLE_OPTIONS_CANONICAL)),
|
|
238
379
|
_ts_param(2, Inject(RUN_REDIS_WORKER)),
|
|
239
380
|
_ts_param(3, Inject(DURABLE_WORKER_RUNNERS)),
|
|
240
|
-
|
|
241
|
-
|
|
381
|
+
_ts_metadata2("design:type", Function),
|
|
382
|
+
_ts_metadata2("design:paramtypes", [
|
|
242
383
|
typeof DurableWorkerRuntime === "undefined" ? Object : DurableWorkerRuntime,
|
|
243
|
-
typeof
|
|
384
|
+
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions,
|
|
244
385
|
typeof RunRedisWorkerFn === "undefined" ? Object : RunRedisWorkerFn,
|
|
245
386
|
Array
|
|
246
387
|
])
|
|
247
388
|
], ThinWorkerBootstrap);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
inject:
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
static build(optionsProvider) {
|
|
266
|
-
return {
|
|
267
|
-
module: _DurableWorkerModule,
|
|
268
|
-
imports: [
|
|
269
|
-
DiscoveryModule
|
|
270
|
-
],
|
|
271
|
-
providers: [
|
|
272
|
-
optionsProvider,
|
|
273
|
-
{
|
|
274
|
-
provide: DurableWorkerRuntime,
|
|
275
|
-
useFactory: /* @__PURE__ */ __name(() => new DurableWorkerRuntime(), "useFactory")
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
provide: RUN_REDIS_WORKER,
|
|
279
|
-
useValue: defaultRunRedisWorker
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
provide: DURABLE_WORKER_RUNNERS,
|
|
283
|
-
useValue: []
|
|
284
|
-
},
|
|
285
|
-
ThinWorkflowRegistrar,
|
|
286
|
-
ThinStepRegistrar,
|
|
287
|
-
ThinWorkerBootstrap
|
|
288
|
-
],
|
|
289
|
-
exports: [
|
|
290
|
-
DurableWorkerRuntime
|
|
389
|
+
function thinWorkerProviders() {
|
|
390
|
+
return [
|
|
391
|
+
{
|
|
392
|
+
provide: DurableWorkerRuntime,
|
|
393
|
+
// The runtime's `WorkflowWorker` falls back to its own `group` ctor param as the WORKFLOW's
|
|
394
|
+
// `workflowPartition` for any `ctx.step` call (see `workflow-context.ts`'s `resolveCallGroup`)
|
|
395
|
+
// — that fallback MUST equal this module's own `partition`, or a dispatched step's decision
|
|
396
|
+
// carries a mismatched token and the engine dispatches it to a queue nothing here subscribes
|
|
397
|
+
// to. Explicit `''` (never
|
|
398
|
+
// `undefined`) so it does NOT fall through to `WorkflowWorker`'s unrelated `'workflows'`
|
|
399
|
+
// default parameter.
|
|
400
|
+
useFactory: /* @__PURE__ */ __name((options) => new DurableWorkerRuntime({
|
|
401
|
+
workflowGroup: options.partition ?? ""
|
|
402
|
+
}), "useFactory"),
|
|
403
|
+
inject: [
|
|
404
|
+
DURABLE_OPTIONS_CANONICAL
|
|
291
405
|
]
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
provide: RUN_REDIS_WORKER,
|
|
409
|
+
useValue: defaultRunRedisWorker
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
provide: DURABLE_WORKER_RUNNERS,
|
|
413
|
+
useValue: []
|
|
414
|
+
},
|
|
415
|
+
ThinWorkflowRegistrar,
|
|
416
|
+
ThinStepRegistrar,
|
|
417
|
+
ThinWorkerBootstrap
|
|
418
|
+
];
|
|
419
|
+
}
|
|
420
|
+
__name(thinWorkerProviders, "thinWorkerProviders");
|
|
421
|
+
function tenantGatewayUnavailable(method) {
|
|
422
|
+
return Promise.reject(new Error(`RunGateway.${method}() is not available \u2014 pass \`transport\` to use RunGateway.`));
|
|
423
|
+
}
|
|
424
|
+
__name(tenantGatewayUnavailable, "tenantGatewayUnavailable");
|
|
425
|
+
function unavailableRunGateway() {
|
|
426
|
+
return {
|
|
427
|
+
getRunDetail(_runId) {
|
|
428
|
+
return tenantGatewayUnavailable("getRunDetail");
|
|
429
|
+
},
|
|
430
|
+
listRuns(_query) {
|
|
431
|
+
return tenantGatewayUnavailable("listRuns");
|
|
432
|
+
},
|
|
433
|
+
cancel(_runId) {
|
|
434
|
+
return tenantGatewayUnavailable("cancel");
|
|
435
|
+
},
|
|
436
|
+
retry(_runId) {
|
|
437
|
+
return tenantGatewayUnavailable("retry");
|
|
438
|
+
},
|
|
439
|
+
continue(_runId) {
|
|
440
|
+
return tenantGatewayUnavailable("continue");
|
|
441
|
+
},
|
|
442
|
+
retryWithInput(_runId, _input) {
|
|
443
|
+
return tenantGatewayUnavailable("retryWithInput");
|
|
444
|
+
},
|
|
445
|
+
subscribe(_runId, _onEvent) {
|
|
446
|
+
throw new Error("RunGateway.subscribe() is not available \u2014 pass `transport` to use RunGateway.");
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
__name(unavailableRunGateway, "unavailableRunGateway");
|
|
298
451
|
|
|
299
452
|
// src/durable.module.ts
|
|
300
|
-
import { DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL as
|
|
301
|
-
import {
|
|
302
|
-
import { DiscoveryModule
|
|
453
|
+
import { DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL7, STATE_STORE, STATE_STORE_CANONICAL as STATE_STORE_CANONICAL4, TRANSPORT, TRANSPORT_CANONICAL as TRANSPORT_CANONICAL3, WorkflowEngine as WorkflowEngine6 } from "@dudousxd/nestjs-durable-core";
|
|
454
|
+
import { Inject as Inject8, Injectable as Injectable12, Module } from "@nestjs/common";
|
|
455
|
+
import { DiscoveryModule, ModuleRef } from "@nestjs/core";
|
|
303
456
|
|
|
304
457
|
// src/durable-step.registrar.ts
|
|
305
|
-
import { DURABLE_OPTIONS_CANONICAL, TRANSPORT_CANONICAL } from "@dudousxd/nestjs-durable-core";
|
|
306
|
-
import { Inject as Inject2, Injectable as
|
|
458
|
+
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL2, TRANSPORT_CANONICAL } from "@dudousxd/nestjs-durable-core";
|
|
459
|
+
import { Inject as Inject2, Injectable as Injectable3 } from "@nestjs/common";
|
|
307
460
|
import { DiscoveryService as DiscoveryService2, MetadataScanner as MetadataScanner2 } from "@nestjs/core";
|
|
308
|
-
|
|
461
|
+
|
|
462
|
+
// src/role.ts
|
|
463
|
+
function isOperatorRole(options) {
|
|
464
|
+
return options.store !== void 0;
|
|
465
|
+
}
|
|
466
|
+
__name(isOperatorRole, "isOperatorRole");
|
|
467
|
+
function isDrivingOperator(options) {
|
|
468
|
+
return isOperatorRole(options) && options.drive !== false;
|
|
469
|
+
}
|
|
470
|
+
__name(isDrivingOperator, "isDrivingOperator");
|
|
471
|
+
|
|
472
|
+
// src/durable-step.registrar.ts
|
|
473
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
309
474
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
310
475
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
311
476
|
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;
|
|
312
477
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
313
478
|
}
|
|
314
|
-
__name(
|
|
315
|
-
function
|
|
479
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
480
|
+
function _ts_metadata3(k, v) {
|
|
316
481
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
317
482
|
}
|
|
318
|
-
__name(
|
|
483
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
319
484
|
function _ts_param2(paramIndex, decorator) {
|
|
320
485
|
return function(target, key) {
|
|
321
486
|
decorator(target, key, paramIndex);
|
|
@@ -341,18 +506,18 @@ var DurableStepRegistrar = class {
|
|
|
341
506
|
this.options = options;
|
|
342
507
|
}
|
|
343
508
|
onModuleInit() {
|
|
344
|
-
if (this.options
|
|
509
|
+
if (!isDrivingOperator(this.options)) return;
|
|
345
510
|
if (!supportsHandle(this.transport)) return;
|
|
346
511
|
const transport = this.transport;
|
|
347
512
|
scanSteps(this.discovery, this.metadataScanner, (meta, handler) => transport.handle(meta.name, handler));
|
|
348
513
|
}
|
|
349
514
|
};
|
|
350
|
-
DurableStepRegistrar =
|
|
351
|
-
|
|
515
|
+
DurableStepRegistrar = _ts_decorate3([
|
|
516
|
+
Injectable3(),
|
|
352
517
|
_ts_param2(2, Inject2(TRANSPORT_CANONICAL)),
|
|
353
|
-
_ts_param2(3, Inject2(
|
|
354
|
-
|
|
355
|
-
|
|
518
|
+
_ts_param2(3, Inject2(DURABLE_OPTIONS_CANONICAL2)),
|
|
519
|
+
_ts_metadata3("design:type", Function),
|
|
520
|
+
_ts_metadata3("design:paramtypes", [
|
|
356
521
|
typeof DiscoveryService2 === "undefined" ? Object : DiscoveryService2,
|
|
357
522
|
typeof MetadataScanner2 === "undefined" ? Object : MetadataScanner2,
|
|
358
523
|
Object,
|
|
@@ -362,19 +527,19 @@ DurableStepRegistrar = _ts_decorate2([
|
|
|
362
527
|
|
|
363
528
|
// src/entity.ts
|
|
364
529
|
import { WorkflowEngine } from "@dudousxd/nestjs-durable-core";
|
|
365
|
-
import { Injectable as
|
|
530
|
+
import { Injectable as Injectable4 } from "@nestjs/common";
|
|
366
531
|
import "reflect-metadata";
|
|
367
|
-
function
|
|
532
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
368
533
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
369
534
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
370
535
|
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;
|
|
371
536
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
372
537
|
}
|
|
373
|
-
__name(
|
|
374
|
-
function
|
|
538
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
539
|
+
function _ts_metadata4(k, v) {
|
|
375
540
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
376
541
|
}
|
|
377
|
-
__name(
|
|
542
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
378
543
|
var ENTITY_METADATA = Symbol("nestjs-durable:entity");
|
|
379
544
|
var ENTITY_ON_METADATA = Symbol("nestjs-durable:entity-on");
|
|
380
545
|
function Entity(options) {
|
|
@@ -431,49 +596,54 @@ var EntityService = class {
|
|
|
431
596
|
return this.engine.getEntityState(name, key);
|
|
432
597
|
}
|
|
433
598
|
};
|
|
434
|
-
EntityService =
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
599
|
+
EntityService = _ts_decorate4([
|
|
600
|
+
Injectable4(),
|
|
601
|
+
_ts_metadata4("design:type", Function),
|
|
602
|
+
_ts_metadata4("design:paramtypes", [
|
|
438
603
|
typeof WorkflowEngine === "undefined" ? Object : WorkflowEngine
|
|
439
604
|
])
|
|
440
605
|
], EntityService);
|
|
441
606
|
|
|
442
607
|
// src/in-app-worker.ts
|
|
443
608
|
import { DurableWorkerRuntime as DurableWorkerRuntime2, runRedisWorker as defaultRunRedisWorker2 } from "@dudousxd/durable-worker";
|
|
444
|
-
import { DURABLE_OPTIONS_CANONICAL as
|
|
445
|
-
import { Inject as Inject3, Injectable as
|
|
609
|
+
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL3, TRANSPORT_CANONICAL as TRANSPORT_CANONICAL2 } from "@dudousxd/nestjs-durable-core";
|
|
610
|
+
import { Inject as Inject3, Injectable as Injectable5 } from "@nestjs/common";
|
|
446
611
|
import { DiscoveryService as DiscoveryService3, MetadataScanner as MetadataScanner3 } from "@nestjs/core";
|
|
447
|
-
function
|
|
612
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
448
613
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
449
614
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
450
615
|
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;
|
|
451
616
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
452
617
|
}
|
|
453
|
-
__name(
|
|
454
|
-
function
|
|
618
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
619
|
+
function _ts_metadata5(k, v) {
|
|
455
620
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
456
621
|
}
|
|
457
|
-
__name(
|
|
622
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
458
623
|
function _ts_param3(paramIndex, decorator) {
|
|
459
624
|
return function(target, key) {
|
|
460
625
|
decorator(target, key, paramIndex);
|
|
461
626
|
};
|
|
462
627
|
}
|
|
463
628
|
__name(_ts_param3, "_ts_param");
|
|
464
|
-
var IN_APP_WORKER_OPTIONS = Symbol("nestjs-durable:in-app-worker-options");
|
|
465
629
|
var IN_APP_WORKER_BINDING = Symbol("nestjs-durable:in-app-worker-binding");
|
|
466
630
|
var IN_APP_WORKER_RUNTIME = Symbol("nestjs-durable:in-app-worker-runtime");
|
|
467
631
|
var IN_APP_RUN_REDIS_WORKER = Symbol("nestjs-durable:in-app-run-redis-worker");
|
|
468
632
|
var IN_APP_WORKER_RUNNERS = Symbol("nestjs-durable:in-app-worker-runners");
|
|
633
|
+
function isCoLocatedWorker(options) {
|
|
634
|
+
return options.store !== void 0 && options.connection !== void 0;
|
|
635
|
+
}
|
|
636
|
+
__name(isCoLocatedWorker, "isCoLocatedWorker");
|
|
469
637
|
function inAppWorkerBinding(transport, options) {
|
|
470
|
-
if (!options) return null;
|
|
638
|
+
if (!isCoLocatedWorker(options)) return null;
|
|
471
639
|
if (!transport?.dispatchWorkflowTask || !transport.onDecision) {
|
|
472
|
-
throw new Error("
|
|
640
|
+
throw new Error("a co-located worker (store + connection) requires a transport that carries workflow tasks (dispatchWorkflowTask + onDecision), e.g. BullMQTransport. An in-process transport cannot serve a group-served workflow.");
|
|
473
641
|
}
|
|
474
642
|
return {
|
|
475
|
-
|
|
476
|
-
|
|
643
|
+
transport,
|
|
644
|
+
...options.partition !== void 0 ? {
|
|
645
|
+
partition: options.partition
|
|
646
|
+
} : {}
|
|
477
647
|
};
|
|
478
648
|
}
|
|
479
649
|
__name(inAppWorkerBinding, "inAppWorkerBinding");
|
|
@@ -497,24 +667,27 @@ var InAppWorkerBootstrap = class {
|
|
|
497
667
|
this.runnersSink = runnersSink;
|
|
498
668
|
}
|
|
499
669
|
onModuleInit() {
|
|
500
|
-
if (!this.options) return;
|
|
670
|
+
if (!isCoLocatedWorker(this.options)) return;
|
|
501
671
|
scanWorkflows(this.discovery, (meta, instance) => this.runtime.registerWorkflow(meta.name, (ctx, input) => instance.run(ctx, input)));
|
|
502
672
|
scanSteps(this.discovery, this.metadataScanner, (meta, handler) => this.runtime.registerStep(meta.name, handler));
|
|
503
673
|
}
|
|
504
674
|
async onApplicationBootstrap() {
|
|
505
|
-
|
|
675
|
+
const options = this.options;
|
|
676
|
+
if (!isCoLocatedWorker(options) || options.connection === void 0) return;
|
|
506
677
|
const handle = await this.runRedisWorker({
|
|
507
678
|
runtime: this.runtime,
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
679
|
+
connection: options.connection,
|
|
680
|
+
...options.partition !== void 0 ? {
|
|
681
|
+
partition: options.partition
|
|
682
|
+
} : {},
|
|
683
|
+
...options.prefix !== void 0 ? {
|
|
684
|
+
prefix: options.prefix
|
|
512
685
|
} : {},
|
|
513
|
-
...
|
|
514
|
-
instanceId:
|
|
686
|
+
...options.instanceId !== void 0 ? {
|
|
687
|
+
instanceId: options.instanceId
|
|
515
688
|
} : {},
|
|
516
|
-
...
|
|
517
|
-
concurrency:
|
|
689
|
+
...options.concurrency !== void 0 ? {
|
|
690
|
+
concurrency: options.concurrency
|
|
518
691
|
} : {}
|
|
519
692
|
});
|
|
520
693
|
this.runners.push(handle);
|
|
@@ -524,17 +697,17 @@ var InAppWorkerBootstrap = class {
|
|
|
524
697
|
await Promise.allSettled(this.runners.map((handle) => handle.close()));
|
|
525
698
|
}
|
|
526
699
|
};
|
|
527
|
-
InAppWorkerBootstrap =
|
|
528
|
-
|
|
529
|
-
_ts_param3(2, Inject3(
|
|
700
|
+
InAppWorkerBootstrap = _ts_decorate5([
|
|
701
|
+
Injectable5(),
|
|
702
|
+
_ts_param3(2, Inject3(DURABLE_OPTIONS_CANONICAL3)),
|
|
530
703
|
_ts_param3(3, Inject3(IN_APP_WORKER_RUNTIME)),
|
|
531
704
|
_ts_param3(4, Inject3(IN_APP_RUN_REDIS_WORKER)),
|
|
532
705
|
_ts_param3(5, Inject3(IN_APP_WORKER_RUNNERS)),
|
|
533
|
-
|
|
534
|
-
|
|
706
|
+
_ts_metadata5("design:type", Function),
|
|
707
|
+
_ts_metadata5("design:paramtypes", [
|
|
535
708
|
typeof DiscoveryService3 === "undefined" ? Object : DiscoveryService3,
|
|
536
709
|
typeof MetadataScanner3 === "undefined" ? Object : MetadataScanner3,
|
|
537
|
-
Object,
|
|
710
|
+
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions,
|
|
538
711
|
typeof DurableWorkerRuntime2 === "undefined" ? Object : DurableWorkerRuntime2,
|
|
539
712
|
typeof RunRedisWorkerFn === "undefined" ? Object : RunRedisWorkerFn,
|
|
540
713
|
Array
|
|
@@ -544,23 +717,28 @@ function inAppWorkerProviders() {
|
|
|
544
717
|
return [
|
|
545
718
|
{
|
|
546
719
|
provide: IN_APP_WORKER_BINDING,
|
|
547
|
-
useFactory: /* @__PURE__ */ __name((transport, options) => inAppWorkerBinding(transport, options
|
|
720
|
+
useFactory: /* @__PURE__ */ __name((transport, options) => inAppWorkerBinding(transport, options), "useFactory"),
|
|
548
721
|
inject: [
|
|
549
722
|
TRANSPORT_CANONICAL2,
|
|
550
|
-
|
|
723
|
+
DURABLE_OPTIONS_CANONICAL3
|
|
551
724
|
]
|
|
552
725
|
},
|
|
553
726
|
{
|
|
554
|
-
provide:
|
|
555
|
-
|
|
727
|
+
provide: IN_APP_WORKER_RUNTIME,
|
|
728
|
+
// The runtime's `WorkflowWorker` uses its `group` ctor param as the WORKFLOW's
|
|
729
|
+
// `workflowPartition` for any `ctx.step` call (see `workflow-context.ts`'s `resolveCallGroup`)
|
|
730
|
+
// — that fallback MUST equal this app's own `partition`, or a dispatched step's decision
|
|
731
|
+
// carries a mismatched token and the engine dispatches it to a queue nothing here subscribes
|
|
732
|
+
// to. Explicit `''` (never
|
|
733
|
+
// `undefined`) so it does NOT fall through to `WorkflowWorker`'s unrelated `'workflows'`
|
|
734
|
+
// default parameter.
|
|
735
|
+
useFactory: /* @__PURE__ */ __name((options) => new DurableWorkerRuntime2({
|
|
736
|
+
workflowGroup: options.partition ?? ""
|
|
737
|
+
}), "useFactory"),
|
|
556
738
|
inject: [
|
|
557
|
-
|
|
739
|
+
DURABLE_OPTIONS_CANONICAL3
|
|
558
740
|
]
|
|
559
741
|
},
|
|
560
|
-
{
|
|
561
|
-
provide: IN_APP_WORKER_RUNTIME,
|
|
562
|
-
useFactory: /* @__PURE__ */ __name(() => new DurableWorkerRuntime2(), "useFactory")
|
|
563
|
-
},
|
|
564
742
|
{
|
|
565
743
|
provide: IN_APP_RUN_REDIS_WORKER,
|
|
566
744
|
useValue: defaultRunRedisWorker2
|
|
@@ -574,20 +752,142 @@ function inAppWorkerProviders() {
|
|
|
574
752
|
}
|
|
575
753
|
__name(inAppWorkerProviders, "inAppWorkerProviders");
|
|
576
754
|
|
|
755
|
+
// src/proxy-run-gateway.ts
|
|
756
|
+
import { Injectable as Injectable6 } from "@nestjs/common";
|
|
757
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
758
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
759
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
760
|
+
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;
|
|
761
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
762
|
+
}
|
|
763
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
764
|
+
function _ts_metadata6(k, v) {
|
|
765
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
766
|
+
}
|
|
767
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
768
|
+
var ProxyRunGateway = class {
|
|
769
|
+
static {
|
|
770
|
+
__name(this, "ProxyRunGateway");
|
|
771
|
+
}
|
|
772
|
+
transport;
|
|
773
|
+
tenant;
|
|
774
|
+
timeoutMs;
|
|
775
|
+
pending = /* @__PURE__ */ new Map();
|
|
776
|
+
constructor(transport, tenant, timeoutMs = 1e4) {
|
|
777
|
+
this.transport = transport;
|
|
778
|
+
this.tenant = tenant;
|
|
779
|
+
this.timeoutMs = timeoutMs;
|
|
780
|
+
this.transport.onRunReply?.((reply) => this.handleReply(reply));
|
|
781
|
+
}
|
|
782
|
+
handleReply(reply) {
|
|
783
|
+
const pending = this.pending.get(reply.requestId);
|
|
784
|
+
if (!pending) return;
|
|
785
|
+
clearTimeout(pending.timer);
|
|
786
|
+
this.pending.delete(reply.requestId);
|
|
787
|
+
if (reply.result.ok) {
|
|
788
|
+
pending.resolve(reply.result.data);
|
|
789
|
+
} else {
|
|
790
|
+
pending.reject(new Error(reply.result.error.message));
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
request(body) {
|
|
794
|
+
return new Promise((resolve, reject) => {
|
|
795
|
+
const requestId = globalThis.crypto.randomUUID();
|
|
796
|
+
const timer = setTimeout(() => {
|
|
797
|
+
this.pending.delete(requestId);
|
|
798
|
+
reject(new Error(`control plane did not respond to ${body.kind} within ${this.timeoutMs}ms`));
|
|
799
|
+
}, this.timeoutMs);
|
|
800
|
+
this.pending.set(requestId, {
|
|
801
|
+
resolve,
|
|
802
|
+
reject,
|
|
803
|
+
timer
|
|
804
|
+
});
|
|
805
|
+
this.transport.dispatchRunRequest?.({
|
|
806
|
+
requestId,
|
|
807
|
+
tenant: this.tenant,
|
|
808
|
+
body
|
|
809
|
+
}).catch((error) => {
|
|
810
|
+
const stillPending = this.pending.get(requestId);
|
|
811
|
+
if (!stillPending) return;
|
|
812
|
+
clearTimeout(stillPending.timer);
|
|
813
|
+
this.pending.delete(requestId);
|
|
814
|
+
stillPending.reject(error instanceof Error ? error : new Error(String(error)));
|
|
815
|
+
});
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
getRunDetail(runId) {
|
|
819
|
+
return this.request({
|
|
820
|
+
kind: "getRunDetail",
|
|
821
|
+
runId
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
listRuns(query) {
|
|
825
|
+
return this.request({
|
|
826
|
+
kind: "listRuns",
|
|
827
|
+
query
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
cancel(runId, opts) {
|
|
831
|
+
return this.request(opts === void 0 ? {
|
|
832
|
+
kind: "cancel",
|
|
833
|
+
runId
|
|
834
|
+
} : {
|
|
835
|
+
kind: "cancel",
|
|
836
|
+
runId,
|
|
837
|
+
opts
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
retry(runId) {
|
|
841
|
+
return this.request({
|
|
842
|
+
kind: "retry",
|
|
843
|
+
runId
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
continue(runId) {
|
|
847
|
+
return this.request({
|
|
848
|
+
kind: "continue",
|
|
849
|
+
runId
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
retryWithInput(runId, input) {
|
|
853
|
+
return this.request({
|
|
854
|
+
kind: "retryWithInput",
|
|
855
|
+
runId,
|
|
856
|
+
input
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
subscribe(runId, onEvent) {
|
|
860
|
+
const unsubscribe = this.transport.onTenantEvent?.(this.tenant, (evt) => {
|
|
861
|
+
if (evt.event.runId === runId) onEvent(evt.event);
|
|
862
|
+
});
|
|
863
|
+
return unsubscribe ?? (() => {
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
};
|
|
867
|
+
ProxyRunGateway = _ts_decorate6([
|
|
868
|
+
Injectable6(),
|
|
869
|
+
_ts_metadata6("design:type", Function),
|
|
870
|
+
_ts_metadata6("design:paramtypes", [
|
|
871
|
+
typeof Transport === "undefined" ? Object : Transport,
|
|
872
|
+
String,
|
|
873
|
+
void 0
|
|
874
|
+
])
|
|
875
|
+
], ProxyRunGateway);
|
|
876
|
+
|
|
577
877
|
// src/retention-poller.ts
|
|
578
|
-
import { DURABLE_OPTIONS_CANONICAL as
|
|
579
|
-
import { Inject as Inject4, Injectable as
|
|
580
|
-
function
|
|
878
|
+
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL4, STATE_STORE_CANONICAL, TERMINAL_RUN_STATUSES, parseDuration } from "@dudousxd/nestjs-durable-core";
|
|
879
|
+
import { Inject as Inject4, Injectable as Injectable7 } from "@nestjs/common";
|
|
880
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
581
881
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
582
882
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
583
883
|
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;
|
|
584
884
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
585
885
|
}
|
|
586
|
-
__name(
|
|
587
|
-
function
|
|
886
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
887
|
+
function _ts_metadata7(k, v) {
|
|
588
888
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
589
889
|
}
|
|
590
|
-
__name(
|
|
890
|
+
__name(_ts_metadata7, "_ts_metadata");
|
|
591
891
|
function _ts_param4(paramIndex, decorator) {
|
|
592
892
|
return function(target, key) {
|
|
593
893
|
decorator(target, key, paramIndex);
|
|
@@ -631,12 +931,19 @@ var RetentionPoller = class {
|
|
|
631
931
|
this.store = store;
|
|
632
932
|
this.options = options;
|
|
633
933
|
}
|
|
934
|
+
/** Non-null once past the `isDrivingOperator` guard (which requires `options.store` to be set). */
|
|
935
|
+
requireStore() {
|
|
936
|
+
if (!this.store) {
|
|
937
|
+
throw new Error("unreachable: STATE_STORE_CANONICAL must resolve a store when options.store is set");
|
|
938
|
+
}
|
|
939
|
+
return this.store;
|
|
940
|
+
}
|
|
634
941
|
async onApplicationBootstrap() {
|
|
635
|
-
if (this.options
|
|
942
|
+
if (!isDrivingOperator(this.options)) return;
|
|
636
943
|
const retention = this.options.retention;
|
|
637
944
|
if (!retention || retention.policies.length === 0) return;
|
|
638
945
|
validateRetention(retention);
|
|
639
|
-
if (typeof this.
|
|
946
|
+
if (typeof this.requireStore().pruneTerminalRuns !== "function") {
|
|
640
947
|
console.warn("[nestjs-durable] `retention` is configured but the store adapter does not implement pruneTerminalRuns; retention is disabled.");
|
|
641
948
|
return;
|
|
642
949
|
}
|
|
@@ -653,7 +960,8 @@ var RetentionPoller = class {
|
|
|
653
960
|
async sweep() {
|
|
654
961
|
if (this.sweeping) return;
|
|
655
962
|
const retention = this.options.retention;
|
|
656
|
-
const
|
|
963
|
+
const store = this.requireStore();
|
|
964
|
+
const prune = store.pruneTerminalRuns;
|
|
657
965
|
if (!retention || typeof prune !== "function") return;
|
|
658
966
|
this.sweeping = true;
|
|
659
967
|
try {
|
|
@@ -661,7 +969,7 @@ var RetentionPoller = class {
|
|
|
661
969
|
const now = Date.now();
|
|
662
970
|
for (const policy of retention.policies) {
|
|
663
971
|
for (let batch = 0; batch < MAX_BATCHES_PER_POLICY; batch++) {
|
|
664
|
-
const deleted = await prune.call(
|
|
972
|
+
const deleted = await prune.call(store, policy, now, batchSize);
|
|
665
973
|
if (deleted < batchSize) break;
|
|
666
974
|
}
|
|
667
975
|
}
|
|
@@ -670,37 +978,244 @@ var RetentionPoller = class {
|
|
|
670
978
|
}
|
|
671
979
|
}
|
|
672
980
|
};
|
|
673
|
-
RetentionPoller =
|
|
674
|
-
|
|
981
|
+
RetentionPoller = _ts_decorate7([
|
|
982
|
+
Injectable7(),
|
|
675
983
|
_ts_param4(0, Inject4(STATE_STORE_CANONICAL)),
|
|
676
|
-
_ts_param4(1, Inject4(
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
984
|
+
_ts_param4(1, Inject4(DURABLE_OPTIONS_CANONICAL4)),
|
|
985
|
+
_ts_metadata7("design:type", Function),
|
|
986
|
+
_ts_metadata7("design:paramtypes", [
|
|
987
|
+
Object,
|
|
680
988
|
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
|
|
681
989
|
])
|
|
682
990
|
], RetentionPoller);
|
|
683
991
|
|
|
684
|
-
// src/
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
992
|
+
// src/run-request-responder.ts
|
|
993
|
+
var RunRequestResponder = class {
|
|
994
|
+
static {
|
|
995
|
+
__name(this, "RunRequestResponder");
|
|
996
|
+
}
|
|
997
|
+
transport;
|
|
998
|
+
gateway;
|
|
999
|
+
constructor(transport, gateway) {
|
|
1000
|
+
this.transport = transport;
|
|
1001
|
+
this.gateway = gateway;
|
|
1002
|
+
}
|
|
1003
|
+
/** Register the consumer on the transport. Each request is answered independently; a handler
|
|
1004
|
+
* failure never throws back into the transport (errors are captured into an error reply). */
|
|
1005
|
+
start() {
|
|
1006
|
+
this.transport.onRunRequest(async (msg) => {
|
|
1007
|
+
const reply = await this.handle(msg);
|
|
1008
|
+
await this.transport.publishRunReply(reply);
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
async handle(msg) {
|
|
1012
|
+
const { body } = msg;
|
|
1013
|
+
if (body.kind === "listRuns") {
|
|
1014
|
+
const data = await this.gateway.listRuns({
|
|
1015
|
+
...body.query,
|
|
1016
|
+
namespace: msg.tenant
|
|
1017
|
+
});
|
|
1018
|
+
return {
|
|
1019
|
+
requestId: msg.requestId,
|
|
1020
|
+
result: {
|
|
1021
|
+
ok: true,
|
|
1022
|
+
data
|
|
1023
|
+
}
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
const detail = await this.gateway.getRunDetail(body.runId);
|
|
1027
|
+
if (detail && detail.run.namespace !== msg.tenant) {
|
|
1028
|
+
return {
|
|
1029
|
+
requestId: msg.requestId,
|
|
1030
|
+
result: {
|
|
1031
|
+
ok: false,
|
|
1032
|
+
error: {
|
|
1033
|
+
message: "run belongs to another tenant",
|
|
1034
|
+
code: "cross-tenant"
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
if (body.kind === "getRunDetail") {
|
|
1040
|
+
return {
|
|
1041
|
+
requestId: msg.requestId,
|
|
1042
|
+
result: {
|
|
1043
|
+
ok: true,
|
|
1044
|
+
data: detail
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
try {
|
|
1049
|
+
const data = await this.callVerb(body);
|
|
1050
|
+
return {
|
|
1051
|
+
requestId: msg.requestId,
|
|
1052
|
+
result: {
|
|
1053
|
+
ok: true,
|
|
1054
|
+
data
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
} catch (err) {
|
|
1058
|
+
return {
|
|
1059
|
+
requestId: msg.requestId,
|
|
1060
|
+
result: {
|
|
1061
|
+
ok: false,
|
|
1062
|
+
error: {
|
|
1063
|
+
message: err instanceof Error ? err.message : String(err)
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
callVerb(body) {
|
|
1070
|
+
switch (body.kind) {
|
|
1071
|
+
case "cancel":
|
|
1072
|
+
return this.gateway.cancel(body.runId, body.opts);
|
|
1073
|
+
case "retry":
|
|
1074
|
+
return this.gateway.retry(body.runId);
|
|
1075
|
+
case "continue":
|
|
1076
|
+
return this.gateway.continue(body.runId);
|
|
1077
|
+
case "retryWithInput":
|
|
1078
|
+
return this.gateway.retryWithInput(body.runId, body.input);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
// src/store-run-gateway.ts
|
|
1084
|
+
import { STATE_STORE_CANONICAL as STATE_STORE_CANONICAL2, WorkflowEngine as WorkflowEngine2 } from "@dudousxd/nestjs-durable-core";
|
|
1085
|
+
import { Inject as Inject5, Injectable as Injectable8 } from "@nestjs/common";
|
|
1086
|
+
function _ts_decorate8(decorators, target, key, desc) {
|
|
688
1087
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
689
1088
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
690
1089
|
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;
|
|
691
1090
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
692
1091
|
}
|
|
693
|
-
__name(
|
|
694
|
-
function
|
|
1092
|
+
__name(_ts_decorate8, "_ts_decorate");
|
|
1093
|
+
function _ts_metadata8(k, v) {
|
|
695
1094
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
696
1095
|
}
|
|
697
|
-
__name(
|
|
1096
|
+
__name(_ts_metadata8, "_ts_metadata");
|
|
698
1097
|
function _ts_param5(paramIndex, decorator) {
|
|
699
1098
|
return function(target, key) {
|
|
700
1099
|
decorator(target, key, paramIndex);
|
|
701
1100
|
};
|
|
702
1101
|
}
|
|
703
1102
|
__name(_ts_param5, "_ts_param");
|
|
1103
|
+
var StoreRunGateway = class {
|
|
1104
|
+
static {
|
|
1105
|
+
__name(this, "StoreRunGateway");
|
|
1106
|
+
}
|
|
1107
|
+
store;
|
|
1108
|
+
engine;
|
|
1109
|
+
constructor(store, engine) {
|
|
1110
|
+
this.store = store;
|
|
1111
|
+
this.engine = engine;
|
|
1112
|
+
}
|
|
1113
|
+
async getRunDetail(runId) {
|
|
1114
|
+
const run = await this.store.getRun(runId);
|
|
1115
|
+
if (!run) return null;
|
|
1116
|
+
const [timeline, children] = await Promise.all([
|
|
1117
|
+
this.store.listCheckpoints(runId),
|
|
1118
|
+
this.engine.getRunChildren(runId)
|
|
1119
|
+
]);
|
|
1120
|
+
return {
|
|
1121
|
+
run,
|
|
1122
|
+
timeline,
|
|
1123
|
+
children
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
listRuns(query) {
|
|
1127
|
+
return this.store.listRuns(query);
|
|
1128
|
+
}
|
|
1129
|
+
cancel(runId, opts) {
|
|
1130
|
+
return this.engine.cancel(runId, opts);
|
|
1131
|
+
}
|
|
1132
|
+
/** Re-enqueue (dispatch model) instead of resuming inline — a worker picks the run up and replays it. */
|
|
1133
|
+
retry(runId) {
|
|
1134
|
+
return this.engine.requeue(runId);
|
|
1135
|
+
}
|
|
1136
|
+
continue(runId) {
|
|
1137
|
+
return this.engine.continue(runId);
|
|
1138
|
+
}
|
|
1139
|
+
retryWithInput(runId, input) {
|
|
1140
|
+
return this.engine.retryWithInput(runId, input);
|
|
1141
|
+
}
|
|
1142
|
+
subscribe(runId, onEvent) {
|
|
1143
|
+
return this.engine.subscribe((event) => {
|
|
1144
|
+
if (event.runId === runId) onEvent(event);
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
StoreRunGateway = _ts_decorate8([
|
|
1149
|
+
Injectable8(),
|
|
1150
|
+
_ts_param5(0, Inject5(STATE_STORE_CANONICAL2)),
|
|
1151
|
+
_ts_metadata8("design:type", Function),
|
|
1152
|
+
_ts_metadata8("design:paramtypes", [
|
|
1153
|
+
typeof StateStore === "undefined" ? Object : StateStore,
|
|
1154
|
+
typeof WorkflowEngine2 === "undefined" ? Object : WorkflowEngine2
|
|
1155
|
+
])
|
|
1156
|
+
], StoreRunGateway);
|
|
1157
|
+
|
|
1158
|
+
// src/tenant-event-republisher.ts
|
|
1159
|
+
function isTerminalRunEvent(event) {
|
|
1160
|
+
return event.type === "run.completed" || event.type === "run.failed";
|
|
1161
|
+
}
|
|
1162
|
+
__name(isTerminalRunEvent, "isTerminalRunEvent");
|
|
1163
|
+
var TenantEventRepublisher = class {
|
|
1164
|
+
static {
|
|
1165
|
+
__name(this, "TenantEventRepublisher");
|
|
1166
|
+
}
|
|
1167
|
+
store;
|
|
1168
|
+
publish;
|
|
1169
|
+
runNamespaces = /* @__PURE__ */ new Map();
|
|
1170
|
+
constructor(store, publish) {
|
|
1171
|
+
this.store = store;
|
|
1172
|
+
this.publish = publish;
|
|
1173
|
+
}
|
|
1174
|
+
async handle(event) {
|
|
1175
|
+
const namespace = await this.namespaceFor(event);
|
|
1176
|
+
if (isTerminalRunEvent(event)) this.runNamespaces.delete(event.runId);
|
|
1177
|
+
if (!namespace || namespace === "default") return;
|
|
1178
|
+
await this.publish({
|
|
1179
|
+
tenant: namespace,
|
|
1180
|
+
event
|
|
1181
|
+
}).catch(() => void 0);
|
|
1182
|
+
}
|
|
1183
|
+
async namespaceFor(event) {
|
|
1184
|
+
if (this.runNamespaces.has(event.runId)) {
|
|
1185
|
+
const cached = this.runNamespaces.get(event.runId);
|
|
1186
|
+
return cached === null ? void 0 : cached;
|
|
1187
|
+
}
|
|
1188
|
+
if (event.namespace !== void 0) {
|
|
1189
|
+
this.runNamespaces.set(event.runId, event.namespace === "default" ? null : event.namespace);
|
|
1190
|
+
return event.namespace;
|
|
1191
|
+
}
|
|
1192
|
+
const run = await this.store.getRun(event.runId);
|
|
1193
|
+
const tenantNamespace = run?.namespace !== void 0 && run.namespace !== "default" ? run.namespace : null;
|
|
1194
|
+
this.runNamespaces.set(event.runId, tenantNamespace);
|
|
1195
|
+
return tenantNamespace === null ? void 0 : tenantNamespace;
|
|
1196
|
+
}
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
// src/timer-poller.ts
|
|
1200
|
+
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL5, WorkflowEngine as WorkflowEngine3, runSchedules } from "@dudousxd/nestjs-durable-core";
|
|
1201
|
+
import { Inject as Inject6, Injectable as Injectable9 } from "@nestjs/common";
|
|
1202
|
+
function _ts_decorate9(decorators, target, key, desc) {
|
|
1203
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1204
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1205
|
+
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;
|
|
1206
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1207
|
+
}
|
|
1208
|
+
__name(_ts_decorate9, "_ts_decorate");
|
|
1209
|
+
function _ts_metadata9(k, v) {
|
|
1210
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1211
|
+
}
|
|
1212
|
+
__name(_ts_metadata9, "_ts_metadata");
|
|
1213
|
+
function _ts_param6(paramIndex, decorator) {
|
|
1214
|
+
return function(target, key) {
|
|
1215
|
+
decorator(target, key, paramIndex);
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
__name(_ts_param6, "_ts_param");
|
|
704
1219
|
var TimerPoller = class {
|
|
705
1220
|
static {
|
|
706
1221
|
__name(this, "TimerPoller");
|
|
@@ -715,7 +1230,7 @@ var TimerPoller = class {
|
|
|
715
1230
|
this.options = options;
|
|
716
1231
|
}
|
|
717
1232
|
async onApplicationBootstrap() {
|
|
718
|
-
if (this.options
|
|
1233
|
+
if (!isDrivingOperator(this.options)) return;
|
|
719
1234
|
this.unsubscribeEnqueued = this.engine.onEnqueued((runId) => void this.engine.runOne(runId));
|
|
720
1235
|
await this.poll();
|
|
721
1236
|
const intervalMs = this.options.timerPollMs ?? 1e3;
|
|
@@ -745,22 +1260,23 @@ var TimerPoller = class {
|
|
|
745
1260
|
}
|
|
746
1261
|
}
|
|
747
1262
|
};
|
|
748
|
-
TimerPoller =
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
typeof
|
|
1263
|
+
TimerPoller = _ts_decorate9([
|
|
1264
|
+
Injectable9(),
|
|
1265
|
+
_ts_param6(1, Inject6(DURABLE_OPTIONS_CANONICAL5)),
|
|
1266
|
+
_ts_metadata9("design:type", Function),
|
|
1267
|
+
_ts_metadata9("design:paramtypes", [
|
|
1268
|
+
typeof WorkflowEngine3 === "undefined" ? Object : WorkflowEngine3,
|
|
754
1269
|
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
|
|
755
1270
|
])
|
|
756
1271
|
], TimerPoller);
|
|
757
1272
|
|
|
758
1273
|
// src/tokens.ts
|
|
759
1274
|
var CONTEXT_ACCESSOR = Symbol.for("@dudousxd/nestjs-context:accessor");
|
|
1275
|
+
var RUN_GATEWAY = Symbol.for("nestjs-durable:run-gateway");
|
|
760
1276
|
|
|
761
1277
|
// src/workflow.registrar.ts
|
|
762
|
-
import { DURABLE_OPTIONS_CANONICAL as
|
|
763
|
-
import { Inject as
|
|
1278
|
+
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL6, RemoteWorkflowExecutor, STATE_STORE_CANONICAL as STATE_STORE_CANONICAL3, WorkflowEngine as WorkflowEngine4, bindWorkflowClass, parseDuration as parseDuration2, sanitizeQueueToken, tenantGroup, workflowName as workflowName2 } from "@dudousxd/nestjs-durable-core";
|
|
1279
|
+
import { Inject as Inject7, Injectable as Injectable10 } from "@nestjs/common";
|
|
764
1280
|
import { DiscoveryService as DiscoveryService4, MetadataScanner as MetadataScanner4 } from "@nestjs/core";
|
|
765
1281
|
|
|
766
1282
|
// src/input-validation.ts
|
|
@@ -803,23 +1319,23 @@ function isStepInterceptor(target) {
|
|
|
803
1319
|
__name(isStepInterceptor, "isStepInterceptor");
|
|
804
1320
|
|
|
805
1321
|
// src/workflow.registrar.ts
|
|
806
|
-
function
|
|
1322
|
+
function _ts_decorate10(decorators, target, key, desc) {
|
|
807
1323
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
808
1324
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
809
1325
|
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;
|
|
810
1326
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
811
1327
|
}
|
|
812
|
-
__name(
|
|
813
|
-
function
|
|
1328
|
+
__name(_ts_decorate10, "_ts_decorate");
|
|
1329
|
+
function _ts_metadata10(k, v) {
|
|
814
1330
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
815
1331
|
}
|
|
816
|
-
__name(
|
|
817
|
-
function
|
|
1332
|
+
__name(_ts_metadata10, "_ts_metadata");
|
|
1333
|
+
function _ts_param7(paramIndex, decorator) {
|
|
818
1334
|
return function(target, key) {
|
|
819
1335
|
decorator(target, key, paramIndex);
|
|
820
1336
|
};
|
|
821
1337
|
}
|
|
822
|
-
__name(
|
|
1338
|
+
__name(_ts_param7, "_ts_param");
|
|
823
1339
|
var WorkflowRegistrar = class {
|
|
824
1340
|
static {
|
|
825
1341
|
__name(this, "WorkflowRegistrar");
|
|
@@ -839,13 +1355,15 @@ var WorkflowRegistrar = class {
|
|
|
839
1355
|
this.inAppWorker = inAppWorker;
|
|
840
1356
|
}
|
|
841
1357
|
async onApplicationBootstrap() {
|
|
842
|
-
if (this.options
|
|
1358
|
+
if (!isDrivingOperator(this.options)) return;
|
|
843
1359
|
await this.engine.recoverIncomplete();
|
|
844
1360
|
}
|
|
845
1361
|
/** On deploy/shutdown: stop picking up new runs and wait for in-flight ones to settle, then close
|
|
846
1362
|
* the transport(s) so the broker workers stop consuming and connections are released. Closing
|
|
847
|
-
* AFTER the drain keeps the transport alive while in-flight runs dispatch/await their remote steps.
|
|
1363
|
+
* AFTER the drain keeps the transport alive while in-flight runs dispatch/await their remote steps.
|
|
1364
|
+
* Operator only — a thin worker (no `store`) holds no engine to drain. */
|
|
848
1365
|
async onApplicationShutdown() {
|
|
1366
|
+
if (!isOperatorRole(this.options)) return;
|
|
849
1367
|
await this.engine.drain(this.options.shutdownTimeoutMs);
|
|
850
1368
|
const transports = [
|
|
851
1369
|
this.options.transport,
|
|
@@ -854,8 +1372,13 @@ var WorkflowRegistrar = class {
|
|
|
854
1372
|
await Promise.allSettled(transports.map((t) => t?.close?.()));
|
|
855
1373
|
}
|
|
856
1374
|
async onModuleInit() {
|
|
1375
|
+
if (!isOperatorRole(this.options)) return;
|
|
1376
|
+
const store = this.store;
|
|
1377
|
+
if (!store) {
|
|
1378
|
+
throw new Error("unreachable: STATE_STORE_CANONICAL must resolve a store when options.store is set");
|
|
1379
|
+
}
|
|
857
1380
|
if (this.options.autoSchema !== false) {
|
|
858
|
-
await
|
|
1381
|
+
await store.ensureSchema?.();
|
|
859
1382
|
}
|
|
860
1383
|
const deadLetterByWorkflow = /* @__PURE__ */ new Map();
|
|
861
1384
|
for (const wrapper of this.discovery.getProviders()) {
|
|
@@ -889,13 +1412,23 @@ var WorkflowRegistrar = class {
|
|
|
889
1412
|
onEvent: getOnEvents(meta, workflowCtor),
|
|
890
1413
|
eventBatch,
|
|
891
1414
|
// Uniform dispatch (opt-in): when an in-app worker is configured, register the body GROUP-SERVED
|
|
892
|
-
// so the engine dispatches its turns
|
|
893
|
-
// co-located worker consumer
|
|
1415
|
+
// so the engine dispatches its turns over the transport instead of running it inline; the
|
|
1416
|
+
// co-located worker consumer (Task 5: one queue PER REGISTERED NAME) replays the same body.
|
|
1417
|
+
// The routing token — and the executor that dispatches under it — MUST be keyed by THIS
|
|
1418
|
+
// workflow's own name (`tenantGroup(sanitizeQueueToken(meta.name), partition)`), not a single
|
|
1419
|
+
// group shared across every discovered `@Workflow`: a fixed shared token would dispatch every
|
|
1420
|
+
// workflow's turns to one queue while the co-located worker subscribes one queue per name,
|
|
1421
|
+
// so a turn dispatched under the wrong token would never be consumed. Absent → the inline fast
|
|
1422
|
+
// path (unchanged).
|
|
894
1423
|
...this.inAppWorker ? {
|
|
895
|
-
group: this.inAppWorker.
|
|
896
|
-
executor: this.inAppWorker.
|
|
1424
|
+
group: tenantGroup(sanitizeQueueToken(meta.name), this.inAppWorker.partition),
|
|
1425
|
+
executor: new RemoteWorkflowExecutor(this.inAppWorker.transport, meta.name, this.inAppWorker.partition)
|
|
897
1426
|
} : {}
|
|
898
1427
|
});
|
|
1428
|
+
bindWorkflowClass(workflowCtor, {
|
|
1429
|
+
start: /* @__PURE__ */ __name((name, input, runId, opts) => this.engine.start(name, input, runId, opts), "start"),
|
|
1430
|
+
waitForRun: /* @__PURE__ */ __name((runId, opts) => this.engine.waitForRun(runId, opts), "waitForRun")
|
|
1431
|
+
});
|
|
899
1432
|
const inline = this.findDeadLetterHandler(workflow);
|
|
900
1433
|
if (inline && meta.deadLetterWorkflow) {
|
|
901
1434
|
throw new Error(`@Workflow ${meta.name} declares both an inline @DeadLetter() method and a deadLetterWorkflow option. Use one: the inline handler, or the reference.`);
|
|
@@ -905,7 +1438,7 @@ var WorkflowRegistrar = class {
|
|
|
905
1438
|
this.engine.register(dlqName, meta.version, inline);
|
|
906
1439
|
deadLetterByWorkflow.set(meta.name, dlqName);
|
|
907
1440
|
} else if (meta.deadLetterWorkflow) {
|
|
908
|
-
deadLetterByWorkflow.set(meta.name,
|
|
1441
|
+
deadLetterByWorkflow.set(meta.name, workflowName2(meta.deadLetterWorkflow));
|
|
909
1442
|
}
|
|
910
1443
|
});
|
|
911
1444
|
this.installDeadLetterRouting(deadLetterByWorkflow);
|
|
@@ -927,31 +1460,40 @@ var WorkflowRegistrar = class {
|
|
|
927
1460
|
* a `dlq:<runId>` id, so re-recovery never double-dispatches.
|
|
928
1461
|
*/
|
|
929
1462
|
installDeadLetterRouting(byWorkflow) {
|
|
930
|
-
const fallback = this.options.deadLetterWorkflow ?
|
|
1463
|
+
const fallback = this.options.deadLetterWorkflow ? workflowName2(this.options.deadLetterWorkflow) : void 0;
|
|
931
1464
|
if (byWorkflow.size === 0 && !fallback) return;
|
|
932
1465
|
this.engine.onDead((run) => {
|
|
933
1466
|
const target = byWorkflow.get(run.workflow) ?? fallback;
|
|
934
1467
|
if (!target) return;
|
|
935
|
-
void this.engine.start(
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1468
|
+
void this.engine.start(
|
|
1469
|
+
target,
|
|
1470
|
+
{
|
|
1471
|
+
deadRunId: run.id,
|
|
1472
|
+
workflow: run.workflow,
|
|
1473
|
+
input: run.input,
|
|
1474
|
+
error: run.error
|
|
1475
|
+
},
|
|
1476
|
+
`dlq:${run.id}`,
|
|
1477
|
+
// Route the dead-letter handler to the dead run's OWN tenant so an operator dispatches it to
|
|
1478
|
+
// that tenant's worker group (`target@<tenant>`), not the bare group.
|
|
1479
|
+
{
|
|
1480
|
+
namespace: run.namespace
|
|
1481
|
+
}
|
|
1482
|
+
).catch(() => void 0);
|
|
941
1483
|
});
|
|
942
1484
|
}
|
|
943
1485
|
};
|
|
944
|
-
WorkflowRegistrar =
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1486
|
+
WorkflowRegistrar = _ts_decorate10([
|
|
1487
|
+
Injectable10(),
|
|
1488
|
+
_ts_param7(3, Inject7(STATE_STORE_CANONICAL3)),
|
|
1489
|
+
_ts_param7(4, Inject7(DURABLE_OPTIONS_CANONICAL6)),
|
|
1490
|
+
_ts_param7(5, Inject7(IN_APP_WORKER_BINDING)),
|
|
1491
|
+
_ts_metadata10("design:type", Function),
|
|
1492
|
+
_ts_metadata10("design:paramtypes", [
|
|
951
1493
|
typeof DiscoveryService4 === "undefined" ? Object : DiscoveryService4,
|
|
952
1494
|
typeof MetadataScanner4 === "undefined" ? Object : MetadataScanner4,
|
|
953
|
-
typeof
|
|
954
|
-
|
|
1495
|
+
typeof WorkflowEngine4 === "undefined" ? Object : WorkflowEngine4,
|
|
1496
|
+
Object,
|
|
955
1497
|
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions,
|
|
956
1498
|
Object
|
|
957
1499
|
])
|
|
@@ -959,19 +1501,19 @@ WorkflowRegistrar = _ts_decorate7([
|
|
|
959
1501
|
|
|
960
1502
|
// src/workflow.service.ts
|
|
961
1503
|
import { randomUUID } from "node:crypto";
|
|
962
|
-
import { WorkflowEngine as
|
|
963
|
-
import { Injectable as
|
|
964
|
-
function
|
|
1504
|
+
import { WorkflowEngine as WorkflowEngine5 } from "@dudousxd/nestjs-durable-core";
|
|
1505
|
+
import { Injectable as Injectable11 } from "@nestjs/common";
|
|
1506
|
+
function _ts_decorate11(decorators, target, key, desc) {
|
|
965
1507
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
966
1508
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
967
1509
|
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;
|
|
968
1510
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
969
1511
|
}
|
|
970
|
-
__name(
|
|
971
|
-
function
|
|
1512
|
+
__name(_ts_decorate11, "_ts_decorate");
|
|
1513
|
+
function _ts_metadata11(k, v) {
|
|
972
1514
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
973
1515
|
}
|
|
974
|
-
__name(
|
|
1516
|
+
__name(_ts_metadata11, "_ts_metadata");
|
|
975
1517
|
var WorkflowService = class {
|
|
976
1518
|
static {
|
|
977
1519
|
__name(this, "WorkflowService");
|
|
@@ -1003,7 +1545,7 @@ var WorkflowService = class {
|
|
|
1003
1545
|
}
|
|
1004
1546
|
/**
|
|
1005
1547
|
* Publish a named event. Resumes runs waiting on it via `ctx.waitForEvent(name, { match })` and
|
|
1006
|
-
* starts a fresh run of every workflow subscribed via `@Workflow({ onEvent })` / `@
|
|
1548
|
+
* starts a fresh run of every workflow subscribed via `@Workflow({ onEvent })` / `@OnDurableEvent` (the
|
|
1007
1549
|
* payload becomes its input). Pass `opts.id` to dedupe redeliveries. Returns how many runs it
|
|
1008
1550
|
* touched (resumed + started).
|
|
1009
1551
|
*/
|
|
@@ -1011,22 +1553,32 @@ var WorkflowService = class {
|
|
|
1011
1553
|
return this.engine.publishEvent(name, payload, opts);
|
|
1012
1554
|
}
|
|
1013
1555
|
};
|
|
1014
|
-
WorkflowService =
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
typeof
|
|
1556
|
+
WorkflowService = _ts_decorate11([
|
|
1557
|
+
Injectable11(),
|
|
1558
|
+
_ts_metadata11("design:type", Function),
|
|
1559
|
+
_ts_metadata11("design:paramtypes", [
|
|
1560
|
+
typeof WorkflowEngine5 === "undefined" ? Object : WorkflowEngine5
|
|
1019
1561
|
])
|
|
1020
1562
|
], WorkflowService);
|
|
1021
1563
|
|
|
1022
1564
|
// src/durable.module.ts
|
|
1023
|
-
function
|
|
1565
|
+
function _ts_decorate12(decorators, target, key, desc) {
|
|
1024
1566
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1025
1567
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1026
1568
|
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;
|
|
1027
1569
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1028
1570
|
}
|
|
1029
|
-
__name(
|
|
1571
|
+
__name(_ts_decorate12, "_ts_decorate");
|
|
1572
|
+
function _ts_metadata12(k, v) {
|
|
1573
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1574
|
+
}
|
|
1575
|
+
__name(_ts_metadata12, "_ts_metadata");
|
|
1576
|
+
function _ts_param8(paramIndex, decorator) {
|
|
1577
|
+
return function(target, key) {
|
|
1578
|
+
decorator(target, key, paramIndex);
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
__name(_ts_param8, "_ts_param");
|
|
1030
1582
|
function resolveAccessor(moduleRef) {
|
|
1031
1583
|
try {
|
|
1032
1584
|
return moduleRef.get(CONTEXT_ACCESSOR, {
|
|
@@ -1066,20 +1618,103 @@ function isControlPlane(x) {
|
|
|
1066
1618
|
return !!x && typeof x.publishControl === "function" && typeof x.onControl === "function";
|
|
1067
1619
|
}
|
|
1068
1620
|
__name(isControlPlane, "isControlPlane");
|
|
1621
|
+
function isScopeableStore(store) {
|
|
1622
|
+
return typeof store.withScope === "function";
|
|
1623
|
+
}
|
|
1624
|
+
__name(isScopeableStore, "isScopeableStore");
|
|
1625
|
+
function scopedStore(store, options) {
|
|
1626
|
+
if (options.scopeReads !== true || options.namespace === void 0) return store;
|
|
1627
|
+
if (!isScopeableStore(store)) return store;
|
|
1628
|
+
return store.withScope({
|
|
1629
|
+
namespace: options.namespace
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
__name(scopedStore, "scopedStore");
|
|
1633
|
+
function assertValidRole(options) {
|
|
1634
|
+
const hasStore = options.store !== void 0;
|
|
1635
|
+
const hasConnection = options.connection !== void 0;
|
|
1636
|
+
if (!hasStore && !hasConnection) {
|
|
1637
|
+
throw new Error("a durable module needs either a `store` (operator) or a `connection` (worker)");
|
|
1638
|
+
}
|
|
1639
|
+
if (hasStore && options.transport === void 0) {
|
|
1640
|
+
throw new Error("an operator (`store`) needs a `transport`");
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
__name(assertValidRole, "assertValidRole");
|
|
1644
|
+
var RunGatewayBootstrap = class RunGatewayBootstrap2 {
|
|
1645
|
+
static {
|
|
1646
|
+
__name(this, "RunGatewayBootstrap");
|
|
1647
|
+
}
|
|
1648
|
+
engine;
|
|
1649
|
+
transport;
|
|
1650
|
+
gateway;
|
|
1651
|
+
store;
|
|
1652
|
+
options;
|
|
1653
|
+
unsubscribe;
|
|
1654
|
+
constructor(engine, transport, gateway, store, options) {
|
|
1655
|
+
this.engine = engine;
|
|
1656
|
+
this.transport = transport;
|
|
1657
|
+
this.gateway = gateway;
|
|
1658
|
+
this.store = store;
|
|
1659
|
+
this.options = options;
|
|
1660
|
+
}
|
|
1661
|
+
onApplicationBootstrap() {
|
|
1662
|
+
if (!isDrivingOperator(this.options) || !this.transport) return;
|
|
1663
|
+
const store = this.store;
|
|
1664
|
+
if (!store) return;
|
|
1665
|
+
const { onRunRequest, publishRunReply, publishTenantEvent } = this.transport;
|
|
1666
|
+
if (typeof onRunRequest === "function" && typeof publishRunReply === "function") {
|
|
1667
|
+
const runRequestTransport = {
|
|
1668
|
+
onRunRequest: onRunRequest.bind(this.transport),
|
|
1669
|
+
publishRunReply: publishRunReply.bind(this.transport)
|
|
1670
|
+
};
|
|
1671
|
+
new RunRequestResponder(runRequestTransport, this.gateway).start();
|
|
1672
|
+
}
|
|
1673
|
+
if (typeof publishTenantEvent === "function") {
|
|
1674
|
+
const republisher = new TenantEventRepublisher(store, publishTenantEvent.bind(this.transport));
|
|
1675
|
+
this.unsubscribe = this.engine.subscribe((event) => {
|
|
1676
|
+
void republisher.handle(event);
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
onModuleDestroy() {
|
|
1681
|
+
this.unsubscribe?.();
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
RunGatewayBootstrap = _ts_decorate12([
|
|
1685
|
+
Injectable12(),
|
|
1686
|
+
_ts_param8(1, Inject8(TRANSPORT_CANONICAL3)),
|
|
1687
|
+
_ts_param8(2, Inject8(RUN_GATEWAY)),
|
|
1688
|
+
_ts_param8(3, Inject8(STATE_STORE_CANONICAL4)),
|
|
1689
|
+
_ts_param8(4, Inject8(DURABLE_OPTIONS_CANONICAL7)),
|
|
1690
|
+
_ts_metadata12("design:type", Function),
|
|
1691
|
+
_ts_metadata12("design:paramtypes", [
|
|
1692
|
+
typeof WorkflowEngine6 === "undefined" ? Object : WorkflowEngine6,
|
|
1693
|
+
Object,
|
|
1694
|
+
typeof RunGateway === "undefined" ? Object : RunGateway,
|
|
1695
|
+
Object,
|
|
1696
|
+
typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
|
|
1697
|
+
])
|
|
1698
|
+
], RunGatewayBootstrap);
|
|
1069
1699
|
var DurableModule = class _DurableModule {
|
|
1070
1700
|
static {
|
|
1071
1701
|
__name(this, "DurableModule");
|
|
1072
1702
|
}
|
|
1073
1703
|
static forRoot(options) {
|
|
1704
|
+
assertValidRole(options);
|
|
1074
1705
|
return _DurableModule.build({
|
|
1075
|
-
provide:
|
|
1706
|
+
provide: DURABLE_OPTIONS_CANONICAL7,
|
|
1076
1707
|
useValue: options
|
|
1077
1708
|
});
|
|
1078
1709
|
}
|
|
1079
1710
|
static forRootAsync(options) {
|
|
1080
1711
|
return _DurableModule.build({
|
|
1081
|
-
provide:
|
|
1082
|
-
useFactory:
|
|
1712
|
+
provide: DURABLE_OPTIONS_CANONICAL7,
|
|
1713
|
+
useFactory: /* @__PURE__ */ __name(async (...args) => {
|
|
1714
|
+
const resolved = await options.useFactory(...args);
|
|
1715
|
+
assertValidRole(resolved);
|
|
1716
|
+
return resolved;
|
|
1717
|
+
}, "useFactory"),
|
|
1083
1718
|
inject: options.inject ?? []
|
|
1084
1719
|
});
|
|
1085
1720
|
}
|
|
@@ -1088,28 +1723,28 @@ var DurableModule = class _DurableModule {
|
|
|
1088
1723
|
module: _DurableModule,
|
|
1089
1724
|
global: true,
|
|
1090
1725
|
imports: [
|
|
1091
|
-
|
|
1726
|
+
DiscoveryModule
|
|
1092
1727
|
],
|
|
1093
1728
|
providers: [
|
|
1094
1729
|
optionsProvider,
|
|
1095
1730
|
{
|
|
1096
|
-
provide:
|
|
1097
|
-
useFactory: /* @__PURE__ */ __name((options) => options.store, "useFactory"),
|
|
1731
|
+
provide: STATE_STORE_CANONICAL4,
|
|
1732
|
+
useFactory: /* @__PURE__ */ __name((options) => options.store !== void 0 ? scopedStore(options.store, options) : null, "useFactory"),
|
|
1098
1733
|
inject: [
|
|
1099
|
-
|
|
1734
|
+
DURABLE_OPTIONS_CANONICAL7
|
|
1100
1735
|
]
|
|
1101
1736
|
},
|
|
1102
1737
|
{
|
|
1103
1738
|
provide: TRANSPORT_CANONICAL3,
|
|
1104
1739
|
useFactory: /* @__PURE__ */ __name((options) => options.transport ?? null, "useFactory"),
|
|
1105
1740
|
inject: [
|
|
1106
|
-
|
|
1741
|
+
DURABLE_OPTIONS_CANONICAL7
|
|
1107
1742
|
]
|
|
1108
1743
|
},
|
|
1109
1744
|
// Legacy back-compat aliases (deprecated tokens still resolve to the same instances):
|
|
1110
1745
|
{
|
|
1111
1746
|
provide: STATE_STORE,
|
|
1112
|
-
useExisting:
|
|
1747
|
+
useExisting: STATE_STORE_CANONICAL4
|
|
1113
1748
|
},
|
|
1114
1749
|
{
|
|
1115
1750
|
provide: TRANSPORT,
|
|
@@ -1117,47 +1752,59 @@ var DurableModule = class _DurableModule {
|
|
|
1117
1752
|
},
|
|
1118
1753
|
{
|
|
1119
1754
|
provide: DURABLE_OPTIONS,
|
|
1120
|
-
useExisting:
|
|
1755
|
+
useExisting: DURABLE_OPTIONS_CANONICAL7
|
|
1121
1756
|
},
|
|
1122
1757
|
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1758
|
+
// Shared token, bound EXACTLY once: a real engine for the operator role, or a store-less
|
|
1759
|
+
// `DurableStartClient` facade for a thin worker (no `store`) — either way, `WorkflowService`
|
|
1760
|
+
// and app code call `engine.start(...)` unchanged.
|
|
1761
|
+
provide: WorkflowEngine6,
|
|
1762
|
+
useFactory: /* @__PURE__ */ __name(async (options, store, transport, moduleRef) => {
|
|
1763
|
+
if (options.store === void 0) {
|
|
1764
|
+
return new DurableStartClient(options);
|
|
1765
|
+
}
|
|
1766
|
+
if (!store) {
|
|
1767
|
+
throw new Error("unreachable: STATE_STORE_CANONICAL must resolve a store when options.store is set");
|
|
1768
|
+
}
|
|
1769
|
+
const primary = transport ?? options.transports?.[0]?.transport;
|
|
1126
1770
|
const accessor = resolveAccessor(moduleRef);
|
|
1127
|
-
const context =
|
|
1771
|
+
const context = options.context ?? (accessor ? () => carrierFromAccessor(accessor) : void 0);
|
|
1128
1772
|
const runtime = accessor ? await resolveContextRuntime() : void 0;
|
|
1129
1773
|
const rehydrate = runtime && ((carrier, fn) => carrier && Object.keys(carrier).length > 0 ? runtime.deserialize(carrier, fn) : fn());
|
|
1130
|
-
const engine = new
|
|
1774
|
+
const engine = new WorkflowEngine6({
|
|
1131
1775
|
store,
|
|
1132
1776
|
transport: transport ?? void 0,
|
|
1133
|
-
transports:
|
|
1134
|
-
controlPlane:
|
|
1135
|
-
leaseMs:
|
|
1136
|
-
admission:
|
|
1137
|
-
maxRecoveryAttempts:
|
|
1138
|
-
remoteAdvanceSilenceMs:
|
|
1139
|
-
instanceId:
|
|
1140
|
-
namespace:
|
|
1141
|
-
webhookUrl:
|
|
1142
|
-
traceparent:
|
|
1777
|
+
transports: options.transports,
|
|
1778
|
+
controlPlane: options.controlPlane ?? (isControlPlane(primary) ? primary : void 0),
|
|
1779
|
+
leaseMs: options.leaseMs,
|
|
1780
|
+
admission: options.admission,
|
|
1781
|
+
maxRecoveryAttempts: options.maxRecoveryAttempts,
|
|
1782
|
+
remoteAdvanceSilenceMs: options.remoteAdvanceSilenceMs,
|
|
1783
|
+
instanceId: options.instanceId,
|
|
1784
|
+
namespace: options.namespace,
|
|
1785
|
+
webhookUrl: options.webhookUrl,
|
|
1786
|
+
traceparent: options.traceparent,
|
|
1143
1787
|
context,
|
|
1144
1788
|
rehydrate: rehydrate || void 0,
|
|
1145
|
-
compensationRetries:
|
|
1146
|
-
// A non-
|
|
1147
|
-
// each `pending` run in the store for a
|
|
1148
|
-
// default in-process dispatcher
|
|
1149
|
-
|
|
1789
|
+
compensationRetries: options.compensationRetries,
|
|
1790
|
+
// A non-driving (dashboard/API) operator must not run workflows: enqueue-only, leaving
|
|
1791
|
+
// each `pending` run in the store for a DRIVING instance's poll. A driving operator gets
|
|
1792
|
+
// the engine's default in-process dispatcher: for a body registered inline, it runs
|
|
1793
|
+
// locally; for one registered GROUP-SERVED (co-located worker) or left unregistered, the
|
|
1794
|
+
// SAME default dispatcher routes it out remotely (group-served executor, or convention
|
|
1795
|
+
// dispatch — always on) instead.
|
|
1796
|
+
runDispatcher: options.drive === false ? {
|
|
1150
1797
|
dispatch: /* @__PURE__ */ __name(() => {
|
|
1151
1798
|
}, "dispatch")
|
|
1152
1799
|
} : void 0
|
|
1153
1800
|
});
|
|
1154
|
-
for (const queue of
|
|
1801
|
+
for (const queue of options.queues ?? []) engine.registerQueue(queue);
|
|
1155
1802
|
return engine;
|
|
1156
1803
|
}, "useFactory"),
|
|
1157
1804
|
inject: [
|
|
1158
|
-
|
|
1805
|
+
DURABLE_OPTIONS_CANONICAL7,
|
|
1806
|
+
STATE_STORE_CANONICAL4,
|
|
1159
1807
|
TRANSPORT_CANONICAL3,
|
|
1160
|
-
DURABLE_OPTIONS_CANONICAL6,
|
|
1161
1808
|
ModuleRef
|
|
1162
1809
|
]
|
|
1163
1810
|
},
|
|
@@ -1167,53 +1814,82 @@ var DurableModule = class _DurableModule {
|
|
|
1167
1814
|
DurableStepRegistrar,
|
|
1168
1815
|
TimerPoller,
|
|
1169
1816
|
RetentionPoller,
|
|
1170
|
-
//
|
|
1171
|
-
//
|
|
1172
|
-
|
|
1817
|
+
// Tenant run gateway: bound EXACTLY once — the store-backed `StoreRunGateway` for an operator,
|
|
1818
|
+
// or (for a thin worker, no `store`) a `ProxyRunGateway` over `transport` when given, else a
|
|
1819
|
+
// gateway whose every method rejects with a clear tenant error.
|
|
1820
|
+
{
|
|
1821
|
+
provide: RUN_GATEWAY,
|
|
1822
|
+
useFactory: /* @__PURE__ */ __name((options, store, engine) => {
|
|
1823
|
+
if (options.store !== void 0) {
|
|
1824
|
+
if (!store) {
|
|
1825
|
+
throw new Error("unreachable: STATE_STORE_CANONICAL must resolve a store when options.store is set");
|
|
1826
|
+
}
|
|
1827
|
+
return new StoreRunGateway(store, engine);
|
|
1828
|
+
}
|
|
1829
|
+
return options.transport ? new ProxyRunGateway(options.transport, options.partition ?? "default", options.runGatewayTimeoutMs) : unavailableRunGateway();
|
|
1830
|
+
}, "useFactory"),
|
|
1831
|
+
inject: [
|
|
1832
|
+
DURABLE_OPTIONS_CANONICAL7,
|
|
1833
|
+
STATE_STORE_CANONICAL4,
|
|
1834
|
+
WorkflowEngine6
|
|
1835
|
+
]
|
|
1836
|
+
},
|
|
1837
|
+
RunGatewayBootstrap,
|
|
1838
|
+
// Co-located in-app worker (uniform dispatch): inert unless BOTH `store` and `connection` are
|
|
1839
|
+
// set — see `in-app-worker.ts`.
|
|
1840
|
+
...inAppWorkerProviders(),
|
|
1841
|
+
// Pure thin-worker consumer: inert unless `connection` is set WITHOUT `store` — see
|
|
1842
|
+
// `durable-worker.module.ts`.
|
|
1843
|
+
...thinWorkerProviders()
|
|
1173
1844
|
],
|
|
1174
1845
|
exports: [
|
|
1175
1846
|
WorkflowService,
|
|
1176
1847
|
EntityService,
|
|
1177
|
-
|
|
1848
|
+
WorkflowEngine6,
|
|
1178
1849
|
STATE_STORE,
|
|
1179
|
-
|
|
1850
|
+
STATE_STORE_CANONICAL4,
|
|
1180
1851
|
TRANSPORT,
|
|
1181
1852
|
TRANSPORT_CANONICAL3,
|
|
1182
|
-
|
|
1853
|
+
DURABLE_OPTIONS_CANONICAL7,
|
|
1854
|
+
RUN_GATEWAY
|
|
1183
1855
|
]
|
|
1184
1856
|
};
|
|
1185
1857
|
}
|
|
1186
1858
|
};
|
|
1187
|
-
DurableModule =
|
|
1188
|
-
|
|
1859
|
+
DurableModule = _ts_decorate12([
|
|
1860
|
+
Module({})
|
|
1189
1861
|
], DurableModule);
|
|
1190
1862
|
export {
|
|
1191
1863
|
CONTEXT_ACCESSOR,
|
|
1192
1864
|
DEAD_LETTER_METADATA,
|
|
1193
1865
|
DURABLE_STEP_METADATA,
|
|
1194
|
-
DURABLE_WORKER_OPTIONS,
|
|
1195
1866
|
DURABLE_WORKER_RUNNERS,
|
|
1196
1867
|
DeadLetter,
|
|
1197
1868
|
DurableModule,
|
|
1869
|
+
DurableStartClient,
|
|
1198
1870
|
DurableStep,
|
|
1199
|
-
DurableWorkerModule,
|
|
1200
1871
|
ENTITY_METADATA,
|
|
1201
1872
|
ENTITY_ON_METADATA,
|
|
1202
1873
|
Entity,
|
|
1203
1874
|
EntityService,
|
|
1204
1875
|
IN_APP_RUN_REDIS_WORKER,
|
|
1205
1876
|
IN_APP_WORKER_BINDING,
|
|
1206
|
-
IN_APP_WORKER_OPTIONS,
|
|
1207
1877
|
IN_APP_WORKER_RUNNERS,
|
|
1208
1878
|
IN_APP_WORKER_RUNTIME,
|
|
1209
1879
|
InAppWorkerBootstrap,
|
|
1210
1880
|
ON_EVENT_METADATA,
|
|
1211
1881
|
On,
|
|
1882
|
+
OnDurableEvent,
|
|
1212
1883
|
OnEvent,
|
|
1884
|
+
ProxyRunGateway,
|
|
1885
|
+
RUN_GATEWAY,
|
|
1213
1886
|
RUN_REDIS_WORKER,
|
|
1887
|
+
RunRequestResponder,
|
|
1214
1888
|
STEP_INTERCEPTOR_METADATA,
|
|
1215
1889
|
Step,
|
|
1216
1890
|
StepInterceptor,
|
|
1891
|
+
StoreRunGateway,
|
|
1892
|
+
TenantEventRepublisher,
|
|
1217
1893
|
ThinStepRegistrar,
|
|
1218
1894
|
ThinWorkerBootstrap,
|
|
1219
1895
|
ThinWorkflowRegistrar,
|
|
@@ -1227,6 +1903,10 @@ export {
|
|
|
1227
1903
|
getWorkflowMeta,
|
|
1228
1904
|
inAppWorkerProviders,
|
|
1229
1905
|
isDeadLetterHandler,
|
|
1230
|
-
|
|
1906
|
+
isDrivingOperator,
|
|
1907
|
+
isOperatorRole,
|
|
1908
|
+
isStepInterceptor,
|
|
1909
|
+
thinWorkerProviders,
|
|
1910
|
+
unavailableRunGateway
|
|
1231
1911
|
};
|
|
1232
1912
|
//# sourceMappingURL=index.js.map
|