@synergenius/flow-weaver-pack-weaver 0.9.138 → 0.9.140

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.
@@ -24,9 +24,401 @@ import { weaverCtxMerge } from '../node-types/ctx-merge.js';
24
24
  // DO NOT EDIT - This section is auto-generated by Flow Weaver
25
25
  // ============================================================================
26
26
 
27
- import { GeneratedExecutionContext, CancellationError } from '@synergenius/flow-weaver/runtime';
28
- import type { TDebugger, TDebugController } from '@synergenius/flow-weaver/runtime';
27
+ // ============================================================================
28
+ // Runtime Types
29
+ // ============================================================================
30
+
31
+ type TStatusType =
32
+ | "RUNNING"
33
+ | "SCHEDULED"
34
+ | "SUCCEEDED"
35
+ | "FAILED"
36
+ | "CANCELLED"
37
+ | "PENDING";
38
+
39
+ type TVariableIdentification = {
40
+ nodeTypeName: string;
41
+ id: string;
42
+ scope?: string | undefined;
43
+ side?: "start" | "exit" | undefined;
44
+ portName: string;
45
+ executionIndex: number;
46
+ key?: string | undefined;
47
+ };
48
+
49
+ type TStatusChangedEvent = {
50
+ type: "STATUS_CHANGED";
51
+ nodeTypeName: string;
52
+ id: string;
53
+ scope?: string;
54
+ side?: "start" | "exit";
55
+ executionIndex: number;
56
+ status: TStatusType;
57
+ innerFlowInvocation?: boolean;
58
+ };
59
+
60
+ type TVariableSetEvent = {
61
+ type: "VARIABLE_SET";
62
+ identifier: TVariableIdentification;
63
+ value?: unknown;
64
+ innerFlowInvocation?: boolean;
65
+ };
66
+
67
+ type TErrorLogEvent = {
68
+ type: "LOG_ERROR";
69
+ nodeTypeName: string;
70
+ id: string;
71
+ scope?: string;
72
+ side?: "start" | "exit";
73
+ executionIndex: number;
74
+ error: string;
75
+ innerFlowInvocation?: boolean;
76
+ };
77
+
78
+ type TWorkflowCompletedEvent = {
79
+ type: "WORKFLOW_COMPLETED";
80
+ executionIndex: number;
81
+ status: "SUCCEEDED" | "FAILED" | "CANCELLED";
82
+ result?: unknown;
83
+ innerFlowInvocation?: boolean;
84
+ };
85
+
86
+ type TEvent =
87
+ | TStatusChangedEvent
88
+ | TVariableSetEvent
89
+ | TErrorLogEvent
90
+ | TWorkflowCompletedEvent;
91
+
92
+ type TDebugger = {
93
+ sendEvent: (event: TEvent) => void | Promise<void>;
94
+ innerFlowInvocation: boolean;
95
+ sessionId?: string;
96
+ };
97
+
29
98
  declare const __flowWeaverDebugger__: TDebugger | undefined;
