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.
Files changed (36) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +110 -24
  3. package/dist/runtime/adapters/factory.js +8 -7
  4. package/dist/runtime/adapters/interfaces/queue.d.ts +5 -0
  5. package/dist/runtime/config/index.js +14 -1
  6. package/dist/runtime/config/types.d.ts +42 -0
  7. package/dist/runtime/events/types.d.ts +0 -1
  8. package/dist/runtime/events/utils/stallDetector.d.ts +13 -77
  9. package/dist/runtime/events/utils/stallDetector.js +8 -192
  10. package/dist/runtime/events/wiring/flowWiring.js +311 -107
  11. package/dist/runtime/events/wiring/triggerWiring.js +3 -1
  12. package/dist/runtime/nitro/plugins/02.workers.js +31 -2
  13. package/dist/runtime/nitro/routes/webhook.await.js +28 -6
  14. package/dist/runtime/nitro/utils/awaitPatterns/event.js +58 -50
  15. package/dist/runtime/nitro/utils/awaitPatterns/schedule.js +6 -1
  16. package/dist/runtime/nitro/utils/awaitPatterns/time.d.ts +1 -1
  17. package/dist/runtime/nitro/utils/awaitPatterns/time.js +6 -2
  18. package/dist/runtime/nitro/utils/awaitPatterns/webhook.js +53 -45
  19. package/dist/runtime/nitro/utils/defineFunction.d.ts +2 -9
  20. package/dist/runtime/nitro/utils/defineFunction.js +1 -14
  21. package/dist/runtime/nitro/utils/defineFunctionConfig.d.ts +84 -16
  22. package/dist/runtime/nitro/utils/defineHooks.d.ts +64 -10
  23. package/dist/runtime/nitro/utils/defineHooks.js +3 -0
  24. package/dist/runtime/nitro/utils/useAwait.d.ts +12 -0
  25. package/dist/runtime/nitro/utils/useAwait.js +34 -4
  26. package/dist/runtime/nitro/utils/useFlow.js +13 -2
  27. package/dist/runtime/nitro/utils/useHookRegistry.d.ts +10 -4
  28. package/dist/runtime/scheduler/scheduler.d.ts +19 -0
  29. package/dist/runtime/scheduler/scheduler.js +184 -8
  30. package/dist/runtime/scheduler/types.d.ts +6 -0
  31. package/dist/runtime/worker/node/runner.js +32 -91
  32. package/dist/runtime/worker/system/awaitHandlers.d.ts +27 -0
  33. package/dist/runtime/worker/system/awaitHandlers.js +230 -0
  34. package/dist/runtime/worker/system/index.d.ts +24 -0
  35. package/dist/runtime/worker/system/index.js +39 -0
  36. 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: config.timeout,
33
- registeredAt: Date.now()
37
+ timeout: timeoutMs,
38
+ // Store resolved timeout (with default)
39
+ registeredAt: Date.now(),
40
+ timeoutAction: config.timeoutAction || defaultTimeoutAction
34
41
  }
35
42
  });
36
- if (config.timeout && config.timeout > 0) {
37
- const scheduler = useScheduler();
38
- const timeoutAt = Date.now() + config.timeout;
39
- const jobId = `await-event-timeout-${runId}-${stepName}-${position}`;
40
- await scheduler.schedule({
41
- id: jobId,
42
- name: `Event Await Timeout: ${flowName} - ${stepName}`,
43
- type: "one-time",
44
- executeAt: timeoutAt,
45
- handler: async () => {
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
- timeout: config.timeout,
79
- eventName: config.event
80
- }
81
- });
82
- logger.debug(`Event timeout scheduled`, {
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
- eventName: config.event,
86
- timeout: config.timeout,
87
- timeoutAction: config.timeoutAction
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: scheduleData,
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', timeData: any): Promise<void>;
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, timeData) {
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: timeData,
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: config.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
- if (config.timeout && config.timeout > 0) {
42
- const scheduler = useScheduler();
43
- const timeoutAt = Date.now() + config.timeout;
44
- const jobId = `await-webhook-timeout-${runId}-${stepName}-${position}`;
45
- await scheduler.schedule({
46
- id: jobId,
47
- name: `Webhook Timeout: ${flowName} - ${stepName}`,
48
- type: "one-time",
49
- executeAt: timeoutAt,
50
- handler: async () => {
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
- timeout: config.timeout
81
- }
82
- });
83
- logger.debug(`Webhook timeout scheduled`, {
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
- timeout: config.timeout,
87
- timeoutAction: config.timeoutAction
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 { useFlow, useQueueAdapter } from '#imports';
2
- import type { RunContext, NodeHandler } from '../worker/node/runner.js';
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
- const wrapped = async (input, ctx) => {
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
- * Declared in config, no functions allowed (AST-parsed)
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
- * Trigger type
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: {runId}, {stepId})
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 data
147
- * e.g., 'orderId' matches event.orderId === step.orderId
148
- * Supports nested paths: 'order.id' matches event.order.id === step.order.id
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 (e.g., '0 9 * * *' for 9 AM daily)
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
- * Hours to add after step completion before calculating next cron occurrence
157
- */
158
- nextAfterHours?: number;
159
- /**
160
- * Timezone for cron expression
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
- * Delay in milliseconds
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 on timeout
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 '../worker/node/runner.js';
6
- export interface AwaitRegisterContext extends Pick<RunContext, 'flowId' | 'flowName' | 'stepName' | 'logger' | 'state'> {
7
- awaitType: 'webhook' | 'event' | 'schedule' | 'time';
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: 'webhook' | 'event' | 'schedule' | 'time';
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
- * export const onAwaitRegister = defineAwaitRegisterHook(async (webhookUrl, stepData, ctx) => {
20
- * // Send notification email with webhook URL
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: (webhookUrl: string, stepData: any, ctx: AwaitRegisterContext) => Promise<void>): (webhookUrl: string, stepData: any, ctx: AwaitRegisterContext) => Promise<void>;
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>;
@@ -4,3 +4,6 @@ export function defineAwaitRegisterHook(hook) {
4
4
  export function defineAwaitResolveHook(hook) {
5
5
  return hook;
6
6
  }
7
+ export function defineAwaitTimeoutHook(hook) {
8
+ return hook;
9
+ }
@@ -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