nvent 0.4.5 → 0.5.0
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.d.mts +1 -1
- package/dist/module.mjs +433 -175
- package/dist/runtime/adapters/base/index.d.ts +6 -0
- package/dist/runtime/adapters/base/index.js +1 -0
- package/dist/runtime/adapters/base/store-validator.d.ts +48 -0
- package/dist/runtime/adapters/base/store-validator.js +147 -0
- package/dist/runtime/adapters/builtin/file-queue.d.ts +15 -1
- package/dist/runtime/adapters/builtin/file-queue.js +70 -6
- package/dist/runtime/adapters/builtin/file-store.d.ts +4 -18
- package/dist/runtime/adapters/builtin/file-store.js +90 -109
- package/dist/runtime/adapters/builtin/memory-queue.js +4 -0
- package/dist/runtime/adapters/builtin/memory-store.d.ts +42 -31
- package/dist/runtime/adapters/builtin/memory-store.js +253 -183
- package/dist/runtime/adapters/factory.d.ts +2 -2
- package/dist/runtime/adapters/factory.js +54 -20
- package/dist/runtime/adapters/interfaces/store.d.ts +177 -113
- package/dist/runtime/config/index.d.ts +2 -2
- package/dist/runtime/config/index.js +14 -6
- package/dist/runtime/config/types.d.ts +32 -2
- package/dist/runtime/events/eventBus.d.ts +1 -1
- package/dist/runtime/events/types.d.ts +31 -2
- package/dist/runtime/events/utils/scheduleTrigger.d.ts +8 -0
- package/dist/runtime/events/utils/scheduleTrigger.js +69 -0
- package/dist/runtime/events/utils/stallDetector.d.ts +44 -3
- package/dist/runtime/events/utils/stallDetector.js +288 -89
- package/dist/runtime/events/utils/triggerRuntime.d.ts +58 -0
- package/dist/runtime/events/utils/triggerRuntime.js +212 -0
- package/dist/runtime/events/wiring/flowWiring.d.ts +11 -5
- package/dist/runtime/events/wiring/flowWiring.js +620 -92
- package/dist/runtime/events/wiring/registry.d.ts +2 -2
- package/dist/runtime/events/wiring/registry.js +8 -6
- package/dist/runtime/events/wiring/streamWiring.d.ts +15 -11
- package/dist/runtime/events/wiring/streamWiring.js +88 -11
- package/dist/runtime/events/wiring/triggerWiring.d.ts +21 -0
- package/dist/runtime/events/wiring/triggerWiring.js +412 -0
- package/dist/runtime/{server → nitro}/plugins/00.adapters.js +8 -4
- package/dist/runtime/{server → nitro}/plugins/02.workers.js +21 -3
- package/dist/runtime/nitro/plugins/03.triggers.d.ts +12 -0
- package/dist/runtime/nitro/plugins/03.triggers.js +55 -0
- package/dist/runtime/nitro/routes/webhook.await.d.ts +23 -0
- package/dist/runtime/nitro/routes/webhook.await.js +90 -0
- package/dist/runtime/nitro/routes/webhook.trigger.d.ts +69 -0
- package/dist/runtime/nitro/routes/webhook.trigger.js +64 -0
- package/dist/runtime/{utils → nitro/utils}/adapters.d.ts +6 -6
- package/dist/runtime/nitro/utils/awaitPatterns/event.d.ts +15 -0
- package/dist/runtime/nitro/utils/awaitPatterns/event.js +120 -0
- package/dist/runtime/nitro/utils/awaitPatterns/index.d.ts +28 -0
- package/dist/runtime/nitro/utils/awaitPatterns/index.js +55 -0
- package/dist/runtime/nitro/utils/awaitPatterns/schedule.d.ts +16 -0
- package/dist/runtime/nitro/utils/awaitPatterns/schedule.js +78 -0
- package/dist/runtime/nitro/utils/awaitPatterns/time.d.ts +15 -0
- package/dist/runtime/nitro/utils/awaitPatterns/time.js +67 -0
- package/dist/runtime/nitro/utils/awaitPatterns/webhook.d.ts +15 -0
- package/dist/runtime/nitro/utils/awaitPatterns/webhook.js +120 -0
- package/dist/runtime/{utils → nitro/utils}/defineFunction.d.ts +2 -2
- package/dist/runtime/{utils → nitro/utils}/defineFunction.js +3 -3
- package/dist/runtime/{utils → nitro/utils}/defineFunctionConfig.d.ts +156 -0
- package/dist/runtime/{utils → nitro/utils}/defineFunctionConfig.js +1 -0
- package/dist/runtime/nitro/utils/defineHooks.d.ts +41 -0
- package/dist/runtime/nitro/utils/defineHooks.js +6 -0
- package/dist/runtime/{utils → nitro/utils}/registerAdapter.d.ts +3 -3
- package/dist/runtime/{utils → nitro/utils}/registerAdapter.js +1 -1
- package/dist/runtime/nitro/utils/useAwait.d.ts +71 -0
- package/dist/runtime/nitro/utils/useAwait.js +139 -0
- package/dist/runtime/{utils → nitro/utils}/useEventManager.d.ts +2 -2
- package/dist/runtime/{utils → nitro/utils}/useEventManager.js +1 -1
- package/dist/runtime/nitro/utils/useFlow.d.ts +68 -0
- package/dist/runtime/nitro/utils/useFlow.js +226 -0
- package/dist/runtime/nitro/utils/useHookRegistry.d.ts +34 -0
- package/dist/runtime/nitro/utils/useHookRegistry.js +25 -0
- package/dist/runtime/nitro/utils/useRunContext.d.ts +6 -0
- package/dist/runtime/nitro/utils/useRunContext.js +102 -0
- package/dist/runtime/nitro/utils/useStreamTopics.d.ts +83 -0
- package/dist/runtime/nitro/utils/useStreamTopics.js +94 -0
- package/dist/runtime/nitro/utils/useTrigger.d.ts +150 -0
- package/dist/runtime/nitro/utils/useTrigger.js +320 -0
- package/dist/runtime/scheduler/index.d.ts +33 -0
- package/dist/runtime/scheduler/index.js +38 -0
- package/dist/runtime/scheduler/scheduler.d.ts +113 -0
- package/dist/runtime/scheduler/scheduler.js +623 -0
- package/dist/runtime/scheduler/types.d.ts +116 -0
- package/dist/runtime/scheduler/types.js +0 -0
- package/dist/runtime/worker/node/runner.d.ts +12 -2
- package/dist/runtime/worker/node/runner.js +141 -37
- package/package.json +6 -6
- package/dist/runtime/server/api/_flows/[name]/clear-history.delete.d.ts +0 -10
- package/dist/runtime/server/api/_flows/[name]/clear-history.delete.js +0 -55
- package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.d.ts +0 -2
- package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.js +0 -21
- package/dist/runtime/server/api/_flows/[name]/runs.get.d.ts +0 -17
- package/dist/runtime/server/api/_flows/[name]/runs.get.js +0 -64
- package/dist/runtime/server/api/_flows/[name]/schedule.post.d.ts +0 -2
- package/dist/runtime/server/api/_flows/[name]/schedule.post.js +0 -66
- package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.d.ts +0 -2
- package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.js +0 -47
- package/dist/runtime/server/api/_flows/[name]/schedules.get.d.ts +0 -2
- package/dist/runtime/server/api/_flows/[name]/schedules.get.js +0 -50
- package/dist/runtime/server/api/_flows/[name]/start.post.d.ts +0 -2
- package/dist/runtime/server/api/_flows/[name]/start.post.js +0 -9
- package/dist/runtime/server/api/_flows/index.get.d.ts +0 -6
- package/dist/runtime/server/api/_flows/index.get.js +0 -5
- package/dist/runtime/server/api/_flows/ws.d.ts +0 -60
- package/dist/runtime/server/api/_flows/ws.js +0 -209
- package/dist/runtime/server/api/_queues/[name]/job/[id].get.d.ts +0 -2
- package/dist/runtime/server/api/_queues/[name]/job/[id].get.js +0 -14
- package/dist/runtime/server/api/_queues/[name]/job/index.get.d.ts +0 -2
- package/dist/runtime/server/api/_queues/[name]/job/index.get.js +0 -27
- package/dist/runtime/server/api/_queues/index.get.d.ts +0 -2
- package/dist/runtime/server/api/_queues/index.get.js +0 -106
- package/dist/runtime/server/api/_queues/ws.d.ts +0 -48
- package/dist/runtime/server/api/_queues/ws.js +0 -215
- package/dist/runtime/utils/useFlowEngine.d.ts +0 -19
- package/dist/runtime/utils/useFlowEngine.js +0 -108
- package/dist/runtime/utils/useStreamTopics.d.ts +0 -72
- package/dist/runtime/utils/useStreamTopics.js +0 -47
- /package/dist/runtime/{server → nitro}/plugins/00.adapters.d.ts +0 -0
- /package/dist/runtime/{server → nitro}/plugins/01.ws-lifecycle.d.ts +0 -0
- /package/dist/runtime/{server → nitro}/plugins/01.ws-lifecycle.js +0 -0
- /package/dist/runtime/{server → nitro}/plugins/02.workers.d.ts +0 -0
- /package/dist/runtime/{utils → nitro/utils}/adapters.js +0 -0
- /package/dist/runtime/{utils → nitro/utils}/useNventLogger.d.ts +0 -0
- /package/dist/runtime/{utils → nitro/utils}/useNventLogger.js +0 -0
- /package/dist/runtime/{utils → nitro/utils}/wsPeerManager.d.ts +0 -0
- /package/dist/runtime/{utils → nitro/utils}/wsPeerManager.js +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useAdapterRegistry } from "./registry.js";
|
|
2
|
+
import { useStreamTopics, $useAnalyzedFlows } from "#imports";
|
|
2
3
|
import {
|
|
3
4
|
MemoryQueueAdapter,
|
|
4
5
|
MemoryStreamAdapter,
|
|
@@ -39,29 +40,62 @@ async function createStreamAdapter(config) {
|
|
|
39
40
|
async function createStoreAdapter(config) {
|
|
40
41
|
const type = config.adapter || "file";
|
|
41
42
|
const registry = useAdapterRegistry();
|
|
43
|
+
let adapter;
|
|
42
44
|
if (registry.hasStore(type)) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
adapter = registry.getStore(type);
|
|
46
|
+
} else {
|
|
47
|
+
switch (type) {
|
|
48
|
+
case "memory": {
|
|
49
|
+
adapter = new MemoryStoreAdapter();
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case "file": {
|
|
53
|
+
const dataDir = config.file?.dataDir || ".data/store";
|
|
54
|
+
const fileAdapter = new FileStoreAdapter({
|
|
55
|
+
dataDir
|
|
56
|
+
});
|
|
57
|
+
await fileAdapter.init();
|
|
58
|
+
adapter = fileAdapter;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case "redis":
|
|
62
|
+
throw new Error("Redis store adapter not registered. Install @nvent/adapter-store-redis and add it to your nuxt.config modules.");
|
|
63
|
+
case "postgres":
|
|
64
|
+
throw new Error("Postgres store adapter not yet implemented");
|
|
65
|
+
default:
|
|
66
|
+
throw new Error(`Unknown store adapter type: ${type}`);
|
|
49
67
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const { StoreSubjects } = useStreamTopics();
|
|
71
|
+
const flowIndexKey = StoreSubjects.flowIndex();
|
|
72
|
+
const existingFlows = await adapter.index.read(flowIndexKey, { limit: 1 });
|
|
73
|
+
if (existingFlows.length === 0) {
|
|
74
|
+
const analyzedFlows = $useAnalyzedFlows();
|
|
75
|
+
if (analyzedFlows && analyzedFlows.length > 0) {
|
|
76
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
77
|
+
for (const flow of analyzedFlows) {
|
|
78
|
+
await adapter.index.add(flowIndexKey, flow.id, Date.now(), {
|
|
79
|
+
name: flow.id,
|
|
80
|
+
displayName: flow.id,
|
|
81
|
+
registeredAt: now,
|
|
82
|
+
stats: {
|
|
83
|
+
total: 0,
|
|
84
|
+
success: 0,
|
|
85
|
+
failure: 0,
|
|
86
|
+
cancel: 0,
|
|
87
|
+
running: 0,
|
|
88
|
+
awaiting: 0
|
|
89
|
+
},
|
|
90
|
+
version: 1
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
57
94
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
case "postgres":
|
|
61
|
-
throw new Error("Postgres store adapter not yet implemented");
|
|
62
|
-
default:
|
|
63
|
-
throw new Error(`Unknown store adapter type: ${type}`);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.warn("[factory] Failed to initialize flow index:", err?.message);
|
|
64
97
|
}
|
|
98
|
+
return adapter;
|
|
65
99
|
}
|
|
66
100
|
async function createQueueAdapter(config) {
|
|
67
101
|
const type = config.adapter || "file";
|
|
@@ -86,7 +120,7 @@ async function createQueueAdapter(config) {
|
|
|
86
120
|
case "redis":
|
|
87
121
|
throw new Error("Redis queue adapter not registered. Install @nvent/adapter-queue-redis and add it to your nuxt.config modules.");
|
|
88
122
|
case "postgres":
|
|
89
|
-
throw new Error("Postgres queue adapter
|
|
123
|
+
throw new Error("Postgres queue adapter not registered. Install @nvent/adapter-queue-postgres and add it to your nuxt.config modules.");
|
|
90
124
|
default:
|
|
91
125
|
throw new Error(`Unknown queue adapter type: ${type}`);
|
|
92
126
|
}
|
|
@@ -2,66 +2,121 @@
|
|
|
2
2
|
* Store Adapter Interface
|
|
3
3
|
*
|
|
4
4
|
* Three-tier storage system:
|
|
5
|
-
* 1. Event Stream - Append-only event log
|
|
6
|
-
* 2.
|
|
5
|
+
* 1. Event Stream - Append-only event log
|
|
6
|
+
* 2. Sorted Index - Time-ordered metadata storage
|
|
7
7
|
* 3. Key-Value Store - Fast lookups (for state, caching)
|
|
8
|
+
*
|
|
9
|
+
* ## Critical Implementation Requirements
|
|
10
|
+
*
|
|
11
|
+
* ### 1. Index Operations - add() vs update()
|
|
12
|
+
*
|
|
13
|
+
* **index.add()** - MUST completely REPLACE metadata when entry exists:
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // First call
|
|
16
|
+
* await index.add('flows', 'my-flow', 123, { name: 'Flow', stats: {...} })
|
|
17
|
+
* // Second call - REPLACES entire metadata
|
|
18
|
+
* await index.add('flows', 'my-flow', 456, { lastRunAt: 789 })
|
|
19
|
+
* // Result: { lastRunAt: 789 } ← stats are LOST!
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* **index.update()** - MUST perform DEEP MERGE of metadata:
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // Initial state: { status: 'running', emittedEvents: { test: { completed: 1 } } }
|
|
25
|
+
* await index.update('runs', 'run-id', { emittedEvents: { another: { fired: 2 } } })
|
|
26
|
+
* // Result: { status: 'running', emittedEvents: { test: { completed: 1 }, another: { fired: 2 } } }
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* ⚠️ **CRITICAL**: update() must perform DEEP merge at ALL nesting levels, not just top-level!
|
|
30
|
+
* - PostgreSQL `||` operator: Only shallow merge (top-level keys)
|
|
31
|
+
* - Redis HSET loop: Field-level merge (simulates deep merge for flat structures)
|
|
32
|
+
* - Memory defu(): True deep merge
|
|
33
|
+
*
|
|
34
|
+
* ### 2. Nested Metadata Structure
|
|
35
|
+
*
|
|
36
|
+
* Flow orchestration stores deeply nested metadata:
|
|
37
|
+
* ```typescript
|
|
38
|
+
* {
|
|
39
|
+
* emittedEvents: {
|
|
40
|
+
* 'step1': {
|
|
41
|
+
* 'completed': 1234567890,
|
|
42
|
+
* 'custom_event': 1234567891
|
|
43
|
+
* },
|
|
44
|
+
* 'step2': {
|
|
45
|
+
* 'completed': 1234567892
|
|
46
|
+
* }
|
|
47
|
+
* },
|
|
48
|
+
* awaitingSteps: {
|
|
49
|
+
* 'step_name': {
|
|
50
|
+
* status: 'awaiting',
|
|
51
|
+
* position: 'after',
|
|
52
|
+
* awaitType: 'event'
|
|
53
|
+
* }
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* Multiple updates add to nested structures incrementally. If deep merge fails,
|
|
59
|
+
* flow orchestration will miss events and steps won't trigger.
|
|
60
|
+
*
|
|
61
|
+
* ### 3. Concurrent Updates
|
|
62
|
+
*
|
|
63
|
+
* Flow steps run in parallel and update metadata concurrently:
|
|
64
|
+
* - Multiple steps emit events simultaneously
|
|
65
|
+
* - Each emits triggers index.updateWithRetry() with partial metadata
|
|
66
|
+
* - Updates must NOT overwrite each other
|
|
67
|
+
* - Use optimistic locking (version field) + retries
|
|
68
|
+
*
|
|
69
|
+
* ### 4. Testing Deep Merge
|
|
70
|
+
*
|
|
71
|
+
* Test that your adapter correctly handles:
|
|
72
|
+
* ```typescript
|
|
73
|
+
* // Setup
|
|
74
|
+
* await index.add('test', 'id', 1, { a: { b: 1 }, c: 2 })
|
|
75
|
+
*
|
|
76
|
+
* // Update nested property
|
|
77
|
+
* await index.update('test', 'id', { a: { d: 3 } })
|
|
78
|
+
* const result = await index.get('test', 'id')
|
|
79
|
+
*
|
|
80
|
+
* // MUST preserve existing nested data
|
|
81
|
+
* expect(result.metadata).toEqual({ a: { b: 1, d: 3 }, c: 2 })
|
|
82
|
+
* // NOT: { a: { d: 3 }, c: 2 } ← b is lost!
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
8
85
|
*/
|
|
9
86
|
export interface StoreAdapter {
|
|
10
87
|
/**
|
|
11
88
|
* Close/cleanup the adapter
|
|
12
89
|
*/
|
|
13
90
|
close(): Promise<void>;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
* Get a document from a collection
|
|
44
|
-
* @param collection - Collection name
|
|
45
|
-
* @param id - Document ID
|
|
46
|
-
* @returns Document or null if not found
|
|
47
|
-
*/
|
|
48
|
-
get(collection: string, id: string): Promise<Record<string, any> | null>;
|
|
49
|
-
/**
|
|
50
|
-
* List documents in a collection (optional, not all adapters may support complex queries)
|
|
51
|
-
* @param collection - Collection name
|
|
52
|
-
* @param opts - Query options (filtering, pagination, sorting)
|
|
53
|
-
* @returns Array of documents with their IDs
|
|
54
|
-
*/
|
|
55
|
-
list?(collection: string, opts?: ListOptions): Promise<Array<{
|
|
56
|
-
id: string;
|
|
57
|
-
doc: any;
|
|
58
|
-
}>>;
|
|
59
|
-
/**
|
|
60
|
-
* Delete a document from a collection
|
|
61
|
-
* @param collection - Collection name
|
|
62
|
-
* @param id - Document ID
|
|
63
|
-
*/
|
|
64
|
-
delete(collection: string, id: string): Promise<void>;
|
|
91
|
+
stream: {
|
|
92
|
+
/**
|
|
93
|
+
* Append an event to a subject's event stream
|
|
94
|
+
* @param subject - Event stream identifier (e.g., 'nq:flow:abc-123')
|
|
95
|
+
* @param event - Event to append (id and ts will be auto-generated)
|
|
96
|
+
* @returns The complete event record with generated id and timestamp
|
|
97
|
+
*/
|
|
98
|
+
append(subject: string, event: Omit<EventRecord, 'id' | 'ts'>): Promise<EventRecord>;
|
|
99
|
+
/**
|
|
100
|
+
* Read events from a subject's event stream
|
|
101
|
+
* @param subject - Event stream identifier
|
|
102
|
+
* @param opts - Query options (filtering, pagination, etc.)
|
|
103
|
+
* @returns Array of event records
|
|
104
|
+
*/
|
|
105
|
+
read(subject: string, opts?: EventReadOptions): Promise<EventRecord[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Subscribe to new events in a subject's event stream (optional, not all adapters support this)
|
|
108
|
+
* @param subject - Event stream identifier (supports wildcards if adapter allows)
|
|
109
|
+
* @param onEvent - Callback for new events
|
|
110
|
+
* @returns Subscription handle for unsubscribing
|
|
111
|
+
*/
|
|
112
|
+
subscribe?(subject: string, onEvent: (event: EventRecord) => void): Promise<EventSubscription>;
|
|
113
|
+
/**
|
|
114
|
+
* Delete an entire event stream
|
|
115
|
+
* @param subject - Event stream identifier
|
|
116
|
+
* @returns True if stream was deleted, false if not found
|
|
117
|
+
*/
|
|
118
|
+
delete?(subject: string): Promise<boolean>;
|
|
119
|
+
};
|
|
65
120
|
kv: {
|
|
66
121
|
/**
|
|
67
122
|
* Get a value by key
|
|
@@ -89,66 +144,75 @@ export interface StoreAdapter {
|
|
|
89
144
|
*/
|
|
90
145
|
increment?(key: string, by?: number): Promise<number>;
|
|
91
146
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
id: string
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
index: {
|
|
148
|
+
/**
|
|
149
|
+
* Add entry to a sorted index
|
|
150
|
+
* @param key - Index key (e.g., 'nq:flows:flowName')
|
|
151
|
+
* @param id - Entry ID
|
|
152
|
+
* @param score - Sort score (typically timestamp)
|
|
153
|
+
* @param metadata - Optional metadata to store with entry
|
|
154
|
+
*/
|
|
155
|
+
add(key: string, id: string, score: number, metadata?: Record<string, any>): Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Get a single entry from a sorted index
|
|
158
|
+
* @param key - Index key
|
|
159
|
+
* @param id - Entry ID
|
|
160
|
+
* @returns Entry with score and metadata, or null if not found
|
|
161
|
+
*/
|
|
162
|
+
get(key: string, id: string): Promise<{
|
|
163
|
+
id: string;
|
|
164
|
+
score: number;
|
|
165
|
+
metadata?: any;
|
|
166
|
+
} | null>;
|
|
167
|
+
/**
|
|
168
|
+
* Read entries from a sorted index (ordered by score descending)
|
|
169
|
+
* @param key - Index key
|
|
170
|
+
* @param opts - Pagination options
|
|
171
|
+
* @param opts.offset - Number of entries to skip
|
|
172
|
+
* @param opts.limit - Maximum number of entries to return
|
|
173
|
+
* @returns Array of entries with scores and metadata
|
|
174
|
+
*/
|
|
175
|
+
read(key: string, opts?: {
|
|
176
|
+
offset?: number;
|
|
177
|
+
limit?: number;
|
|
178
|
+
}): Promise<Array<{
|
|
179
|
+
id: string;
|
|
180
|
+
score: number;
|
|
181
|
+
metadata?: any;
|
|
182
|
+
}>>;
|
|
183
|
+
/**
|
|
184
|
+
* Update metadata for an entry in a sorted index
|
|
185
|
+
* @param key - Index key
|
|
186
|
+
* @param id - Entry ID
|
|
187
|
+
* @param metadata - Metadata to update
|
|
188
|
+
* @returns True if update succeeded, false if version conflict
|
|
189
|
+
*/
|
|
190
|
+
update(key: string, id: string, metadata: Record<string, any>): Promise<boolean>;
|
|
191
|
+
/**
|
|
192
|
+
* Update with automatic retries on version conflicts
|
|
193
|
+
* @param key - Index key
|
|
194
|
+
* @param id - Entry ID
|
|
195
|
+
* @param metadata - Metadata to update
|
|
196
|
+
* @param maxRetries - Maximum retry attempts (default: 3)
|
|
197
|
+
*/
|
|
198
|
+
updateWithRetry(key: string, id: string, metadata: Record<string, any>, maxRetries?: number): Promise<void>;
|
|
199
|
+
/**
|
|
200
|
+
* Atomic increment of a metadata field in an index entry
|
|
201
|
+
* @param key - Index key
|
|
202
|
+
* @param id - Entry ID
|
|
203
|
+
* @param field - Field name to increment
|
|
204
|
+
* @param increment - Amount to increment by (default: 1)
|
|
205
|
+
* @returns New value after increment
|
|
206
|
+
*/
|
|
207
|
+
increment(key: string, id: string, field: string, increment?: number): Promise<number>;
|
|
208
|
+
/**
|
|
209
|
+
* Delete an entry from a sorted index
|
|
210
|
+
* @param key - Index key
|
|
211
|
+
* @param id - Entry ID
|
|
212
|
+
* @returns True if entry was deleted, false if not found
|
|
213
|
+
*/
|
|
214
|
+
delete(key: string, id: string): Promise<boolean>;
|
|
215
|
+
};
|
|
152
216
|
}
|
|
153
217
|
/**
|
|
154
218
|
* Event record in the event stream
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { ModuleOptions, ModuleConfig } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Merge and normalize module options with defaults
|
|
3
|
+
* Merge and normalize module options with defaults.
|
|
4
4
|
* Applies connection fallback: adapter-specific connections override connections.redis/postgres.
|
|
5
5
|
* Only includes connection defaults for adapters that are actually used.
|
|
6
6
|
*/
|
|
7
7
|
export declare function normalizeModuleOptions(options: ModuleOptions): Required<ModuleOptions>;
|
|
8
8
|
/**
|
|
9
|
-
* Convert normalized module options to runtime config format
|
|
9
|
+
* Convert normalized module options to runtime config format.
|
|
10
10
|
*/
|
|
11
11
|
export declare function toRuntimeConfig(normalizedOptions: Required<ModuleOptions>): ModuleConfig;
|
|
12
12
|
/**
|
|
@@ -7,7 +7,8 @@ export function normalizeModuleOptions(options) {
|
|
|
7
7
|
connections: {},
|
|
8
8
|
queue: {
|
|
9
9
|
adapter: "file",
|
|
10
|
-
prefix: "
|
|
10
|
+
prefix: "nvent",
|
|
11
|
+
schema: "nvent_queue",
|
|
11
12
|
defaultJobOptions: {},
|
|
12
13
|
worker: {
|
|
13
14
|
concurrency: 2,
|
|
@@ -17,11 +18,12 @@ export function normalizeModuleOptions(options) {
|
|
|
17
18
|
},
|
|
18
19
|
stream: {
|
|
19
20
|
adapter: "memory",
|
|
20
|
-
prefix: "
|
|
21
|
+
prefix: "nvent"
|
|
21
22
|
},
|
|
22
23
|
store: {
|
|
23
24
|
adapter: "file",
|
|
24
|
-
prefix: "
|
|
25
|
+
prefix: "nvent",
|
|
26
|
+
schema: "nvent_store",
|
|
25
27
|
state: {
|
|
26
28
|
autoScope: "always",
|
|
27
29
|
cleanup: {
|
|
@@ -35,7 +37,7 @@ export function normalizeModuleOptions(options) {
|
|
|
35
37
|
metadataTTL: 2592e3
|
|
36
38
|
// 30 days
|
|
37
39
|
},
|
|
38
|
-
|
|
40
|
+
flow: {
|
|
39
41
|
stallDetection: {
|
|
40
42
|
enabled: true,
|
|
41
43
|
stallTimeout: 30 * 60 * 1e3,
|
|
@@ -44,6 +46,11 @@ export function normalizeModuleOptions(options) {
|
|
|
44
46
|
// 15 minutes
|
|
45
47
|
enablePeriodicCheck: true
|
|
46
48
|
}
|
|
49
|
+
},
|
|
50
|
+
webhooks: {
|
|
51
|
+
// baseUrl will be determined at runtime from Nitro context
|
|
52
|
+
// Users can override via NUXT_PUBLIC_SITE_URL or explicit config
|
|
53
|
+
baseUrl: process.env.NUXT_PUBLIC_SITE_URL || void 0
|
|
47
54
|
}
|
|
48
55
|
};
|
|
49
56
|
const normalized = defu(options, defaults);
|
|
@@ -83,7 +90,7 @@ export function normalizeModuleOptions(options) {
|
|
|
83
90
|
}
|
|
84
91
|
if (neededConnections.has("postgres") && !normalized.connections.postgres) {
|
|
85
92
|
normalized.connections.postgres = {
|
|
86
|
-
connectionString: process.env.DATABASE_URL || "postgresql://localhost:5432/
|
|
93
|
+
connectionString: process.env.DATABASE_URL || "postgresql://localhost:5432/nvent"
|
|
87
94
|
};
|
|
88
95
|
}
|
|
89
96
|
if (neededConnections.has("rabbitmq") && !normalized.connections.rabbitmq) {
|
|
@@ -146,7 +153,8 @@ export function toRuntimeConfig(normalizedOptions) {
|
|
|
146
153
|
stream: normalizedOptions.stream,
|
|
147
154
|
store: normalizedOptions.store,
|
|
148
155
|
connections: normalizedOptions.connections,
|
|
149
|
-
|
|
156
|
+
flow: normalizedOptions.flow,
|
|
157
|
+
webhooks: normalizedOptions.webhooks
|
|
150
158
|
};
|
|
151
159
|
}
|
|
152
160
|
export function getRedisStorageConfig(normalizedOptions) {
|
|
@@ -133,6 +133,12 @@ export interface QueueConfig {
|
|
|
133
133
|
* Queue-specific options (BullMQ/PGBoss configuration)
|
|
134
134
|
*/
|
|
135
135
|
prefix?: string;
|
|
136
|
+
/**
|
|
137
|
+
* PostgreSQL schema name for pg-boss tables
|
|
138
|
+
* Only applies when adapter is 'postgres'
|
|
139
|
+
* @default 'pgboss'
|
|
140
|
+
*/
|
|
141
|
+
schema?: string;
|
|
136
142
|
defaultJobOptions?: {
|
|
137
143
|
attempts?: number;
|
|
138
144
|
backoff?: number | {
|
|
@@ -189,6 +195,18 @@ export interface StreamConfig {
|
|
|
189
195
|
retryAttempts?: number;
|
|
190
196
|
retryDelay?: number;
|
|
191
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Webhooks configuration
|
|
200
|
+
*/
|
|
201
|
+
export interface WebhooksConfig {
|
|
202
|
+
/**
|
|
203
|
+
* Base URL for webhook endpoints
|
|
204
|
+
* Auto-detected from Nitro context in development
|
|
205
|
+
* Set explicitly for production or to override auto-detection
|
|
206
|
+
* @default Auto-detected from NUXT_PUBLIC_SITE_URL, NITRO_URL, or dev server (http://localhost:3000 fallback)
|
|
207
|
+
*/
|
|
208
|
+
baseUrl?: string;
|
|
209
|
+
}
|
|
192
210
|
/**
|
|
193
211
|
* Flow configuration
|
|
194
212
|
*/
|
|
@@ -281,6 +299,12 @@ export interface StoreConfig {
|
|
|
281
299
|
* @default 'nq'
|
|
282
300
|
*/
|
|
283
301
|
prefix?: string;
|
|
302
|
+
/**
|
|
303
|
+
* PostgreSQL schema name for store tables
|
|
304
|
+
* Only applies when adapter is 'postgres'
|
|
305
|
+
* @default 'public'
|
|
306
|
+
*/
|
|
307
|
+
schema?: string;
|
|
284
308
|
/**
|
|
285
309
|
* State management configuration (KV store behavior)
|
|
286
310
|
*/
|
|
@@ -345,7 +369,12 @@ export interface ModuleOptions {
|
|
|
345
369
|
* Flow-specific configuration
|
|
346
370
|
* @since v0.4.1
|
|
347
371
|
*/
|
|
348
|
-
|
|
372
|
+
flow?: FlowConfig;
|
|
373
|
+
/**
|
|
374
|
+
* Webhooks configuration
|
|
375
|
+
* @since v0.5.0
|
|
376
|
+
*/
|
|
377
|
+
webhooks?: WebhooksConfig;
|
|
349
378
|
/**
|
|
350
379
|
* Shared connection configurations
|
|
351
380
|
* Used as fallback if adapters don't specify their own connections
|
|
@@ -361,7 +390,8 @@ export interface ModuleConfig {
|
|
|
361
390
|
queue: Required<QueueConfig>;
|
|
362
391
|
stream: Required<StreamConfig>;
|
|
363
392
|
store: Required<StoreConfig>;
|
|
364
|
-
|
|
393
|
+
flow: Required<FlowConfig>;
|
|
394
|
+
webhooks: Required<WebhooksConfig>;
|
|
365
395
|
connections: Required<ConnectionsConfig>;
|
|
366
396
|
rootDir?: string;
|
|
367
397
|
}
|
|
@@ -15,7 +15,7 @@ export interface PublishPayload<T = any> {
|
|
|
15
15
|
attempt?: number;
|
|
16
16
|
data?: T;
|
|
17
17
|
}
|
|
18
|
-
export type EventType = 'flow.start' | 'flow.completed' | 'flow.failed' | 'flow.cancel' | 'step.started' | 'step.completed' | 'step.failed' | 'step.retry' | 'log' | 'emit' | 'state' | 'flow.stalled';
|
|
18
|
+
export type EventType = 'flow.start' | 'flow.completed' | 'flow.failed' | 'flow.cancel' | 'step.started' | 'step.completed' | 'step.failed' | 'step.retry' | 'log' | 'emit' | 'state' | 'flow.stalled' | 'trigger.fired' | 'trigger.registered' | 'await.registered' | 'await.resolved' | 'await.timeout';
|
|
19
19
|
export interface BaseEvent {
|
|
20
20
|
id?: string;
|
|
21
21
|
ts?: string;
|
|
@@ -113,4 +113,33 @@ export interface StateEvent extends StepEvent {
|
|
|
113
113
|
value?: any;
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
|
-
export
|
|
116
|
+
export interface TriggerFiredEvent extends BaseEvent {
|
|
117
|
+
type: 'trigger.fired';
|
|
118
|
+
triggerName: string;
|
|
119
|
+
data: any;
|
|
120
|
+
}
|
|
121
|
+
export interface TriggerRegisteredEvent {
|
|
122
|
+
type: 'trigger.registered';
|
|
123
|
+
triggerName: string;
|
|
124
|
+
triggerType: 'event' | 'webhook' | 'schedule' | 'manual';
|
|
125
|
+
scope: 'flow' | 'run';
|
|
126
|
+
}
|
|
127
|
+
export interface AwaitRegisteredEvent extends BaseEvent {
|
|
128
|
+
type: 'await.registered';
|
|
129
|
+
stepName: string;
|
|
130
|
+
awaitType: 'webhook' | 'event' | 'schedule' | 'time';
|
|
131
|
+
position: 'before' | 'after';
|
|
132
|
+
config: any;
|
|
133
|
+
}
|
|
134
|
+
export interface AwaitResolvedEvent extends BaseEvent {
|
|
135
|
+
type: 'await.resolved';
|
|
136
|
+
stepName: string;
|
|
137
|
+
triggerData: any;
|
|
138
|
+
position: 'before' | 'after';
|
|
139
|
+
}
|
|
140
|
+
export interface AwaitTimeoutEvent extends BaseEvent {
|
|
141
|
+
type: 'await.timeout';
|
|
142
|
+
stepName: string;
|
|
143
|
+
action: 'fail' | 'continue' | 'retry';
|
|
144
|
+
}
|
|
145
|
+
export type FlowEvent = FlowStartEvent | FlowCompletedEvent | FlowFailedEvent | FlowCancelEvent | FlowStalledEvent | StepStartedEvent | StepCompletedEvent | StepFailedEvent | StepRetryEvent | LogEvent | EmitEvent | StateEvent | TriggerFiredEvent | TriggerRegisteredEvent | AwaitRegisteredEvent | AwaitResolvedEvent | AwaitTimeoutEvent;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schedule or update a schedule trigger in the scheduler
|
|
3
|
+
*/
|
|
4
|
+
export declare function scheduleTrigger(triggerName: string, scheduleConfig: any, triggerStatus?: string): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Unschedule a schedule trigger from the scheduler
|
|
7
|
+
*/
|
|
8
|
+
export declare function unscheduleTrigger(triggerName: string): Promise<void>;
|