nvent 0.5.3 → 0.5.5
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/module.json +1 -1
- package/dist/module.mjs +110 -24
- package/dist/runtime/adapters/factory.js +8 -7
- package/dist/runtime/adapters/interfaces/queue.d.ts +5 -0
- package/dist/runtime/config/index.js +14 -1
- package/dist/runtime/config/types.d.ts +42 -0
- package/dist/runtime/events/types.d.ts +0 -1
- package/dist/runtime/events/utils/stallDetector.d.ts +13 -77
- package/dist/runtime/events/utils/stallDetector.js +8 -192
- package/dist/runtime/events/wiring/flowWiring.js +311 -107
- package/dist/runtime/events/wiring/triggerWiring.js +3 -1
- package/dist/runtime/nitro/plugins/02.workers.js +31 -2
- package/dist/runtime/nitro/routes/webhook.await.js +28 -6
- package/dist/runtime/nitro/utils/awaitPatterns/event.js +58 -50
- package/dist/runtime/nitro/utils/awaitPatterns/schedule.js +6 -1
- package/dist/runtime/nitro/utils/awaitPatterns/time.d.ts +1 -1
- package/dist/runtime/nitro/utils/awaitPatterns/time.js +6 -2
- package/dist/runtime/nitro/utils/awaitPatterns/webhook.js +53 -45
- package/dist/runtime/nitro/utils/defineFunction.d.ts +2 -9
- package/dist/runtime/nitro/utils/defineFunction.js +1 -14
- package/dist/runtime/nitro/utils/defineFunctionConfig.d.ts +84 -16
- package/dist/runtime/nitro/utils/defineHooks.d.ts +64 -10
- package/dist/runtime/nitro/utils/defineHooks.js +3 -0
- package/dist/runtime/nitro/utils/useAwait.d.ts +12 -0
- package/dist/runtime/nitro/utils/useAwait.js +34 -4
- package/dist/runtime/nitro/utils/useFlow.js +13 -2
- package/dist/runtime/nitro/utils/useHookRegistry.d.ts +10 -4
- package/dist/runtime/scheduler/scheduler.d.ts +19 -0
- package/dist/runtime/scheduler/scheduler.js +184 -8
- package/dist/runtime/scheduler/types.d.ts +6 -0
- package/dist/runtime/worker/node/runner.js +32 -91
- package/dist/runtime/worker/system/awaitHandlers.d.ts +27 -0
- package/dist/runtime/worker/system/awaitHandlers.js +230 -0
- package/dist/runtime/worker/system/index.d.ts +24 -0
- package/dist/runtime/worker/system/index.js +39 -0
- package/package.json +1 -1
|
@@ -18,6 +18,9 @@ export async function registerEventAwait(runId, stepName, flowName, config, posi
|
|
|
18
18
|
await resolveEventAwait(runId, stepName, flowName, position, event.data);
|
|
19
19
|
unsubscribe();
|
|
20
20
|
});
|
|
21
|
+
const { useAwaitDefaults } = await import("../useAwait.js");
|
|
22
|
+
const { eventTimeout: defaultTimeout, timeoutAction: defaultTimeoutAction } = useAwaitDefaults();
|
|
23
|
+
const timeoutMs = config.timeout && config.timeout > 0 ? config.timeout : defaultTimeout;
|
|
21
24
|
eventBus.publish({
|
|
22
25
|
type: "await.registered",
|
|
23
26
|
flowName,
|
|
@@ -27,66 +30,69 @@ export async function registerEventAwait(runId, stepName, flowName, config, posi
|
|
|
27
30
|
position,
|
|
28
31
|
config,
|
|
29
32
|
data: {
|
|
33
|
+
position,
|
|
34
|
+
// Store position in data for database persistence
|
|
30
35
|
eventName: config.event,
|
|
31
36
|
filterKey: config.filterKey,
|
|
32
|
-
timeout:
|
|
33
|
-
|
|
37
|
+
timeout: timeoutMs,
|
|
38
|
+
// Store resolved timeout (with default)
|
|
39
|
+
registeredAt: Date.now(),
|
|
40
|
+
timeoutAction: config.timeoutAction || defaultTimeoutAction
|
|
34
41
|
}
|
|
35
42
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
logger.warn("Event await timeout", {
|
|
47
|
-
runId,
|
|
48
|
-
stepName,
|
|
49
|
-
flowName,
|
|
50
|
-
eventName: config.event,
|
|
51
|
-
timeout: config.timeout,
|
|
52
|
-
timeoutAction: config.timeoutAction || "fail"
|
|
53
|
-
});
|
|
54
|
-
eventBus.publish({
|
|
55
|
-
type: "await.timeout",
|
|
56
|
-
flowName,
|
|
57
|
-
runId,
|
|
58
|
-
stepName,
|
|
59
|
-
position,
|
|
60
|
-
awaitType: "event",
|
|
61
|
-
timeoutAction: config.timeoutAction || "fail",
|
|
62
|
-
data: {
|
|
63
|
-
eventName: config.event,
|
|
64
|
-
timeout: config.timeout,
|
|
65
|
-
registeredAt: Date.now() - (config.timeout || 0),
|
|
66
|
-
timedOutAt: Date.now()
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
unsubscribe();
|
|
70
|
-
},
|
|
71
|
-
metadata: {
|
|
72
|
-
component: "await-pattern",
|
|
73
|
-
awaitType: "event",
|
|
43
|
+
const scheduler = useScheduler();
|
|
44
|
+
const timeoutAt = Date.now() + timeoutMs;
|
|
45
|
+
const jobId = `await-event-timeout-${runId}-${stepName}-${position}`;
|
|
46
|
+
await scheduler.schedule({
|
|
47
|
+
id: jobId,
|
|
48
|
+
name: `Event Await Timeout: ${flowName} - ${stepName}`,
|
|
49
|
+
type: "one-time",
|
|
50
|
+
executeAt: timeoutAt,
|
|
51
|
+
handler: async () => {
|
|
52
|
+
logger.warn("Event await timeout", {
|
|
74
53
|
runId,
|
|
75
54
|
stepName,
|
|
76
55
|
flowName,
|
|
56
|
+
eventName: config.event,
|
|
57
|
+
timeout: timeoutMs,
|
|
58
|
+
timeoutAction: config.timeoutAction || "fail"
|
|
59
|
+
});
|
|
60
|
+
eventBus.publish({
|
|
61
|
+
type: "await.timeout",
|
|
62
|
+
flowName,
|
|
63
|
+
runId,
|
|
64
|
+
stepName,
|
|
77
65
|
position,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
66
|
+
awaitType: "event",
|
|
67
|
+
timeoutAction: config.timeoutAction || "fail",
|
|
68
|
+
data: {
|
|
69
|
+
eventName: config.event,
|
|
70
|
+
timeout: timeoutMs,
|
|
71
|
+
registeredAt: Date.now() - timeoutMs,
|
|
72
|
+
timedOutAt: Date.now()
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
unsubscribe();
|
|
76
|
+
},
|
|
77
|
+
metadata: {
|
|
78
|
+
component: "await-pattern",
|
|
79
|
+
awaitType: "event",
|
|
83
80
|
runId,
|
|
84
81
|
stepName,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
flowName,
|
|
83
|
+
position,
|
|
84
|
+
timeout: timeoutMs,
|
|
85
|
+
eventName: config.event
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
logger.debug(`Event timeout scheduled`, {
|
|
89
|
+
runId,
|
|
90
|
+
stepName,
|
|
91
|
+
eventName: config.event,
|
|
92
|
+
timeout: timeoutMs,
|
|
93
|
+
timeoutAction: config.timeoutAction,
|
|
94
|
+
isDefault: !config.timeout || config.timeout <= 0
|
|
95
|
+
});
|
|
90
96
|
logger.debug(`Event await registered: ${config.event}`, { runId, stepName });
|
|
91
97
|
return {
|
|
92
98
|
eventName: config.event,
|
|
@@ -113,6 +119,8 @@ export async function resolveEventAwait(runId, stepName, flowName, position, eve
|
|
|
113
119
|
position,
|
|
114
120
|
triggerData: eventData,
|
|
115
121
|
data: {
|
|
122
|
+
position,
|
|
123
|
+
// Store position in data for database persistence
|
|
116
124
|
resolvedAt: Date.now()
|
|
117
125
|
}
|
|
118
126
|
});
|
|
@@ -43,6 +43,8 @@ export async function registerScheduleAwait(runId, stepName, flowName, config, p
|
|
|
43
43
|
position,
|
|
44
44
|
config,
|
|
45
45
|
data: {
|
|
46
|
+
position,
|
|
47
|
+
// Store position in data for database persistence
|
|
46
48
|
cron: config.cron,
|
|
47
49
|
nextOccurrence,
|
|
48
50
|
timeUntilNext,
|
|
@@ -63,14 +65,17 @@ export async function resolveScheduleAwait(runId, stepName, flowName, position,
|
|
|
63
65
|
const logger = useNventLogger("await-schedule");
|
|
64
66
|
const eventBus = getEventBus();
|
|
65
67
|
logger.info(`Resolving schedule await`, { runId, stepName });
|
|
68
|
+
const scheduledAt = scheduleData?.scheduledAt || Date.now();
|
|
66
69
|
eventBus.publish({
|
|
67
70
|
type: "await.resolved",
|
|
68
71
|
flowName,
|
|
69
72
|
runId,
|
|
70
73
|
stepName,
|
|
71
74
|
position,
|
|
72
|
-
triggerData:
|
|
75
|
+
triggerData: { scheduledAt },
|
|
73
76
|
data: {
|
|
77
|
+
position,
|
|
78
|
+
// Store position in data for database persistence
|
|
74
79
|
resolvedAt: Date.now()
|
|
75
80
|
}
|
|
76
81
|
});
|
|
@@ -12,4 +12,4 @@ export declare function registerTimeAwait(runId: string, stepName: string, flowN
|
|
|
12
12
|
/**
|
|
13
13
|
* Resolve time await when delay completes
|
|
14
14
|
*/
|
|
15
|
-
export declare function resolveTimeAwait(runId: string, stepName: string, flowName: string, position: 'before' | 'after',
|
|
15
|
+
export declare function resolveTimeAwait(runId: string, stepName: string, flowName: string, position: 'before' | 'after', _timeData: any): Promise<void>;
|
|
@@ -37,6 +37,8 @@ export async function registerTimeAwait(runId, stepName, flowName, config, posit
|
|
|
37
37
|
position,
|
|
38
38
|
config,
|
|
39
39
|
data: {
|
|
40
|
+
position,
|
|
41
|
+
// Store position in data for database persistence
|
|
40
42
|
delay: config.delay,
|
|
41
43
|
resolveAt,
|
|
42
44
|
registeredAt: Date.now()
|
|
@@ -48,7 +50,7 @@ export async function registerTimeAwait(runId, stepName, flowName, config, posit
|
|
|
48
50
|
resolveAt
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
|
-
export async function resolveTimeAwait(runId, stepName, flowName, position,
|
|
53
|
+
export async function resolveTimeAwait(runId, stepName, flowName, position, _timeData) {
|
|
52
54
|
const logger = useNventLogger("await-time");
|
|
53
55
|
const eventBus = getEventBus();
|
|
54
56
|
logger.info(`Resolving time await`, { runId, stepName });
|
|
@@ -58,8 +60,10 @@ export async function resolveTimeAwait(runId, stepName, flowName, position, time
|
|
|
58
60
|
runId,
|
|
59
61
|
stepName,
|
|
60
62
|
position,
|
|
61
|
-
triggerData:
|
|
63
|
+
triggerData: {},
|
|
62
64
|
data: {
|
|
65
|
+
position,
|
|
66
|
+
// Store position in data for database persistence
|
|
63
67
|
resolvedAt: Date.now()
|
|
64
68
|
}
|
|
65
69
|
});
|
|
@@ -22,6 +22,9 @@ export async function registerWebhookAwait(runId, stepName, flowName, config, po
|
|
|
22
22
|
const webhookPath = `/api/_webhook/await${path}`;
|
|
23
23
|
const fullWebhookUrl = `${baseUrl.replace(/\/$/, "")}${webhookPath}`;
|
|
24
24
|
logger.info(`Registering webhook await: ${fullWebhookUrl}`, { runId, stepName });
|
|
25
|
+
const { useAwaitDefaults } = await import("../useAwait.js");
|
|
26
|
+
const { webhookTimeout: defaultTimeout, timeoutAction: defaultTimeoutAction } = useAwaitDefaults();
|
|
27
|
+
const timeoutMs = config.timeout && config.timeout > 0 ? config.timeout : defaultTimeout;
|
|
25
28
|
eventBus.publish({
|
|
26
29
|
type: "await.registered",
|
|
27
30
|
flowName,
|
|
@@ -31,62 +34,65 @@ export async function registerWebhookAwait(runId, stepName, flowName, config, po
|
|
|
31
34
|
position,
|
|
32
35
|
config,
|
|
33
36
|
data: {
|
|
37
|
+
position,
|
|
38
|
+
// Store position in data for database persistence
|
|
34
39
|
path,
|
|
35
40
|
method: config.method || "POST",
|
|
36
|
-
timeout:
|
|
41
|
+
timeout: timeoutMs,
|
|
42
|
+
// Store resolved timeout (with default)
|
|
37
43
|
registeredAt: Date.now(),
|
|
38
|
-
webhookUrl: fullWebhookUrl
|
|
44
|
+
webhookUrl: fullWebhookUrl,
|
|
45
|
+
timeoutAction: config.timeoutAction || defaultTimeoutAction
|
|
39
46
|
}
|
|
40
47
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
logger.warn("Webhook await timeout", {
|
|
52
|
-
runId,
|
|
53
|
-
stepName,
|
|
54
|
-
flowName,
|
|
55
|
-
timeout: config.timeout,
|
|
56
|
-
timeoutAction: config.timeoutAction || "fail"
|
|
57
|
-
});
|
|
58
|
-
eventBus.publish({
|
|
59
|
-
type: "await.timeout",
|
|
60
|
-
flowName,
|
|
61
|
-
runId,
|
|
62
|
-
stepName,
|
|
63
|
-
position,
|
|
64
|
-
awaitType: "webhook",
|
|
65
|
-
timeoutAction: config.timeoutAction || "fail",
|
|
66
|
-
data: {
|
|
67
|
-
timeout: config.timeout,
|
|
68
|
-
registeredAt: Date.now() - (config.timeout || 0),
|
|
69
|
-
timedOutAt: Date.now()
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
},
|
|
73
|
-
metadata: {
|
|
74
|
-
component: "await-pattern",
|
|
75
|
-
awaitType: "webhook",
|
|
48
|
+
const scheduler = useScheduler();
|
|
49
|
+
const timeoutAt = Date.now() + timeoutMs;
|
|
50
|
+
const jobId = `await-webhook-timeout-${runId}-${stepName}-${position}`;
|
|
51
|
+
await scheduler.schedule({
|
|
52
|
+
id: jobId,
|
|
53
|
+
name: `Webhook Timeout: ${flowName} - ${stepName}`,
|
|
54
|
+
type: "one-time",
|
|
55
|
+
executeAt: timeoutAt,
|
|
56
|
+
handler: async () => {
|
|
57
|
+
logger.warn("Webhook await timeout", {
|
|
76
58
|
runId,
|
|
77
59
|
stepName,
|
|
78
60
|
flowName,
|
|
61
|
+
timeout: timeoutMs,
|
|
62
|
+
timeoutAction: config.timeoutAction || "fail"
|
|
63
|
+
});
|
|
64
|
+
eventBus.publish({
|
|
65
|
+
type: "await.timeout",
|
|
66
|
+
flowName,
|
|
67
|
+
runId,
|
|
68
|
+
stepName,
|
|
79
69
|
position,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
70
|
+
awaitType: "webhook",
|
|
71
|
+
timeoutAction: config.timeoutAction || "fail",
|
|
72
|
+
data: {
|
|
73
|
+
timeout: timeoutMs,
|
|
74
|
+
registeredAt: Date.now() - timeoutMs,
|
|
75
|
+
timedOutAt: Date.now()
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
metadata: {
|
|
80
|
+
component: "await-pattern",
|
|
81
|
+
awaitType: "webhook",
|
|
84
82
|
runId,
|
|
85
83
|
stepName,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
flowName,
|
|
85
|
+
position,
|
|
86
|
+
timeout: timeoutMs
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
logger.debug(`Webhook timeout scheduled`, {
|
|
90
|
+
runId,
|
|
91
|
+
stepName,
|
|
92
|
+
timeout: timeoutMs,
|
|
93
|
+
timeoutAction: config.timeoutAction,
|
|
94
|
+
isDefault: !config.timeout || config.timeout <= 0
|
|
95
|
+
});
|
|
90
96
|
logger.debug(`Webhook await registered: ${fullWebhookUrl}`, { runId, stepName });
|
|
91
97
|
return {
|
|
92
98
|
webhookUrl: fullWebhookUrl,
|
|
@@ -113,6 +119,8 @@ export async function resolveWebhookAwait(runId, stepName, flowName, position, w
|
|
|
113
119
|
position,
|
|
114
120
|
triggerData: webhookData,
|
|
115
121
|
data: {
|
|
122
|
+
position,
|
|
123
|
+
// Store position in data for database persistence
|
|
116
124
|
resolvedAt: Date.now()
|
|
117
125
|
}
|
|
118
126
|
});
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export type ExtendedRunContext = RunContext & {
|
|
4
|
-
provider: ReturnType<typeof useQueueAdapter>;
|
|
5
|
-
flow: ReturnType<typeof useFlow>;
|
|
6
|
-
registry: any;
|
|
7
|
-
};
|
|
8
|
-
export type DefineFunction = (handler: (input: any, ctx: ExtendedRunContext) => Promise<any>) => NodeHandler;
|
|
9
|
-
export declare const defineFunction: DefineFunction;
|
|
1
|
+
import type { RunContext, NodeHandler } from '../../worker/node/runner.js';
|
|
2
|
+
export declare const defineFunction: <TInput = any, TOutput = any>(handler: (input: TInput, ctx: RunContext) => Promise<TOutput>) => NodeHandler;
|
|
10
3
|
export default defineFunction;
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import { $useFunctionRegistry, useFlow, useQueueAdapter } from "#imports";
|
|
2
1
|
export const defineFunction = (handler) => {
|
|
3
|
-
|
|
4
|
-
const provider = useQueueAdapter();
|
|
5
|
-
const flow = ctx.flow || useFlow();
|
|
6
|
-
const registry = $useFunctionRegistry();
|
|
7
|
-
const extended = {
|
|
8
|
-
...ctx,
|
|
9
|
-
provider,
|
|
10
|
-
flow,
|
|
11
|
-
registry
|
|
12
|
-
};
|
|
13
|
-
return handler(input, extended);
|
|
14
|
-
};
|
|
15
|
-
return wrapped;
|
|
2
|
+
return handler;
|
|
16
3
|
};
|
|
17
4
|
export default defineFunction;
|
|
@@ -110,6 +110,14 @@ export interface FlowConfig {
|
|
|
110
110
|
*/
|
|
111
111
|
mode?: 'auto' | 'manual';
|
|
112
112
|
};
|
|
113
|
+
/**
|
|
114
|
+
* Step execution timeout in milliseconds (v0.5.1)
|
|
115
|
+
* Overrides global flow.stepTimeout and queue.defaultJobOptions.timeout for this specific step
|
|
116
|
+
*
|
|
117
|
+
* @example 600000 // 10 minutes
|
|
118
|
+
* @example 3600000 // 1 hour
|
|
119
|
+
*/
|
|
120
|
+
stepTimeout?: number;
|
|
113
121
|
/**
|
|
114
122
|
* Await pattern: Wait BEFORE step execution (v0.5)
|
|
115
123
|
* Step won't execute until trigger fires
|
|
@@ -123,53 +131,113 @@ export interface FlowConfig {
|
|
|
123
131
|
}
|
|
124
132
|
/**
|
|
125
133
|
* Await configuration (run-scoped triggers)
|
|
126
|
-
*
|
|
134
|
+
*
|
|
135
|
+
* Pauses flow execution until a specific condition is met. Can be used with:
|
|
136
|
+
* - `awaitBefore`: Wait before step execution starts
|
|
137
|
+
* - `awaitAfter`: Wait after step completes before triggering next steps
|
|
138
|
+
*
|
|
139
|
+
* Declared in config, no functions allowed (AST-parsed at build time)
|
|
127
140
|
*/
|
|
128
141
|
export interface AwaitConfig {
|
|
129
142
|
/**
|
|
130
|
-
*
|
|
143
|
+
* Type of trigger to wait for
|
|
144
|
+
* - `webhook`: Wait for HTTP request to specific endpoint
|
|
145
|
+
* - `event`: Wait for custom event with optional data matching
|
|
146
|
+
* - `schedule`: Wait until specific cron schedule time
|
|
147
|
+
* - `time`: Wait for fixed time delay
|
|
131
148
|
*/
|
|
132
149
|
type: 'webhook' | 'event' | 'schedule' | 'time';
|
|
133
150
|
/**
|
|
134
|
-
* URL path for webhook (supports template variables
|
|
151
|
+
* URL path for webhook trigger (supports template variables)
|
|
152
|
+
*
|
|
153
|
+
* Only used when `type: 'webhook'`
|
|
154
|
+
*
|
|
155
|
+
* Template variables available:
|
|
156
|
+
* - `{runId}`: Current flow run ID
|
|
157
|
+
* - `{stepId}`: Current step execution ID
|
|
158
|
+
*
|
|
159
|
+
* @example '/webhooks/approve/{runId}'
|
|
160
|
+
* @example '/api/confirm/{stepId}'
|
|
135
161
|
*/
|
|
136
162
|
path?: string;
|
|
137
163
|
/**
|
|
138
|
-
* HTTP method for webhook
|
|
164
|
+
* HTTP method for webhook endpoint
|
|
165
|
+
*
|
|
166
|
+
* Only used when `type: 'webhook'`
|
|
167
|
+
*
|
|
168
|
+
* @default 'POST'
|
|
139
169
|
*/
|
|
140
170
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
141
171
|
/**
|
|
142
172
|
* Event name to wait for
|
|
173
|
+
*
|
|
174
|
+
* Only used when `type: 'event'`
|
|
175
|
+
*
|
|
176
|
+
* @example 'payment.completed'
|
|
177
|
+
* @example 'order.shipped'
|
|
143
178
|
*/
|
|
144
179
|
event?: string;
|
|
145
180
|
/**
|
|
146
|
-
* Key to match between event and step
|
|
147
|
-
*
|
|
148
|
-
*
|
|
181
|
+
* Key to match between event data and step output
|
|
182
|
+
*
|
|
183
|
+
* Only used when `type: 'event'`
|
|
184
|
+
*
|
|
185
|
+
* Matches incoming event data against step output data.
|
|
186
|
+
* Supports nested paths using dot notation.
|
|
187
|
+
*
|
|
188
|
+
* @example 'orderId' - matches event.orderId === stepOutput.orderId
|
|
189
|
+
* @example 'order.id' - matches event.order.id === stepOutput.order.id
|
|
149
190
|
*/
|
|
150
191
|
filterKey?: string;
|
|
151
192
|
/**
|
|
152
|
-
* Cron expression
|
|
193
|
+
* Cron expression defining when to trigger (one-time schedule)
|
|
194
|
+
*
|
|
195
|
+
* Only used when `type: 'schedule'`
|
|
196
|
+
*
|
|
197
|
+
* Note: This is a one-time trigger, not recurring. The next occurrence
|
|
198
|
+
* of the cron expression after step completion will trigger continuation.
|
|
199
|
+
*
|
|
200
|
+
* @example '0 9 * * *' - 9 AM daily (triggers at next 9 AM occurrence)
|
|
201
|
+
* @example '0 0 * * MON' - Midnight every Monday
|
|
153
202
|
*/
|
|
154
203
|
cron?: string;
|
|
155
204
|
/**
|
|
156
|
-
*
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
*
|
|
205
|
+
* Timezone for cron expression evaluation
|
|
206
|
+
*
|
|
207
|
+
* Only used when `type: 'schedule'`
|
|
208
|
+
*
|
|
209
|
+
* @example 'America/New_York'
|
|
210
|
+
* @example 'Europe/Berlin'
|
|
211
|
+
* @default 'UTC'
|
|
161
212
|
*/
|
|
162
213
|
timezone?: string;
|
|
163
214
|
/**
|
|
164
|
-
*
|
|
215
|
+
* Fixed delay in milliseconds before continuation
|
|
216
|
+
*
|
|
217
|
+
* Only used when `type: 'time'`
|
|
218
|
+
*
|
|
219
|
+
* @example 60000 - 1 minute
|
|
220
|
+
* @example 3600000 - 1 hour
|
|
165
221
|
*/
|
|
166
222
|
delay?: number;
|
|
167
223
|
/**
|
|
168
|
-
* Maximum wait time in milliseconds
|
|
224
|
+
* Maximum wait time in milliseconds before timeout
|
|
225
|
+
*
|
|
226
|
+
* Applies to all trigger types. If the trigger doesn't fire within
|
|
227
|
+
* this duration, the timeout action will be taken.
|
|
228
|
+
*
|
|
229
|
+
* @example 86400000 - 24 hours
|
|
230
|
+
* @example 604800000 - 7 days
|
|
169
231
|
*/
|
|
170
232
|
timeout?: number;
|
|
171
233
|
/**
|
|
172
|
-
* Action to take
|
|
234
|
+
* Action to take when timeout is reached
|
|
235
|
+
*
|
|
236
|
+
* - `fail`: Mark step/flow as failed
|
|
237
|
+
* - `continue`: Continue flow execution anyway
|
|
238
|
+
* - `retry`: Retry waiting (reset timeout)
|
|
239
|
+
*
|
|
240
|
+
* @default 'fail'
|
|
173
241
|
*/
|
|
174
242
|
timeoutAction?: 'fail' | 'continue' | 'retry';
|
|
175
243
|
}
|
|
@@ -2,30 +2,65 @@
|
|
|
2
2
|
* Type-safe hook definitions for await patterns
|
|
3
3
|
* v0.5 - Await Integration
|
|
4
4
|
*/
|
|
5
|
-
import type { RunContext } from '
|
|
6
|
-
export
|
|
7
|
-
|
|
5
|
+
import type { RunContext } from '../../worker/node/runner.js';
|
|
6
|
+
export type AwaitType = 'webhook' | 'event' | 'schedule' | 'time';
|
|
7
|
+
/**
|
|
8
|
+
* Hook data types specific to each await type
|
|
9
|
+
*/
|
|
10
|
+
export interface WebhookHookData {
|
|
11
|
+
webhookUrl: string;
|
|
12
|
+
}
|
|
13
|
+
export interface EventHookData {
|
|
14
|
+
eventName: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ScheduleHookData {
|
|
17
|
+
cronExpression: string;
|
|
18
|
+
nextOccurrence: Date;
|
|
19
|
+
}
|
|
20
|
+
export interface TimeHookData {
|
|
21
|
+
delayMs: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Conditional type to get the correct hook data based on await type
|
|
25
|
+
*/
|
|
26
|
+
export type HookDataForAwaitType<T extends AwaitType> = T extends 'webhook' ? WebhookHookData : T extends 'event' ? EventHookData : T extends 'schedule' ? ScheduleHookData : T extends 'time' ? TimeHookData : never;
|
|
27
|
+
export interface AwaitRegisterContext<T extends AwaitType = AwaitType> extends Pick<RunContext, 'flowId' | 'flowName' | 'stepName' | 'logger' | 'state'> {
|
|
28
|
+
awaitType: T;
|
|
8
29
|
awaitConfig: any;
|
|
30
|
+
position: 'before' | 'after';
|
|
9
31
|
}
|
|
10
|
-
export interface AwaitResolveContext extends Pick<RunContext, 'flowId' | 'flowName' | 'stepName' | 'logger' | 'state'> {
|
|
11
|
-
awaitType:
|
|
32
|
+
export interface AwaitResolveContext<T extends AwaitType = AwaitType> extends Pick<RunContext, 'flowId' | 'flowName' | 'stepName' | 'logger' | 'state'> {
|
|
33
|
+
awaitType: T;
|
|
12
34
|
resolvedData: any;
|
|
35
|
+
position: 'before' | 'after';
|
|
36
|
+
}
|
|
37
|
+
export interface AwaitTimeoutContext<T extends AwaitType = AwaitType> extends Pick<RunContext, 'flowId' | 'flowName' | 'stepName' | 'logger' | 'state'> {
|
|
38
|
+
awaitType: T;
|
|
39
|
+
timeoutAction: 'fail' | 'continue' | 'retry';
|
|
40
|
+
position: 'before' | 'after';
|
|
13
41
|
}
|
|
14
42
|
/**
|
|
15
43
|
* Define onAwaitRegister hook with proper types
|
|
16
44
|
* Called when an await pattern is registered (before handler execution or after completion)
|
|
17
45
|
*
|
|
18
46
|
* @example
|
|
19
|
-
*
|
|
20
|
-
*
|
|
47
|
+
* // Webhook example
|
|
48
|
+
* export const onAwaitRegister = defineAwaitRegisterHook(async (hookData, stepData, ctx) => {
|
|
49
|
+
* // hookData.webhookUrl is typed correctly for webhook awaits
|
|
21
50
|
* await sendEmail({
|
|
22
51
|
* to: stepData.reviewerEmail,
|
|
23
52
|
* subject: 'Approval Required',
|
|
24
|
-
* approveUrl: webhookUrl
|
|
53
|
+
* approveUrl: hookData.webhookUrl
|
|
25
54
|
* })
|
|
26
55
|
* })
|
|
56
|
+
*
|
|
57
|
+
* // Event example
|
|
58
|
+
* export const onAwaitRegister = defineAwaitRegisterHook(async (hookData, stepData, ctx) => {
|
|
59
|
+
* // hookData.eventName is available for event awaits
|
|
60
|
+
* console.log(`Waiting for event: ${hookData.eventName}`)
|
|
61
|
+
* })
|
|
27
62
|
*/
|
|
28
|
-
export declare function defineAwaitRegisterHook(hook: (
|
|
63
|
+
export declare function defineAwaitRegisterHook<T extends AwaitType = AwaitType>(hook: (hookData: HookDataForAwaitType<T>, stepData: any, ctx: AwaitRegisterContext<T>) => Promise<void>): (hookData: HookDataForAwaitType<T>, stepData: any, ctx: AwaitRegisterContext<T>) => Promise<void>;
|
|
29
64
|
/**
|
|
30
65
|
* Define onAwaitResolve hook with proper types
|
|
31
66
|
* Called when an await pattern is resolved (external trigger fired)
|
|
@@ -38,4 +73,23 @@ export declare function defineAwaitRegisterHook(hook: (webhookUrl: string, stepD
|
|
|
38
73
|
* await updateTicketStatus(stepData.ticketId, resolvedData.approved ? 'approved' : 'rejected')
|
|
39
74
|
* })
|
|
40
75
|
*/
|
|
41
|
-
export declare function defineAwaitResolveHook(hook: (resolvedData: any, stepData: any, ctx: AwaitResolveContext) => Promise<void>): (resolvedData: any, stepData: any, ctx: AwaitResolveContext) => Promise<void>;
|
|
76
|
+
export declare function defineAwaitResolveHook<T extends AwaitType = AwaitType>(hook: (resolvedData: any, stepData: any, ctx: AwaitResolveContext<T>) => Promise<void>): (resolvedData: any, stepData: any, ctx: AwaitResolveContext<T>) => Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Define onAwaitTimeout hook with proper types
|
|
79
|
+
* Called when an await pattern times out (timeout exceeded without resolution)
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* export const onAwaitTimeout = defineAwaitTimeoutHook(async (stepData, ctx) => {
|
|
83
|
+
* ctx.logger.log('warn', 'Approval request timed out', {
|
|
84
|
+
* action: ctx.timeoutAction
|
|
85
|
+
* })
|
|
86
|
+
*
|
|
87
|
+
* // Send timeout notification
|
|
88
|
+
* await sendEmail({
|
|
89
|
+
* to: stepData.reviewerEmail,
|
|
90
|
+
* subject: 'Approval Request Expired',
|
|
91
|
+
* message: 'The approval request was not completed in time'
|
|
92
|
+
* })
|
|
93
|
+
* })
|
|
94
|
+
*/
|
|
95
|
+
export declare function defineAwaitTimeoutHook<T extends AwaitType = AwaitType>(hook: (stepData: any, ctx: AwaitTimeoutContext<T>) => Promise<void>): (stepData: any, ctx: AwaitTimeoutContext<T>) => Promise<void>;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type { AwaitConfig } from '../../../registry/types.js';
|
|
2
2
|
import { registerAwaitPattern, resolveAwaitPattern, registerWebhookAwait, resolveWebhookAwait, registerEventAwait, resolveEventAwait, registerScheduleAwait, resolveScheduleAwait, registerTimeAwait, resolveTimeAwait } from './awaitPatterns/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get default timeout values for await patterns from runtime config
|
|
5
|
+
* These are configurable via module options and used throughout the system
|
|
6
|
+
* Exported for use by await pattern implementations
|
|
7
|
+
*/
|
|
8
|
+
export declare function useAwaitDefaults(): {
|
|
9
|
+
webhookTimeout: any;
|
|
10
|
+
eventTimeout: any;
|
|
11
|
+
timeTimeout: any;
|
|
12
|
+
scheduleTimeout: any;
|
|
13
|
+
timeoutAction: any;
|
|
14
|
+
};
|
|
3
15
|
/**
|
|
4
16
|
* Await pattern composable
|
|
5
17
|
* Provides unified API for managing await patterns in flows
|