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,47 +0,0 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, createError, useQueueAdapter, $useQueueRegistry } from "#imports";
|
|
2
|
-
export default defineEventHandler(async (event) => {
|
|
3
|
-
const flowName = getRouterParam(event, "name");
|
|
4
|
-
const scheduleId = getRouterParam(event, "id");
|
|
5
|
-
if (!flowName || !scheduleId) {
|
|
6
|
-
throw createError({ statusCode: 400, statusMessage: "Flow name and schedule ID are required" });
|
|
7
|
-
}
|
|
8
|
-
const registry = $useQueueRegistry();
|
|
9
|
-
const flow = registry?.flows?.[flowName];
|
|
10
|
-
if (!flow || !flow.entry) {
|
|
11
|
-
throw createError({ statusCode: 404, statusMessage: `Flow '${flowName}' not found` });
|
|
12
|
-
}
|
|
13
|
-
let adapter;
|
|
14
|
-
try {
|
|
15
|
-
adapter = useQueueAdapter();
|
|
16
|
-
} catch {
|
|
17
|
-
throw createError({
|
|
18
|
-
statusCode: 503,
|
|
19
|
-
statusMessage: "Server initializing",
|
|
20
|
-
data: "Queue adapter not ready yet, please retry"
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
if (!adapter.removeScheduledJob) {
|
|
24
|
-
throw createError({
|
|
25
|
-
statusCode: 501,
|
|
26
|
-
statusMessage: "Queue adapter does not support scheduled jobs removal"
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const removed = await adapter.removeScheduledJob(scheduleId);
|
|
31
|
-
if (!removed) {
|
|
32
|
-
throw createError({ statusCode: 404, statusMessage: "Schedule not found" });
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
success: true,
|
|
36
|
-
message: "Schedule deleted successfully"
|
|
37
|
-
};
|
|
38
|
-
} catch (error) {
|
|
39
|
-
if (error.statusCode === 404) {
|
|
40
|
-
throw error;
|
|
41
|
-
}
|
|
42
|
-
throw createError({
|
|
43
|
-
statusCode: 500,
|
|
44
|
-
statusMessage: `Failed to delete schedule: ${error.message}`
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, createError, useQueueAdapter, $useQueueRegistry } from "#imports";
|
|
2
|
-
export default defineEventHandler(async (event) => {
|
|
3
|
-
const flowName = getRouterParam(event, "name");
|
|
4
|
-
if (!flowName) {
|
|
5
|
-
throw createError({ statusCode: 400, statusMessage: "Flow name is required" });
|
|
6
|
-
}
|
|
7
|
-
const registry = $useQueueRegistry();
|
|
8
|
-
const flow = registry?.flows?.[flowName];
|
|
9
|
-
if (!flow || !flow.entry) {
|
|
10
|
-
throw createError({ statusCode: 404, statusMessage: `Flow '${flowName}' not found` });
|
|
11
|
-
}
|
|
12
|
-
const queueName = typeof flow.entry.queue === "string" ? flow.entry.queue : flow.entry.queue?.name || flow.entry.queue;
|
|
13
|
-
let adapter;
|
|
14
|
-
try {
|
|
15
|
-
adapter = useQueueAdapter();
|
|
16
|
-
} catch {
|
|
17
|
-
throw createError({
|
|
18
|
-
statusCode: 503,
|
|
19
|
-
statusMessage: "Server initializing",
|
|
20
|
-
data: "Queue adapter not ready yet, please retry"
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
if (!adapter.getScheduledJobs) {
|
|
24
|
-
throw createError({
|
|
25
|
-
statusCode: 501,
|
|
26
|
-
statusMessage: "Queue adapter does not support scheduled jobs"
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const scheduledJobs = await adapter.getScheduledJobs(queueName);
|
|
31
|
-
const schedules = scheduledJobs.filter((job) => job.jobName === flow.entry.step).map((job) => ({
|
|
32
|
-
id: job.id,
|
|
33
|
-
flowName,
|
|
34
|
-
queue: queueName,
|
|
35
|
-
step: flow.entry.step,
|
|
36
|
-
schedule: {
|
|
37
|
-
cron: job.cron || job.pattern
|
|
38
|
-
},
|
|
39
|
-
nextRun: job.nextRun ? job.nextRun.toISOString() : void 0,
|
|
40
|
-
repeatCount: job.repeatCount,
|
|
41
|
-
limit: job.limit
|
|
42
|
-
}));
|
|
43
|
-
return schedules;
|
|
44
|
-
} catch (error) {
|
|
45
|
-
throw createError({
|
|
46
|
-
statusCode: 500,
|
|
47
|
-
statusMessage: `Failed to list schedules: ${error.message}`
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, createError, readBody, useFlowEngine } from "#imports";
|
|
2
|
-
export default defineEventHandler(async (event) => {
|
|
3
|
-
const flowName = getRouterParam(event, "name");
|
|
4
|
-
if (!flowName) throw createError({ statusCode: 400, statusMessage: "Flow name is required" });
|
|
5
|
-
const { startFlow } = useFlowEngine();
|
|
6
|
-
const body = await readBody(event);
|
|
7
|
-
const result = await startFlow(flowName, body || {});
|
|
8
|
-
return result;
|
|
9
|
-
});
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket endpoint for flow run events
|
|
3
|
-
* Supports subscribing to specific flow runs and receiving real-time updates
|
|
4
|
-
*
|
|
5
|
-
* Message format (client -> server):
|
|
6
|
-
* {
|
|
7
|
-
* "type": "subscribe",
|
|
8
|
-
* "flowName": "example",
|
|
9
|
-
* "runId": "abc123"
|
|
10
|
-
* }
|
|
11
|
-
*
|
|
12
|
-
* {
|
|
13
|
-
* "type": "unsubscribe",
|
|
14
|
-
* "flowName": "example",
|
|
15
|
-
* "runId": "abc123"
|
|
16
|
-
* }
|
|
17
|
-
*
|
|
18
|
-
* {
|
|
19
|
-
* "type": "ping"
|
|
20
|
-
* }
|
|
21
|
-
*
|
|
22
|
-
* Message format (server -> client):
|
|
23
|
-
* {
|
|
24
|
-
* "type": "event",
|
|
25
|
-
* "flowName": "example",
|
|
26
|
-
* "runId": "abc123",
|
|
27
|
-
* "event": { v: 1, eventType: "...", record: {...} }
|
|
28
|
-
* }
|
|
29
|
-
*
|
|
30
|
-
* {
|
|
31
|
-
* "type": "history",
|
|
32
|
-
* "flowName": "example",
|
|
33
|
-
* "runId": "abc123",
|
|
34
|
-
* "events": [ ...historicalEvents ]
|
|
35
|
-
* }
|
|
36
|
-
*
|
|
37
|
-
* {
|
|
38
|
-
* "type": "subscribed",
|
|
39
|
-
* "flowName": "example",
|
|
40
|
-
* "runId": "abc123"
|
|
41
|
-
* }
|
|
42
|
-
*
|
|
43
|
-
* {
|
|
44
|
-
* "type": "unsubscribed",
|
|
45
|
-
* "flowName": "example",
|
|
46
|
-
* "runId": "abc123"
|
|
47
|
-
* }
|
|
48
|
-
*
|
|
49
|
-
* {
|
|
50
|
-
* "type": "pong",
|
|
51
|
-
* "timestamp": 1234567890
|
|
52
|
-
* }
|
|
53
|
-
*
|
|
54
|
-
* {
|
|
55
|
-
* "type": "error",
|
|
56
|
-
* "message": "error description"
|
|
57
|
-
* }
|
|
58
|
-
*/
|
|
59
|
-
declare const _default: any;
|
|
60
|
-
export default _default;
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineWebSocketHandler,
|
|
3
|
-
usePeerManager,
|
|
4
|
-
useNventLogger,
|
|
5
|
-
useStreamAdapter,
|
|
6
|
-
useStoreAdapter,
|
|
7
|
-
useStreamTopics
|
|
8
|
-
} from "#imports";
|
|
9
|
-
const peerContexts = /* @__PURE__ */ new WeakMap();
|
|
10
|
-
function safeSend(peer, data) {
|
|
11
|
-
try {
|
|
12
|
-
peer.send(JSON.stringify(data));
|
|
13
|
-
return true;
|
|
14
|
-
} catch {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
export default defineWebSocketHandler({
|
|
19
|
-
async open(peer) {
|
|
20
|
-
const logger = useNventLogger("api-flows-ws");
|
|
21
|
-
logger.info("[ws] client connected:", { peerId: peer.id });
|
|
22
|
-
const { registerWsPeer } = usePeerManager();
|
|
23
|
-
registerWsPeer(peer);
|
|
24
|
-
peerContexts.set(peer, {
|
|
25
|
-
subscriptions: /* @__PURE__ */ new Map()
|
|
26
|
-
});
|
|
27
|
-
safeSend(peer, {
|
|
28
|
-
type: "connected",
|
|
29
|
-
timestamp: Date.now()
|
|
30
|
-
});
|
|
31
|
-
},
|
|
32
|
-
async message(peer, message) {
|
|
33
|
-
const logger = useNventLogger("api-flows-ws");
|
|
34
|
-
const context = peerContexts.get(peer);
|
|
35
|
-
if (!context) {
|
|
36
|
-
logger.error("[ws] no context for peer:", { peerId: peer.id });
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
let data;
|
|
40
|
-
try {
|
|
41
|
-
data = JSON.parse(message.text());
|
|
42
|
-
} catch {
|
|
43
|
-
safeSend(peer, {
|
|
44
|
-
type: "error",
|
|
45
|
-
message: "Invalid JSON"
|
|
46
|
-
});
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
const { type, flowName, runId } = data;
|
|
50
|
-
if (type === "subscribe") {
|
|
51
|
-
if (!flowName || !runId) {
|
|
52
|
-
safeSend(peer, {
|
|
53
|
-
type: "error",
|
|
54
|
-
message: "Missing flowName or runId"
|
|
55
|
-
});
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
let stream;
|
|
59
|
-
let store;
|
|
60
|
-
try {
|
|
61
|
-
stream = useStreamAdapter();
|
|
62
|
-
store = useStoreAdapter();
|
|
63
|
-
} catch (err) {
|
|
64
|
-
logger.error("[ws] Adapters not initialized yet:", { error: err });
|
|
65
|
-
safeSend(peer, {
|
|
66
|
-
type: "error",
|
|
67
|
-
message: "Server initializing, please retry"
|
|
68
|
-
});
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const subscriptionKey = `${flowName}:${runId}`;
|
|
72
|
-
const existingHandle = context.subscriptions.get(subscriptionKey);
|
|
73
|
-
if (existingHandle) {
|
|
74
|
-
try {
|
|
75
|
-
await existingHandle.unsubscribe();
|
|
76
|
-
} catch (err) {
|
|
77
|
-
logger.error("[ws] error unsubscribing:", { error: err });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
const { SubjectPatterns, getClientFlowTopic } = useStreamTopics();
|
|
81
|
-
const subject = SubjectPatterns.flowRun(runId);
|
|
82
|
-
const topic = getClientFlowTopic(runId);
|
|
83
|
-
const handle = await stream.subscribe(topic, async (message2) => {
|
|
84
|
-
const event = message2.data?.event;
|
|
85
|
-
if (!event) {
|
|
86
|
-
logger.warn("[ws] Received message without event data:", message2);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
safeSend(peer, {
|
|
90
|
-
type: "event",
|
|
91
|
-
flowName,
|
|
92
|
-
runId,
|
|
93
|
-
event: {
|
|
94
|
-
v: 1,
|
|
95
|
-
eventType: event.type,
|
|
96
|
-
record: event
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
context.subscriptions.set(subscriptionKey, handle);
|
|
101
|
-
try {
|
|
102
|
-
const historicalEvents = await store.read(subject, {
|
|
103
|
-
limit: 100,
|
|
104
|
-
order: "asc"
|
|
105
|
-
// forward order
|
|
106
|
-
});
|
|
107
|
-
safeSend(peer, {
|
|
108
|
-
type: "history",
|
|
109
|
-
flowName,
|
|
110
|
-
runId,
|
|
111
|
-
events: historicalEvents.map((e) => ({
|
|
112
|
-
v: 1,
|
|
113
|
-
eventType: e.kind || e.type,
|
|
114
|
-
record: e
|
|
115
|
-
}))
|
|
116
|
-
});
|
|
117
|
-
} catch (err) {
|
|
118
|
-
logger.error("[ws] error sending history:", { error: err });
|
|
119
|
-
safeSend(peer, {
|
|
120
|
-
type: "error",
|
|
121
|
-
message: "Failed to load history"
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
safeSend(peer, {
|
|
125
|
-
type: "subscribed",
|
|
126
|
-
flowName,
|
|
127
|
-
runId
|
|
128
|
-
});
|
|
129
|
-
} else if (type === "unsubscribe") {
|
|
130
|
-
if (!flowName || !runId) {
|
|
131
|
-
safeSend(peer, {
|
|
132
|
-
type: "error",
|
|
133
|
-
message: "Missing flowName or runId"
|
|
134
|
-
});
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const subscriptionKey = `${flowName}:${runId}`;
|
|
138
|
-
const handle = context.subscriptions.get(subscriptionKey);
|
|
139
|
-
if (handle) {
|
|
140
|
-
try {
|
|
141
|
-
await handle.unsubscribe();
|
|
142
|
-
context.subscriptions.delete(subscriptionKey);
|
|
143
|
-
safeSend(peer, {
|
|
144
|
-
type: "unsubscribed",
|
|
145
|
-
flowName,
|
|
146
|
-
runId
|
|
147
|
-
});
|
|
148
|
-
} catch (err) {
|
|
149
|
-
logger.error("[ws] error unsubscribing:", { error: err });
|
|
150
|
-
safeSend(peer, {
|
|
151
|
-
type: "error",
|
|
152
|
-
message: "Failed to unsubscribe"
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
} else if (type === "ping") {
|
|
157
|
-
safeSend(peer, {
|
|
158
|
-
type: "pong",
|
|
159
|
-
timestamp: Date.now()
|
|
160
|
-
});
|
|
161
|
-
} else {
|
|
162
|
-
safeSend(peer, {
|
|
163
|
-
type: "error",
|
|
164
|
-
message: `Unknown message type: ${type}`
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
async close(peer, event) {
|
|
169
|
-
const logger = useNventLogger("api-flows-ws");
|
|
170
|
-
const isNormalClosure = event?.code === 1e3 || event?.code === 1001;
|
|
171
|
-
if (!isNormalClosure) {
|
|
172
|
-
logger.info("[ws] client disconnected:", { peerId: peer.id, code: event?.code, reason: event?.reason });
|
|
173
|
-
}
|
|
174
|
-
const { unregisterWsPeer } = usePeerManager();
|
|
175
|
-
unregisterWsPeer(peer);
|
|
176
|
-
const context = peerContexts.get(peer);
|
|
177
|
-
if (context) {
|
|
178
|
-
for (const handle of Array.from(context.subscriptions.values())) {
|
|
179
|
-
try {
|
|
180
|
-
await handle.unsubscribe();
|
|
181
|
-
} catch (err) {
|
|
182
|
-
if (!isNormalClosure) {
|
|
183
|
-
logger.error("[ws] error unsubscribing on close:", { error: err });
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
context.subscriptions.clear();
|
|
188
|
-
peerContexts.delete(peer);
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
async error(peer, error) {
|
|
192
|
-
const logger = useNventLogger("api-flows-ws");
|
|
193
|
-
logger.error("[ws] error for peer:", { peerId: peer.id, error });
|
|
194
|
-
const { unregisterWsPeer } = usePeerManager();
|
|
195
|
-
unregisterWsPeer(peer);
|
|
196
|
-
const context = peerContexts.get(peer);
|
|
197
|
-
if (context) {
|
|
198
|
-
for (const handle of Array.from(context.subscriptions.values())) {
|
|
199
|
-
try {
|
|
200
|
-
await handle.unsubscribe();
|
|
201
|
-
} catch (err) {
|
|
202
|
-
logger.error("[ws] error unsubscribing on error:", { error: err });
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
context.subscriptions.clear();
|
|
206
|
-
peerContexts.delete(peer);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
});
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, useQueueAdapter } from "#imports";
|
|
2
|
-
export default defineEventHandler(async (event) => {
|
|
3
|
-
const name = getRouterParam(event, "name") || "";
|
|
4
|
-
const id = getRouterParam(event, "id") || "";
|
|
5
|
-
let queue;
|
|
6
|
-
try {
|
|
7
|
-
queue = useQueueAdapter();
|
|
8
|
-
} catch {
|
|
9
|
-
return null;
|
|
10
|
-
}
|
|
11
|
-
const job = await queue.getJob(name, id);
|
|
12
|
-
if (!job) return null;
|
|
13
|
-
return { ...job, queue: name };
|
|
14
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, getQuery, useQueueAdapter, createError } from "#imports";
|
|
2
|
-
export default defineEventHandler(async (event) => {
|
|
3
|
-
const name = getRouterParam(event, "name");
|
|
4
|
-
if (!name) {
|
|
5
|
-
throw createError({ statusCode: 400, statusMessage: "Missing queue name" });
|
|
6
|
-
}
|
|
7
|
-
const query = getQuery(event);
|
|
8
|
-
const state = query.state;
|
|
9
|
-
let queue;
|
|
10
|
-
try {
|
|
11
|
-
queue = useQueueAdapter();
|
|
12
|
-
} catch {
|
|
13
|
-
throw createError({
|
|
14
|
-
statusCode: 503,
|
|
15
|
-
statusMessage: "Server initializing",
|
|
16
|
-
data: "Queue adapter not ready yet, please retry"
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
const jobs = await queue.getJobs(name, {
|
|
20
|
-
state: state ? [state] : void 0,
|
|
21
|
-
limit: 1e3
|
|
22
|
-
// Fetch all jobs, pagination happens client-side
|
|
23
|
-
});
|
|
24
|
-
return {
|
|
25
|
-
jobs
|
|
26
|
-
};
|
|
27
|
-
});
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { defineEventHandler, useRuntimeConfig, $useQueueRegistry, useQueueAdapter, useNventLogger } from "#imports";
|
|
2
|
-
const logger = useNventLogger("api-queues-index");
|
|
3
|
-
export default defineEventHandler(async () => {
|
|
4
|
-
const rc = useRuntimeConfig();
|
|
5
|
-
const registry = $useQueueRegistry();
|
|
6
|
-
let queue;
|
|
7
|
-
try {
|
|
8
|
-
queue = useQueueAdapter();
|
|
9
|
-
} catch (err) {
|
|
10
|
-
logger.error("[queues/index] Adapters not initialized yet:", { error: err });
|
|
11
|
-
return [];
|
|
12
|
-
}
|
|
13
|
-
const globalQueueConfig = rc?.nvent?.queue || {};
|
|
14
|
-
const globalWorkerDefaults = globalQueueConfig.worker || {};
|
|
15
|
-
const globalQueueDefaults = {
|
|
16
|
-
prefix: globalQueueConfig.prefix,
|
|
17
|
-
defaultJobOptions: globalQueueConfig.defaultJobOptions,
|
|
18
|
-
limiter: globalQueueConfig.limiter
|
|
19
|
-
};
|
|
20
|
-
const names = /* @__PURE__ */ new Set();
|
|
21
|
-
if (registry?.workers?.length) {
|
|
22
|
-
for (const w of registry.workers) names.add(w.queue.name);
|
|
23
|
-
}
|
|
24
|
-
const queuesWithCounts = await Promise.all(
|
|
25
|
-
Array.from(names).map(async (name) => {
|
|
26
|
-
try {
|
|
27
|
-
const counts = await queue.getJobCounts(name);
|
|
28
|
-
const isPaused = await queue.isPaused(name);
|
|
29
|
-
const workers = registry?.workers?.filter((w) => w.queue.name === name) || [];
|
|
30
|
-
const mergedQueueConfig = workers.reduce((acc, w) => {
|
|
31
|
-
if (!w.queue) return acc;
|
|
32
|
-
const result = {
|
|
33
|
-
...acc,
|
|
34
|
-
name: w.queue.name
|
|
35
|
-
};
|
|
36
|
-
if (w.queue.prefix && w.queue.prefix !== acc.prefix) {
|
|
37
|
-
result.prefix = w.queue.prefix;
|
|
38
|
-
}
|
|
39
|
-
if (w.queue.limiter) {
|
|
40
|
-
result.limiter = w.queue.limiter;
|
|
41
|
-
}
|
|
42
|
-
if (w.queue.defaultJobOptions) {
|
|
43
|
-
result.defaultJobOptions = { ...acc.defaultJobOptions };
|
|
44
|
-
const wOpts = w.queue.defaultJobOptions;
|
|
45
|
-
const accOpts = acc.defaultJobOptions || {};
|
|
46
|
-
if (typeof wOpts.attempts === "number") {
|
|
47
|
-
result.defaultJobOptions.attempts = Math.max(wOpts.attempts, accOpts.attempts || 0);
|
|
48
|
-
}
|
|
49
|
-
if (wOpts.backoff) {
|
|
50
|
-
if (!accOpts.backoff || wOpts.backoff.delay && wOpts.backoff.delay !== globalQueueDefaults.defaultJobOptions?.backoff?.delay) {
|
|
51
|
-
result.defaultJobOptions.backoff = wOpts.backoff;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (typeof wOpts.priority === "number") result.defaultJobOptions.priority = wOpts.priority;
|
|
55
|
-
if (typeof wOpts.timeout === "number") result.defaultJobOptions.timeout = wOpts.timeout;
|
|
56
|
-
if (typeof wOpts.delay === "number") result.defaultJobOptions.delay = wOpts.delay;
|
|
57
|
-
if (typeof wOpts.lifo === "boolean") result.defaultJobOptions.lifo = wOpts.lifo;
|
|
58
|
-
if (wOpts.removeOnComplete !== void 0) result.defaultJobOptions.removeOnComplete = wOpts.removeOnComplete;
|
|
59
|
-
if (wOpts.removeOnFail !== void 0) result.defaultJobOptions.removeOnFail = wOpts.removeOnFail;
|
|
60
|
-
}
|
|
61
|
-
return result;
|
|
62
|
-
}, { ...globalQueueDefaults, name });
|
|
63
|
-
const mergedWorkerConfig = workers.reduce((acc, w) => {
|
|
64
|
-
if (!w.worker) return acc;
|
|
65
|
-
return {
|
|
66
|
-
concurrency: Math.max(acc.concurrency || 0, w.worker.concurrency || 0),
|
|
67
|
-
// Use max concurrency
|
|
68
|
-
lockDurationMs: w.worker.lockDurationMs ?? acc.lockDurationMs,
|
|
69
|
-
maxStalledCount: w.worker.maxStalledCount ?? acc.maxStalledCount,
|
|
70
|
-
drainDelayMs: w.worker.drainDelayMs ?? acc.drainDelayMs,
|
|
71
|
-
autorun: w.worker.autorun ?? acc.autorun,
|
|
72
|
-
pollingIntervalMs: w.worker.pollingIntervalMs ?? acc.pollingIntervalMs
|
|
73
|
-
};
|
|
74
|
-
}, { ...globalWorkerDefaults });
|
|
75
|
-
return {
|
|
76
|
-
name,
|
|
77
|
-
counts,
|
|
78
|
-
isPaused,
|
|
79
|
-
config: {
|
|
80
|
-
queue: mergedQueueConfig,
|
|
81
|
-
worker: mergedWorkerConfig
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
} catch (err) {
|
|
85
|
-
logger.error(`Failed to get counts for queue ${name}:`, { error: err });
|
|
86
|
-
return {
|
|
87
|
-
name,
|
|
88
|
-
counts: {
|
|
89
|
-
active: 0,
|
|
90
|
-
completed: 0,
|
|
91
|
-
failed: 0,
|
|
92
|
-
delayed: 0,
|
|
93
|
-
waiting: 0,
|
|
94
|
-
paused: 0
|
|
95
|
-
},
|
|
96
|
-
isPaused: false,
|
|
97
|
-
config: {
|
|
98
|
-
queue: globalQueueDefaults,
|
|
99
|
-
worker: globalWorkerDefaults
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
);
|
|
105
|
-
return queuesWithCounts;
|
|
106
|
-
});
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket endpoint for queue events
|
|
3
|
-
* Supports subscribing to specific queues and receiving real-time job updates
|
|
4
|
-
*
|
|
5
|
-
* Message format (client -> server):
|
|
6
|
-
* {
|
|
7
|
-
* "type": "subscribe",
|
|
8
|
-
* "queueName": "test"
|
|
9
|
-
* }
|
|
10
|
-
*
|
|
11
|
-
* {
|
|
12
|
-
* "type": "unsubscribe",
|
|
13
|
-
* "queueName": "test"
|
|
14
|
-
* }
|
|
15
|
-
*
|
|
16
|
-
* {
|
|
17
|
-
* "type": "ping"
|
|
18
|
-
* }
|
|
19
|
-
*
|
|
20
|
-
* Message format (server -> client):
|
|
21
|
-
* {
|
|
22
|
-
* "type": "event",
|
|
23
|
-
* "queueName": "test",
|
|
24
|
-
* "event": { eventType: "waiting|active|completed|failed", jobId: "...", ... }
|
|
25
|
-
* }
|
|
26
|
-
*
|
|
27
|
-
* {
|
|
28
|
-
* "type": "subscribed",
|
|
29
|
-
* "queueName": "test"
|
|
30
|
-
* }
|
|
31
|
-
*
|
|
32
|
-
* {
|
|
33
|
-
* "type": "unsubscribed",
|
|
34
|
-
* "queueName": "test"
|
|
35
|
-
* }
|
|
36
|
-
*
|
|
37
|
-
* {
|
|
38
|
-
* "type": "pong",
|
|
39
|
-
* "timestamp": 1234567890
|
|
40
|
-
* }
|
|
41
|
-
*
|
|
42
|
-
* {
|
|
43
|
-
* "type": "error",
|
|
44
|
-
* "message": "error description"
|
|
45
|
-
* }
|
|
46
|
-
*/
|
|
47
|
-
declare const _default: any;
|
|
48
|
-
export default _default;
|