@nvent-addon/app 0.4.5 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.d.mts +19 -1
- package/dist/module.mjs +20 -8
- package/dist/runtime/app/components/{nhealth/component-router.d.vue.ts → ComponentRouter.d.vue.ts} +1 -5
- package/dist/runtime/app/components/{nhealth/component-router.vue.d.ts → ComponentRouter.vue.d.ts} +1 -5
- package/dist/runtime/app/components/{nhealth/component-shell.d.vue.ts → ComponentShell.d.vue.ts} +4 -9
- package/dist/runtime/app/components/ComponentShell.vue +87 -0
- package/dist/runtime/app/components/{nhealth/component-shell.vue.d.ts → ComponentShell.vue.d.ts} +4 -9
- package/dist/runtime/app/components/ConfirmDialog.d.vue.ts +1 -6
- package/dist/runtime/app/components/ConfirmDialog.vue.d.ts +1 -6
- package/dist/runtime/app/components/ListItem.d.vue.ts +3 -6
- package/dist/runtime/app/components/ListItem.vue.d.ts +3 -6
- package/dist/runtime/app/components/LiveIndicator.d.vue.ts +7 -0
- package/dist/runtime/app/components/LiveIndicator.vue +30 -0
- package/dist/runtime/app/components/LiveIndicator.vue.d.ts +7 -0
- package/dist/runtime/app/components/{QueueConfigDetails.d.vue.ts → QueueConfiguration.d.vue.ts} +1 -10
- package/dist/runtime/app/components/QueueConfiguration.vue +387 -0
- package/dist/runtime/app/components/{QueueConfigDetails.vue.d.ts → QueueConfiguration.vue.d.ts} +1 -10
- package/dist/runtime/app/components/StatCard.d.vue.ts +9 -0
- package/dist/runtime/app/components/StatCard.vue +57 -0
- package/dist/runtime/app/components/StatCard.vue.d.ts +9 -0
- package/dist/runtime/app/components/TimelineList.vue +67 -0
- package/dist/runtime/app/components/flow/AwaitNode.d.vue.ts +18 -0
- package/dist/runtime/app/components/flow/AwaitNode.vue +91 -0
- package/dist/runtime/app/components/flow/AwaitNode.vue.d.ts +18 -0
- package/dist/runtime/app/components/{FlowDiagram.d.vue.ts → flow/Diagram.d.vue.ts} +12 -1
- package/dist/runtime/app/components/{FlowDiagram.vue → flow/Diagram.vue} +92 -11
- package/dist/runtime/app/components/{FlowDiagram.vue.d.ts → flow/Diagram.vue.d.ts} +12 -1
- package/dist/runtime/app/components/{FlowRunOverview.d.vue.ts → flow/RunOverview.d.vue.ts} +3 -0
- package/dist/runtime/app/components/{FlowRunOverview.vue → flow/RunOverview.vue} +94 -8
- package/dist/runtime/app/components/{FlowRunOverview.vue.d.ts → flow/RunOverview.vue.d.ts} +3 -0
- package/dist/runtime/app/components/{FlowRunStatusBadge.d.vue.ts → flow/RunStatusBadge.d.vue.ts} +2 -8
- package/dist/runtime/app/components/{FlowRunStatusBadge.vue → flow/RunStatusBadge.vue} +8 -1
- package/dist/runtime/app/components/{FlowRunStatusBadge.vue.d.ts → flow/RunStatusBadge.vue.d.ts} +2 -8
- package/dist/runtime/app/components/{FlowRunTimeline.vue → flow/RunTimeline.vue} +1 -1
- package/dist/runtime/app/components/{FlowStepSelector.d.vue.ts → flow/StepSelector.d.vue.ts} +1 -0
- package/dist/runtime/app/components/flow/StepSelector.vue +553 -0
- package/dist/runtime/app/components/{FlowStepSelector.vue.d.ts → flow/StepSelector.vue.d.ts} +1 -0
- package/dist/runtime/app/components/trigger/BasicInfoCard.d.vue.ts +33 -0
- package/dist/runtime/app/components/trigger/BasicInfoCard.vue +168 -0
- package/dist/runtime/app/components/trigger/BasicInfoCard.vue.d.ts +33 -0
- package/dist/runtime/app/components/{FlowSchedulesList.d.vue.ts → trigger/DangerZone.d.vue.ts} +4 -6
- package/dist/runtime/app/components/trigger/DangerZone.vue +46 -0
- package/dist/runtime/app/components/{FlowSchedulesList.vue.d.ts → trigger/DangerZone.vue.d.ts} +4 -6
- package/dist/runtime/app/components/trigger/EditHeader.d.vue.ts +15 -0
- package/dist/runtime/app/components/trigger/EditHeader.vue +55 -0
- package/dist/runtime/app/components/trigger/EditHeader.vue.d.ts +15 -0
- package/dist/runtime/app/components/trigger/EventConfig.d.vue.ts +24 -0
- package/dist/runtime/app/components/trigger/EventConfig.vue +68 -0
- package/dist/runtime/app/components/trigger/EventConfig.vue.d.ts +24 -0
- package/dist/runtime/app/components/trigger/FlowSubscriptions.d.vue.ts +14 -0
- package/dist/runtime/app/components/trigger/FlowSubscriptions.vue +128 -0
- package/dist/runtime/app/components/trigger/FlowSubscriptions.vue.d.ts +14 -0
- package/dist/runtime/app/components/trigger/ScheduleConfig.d.vue.ts +27 -0
- package/dist/runtime/app/components/trigger/ScheduleConfig.vue +375 -0
- package/dist/runtime/app/components/trigger/ScheduleConfig.vue.d.ts +27 -0
- package/dist/runtime/app/components/{FlowScheduleDialog.d.vue.ts → trigger/StatusConfig.d.vue.ts} +6 -6
- package/dist/runtime/app/components/trigger/StatusConfig.vue +78 -0
- package/dist/runtime/app/components/{FlowScheduleDialog.vue.d.ts → trigger/StatusConfig.vue.d.ts} +6 -6
- package/dist/runtime/app/components/trigger/WebhookConfig.d.vue.ts +30 -0
- package/dist/runtime/app/components/trigger/WebhookConfig.vue +97 -0
- package/dist/runtime/app/components/trigger/WebhookConfig.vue.d.ts +30 -0
- package/dist/runtime/app/composables/useAnalyzedFlows.d.ts +5 -0
- package/dist/runtime/app/composables/useAnalyzedFlows.js +15 -1
- package/dist/runtime/app/composables/useComponentRouter.d.ts +8 -0
- package/dist/runtime/app/composables/useComponentRouter.js +10 -2
- package/dist/runtime/app/composables/useFlowRunsInfinite.d.ts +1 -1
- package/dist/runtime/app/composables/useFlowState.js +65 -0
- package/dist/runtime/app/composables/useFlowWebSocket.d.ts +11 -2
- package/dist/runtime/app/composables/useFlowWebSocket.js +181 -65
- package/dist/runtime/app/composables/useQueueJobs.d.ts +12 -1
- package/dist/runtime/app/composables/useQueueJobs.js +13 -7
- package/dist/runtime/app/composables/useTrigger.d.ts +137 -0
- package/dist/runtime/app/composables/useTrigger.js +116 -0
- package/dist/runtime/app/composables/useTriggerWebSocket.d.ts +35 -0
- package/dist/runtime/app/composables/useTriggerWebSocket.js +333 -0
- package/dist/runtime/app/pages/dashboard.d.vue.ts +3 -0
- package/dist/runtime/app/pages/dashboard.vue +738 -0
- package/dist/runtime/app/pages/dashboard.vue.d.ts +3 -0
- package/dist/runtime/app/pages/flows/[name].d.vue.ts +3 -0
- package/dist/runtime/app/pages/flows/[name].vue +680 -0
- package/dist/runtime/app/pages/flows/[name].vue.d.ts +3 -0
- package/dist/runtime/app/pages/flows/index.vue +321 -620
- package/dist/runtime/app/pages/index.vue +39 -9
- package/dist/runtime/app/pages/queues/index.vue +202 -194
- package/dist/runtime/app/pages/queues/jobs.vue +534 -207
- package/dist/runtime/app/pages/settings/scheduler.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/scheduler.vue +310 -0
- package/dist/runtime/app/pages/settings/scheduler.vue.d.ts +3 -0
- package/dist/runtime/app/pages/triggers/[name]/edit.d.vue.ts +3 -0
- package/dist/runtime/app/pages/triggers/[name]/edit.vue +429 -0
- package/dist/runtime/app/pages/triggers/[name]/edit.vue.d.ts +3 -0
- package/dist/runtime/app/pages/triggers/[name].d.vue.ts +3 -0
- package/dist/runtime/app/pages/triggers/[name].vue +898 -0
- package/dist/runtime/app/pages/triggers/[name].vue.d.ts +3 -0
- package/dist/runtime/app/pages/triggers/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/triggers/index.vue +528 -0
- package/dist/runtime/app/pages/triggers/index.vue.d.ts +3 -0
- package/dist/runtime/app/pages/triggers/new.d.vue.ts +3 -0
- package/dist/runtime/app/pages/triggers/new.vue +610 -0
- package/dist/runtime/app/pages/triggers/new.vue.d.ts +3 -0
- package/dist/runtime/server/api/_flows/[name]/clear-history.delete.d.ts +10 -0
- package/dist/runtime/server/api/_flows/[name]/clear-history.delete.js +49 -0
- package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.d.ts +2 -0
- 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 +17 -0
- package/dist/runtime/server/api/_flows/[name]/runs.get.js +64 -0
- package/dist/runtime/server/api/_flows/[name]/start.post.d.ts +2 -0
- package/dist/runtime/server/api/_flows/[name]/start.post.js +9 -0
- package/dist/runtime/server/api/_flows/index.get.d.ts +7 -0
- package/dist/runtime/server/api/_flows/index.get.js +5 -0
- package/dist/runtime/server/api/_flows/recent-runs.get.d.ts +15 -0
- package/dist/runtime/server/api/_flows/recent-runs.get.js +67 -0
- package/dist/runtime/server/api/_flows/ws.d.ts +80 -0
- package/dist/runtime/server/api/_flows/ws.js +309 -0
- package/dist/runtime/server/api/_queues/[name]/job/[id].get.d.ts +2 -0
- package/dist/runtime/server/api/_queues/[name]/job/[id].get.js +14 -0
- package/dist/runtime/server/api/_queues/[name]/job/index.get.d.ts +2 -0
- package/dist/runtime/server/api/_queues/[name]/job/index.get.js +39 -0
- package/dist/runtime/server/api/_queues/index.get.d.ts +2 -0
- package/dist/runtime/server/api/_queues/index.get.js +106 -0
- package/dist/runtime/server/api/_queues/ws.d.ts +48 -0
- package/dist/runtime/server/api/_queues/ws.js +215 -0
- package/dist/runtime/server/api/_scheduler/jobs.get.d.ts +19 -0
- package/dist/runtime/server/api/_scheduler/jobs.get.js +36 -0
- package/dist/runtime/server/api/_triggers/[name]/events.get.d.ts +6 -0
- package/dist/runtime/server/api/_triggers/[name]/events.get.js +43 -0
- package/dist/runtime/server/api/_triggers/[name]/index.get.d.ts +6 -0
- package/dist/runtime/server/api/_triggers/[name]/index.get.js +76 -0
- package/dist/runtime/server/api/_triggers/[name].delete.d.ts +7 -0
- package/dist/runtime/server/api/_triggers/[name].delete.js +37 -0
- package/dist/runtime/server/api/_triggers/[name].patch.d.ts +7 -0
- package/dist/runtime/server/api/_triggers/[name].patch.js +117 -0
- package/dist/runtime/server/api/_triggers/index.get.d.ts +6 -0
- package/dist/runtime/server/api/_triggers/index.get.js +44 -0
- package/dist/runtime/server/api/_triggers/index.post.d.ts +7 -0
- package/dist/runtime/server/api/_triggers/index.post.js +124 -0
- package/dist/runtime/server/api/_triggers/stats.get.d.ts +6 -0
- package/dist/runtime/server/api/_triggers/stats.get.js +41 -0
- package/dist/runtime/server/api/_triggers/ws.d.ts +74 -0
- package/dist/runtime/server/api/_triggers/ws.js +315 -0
- package/dist/runtime/server/tsconfig.json +7 -0
- package/package.json +8 -8
- package/dist/runtime/app/components/FlowScheduleDialog.vue +0 -226
- package/dist/runtime/app/components/FlowSchedulesList.vue +0 -99
- package/dist/runtime/app/components/FlowStepSelector.vue +0 -238
- package/dist/runtime/app/components/QueueConfigDetails.vue +0 -412
- package/dist/runtime/app/components/nhealth/component-shell.vue +0 -89
- /package/dist/runtime/app/components/{nhealth/component-router.vue → ComponentRouter.vue} +0 -0
- /package/dist/runtime/app/components/{FlowNodeCard.d.vue.ts → flow/NodeCard.d.vue.ts} +0 -0
- /package/dist/runtime/app/components/{FlowNodeCard.vue → flow/NodeCard.vue} +0 -0
- /package/dist/runtime/app/components/{FlowNodeCard.vue.d.ts → flow/NodeCard.vue.d.ts} +0 -0
- /package/dist/runtime/app/components/{FlowRunTimeline.d.vue.ts → flow/RunTimeline.d.vue.ts} +0 -0
- /package/dist/runtime/app/components/{FlowRunTimeline.vue.d.ts → flow/RunTimeline.vue.d.ts} +0 -0
|
@@ -12,3 +12,8 @@ export declare function useAnalyzedFlows(): any;
|
|
|
12
12
|
* Use this when you don't need reactivity.
|
|
13
13
|
*/
|
|
14
14
|
export declare function getAnalyzedFlows(): AnalyzedFlows;
|
|
15
|
+
/**
|
|
16
|
+
* Get analyzed flows with flattened structure for UI consumption.
|
|
17
|
+
* Merges analyzed properties to top level for easier access.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useFlattenedAnalyzedFlows(): import("vue").ComputedRef<any>;
|
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
import { analyzedFlows } from "#build/analyzed-flows";
|
|
2
|
-
import { readonly, ref } from "#imports";
|
|
2
|
+
import { readonly, ref, computed } from "#imports";
|
|
3
3
|
export function useAnalyzedFlows() {
|
|
4
4
|
return readonly(ref(analyzedFlows));
|
|
5
5
|
}
|
|
6
6
|
export function getAnalyzedFlows() {
|
|
7
7
|
return analyzedFlows;
|
|
8
8
|
}
|
|
9
|
+
export function useFlattenedAnalyzedFlows() {
|
|
10
|
+
return computed(() => {
|
|
11
|
+
return analyzedFlows.map((flow) => ({
|
|
12
|
+
id: flow.id,
|
|
13
|
+
entry: flow.entry,
|
|
14
|
+
steps: flow.analyzed?.steps || flow.steps || {},
|
|
15
|
+
levels: flow.analyzed?.levels || [],
|
|
16
|
+
maxLevel: flow.analyzed?.maxLevel || 0,
|
|
17
|
+
stallTimeout: flow.analyzed?.stallTimeout,
|
|
18
|
+
awaitPatterns: flow.analyzed?.awaitPatterns,
|
|
19
|
+
hasAwait: flow.analyzed?.awaitPatterns?.steps?.length > 0 || false
|
|
20
|
+
}));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { shallowRef } from '#imports';
|
|
2
|
+
import { createHooks } from 'hookable';
|
|
2
3
|
export type ComponentRouteRecord = {
|
|
3
4
|
path: string;
|
|
4
5
|
component: any;
|
|
@@ -13,6 +14,12 @@ export interface UseComponentRouterOptions {
|
|
|
13
14
|
provideKey?: string;
|
|
14
15
|
debug?: boolean;
|
|
15
16
|
}
|
|
17
|
+
type RouterHooks = {
|
|
18
|
+
navigated: (data: {
|
|
19
|
+
path: string;
|
|
20
|
+
params: Record<string, string>;
|
|
21
|
+
}) => void;
|
|
22
|
+
};
|
|
16
23
|
type RouterContext = {
|
|
17
24
|
route: ReturnType<typeof shallowRef<{
|
|
18
25
|
path: string;
|
|
@@ -25,6 +32,7 @@ type RouterContext = {
|
|
|
25
32
|
makeHref: (patternOrPath: string, params?: Record<string, any>) => string;
|
|
26
33
|
pushTo: (patternOrPath: string, params?: Record<string, any>) => Promise<void>;
|
|
27
34
|
replaceTo: (patternOrPath: string, params?: Record<string, any>) => Promise<void>;
|
|
35
|
+
hooks: ReturnType<typeof createHooks<RouterHooks>>;
|
|
28
36
|
};
|
|
29
37
|
export declare function useComponentRouter(): RouterContext & {
|
|
30
38
|
component?: any;
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
watch,
|
|
9
9
|
defineAsyncComponent
|
|
10
10
|
} from "#imports";
|
|
11
|
+
import { createHooks } from "hookable";
|
|
11
12
|
export function useComponentRouter(opts) {
|
|
12
13
|
const CTX_KEY = "component-router";
|
|
13
14
|
if (!opts || !("routes" in opts) || !opts.routes) {
|
|
@@ -23,6 +24,7 @@ export function useComponentRouter(opts) {
|
|
|
23
24
|
);
|
|
24
25
|
const noopMake = (p, _params) => p;
|
|
25
26
|
const noopHref = (p, _params) => p;
|
|
27
|
+
const emptyHooks = createHooks();
|
|
26
28
|
return {
|
|
27
29
|
route: emptyRoute,
|
|
28
30
|
push: warnNav,
|
|
@@ -31,6 +33,7 @@ export function useComponentRouter(opts) {
|
|
|
31
33
|
makeHref: noopHref,
|
|
32
34
|
pushTo: async (p, _params) => warnNav(p),
|
|
33
35
|
replaceTo: async (p, _params) => warnNav(p),
|
|
36
|
+
hooks: emptyHooks,
|
|
34
37
|
component: void 0
|
|
35
38
|
};
|
|
36
39
|
}
|
|
@@ -55,6 +58,7 @@ export function useComponentRouter(opts) {
|
|
|
55
58
|
params: {},
|
|
56
59
|
query: {}
|
|
57
60
|
});
|
|
61
|
+
const hooks = createHooks();
|
|
58
62
|
const dbg = (...args) => {
|
|
59
63
|
if (props.debug) console.info("[component-router]", ...args);
|
|
60
64
|
};
|
|
@@ -119,6 +123,8 @@ export function useComponentRouter(opts) {
|
|
|
119
123
|
// Only use query params from the current path, not from nuxtRoute
|
|
120
124
|
};
|
|
121
125
|
dbg("current", route.value);
|
|
126
|
+
dbg("calling navigated hook with", { path: pathOnly || path, params: m.params });
|
|
127
|
+
hooks.callHook("navigated", { path: pathOnly || path, params: m.params });
|
|
122
128
|
}
|
|
123
129
|
function readFromHost() {
|
|
124
130
|
if (props.mode === "query") {
|
|
@@ -137,6 +143,8 @@ export function useComponentRouter(opts) {
|
|
|
137
143
|
}
|
|
138
144
|
async function writeToHost(path, replace2 = false) {
|
|
139
145
|
dbg("writeToHost", path, { replace: replace2, mode: props.mode });
|
|
146
|
+
const prevPath = route.value.path;
|
|
147
|
+
dbg("current path before write:", prevPath, "new path:", path);
|
|
140
148
|
if (props.mode === "query") {
|
|
141
149
|
const [pathOnly, queryString] = path.split("?");
|
|
142
150
|
const pathQuery = {};
|
|
@@ -199,7 +207,7 @@ export function useComponentRouter(opts) {
|
|
|
199
207
|
const path = makePath(patternOrPath, params);
|
|
200
208
|
await replace(path);
|
|
201
209
|
}
|
|
202
|
-
const exposed = { push, replace, route, makePath, makeHref, pushTo, replaceTo };
|
|
210
|
+
const exposed = { push, replace, route, makePath, makeHref, pushTo, replaceTo, hooks };
|
|
203
211
|
provide(props.provideKey, exposed);
|
|
204
212
|
const initialPath = readFromHost() || props.initial || props.routes[0]?.path || "/";
|
|
205
213
|
dbg("init", { initialPath });
|
|
@@ -215,7 +223,7 @@ export function useComponentRouter(opts) {
|
|
|
215
223
|
if (path) setCurrent(path);
|
|
216
224
|
}
|
|
217
225
|
);
|
|
218
|
-
return { component, route, push, replace, makePath, makeHref, pushTo, replaceTo };
|
|
226
|
+
return { component, route, push, replace, makePath, makeHref, pushTo, replaceTo, hooks };
|
|
219
227
|
}
|
|
220
228
|
export default useComponentRouter;
|
|
221
229
|
export function createComponentRoutes(glob, options) {
|
|
@@ -6,7 +6,7 @@ export declare function useFlowRunsInfinite(flowId: Ref<string>): {
|
|
|
6
6
|
items: import("vue").ComputedRef<{
|
|
7
7
|
id: string;
|
|
8
8
|
flowName: string;
|
|
9
|
-
status: "running" | "completed" | "failed" | "canceled" | "stalled" | "unknown";
|
|
9
|
+
status: "running" | "completed" | "failed" | "canceled" | "stalled" | "awaiting" | "unknown";
|
|
10
10
|
createdAt: string;
|
|
11
11
|
startedAt?: string | undefined;
|
|
12
12
|
completedAt?: string | undefined;
|
|
@@ -16,6 +16,13 @@ export function reduceFlowState(events) {
|
|
|
16
16
|
if (e.flowName) state.meta = { ...state.meta, flowName: e.flowName };
|
|
17
17
|
if (e.data?.flowName) state.meta = { ...state.meta, flowName: e.data.flowName };
|
|
18
18
|
if (e.data?.input) state.meta = { ...state.meta, input: e.data.input };
|
|
19
|
+
if (e.data?.trigger) {
|
|
20
|
+
state.meta = {
|
|
21
|
+
...state.meta,
|
|
22
|
+
triggerName: e.data.trigger.name,
|
|
23
|
+
triggerType: e.data.trigger.type || "manual"
|
|
24
|
+
};
|
|
25
|
+
}
|
|
19
26
|
break;
|
|
20
27
|
case "flow.complete":
|
|
21
28
|
case "flow.completed":
|
|
@@ -119,6 +126,64 @@ export function reduceFlowState(events) {
|
|
|
119
126
|
state.steps[stepKey].completedAt = e.ts;
|
|
120
127
|
break;
|
|
121
128
|
}
|
|
129
|
+
case "await.registered": {
|
|
130
|
+
if (!stepKey) break;
|
|
131
|
+
const awaitKeyAfter = `${stepKey}:await-after`;
|
|
132
|
+
const awaitKeyBefore = `${stepKey}:await-before`;
|
|
133
|
+
if (!state.steps[awaitKeyAfter]) {
|
|
134
|
+
state.steps[awaitKeyAfter] = { status: "waiting", attempt: 1 };
|
|
135
|
+
}
|
|
136
|
+
state.steps[awaitKeyAfter].status = "waiting";
|
|
137
|
+
state.steps[awaitKeyAfter].awaitType = e.data?.awaitType;
|
|
138
|
+
state.steps[awaitKeyAfter].awaitData = e.data;
|
|
139
|
+
if (!state.steps[awaitKeyBefore]) {
|
|
140
|
+
state.steps[awaitKeyBefore] = { status: "waiting", attempt: 1 };
|
|
141
|
+
}
|
|
142
|
+
state.steps[awaitKeyBefore].status = "waiting";
|
|
143
|
+
state.steps[awaitKeyBefore].awaitType = e.data?.awaitType;
|
|
144
|
+
state.steps[awaitKeyBefore].awaitData = e.data;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case "await.resolved": {
|
|
148
|
+
if (!stepKey) break;
|
|
149
|
+
const awaitKeyAfter = `${stepKey}:await-after`;
|
|
150
|
+
const awaitKeyBefore = `${stepKey}:await-before`;
|
|
151
|
+
if (!state.steps[awaitKeyAfter]) {
|
|
152
|
+
state.steps[awaitKeyAfter] = { status: "completed", attempt: 1 };
|
|
153
|
+
}
|
|
154
|
+
state.steps[awaitKeyAfter].status = "completed";
|
|
155
|
+
state.steps[awaitKeyAfter].completedAt = e.ts;
|
|
156
|
+
state.steps[awaitKeyAfter].awaitType = e.data?.awaitType;
|
|
157
|
+
if (e.data?.triggerData) state.steps[awaitKeyAfter].result = e.data.triggerData;
|
|
158
|
+
if (!state.steps[awaitKeyBefore]) {
|
|
159
|
+
state.steps[awaitKeyBefore] = { status: "completed", attempt: 1 };
|
|
160
|
+
}
|
|
161
|
+
state.steps[awaitKeyBefore].status = "completed";
|
|
162
|
+
state.steps[awaitKeyBefore].completedAt = e.ts;
|
|
163
|
+
state.steps[awaitKeyBefore].awaitType = e.data?.awaitType;
|
|
164
|
+
if (e.data?.triggerData) state.steps[awaitKeyBefore].result = e.data.triggerData;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case "await.timeout": {
|
|
168
|
+
if (!stepKey) break;
|
|
169
|
+
const awaitKeyAfter = `${stepKey}:await-after`;
|
|
170
|
+
const awaitKeyBefore = `${stepKey}:await-before`;
|
|
171
|
+
if (!state.steps[awaitKeyAfter]) {
|
|
172
|
+
state.steps[awaitKeyAfter] = { status: "timeout", attempt: 1 };
|
|
173
|
+
}
|
|
174
|
+
state.steps[awaitKeyAfter].status = "timeout";
|
|
175
|
+
state.steps[awaitKeyAfter].error = `Await timeout`;
|
|
176
|
+
state.steps[awaitKeyAfter].completedAt = e.ts;
|
|
177
|
+
state.steps[awaitKeyAfter].awaitType = e.data?.awaitType;
|
|
178
|
+
if (!state.steps[awaitKeyBefore]) {
|
|
179
|
+
state.steps[awaitKeyBefore] = { status: "timeout", attempt: 1 };
|
|
180
|
+
}
|
|
181
|
+
state.steps[awaitKeyBefore].status = "timeout";
|
|
182
|
+
state.steps[awaitKeyBefore].error = `Await timeout`;
|
|
183
|
+
state.steps[awaitKeyBefore].completedAt = e.ts;
|
|
184
|
+
state.steps[awaitKeyBefore].awaitType = e.data?.awaitType;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
122
187
|
case "runner.log":
|
|
123
188
|
case "log": {
|
|
124
189
|
state.logs.push({
|
|
@@ -13,14 +13,23 @@ export interface FlowSubscription {
|
|
|
13
13
|
onEvent: (event: any) => void;
|
|
14
14
|
onHistory?: (events: any[]) => void;
|
|
15
15
|
}
|
|
16
|
+
export interface StatsSubscription {
|
|
17
|
+
onInitial?: (data: any) => void;
|
|
18
|
+
onUpdate?: (data: any) => void;
|
|
19
|
+
}
|
|
16
20
|
/**
|
|
17
|
-
* WebSocket composable for flow run events
|
|
18
|
-
*
|
|
21
|
+
* WebSocket composable for flow run events and flow stats
|
|
22
|
+
* Architecture: Client (this) → WebSocket → Server Handler → StreamAdapter.subscribe(StreamTopics.flowEvents)
|
|
23
|
+
* Supports subscribing to specific flow runs and global flow statistics
|
|
24
|
+
* Uses a singleton connection shared across all instances
|
|
19
25
|
*/
|
|
20
26
|
export declare function useFlowWebSocket(): {
|
|
21
27
|
subscribe: (subscription: FlowSubscription, opts?: UseFlowWebSocketOptions) => void;
|
|
22
28
|
unsubscribe: () => void;
|
|
29
|
+
subscribeStats: (subscription: StatsSubscription, opts?: UseFlowWebSocketOptions) => void;
|
|
30
|
+
unsubscribeStats: () => void;
|
|
23
31
|
stop: () => void;
|
|
32
|
+
forceClose: () => void;
|
|
24
33
|
connected: import("vue").Ref<boolean, boolean>;
|
|
25
34
|
reconnecting: import("vue").Ref<boolean, boolean>;
|
|
26
35
|
};
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import { ref, onBeforeUnmount } from "#imports";
|
|
2
|
+
let sharedWs = null;
|
|
3
|
+
let sharedConnected = false;
|
|
4
|
+
let sharedReconnecting = false;
|
|
5
|
+
let retry = 0;
|
|
6
|
+
let reconnectTimer = null;
|
|
7
|
+
let currentOptions;
|
|
8
|
+
let currentSubscription = null;
|
|
9
|
+
let currentStatsSubscription = null;
|
|
10
|
+
let pendingStatsSubscription = false;
|
|
11
|
+
let isStatsSubscribed = false;
|
|
12
|
+
let statsCache = [];
|
|
13
|
+
let pingInterval = null;
|
|
14
|
+
let isServerRestarting = false;
|
|
15
|
+
let refCount = 0;
|
|
2
16
|
export function useFlowWebSocket() {
|
|
3
|
-
const ws = ref(
|
|
4
|
-
const connected = ref(
|
|
5
|
-
const reconnecting = ref(
|
|
6
|
-
|
|
7
|
-
let reconnectTimer = null;
|
|
8
|
-
let currentOptions;
|
|
9
|
-
let currentSubscription = null;
|
|
10
|
-
let pingInterval = null;
|
|
11
|
-
let isServerRestarting = false;
|
|
17
|
+
const ws = ref(sharedWs);
|
|
18
|
+
const connected = ref(sharedConnected);
|
|
19
|
+
const reconnecting = ref(sharedReconnecting);
|
|
20
|
+
refCount++;
|
|
12
21
|
const computeDelay = (opts) => {
|
|
13
22
|
const base = Math.max(100, opts?.baseDelayMs ?? 1e3);
|
|
14
23
|
const max = Math.max(base, opts?.maxDelayMs ?? 1e4);
|
|
@@ -32,34 +41,55 @@ export function useFlowWebSocket() {
|
|
|
32
41
|
pingInterval = null;
|
|
33
42
|
}
|
|
34
43
|
};
|
|
44
|
+
const updateRefs = () => {
|
|
45
|
+
ws.value = sharedWs;
|
|
46
|
+
connected.value = sharedConnected;
|
|
47
|
+
reconnecting.value = sharedReconnecting;
|
|
48
|
+
};
|
|
35
49
|
const send = (data) => {
|
|
36
|
-
if (
|
|
37
|
-
|
|
50
|
+
if (sharedWs && sharedWs.readyState === WebSocket.OPEN) {
|
|
51
|
+
try {
|
|
52
|
+
sharedWs.send(JSON.stringify(data));
|
|
53
|
+
return true;
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.error("[useFlowWebSocket] Error sending message:", err);
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
38
58
|
}
|
|
59
|
+
return false;
|
|
39
60
|
};
|
|
40
61
|
const startPingInterval = () => {
|
|
41
62
|
clearTimers();
|
|
42
63
|
pingInterval = setInterval(() => {
|
|
43
|
-
if (
|
|
64
|
+
if (sharedWs && sharedWs.readyState === WebSocket.OPEN) {
|
|
44
65
|
send({ type: "ping" });
|
|
45
66
|
}
|
|
46
67
|
}, 3e4);
|
|
47
68
|
};
|
|
48
69
|
const stop = () => {
|
|
70
|
+
refCount = Math.max(0, refCount - 1);
|
|
71
|
+
};
|
|
72
|
+
const forceClose = () => {
|
|
49
73
|
clearTimers();
|
|
50
74
|
isServerRestarting = false;
|
|
51
75
|
try {
|
|
52
|
-
if (
|
|
53
|
-
|
|
76
|
+
if (sharedWs) {
|
|
77
|
+
sharedWs.close(1e3, "Client closing");
|
|
54
78
|
}
|
|
55
79
|
} catch (err) {
|
|
56
80
|
console.warn("[useFlowWebSocket] Error closing WebSocket:", err);
|
|
57
81
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
82
|
+
sharedWs = null;
|
|
83
|
+
sharedConnected = false;
|
|
84
|
+
sharedReconnecting = false;
|
|
85
|
+
updateRefs();
|
|
61
86
|
retry = 0;
|
|
87
|
+
refCount = 0;
|
|
62
88
|
currentSubscription = null;
|
|
89
|
+
currentStatsSubscription = null;
|
|
90
|
+
isStatsSubscribed = false;
|
|
91
|
+
pendingStatsSubscription = false;
|
|
92
|
+
statsCache = [];
|
|
63
93
|
};
|
|
64
94
|
const attemptReconnect = () => {
|
|
65
95
|
if (!currentOptions?.autoReconnect) {
|
|
@@ -73,29 +103,38 @@ export function useFlowWebSocket() {
|
|
|
73
103
|
return;
|
|
74
104
|
}
|
|
75
105
|
retry++;
|
|
76
|
-
|
|
106
|
+
sharedReconnecting = true;
|
|
107
|
+
updateRefs();
|
|
77
108
|
const baseDelay = isServerRestarting ? 2e3 : computeDelay(currentOptions);
|
|
78
109
|
const delay = baseDelay;
|
|
79
|
-
console.log(`[useFlowWebSocket] Will attempt reconnection in ${delay}ms (attempt ${retry}/${max})${isServerRestarting ? " [server restart]" : ""}`);
|
|
80
110
|
clearTimers();
|
|
81
111
|
reconnectTimer = setTimeout(() => {
|
|
82
|
-
if (currentSubscription) {
|
|
83
|
-
|
|
112
|
+
if (currentSubscription || currentStatsSubscription) {
|
|
113
|
+
connect(currentOptions);
|
|
84
114
|
}
|
|
85
115
|
}, delay);
|
|
86
116
|
};
|
|
87
|
-
const setupWebSocket = (socket,
|
|
117
|
+
const setupWebSocket = (socket, opts) => {
|
|
88
118
|
socket.onopen = () => {
|
|
89
119
|
console.log("[useFlowWebSocket] Connected");
|
|
90
|
-
|
|
91
|
-
|
|
120
|
+
sharedConnected = true;
|
|
121
|
+
sharedReconnecting = false;
|
|
122
|
+
updateRefs();
|
|
92
123
|
retry = 0;
|
|
93
124
|
startPingInterval();
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
125
|
+
if (currentSubscription) {
|
|
126
|
+
send({
|
|
127
|
+
type: "subscribe",
|
|
128
|
+
flowName: currentSubscription.flowName,
|
|
129
|
+
runId: currentSubscription.runId
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (currentStatsSubscription || pendingStatsSubscription) {
|
|
133
|
+
send({
|
|
134
|
+
type: "subscribe.stats"
|
|
135
|
+
});
|
|
136
|
+
pendingStatsSubscription = false;
|
|
137
|
+
}
|
|
99
138
|
opts?.onOpen?.();
|
|
100
139
|
};
|
|
101
140
|
socket.onmessage = (event) => {
|
|
@@ -103,30 +142,64 @@ export function useFlowWebSocket() {
|
|
|
103
142
|
const data = JSON.parse(event.data);
|
|
104
143
|
switch (data.type) {
|
|
105
144
|
case "connected":
|
|
106
|
-
console.log("[useFlowWebSocket] Server acknowledged connection");
|
|
107
145
|
break;
|
|
108
146
|
case "subscribed":
|
|
109
|
-
console.log("[useFlowWebSocket] Subscribed to flow:", data.flowName, data.runId);
|
|
110
147
|
break;
|
|
111
148
|
case "unsubscribed":
|
|
112
|
-
console.log("[useFlowWebSocket] Unsubscribed from flow:", data.flowName, data.runId);
|
|
113
149
|
break;
|
|
114
|
-
case "
|
|
115
|
-
|
|
116
|
-
|
|
150
|
+
case "stats.subscribed":
|
|
151
|
+
isStatsSubscribed = true;
|
|
152
|
+
break;
|
|
153
|
+
case "stats.unsubscribed":
|
|
154
|
+
isStatsSubscribed = false;
|
|
155
|
+
break;
|
|
156
|
+
case "flow.stats.initial": {
|
|
157
|
+
const existingIndex = statsCache.findIndex((s) => s.id === data.data.id);
|
|
158
|
+
if (existingIndex >= 0) {
|
|
159
|
+
statsCache[existingIndex] = data.data;
|
|
160
|
+
} else {
|
|
161
|
+
statsCache.push(data.data);
|
|
162
|
+
}
|
|
163
|
+
if (currentStatsSubscription?.onInitial) {
|
|
164
|
+
currentStatsSubscription.onInitial(data.data);
|
|
165
|
+
} else {
|
|
166
|
+
console.warn("[useFlowWebSocket] No onInitial handler for stats:", data.data);
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case "flow.stats.update": {
|
|
171
|
+
const cacheIndex = statsCache.findIndex((s) => s.id === data.data.id);
|
|
172
|
+
if (cacheIndex >= 0) {
|
|
173
|
+
statsCache[cacheIndex] = data.data;
|
|
174
|
+
} else {
|
|
175
|
+
statsCache.push(data.data);
|
|
176
|
+
}
|
|
177
|
+
if (currentStatsSubscription?.onUpdate) {
|
|
178
|
+
currentStatsSubscription.onUpdate(data.data);
|
|
117
179
|
} else {
|
|
118
|
-
|
|
119
|
-
|
|
180
|
+
console.warn("[useFlowWebSocket] No onUpdate handler for stats:", data.data);
|
|
181
|
+
}
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
case "history":
|
|
185
|
+
if (currentSubscription) {
|
|
186
|
+
if (currentSubscription.onHistory) {
|
|
187
|
+
currentSubscription.onHistory(data.events);
|
|
188
|
+
} else {
|
|
189
|
+
for (const eventData of data.events) {
|
|
190
|
+
currentSubscription.onEvent(eventData);
|
|
191
|
+
}
|
|
120
192
|
}
|
|
121
193
|
}
|
|
122
194
|
break;
|
|
123
195
|
case "event":
|
|
124
|
-
|
|
196
|
+
if (currentSubscription) {
|
|
197
|
+
currentSubscription.onEvent(data.event);
|
|
198
|
+
}
|
|
125
199
|
break;
|
|
126
200
|
case "pong":
|
|
127
201
|
break;
|
|
128
202
|
case "server-restart":
|
|
129
|
-
console.log("[useFlowWebSocket] Server is restarting (HMR)");
|
|
130
203
|
isServerRestarting = true;
|
|
131
204
|
break;
|
|
132
205
|
case "error":
|
|
@@ -146,51 +219,40 @@ export function useFlowWebSocket() {
|
|
|
146
219
|
};
|
|
147
220
|
socket.onclose = (event) => {
|
|
148
221
|
console.log("[useFlowWebSocket] Connection closed:", event.code, event.reason);
|
|
149
|
-
|
|
222
|
+
sharedConnected = false;
|
|
223
|
+
updateRefs();
|
|
150
224
|
clearTimers();
|
|
151
225
|
opts?.onClose?.(event);
|
|
152
226
|
const shouldReconnect = event.code !== 1e3 && opts?.autoReconnect;
|
|
153
227
|
if (shouldReconnect) {
|
|
154
|
-
console.log("[useFlowWebSocket] Will attempt reconnection (code:", event.code, ")");
|
|
155
228
|
attemptReconnect();
|
|
156
229
|
} else {
|
|
157
230
|
isServerRestarting = false;
|
|
158
231
|
}
|
|
159
232
|
};
|
|
160
233
|
};
|
|
161
|
-
const
|
|
234
|
+
const connect = (opts) => {
|
|
162
235
|
if (import.meta.server || typeof WebSocket === "undefined") {
|
|
163
236
|
console.warn("[useFlowWebSocket] WebSocket not available (SSR context)");
|
|
164
237
|
return;
|
|
165
238
|
}
|
|
166
|
-
if (
|
|
167
|
-
console.log("[useFlowWebSocket] Reusing connection, switching subscription");
|
|
168
|
-
if (currentSubscription) {
|
|
169
|
-
send({
|
|
170
|
-
type: "unsubscribe",
|
|
171
|
-
flowName: currentSubscription.flowName,
|
|
172
|
-
runId: currentSubscription.runId
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
currentSubscription = subscription;
|
|
176
|
-
send({
|
|
177
|
-
type: "subscribe",
|
|
178
|
-
flowName: subscription.flowName,
|
|
179
|
-
runId: subscription.runId
|
|
180
|
-
});
|
|
239
|
+
if (sharedWs && (sharedWs.readyState === WebSocket.OPEN || sharedWs.readyState === WebSocket.CONNECTING)) {
|
|
181
240
|
return;
|
|
182
241
|
}
|
|
183
|
-
if (
|
|
184
|
-
|
|
242
|
+
if (sharedWs) {
|
|
243
|
+
try {
|
|
244
|
+
sharedWs.close();
|
|
245
|
+
} catch {
|
|
246
|
+
}
|
|
185
247
|
}
|
|
186
248
|
currentOptions = opts;
|
|
187
|
-
currentSubscription = subscription;
|
|
188
249
|
try {
|
|
189
250
|
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
|
190
251
|
const wsUrl = `${protocol}//${window.location.host}/api/_flows/ws`;
|
|
191
252
|
const socket = new WebSocket(wsUrl);
|
|
192
|
-
|
|
193
|
-
|
|
253
|
+
sharedWs = socket;
|
|
254
|
+
updateRefs();
|
|
255
|
+
setupWebSocket(socket, opts);
|
|
194
256
|
} catch (err) {
|
|
195
257
|
console.error("[useFlowWebSocket] Error creating WebSocket:", err);
|
|
196
258
|
opts?.onError?.(err);
|
|
@@ -198,10 +260,26 @@ export function useFlowWebSocket() {
|
|
|
198
260
|
}
|
|
199
261
|
};
|
|
200
262
|
const subscribe = (subscription, opts) => {
|
|
201
|
-
|
|
263
|
+
if (currentSubscription && sharedWs && sharedWs.readyState === WebSocket.OPEN) {
|
|
264
|
+
send({
|
|
265
|
+
type: "unsubscribe",
|
|
266
|
+
flowName: currentSubscription.flowName,
|
|
267
|
+
runId: currentSubscription.runId
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
currentSubscription = subscription;
|
|
271
|
+
if (sharedWs && sharedWs.readyState === WebSocket.OPEN) {
|
|
272
|
+
send({
|
|
273
|
+
type: "subscribe",
|
|
274
|
+
flowName: subscription.flowName,
|
|
275
|
+
runId: subscription.runId
|
|
276
|
+
});
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
connect(opts);
|
|
202
280
|
};
|
|
203
281
|
const unsubscribe = () => {
|
|
204
|
-
if (currentSubscription &&
|
|
282
|
+
if (currentSubscription && sharedWs && sharedWs.readyState === WebSocket.OPEN) {
|
|
205
283
|
send({
|
|
206
284
|
type: "unsubscribe",
|
|
207
285
|
flowName: currentSubscription.flowName,
|
|
@@ -210,11 +288,49 @@ export function useFlowWebSocket() {
|
|
|
210
288
|
}
|
|
211
289
|
currentSubscription = null;
|
|
212
290
|
};
|
|
213
|
-
|
|
291
|
+
const subscribeStats = (subscription, opts) => {
|
|
292
|
+
currentStatsSubscription = subscription;
|
|
293
|
+
if (sharedWs && sharedWs.readyState === WebSocket.OPEN) {
|
|
294
|
+
if (isStatsSubscribed) {
|
|
295
|
+
if (subscription.onInitial && statsCache.length > 0) {
|
|
296
|
+
for (const cachedStat of statsCache) {
|
|
297
|
+
subscription.onInitial(cachedStat);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
send({
|
|
303
|
+
type: "subscribe.stats"
|
|
304
|
+
});
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (sharedWs && sharedWs.readyState === WebSocket.CONNECTING) {
|
|
308
|
+
pendingStatsSubscription = true;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
pendingStatsSubscription = true;
|
|
312
|
+
connect(opts);
|
|
313
|
+
};
|
|
314
|
+
const unsubscribeStats = () => {
|
|
315
|
+
if (currentStatsSubscription && sharedWs && sharedWs.readyState === WebSocket.OPEN) {
|
|
316
|
+
send({
|
|
317
|
+
type: "unsubscribe.stats"
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
currentStatsSubscription = null;
|
|
321
|
+
isStatsSubscribed = false;
|
|
322
|
+
};
|
|
323
|
+
onBeforeUnmount(() => {
|
|
324
|
+
stop();
|
|
325
|
+
});
|
|
214
326
|
return {
|
|
215
327
|
subscribe,
|
|
216
328
|
unsubscribe,
|
|
329
|
+
subscribeStats,
|
|
330
|
+
unsubscribeStats,
|
|
217
331
|
stop,
|
|
332
|
+
forceClose,
|
|
333
|
+
// Exposed for debugging/manual cleanup
|
|
218
334
|
connected,
|
|
219
335
|
reconnecting
|
|
220
336
|
};
|
|
@@ -13,12 +13,23 @@ export interface Job {
|
|
|
13
13
|
}
|
|
14
14
|
export interface JobsResponse {
|
|
15
15
|
jobs: Job[];
|
|
16
|
+
count: number;
|
|
17
|
+
total: number;
|
|
18
|
+
hasMore: boolean;
|
|
16
19
|
}
|
|
17
20
|
/**
|
|
18
21
|
* Composable for fetching jobs for a queue
|
|
19
22
|
* Client-only to avoid hydration mismatches
|
|
20
23
|
*/
|
|
21
|
-
export declare function useQueueJobs(queueName: Ref<string>,
|
|
24
|
+
export declare function useQueueJobs(queueName: Ref<string>, options?: Ref<{
|
|
25
|
+
state?: string | null;
|
|
26
|
+
limit?: number;
|
|
27
|
+
offset?: number;
|
|
28
|
+
}> | {
|
|
29
|
+
state?: string | null;
|
|
30
|
+
limit?: number;
|
|
31
|
+
offset?: number;
|
|
32
|
+
}): {
|
|
22
33
|
data: Ref<JobsResponse | null | undefined>;
|
|
23
34
|
refresh: () => Promise<void>;
|
|
24
35
|
status: Ref<'idle' | 'pending' | 'success' | 'error'>;
|
|
@@ -1,20 +1,26 @@
|
|
|
1
|
-
import { ref, useFetch } from "#imports";
|
|
2
|
-
export function useQueueJobs(queueName,
|
|
1
|
+
import { ref, useFetch, isRef } from "#imports";
|
|
2
|
+
export function useQueueJobs(queueName, options) {
|
|
3
|
+
const opts = isRef(options) ? options : ref(options || {});
|
|
3
4
|
return useFetch(
|
|
4
5
|
() => {
|
|
5
6
|
const params = new URLSearchParams();
|
|
6
|
-
if (
|
|
7
|
-
params.append("state",
|
|
7
|
+
if (opts.value.state) {
|
|
8
|
+
params.append("state", opts.value.state);
|
|
9
|
+
}
|
|
10
|
+
if (opts.value.limit) {
|
|
11
|
+
params.append("limit", opts.value.limit.toString());
|
|
12
|
+
}
|
|
13
|
+
if (opts.value.offset) {
|
|
14
|
+
params.append("offset", opts.value.offset.toString());
|
|
8
15
|
}
|
|
9
16
|
const queryString = params.toString();
|
|
10
17
|
return `/api/_queues/${encodeURIComponent(queueName.value)}/job${queryString ? `?${queryString}` : ""}`;
|
|
11
18
|
},
|
|
12
19
|
{
|
|
13
|
-
key: () => `queue-jobs-${queueName.value}-${
|
|
14
|
-
watch:
|
|
20
|
+
key: () => `queue-jobs-${queueName.value}-${opts.value.state || "all"}-${opts.value.offset || 0}`,
|
|
21
|
+
watch: false,
|
|
15
22
|
immediate: true,
|
|
16
23
|
server: false
|
|
17
|
-
// Client-only
|
|
18
24
|
}
|
|
19
25
|
);
|
|
20
26
|
}
|