nvent 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.d.mts +3 -184
- package/dist/module.json +3 -3
- package/dist/module.mjs +133 -197
- package/dist/runtime/adapters/builtin/file-queue.d.ts +53 -0
- package/dist/runtime/adapters/builtin/file-queue.js +435 -0
- package/dist/runtime/adapters/builtin/file-store.d.ts +46 -0
- package/dist/runtime/adapters/builtin/file-store.js +225 -0
- package/dist/runtime/adapters/builtin/file-stream.d.ts +39 -0
- package/dist/runtime/adapters/builtin/file-stream.js +56 -0
- package/dist/runtime/adapters/builtin/index.d.ts +10 -0
- package/dist/runtime/adapters/builtin/index.js +5 -0
- package/dist/runtime/adapters/builtin/memory-queue.d.ts +52 -0
- package/dist/runtime/adapters/builtin/memory-queue.js +239 -0
- package/dist/runtime/adapters/builtin/memory-store.d.ts +57 -0
- package/dist/runtime/adapters/builtin/memory-store.js +263 -0
- package/dist/runtime/adapters/builtin/memory-stream.d.ts +21 -0
- package/dist/runtime/adapters/builtin/memory-stream.js +56 -0
- package/dist/runtime/adapters/factory.d.ts +31 -0
- package/dist/runtime/adapters/factory.js +100 -0
- package/dist/runtime/adapters/index.d.ts +8 -0
- package/dist/runtime/adapters/index.js +3 -0
- package/dist/runtime/adapters/interfaces/index.d.ts +11 -0
- package/dist/runtime/adapters/interfaces/index.js +3 -0
- package/dist/runtime/adapters/interfaces/queue.d.ts +150 -0
- package/dist/runtime/adapters/interfaces/store.d.ts +233 -0
- package/dist/runtime/adapters/interfaces/stream.d.ts +62 -0
- package/dist/runtime/adapters/registry.d.ts +85 -0
- package/dist/runtime/adapters/registry.js +161 -0
- package/dist/runtime/config/index.d.ts +29 -0
- package/dist/runtime/config/index.js +167 -0
- package/dist/runtime/config/types.d.ts +367 -0
- package/dist/runtime/config/types.js +0 -0
- package/dist/runtime/events/types.d.ts +116 -0
- package/dist/runtime/events/types.js +0 -0
- package/dist/runtime/events/utils/stallDetector.d.ts +99 -0
- package/dist/runtime/events/utils/stallDetector.js +237 -0
- package/dist/runtime/{server-utils/events → events}/wiring/flowWiring.d.ts +3 -8
- package/dist/runtime/{server-utils/events → events}/wiring/flowWiring.js +119 -36
- package/dist/runtime/events/wiring/registry.d.ts +19 -0
- package/dist/runtime/events/wiring/registry.js +33 -0
- package/dist/runtime/events/wiring/stateWiring.d.ts +37 -0
- package/dist/runtime/events/wiring/stateWiring.js +92 -0
- package/dist/runtime/events/wiring/streamWiring.d.ts +32 -0
- package/dist/runtime/events/wiring/streamWiring.js +79 -0
- package/dist/runtime/server/api/_flows/[name]/clear-history.delete.js +16 -5
- package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.js +21 -0
- package/dist/runtime/server/api/_flows/[name]/runs.get.d.ts +12 -2
- package/dist/runtime/server/api/_flows/[name]/runs.get.js +15 -4
- package/dist/runtime/server/api/_flows/[name]/schedule.post.js +11 -2
- package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.js +21 -16
- package/dist/runtime/server/api/_flows/[name]/schedules.get.js +21 -19
- package/dist/runtime/server/api/_flows/ws.js +43 -22
- package/dist/runtime/server/api/_queues/[name]/job/[id].get.js +8 -3
- package/dist/runtime/server/api/_queues/[name]/job/index.get.js +12 -3
- package/dist/runtime/server/api/_queues/index.get.js +66 -23
- package/dist/runtime/server/api/_queues/ws.js +14 -4
- package/dist/runtime/server/plugins/00.adapters.d.ts +14 -0
- package/dist/runtime/server/plugins/00.adapters.js +69 -0
- package/dist/runtime/server/plugins/02.workers.js +45 -0
- package/dist/runtime/tsconfig.json +8 -0
- package/dist/runtime/utils/adapters.d.ts +66 -0
- package/dist/runtime/utils/adapters.js +51 -0
- package/dist/runtime/utils/defineFunction.d.ts +10 -0
- package/dist/runtime/{server-utils/utils/defineQueueWorker.js → utils/defineFunction.js} +4 -4
- package/dist/runtime/{server-utils/utils/defineQueueConfig.d.ts → utils/defineFunctionConfig.d.ts} +3 -3
- package/dist/runtime/utils/defineFunctionConfig.js +2 -0
- package/dist/runtime/utils/registerAdapter.d.ts +59 -0
- package/dist/runtime/utils/registerAdapter.js +13 -0
- package/dist/runtime/utils/useFlowEngine.d.ts +19 -0
- package/dist/runtime/utils/useFlowEngine.js +108 -0
- package/dist/runtime/{server-utils/utils → utils}/useNventLogger.js +2 -2
- package/dist/runtime/utils/useStreamTopics.d.ts +72 -0
- package/dist/runtime/utils/useStreamTopics.js +47 -0
- package/dist/runtime/{server-utils/worker/runner/node.d.ts → worker/node/runner.d.ts} +18 -2
- package/dist/runtime/{server-utils/worker/runner/node.js → worker/node/runner.js} +44 -17
- package/dist/types.d.mts +2 -2
- package/package.json +14 -44
- package/LICENSE +0 -21
- package/README.md +0 -389
- package/dist/runtime/app/assets/vueflow.css +0 -1
- package/dist/runtime/app/components/ConfirmDialog.d.vue.ts +0 -33
- package/dist/runtime/app/components/ConfirmDialog.vue +0 -121
- package/dist/runtime/app/components/ConfirmDialog.vue.d.ts +0 -33
- package/dist/runtime/app/components/FlowDiagram.d.vue.ts +0 -64
- package/dist/runtime/app/components/FlowDiagram.vue +0 -338
- package/dist/runtime/app/components/FlowDiagram.vue.d.ts +0 -64
- package/dist/runtime/app/components/FlowNodeCard.d.vue.ts +0 -29
- package/dist/runtime/app/components/FlowNodeCard.vue +0 -156
- package/dist/runtime/app/components/FlowNodeCard.vue.d.ts +0 -29
- package/dist/runtime/app/components/FlowRunOverview.d.vue.ts +0 -9
- package/dist/runtime/app/components/FlowRunOverview.vue +0 -291
- package/dist/runtime/app/components/FlowRunOverview.vue.d.ts +0 -9
- package/dist/runtime/app/components/FlowRunStatusBadge.d.vue.ts +0 -14
- package/dist/runtime/app/components/FlowRunStatusBadge.vue +0 -60
- package/dist/runtime/app/components/FlowRunStatusBadge.vue.d.ts +0 -14
- package/dist/runtime/app/components/FlowRunTimeline.d.vue.ts +0 -12
- package/dist/runtime/app/components/FlowRunTimeline.vue +0 -127
- package/dist/runtime/app/components/FlowRunTimeline.vue.d.ts +0 -12
- package/dist/runtime/app/components/FlowScheduleDialog.d.vue.ts +0 -16
- package/dist/runtime/app/components/FlowScheduleDialog.vue +0 -226
- package/dist/runtime/app/components/FlowScheduleDialog.vue.d.ts +0 -16
- package/dist/runtime/app/components/FlowSchedulesList.d.vue.ts +0 -12
- package/dist/runtime/app/components/FlowSchedulesList.vue +0 -99
- package/dist/runtime/app/components/FlowSchedulesList.vue.d.ts +0 -12
- package/dist/runtime/app/components/JobScheduling.d.vue.ts +0 -6
- package/dist/runtime/app/components/JobScheduling.vue +0 -203
- package/dist/runtime/app/components/JobScheduling.vue.d.ts +0 -6
- package/dist/runtime/app/components/ListItem.d.vue.ts +0 -23
- package/dist/runtime/app/components/ListItem.vue +0 -70
- package/dist/runtime/app/components/ListItem.vue.d.ts +0 -23
- package/dist/runtime/app/components/QueueConfigDetails.d.vue.ts +0 -45
- package/dist/runtime/app/components/QueueConfigDetails.vue +0 -412
- package/dist/runtime/app/components/QueueConfigDetails.vue.d.ts +0 -45
- package/dist/runtime/app/components/StatCounter.d.vue.ts +0 -9
- package/dist/runtime/app/components/StatCounter.vue +0 -25
- package/dist/runtime/app/components/StatCounter.vue.d.ts +0 -9
- package/dist/runtime/app/components/TimelineList.d.vue.ts +0 -7
- package/dist/runtime/app/components/TimelineList.vue +0 -210
- package/dist/runtime/app/components/TimelineList.vue.d.ts +0 -7
- package/dist/runtime/app/components/nhealth/component-router.d.vue.ts +0 -46
- package/dist/runtime/app/components/nhealth/component-router.vue +0 -26
- package/dist/runtime/app/components/nhealth/component-router.vue.d.ts +0 -46
- package/dist/runtime/app/components/nhealth/component-shell.d.vue.ts +0 -24
- package/dist/runtime/app/components/nhealth/component-shell.vue +0 -89
- package/dist/runtime/app/components/nhealth/component-shell.vue.d.ts +0 -24
- package/dist/runtime/app/composables/useAnalyzedFlows.d.ts +0 -14
- package/dist/runtime/app/composables/useAnalyzedFlows.js +0 -8
- package/dist/runtime/app/composables/useComponentRouter.d.ts +0 -38
- package/dist/runtime/app/composables/useComponentRouter.js +0 -240
- package/dist/runtime/app/composables/useFlowRunTimeline.d.ts +0 -80
- package/dist/runtime/app/composables/useFlowRunTimeline.js +0 -68
- package/dist/runtime/app/composables/useFlowRuns.d.ts +0 -18
- package/dist/runtime/app/composables/useFlowRuns.js +0 -32
- package/dist/runtime/app/composables/useFlowRunsInfinite.d.ts +0 -24
- package/dist/runtime/app/composables/useFlowRunsInfinite.js +0 -123
- package/dist/runtime/app/composables/useFlowRunsPolling.d.ts +0 -9
- package/dist/runtime/app/composables/useFlowRunsPolling.js +0 -33
- package/dist/runtime/app/composables/useFlowState.d.ts +0 -125
- package/dist/runtime/app/composables/useFlowState.js +0 -211
- package/dist/runtime/app/composables/useFlowWebSocket.d.ts +0 -27
- package/dist/runtime/app/composables/useFlowWebSocket.js +0 -205
- package/dist/runtime/app/composables/useFlowsNavigation.d.ts +0 -10
- package/dist/runtime/app/composables/useFlowsNavigation.js +0 -58
- package/dist/runtime/app/composables/useQueueJobs.d.ts +0 -26
- package/dist/runtime/app/composables/useQueueJobs.js +0 -20
- package/dist/runtime/app/composables/useQueueUpdates.d.ts +0 -26
- package/dist/runtime/app/composables/useQueueUpdates.js +0 -122
- package/dist/runtime/app/composables/useQueues.d.ts +0 -45
- package/dist/runtime/app/composables/useQueues.js +0 -26
- package/dist/runtime/app/composables/useQueuesLive.d.ts +0 -19
- package/dist/runtime/app/composables/useQueuesLive.js +0 -143
- package/dist/runtime/app/pages/flows/index.d.vue.ts +0 -3
- package/dist/runtime/app/pages/flows/index.vue +0 -645
- package/dist/runtime/app/pages/flows/index.vue.d.ts +0 -3
- package/dist/runtime/app/pages/index.d.vue.ts +0 -3
- package/dist/runtime/app/pages/index.vue +0 -34
- package/dist/runtime/app/pages/index.vue.d.ts +0 -3
- package/dist/runtime/app/pages/queues/index.d.vue.ts +0 -3
- package/dist/runtime/app/pages/queues/index.vue +0 -229
- package/dist/runtime/app/pages/queues/index.vue.d.ts +0 -3
- package/dist/runtime/app/pages/queues/job.d.vue.ts +0 -3
- package/dist/runtime/app/pages/queues/job.vue +0 -262
- package/dist/runtime/app/pages/queues/job.vue.d.ts +0 -3
- package/dist/runtime/app/pages/queues/jobs.d.vue.ts +0 -3
- package/dist/runtime/app/pages/queues/jobs.vue +0 -291
- package/dist/runtime/app/pages/queues/jobs.vue.d.ts +0 -3
- package/dist/runtime/app/plugins/vueflow.client.d.ts +0 -2
- package/dist/runtime/app/plugins/vueflow.client.js +0 -11
- package/dist/runtime/constants.d.ts +0 -11
- package/dist/runtime/constants.js +0 -11
- package/dist/runtime/schema.d.ts +0 -37
- package/dist/runtime/schema.js +0 -20
- package/dist/runtime/server/plugins/00.event-store.d.ts +0 -13
- package/dist/runtime/server/plugins/00.event-store.js +0 -16
- package/dist/runtime/server/plugins/flow-management.d.ts +0 -13
- package/dist/runtime/server/plugins/flow-management.js +0 -65
- package/dist/runtime/server/plugins/queue-management.js +0 -27
- package/dist/runtime/server/plugins/state-cleanup.d.ts +0 -11
- package/dist/runtime/server/plugins/state-cleanup.js +0 -93
- package/dist/runtime/server/plugins/worker-management.js +0 -33
- package/dist/runtime/server/tsconfig.json +0 -3
- package/dist/runtime/server-utils/events/adapters/fileAdapter.d.ts +0 -2
- package/dist/runtime/server-utils/events/adapters/fileAdapter.js +0 -382
- package/dist/runtime/server-utils/events/adapters/memoryAdapter.d.ts +0 -2
- package/dist/runtime/server-utils/events/adapters/memoryAdapter.js +0 -171
- package/dist/runtime/server-utils/events/adapters/redis/redisAdapter.d.ts +0 -2
- package/dist/runtime/server-utils/events/adapters/redis/redisAdapter.js +0 -348
- package/dist/runtime/server-utils/events/adapters/redis/redisPubSubGateway.d.ts +0 -30
- package/dist/runtime/server-utils/events/adapters/redis/redisPubSubGateway.js +0 -82
- package/dist/runtime/server-utils/events/eventStoreFactory.d.ts +0 -19
- package/dist/runtime/server-utils/events/eventStoreFactory.js +0 -44
- package/dist/runtime/server-utils/events/streamNames.d.ts +0 -17
- package/dist/runtime/server-utils/events/streamNames.js +0 -17
- package/dist/runtime/server-utils/events/types.d.ts +0 -63
- package/dist/runtime/server-utils/events/wiring/registry.d.ts +0 -10
- package/dist/runtime/server-utils/events/wiring/registry.js +0 -24
- package/dist/runtime/server-utils/queue/adapters/bullmq.d.ts +0 -18
- package/dist/runtime/server-utils/queue/adapters/bullmq.js +0 -164
- package/dist/runtime/server-utils/queue/queueFactory.d.ts +0 -3
- package/dist/runtime/server-utils/queue/queueFactory.js +0 -10
- package/dist/runtime/server-utils/queue/types.d.ts +0 -47
- package/dist/runtime/server-utils/state/adapters/redis.d.ts +0 -2
- package/dist/runtime/server-utils/state/adapters/redis.js +0 -42
- package/dist/runtime/server-utils/state/stateFactory.d.ts +0 -3
- package/dist/runtime/server-utils/state/stateFactory.js +0 -17
- package/dist/runtime/server-utils/state/types.d.ts +0 -23
- package/dist/runtime/server-utils/utils/defineQueueConfig.js +0 -2
- package/dist/runtime/server-utils/utils/defineQueueWorker.d.ts +0 -10
- package/dist/runtime/server-utils/utils/useEventStore.d.ts +0 -20
- package/dist/runtime/server-utils/utils/useEventStore.js +0 -119
- package/dist/runtime/server-utils/utils/useFlowEngine.d.ts +0 -9
- package/dist/runtime/server-utils/utils/useFlowEngine.js +0 -44
- package/dist/runtime/server-utils/utils/useLogs.d.ts +0 -41
- package/dist/runtime/server-utils/utils/useLogs.js +0 -74
- package/dist/runtime/server-utils/utils/useQueue.d.ts +0 -31
- package/dist/runtime/server-utils/utils/useQueue.js +0 -24
- package/dist/runtime/server-utils/worker/adapter.d.ts +0 -4
- package/dist/runtime/server-utils/worker/adapter.js +0 -66
- package/dist/runtime/types.d.ts +0 -132
- /package/dist/runtime/{server-utils/events/types.js → adapters/interfaces/queue.js} +0 -0
- /package/dist/runtime/{server-utils/queue/types.js → adapters/interfaces/store.js} +0 -0
- /package/dist/runtime/{server-utils/state/types.js → adapters/interfaces/stream.js} +0 -0
- /package/dist/runtime/{server-utils/events → events}/eventBus.d.ts +0 -0
- /package/dist/runtime/{server-utils/events → events}/eventBus.js +0 -0
- /package/dist/runtime/server/{plugins/queue-management.d.ts → api/_flows/[name]/runs/[runId]/cancel.post.d.ts} +0 -0
- /package/dist/runtime/server/plugins/{00.ws-lifecycle.d.ts → 01.ws-lifecycle.d.ts} +0 -0
- /package/dist/runtime/server/plugins/{00.ws-lifecycle.js → 01.ws-lifecycle.js} +0 -0
- /package/dist/runtime/server/plugins/{worker-management.d.ts → 02.workers.d.ts} +0 -0
- /package/dist/runtime/{server-utils/utils → utils}/useEventManager.d.ts +0 -0
- /package/dist/runtime/{server-utils/utils → utils}/useEventManager.js +0 -0
- /package/dist/runtime/{server-utils/utils → utils}/useNventLogger.d.ts +0 -0
- /package/dist/runtime/{server-utils/utils → utils}/wsPeerManager.d.ts +0 -0
- /package/dist/runtime/{server-utils/utils → utils}/wsPeerManager.js +0 -0
- /package/dist/runtime/{python → worker/python}/get_config.py +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface Wiring {
|
|
2
|
+
start(): void;
|
|
3
|
+
stop(): void;
|
|
4
|
+
}
|
|
5
|
+
export interface WiringRegistryOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Stream wiring options
|
|
8
|
+
*/
|
|
9
|
+
streamWiring?: {
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* State wiring options
|
|
14
|
+
*/
|
|
15
|
+
stateWiring?: {
|
|
16
|
+
strategy?: 'never' | 'on-complete' | 'immediate' | 'ttl';
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare function createWiringRegistry(opts?: WiringRegistryOptions): Wiring;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createFlowWiring } from "./flowWiring.js";
|
|
2
|
+
import { createStreamWiring } from "./streamWiring.js";
|
|
3
|
+
import { createStateWiring } from "./stateWiring.js";
|
|
4
|
+
export function createWiringRegistry(opts) {
|
|
5
|
+
const wirings = [
|
|
6
|
+
// 1. Flow orchestration (persistence, completion tracking, step triggering)
|
|
7
|
+
createFlowWiring(),
|
|
8
|
+
// 2. Stream wiring (publish persisted events to UI clients)
|
|
9
|
+
createStreamWiring(opts?.streamWiring || {
|
|
10
|
+
enabled: true
|
|
11
|
+
}),
|
|
12
|
+
// 3. State wiring (automatic state cleanup)
|
|
13
|
+
createStateWiring(opts?.stateWiring)
|
|
14
|
+
// Future wirings: triggers, webhooks, etc.
|
|
15
|
+
];
|
|
16
|
+
let started = false;
|
|
17
|
+
return {
|
|
18
|
+
start() {
|
|
19
|
+
if (started) return;
|
|
20
|
+
started = true;
|
|
21
|
+
for (const w of wirings) w.start();
|
|
22
|
+
},
|
|
23
|
+
stop() {
|
|
24
|
+
for (const w of wirings) {
|
|
25
|
+
try {
|
|
26
|
+
w.stop();
|
|
27
|
+
} catch {
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
started = false;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Wiring - Automatic cleanup of flow state
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to the local event bus (single source of truth) and handles
|
|
5
|
+
* automatic cleanup of flow state based on configuration strategy.
|
|
6
|
+
*
|
|
7
|
+
* Cleanup strategies:
|
|
8
|
+
* - 'never': State persists indefinitely (default)
|
|
9
|
+
* - 'on-complete': Cleanup when flow completes (recommended)
|
|
10
|
+
* - 'immediate': Cleanup after each step (not recommended)
|
|
11
|
+
* - 'ttl': State expires automatically via TTL (handled by storage provider)
|
|
12
|
+
*
|
|
13
|
+
* Benefits:
|
|
14
|
+
* - Single source of truth (event bus)
|
|
15
|
+
* - Configurable cleanup strategies
|
|
16
|
+
* - Clear separation of concerns
|
|
17
|
+
*/
|
|
18
|
+
export interface StateWiringOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Cleanup strategy
|
|
21
|
+
* - 'never': State persists indefinitely
|
|
22
|
+
* - 'on-complete': Cleanup when flow completes (recommended)
|
|
23
|
+
* - 'immediate': Cleanup after each step
|
|
24
|
+
* - 'ttl': State expires automatically via TTL
|
|
25
|
+
* Default: 'never'
|
|
26
|
+
*/
|
|
27
|
+
strategy?: 'never' | 'on-complete' | 'immediate' | 'ttl';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create state wiring
|
|
31
|
+
*
|
|
32
|
+
* Subscribes to event bus and handles state cleanup based on configuration
|
|
33
|
+
*/
|
|
34
|
+
export declare function createStateWiring(opts?: StateWiringOptions): {
|
|
35
|
+
start: () => void;
|
|
36
|
+
stop: () => void;
|
|
37
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { getEventBus } from "../eventBus.js";
|
|
2
|
+
import { useNventLogger, useStateAdapter, useRuntimeConfig } from "#imports";
|
|
3
|
+
export function createStateWiring(opts) {
|
|
4
|
+
let strategy = opts?.strategy;
|
|
5
|
+
if (!strategy) {
|
|
6
|
+
try {
|
|
7
|
+
const rc = useRuntimeConfig();
|
|
8
|
+
strategy = rc?.nvent?.store?.state?.cleanup?.strategy || "never";
|
|
9
|
+
} catch {
|
|
10
|
+
strategy = "never";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const bus = getEventBus();
|
|
14
|
+
const unsubs = [];
|
|
15
|
+
let wired = false;
|
|
16
|
+
function start() {
|
|
17
|
+
if (wired) return;
|
|
18
|
+
wired = true;
|
|
19
|
+
if (strategy === "never" || strategy === "ttl") {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const logger = useNventLogger("state-wiring");
|
|
23
|
+
const stateAdapter = useStateAdapter();
|
|
24
|
+
logger.info("Starting state wiring", { strategy });
|
|
25
|
+
if (strategy === "on-complete") {
|
|
26
|
+
const cleanupFlowState = async (event, reason) => {
|
|
27
|
+
const flowId = event.runId;
|
|
28
|
+
if (!flowId) return;
|
|
29
|
+
try {
|
|
30
|
+
const pattern = `flow:${flowId}:*`;
|
|
31
|
+
const deletedCount = await stateAdapter.clear(pattern);
|
|
32
|
+
if (deletedCount > 0) {
|
|
33
|
+
logger.info(`Cleaned up state after ${reason}`, {
|
|
34
|
+
flowId,
|
|
35
|
+
deletedCount
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
} catch (error) {
|
|
39
|
+
logger.error(`Error cleaning up state after ${reason}`, {
|
|
40
|
+
flowId,
|
|
41
|
+
error: error?.message
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const handleFlowCompleted = (event) => cleanupFlowState(event, "flow completion");
|
|
46
|
+
const handleFlowFailed = (event) => cleanupFlowState(event, "flow failure");
|
|
47
|
+
const handleFlowCanceled = (event) => cleanupFlowState(event, "flow cancellation");
|
|
48
|
+
const handleFlowStalled = (event) => cleanupFlowState(event, "flow stall");
|
|
49
|
+
unsubs.push(bus.onType("flow.completed", handleFlowCompleted));
|
|
50
|
+
unsubs.push(bus.onType("flow.failed", handleFlowFailed));
|
|
51
|
+
unsubs.push(bus.onType("flow.cancel", handleFlowCanceled));
|
|
52
|
+
unsubs.push(bus.onType("flow.stalled", handleFlowStalled));
|
|
53
|
+
logger.debug("State cleanup enabled: on-complete (includes stalled and canceled)");
|
|
54
|
+
} else if (strategy === "immediate") {
|
|
55
|
+
const handleStepCompleted = async (event) => {
|
|
56
|
+
const flowId = event.runId;
|
|
57
|
+
if (!flowId) return;
|
|
58
|
+
try {
|
|
59
|
+
const pattern = `flow:${flowId}:*`;
|
|
60
|
+
const deletedCount = await stateAdapter.clear(pattern);
|
|
61
|
+
if (deletedCount > 0) {
|
|
62
|
+
logger.info("Cleaned up state after step completion", {
|
|
63
|
+
flowId,
|
|
64
|
+
stepName: event.stepName,
|
|
65
|
+
deletedCount
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
} catch (error) {
|
|
69
|
+
logger.error("Error cleaning up state after step", {
|
|
70
|
+
flowId,
|
|
71
|
+
error: error?.message
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
unsubs.push(bus.onType("step.completed", handleStepCompleted));
|
|
76
|
+
logger.debug("State cleanup enabled: immediate");
|
|
77
|
+
}
|
|
78
|
+
logger.info("State wiring started");
|
|
79
|
+
}
|
|
80
|
+
function stop() {
|
|
81
|
+
const logger = useNventLogger("state-wiring");
|
|
82
|
+
for (const unsub of unsubs.splice(0)) {
|
|
83
|
+
try {
|
|
84
|
+
unsub();
|
|
85
|
+
} catch {
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
wired = false;
|
|
89
|
+
logger.debug("State wiring stopped");
|
|
90
|
+
}
|
|
91
|
+
return { start, stop };
|
|
92
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream Wiring - Publish flow events to UI clients via StreamAdapter
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to the local event bus (single source of truth) and publishes
|
|
5
|
+
* persisted events to the StreamAdapter for WebSocket/SSE clients.
|
|
6
|
+
*
|
|
7
|
+
* Simple and focused:
|
|
8
|
+
* - Listens to event bus for persisted events (with id/ts)
|
|
9
|
+
* - Publishes to client channel: client:flow:{runId}
|
|
10
|
+
* - UI gets real-time updates
|
|
11
|
+
*
|
|
12
|
+
* Benefits:
|
|
13
|
+
* - Single source of truth (event bus)
|
|
14
|
+
* - Easy to debug (no republishing)
|
|
15
|
+
* - Clear separation of concerns
|
|
16
|
+
*/
|
|
17
|
+
export interface StreamWiringOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Enable client messages (WebSocket/SSE)
|
|
20
|
+
* Default: true
|
|
21
|
+
*/
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create stream wiring
|
|
26
|
+
*
|
|
27
|
+
* Subscribes to event bus and publishes persisted events to UI clients
|
|
28
|
+
*/
|
|
29
|
+
export declare function createStreamWiring(opts?: StreamWiringOptions): {
|
|
30
|
+
start: () => void;
|
|
31
|
+
stop: () => void;
|
|
32
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getEventBus } from "../eventBus.js";
|
|
2
|
+
import { useNventLogger, useStreamAdapter, useStreamTopics } from "#imports";
|
|
3
|
+
export function createStreamWiring(opts = {}) {
|
|
4
|
+
const {
|
|
5
|
+
enabled = true
|
|
6
|
+
} = opts;
|
|
7
|
+
const bus = getEventBus();
|
|
8
|
+
const unsubs = [];
|
|
9
|
+
let wired = false;
|
|
10
|
+
function start() {
|
|
11
|
+
if (wired) return;
|
|
12
|
+
wired = true;
|
|
13
|
+
if (!enabled) return;
|
|
14
|
+
const logger = useNventLogger("stream-wiring");
|
|
15
|
+
const stream = useStreamAdapter();
|
|
16
|
+
const { getClientFlowTopic } = useStreamTopics();
|
|
17
|
+
logger.info("Starting stream wiring for UI clients");
|
|
18
|
+
const handleClientMessage = async (e) => {
|
|
19
|
+
if (!e.id || !e.ts) return;
|
|
20
|
+
const runId = e.runId;
|
|
21
|
+
if (!runId) return;
|
|
22
|
+
try {
|
|
23
|
+
const topic = getClientFlowTopic(runId);
|
|
24
|
+
await stream.publish(topic, {
|
|
25
|
+
type: "flow.event",
|
|
26
|
+
data: {
|
|
27
|
+
event: {
|
|
28
|
+
id: e.id,
|
|
29
|
+
ts: e.ts,
|
|
30
|
+
type: e.type,
|
|
31
|
+
runId: e.runId,
|
|
32
|
+
flowName: e.flowName,
|
|
33
|
+
// Include step-specific fields for UI
|
|
34
|
+
stepName: e.stepName,
|
|
35
|
+
stepId: e.stepId,
|
|
36
|
+
attempt: e.attempt,
|
|
37
|
+
data: e.data
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
timestamp: Date.now()
|
|
41
|
+
});
|
|
42
|
+
logger.debug("Published to UI clients", { type: e.type, runId });
|
|
43
|
+
} catch (err) {
|
|
44
|
+
logger.error("Failed to publish to UI clients", {
|
|
45
|
+
error: err?.message
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const clientEventTypes = [
|
|
50
|
+
"flow.start",
|
|
51
|
+
"flow.completed",
|
|
52
|
+
"flow.failed",
|
|
53
|
+
"flow.cancel",
|
|
54
|
+
"step.started",
|
|
55
|
+
"step.completed",
|
|
56
|
+
"step.failed",
|
|
57
|
+
"step.retry",
|
|
58
|
+
"log",
|
|
59
|
+
"emit",
|
|
60
|
+
"state"
|
|
61
|
+
];
|
|
62
|
+
for (const type of clientEventTypes) {
|
|
63
|
+
unsubs.push(bus.onType(type, handleClientMessage));
|
|
64
|
+
}
|
|
65
|
+
logger.info("Stream wiring started - listening for persisted events");
|
|
66
|
+
}
|
|
67
|
+
function stop() {
|
|
68
|
+
const logger = useNventLogger("stream-wiring");
|
|
69
|
+
for (const unsub of unsubs.splice(0)) {
|
|
70
|
+
try {
|
|
71
|
+
unsub();
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
wired = false;
|
|
76
|
+
logger.debug("Stream wiring stopped");
|
|
77
|
+
}
|
|
78
|
+
return { start, stop };
|
|
79
|
+
}
|
|
@@ -1,20 +1,31 @@
|
|
|
1
|
-
import { defineEventHandler, createError,
|
|
1
|
+
import { defineEventHandler, createError, useStoreAdapter, useStreamTopics } from "#imports";
|
|
2
2
|
export default defineEventHandler(async (event) => {
|
|
3
3
|
const flowName = event.context.params?.name;
|
|
4
4
|
if (!flowName) {
|
|
5
5
|
throw createError({ statusCode: 400, statusMessage: "Flow name required" });
|
|
6
6
|
}
|
|
7
|
+
let store;
|
|
8
|
+
let SubjectPatterns;
|
|
9
|
+
try {
|
|
10
|
+
store = useStoreAdapter();
|
|
11
|
+
const topics = useStreamTopics();
|
|
12
|
+
SubjectPatterns = topics.SubjectPatterns;
|
|
13
|
+
} catch {
|
|
14
|
+
throw createError({
|
|
15
|
+
statusCode: 503,
|
|
16
|
+
statusMessage: "Server initializing",
|
|
17
|
+
data: "Adapters not ready yet, please retry"
|
|
18
|
+
});
|
|
19
|
+
}
|
|
7
20
|
try {
|
|
8
|
-
const store = useEventStore();
|
|
9
|
-
const names = store.names();
|
|
10
21
|
let deletedStreams = 0;
|
|
11
22
|
let deletedIndex = false;
|
|
12
|
-
const indexKey =
|
|
23
|
+
const indexKey = SubjectPatterns.flowRunIndex(flowName);
|
|
13
24
|
if (store.indexRead) {
|
|
14
25
|
const runs = await store.indexRead(indexKey, { limit: 1e4 });
|
|
15
26
|
if (store.deleteStream) {
|
|
16
27
|
for (const run of runs) {
|
|
17
|
-
const streamName =
|
|
28
|
+
const streamName = SubjectPatterns.flowRun(run.id);
|
|
18
29
|
await store.deleteStream(streamName);
|
|
19
30
|
if (store.deleteIndex) {
|
|
20
31
|
const metaKey = `${indexKey}:meta:${run.id}`;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineEventHandler, getRouterParam, createError, useFlowEngine } from "#imports";
|
|
2
|
+
export default defineEventHandler(async (event) => {
|
|
3
|
+
const flowName = getRouterParam(event, "name");
|
|
4
|
+
const runId = getRouterParam(event, "runId");
|
|
5
|
+
if (!flowName || !runId) {
|
|
6
|
+
throw createError({
|
|
7
|
+
statusCode: 400,
|
|
8
|
+
statusMessage: "Flow name and run ID are required"
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const flowEngine = useFlowEngine();
|
|
12
|
+
try {
|
|
13
|
+
const result = await flowEngine.cancelFlow(flowName, runId);
|
|
14
|
+
return result;
|
|
15
|
+
} catch (error) {
|
|
16
|
+
throw createError({
|
|
17
|
+
statusCode: 500,
|
|
18
|
+
statusMessage: `Failed to cancel flow: ${error.message}`
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GET /api/_flows/:
|
|
2
|
+
* GET /api/_flows/:flowName/runs
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Returns a list of flow runs with their metadata from the sorted set index.
|
|
5
|
+
* Supports pagination via offset/limit query params.
|
|
6
|
+
*
|
|
7
|
+
* Query params:
|
|
8
|
+
* - limit: number (default: 50)
|
|
9
|
+
* - offset: number (default: 0)
|
|
10
|
+
*
|
|
11
|
+
* Returns:
|
|
12
|
+
* {
|
|
13
|
+
* runs: Array<{ id, score, metadata }>
|
|
14
|
+
* }
|
|
5
15
|
*/
|
|
6
16
|
declare const _default: any;
|
|
7
17
|
export default _default;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, getQuery,
|
|
1
|
+
import { defineEventHandler, getRouterParam, getQuery, useStoreAdapter, useNventLogger, useStreamTopics } from "#imports";
|
|
2
2
|
export default defineEventHandler(async (event) => {
|
|
3
3
|
const logger = useNventLogger("api-flows-runs");
|
|
4
4
|
const flowName = getRouterParam(event, "name");
|
|
@@ -11,10 +11,21 @@ export default defineEventHandler(async (event) => {
|
|
|
11
11
|
if (!flowName) {
|
|
12
12
|
return { error: "Missing flow name" };
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
let store;
|
|
15
|
+
let SubjectPatterns;
|
|
16
16
|
try {
|
|
17
|
-
|
|
17
|
+
store = useStoreAdapter();
|
|
18
|
+
const topics = useStreamTopics();
|
|
19
|
+
SubjectPatterns = topics.SubjectPatterns;
|
|
20
|
+
} catch (err) {
|
|
21
|
+
logger.error("[flows/runs] Adapters not initialized yet:", { error: err });
|
|
22
|
+
return {
|
|
23
|
+
error: "Server initializing",
|
|
24
|
+
message: "Please retry in a moment"
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const runIndexKey = SubjectPatterns.flowRunIndex(flowName);
|
|
18
29
|
let totalCount = 0;
|
|
19
30
|
try {
|
|
20
31
|
const allEntries = await store.indexRead(runIndexKey, { limit: 1e4 });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineEventHandler, readBody, getRouterParam, createError,
|
|
1
|
+
import { defineEventHandler, readBody, getRouterParam, createError, useQueueAdapter, $useQueueRegistry } from "#imports";
|
|
2
2
|
export default defineEventHandler(async (event) => {
|
|
3
3
|
const flowName = getRouterParam(event, "name");
|
|
4
4
|
if (!flowName) {
|
|
@@ -24,7 +24,16 @@ export default defineEventHandler(async (event) => {
|
|
|
24
24
|
throw createError({ statusCode: 404, statusMessage: `Flow '${flowName}' not found` });
|
|
25
25
|
}
|
|
26
26
|
const queueName = typeof flow.entry.queue === "string" ? flow.entry.queue : flow.entry.queue?.name || flow.entry.queue;
|
|
27
|
-
|
|
27
|
+
let queue;
|
|
28
|
+
try {
|
|
29
|
+
queue = useQueueAdapter();
|
|
30
|
+
} catch {
|
|
31
|
+
throw createError({
|
|
32
|
+
statusCode: 503,
|
|
33
|
+
statusMessage: "Server initializing",
|
|
34
|
+
data: "Queue adapter not ready yet, please retry"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
28
37
|
const scheduleOpts = {};
|
|
29
38
|
if (cron) scheduleOpts.cron = cron;
|
|
30
39
|
if (delay) scheduleOpts.delay = delay;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, createError,
|
|
2
|
-
import { Queue } from "bullmq";
|
|
1
|
+
import { defineEventHandler, getRouterParam, createError, useQueueAdapter, $useQueueRegistry } from "#imports";
|
|
3
2
|
export default defineEventHandler(async (event) => {
|
|
4
3
|
const flowName = getRouterParam(event, "name");
|
|
5
4
|
const scheduleId = getRouterParam(event, "id");
|
|
@@ -11,29 +10,35 @@ export default defineEventHandler(async (event) => {
|
|
|
11
10
|
if (!flow || !flow.entry) {
|
|
12
11
|
throw createError({ statusCode: 404, statusMessage: `Flow '${flowName}' not found` });
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
const rc = useRuntimeConfig();
|
|
16
|
-
const connection = rc.queue?.redis;
|
|
17
|
-
let prefix;
|
|
13
|
+
let adapter;
|
|
18
14
|
try {
|
|
19
|
-
|
|
20
|
-
const worker = registry.workers.find((w) => w?.queue?.name === queueName);
|
|
21
|
-
if (worker?.queue?.prefix) {
|
|
22
|
-
prefix = worker.queue.prefix;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
15
|
+
adapter = useQueueAdapter();
|
|
25
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
|
+
});
|
|
26
28
|
}
|
|
27
|
-
const queue = new Queue(queueName, { connection, prefix });
|
|
28
29
|
try {
|
|
29
|
-
await
|
|
30
|
-
|
|
30
|
+
const removed = await adapter.removeScheduledJob(scheduleId);
|
|
31
|
+
if (!removed) {
|
|
32
|
+
throw createError({ statusCode: 404, statusMessage: "Schedule not found" });
|
|
33
|
+
}
|
|
31
34
|
return {
|
|
32
35
|
success: true,
|
|
33
36
|
message: "Schedule deleted successfully"
|
|
34
37
|
};
|
|
35
38
|
} catch (error) {
|
|
36
|
-
|
|
39
|
+
if (error.statusCode === 404) {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
37
42
|
throw createError({
|
|
38
43
|
statusCode: 500,
|
|
39
44
|
statusMessage: `Failed to delete schedule: ${error.message}`
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { defineEventHandler, getRouterParam, createError,
|
|
2
|
-
import { Queue } from "bullmq";
|
|
1
|
+
import { defineEventHandler, getRouterParam, createError, useQueueAdapter, $useQueueRegistry } from "#imports";
|
|
3
2
|
export default defineEventHandler(async (event) => {
|
|
4
3
|
const flowName = getRouterParam(event, "name");
|
|
5
4
|
if (!flowName) {
|
|
@@ -10,36 +9,39 @@ export default defineEventHandler(async (event) => {
|
|
|
10
9
|
if (!flow || !flow.entry) {
|
|
11
10
|
throw createError({ statusCode: 404, statusMessage: `Flow '${flowName}' not found` });
|
|
12
11
|
}
|
|
13
|
-
const rc = useRuntimeConfig();
|
|
14
|
-
const connection = rc.queue?.redis;
|
|
15
12
|
const queueName = typeof flow.entry.queue === "string" ? flow.entry.queue : flow.entry.queue?.name || flow.entry.queue;
|
|
16
|
-
let
|
|
13
|
+
let adapter;
|
|
17
14
|
try {
|
|
18
|
-
|
|
19
|
-
const worker = registry.workers.find((w) => w?.queue?.name === queueName);
|
|
20
|
-
if (worker?.queue?.prefix) {
|
|
21
|
-
prefix = worker.queue.prefix;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
15
|
+
adapter = useQueueAdapter();
|
|
24
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
|
+
});
|
|
25
28
|
}
|
|
26
|
-
const queue = new Queue(queueName, { connection, prefix });
|
|
27
29
|
try {
|
|
28
|
-
const
|
|
29
|
-
const schedules =
|
|
30
|
-
id: job.
|
|
30
|
+
const scheduledJobs = await adapter.getScheduledJobs(queueName);
|
|
31
|
+
const schedules = scheduledJobs.filter((job) => job.jobName === flow.entry.step).map((job) => ({
|
|
32
|
+
id: job.id,
|
|
31
33
|
flowName,
|
|
32
34
|
queue: queueName,
|
|
33
35
|
step: flow.entry.step,
|
|
34
36
|
schedule: {
|
|
35
|
-
cron: job.pattern
|
|
37
|
+
cron: job.cron || job.pattern
|
|
36
38
|
},
|
|
37
|
-
nextRun: job.
|
|
39
|
+
nextRun: job.nextRun ? job.nextRun.toISOString() : void 0,
|
|
40
|
+
repeatCount: job.repeatCount,
|
|
41
|
+
limit: job.limit
|
|
38
42
|
}));
|
|
39
|
-
await queue.close();
|
|
40
43
|
return schedules;
|
|
41
44
|
} catch (error) {
|
|
42
|
-
await queue.close();
|
|
43
45
|
throw createError({
|
|
44
46
|
statusCode: 500,
|
|
45
47
|
statusMessage: `Failed to list schedules: ${error.message}`
|