nvent 0.4.5 → 0.5.1

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 (124) hide show
  1. package/dist/module.d.mts +1 -1
  2. package/dist/module.mjs +433 -180
  3. package/dist/runtime/adapters/base/index.d.ts +6 -0
  4. package/dist/runtime/adapters/base/index.js +1 -0
  5. package/dist/runtime/adapters/base/store-validator.d.ts +48 -0
  6. package/dist/runtime/adapters/base/store-validator.js +147 -0
  7. package/dist/runtime/adapters/builtin/file-queue.d.ts +15 -1
  8. package/dist/runtime/adapters/builtin/file-queue.js +70 -6
  9. package/dist/runtime/adapters/builtin/file-store.d.ts +4 -18
  10. package/dist/runtime/adapters/builtin/file-store.js +90 -109
  11. package/dist/runtime/adapters/builtin/memory-queue.js +4 -0
  12. package/dist/runtime/adapters/builtin/memory-store.d.ts +42 -31
  13. package/dist/runtime/adapters/builtin/memory-store.js +253 -183
  14. package/dist/runtime/adapters/factory.d.ts +2 -2
  15. package/dist/runtime/adapters/factory.js +54 -20
  16. package/dist/runtime/adapters/interfaces/store.d.ts +177 -113
  17. package/dist/runtime/config/index.d.ts +2 -2
  18. package/dist/runtime/config/index.js +14 -6
  19. package/dist/runtime/config/types.d.ts +32 -2
  20. package/dist/runtime/events/eventBus.d.ts +1 -1
  21. package/dist/runtime/events/types.d.ts +31 -2
  22. package/dist/runtime/events/utils/scheduleTrigger.d.ts +8 -0
  23. package/dist/runtime/events/utils/scheduleTrigger.js +69 -0
  24. package/dist/runtime/events/utils/stallDetector.d.ts +44 -3
  25. package/dist/runtime/events/utils/stallDetector.js +288 -89
  26. package/dist/runtime/events/utils/triggerRuntime.d.ts +58 -0
  27. package/dist/runtime/events/utils/triggerRuntime.js +212 -0
  28. package/dist/runtime/events/wiring/flowWiring.d.ts +11 -5
  29. package/dist/runtime/events/wiring/flowWiring.js +620 -92
  30. package/dist/runtime/events/wiring/registry.d.ts +2 -2
  31. package/dist/runtime/events/wiring/registry.js +8 -6
  32. package/dist/runtime/events/wiring/streamWiring.d.ts +15 -11
  33. package/dist/runtime/events/wiring/streamWiring.js +88 -11
  34. package/dist/runtime/events/wiring/triggerWiring.d.ts +21 -0
  35. package/dist/runtime/events/wiring/triggerWiring.js +412 -0
  36. package/dist/runtime/{server → nitro}/plugins/00.adapters.js +8 -4
  37. package/dist/runtime/{server → nitro}/plugins/02.workers.js +21 -3
  38. package/dist/runtime/nitro/plugins/03.triggers.d.ts +12 -0
  39. package/dist/runtime/nitro/plugins/03.triggers.js +55 -0
  40. package/dist/runtime/nitro/routes/webhook.await.d.ts +23 -0
  41. package/dist/runtime/nitro/routes/webhook.await.js +90 -0
  42. package/dist/runtime/nitro/routes/webhook.trigger.d.ts +69 -0
  43. package/dist/runtime/nitro/routes/webhook.trigger.js +64 -0
  44. package/dist/runtime/{utils → nitro/utils}/adapters.d.ts +6 -6
  45. package/dist/runtime/nitro/utils/awaitPatterns/event.d.ts +15 -0
  46. package/dist/runtime/nitro/utils/awaitPatterns/event.js +120 -0
  47. package/dist/runtime/nitro/utils/awaitPatterns/index.d.ts +28 -0
  48. package/dist/runtime/nitro/utils/awaitPatterns/index.js +55 -0
  49. package/dist/runtime/nitro/utils/awaitPatterns/schedule.d.ts +16 -0
  50. package/dist/runtime/nitro/utils/awaitPatterns/schedule.js +78 -0
  51. package/dist/runtime/nitro/utils/awaitPatterns/time.d.ts +15 -0
  52. package/dist/runtime/nitro/utils/awaitPatterns/time.js +67 -0
  53. package/dist/runtime/nitro/utils/awaitPatterns/webhook.d.ts +15 -0
  54. package/dist/runtime/nitro/utils/awaitPatterns/webhook.js +120 -0
  55. package/dist/runtime/{utils → nitro/utils}/defineFunction.d.ts +2 -2
  56. package/dist/runtime/{utils → nitro/utils}/defineFunction.js +3 -3
  57. package/dist/runtime/{utils → nitro/utils}/defineFunctionConfig.d.ts +156 -0
  58. package/dist/runtime/{utils → nitro/utils}/defineFunctionConfig.js +1 -0
  59. package/dist/runtime/nitro/utils/defineHooks.d.ts +41 -0
  60. package/dist/runtime/nitro/utils/defineHooks.js +6 -0
  61. package/dist/runtime/{utils → nitro/utils}/registerAdapter.d.ts +3 -3
  62. package/dist/runtime/{utils → nitro/utils}/registerAdapter.js +1 -1
  63. package/dist/runtime/nitro/utils/useAwait.d.ts +71 -0
  64. package/dist/runtime/nitro/utils/useAwait.js +139 -0
  65. package/dist/runtime/{utils → nitro/utils}/useEventManager.d.ts +2 -2
  66. package/dist/runtime/{utils → nitro/utils}/useEventManager.js +1 -1
  67. package/dist/runtime/nitro/utils/useFlow.d.ts +68 -0
  68. package/dist/runtime/nitro/utils/useFlow.js +226 -0
  69. package/dist/runtime/nitro/utils/useHookRegistry.d.ts +34 -0
  70. package/dist/runtime/nitro/utils/useHookRegistry.js +25 -0
  71. package/dist/runtime/nitro/utils/useRunContext.d.ts +6 -0
  72. package/dist/runtime/nitro/utils/useRunContext.js +102 -0
  73. package/dist/runtime/nitro/utils/useStreamTopics.d.ts +83 -0
  74. package/dist/runtime/nitro/utils/useStreamTopics.js +94 -0
  75. package/dist/runtime/nitro/utils/useTrigger.d.ts +150 -0
  76. package/dist/runtime/nitro/utils/useTrigger.js +320 -0
  77. package/dist/runtime/scheduler/index.d.ts +33 -0
  78. package/dist/runtime/scheduler/index.js +38 -0
  79. package/dist/runtime/scheduler/scheduler.d.ts +113 -0
  80. package/dist/runtime/scheduler/scheduler.js +623 -0
  81. package/dist/runtime/scheduler/types.d.ts +116 -0
  82. package/dist/runtime/scheduler/types.js +0 -0
  83. package/dist/runtime/worker/node/runner.d.ts +12 -2
  84. package/dist/runtime/worker/node/runner.js +141 -37
  85. package/package.json +6 -6
  86. package/dist/runtime/server/api/_flows/[name]/clear-history.delete.d.ts +0 -10
  87. package/dist/runtime/server/api/_flows/[name]/clear-history.delete.js +0 -55
  88. package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.d.ts +0 -2
  89. package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.js +0 -21
  90. package/dist/runtime/server/api/_flows/[name]/runs.get.d.ts +0 -17
  91. package/dist/runtime/server/api/_flows/[name]/runs.get.js +0 -64
  92. package/dist/runtime/server/api/_flows/[name]/schedule.post.d.ts +0 -2
  93. package/dist/runtime/server/api/_flows/[name]/schedule.post.js +0 -66
  94. package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.d.ts +0 -2
  95. package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.js +0 -47
  96. package/dist/runtime/server/api/_flows/[name]/schedules.get.d.ts +0 -2
  97. package/dist/runtime/server/api/_flows/[name]/schedules.get.js +0 -50
  98. package/dist/runtime/server/api/_flows/[name]/start.post.d.ts +0 -2
  99. package/dist/runtime/server/api/_flows/[name]/start.post.js +0 -9
  100. package/dist/runtime/server/api/_flows/index.get.d.ts +0 -6
  101. package/dist/runtime/server/api/_flows/index.get.js +0 -5
  102. package/dist/runtime/server/api/_flows/ws.d.ts +0 -60
  103. package/dist/runtime/server/api/_flows/ws.js +0 -209
  104. package/dist/runtime/server/api/_queues/[name]/job/[id].get.d.ts +0 -2
  105. package/dist/runtime/server/api/_queues/[name]/job/[id].get.js +0 -14
  106. package/dist/runtime/server/api/_queues/[name]/job/index.get.d.ts +0 -2
  107. package/dist/runtime/server/api/_queues/[name]/job/index.get.js +0 -27
  108. package/dist/runtime/server/api/_queues/index.get.d.ts +0 -2
  109. package/dist/runtime/server/api/_queues/index.get.js +0 -106
  110. package/dist/runtime/server/api/_queues/ws.d.ts +0 -48
  111. package/dist/runtime/server/api/_queues/ws.js +0 -215
  112. package/dist/runtime/utils/useFlowEngine.d.ts +0 -19
  113. package/dist/runtime/utils/useFlowEngine.js +0 -108
  114. package/dist/runtime/utils/useStreamTopics.d.ts +0 -72
  115. package/dist/runtime/utils/useStreamTopics.js +0 -47
  116. /package/dist/runtime/{server → nitro}/plugins/00.adapters.d.ts +0 -0
  117. /package/dist/runtime/{server → nitro}/plugins/01.ws-lifecycle.d.ts +0 -0
  118. /package/dist/runtime/{server → nitro}/plugins/01.ws-lifecycle.js +0 -0
  119. /package/dist/runtime/{server → nitro}/plugins/02.workers.d.ts +0 -0
  120. /package/dist/runtime/{utils → nitro/utils}/adapters.js +0 -0
  121. /package/dist/runtime/{utils → nitro/utils}/useNventLogger.d.ts +0 -0
  122. /package/dist/runtime/{utils → nitro/utils}/useNventLogger.js +0 -0
  123. /package/dist/runtime/{utils → nitro/utils}/wsPeerManager.d.ts +0 -0
  124. /package/dist/runtime/{utils → nitro/utils}/wsPeerManager.js +0 -0
