@voyantjs/workflows-orchestrator-node 0.107.5 → 0.107.6

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 (69) hide show
  1. package/dist/dashboard-chunks.d.ts +17 -0
  2. package/dist/dashboard-chunks.d.ts.map +1 -0
  3. package/dist/dashboard-chunks.js +19 -0
  4. package/dist/dashboard-http-server.d.ts +6 -0
  5. package/dist/dashboard-http-server.d.ts.map +1 -0
  6. package/dist/dashboard-http-server.js +99 -0
  7. package/dist/dashboard-metrics.d.ts +3 -0
  8. package/dist/dashboard-metrics.d.ts.map +1 -0
  9. package/dist/dashboard-metrics.js +26 -0
  10. package/dist/dashboard-request.d.ts +7 -0
  11. package/dist/dashboard-request.d.ts.map +1 -0
  12. package/dist/dashboard-request.js +436 -0
  13. package/dist/dashboard-server.d.ts +9 -171
  14. package/dist/dashboard-server.d.ts.map +1 -1
  15. package/dist/dashboard-server.js +7 -1229
  16. package/dist/dashboard-sse.d.ts +7 -0
  17. package/dist/dashboard-sse.d.ts.map +1 -0
  18. package/dist/dashboard-sse.js +134 -0
  19. package/dist/dashboard-static.d.ts +7 -0
  20. package/dist/dashboard-static.d.ts.map +1 -0
  21. package/dist/dashboard-static.js +89 -0
  22. package/dist/dashboard-types.d.ts +134 -0
  23. package/dist/dashboard-types.d.ts.map +1 -0
  24. package/dist/dashboard-types.js +1 -0
  25. package/dist/node-selfhost-defaults.d.ts +7 -0
  26. package/dist/node-selfhost-defaults.d.ts.map +1 -0
  27. package/dist/node-selfhost-defaults.js +8 -0
  28. package/dist/node-selfhost-deps.d.ts +4 -0
  29. package/dist/node-selfhost-deps.d.ts.map +1 -0
  30. package/dist/node-selfhost-deps.js +403 -0
  31. package/dist/node-selfhost-resume-input.d.ts +4 -0
  32. package/dist/node-selfhost-resume-input.d.ts.map +1 -0
  33. package/dist/node-selfhost-resume-input.js +20 -0
  34. package/dist/node-standalone-driver.d.ts.map +1 -1
  35. package/dist/node-standalone-driver.js +40 -3
  36. package/dist/node-step-runner.d.ts +3 -0
  37. package/dist/node-step-runner.d.ts.map +1 -0
  38. package/dist/node-step-runner.js +26 -0
  39. package/dist/postgres-manifest-store.d.ts.map +1 -1
  40. package/dist/postgres-manifest-store.js +6 -2
  41. package/dist/postgres-run-record-store.js +1 -1
  42. package/dist/postgres-schema.d.ts.map +1 -1
  43. package/dist/postgres-schema.js +2 -0
  44. package/dist/sleep-alarm-manager.d.ts.map +1 -1
  45. package/dist/sleep-alarm-manager.js +9 -1
  46. package/dist/store-stream.d.ts.map +1 -1
  47. package/dist/store-stream.js +9 -1
  48. package/dist/wakeup-poller.d.ts.map +1 -1
  49. package/dist/wakeup-poller.js +9 -1
  50. package/package.json +3 -3
  51. package/src/dashboard-chunks.ts +35 -0
  52. package/src/dashboard-http-server.ts +118 -0
  53. package/src/dashboard-metrics.ts +39 -0
  54. package/src/dashboard-request.ts +488 -0
  55. package/src/dashboard-server.ts +17 -1535
  56. package/src/dashboard-sse.ts +150 -0
  57. package/src/dashboard-static.ts +88 -0
  58. package/src/dashboard-types.ts +106 -0
  59. package/src/node-selfhost-defaults.ts +9 -0
  60. package/src/node-selfhost-deps.ts +495 -0
  61. package/src/node-selfhost-resume-input.ts +27 -0
  62. package/src/node-standalone-driver.ts +59 -3
  63. package/src/node-step-runner.ts +28 -0
  64. package/src/postgres-manifest-store.ts +2 -0
  65. package/src/postgres-run-record-store.ts +1 -1
  66. package/src/postgres-schema.ts +2 -0
  67. package/src/sleep-alarm-manager.ts +12 -1
  68. package/src/store-stream.ts +12 -1
  69. package/src/wakeup-poller.ts +12 -1