99
+
100
+ type TDebugController = {
101
+ beforeNode(nodeId: string, ctx: GeneratedExecutionContext): Promise<boolean> | boolean;
102
+ afterNode(nodeId: string, ctx: GeneratedExecutionContext): Promise<void> | void;
103
+ };
104
+
105
+ declare const __abortSignal__: AbortSignal | undefined;
106
+
107
+ interface VariableAddress {
108
+ id: string;
109
+ portName: string;
110
+ executionIndex: number;
111
+ nodeTypeName?: string | undefined;
112
+ scope?: string | undefined;
113
+ side?: 'start' | 'exit' | undefined;
114
+ }
115
+
116
+ interface ExecutionInfo {
117
+ id: string;
118
+ index: number;
119
+ parentIndex?: number | undefined;
120
+ scopeName?: string | undefined;
121
+ }
122
+
123
+ type VariableValue = unknown | (() => unknown) | (() => Promise<unknown>);
124
+
125
+ // ============================================================================
126
+ // Cancellation Error
127
+ // ============================================================================
128
+
129
+ class CancellationError extends Error {
130
+ public readonly executionIndex: number;
131
+ public readonly nodeId?: string;
132
+ public readonly timestamp: number;
133
+
134
+ constructor(
135
+ message: string = 'Workflow execution cancelled',
136
+ executionIndex: number = 0,
137
+ nodeId?: string,
138
+ timestamp: number = Date.now()
139
+ ) {
140
+ super(message);
141
+ this.name = 'CancellationError';
142
+ this.executionIndex = executionIndex;
143
+ this.nodeId = nodeId;
144
+ this.timestamp = timestamp;
145
+ }
146
+
147
+ static isCancellationError(error: unknown): error is CancellationError {
148
+ return (
149
+ error instanceof CancellationError ||
150
+ (error instanceof Error && error.name === 'CancellationError')
151
+ );
152
+ }
153
+ }
154
+
155
+ // ============================================================================
156
+ // Execution Context
157
+ // ============================================================================
158
+
159
+ class GeneratedExecutionContext {
160
+ private variables: Map<string, VariableValue> = new Map();
161
+ private executions: Map<string, ExecutionInfo> = new Map();
162
+ private executionCounter: number = 0;
163
+ private nodeExecutionCounts: Map<string, number> = new Map();
164
+ private isAsync: boolean;
165
+ private flowWeaverDebugger?: TDebugger | undefined;
166
+ private pullExecutors: Map<string, () => void | Promise<void>> = new Map();
167
+ private nodeExecutionIndices: Map<string, number> = new Map();
168
+ private abortSignal?: AbortSignal | undefined;
169
+
170
+ constructor(isAsync: boolean = true, flowWeaverDebugger?: TDebugger, abortSignal?: AbortSignal) {
171
+ this.isAsync = isAsync;
172
+ this.flowWeaverDebugger = flowWeaverDebugger;
173
+ this.abortSignal = abortSignal;
174
+ }
175
+
176
+ registerPullExecutor(id: string, executor: () => void | Promise<void>): void {
177
+ this.pullExecutors.set(id, executor);
178
+ }
179
+
180
+ addExecution(id: string, parentIndex?: number, scopeName?: string): number {
181
+ // Use per-node execution counter (each node starts at 0)
182
+ const currentCount = this.nodeExecutionCounts.get(id) || 0;
183
+ const index = currentCount;
184
+ this.nodeExecutionCounts.set(id, currentCount + 1);
185
+ this.executionCounter++;
186
+ this.executions.set(this.getExecutionKey(id, index), {
187
+ id,
188
+ index,
189
+ parentIndex,
190
+ scopeName,
191
+ });
192
+ this.nodeExecutionIndices.set(id, index);
193
+ return index;
194
+ }
195
+
196
+ setVariable(address: VariableAddress, value: VariableValue): void | Promise<void> {
197
+ const key = this.getVariableKey(address);
198
+ this.variables.set(key, value);
199
+ if (this.flowWeaverDebugger) {
200
+ const actualValue = typeof value === "function" ? value() : value;
201
+ this.sendVariableSetEvent({
202
+ identifier: {
203
+ nodeTypeName: address.nodeTypeName || "unknown",
204
+ id: address.id,
205
+ portName: address.portName,
206
+ executionIndex: address.executionIndex,
207
+ key: "default",
208
+ ...(address.scope && { scope: address.scope }),
209
+ ...(address.side && { side: address.side }),
210
+ },
211
+ value: actualValue,
212
+ });
213
+ }
214
+ return this.isAsync ? Promise.resolve() : undefined;
215
+ }
216
+
217
+ getVariable(address: VariableAddress): unknown | Promise<unknown> {
218
+ const executor = this.pullExecutors.get(address.id);
219
+ if (executor) {
220
+ if (!this.hasVariable(address)) {
221
+ const result = executor();
222
+ // Handle async executor (returns Promise)
223
+ if (result instanceof Promise) {
224
+ return result.then(() => {
225
+ const trackedIndex = this.nodeExecutionIndices.get(address.id);
226
+ const finalAddress = trackedIndex !== undefined
227
+ ? { ...address, executionIndex: trackedIndex }
228
+ : address;
229
+ return this.retrieveVariable(finalAddress);
230
+ });
231
+ }
232
+ // Handle sync executor (returns void)
233
+ const trackedIndex = this.nodeExecutionIndices.get(address.id);
234
+ const finalAddress = trackedIndex !== undefined
235
+ ? { ...address, executionIndex: trackedIndex }
236
+ : address;
237
+ return this.retrieveVariable(finalAddress);
238
+ }
239
+ }
240
+ return this.retrieveVariable(address);
241
+ }
242
+
243
+ private retrieveVariable(address: VariableAddress): unknown | Promise<unknown> {
244
+ const key = this.getVariableKey(address);
245
+ if (!this.variables.has(key)) {
246
+ throw new Error(`Variable not found: ${address.id}.${address.portName}[${address.executionIndex}]`);
247
+ }
248
+ const value = this.variables.get(key);
249
+ if (typeof value === "function") {
250
+ const result = value();
251
+ if (result instanceof Promise) {
252
+ return result;
253
+ }
254
+ return this.isAsync ? Promise.resolve(result) : result;
255
+ }
256
+ return this.isAsync ? Promise.resolve(value) : value;
257
+ }
258
+
259
+ hasVariable(address: VariableAddress): boolean {
260
+ const key = this.getVariableKey(address);
261
+ return this.variables.has(key);
262
+ }
263
+
264
+ getExecution(id: string, index: number): ExecutionInfo | undefined {
265
+ return this.executions.get(this.getExecutionKey(id, index));
266
+ }
267
+
268
+ createScope(_parentNodeName: string, _parentIndex: number, _scopeName: string, cleanScope: boolean = false, isAsyncOverride?: boolean): GeneratedExecutionContext {
269
+ const effectiveIsAsync = isAsyncOverride !== undefined ? isAsyncOverride : this.isAsync;
270
+ const scopedContext = new GeneratedExecutionContext(effectiveIsAsync, this.flowWeaverDebugger, this.abortSignal);
271
+ // For per-port function scopes (cleanScope=true), start with empty variables
272
+ // For node-level scopes (cleanScope=false), inherit parent variables
273
+ scopedContext.variables = cleanScope ? new Map() : new Map(this.variables);
274
+ scopedContext.executions = new Map(this.executions);
275
+ scopedContext.executionCounter = this.executionCounter;
276
+ scopedContext.nodeExecutionCounts = new Map(this.nodeExecutionCounts);
277
+ return scopedContext;
278
+ }
279
+
280
+ mergeScope(scopedContext: GeneratedExecutionContext): void {
281
+ scopedContext.executions.forEach((info, key) => {
282
+ this.executions.set(key, info);
283
+ });
284
+ scopedContext.variables.forEach((value, key) => {
285
+ this.variables.set(key, value);
286
+ });
287
+ this.executionCounter = Math.max(this.executionCounter, scopedContext.executionCounter);
288
+ scopedContext.nodeExecutionCounts.forEach((count, id) => {
289
+ const currentCount = this.nodeExecutionCounts.get(id) || 0;
290
+ this.nodeExecutionCounts.set(id, Math.max(currentCount, count));
291
+ });
292
+ }
293
+
294
+ private getVariableKey(address: VariableAddress): string {
295
+ return `${address.id}:${address.portName}:${address.executionIndex}`;
296
+ }
297
+
298
+ private getExecutionKey(id: string, index: number): string {
299
+ return `${id}:${index}`;
300
+ }
301
+
302
+ getExecutionCount(): number {
303
+ return this.executionCounter;
304
+ }
305
+
306
+ reset(): void {
307
+ this.variables.clear();
308
+ this.executions.clear();
309
+ this.executionCounter = 0;
310
+ this.nodeExecutionCounts.clear();
311
+ }
312
+
313
+ isAborted(): boolean {
314
+ return this.abortSignal?.aborted ?? false;
315
+ }
316
+
317
+ checkAborted(nodeId?: string): void {
318
+ if (this.abortSignal?.aborted) {
319
+ throw new CancellationError(
320
+ `Workflow execution cancelled${nodeId ? ` at ${nodeId}` : ''}`,
321
+ this.executionCounter,
322
+ nodeId
323
+ );
324
+ }
325
+ }
326
+
327
+ async sendStatusChangedEvent(args: {
328
+ nodeTypeName: string;
329
+ id: string;
330
+ scope?: string;
331
+ side?: "start" | "exit";
332
+ executionIndex: number;
333
+ status: TStatusType;
334
+ }): Promise<void> {
335
+ if (this.flowWeaverDebugger) {
336
+ await this.flowWeaverDebugger.sendEvent({
337
+ type: "STATUS_CHANGED",
338
+ ...args,
339
+ innerFlowInvocation: this.flowWeaverDebugger.innerFlowInvocation,
340
+ });
341
+ }
342
+ }
343
+
344
+ private async sendVariableSetEvent(args: {
345
+ identifier: TVariableIdentification;
346
+ value: unknown;
347
+ }): Promise<void> {
348
+ if (this.flowWeaverDebugger) {
349
+ await this.flowWeaverDebugger.sendEvent({
350
+ type: "VARIABLE_SET",
351
+ ...args,
352
+ innerFlowInvocation: this.flowWeaverDebugger.innerFlowInvocation,
353
+ });
354
+ }
355
+ }
356
+
357
+ async sendLogErrorEvent(args: {
358
+ nodeTypeName: string;
359
+ id: string;
360
+ scope?: string;
361
+ side?: "start" | "exit";
362
+ executionIndex: number;
363
+ error: string;
364
+ }): Promise<void> {
365
+ if (this.flowWeaverDebugger) {
366
+ await this.flowWeaverDebugger.sendEvent({
367
+ type: "LOG_ERROR",
368
+ ...args,
369
+ innerFlowInvocation: this.flowWeaverDebugger.innerFlowInvocation,
370
+ });
371
+ }
372
+ }
373
+
374
+ async sendWorkflowCompletedEvent(args: {
375
+ executionIndex: number;
376
+ status: "SUCCEEDED" | "FAILED" | "CANCELLED";
377
+ result?: unknown;
378
+ }): Promise<void> {
379
+ if (this.flowWeaverDebugger) {
380
+ await this.flowWeaverDebugger.sendEvent({
381
+ type: "WORKFLOW_COMPLETED",
382
+ ...args,
383
+ innerFlowInvocation: this.flowWeaverDebugger.innerFlowInvocation,
384
+ });
385
+ }
386
+ }
387
+
388
+ serialize(): {
389
+ variables: Record<string, unknown>;
390
+ executions: Record<string, ExecutionInfo>;
391
+ executionCounter: number;
392
+ nodeExecutionCounts: Record<string, number>;
393
+ } {
394
+ const vars: Record<string, unknown> = {};
395
+ for (const [key, value] of this.variables) {
396
+ if (typeof value === "function") {
397
+ try { vars[key] = (value as () => unknown)(); } catch { vars[key] = value; }
398
+ } else {
399
+ vars[key] = value;
400
+ }
401
+ }
402
+ const execs: Record<string, ExecutionInfo> = {};
403
+ for (const [key, info] of this.executions) { execs[key] = { ...info }; }
404
+ const nodeCounts: Record<string, number> = {};
405
+ for (const [key, count] of this.nodeExecutionIndices) { nodeCounts[key] = count; }
406
+ return { variables: vars, executions: execs, executionCounter: this.executionCounter, nodeExecutionCounts: nodeCounts };
407
+ }
408
+
409
+ restore(data: {
410
+ variables: Record<string, unknown>;
411
+ executions: Record<string, ExecutionInfo>;
412
+ executionCounter: number;
413
+ nodeExecutionCounts: Record<string, number>;
414
+ }): void {
415
+ this.variables = new Map(Object.entries(data.variables));
416
+ this.executions = new Map(Object.entries(data.executions));
417
+ this.executionCounter = data.executionCounter;
418
+ this.nodeExecutionIndices = new Map(Object.entries(data.nodeExecutionCounts));
419
+ }
420
+ }
421
+
30
422
  // @flow-weaver-runtime-end