@@ -1,4 +1,4 @@
1
- import { defineNitroPlugin, $useWorkerHandlers, $useQueueRegistry, useQueueAdapter } from "#imports";
1
+ import { defineNitroPlugin, $useWorkerHandlers, $useFunctionRegistry, useQueueAdapter, useHookRegistry } from "#imports";
2
2
  import { createJobProcessor } from "../../worker/node/runner.js";
3
3
  export default defineNitroPlugin(async (nitroApp) => {
4
4
  nitroApp.hooks.hook("close", async () => {
@@ -9,10 +9,10 @@ export default defineNitroPlugin(async (nitroApp) => {
9
9
  const queueAdapter = useQueueAdapter();
10
10
  try {
11
11
  const handlers = $useWorkerHandlers();
12
- const registry = $useQueueRegistry() || { workers: [] };
12
+ const registry = $useFunctionRegistry() || { workers: [] };
13
13
  const registeredQueues = /* @__PURE__ */ new Set();
14
14
  for (const entry of handlers) {
15
- const { queue, id, handler } = entry;
15
+ const { queue, id, handler, module } = entry;
16
16
  const w = registry.workers.find((rw) => rw?.id === id || rw?.queue?.name === queue && rw?.absPath === entry.absPath);
17
17
  let jobName;
18
18
  if (w?.flow?.step) {
@@ -20,6 +20,24 @@ export default defineNitroPlugin(async (nitroApp) => {
20
20
  } else {
21
21
  jobName = id.includes("/") ? id.split("/").pop() : id;
22
22
  }
23
+ if (module && w?.flow) {
24
+ const hooks = {};
25
+ if (typeof module.onAwaitRegister === "function") {
26
+ hooks.onAwaitRegister = module.onAwaitRegister;
27
+ }
28
+ if (typeof module.onAwaitResolve === "function") {
29
+ hooks.onAwaitResolve = module.onAwaitResolve;
30
+ }
31
+ if (Object.keys(hooks).length > 0) {
32
+ const hookRegistry = useHookRegistry();
33
+ const flowNames = w.flow.names ? Array.isArray(w.flow.names) ? w.flow.names : [w.flow.names] : w.flow.name ? Array.isArray(w.flow.name) ? w.flow.name : [w.flow.name] : [];
34
+ for (const flowName of flowNames) {
35
+ if (flowName) {
36
+ hookRegistry.register(flowName, jobName, hooks);
37
+ }
38
+ }
39
+ }
40
+ }
23
41
  if (typeof handler === "function") {
24
42
  const workerCfg = w && w.worker || {};
25
43
  const queueCfg = w && w.queue || {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Trigger Registration Plugin
3
+ *
4
+ * Loads pre-analyzed triggers and subscriptions from build-time registry
5
+ * and registers them via event bus (trigger.registered events).
6
+ * The trigger wiring will handle the actual registration logic.
7
+ *
8
+ * This plugin is ONLY for registering dev/build-time discovered triggers.
9
+ * Trigger wiring and event handling is done in the wiring registry.
10
+ */
11
+ declare const _default: any;
12
+ export default _default;
@@ -0,0 +1,55 @@
1
+ import { defineNitroPlugin, $useTriggerRegistry, useNventLogger, useTrigger } from "#imports";
2
+ import { getEventBus } from "../../events/eventBus.js";
3
+ export default defineNitroPlugin(async (nitroApp) => {
4
+ nitroApp.hooks.hook("nvent:adapters:ready", async () => {
5
+ const logger = useNventLogger("trigger-registration");
6
+ const eventBus = getEventBus();
7
+ const trigger = useTrigger();
8
+ try {
9
+ logger.info("Registering build-time triggers...");
10
+ const triggerRegistry = $useTriggerRegistry();
11
+ const subscriptions = triggerRegistry?.subscriptions || [];
12
+ const triggers = triggerRegistry?.triggers || [];
13
+ logger.info(`Found ${triggers.length} triggers and ${subscriptions.length} subscriptions from build`);
14
+ let newTriggers = 0;
15
+ for (const triggerData of triggers) {
16
+ if (!trigger.hasTrigger(triggerData.name)) {
17
+ await eventBus.publish({
18
+ type: "trigger.registered",
19
+ triggerName: triggerData.name,
20
+ data: triggerData
21
+ });
22
+ newTriggers++;
23
+ } else {
24
+ logger.debug(`Trigger '${triggerData.name}' already registered, skipping`);
25
+ }
26
+ }
27
+ let newSubscriptions = 0;
28
+ for (const sub of subscriptions) {
29
+ const existing = trigger.getSubscription(sub.triggerName, sub.flowName);
30
+ if (!existing) {
31
+ await eventBus.publish({
32
+ type: "subscription.added",
33
+ triggerName: sub.triggerName,
34
+ data: {
35
+ trigger: sub.triggerName,
36
+ flow: sub.flowName,
37
+ mode: sub.mode,
38
+ source: "build-time"
39
+ }
40
+ });
41
+ newSubscriptions++;
42
+ } else {
43
+ logger.debug(`Subscription '${sub.flowName}' -> '${sub.triggerName}' already exists, skipping`);
44
+ }
45
+ }
46
+ logger.info(
47
+ `Build-time trigger registration complete (${newTriggers} new triggers, ${newSubscriptions} new subscriptions)`
48
+ );
49
+ } catch (error) {
50
+ logger.error("Failed to register build-time triggers", {
51
+ error: error instanceof Error ? error.message : String(error)
52
+ });
53
+ }
54
+ });
55
+ });
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Dynamic webhook handler for await patterns
3
+ * Handles webhook calls and resolves awaiting steps
4
+ *
5
+ * Routes:
6
+ * - POST /api/_webhook/await/{flowName}/{runId}/{stepName}
7
+ * - GET /api/_webhook/await/{flowName}/{runId}/{stepName}
8
+ *
9
+ * Architecture:
10
+ * 1. Parse URL params to get flowName, runId, stepName
11
+ * 2. Look up flow in store index to verify it exists and is awaiting
12
+ * 3. Verify flow status and await configuration
13
+ * 4. Use useAwait().webhook.resolve() which publishes await.resolved event
14
+ * 5. Trigger wiring handles the actual flow resumption
15
+ */
16
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
17
+ success: boolean;
18
+ runId: string;
19
+ stepName: string;
20
+ flowName: string;
21
+ message: string;
22
+ }>>;
23
+ export default _default;
@@ -0,0 +1,90 @@
1
+ import { defineEventHandler, readBody, getRouterParams, createError, setResponseStatus } from "h3";
2
+ import { useStoreAdapter, useStreamTopics, useNventLogger, useAwait } from "#imports";
3
+ export default defineEventHandler(async (event) => {
4
+ const logger = useNventLogger("webhook-handler");
5
+ const store = useStoreAdapter();
6
+ const await$ = useAwait();
7
+ const { StoreSubjects } = useStreamTopics();
8
+ const params = getRouterParams(event);
9
+ const flowName = params.flowName;
10
+ const runId = params.runId;
11
+ const stepName = params.stepName;
12
+ if (!flowName || !runId || !stepName) {
13
+ logger.warn("Missing required webhook parameters", { params });
14
+ throw createError({
15
+ statusCode: 400,
16
+ statusMessage: "Invalid webhook path",
17
+ message: "Webhook path must include flowName, runId, and stepName"
18
+ });
19
+ }
20
+ logger.info(`Webhook received: ${event.method} for ${flowName}/${runId}/${stepName}`);
21
+ const indexKey = StoreSubjects.flowRunIndex(flowName);
22
+ const flowEntry = await store.index.get?.(indexKey, runId);
23
+ if (!flowEntry) {
24
+ logger.warn(`Flow not found`, { flowName, runId, stepName });
25
+ setResponseStatus(event, 404);
26
+ throw createError({
27
+ statusCode: 404,
28
+ statusMessage: "Flow not found",
29
+ message: "The flow associated with this webhook no longer exists."
30
+ });
31
+ }
32
+ const status = flowEntry.metadata?.status;
33
+ if (status && status !== "running") {
34
+ logger.warn(`Flow is not running`, { flowName, runId, stepName, status });
35
+ setResponseStatus(event, 410);
36
+ throw createError({
37
+ statusCode: 410,
38
+ statusMessage: `Flow is ${status}`,
39
+ message: `This webhook is no longer valid because the flow is ${status}.`
40
+ });
41
+ }
42
+ const awaitState = flowEntry.metadata?.awaitingSteps?.[stepName];
43
+ if (!awaitState || awaitState.status !== "awaiting") {
44
+ logger.warn(`Step is not awaiting`, { flowName, runId, stepName, awaitState });
45
+ setResponseStatus(event, 410);
46
+ throw createError({
47
+ statusCode: 410,
48
+ statusMessage: "Step is not awaiting",
49
+ message: "This webhook has already been called or the await has expired."
50
+ });
51
+ }
52
+ if (awaitState.awaitType !== "webhook") {
53
+ logger.warn(`Step is not waiting for webhook`, { flowName, runId, stepName, awaitType: awaitState.awaitType });
54
+ throw createError({
55
+ statusCode: 400,
56
+ statusMessage: "Invalid await type",
57
+ message: `This step is waiting for ${awaitState.awaitType}, not a webhook.`
58
+ });
59
+ }
60
+ const expectedMethod = awaitState.config?.method || "POST";
61
+ if (event.method !== expectedMethod) {
62
+ logger.warn(`Method mismatch: expected ${expectedMethod}, got ${event.method}`, { flowName, runId, stepName });
63
+ throw createError({
64
+ statusCode: 405,
65
+ statusMessage: "Method Not Allowed",
66
+ message: `This webhook expects ${expectedMethod} requests.`
67
+ });
68
+ }
69
+ const position = awaitState.position || "after";
70
+ let webhookData;
71
+ if (event.method === "GET") {
72
+ webhookData = getRouterParams(event, { decode: true });
73
+ } else {
74
+ webhookData = await readBody(event).catch(() => ({}));
75
+ }
76
+ logger.debug(`Webhook data received`, {
77
+ runId,
78
+ stepName,
79
+ dataKeys: Object.keys(webhookData || {})
80
+ });
81
+ await await$.webhook.resolve(runId, stepName, flowName, position, webhookData);
82
+ logger.info(`Webhook await resolved`, { flowName, runId, stepName });
83
+ return {
84
+ success: true,
85
+ runId,
86
+ stepName,
87
+ flowName,
88
+ message: "Webhook processed successfully. Flow will resume shortly."
89
+ };
90
+ });
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Dynamic webhook trigger handler for entry triggers (flow-scoped)
3
+ * Receives webhook calls and fires triggers to start flows
4
+ *
5
+ * Routes:
6
+ * - POST /api/_webhook/trigger/{triggerName}
7
+ * - GET /api/_webhook/trigger/{triggerName}
8
+ *
9
+ * Different from await webhooks:
10
+ * - Entry triggers are flow-scoped (start new flow runs)
11
+ * - Await webhooks are run-scoped (resume specific steps)
12
+ */
13
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
14
+ error: string;
15
+ message: string;
16
+ triggerName?: undefined;
17
+ expectedType?: undefined;
18
+ actualType?: undefined;
19
+ expectedMethod?: undefined;
20
+ actualMethod?: undefined;
21
+ success?: undefined;
22
+ subscribedFlows?: undefined;
23
+ timestamp?: undefined;
24
+ } | {
25
+ error: string;
26
+ triggerName: string;
27
+ message: string;
28
+ expectedType?: undefined;
29
+ actualType?: undefined;
30
+ expectedMethod?: undefined;
31
+ actualMethod?: undefined;
32
+ success?: undefined;
33
+ subscribedFlows?: undefined;
34
+ timestamp?: undefined;
35
+ } | {
36
+ error: string;
37
+ triggerName: string;
38
+ expectedType: string;
39
+ actualType: any;
40
+ message?: undefined;
41
+ expectedMethod?: undefined;
42
+ actualMethod?: undefined;
43
+ success?: undefined;
44
+ subscribedFlows?: undefined;
45
+ timestamp?: undefined;
46
+ } | {
47
+ error: string;
48
+ expectedMethod: any;
49
+ actualMethod: import("h3").HTTPMethod;
50
+ message?: undefined;
51
+ triggerName?: undefined;
52
+ expectedType?: undefined;
53
+ actualType?: undefined;
54
+ success?: undefined;
55
+ subscribedFlows?: undefined;
56
+ timestamp?: undefined;
57
+ } | {
58
+ success: boolean;
59
+ triggerName: string;
60
+ subscribedFlows: any;
61
+ message: string;
62
+ timestamp: string;
63
+ error?: undefined;
64
+ expectedType?: undefined;
65
+ actualType?: undefined;
66
+ expectedMethod?: undefined;
67
+ actualMethod?: undefined;
68
+ }>>;
69
+ export default _default;
@@ -0,0 +1,64 @@
1
+ import { defineEventHandler, readBody } from "h3";
2
+ import { useNventLogger, useTrigger } from "#imports";
3
+ export default defineEventHandler(async (event) => {
4
+ const logger = useNventLogger("webhook-trigger");
5
+ const trigger = useTrigger();
6
+ const triggerName = event.context.params?.triggerName;
7
+ if (!triggerName) {
8
+ logger.warn("No trigger name provided in request");
9
+ return {
10
+ error: "Missing trigger name",
11
+ message: "Trigger name is required"
12
+ };
13
+ }
14
+ logger.info(`Webhook trigger received: ${event.method} ${triggerName}`);
15
+ const triggerEntry = trigger.getTrigger(triggerName);
16
+ if (!triggerEntry) {
17
+ logger.warn(`Trigger not found: ${triggerName}`);
18
+ return {
19
+ error: "Trigger not found",
20
+ triggerName,
21
+ message: `No trigger registered with name '${triggerName}'`
22
+ };
23
+ }
24
+ if (triggerEntry.type !== "webhook") {
25
+ logger.warn(`Trigger is not a webhook: ${triggerName} (type: ${triggerEntry.type})`);
26
+ return {
27
+ error: "Invalid trigger type",
28
+ triggerName,
29
+ expectedType: "webhook",
30
+ actualType: triggerEntry.type
31
+ };
32
+ }
33
+ const expectedMethod = triggerEntry.webhook?.method || "POST";
34
+ if (event.method !== expectedMethod) {
35
+ logger.warn(`Method mismatch: expected ${expectedMethod}, got ${event.method}`);
36
+ return {
37
+ error: "Method not allowed",
38
+ expectedMethod,
39
+ actualMethod: event.method
40
+ };
41
+ }
42
+ let webhookData;
43
+ if (event.method === "GET") {
44
+ webhookData = event.context.params || {};
45
+ } else {
46
+ webhookData = await readBody(event);
47
+ }
48
+ logger.debug(`Webhook data received`, {
49
+ triggerName,
50
+ dataKeys: Object.keys(webhookData || {})
51
+ });
52
+ await trigger.emitTrigger(triggerName, webhookData);
53
+ logger.info(`Webhook trigger fired`, {
54
+ triggerName,
55
+ subscribedFlows: trigger.getSubscribedFlows(triggerName).length
56
+ });
57
+ return {
58
+ success: true,
59
+ triggerName,
60
+ subscribedFlows: trigger.getSubscribedFlows(triggerName),
61
+ message: "Trigger fired successfully",
62
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
63
+ };
64
+ });
@@ -1,7 +1,7 @@
1
- import type { QueueAdapter } from '../adapters/interfaces/queue.js';
2
- import type { StreamAdapter } from '../adapters/interfaces/stream.js';
3
- import type { StoreAdapter } from '../adapters/interfaces/store.js';
4
- import type { AdapterSet } from '../adapters/factory.js';
1
+ import type { QueueAdapter } from '../../adapters/interfaces/queue.js';
2
+ import type { StreamAdapter } from '../../adapters/interfaces/stream.js';
3
+ import type { StoreAdapter } from '../../adapters/interfaces/store.js';
4
+ import type { AdapterSet } from '../../adapters/factory.js';
5
5
  declare global {
6
6
  var __nq_adapters: AdapterSet | undefined;
7
7
  }
@@ -36,8 +36,8 @@ export declare function useStreamAdapter(): StreamAdapter;
36
36
  *
37
37
  * @example
38
38
  * const store = useStoreAdapter()
39
- * await store.append('nq:flow:abc-123', { type: 'step.completed', data: {...} })
40
- * const events = await store.read('nq:flow:abc-123')
39
+ * await store.stream.append('nq:flow:abc-123', { type: 'step.completed', data: {...} })
40
+ * const events = await store.stream.read('nq:flow:abc-123')
41
41
  */
42
42
  export declare function useStoreAdapter(): StoreAdapter;
43
43
  /**
@@ -0,0 +1,15 @@
1
+ import type { AwaitConfig } from '../../../../registry/types.js';
2
+ /**
3
+ * Await Pattern: Event
4
+ *
5
+ * Waits for a specific event to be emitted (internal or external)
6
+ * Useful for cross-flow coordination, external system notifications
7
+ */
8
+ export declare function registerEventAwait(runId: string, stepName: string, flowName: string, config: AwaitConfig, position?: 'before' | 'after'): Promise<{
9
+ eventName: string;
10
+ timeout: number | undefined;
11
+ }>;
12
+ /**
13
+ * Resolve event await when target event is received
14
+ */
15
+ export declare function resolveEventAwait(runId: string, stepName: string, flowName: string, position: 'before' | 'after', eventData: any): Promise<void>;
@@ -0,0 +1,120 @@
1
+ import { useNventLogger, useScheduler } from "#imports";
2
+ import { getEventBus } from "../../../events/eventBus.js";
3
+ export async function registerEventAwait(runId, stepName, flowName, config, position = "after") {
4
+ const logger = useNventLogger("await-event");
5
+ const eventBus = getEventBus();
6
+ if (!config.event) {
7
+ throw new Error("Event await requires event name configuration");
8
+ }
9
+ logger.info(`Registering event await: ${config.event}`, { runId, stepName });
10
+ const unsubscribe = eventBus.onType(config.event, async (event) => {
11
+ if (config.filterKey) {
12
+ const awaitValue = event.data?.[config.filterKey];
13
+ const stepValue = event.data?.stepData?.[config.filterKey];
14
+ if (awaitValue !== stepValue) {
15
+ return;
16
+ }
17
+ }
18
+ await resolveEventAwait(runId, stepName, flowName, position, event.data);
19
+ unsubscribe();
20
+ });
21
+ eventBus.publish({
22
+ type: "await.registered",
23
+ flowName,
24
+ runId,
25
+ stepName,
26
+ awaitType: "event",
27
+ position,
28
+ config,
29
+ data: {
30
+ eventName: config.event,
31
+ filterKey: config.filterKey,
32
+ timeout: config.timeout,
33
+ registeredAt: Date.now()
34
+ }
35
+ });
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",
74
+ runId,
75
+ stepName,
76
+ flowName,
77
+ position,
78
+ timeout: config.timeout,
79
+ eventName: config.event
80
+ }
81
+ });
82
+ logger.debug(`Event timeout scheduled`, {
83
+ runId,
84
+ stepName,
85
+ eventName: config.event,
86
+ timeout: config.timeout,
87
+ timeoutAction: config.timeoutAction
88
+ });
89
+ }
90
+ logger.debug(`Event await registered: ${config.event}`, { runId, stepName });
91
+ return {
92
+ eventName: config.event,
93
+ timeout: config.timeout
94
+ };
95
+ }
96
+ export async function resolveEventAwait(runId, stepName, flowName, position, eventData) {
97
+ const logger = useNventLogger("await-event");
98
+ const eventBus = getEventBus();
99
+ const scheduler = useScheduler();
100
+ logger.info(`Resolving event await`, { runId, stepName });
101
+ const jobId = `await-event-timeout-${runId}-${stepName}-${position}`;
102
+ try {
103
+ await scheduler.unschedule(jobId);
104
+ logger.debug("Unscheduled event timeout job", { runId, stepName, jobId });
105
+ } catch {
106
+ logger.debug("Could not unschedule timeout job (may not exist)", { runId, stepName, jobId });
107
+ }
108
+ eventBus.publish({
109
+ type: "await.resolved",
110
+ flowName,
111
+ runId,
112
+ stepName,
113
+ position,
114
+ triggerData: eventData,
115
+ data: {
116
+ resolvedAt: Date.now()
117
+ }
118
+ });
119
+ logger.debug(`Event await resolved`, { runId, stepName });
120
+ }
@@ -0,0 +1,28 @@
1
+ import type { AwaitConfig } from '../../../../registry/types.js';
2
+ import { registerWebhookAwait, resolveWebhookAwait } from './webhook.js';
3
+ import { registerEventAwait, resolveEventAwait } from './event.js';
4
+ import { registerScheduleAwait, resolveScheduleAwait } from './schedule.js';
5
+ import { registerTimeAwait, resolveTimeAwait } from './time.js';
6
+ /**
7
+ * Unified await pattern registry
8
+ * Routes to appropriate await implementation based on type
9
+ */
10
+ export declare function registerAwaitPattern(runId: string, stepName: string, flowName: string, config: AwaitConfig, position?: 'before' | 'after'): Promise<{
11
+ delay: number;
12
+ resolveAt: number;
13
+ } | {
14
+ cron: string;
15
+ nextOccurrence: number;
16
+ timeUntilNext: number;
17
+ } | {
18
+ webhookUrl: string;
19
+ timeout: number | undefined;
20
+ } | {
21
+ eventName: string;
22
+ timeout: number | undefined;
23
+ }>;
24
+ /**
25
+ * Resolve await pattern by type
26
+ */
27
+ export declare function resolveAwaitPattern(type: 'webhook' | 'event' | 'schedule' | 'time', runId: string, stepName: string, flowName: string, position: 'before' | 'after', data: any): Promise<void>;
28
+ export { registerWebhookAwait, resolveWebhookAwait, registerEventAwait, resolveEventAwait, registerScheduleAwait, resolveScheduleAwait, registerTimeAwait, resolveTimeAwait, };
@@ -0,0 +1,55 @@
1
+ import { useNventLogger } from "#imports";
2
+ import { registerWebhookAwait, resolveWebhookAwait } from "./webhook.js";
3
+ import { registerEventAwait, resolveEventAwait } from "./event.js";
4
+ import { registerScheduleAwait, resolveScheduleAwait } from "./schedule.js";
5
+ import { registerTimeAwait, resolveTimeAwait } from "./time.js";
6
+ export async function registerAwaitPattern(runId, stepName, flowName, config, position = "after") {
7
+ const logger = useNventLogger("await-patterns");
8
+ logger.info(`Registering await pattern: ${config.type}`, {
9
+ runId,
10
+ stepName,
11
+ type: config.type
12
+ });
13
+ switch (config.type) {
14
+ case "webhook":
15
+ return await registerWebhookAwait(runId, stepName, flowName, config, position);
16
+ case "event":
17
+ return await registerEventAwait(runId, stepName, flowName, config, position);
18
+ case "schedule":
19
+ return await registerScheduleAwait(runId, stepName, flowName, config, position);
20
+ case "time":
21
+ return await registerTimeAwait(runId, stepName, flowName, config, position);
22
+ default:
23
+ throw new Error(`Unknown await pattern type: ${config.type}`);
24
+ }
25
+ }
26
+ export async function resolveAwaitPattern(type, runId, stepName, flowName, position, data) {
27
+ const logger = useNventLogger("await-patterns");
28
+ logger.info(`Resolving await pattern: ${type}`, {
29
+ runId,
30
+ stepName,
31
+ type
32
+ });
33
+ switch (type) {
34
+ case "webhook":
35
+ return await resolveWebhookAwait(runId, stepName, data);
36
+ case "event":
37
+ return await resolveEventAwait(runId, stepName, data);
38
+ case "schedule":
39
+ return await resolveScheduleAwait(runId, stepName, data);
40
+ case "time":
41
+ return await resolveTimeAwait(runId, stepName, flowName, position, data);
42
+ default:
43
+ throw new Error(`Unknown await pattern type: ${type}`);
44
+ }
45
+ }
46
+ export {
47
+ registerWebhookAwait,
48
+ resolveWebhookAwait,
49
+ registerEventAwait,
50
+ resolveEventAwait,
51
+ registerScheduleAwait,
52
+ resolveScheduleAwait,
53
+ registerTimeAwait,
54
+ resolveTimeAwait
55
+ };
@@ -0,0 +1,16 @@
1
+ import type { AwaitConfig } from '../../../../registry/types.js';
2
+ /**
3
+ * Await Pattern: Schedule
4
+ *
5
+ * Waits until next cron schedule occurrence
6
+ * Useful for batch processing, daily reports, scheduled operations
7
+ */
8
+ export declare function registerScheduleAwait(runId: string, stepName: string, flowName: string, config: AwaitConfig, position?: 'before' | 'after'): Promise<{
9
+ cron: string;
10
+ nextOccurrence: number;
11
+ timeUntilNext: number;
12
+ }>;
13
+ /**
14
+ * Resolve schedule await when cron time is reached
15
+ */
16
+ export declare function resolveScheduleAwait(runId: string, stepName: string, flowName: string, position: 'before' | 'after', scheduleData: any): Promise<void>;