@@ -0,0 +1,403 @@
1
+ import { createServer } from "node:http";
2
+ import { resolve as resolvePath } from "node:path";
3
+ import { handleStepRequest } from "@voyantjs/workflows/handler";
4
+ import { createInMemoryRateLimiter } from "@voyantjs/workflows/rate-limit";
5
+ import { createInMemoryRunStore, resume, resumeDueAlarms, trigger, } from "@voyantjs/workflows-orchestrator";
6
+ import { createChunkBus } from "./dashboard-chunks.js";
7
+ import { startServer } from "./dashboard-http-server.js";
8
+ import { renderMetrics } from "./dashboard-metrics.js";
9
+ import { assertReadableDirectory, assertReadableFile, findDashboardDir, } from "./dashboard-static.js";
10
+ import { loadEntryFile } from "./entry-loader.js";
11
+ import { durationToMs, generateLocalRunId } from "./local-runtime.js";
12
+ import { createDefaultWakeupLeaseOwner, localTenantMeta } from "./node-selfhost-defaults.js";
13
+ import { mergeTags, requireExternalResumeFromStep, requireExternalSeedResults, } from "./node-selfhost-resume-input.js";
14
+ import { nodeStepRunner } from "./node-step-runner.js";
15
+ import { createPersistentWakeupManager } from "./persistent-wakeup-manager.js";
16
+ import { createPostgresConnection } from "./postgres.js";
17
+ import { createPostgresSnapshotRunStore } from "./postgres-snapshot-run-store.js";
18
+ import { createPostgresWakeupStore } from "./postgres-wakeup-store.js";
19
+ import { buildResumeJournal, buildSeededResumeJournal } from "./resume-run.js";
20
+ import { recordToSnapshot, snapshotToRecord } from "./run-record-snapshot.js";
21
+ import { createScheduler } from "./scheduler.js";
22
+ import { createFsSnapshotRunStore } from "./snapshot-run-store.js";
23
+ import { createFsWakeupStore } from "./wakeup-store.js";
24
+ export async function startNodeSelfHostServer(opts) {
25
+ const deps = await createNodeSelfHostDeps(opts);
26
+ return startServer({
27
+ port: opts.port ?? 3232,
28
+ host: opts.host ?? "127.0.0.1",
29
+ }, deps);
30
+ }
31
+ export async function createNodeSelfHostDeps(opts) {
32
+ let staticDir = opts.staticDir;
33
+ if (!staticDir)
34
+ staticDir = await findDashboardDir(process.cwd());
35
+ if (!staticDir && typeof import.meta.url === "string") {
36
+ const here = resolvePath(new URL(".", import.meta.url).pathname);
37
+ staticDir = await findDashboardDir(here);
38
+ }
39
+ if (staticDir) {
40
+ await assertReadableDirectory(staticDir, "dashboard static dir");
41
+ }
42
+ const databaseUrl = opts.databaseUrl ?? process.env.DATABASE_URL;
43
+ const pg = databaseUrl ? createPostgresConnection({ databaseUrl }) : undefined;
44
+ const store = opts.store ?? (pg ? createPostgresSnapshotRunStore({ db: pg.db }) : createFsSnapshotRunStore());
45
+ const wfMod = await import("@voyantjs/workflows");
46
+ wfMod.__resetRegistry();
47
+ const entryAbs = resolvePath(process.cwd(), opts.entryFile);
48
+ await assertReadableFile(entryAbs, "workflow entry");
49
+ await loadEntryFile(entryAbs, { cacheBust: opts.cacheBustEntry });
50
+ const _handlerMod = await import("@voyantjs/workflows/handler");
51
+ const rateLimiter = createInMemoryRateLimiter();
52
+ const chunkBus = createChunkBus();
53
+ const stepHandler = async (req, stepOpts) => handleStepRequest(req, { rateLimiter, nodeStepRunner, services: opts.services }, stepOpts);
54
+ const wakeupStore = pg ? createPostgresWakeupStore({ db: pg.db }) : createFsWakeupStore();
55
+ const leaseOwner = opts.wakeupLeaseOwner ?? createDefaultWakeupLeaseOwner();
56
+ const listWorkflows = () => wfMod.__listRegisteredWorkflows().map((workflow) => ({
57
+ id: workflow.id,
58
+ description: workflow.config.description,
59
+ }));
60
+ const registeredWorkflows = listWorkflows();
61
+ if (registeredWorkflows.length === 0) {
62
+ throw new Error("voyant workflows selfhost: workflow entry registered no workflows. " +
63
+ `Check "${entryAbs}" and ensure it calls workflow(...).`);
64
+ }
65
+ const healthCheck = () => ({
66
+ ok: true,
67
+ service: "voyant-workflows-selfhost",
68
+ });
69
+ const readinessCheck = async () => {
70
+ const checks = {
71
+ workflowEntry: "ok",
72
+ };
73
+ const details = {};
74
+ if (pg) {
75
+ try {
76
+ await pg.pool.query("select 1");
77
+ checks.database = "ok";
78
+ }
79
+ catch (err) {
80
+ checks.database = "error";
81
+ details.database = err instanceof Error ? err.message : String(err);
82
+ }
83
+ }
84
+ return {
85
+ ok: Object.values(checks).every((status) => status === "ok"),
86
+ service: "voyant-workflows-selfhost",
87
+ checks,
88
+ details: Object.keys(details).length > 0 ? details : undefined,
89
+ };
90
+ };
91
+ const collectMetrics = async () => {
92
+ const runs = await store.list();
93
+ const wakeups = await wakeupStore.list();
94
+ const runsByStatus = runs.reduce((acc, run) => {
95
+ acc[run.status] = (acc[run.status] ?? 0) + 1;
96
+ return acc;
97
+ }, {});
98
+ return renderMetrics({
99
+ workflowsRegistered: listWorkflows().length,
100
+ schedulesRegistered: listSchedules ? listSchedules().length : 0,
101
+ runsTotal: runs.length,
102
+ wakeupsTotal: wakeups.length,
103
+ runsByStatus,
104
+ generatedAtMs: Date.now(),
105
+ });
106
+ };
107
+ const wakeupManager = createPersistentWakeupManager({
108
+ wakeupStore,
109
+ listRuns: () => store.list(),
110
+ getRun: (runId) => store.get(runId),
111
+ saveRun: async (stored) => {
112
+ if (!store.update) {
113
+ throw new Error("snapshot run store does not support update");
114
+ }
115
+ return store.update(stored);
116
+ },
117
+ toRecord: (stored) => snapshotToRecord(stored),
118
+ fromRecord: (record, base) => recordToSnapshot(record, base),
119
+ handler: stepHandler,
120
+ onStreamChunk: ({ runId, chunk }) => chunkBus.publish({ runId, chunk }),
121
+ logger: (level, message, data) => {
122
+ const error = typeof data === "object" && data !== null && "error" in data ? data.error : undefined;
123
+ const details = error ? `: ${String(error)}` : "";
124
+ if (level === "error")
125
+ console.error(`[voyant] ${message}${details}`);
126
+ else
127
+ console.warn(`[voyant] ${message}${details}`);
128
+ },
129
+ createRunStore: createInMemoryRunStore,
130
+ resumeDueAlarmsImpl: resumeDueAlarms,
131
+ leaseOwner,
132
+ intervalMs: opts.wakeupPollIntervalMs,
133
+ leaseMs: opts.wakeupLeaseMs,
134
+ });
135
+ const cancelRun = async ({ runId }) => {
136
+ const existing = await store.get(runId);
137
+ if (!existing)
138
+ return { ok: false, message: `run "${runId}" not found`, exitCode: 1 };
139
+ if (existing.status !== "waiting") {
140
+ return {
141
+ ok: false,
142
+ message: `run "${runId}" is not parked (status: ${existing.status})`,
143
+ exitCode: 2,
144
+ };
145
+ }
146
+ if (!store.update) {
147
+ return { ok: false, message: "snapshot run store does not support update", exitCode: 1 };
148
+ }
149
+ const now = Date.now();
150
+ const updated = {
151
+ ...existing,
152
+ status: "cancelled",
153
+ completedAt: now,
154
+ durationMs: now - existing.startedAt,
155
+ result: {
156
+ ...existing.result,
157
+ status: "cancelled",
158
+ cancelledAt: now,
159
+ },
160
+ };
161
+ const saved = await store.update(updated);
162
+ await wakeupManager.clear(runId);
163
+ return { ok: true, saved };
164
+ };
165
+ const triggerRun = async ({ workflowId, input, runId, tags, triggeredByUserId, }) => {
166
+ const workflow = wfMod.__listRegisteredWorkflows().find((entry) => entry.id === workflowId);
167
+ if (!workflow) {
168
+ return {
169
+ ok: false,
170
+ message: `workflow "${workflowId}" is not registered in ${entryAbs}.`,
171
+ exitCode: 2,
172
+ };
173
+ }
174
+ const nextRunId = runId ?? generateLocalRunId();
175
+ const memStore = createInMemoryRunStore();
176
+ let record;
177
+ try {
178
+ record = await trigger({
179
+ runId: nextRunId,
180
+ workflowId,
181
+ workflowVersion: "local",
182
+ input,
183
+ tenantMeta: localTenantMeta,
184
+ tags,
185
+ triggeredBy: triggeredByUserId === undefined || triggeredByUserId === null
186
+ ? { kind: "api" }
187
+ : { kind: "api", actor: triggeredByUserId },
188
+ timeoutMs: durationToMs(workflow.config.timeout),
189
+ }, {
190
+ store: memStore,
191
+ handler: stepHandler,
192
+ onStreamChunk: (chunk) => chunkBus.publish({ runId: nextRunId, chunk }),
193
+ });
194
+ }
195
+ catch (err) {
196
+ return {
197
+ ok: false,
198
+ message: err instanceof Error ? err.message : String(err),
199
+ exitCode: 1,
200
+ };
201
+ }
202
+ if (!store.update) {
203
+ return { ok: false, message: "snapshot run store does not support update", exitCode: 1 };
204
+ }
205
+ const stored = recordToSnapshot(record);
206
+ stored.entryFile = entryAbs;
207
+ const saved = await store.update(stored);
208
+ await wakeupManager.syncStoredRun(saved);
209
+ return { ok: true, saved };
210
+ };
211
+ const resumeRun = async ({ parentRunId, workflowId: requestedWorkflowId, input, resumeFromStep, seedResults, runId, tags, triggeredByUserId, }) => {
212
+ const existing = await store.get(parentRunId);
213
+ let parent;
214
+ if (existing) {
215
+ try {
216
+ parent = snapshotToRecord(existing);
217
+ }
218
+ catch (err) {
219
+ return {
220
+ ok: false,
221
+ message: err instanceof Error ? err.message : String(err),
222
+ exitCode: 1,
223
+ };
224
+ }
225
+ }
226
+ else if (!requestedWorkflowId) {
227
+ return {
228
+ ok: false,
229
+ message: `parent run "${parentRunId}" not found; pass workflowId, resumeFromStep, ` +
230
+ "and seedResults to resume from an external workflow-runs parent",
231
+ exitCode: 1,
232
+ };
233
+ }
234
+ const workflowId = parent?.workflowId ?? requestedWorkflowId;
235
+ const workflow = wfMod.__listRegisteredWorkflows().find((entry) => entry.id === workflowId);
236
+ if (!workflow) {
237
+ return {
238
+ ok: false,
239
+ message: `workflow "${workflowId}" is not registered in ${entryAbs}.`,
240
+ exitCode: 2,
241
+ };
242
+ }
243
+ let resumeSeed;
244
+ try {
245
+ resumeSeed = parent
246
+ ? buildResumeJournal({
247
+ parent,
248
+ resumeFromStep,
249
+ seedResults,
250
+ })
251
+ : buildSeededResumeJournal({
252
+ parentRunId,
253
+ resumeFromStep: requireExternalResumeFromStep(resumeFromStep),
254
+ seedResults: requireExternalSeedResults(seedResults),
255
+ });
256
+ }
257
+ catch (err) {
258
+ return {
259
+ ok: false,
260
+ message: err instanceof Error ? err.message : String(err),
261
+ exitCode: 2,
262
+ };
263
+ }
264
+ const memStore = createInMemoryRunStore();
265
+ const nextRunId = runId ?? generateLocalRunId();
266
+ let record;
267
+ try {
268
+ record = await trigger({
269
+ runId: nextRunId,
270
+ workflowId,
271
+ workflowVersion: parent?.workflowVersion ?? "local",
272
+ input: input === undefined ? parent?.input : input,
273
+ tenantMeta: parent?.tenantMeta ?? localTenantMeta,
274
+ environment: parent?.environment,
275
+ triggeredBy: triggeredByUserId === undefined || triggeredByUserId === null
276
+ ? { kind: "api" }
277
+ : { kind: "api", actor: triggeredByUserId },
278
+ tags: mergeTags(parent?.tags, [
279
+ "resume:true",
280
+ `parentRunId:${parent?.id ?? parentRunId}`,
281
+ ...(tags ?? []),
282
+ ]),
283
+ timeoutMs: durationToMs(workflow.config.timeout),
284
+ initialJournal: resumeSeed.journal,
285
+ initialMetadataAppliedCount: resumeSeed.metadataAppliedCount,
286
+ }, {
287
+ store: memStore,
288
+ handler: stepHandler,
289
+ onStreamChunk: (chunk) => chunkBus.publish({ runId: nextRunId, chunk }),
290
+ });
291
+ }
292
+ catch (err) {
293
+ return {
294
+ ok: false,
295
+ message: err instanceof Error ? err.message : String(err),
296
+ exitCode: 1,
297
+ };
298
+ }
299
+ if (!store.update) {
300
+ return { ok: false, message: "snapshot run store does not support update", exitCode: 1 };
301
+ }
302
+ const stored = recordToSnapshot(record, {
303
+ entryFile: entryAbs,
304
+ replayOf: parent?.id ?? parentRunId,
305
+ });
306
+ const saved = await store.update(stored);
307
+ await wakeupManager.syncStoredRun(saved);
308
+ return {
309
+ ok: true,
310
+ saved,
311
+ parentRunId: parent?.id ?? parentRunId,
312
+ resumeFromStep: resumeSeed.resumeFromStep,
313
+ };
314
+ };
315
+ const injectWaitpoint = async ({ runId, injection }) => {
316
+ const existing = await store.get(runId);
317
+ if (!existing) {
318
+ return { ok: false, message: `run "${runId}" not found`, exitCode: 1 };
319
+ }
320
+ if (existing.status !== "waiting") {
321
+ return {
322
+ ok: false,
323
+ message: `run "${runId}" is not parked (status: ${existing.status})`,
324
+ exitCode: 2,
325
+ };
326
+ }
327
+ const record = snapshotToRecord(existing);
328
+ if (!record) {
329
+ return { ok: false, message: `run "${runId}" has no resumable snapshot`, exitCode: 1 };
330
+ }
331
+ const memStore = createInMemoryRunStore();
332
+ await memStore.save(record);
333
+ const out = await resume({ runId, injection }, {
334
+ store: memStore,
335
+ handler: stepHandler,
336
+ onStreamChunk: (chunk) => chunkBus.publish({ runId, chunk }),
337
+ });
338
+ if (!out.ok) {
339
+ const exitCode = out.status === "no_match" || out.status === "not_parked" ? 2 : 1;
340
+ return { ok: false, message: out.message, exitCode };
341
+ }
342
+ if (!store.update) {
343
+ return { ok: false, message: "snapshot run store does not support update", exitCode: 1 };
344
+ }
345
+ const saved = await store.update(recordToSnapshot(out.record, existing));
346
+ await wakeupManager.syncStoredRun(saved);
347
+ return { ok: true, saved };
348
+ };
349
+ try {
350
+ await wakeupManager.bootstrap();
351
+ }
352
+ catch (err) {
353
+ console.warn(`[voyant] failed to bootstrap wakeup leases from run store: ${err instanceof Error ? err.message : String(err)}`);
354
+ }
355
+ wakeupManager.start();
356
+ let scheduler;
357
+ let listSchedules;
358
+ const sources = [];
359
+ for (const workflow of wfMod.__listRegisteredWorkflows()) {
360
+ const decl = workflow.config.schedule;
361
+ if (!decl)
362
+ continue;
363
+ const decls = Array.isArray(decl) ? decl : [decl];
364
+ for (const source of decls) {
365
+ sources.push({ workflowId: workflow.id, decl: source });
366
+ }
367
+ }
368
+ if (sources.length > 0) {
369
+ scheduler = createScheduler({
370
+ sources,
371
+ onFire: async ({ workflowId, input }) => {
372
+ await triggerRun({ workflowId, input });
373
+ },
374
+ logger: (level, message) => {
375
+ if (level === "error")
376
+ console.error(`[scheduler] ${message}`);
377
+ else if (level === "warn")
378
+ console.warn(`[scheduler] ${message}`);
379
+ },
380
+ });
381
+ listSchedules = () => scheduler.nextFirings();
382
+ }
383
+ return {
384
+ store,
385
+ createServer,
386
+ healthCheck,
387
+ readinessCheck,
388
+ collectMetrics,
389
+ shutdown: async () => {
390
+ wakeupManager.stop();
391
+ await pg?.close();
392
+ },
393
+ staticDir,
394
+ triggerRun,
395
+ resumeRun,
396
+ listWorkflows,
397
+ injectWaitpoint,
398
+ scheduler,
399
+ listSchedules,
400
+ cancelRun,
401
+ chunkBus,
402
+ };
403
+ }
@@ -0,0 +1,4 @@
1
+ export declare function mergeTags(...groups: ReadonlyArray<ReadonlyArray<string> | undefined>): string[];
2
+ export declare function requireExternalResumeFromStep(resumeFromStep: string | undefined): string;
3
+ export declare function requireExternalSeedResults(seedResults: Record<string, unknown> | undefined): Record<string, unknown>;
4
+ //# sourceMappingURL=node-selfhost-resume-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-selfhost-resume-input.d.ts","sourceRoot":"","sources":["../src/node-selfhost-resume-input.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,CAM/F;AAED,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAOxF;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC/C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzB"}
@@ -0,0 +1,20 @@
1
+ export function mergeTags(...groups) {
2
+ const tags = new Set();
3
+ for (const group of groups) {
4
+ for (const tag of group ?? [])
5
+ tags.add(tag);
6
+ }
7
+ return Array.from(tags);
8
+ }
9
+ export function requireExternalResumeFromStep(resumeFromStep) {
10
+ if (!resumeFromStep) {
11
+ throw new Error("resumeFromStep is required when the parent run is not stored by this self-host server");
12
+ }
13
+ return resumeFromStep;
14
+ }
15
+ export function requireExternalSeedResults(seedResults) {
16
+ if (!seedResults) {
17
+ throw new Error("seedResults is required when the parent run is not stored by this self-host server");
18
+ }
19
+ return seedResults;
20
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"node-standalone-driver.d.ts","sourceRoot":"","sources":["../src/node-standalone-driver.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,aAAa,EAOd,MAAM,4BAA4B,CAAA;AAInC,OAAO,EAML,KAAK,SAAS,EAId,KAAK,WAAW,EAEjB,MAAM,kCAAkC,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAWxD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;AAIpC,MAAM,WAAW,2BAA2B;IAC1C,4EAA4E;IAC5E,EAAE,EAAE,EAAE,CAAA;IACN,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;IAC7D,wDAAwD;IACxD,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAA;IACpC,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,2DAA2D;IAC3D,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAUD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,2BAA2B,GAAG,aAAa,CAuX3F"}
1
+ {"version":3,"file":"node-standalone-driver.d.ts","sourceRoot":"","sources":["../src/node-standalone-driver.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,aAAa,EAOd,MAAM,4BAA4B,CAAA;AAInC,OAAO,EAML,KAAK,SAAS,EAId,KAAK,WAAW,EAEjB,MAAM,kCAAkC,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAWxD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;AAIpC,MAAM,WAAW,2BAA2B;IAC1C,4EAA4E;IAC5E,EAAE,EAAE,EAAE,CAAA;IACN,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;IAC7D,wDAAwD;IACxD,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAA;IACpC,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,2DAA2D;IAC3D,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAiED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,2BAA2B,GAAG,aAAa,CAuX3F"}
@@ -1,4 +1,5 @@
1
1
  // Mode 2 driver — pure Node, Postgres-backed.
2
+ // agent-quality: file-size exception -- Public driver factory currently owns manifest, trigger, event-ingest, schedule, and admin wiring; split only with a dedicated driver-surface refactor.
2
3
  //
3
4
  // Returns a `DriverFactory` (per architecture doc §6.3) that the framework
4
5
  // invokes after `createApp()` has assembled its `ModuleContainer`. Composes:
@@ -30,6 +31,42 @@ const DEFAULT_TENANT_META = {
30
31
  organizationId: "default",
31
32
  };
32
33
  const DEFAULT_MANIFEST_KEEP = 3;
34
+ function serializeWorkflowManifest(manifest) {
35
+ return { ...manifest };
36
+ }
37
+ function deserializeWorkflowManifest(manifest) {
38
+ const { schemaVersion, projectId, versionId, builtAt, builderVersion, capabilities, workflows, eventFilters, bindings, environments, } = manifest;
39
+ if (schemaVersion !== 1 ||
40
+ typeof projectId !== "string" ||
41
+ typeof versionId !== "string" ||
42
+ typeof builtAt !== "number" ||
43
+ typeof builderVersion !== "string" ||
44
+ !isStringArray(capabilities) ||
45
+ !Array.isArray(workflows) ||
46
+ !Array.isArray(eventFilters) ||
47
+ !isRecord(bindings) ||
48
+ !isRecord(environments)) {
49
+ throw new Error("stored workflow manifest has an invalid shape");
50
+ }
51
+ return {
52
+ schemaVersion,
53
+ projectId,
54
+ versionId,
55
+ builtAt,
56
+ builderVersion,
57
+ capabilities,
58
+ workflows: workflows,
59
+ eventFilters: eventFilters,
60
+ bindings: bindings,
61
+ environments: environments,
62
+ };
63
+ }
64
+ function isRecord(value) {
65
+ return typeof value === "object" && value !== null && !Array.isArray(value);
66
+ }
67
+ function isStringArray(value) {
68
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
69
+ }
33
70
  /**
34
71
  * Build the Mode 2 driver factory. The factory closes over its options
35
72
  * and returns a fresh `WorkflowDriver` when `createApp()` (or a test)
@@ -114,7 +151,7 @@ export function createNodeStandaloneDriver(opts) {
114
151
  const result = await manifestStore.registerManifest({
115
152
  environment: args.environment,
116
153
  versionId: args.manifest.versionId,
117
- manifest: args.manifest,
154
+ manifest: serializeWorkflowManifest(args.manifest),
118
155
  });
119
156
  // Best-effort prune; failures here shouldn't fail boot.
120
157
  try {
@@ -133,7 +170,7 @@ export function createNodeStandaloneDriver(opts) {
133
170
  const envelope = await manifestStore.getCurrent(args.environment);
134
171
  if (!envelope)
135
172
  return null;
136
- return envelope.manifest;
173
+ return deserializeWorkflowManifest(envelope.manifest);
137
174
  }
138
175
  async function trigger(workflow, input, triggerOpts) {
139
176
  assertNotShutdown(shuttingDown);
@@ -167,7 +204,7 @@ export function createNodeStandaloneDriver(opts) {
167
204
  };
168
205
  }
169
206
  const eventId = await ensureEventId(args.envelope);
170
- const manifest = stored.manifest;
207
+ const manifest = deserializeWorkflowManifest(stored.manifest);
171
208
  const routed = routeEvent({
172
209
  manifest,
173
210
  envelope: args.envelope,
@@ -0,0 +1,3 @@
1
+ import type { StepRunner } from "@voyantjs/workflows/handler";
2
+ export declare const nodeStepRunner: StepRunner;
3
+ //# sourceMappingURL=node-step-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-step-runner.d.ts","sourceRoot":"","sources":["../src/node-step-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAE7D,eAAO,MAAM,cAAc,EAAE,UAyB5B,CAAA"}
@@ -0,0 +1,26 @@
1
+ export const nodeStepRunner = async ({ attempt, fn, stepCtx }) => {
2
+ const startedAt = Date.now();
3
+ try {
4
+ const output = await fn(stepCtx);
5
+ return { attempt, status: "ok", output, startedAt, finishedAt: Date.now() };
6
+ }
7
+ catch (err) {
8
+ const error = err;
9
+ const code = typeof err.code === "string"
10
+ ? err.code
11
+ : "UNKNOWN";
12
+ return {
13
+ attempt,
14
+ status: "err",
15
+ error: {
16
+ category: "USER_ERROR",
17
+ code,
18
+ message: error?.message ?? String(err),
19
+ name: error?.name,
20
+ stack: error?.stack,
21
+ },
22
+ startedAt,
23
+ finishedAt: Date.now(),
24
+ };
25
+ }
26
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-manifest-store.d.ts","sourceRoot":"","sources":["../src/postgres-manifest-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAIxD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;AAE5C;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAE5E,iEAAiE;IACjE,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAEjE,uEAAuE;IACvE,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACjF;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,UAAU,CAAA;CACf;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,4BAA4B,GAAG,aAAa,CA8F7F"}
1
+ {"version":3,"file":"postgres-manifest-store.d.ts","sourceRoot":"","sources":["../src/postgres-manifest-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAIxD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;AAE5C;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAE5E,iEAAiE;IACjE,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAEjE,uEAAuE;IACvE,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACjF;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,UAAU,CAAA;CACf;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,4BAA4B,GAAG,aAAa,CAgG7F"}
@@ -73,9 +73,13 @@ export function createPostgresManifestStore(opts) {
73
73
  const keepIds = newest.map((r) => r.versionId);
74
74
  if (keepIds.length === 0)
75
75
  return { deleted: 0 };
76
- const result = await db.execute(sql `DELETE FROM ${workflowManifestsTable}
76
+ const result = await db.execute(
77
+ // agent-quality: raw-sql reviewed -- owner: workflows-orchestrator-node; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
78
+ sql `DELETE FROM ${workflowManifestsTable}
77
79
  WHERE environment = ${environment}
78
- AND version_id NOT IN (${sql.join(keepIds.map((id) => sql `${id}`), sql `, `)})`);
80
+ AND version_id NOT IN (${sql.join(
81
+ // agent-quality: raw-sql reviewed -- owner: workflows-orchestrator-node; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
82
+ keepIds.map((id) => sql `${id}`), sql `, `)})`);
79
83
  return { deleted: result.rowCount ?? 0 };
80
84
  },
81
85
  };
@@ -134,7 +134,7 @@ function recordToValues(record) {
134
134
  completedAt: record.completedAt,
135
135
  }),
136
136
  input: normalizeJson(record.input),
137
- runRecord: normalizeRequiredJson(record),
137
+ runRecord: normalizeRequiredJson({ ...record }),
138
138
  entryFile: null,
139
139
  replayOf: null,
140
140
  idempotencyKey: record.idempotencyKey ?? null,
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-schema.d.ts","sourceRoot":"","sources":["../src/postgres-schema.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0C7B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcxB,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAelC,CAAA"}
1
+ {"version":3,"file":"postgres-schema.d.ts","sourceRoot":"","sources":["../src/postgres-schema.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2C7B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcxB,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBlC,CAAA"}
@@ -31,6 +31,7 @@ export const snapshotRunsTable = pgTable("voyant_snapshot_runs", {
31
31
  */
32
32
  idempotencyIdx: uniqueIndex("voyant_snapshot_runs_idempotency_idx")
33
33
  .on(table.workflowId, table.idempotencyKey)
34
+ // agent-quality: raw-sql reviewed -- owner: workflows-orchestrator-node; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
34
35
  .where(sql `${table.idempotencyKey} IS NOT NULL`),
35
36
  }));