31
423
 
32
424
  /**
@@ -76,6 +468,7 @@ declare const __flowWeaverDebugger__: TDebugger | undefined;
76
468
  * @connect gitOps.ctx -> report.mainCtx
77
469
  * @connect readWf.ctx -> report.readCtx
78
470
  * @connect abort.ctx -> report.abortCtx
471
+ * @connect execRetry.ctx -> report.failCtx
79
472
  * @connect report.summary -> Exit.summary
80
473
  * @param execute [order:-1] - Execute
81
474
  * @param taskJson [order:0] - TaskJson
@@ -1731,7 +2124,9 @@ export async function weaverBot(
1731
2124
  await ctx.setVariable({ id: 'report', portName: 'readCtx', executionIndex: reportIdx, nodeTypeName: 'weaverBotReport' }, report_readCtx);
1732
2125
  const report_abortCtx = abortIdx !== undefined ? await ctx.getVariable({ id: 'abort', portName: 'ctx', executionIndex: abortIdx }) as string : undefined;
1733
2126
  await ctx.setVariable({ id: 'report', portName: 'abortCtx', executionIndex: reportIdx, nodeTypeName: 'weaverBotReport' }, report_abortCtx);
1734
- const reportResult = await weaverBotReport(report_execute, report_mainCtx, report_readCtx, report_abortCtx);
2127
+ const report_failCtx = execRetryIdx !== undefined ? await ctx.getVariable({ id: 'execRetry', portName: 'ctx', executionIndex: execRetryIdx }) as string : undefined;
2128
+ await ctx.setVariable({ id: 'report', portName: 'failCtx', executionIndex: reportIdx, nodeTypeName: 'weaverBotReport' }, report_failCtx);
2129
+ const reportResult = await weaverBotReport(report_execute, report_mainCtx, report_readCtx, report_abortCtx, report_failCtx);
1735
2130
  await ctx.setVariable({ id: 'report', portName: 'summary', executionIndex: reportIdx, nodeTypeName: 'weaverBotReport' }, reportResult.summary);
1736
2131
  await ctx.setVariable({ id: 'report', portName: 'reportJson', executionIndex: reportIdx, nodeTypeName: 'weaverBotReport' }, reportResult.reportJson);
1737
2132
  await ctx.setVariable({ id: 'report', portName: 'onFailure', executionIndex: reportIdx, nodeTypeName: 'weaverBotReport' }, reportResult.onFailure);