@hazeljs/flow 0.2.0-beta.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/README.md +111 -0
- package/dist/decorators/flow.decorators.d.ts +32 -0
- package/dist/decorators/flow.decorators.d.ts.map +1 -0
- package/dist/decorators/flow.decorators.js +100 -0
- package/dist/dsl/flow.d.ts +19 -0
- package/dist/dsl/flow.d.ts.map +1 -0
- package/dist/dsl/flow.js +46 -0
- package/dist/dsl/types.d.ts +5 -0
- package/dist/dsl/types.d.ts.map +1 -0
- package/dist/dsl/types.js +2 -0
- package/dist/engine/Executor.d.ts +11 -0
- package/dist/engine/Executor.d.ts.map +1 -0
- package/dist/engine/Executor.js +113 -0
- package/dist/engine/FlowEngine.d.ts +46 -0
- package/dist/engine/FlowEngine.d.ts.map +1 -0
- package/dist/engine/FlowEngine.js +237 -0
- package/dist/engine/Idempotency.d.ts +10 -0
- package/dist/engine/Idempotency.d.ts.map +1 -0
- package/dist/engine/Idempotency.js +16 -0
- package/dist/engine/Locks.d.ts +11 -0
- package/dist/engine/Locks.d.ts.map +1 -0
- package/dist/engine/Locks.js +68 -0
- package/dist/engine/Retry.d.ts +7 -0
- package/dist/engine/Retry.d.ts.map +1 -0
- package/dist/engine/Retry.js +22 -0
- package/dist/engine/Timeout.d.ts +10 -0
- package/dist/engine/Timeout.d.ts.map +1 -0
- package/dist/engine/Timeout.js +25 -0
- package/dist/engine/Transition.d.ts +6 -0
- package/dist/engine/Transition.d.ts.map +1 -0
- package/dist/engine/Transition.js +19 -0
- package/dist/engine/utils.d.ts +5 -0
- package/dist/engine/utils.d.ts.map +1 -0
- package/dist/engine/utils.js +25 -0
- package/dist/examples/branching.d.ts +2 -0
- package/dist/examples/branching.d.ts.map +1 -0
- package/dist/examples/branching.js +72 -0
- package/dist/examples/simple.d.ts +2 -0
- package/dist/examples/simple.d.ts.map +1 -0
- package/dist/examples/simple.js +65 -0
- package/dist/examples/wait_resume.d.ts +2 -0
- package/dist/examples/wait_resume.d.ts.map +1 -0
- package/dist/examples/wait_resume.js +75 -0
- package/dist/generated/prisma/client.d.ts +1 -0
- package/dist/generated/prisma/client.js +5 -0
- package/dist/generated/prisma/default.d.ts +1 -0
- package/dist/generated/prisma/default.js +5 -0
- package/dist/generated/prisma/edge.d.ts +1 -0
- package/dist/generated/prisma/edge.js +250 -0
- package/dist/generated/prisma/index-browser.js +236 -0
- package/dist/generated/prisma/index.d.ts +6577 -0
- package/dist/generated/prisma/index.js +271 -0
- package/dist/generated/prisma/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
- package/dist/generated/prisma/package.json +183 -0
- package/dist/generated/prisma/query_engine_bg.js +2 -0
- package/dist/generated/prisma/query_engine_bg.wasm +0 -0
- package/dist/generated/prisma/runtime/edge-esm.js +35 -0
- package/dist/generated/prisma/runtime/edge.js +35 -0
- package/dist/generated/prisma/runtime/index-browser.d.ts +370 -0
- package/dist/generated/prisma/runtime/index-browser.js +17 -0
- package/dist/generated/prisma/runtime/library.d.ts +3982 -0
- package/dist/generated/prisma/runtime/library.js +147 -0
- package/dist/generated/prisma/runtime/react-native.js +84 -0
- package/dist/generated/prisma/runtime/wasm-compiler-edge.js +85 -0
- package/dist/generated/prisma/runtime/wasm-engine-edge.js +38 -0
- package/dist/generated/prisma/schema.prisma +70 -0
- package/dist/generated/prisma/wasm-edge-light-loader.mjs +5 -0
- package/dist/generated/prisma/wasm-worker-loader.mjs +5 -0
- package/dist/generated/prisma/wasm.d.ts +1 -0
- package/dist/generated/prisma/wasm.js +257 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/persistence/FlowDefinitionRepo.d.ts +14 -0
- package/dist/persistence/FlowDefinitionRepo.d.ts.map +1 -0
- package/dist/persistence/FlowDefinitionRepo.js +44 -0
- package/dist/persistence/FlowEventRepo.d.ts +15 -0
- package/dist/persistence/FlowEventRepo.d.ts.map +1 -0
- package/dist/persistence/FlowEventRepo.js +33 -0
- package/dist/persistence/FlowRunRepo.d.ts +12 -0
- package/dist/persistence/FlowRunRepo.d.ts.map +1 -0
- package/dist/persistence/FlowRunRepo.js +50 -0
- package/dist/persistence/IdempotencyRepo.d.ts +15 -0
- package/dist/persistence/IdempotencyRepo.d.ts.map +1 -0
- package/dist/persistence/IdempotencyRepo.js +39 -0
- package/dist/persistence/memory.d.ts +9 -0
- package/dist/persistence/memory.d.ts.map +1 -0
- package/dist/persistence/memory.js +154 -0
- package/dist/persistence/prisma.d.ts +5 -0
- package/dist/persistence/prisma.d.ts.map +1 -0
- package/dist/persistence/prisma.js +9 -0
- package/dist/persistence/prismaClient.d.ts +21 -0
- package/dist/persistence/prismaClient.d.ts.map +1 -0
- package/dist/persistence/prismaClient.js +47 -0
- package/dist/persistence/prismaStorage.d.ts +11 -0
- package/dist/persistence/prismaStorage.d.ts.map +1 -0
- package/dist/persistence/prismaStorage.js +24 -0
- package/dist/persistence/serialize.d.ts +6 -0
- package/dist/persistence/serialize.d.ts.map +1 -0
- package/dist/persistence/serialize.js +28 -0
- package/dist/persistence/storage.d.ts +75 -0
- package/dist/persistence/storage.d.ts.map +1 -0
- package/dist/persistence/storage.js +6 -0
- package/dist/prisma.d.ts +14 -0
- package/dist/prisma.d.ts.map +1 -0
- package/dist/prisma.js +25 -0
- package/dist/types/Errors.d.ts +21 -0
- package/dist/types/Errors.d.ts.map +1 -0
- package/dist/types/Errors.js +44 -0
- package/dist/types/Events.d.ts +17 -0
- package/dist/types/Events.d.ts.map +1 -0
- package/dist/types/Events.js +5 -0
- package/dist/types/FlowTypes.d.ts +66 -0
- package/dist/types/FlowTypes.d.ts.map +1 -0
- package/dist/types/FlowTypes.js +5 -0
- package/package.json +72 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { FlowDefinition, FlowRunStatus } from '../types/FlowTypes.js';
|
|
2
|
+
import type { FlowRunRow } from '../persistence/storage.js';
|
|
3
|
+
import type { FlowStorage } from '../persistence/storage.js';
|
|
4
|
+
export interface FlowEngineOptions {
|
|
5
|
+
/** Storage (default: in-memory). Use createPrismaStorage(prisma) from @hazeljs/flow/prisma for DB. */
|
|
6
|
+
storage?: FlowStorage;
|
|
7
|
+
services?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface StartRunArgs {
|
|
10
|
+
flowId: string;
|
|
11
|
+
version: string;
|
|
12
|
+
tenantId?: string;
|
|
13
|
+
input: unknown;
|
|
14
|
+
initialState?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface StartRunResult {
|
|
17
|
+
runId: string;
|
|
18
|
+
status: FlowRunStatus;
|
|
19
|
+
}
|
|
20
|
+
export declare class FlowEngine {
|
|
21
|
+
private readonly storage;
|
|
22
|
+
private readonly services;
|
|
23
|
+
private readonly defRegistry;
|
|
24
|
+
constructor(options?: FlowEngineOptions);
|
|
25
|
+
registerDefinition(def: FlowDefinition): Promise<void>;
|
|
26
|
+
private getDefinition;
|
|
27
|
+
startRun(args: StartRunArgs): Promise<StartRunResult>;
|
|
28
|
+
tick(runId: string): Promise<FlowRunRow>;
|
|
29
|
+
private tickCore;
|
|
30
|
+
resumeRun(runId: string, payload?: unknown): Promise<FlowRunRow>;
|
|
31
|
+
getRun(runId: string): Promise<FlowRunRow | null>;
|
|
32
|
+
getRunningRunIds(): Promise<string[]>;
|
|
33
|
+
listFlows(): Promise<Array<{
|
|
34
|
+
flowId: string;
|
|
35
|
+
version: string;
|
|
36
|
+
definitionJson: unknown;
|
|
37
|
+
}>>;
|
|
38
|
+
getTimeline(runId: string): Promise<Array<{
|
|
39
|
+
at: Date;
|
|
40
|
+
type: string;
|
|
41
|
+
nodeId: string | null;
|
|
42
|
+
attempt: number | null;
|
|
43
|
+
payloadJson: unknown;
|
|
44
|
+
}>>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=FlowEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlowEngine.d.ts","sourceRoot":"","sources":["../../src/engine/FlowEngine.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAe,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAM7D,MAAM,WAAW,iBAAiB;IAChC,sGAAsG;IACtG,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,CAAC;CACvB;AAOD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;gBAErD,OAAO,GAAE,iBAAsB;IAKrC,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5D,OAAO,CAAC,aAAa;IAIf,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAyBrD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAIhC,QAAQ;IAyHhB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAiChE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIjD,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAKrC,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAIzF,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CACvC,KAAK,CAAC;QACJ,EAAE,EAAE,IAAI,CAAC;QACT,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC,CACH;CAGF"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FlowEngine = void 0;
|
|
37
|
+
/**
|
|
38
|
+
* FlowEngine - framework-agnostic execution graph engine
|
|
39
|
+
* Default storage is in-memory (no DB). For DB persistence, pass storage from createPrismaStorage(prisma) via @hazeljs/flow/prisma.
|
|
40
|
+
*/
|
|
41
|
+
const crypto_1 = require("crypto");
|
|
42
|
+
const memory_js_1 = require("../persistence/memory.js");
|
|
43
|
+
const Executor_js_1 = require("./Executor.js");
|
|
44
|
+
const Transition_js_1 = require("./Transition.js");
|
|
45
|
+
const Errors_js_1 = require("../types/Errors.js");
|
|
46
|
+
const RUNNING = 'RUNNING';
|
|
47
|
+
const WAITING = 'WAITING';
|
|
48
|
+
const COMPLETED = 'COMPLETED';
|
|
49
|
+
const FAILED = 'FAILED';
|
|
50
|
+
class FlowEngine {
|
|
51
|
+
constructor(options = {}) {
|
|
52
|
+
this.defRegistry = new Map();
|
|
53
|
+
this.storage = options.storage ?? (0, memory_js_1.createMemoryStorage)();
|
|
54
|
+
this.services = options.services ?? {};
|
|
55
|
+
}
|
|
56
|
+
async registerDefinition(def) {
|
|
57
|
+
this.defRegistry.set(`${def.flowId}@${def.version}`, def);
|
|
58
|
+
await this.storage.definitionRepo.save(def);
|
|
59
|
+
}
|
|
60
|
+
getDefinition(flowId, version) {
|
|
61
|
+
return this.defRegistry.get(`${flowId}@${version}`) ?? null;
|
|
62
|
+
}
|
|
63
|
+
async startRun(args) {
|
|
64
|
+
const def = this.getDefinition(args.flowId, args.version);
|
|
65
|
+
if (!def) {
|
|
66
|
+
throw new Errors_js_1.FlowNotFoundError(args.flowId, args.version);
|
|
67
|
+
}
|
|
68
|
+
const runId = (0, crypto_1.randomUUID)();
|
|
69
|
+
await this.storage.runRepo.create({
|
|
70
|
+
runId,
|
|
71
|
+
flowId: args.flowId,
|
|
72
|
+
flowVersion: args.version,
|
|
73
|
+
tenantId: args.tenantId,
|
|
74
|
+
input: args.input,
|
|
75
|
+
initialState: args.initialState,
|
|
76
|
+
});
|
|
77
|
+
await this.storage.eventRepo.append(runId, 'RUN_STARTED', {});
|
|
78
|
+
await this.storage.runRepo.update(runId, {
|
|
79
|
+
currentNodeId: def.entry,
|
|
80
|
+
});
|
|
81
|
+
return { runId, status: RUNNING };
|
|
82
|
+
}
|
|
83
|
+
async tick(runId) {
|
|
84
|
+
return this.storage.withLock(runId, () => this.tickCore(runId));
|
|
85
|
+
}
|
|
86
|
+
async tickCore(runId) {
|
|
87
|
+
const run = await this.storage.runRepo.get(runId);
|
|
88
|
+
if (!run)
|
|
89
|
+
throw new Errors_js_1.RunNotFoundError(runId);
|
|
90
|
+
if (run.status !== RUNNING && run.status !== WAITING) {
|
|
91
|
+
return run;
|
|
92
|
+
}
|
|
93
|
+
const def = this.getDefinition(run.flowId, run.flowVersion);
|
|
94
|
+
if (!def)
|
|
95
|
+
throw new Errors_js_1.FlowNotFoundError(run.flowId, run.flowVersion);
|
|
96
|
+
const currentNodeId = run.currentNodeId ?? def.entry;
|
|
97
|
+
const node = def.nodes[currentNodeId];
|
|
98
|
+
if (!node) {
|
|
99
|
+
await this.storage.runRepo.update(runId, { status: FAILED });
|
|
100
|
+
await this.storage.eventRepo.append(runId, 'RUN_ABORTED', {
|
|
101
|
+
error: { code: 'NODE_NOT_FOUND', message: `Node ${currentNodeId} not found` },
|
|
102
|
+
});
|
|
103
|
+
return (await this.storage.runRepo.get(runId));
|
|
104
|
+
}
|
|
105
|
+
const ctx = {
|
|
106
|
+
runId,
|
|
107
|
+
flowId: run.flowId,
|
|
108
|
+
flowVersion: run.flowVersion,
|
|
109
|
+
tenantId: run.tenantId ?? undefined,
|
|
110
|
+
input: run.inputJson,
|
|
111
|
+
state: run.stateJson,
|
|
112
|
+
outputs: run.outputsJson,
|
|
113
|
+
meta: { attempts: {}, startedAt: run.createdAt.toISOString() },
|
|
114
|
+
services: this.services,
|
|
115
|
+
};
|
|
116
|
+
const { result, cached } = await (0, Executor_js_1.executeNode)(node, ctx, this.storage.eventRepo, this.storage.idempotencyRepo);
|
|
117
|
+
if (result.status === 'error') {
|
|
118
|
+
await this.storage.runRepo.update(runId, {
|
|
119
|
+
status: FAILED,
|
|
120
|
+
currentNodeId: null,
|
|
121
|
+
});
|
|
122
|
+
await this.storage.eventRepo.append(runId, 'RUN_ABORTED', {
|
|
123
|
+
error: result.error,
|
|
124
|
+
});
|
|
125
|
+
return (await this.storage.runRepo.get(runId));
|
|
126
|
+
}
|
|
127
|
+
if (result.status === 'wait') {
|
|
128
|
+
let newState = ctx.state;
|
|
129
|
+
if (result.patch) {
|
|
130
|
+
const { applyPatch } = await Promise.resolve().then(() => __importStar(require('./Executor.js')));
|
|
131
|
+
newState = applyPatch(ctx.state, result.patch);
|
|
132
|
+
}
|
|
133
|
+
const newOutputs = { ...ctx.outputs, [currentNodeId]: result.output };
|
|
134
|
+
await this.storage.runRepo.update(runId, {
|
|
135
|
+
status: WAITING,
|
|
136
|
+
stateJson: newState,
|
|
137
|
+
outputsJson: newOutputs,
|
|
138
|
+
currentNodeId,
|
|
139
|
+
});
|
|
140
|
+
await this.storage.eventRepo.append(runId, 'RUN_WAITING', {
|
|
141
|
+
nodeId: currentNodeId,
|
|
142
|
+
reason: result.reason,
|
|
143
|
+
until: result.until,
|
|
144
|
+
});
|
|
145
|
+
return (await this.storage.runRepo.get(runId));
|
|
146
|
+
}
|
|
147
|
+
// result.status === 'ok'
|
|
148
|
+
let newState = ctx.state;
|
|
149
|
+
if (result.patch && !cached) {
|
|
150
|
+
const { applyPatch } = await Promise.resolve().then(() => __importStar(require('./Executor.js')));
|
|
151
|
+
newState = applyPatch(ctx.state, result.patch);
|
|
152
|
+
}
|
|
153
|
+
else if (result.patch && cached) {
|
|
154
|
+
newState = { ...ctx.state, ...result.patch };
|
|
155
|
+
}
|
|
156
|
+
const newOutputs = { ...ctx.outputs, [currentNodeId]: result.output };
|
|
157
|
+
let nextNodeId;
|
|
158
|
+
try {
|
|
159
|
+
nextNodeId = (0, Transition_js_1.selectNextNode)(currentNodeId, def.edges, {
|
|
160
|
+
...ctx,
|
|
161
|
+
state: newState,
|
|
162
|
+
outputs: newOutputs,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
const code = err instanceof Error && 'code' in err ? err.code : 'UNKNOWN';
|
|
167
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
168
|
+
await this.storage.runRepo.update(runId, {
|
|
169
|
+
status: FAILED,
|
|
170
|
+
currentNodeId: null,
|
|
171
|
+
});
|
|
172
|
+
await this.storage.eventRepo.append(runId, 'RUN_ABORTED', {
|
|
173
|
+
error: { code, message },
|
|
174
|
+
});
|
|
175
|
+
return (await this.storage.runRepo.get(runId));
|
|
176
|
+
}
|
|
177
|
+
if (nextNodeId === null) {
|
|
178
|
+
await this.storage.runRepo.update(runId, {
|
|
179
|
+
status: COMPLETED,
|
|
180
|
+
stateJson: newState,
|
|
181
|
+
outputsJson: newOutputs,
|
|
182
|
+
currentNodeId: null,
|
|
183
|
+
});
|
|
184
|
+
await this.storage.eventRepo.append(runId, 'RUN_COMPLETED', {});
|
|
185
|
+
return (await this.storage.runRepo.get(runId));
|
|
186
|
+
}
|
|
187
|
+
await this.storage.runRepo.update(runId, {
|
|
188
|
+
stateJson: newState,
|
|
189
|
+
outputsJson: newOutputs,
|
|
190
|
+
currentNodeId: nextNodeId,
|
|
191
|
+
});
|
|
192
|
+
return (await this.storage.runRepo.get(runId));
|
|
193
|
+
}
|
|
194
|
+
async resumeRun(runId, payload) {
|
|
195
|
+
return this.storage.withLock(runId, async () => {
|
|
196
|
+
const run = await this.storage.runRepo.get(runId);
|
|
197
|
+
if (!run)
|
|
198
|
+
throw new Errors_js_1.RunNotFoundError(runId);
|
|
199
|
+
if (run.status !== WAITING) {
|
|
200
|
+
return run;
|
|
201
|
+
}
|
|
202
|
+
const def = this.getDefinition(run.flowId, run.flowVersion);
|
|
203
|
+
if (!def)
|
|
204
|
+
throw new Errors_js_1.FlowNotFoundError(run.flowId, run.flowVersion);
|
|
205
|
+
const currentNodeId = run.currentNodeId;
|
|
206
|
+
const node = def.nodes[currentNodeId];
|
|
207
|
+
if (!node) {
|
|
208
|
+
await this.storage.runRepo.update(runId, { status: FAILED });
|
|
209
|
+
return (await this.storage.runRepo.get(runId));
|
|
210
|
+
}
|
|
211
|
+
// Merge payload into state (e.g. for wait/resume flows)
|
|
212
|
+
let newState = run.stateJson;
|
|
213
|
+
if (payload != null && typeof payload === 'object') {
|
|
214
|
+
newState = { ...newState, _resumePayload: payload };
|
|
215
|
+
}
|
|
216
|
+
await this.storage.runRepo.update(runId, {
|
|
217
|
+
status: RUNNING,
|
|
218
|
+
stateJson: newState,
|
|
219
|
+
});
|
|
220
|
+
return this.tickCore(runId);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
async getRun(runId) {
|
|
224
|
+
return this.storage.runRepo.get(runId);
|
|
225
|
+
}
|
|
226
|
+
async getRunningRunIds() {
|
|
227
|
+
const runs = await this.storage.runRepo.findRunning();
|
|
228
|
+
return runs.map((r) => r.runId);
|
|
229
|
+
}
|
|
230
|
+
async listFlows() {
|
|
231
|
+
return this.storage.definitionRepo.list();
|
|
232
|
+
}
|
|
233
|
+
async getTimeline(runId) {
|
|
234
|
+
return this.storage.eventRepo.getTimeline(runId);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.FlowEngine = FlowEngine;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotency check and store helpers
|
|
3
|
+
*/
|
|
4
|
+
import type { IIdempotencyRepo } from '../persistence/storage.js';
|
|
5
|
+
export declare function checkIdempotency(repo: IIdempotencyRepo, key: string): Promise<{
|
|
6
|
+
output?: unknown;
|
|
7
|
+
patch?: Record<string, unknown>;
|
|
8
|
+
} | null>;
|
|
9
|
+
export declare function storeIdempotency(repo: IIdempotencyRepo, key: string, runId: string, nodeId: string, output?: unknown, patch?: Record<string, unknown>): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=Idempotency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Idempotency.d.ts","sourceRoot":"","sources":["../../src/engine/Idempotency.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAAC,CAOvE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkIdempotency = checkIdempotency;
|
|
4
|
+
exports.storeIdempotency = storeIdempotency;
|
|
5
|
+
async function checkIdempotency(repo, key) {
|
|
6
|
+
const record = await repo.get(key);
|
|
7
|
+
if (!record)
|
|
8
|
+
return null;
|
|
9
|
+
return {
|
|
10
|
+
output: record.outputJson,
|
|
11
|
+
patch: record.patchJson,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async function storeIdempotency(repo, key, runId, nodeId, output, patch) {
|
|
15
|
+
await repo.set(key, runId, nodeId, output, patch);
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres advisory locks for flow run concurrency safety.
|
|
3
|
+
* Uses a stable hash of runId -> bigint for pg_advisory_lock.
|
|
4
|
+
*
|
|
5
|
+
* Hash algorithm: djb2-like string hash, then take mod to fit in int8 range.
|
|
6
|
+
* PostgreSQL advisory lock keys are int8 (signed 64-bit).
|
|
7
|
+
*/
|
|
8
|
+
import type { PrismaClient } from '../persistence/prisma.js';
|
|
9
|
+
export declare function runIdToLockKey(runId: string): bigint;
|
|
10
|
+
export declare function withAdvisoryLock<T>(prisma: PrismaClient, runId: string, fn: () => Promise<T>): Promise<T>;
|
|
11
|
+
//# sourceMappingURL=Locks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Locks.d.ts","sourceRoot":"","sources":["../../src/engine/Locks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD;AAED,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAaZ"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Postgres advisory locks for flow run concurrency safety.
|
|
4
|
+
* Uses a stable hash of runId -> bigint for pg_advisory_lock.
|
|
5
|
+
*
|
|
6
|
+
* Hash algorithm: djb2-like string hash, then take mod to fit in int8 range.
|
|
7
|
+
* PostgreSQL advisory lock keys are int8 (signed 64-bit).
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.runIdToLockKey = runIdToLockKey;
|
|
44
|
+
exports.withAdvisoryLock = withAdvisoryLock;
|
|
45
|
+
function runIdToLockKey(runId) {
|
|
46
|
+
let hash = 5381;
|
|
47
|
+
for (let i = 0; i < runId.length; i++) {
|
|
48
|
+
hash = ((hash << 5) + hash) ^ runId.charCodeAt(i);
|
|
49
|
+
}
|
|
50
|
+
// Ensure positive and within safe int8 range (use MAX_SAFE_INTEGER to avoid precision loss)
|
|
51
|
+
const h = Math.abs(hash);
|
|
52
|
+
return BigInt(h % Number.MAX_SAFE_INTEGER);
|
|
53
|
+
}
|
|
54
|
+
async function withAdvisoryLock(prisma, runId, fn) {
|
|
55
|
+
const key = runIdToLockKey(runId);
|
|
56
|
+
try {
|
|
57
|
+
const result = await prisma.$queryRaw `SELECT pg_try_advisory_lock(${key}) as acquired`;
|
|
58
|
+
const acquired = result[0]?.acquired;
|
|
59
|
+
if (!acquired) {
|
|
60
|
+
const { LockBusyError } = await Promise.resolve().then(() => __importStar(require('../types/Errors.js')));
|
|
61
|
+
throw new LockBusyError(runId);
|
|
62
|
+
}
|
|
63
|
+
return await fn();
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
await prisma.$executeRaw `SELECT pg_advisory_unlock(${key})`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry logic with fixed or exponential backoff
|
|
3
|
+
*/
|
|
4
|
+
import type { RetryPolicy } from '../types/FlowTypes.js';
|
|
5
|
+
export declare function delay(ms: number): Promise<void>;
|
|
6
|
+
export declare function getRetryDelayMs(attempt: number, policy: RetryPolicy): number;
|
|
7
|
+
//# sourceMappingURL=Retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Retry.d.ts","sourceRoot":"","sources":["../../src/engine/Retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAY5E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.delay = delay;
|
|
4
|
+
exports.getRetryDelayMs = getRetryDelayMs;
|
|
5
|
+
function delay(ms) {
|
|
6
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7
|
+
}
|
|
8
|
+
function getRetryDelayMs(attempt, policy) {
|
|
9
|
+
if (attempt >= policy.maxAttempts)
|
|
10
|
+
return -1;
|
|
11
|
+
let ms;
|
|
12
|
+
if (policy.backoff === 'exponential') {
|
|
13
|
+
ms = policy.baseDelayMs * Math.pow(2, attempt);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
ms = policy.baseDelayMs;
|
|
17
|
+
}
|
|
18
|
+
if (policy.maxDelayMs != null && ms > policy.maxDelayMs) {
|
|
19
|
+
ms = policy.maxDelayMs;
|
|
20
|
+
}
|
|
21
|
+
return ms;
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-node timeout via Promise.race
|
|
3
|
+
*/
|
|
4
|
+
export declare class TimeoutError extends Error {
|
|
5
|
+
readonly nodeId: string;
|
|
6
|
+
readonly timeoutMs: number;
|
|
7
|
+
constructor(message: string, nodeId: string, timeoutMs: number);
|
|
8
|
+
}
|
|
9
|
+
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, nodeId: string): Promise<T>;
|
|
10
|
+
//# sourceMappingURL=Timeout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timeout.d.ts","sourceRoot":"","sources":["../../src/engine/Timeout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,YAAa,SAAQ,KAAK;aAGnB,MAAM,EAAE,MAAM;aACd,SAAS,EAAE,MAAM;gBAFjC,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM;CAMpC;AAED,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,CAOZ"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Per-node timeout via Promise.race
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TimeoutError = void 0;
|
|
7
|
+
exports.withTimeout = withTimeout;
|
|
8
|
+
class TimeoutError extends Error {
|
|
9
|
+
constructor(message, nodeId, timeoutMs) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.nodeId = nodeId;
|
|
12
|
+
this.timeoutMs = timeoutMs;
|
|
13
|
+
this.name = 'TimeoutError';
|
|
14
|
+
this.code = 'TIMEOUT';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.TimeoutError = TimeoutError;
|
|
18
|
+
async function withTimeout(promise, timeoutMs, nodeId) {
|
|
19
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
reject(new TimeoutError(`Node ${nodeId} timed out after ${timeoutMs}ms`, nodeId, timeoutMs));
|
|
22
|
+
}, timeoutMs);
|
|
23
|
+
});
|
|
24
|
+
return Promise.race([promise, timeoutPromise]);
|
|
25
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge transition logic - select next node from outgoing edges
|
|
3
|
+
*/
|
|
4
|
+
import type { FlowContext, EdgeDefinition } from '../types/FlowTypes.js';
|
|
5
|
+
export declare function selectNextNode(fromNodeId: string, edges: EdgeDefinition[], ctx: FlowContext): string | null;
|
|
6
|
+
//# sourceMappingURL=Transition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Transition.d.ts","sourceRoot":"","sources":["../../src/engine/Transition.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGzE,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,cAAc,EAAE,EACvB,GAAG,EAAE,WAAW,GACf,MAAM,GAAG,IAAI,CAef"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.selectNextNode = selectNextNode;
|
|
4
|
+
const Errors_js_1 = require("../types/Errors.js");
|
|
5
|
+
function selectNextNode(fromNodeId, edges, ctx) {
|
|
6
|
+
const outgoing = edges.filter((e) => e.from === fromNodeId);
|
|
7
|
+
if (outgoing.length === 0)
|
|
8
|
+
return null;
|
|
9
|
+
const matching = outgoing.filter((e) => !e.when || e.when(ctx));
|
|
10
|
+
if (matching.length === 0)
|
|
11
|
+
return null;
|
|
12
|
+
const sorted = [...matching].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
13
|
+
const topPriority = sorted[0].priority ?? 0;
|
|
14
|
+
const atTop = sorted.filter((e) => (e.priority ?? 0) === topPriority);
|
|
15
|
+
if (atTop.length > 1) {
|
|
16
|
+
throw new Errors_js_1.AmbiguousEdgeError(fromNodeId);
|
|
17
|
+
}
|
|
18
|
+
return sorted[0].to;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/engine/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmBzB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deepMerge = deepMerge;
|
|
4
|
+
/**
|
|
5
|
+
* Simple deep merge for state patching (MVP)
|
|
6
|
+
*/
|
|
7
|
+
function deepMerge(target, source) {
|
|
8
|
+
const result = { ...target };
|
|
9
|
+
for (const key of Object.keys(source)) {
|
|
10
|
+
const srcVal = source[key];
|
|
11
|
+
const tgtVal = result[key];
|
|
12
|
+
if (srcVal != null &&
|
|
13
|
+
typeof srcVal === 'object' &&
|
|
14
|
+
!Array.isArray(srcVal) &&
|
|
15
|
+
tgtVal != null &&
|
|
16
|
+
typeof tgtVal === 'object' &&
|
|
17
|
+
!Array.isArray(tgtVal)) {
|
|
18
|
+
result[key] = deepMerge(tgtVal, srcVal);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
result[key] = srcVal;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branching.d.ts","sourceRoot":"","sources":["../../src/examples/branching.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/**
|
|
13
|
+
* Branching flow example - conditional edges (decorator-based)
|
|
14
|
+
* Run: npm run example:branching | or from source: npx tsx src/examples/branching.ts
|
|
15
|
+
*/
|
|
16
|
+
const index_js_1 = require("../index.js");
|
|
17
|
+
let BranchingFlow = class BranchingFlow {
|
|
18
|
+
async check(ctx) {
|
|
19
|
+
const score = ctx.input.score;
|
|
20
|
+
return { status: 'ok', output: { score }, patch: { score } };
|
|
21
|
+
}
|
|
22
|
+
async approve() {
|
|
23
|
+
return { status: 'ok', output: { decision: 'approved' } };
|
|
24
|
+
}
|
|
25
|
+
async reject() {
|
|
26
|
+
return { status: 'ok', output: { decision: 'rejected' } };
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, index_js_1.Entry)(),
|
|
31
|
+
(0, index_js_1.Node)('check'),
|
|
32
|
+
(0, index_js_1.Edge)('approve', (ctx) => ctx.state.score >= 70, 1),
|
|
33
|
+
(0, index_js_1.Edge)('reject', (ctx) => ctx.state.score < 70, 1),
|
|
34
|
+
__metadata("design:type", Function),
|
|
35
|
+
__metadata("design:paramtypes", [Object]),
|
|
36
|
+
__metadata("design:returntype", Promise)
|
|
37
|
+
], BranchingFlow.prototype, "check", null);
|
|
38
|
+
__decorate([
|
|
39
|
+
(0, index_js_1.Node)('approve'),
|
|
40
|
+
__metadata("design:type", Function),
|
|
41
|
+
__metadata("design:paramtypes", []),
|
|
42
|
+
__metadata("design:returntype", Promise)
|
|
43
|
+
], BranchingFlow.prototype, "approve", null);
|
|
44
|
+
__decorate([
|
|
45
|
+
(0, index_js_1.Node)('reject'),
|
|
46
|
+
__metadata("design:type", Function),
|
|
47
|
+
__metadata("design:paramtypes", []),
|
|
48
|
+
__metadata("design:returntype", Promise)
|
|
49
|
+
], BranchingFlow.prototype, "reject", null);
|
|
50
|
+
BranchingFlow = __decorate([
|
|
51
|
+
(0, index_js_1.Flow)('branching-flow', '1.0.0')
|
|
52
|
+
], BranchingFlow);
|
|
53
|
+
async function main() {
|
|
54
|
+
const engine = new index_js_1.FlowEngine();
|
|
55
|
+
const def = (0, index_js_1.buildFlowDefinition)(BranchingFlow);
|
|
56
|
+
await engine.registerDefinition(def);
|
|
57
|
+
const { runId } = await engine.startRun({
|
|
58
|
+
flowId: 'branching-flow',
|
|
59
|
+
version: '1.0.0',
|
|
60
|
+
input: { score: 85 },
|
|
61
|
+
});
|
|
62
|
+
let run = await engine.getRun(runId);
|
|
63
|
+
while (run?.status === 'RUNNING') {
|
|
64
|
+
run = await engine.tick(runId);
|
|
65
|
+
}
|
|
66
|
+
// eslint-disable-next-line no-console
|
|
67
|
+
console.log('Run result:', run?.outputsJson);
|
|
68
|
+
}
|
|
69
|
+
main().catch((err) => {
|
|
70
|
+
// eslint-disable-next-line no-console
|
|
71
|
+
console.error(err);
|
|
72
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple.d.ts","sourceRoot":"","sources":["../../src/examples/simple.ts"],"names":[],"mappings":""}
|