36
37
  export const wakeupsTable = pgTable("voyant_wakeups", {
@@ -64,5 +65,6 @@ export const workflowManifestsTable = pgTable("voyant_workflow_manifests", {
64
65
  pk: primaryKey({ columns: [table.environment, table.versionId] }),
65
66
  currentIdx: uniqueIndex("voyant_workflow_manifests_current_idx")
66
67
  .on(table.environment)
68
+ // agent-quality: raw-sql reviewed -- owner: workflows-orchestrator-node; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
67
69
  .where(sql `${table.isCurrent}`),
68
70
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"sleep-alarm-manager.d.ts","sourceRoot":"","sources":["../src/sleep-alarm-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,KAAK,SAAS,EACd,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,kCAAkC,CAAA;AAEzC,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB,CAAC,OAAO,SAAS,mBAAmB;IACxE,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAClC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAA;IACvD,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9C,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,CAAA;IACxC,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAA;IAC1D,OAAO,EAAE,WAAW,CAAA;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAA;IACtE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,UAAU,CAAA;IAC9B,YAAY,CAAC,EAAE,OAAO,YAAY,CAAA;IAClC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1E,cAAc,CAAC,EAAE,OAAO,sBAAsB,CAAA;IAC9C,mBAAmB,CAAC,EAAE,OAAO,eAAe,CAAA;CAC7C;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,SAAS,mBAAmB;IACpE,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,SAAS,mBAAmB,EACzE,IAAI,EAAE,qBAAqB,CAAC,OAAO,CAAC,GACnC,iBAAiB,CAAC,OAAO,CAAC,CAmF5B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CASxE"}
1
+ {"version":3,"file":"sleep-alarm-manager.d.ts","sourceRoot":"","sources":["../src/sleep-alarm-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,KAAK,SAAS,EACd,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,kCAAkC,CAAA;AAEzC,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB,CAAC,OAAO,SAAS,mBAAmB;IACxE,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAClC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAA;IACvD,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9C,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,CAAA;IACxC,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAA;IAC1D,OAAO,EAAE,WAAW,CAAA;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAA;IACtE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,UAAU,CAAA;IAC9B,YAAY,CAAC,EAAE,OAAO,YAAY,CAAA;IAClC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1E,cAAc,CAAC,EAAE,OAAO,sBAAsB,CAAA;IAC9C,mBAAmB,CAAC,EAAE,OAAO,eAAe,CAAA;CAC7C;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,SAAS,mBAAmB;IACpE,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB;AAaD,wBAAgB,uBAAuB,CAAC,OAAO,SAAS,mBAAmB,EACzE,IAAI,EAAE,qBAAqB,CAAC,OAAO,CAAC,GACnC,iBAAiB,CAAC,OAAO,CAAC,CAmF5B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CASxE"}
@@ -1,4 +1,12 @@
1
1
  import { createInMemoryRunStore, resumeDueAlarms, } from "@voyantjs/workflows-orchestrator";
2
+ function unrefTimer(timer) {
3
+ if (typeof timer === "object" &&
4
+ timer !== null &&
5
+ "unref" in timer &&
6
+ typeof timer.unref === "function") {
7
+ timer.unref();
8
+ }
9
+ }
2
10
  export function createSleepAlarmManager(deps) {
3
11
  const now = deps.now ?? (() => Date.now());
4
12
  const setTimeoutImpl = deps.setTimeout ?? setTimeout;
@@ -59,7 +67,7 @@ export function createSleepAlarmManager(deps) {
59
67
  });
60
68
  });
61
69
  }, delay);
62
- timer.unref?.();
70
+ unrefTimer(timer);
63
71
  timers.set(stored.id, timer);
64
72
  };
65
73
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"store-stream.d.ts","sourceRoot":"","sources":["../src/store-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAE1E,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,MAAM,IAAI,CAAA;IAClD,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,eAAe,EAAE,MAAM,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,WAAW,CAAA;IAChC,aAAa,CAAC,EAAE,OAAO,aAAa,CAAA;CACrC;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,IAAI,EAAE,SAAS,SAAS,EAAE,GACzB,UAAU,EAAE,CAuBd;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,gBAAgB,EACvB,IAAI,GAAE,kBAAuB,GAC5B,WAAW,CA8Db"}
1
+ {"version":3,"file":"store-stream.d.ts","sourceRoot":"","sources":["../src/store-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAE1E,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,MAAM,IAAI,CAAA;IAClD,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,eAAe,EAAE,MAAM,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,WAAW,CAAA;IAChC,aAAa,CAAC,EAAE,OAAO,aAAa,CAAA;CACrC;AAaD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,IAAI,EAAE,SAAS,SAAS,EAAE,GACzB,UAAU,EAAE,CAuBd;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,gBAAgB,EACvB,IAAI,GAAE,kBAAuB,GAC5B,WAAW,CA8Db"}