bunqueue-dashboard 0.0.34 → 0.0.35
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/README.md +2 -2
- package/agent/manager.ts +3 -3
- package/agent/server.ts +72 -0
- package/agent/workflows.ts +491 -0
- package/dist/.vite/manifest.json +93 -81
- package/dist/assets/AddJob-CG28MSxU.js +3 -0
- package/dist/assets/{Alerts-Dp4Vclez.js → Alerts-D9JojJrj.js} +1 -1
- package/dist/assets/{Benchmark-X_gdZun5.js → Benchmark-BVjUH9dG.js} +1 -1
- package/dist/assets/{BulkAddJobs-CXTpYMZf.js → BulkAddJobs-BHzUCMj_.js} +1 -1
- package/dist/assets/{CopilotPanel-CIXpcwkH.js → CopilotPanel-COLw-atS.js} +1 -1
- package/dist/assets/{Cron-DUHkse77.js → Cron-DoEHDHwy.js} +1 -1
- package/dist/assets/CronManager-vulcesqJ.js +1 -0
- package/dist/assets/{Database-CXPb3XGr.js → Database-DlB_t04Z.js} +1 -1
- package/dist/assets/{Diagnostics-DDtoiDYT.js → Diagnostics-DddCUgeR.js} +1 -1
- package/dist/assets/{Dlq-CX_uRblW.js → Dlq-DMKrsSMP.js} +1 -1
- package/dist/assets/{DlqControl-CazFmSEd.js → DlqControl-9m0Re_TH.js} +1 -1
- package/dist/assets/{DlqPro-HSffdtLJ.js → DlqPro-Dmw-0wta.js} +1 -1
- package/dist/assets/{Flows-CGmyghKF.js → Flows-C3-9nXW4.js} +1 -1
- package/dist/assets/JobInspector-DwIfABmI.js +2 -0
- package/dist/assets/{Jobs-BZGtMnJI.js → Jobs-j8tTS3NC.js} +1 -1
- package/dist/assets/JobsPro-CS__CJJl.js +1 -0
- package/dist/assets/{Logs-DxUD9V2A.js → Logs-BB-VDPA1.js} +1 -1
- package/dist/assets/{LogsPro-BTQhvPKj.js → LogsPro-RNtSQZRT.js} +1 -1
- package/dist/assets/{McpServer-D5rwBg74.js → McpServer-CbaU52l2.js} +2 -2
- package/dist/assets/{Metrics-CSPpBf1m.js → Metrics-ivcddPwT.js} +1 -1
- package/dist/assets/{MetricsPro-DSn-3qNT.js → MetricsPro-xjZno4vg.js} +1 -1
- package/dist/assets/{Overview-StvHYRZ5.js → Overview-D84aD2ph.js} +1 -1
- package/dist/assets/{Pagination-eotgGQf9.js → Pagination-Bfi4vkpp.js} +1 -1
- package/dist/assets/{QueueActions-CibRLzrz.js → QueueActions-DTbD6uek.js} +1 -1
- package/dist/assets/{QueueControl-DwYNcMfI.js → QueueControl-B5xK_SQ-.js} +1 -1
- package/dist/assets/{QueueDetail-NMfKwj6E.js → QueueDetail-BH59kwm9.js} +1 -1
- package/dist/assets/{QueueDetailPro-C8SBjX09.js → QueueDetailPro-DoN25ndy.js} +1 -1
- package/dist/assets/{Queues-BeTAi8V8.js → Queues-CKMJqFHX.js} +1 -1
- package/dist/assets/{QueuesOverview-BfQO8NS4.js → QueuesOverview-BX1lzojl.js} +1 -1
- package/dist/assets/{S3Backup-BYkAtONl.js → S3Backup-Bz3GfoZ9.js} +1 -1
- package/dist/assets/{S3BackupPro-BP1Ch54R.js → S3BackupPro-BC_6-uX-.js} +1 -1
- package/dist/assets/{ServerControl-C85jYgyN.js → ServerControl-CSSrN8G5.js} +2 -2
- package/dist/assets/{Settings-DjP28c_5.js → Settings-DkqmZUIS.js} +1 -1
- package/dist/assets/{Usage-DECeEsO2.js → Usage-Ba20p0xd.js} +1 -1
- package/dist/assets/{UsagePro-CD7dgt3d.js → UsagePro-C2pQwjN9.js} +1 -1
- package/dist/assets/{Webhooks-Ct-x8DD1.js → Webhooks-CVuuvb0L.js} +1 -1
- package/dist/assets/{Workers-lP1BXHFq.js → Workers-C1wPU6CS.js} +1 -1
- package/dist/assets/{WorkersPro-CAUqy3Cp.js → WorkersPro-B0vEkC0T.js} +1 -1
- package/dist/assets/Workflows-C8Qmkflf.js +1 -0
- package/dist/assets/{flowMutationSafety-DVD1IMr-.js → flowMutationSafety-CoOp94wS.js} +1 -1
- package/dist/assets/index-BCNzbhhD.css +1 -0
- package/dist/assets/index-CAtsVmyh.js +8 -0
- package/dist/assets/install-D0eRLf9F.js +3 -0
- package/dist/assets/{upstreamPaths-nG8N1XAz.js → upstreamPaths-D_LPsv7b.js} +1 -1
- package/dist/assets/{useThroughputSeries-Bpyg6Jaq.js → useThroughputSeries-DjxGN8ob.js} +1 -1
- package/dist/index.html +3 -3
- package/package.json +4 -1
- package/scripts/embedded.gen.ts +124 -122
- package/dist/assets/AddJob-Cih9F84t.js +0 -3
- package/dist/assets/CronManager-BeYrLK2E.js +0 -1
- package/dist/assets/JobInspector-B9i1HnG5.js +0 -2
- package/dist/assets/JobsPro-tmEN8f-P.js +0 -1
- package/dist/assets/index-BWoUj86M.css +0 -1
- package/dist/assets/index-Dr__4DsT.js +0 -8
- package/dist/assets/install-DPCcfOYo.js +0 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bunqueue-dashboard",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Web dashboard for a bunqueue server (queues, jobs, DLQ, cron, metrics, workers, live activity). Run with `bunx bunqueue-dashboard` (requires Bun).",
|
|
6
6
|
"bin": {
|
|
@@ -101,5 +101,8 @@
|
|
|
101
101
|
"brace-expansion": "^5.0.9",
|
|
102
102
|
"dompurify": "^3.4.12",
|
|
103
103
|
"postcss": "^8.5.25"
|
|
104
|
+
},
|
|
105
|
+
"dependencies": {
|
|
106
|
+
"msgpackr": "^1.11.8"
|
|
104
107
|
}
|
|
105
108
|
}
|
package/scripts/embedded.gen.ts
CHANGED
|
@@ -4,134 +4,136 @@ import f0 from "../dist/og.png" with { type: 'file' };
|
|
|
4
4
|
import f1 from "../dist/.vite/manifest.json" with { type: 'file' };
|
|
5
5
|
import f2 from "../dist/index.html" with { type: 'file' };
|
|
6
6
|
import f3 from "../dist/favicon.svg" with { type: 'file' };
|
|
7
|
-
import f4 from "../dist/assets/
|
|
8
|
-
import f5 from "../dist/assets/
|
|
9
|
-
import f6 from "../dist/assets/
|
|
10
|
-
import f7 from "../dist/assets/
|
|
11
|
-
import f8 from "../dist/assets/
|
|
12
|
-
import f9 from "../dist/assets/
|
|
13
|
-
import f10 from "../dist/assets/
|
|
14
|
-
import f11 from "../dist/assets/
|
|
15
|
-
import f12 from "../dist/assets/
|
|
16
|
-
import f13 from "../dist/assets/
|
|
7
|
+
import f4 from "../dist/assets/QueueDetailPro-DoN25ndy.js" with { type: 'file' };
|
|
8
|
+
import f5 from "../dist/assets/BulkAddJobs-BHzUCMj_.js" with { type: 'file' };
|
|
9
|
+
import f6 from "../dist/assets/MetricsPro-xjZno4vg.js" with { type: 'file' };
|
|
10
|
+
import f7 from "../dist/assets/react-vendor-Bjui4wS4.js" with { type: 'file' };
|
|
11
|
+
import f8 from "../dist/assets/install-D0eRLf9F.js" with { type: 'file' };
|
|
12
|
+
import f9 from "../dist/assets/Usage-Ba20p0xd.js" with { type: 'file' };
|
|
13
|
+
import f10 from "../dist/assets/Queues-CKMJqFHX.js" with { type: 'file' };
|
|
14
|
+
import f11 from "../dist/assets/QueueDetail-BH59kwm9.js" with { type: 'file' };
|
|
15
|
+
import f12 from "../dist/assets/Overview-D84aD2ph.js" with { type: 'file' };
|
|
16
|
+
import f13 from "../dist/assets/Flows-C3-9nXW4.js" with { type: 'file' };
|
|
17
17
|
import f14 from "../dist/assets/dist-DjvZiKhB.js" with { type: 'file' };
|
|
18
|
-
import f15 from "../dist/assets/
|
|
19
|
-
import f16 from "../dist/assets/
|
|
20
|
-
import f17 from "../dist/assets/
|
|
21
|
-
import f18 from "../dist/assets/
|
|
22
|
-
import f19 from "../dist/assets/
|
|
23
|
-
import f20 from "../dist/assets/
|
|
24
|
-
import f21 from "../dist/assets/
|
|
25
|
-
import f22 from "../dist/assets/
|
|
26
|
-
import f23 from "../dist/assets/
|
|
27
|
-
import f24 from "../dist/assets/
|
|
28
|
-
import f25 from "../dist/assets/
|
|
29
|
-
import f26 from "../dist/assets/
|
|
30
|
-
import f27 from "../dist/assets/
|
|
31
|
-
import f28 from "../dist/assets/
|
|
32
|
-
import f29 from "../dist/assets/
|
|
33
|
-
import f30 from "../dist/assets/
|
|
34
|
-
import f31 from "../dist/assets/
|
|
35
|
-
import f32 from "../dist/assets/
|
|
36
|
-
import f33 from "../dist/assets/AddJob-
|
|
37
|
-
import f34 from "../dist/assets/
|
|
38
|
-
import f35 from "../dist/assets/
|
|
39
|
-
import f36 from "../dist/assets/
|
|
40
|
-
import f37 from "../dist/assets/
|
|
41
|
-
import f38 from "../dist/assets/
|
|
42
|
-
import f39 from "../dist/assets/
|
|
43
|
-
import f40 from "../dist/assets/
|
|
44
|
-
import f41 from "../dist/assets/
|
|
45
|
-
import f42 from "../dist/assets/index-
|
|
46
|
-
import f43 from "../dist/assets/
|
|
47
|
-
import f44 from "../dist/assets/
|
|
48
|
-
import f45 from "../dist/assets/
|
|
49
|
-
import f46 from "../dist/assets/
|
|
50
|
-
import f47 from "../dist/assets/
|
|
51
|
-
import f48 from "../dist/assets/
|
|
52
|
-
import f49 from "../dist/assets/
|
|
53
|
-
import f50 from "../dist/assets/
|
|
54
|
-
import f51 from "../dist/assets/
|
|
55
|
-
import f52 from "../dist/assets/dist-
|
|
56
|
-
import f53 from "../dist/assets/
|
|
57
|
-
import f54 from "../dist/assets/
|
|
58
|
-
import f55 from "../dist/assets/
|
|
59
|
-
import f56 from "../dist/assets/
|
|
60
|
-
import f57 from "../dist/assets/
|
|
61
|
-
import f58 from "../dist/assets/
|
|
62
|
-
import f59 from "../dist/assets/
|
|
63
|
-
import f60 from "../dist/assets/
|
|
64
|
-
import f61 from "../dist/assets/
|
|
65
|
-
import f62 from "../dist/assets/
|
|
66
|
-
import f63 from "../dist/assets/
|
|
67
|
-
import f64 from "../dist/assets/
|
|
68
|
-
import f65 from "../dist/assets/
|
|
18
|
+
import f15 from "../dist/assets/Metrics-ivcddPwT.js" with { type: 'file' };
|
|
19
|
+
import f16 from "../dist/assets/flowMutationSafety-CoOp94wS.js" with { type: 'file' };
|
|
20
|
+
import f17 from "../dist/assets/McpServer-CbaU52l2.js" with { type: 'file' };
|
|
21
|
+
import f18 from "../dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2" with { type: 'file' };
|
|
22
|
+
import f19 from "../dist/assets/QueuesOverview-BX1lzojl.js" with { type: 'file' };
|
|
23
|
+
import f20 from "../dist/assets/LogsPro-RNtSQZRT.js" with { type: 'file' };
|
|
24
|
+
import f21 from "../dist/assets/Diagnostics-DddCUgeR.js" with { type: 'file' };
|
|
25
|
+
import f22 from "../dist/assets/QueueControl-B5xK_SQ-.js" with { type: 'file' };
|
|
26
|
+
import f23 from "../dist/assets/useThroughputSeries-DjxGN8ob.js" with { type: 'file' };
|
|
27
|
+
import f24 from "../dist/assets/S3BackupPro-BC_6-uX-.js" with { type: 'file' };
|
|
28
|
+
import f25 from "../dist/assets/CopilotPanel-COLw-atS.js" with { type: 'file' };
|
|
29
|
+
import f26 from "../dist/assets/Jobs-j8tTS3NC.js" with { type: 'file' };
|
|
30
|
+
import f27 from "../dist/assets/QueueActions-DTbD6uek.js" with { type: 'file' };
|
|
31
|
+
import f28 from "../dist/assets/Settings-DkqmZUIS.js" with { type: 'file' };
|
|
32
|
+
import f29 from "../dist/assets/DlqControl-9m0Re_TH.js" with { type: 'file' };
|
|
33
|
+
import f30 from "../dist/assets/AreaChart-REK4ZsTC.js" with { type: 'file' };
|
|
34
|
+
import f31 from "../dist/assets/Dlq-DMKrsSMP.js" with { type: 'file' };
|
|
35
|
+
import f32 from "../dist/assets/Workflows-C8Qmkflf.js" with { type: 'file' };
|
|
36
|
+
import f33 from "../dist/assets/AddJob-CG28MSxU.js" with { type: 'file' };
|
|
37
|
+
import f34 from "../dist/assets/exportFile-C7xhE8Yh.js" with { type: 'file' };
|
|
38
|
+
import f35 from "../dist/assets/Cron-DoEHDHwy.js" with { type: 'file' };
|
|
39
|
+
import f36 from "../dist/assets/DlqPro-Dmw-0wta.js" with { type: 'file' };
|
|
40
|
+
import f37 from "../dist/assets/dist-DZL8soAh.js" with { type: 'file' };
|
|
41
|
+
import f38 from "../dist/assets/cn-CMFYpumL.js" with { type: 'file' };
|
|
42
|
+
import f39 from "../dist/assets/ServerControl-CSSrN8G5.js" with { type: 'file' };
|
|
43
|
+
import f40 from "../dist/assets/form-DsUq0w8s.js" with { type: 'file' };
|
|
44
|
+
import f41 from "../dist/assets/Database-DlB_t04Z.js" with { type: 'file' };
|
|
45
|
+
import f42 from "../dist/assets/index-BCNzbhhD.css" with { type: 'file' };
|
|
46
|
+
import f43 from "../dist/assets/Webhooks-CVuuvb0L.js" with { type: 'file' };
|
|
47
|
+
import f44 from "../dist/assets/Logs-BB-VDPA1.js" with { type: 'file' };
|
|
48
|
+
import f45 from "../dist/assets/UsagePro-C2pQwjN9.js" with { type: 'file' };
|
|
49
|
+
import f46 from "../dist/assets/useServerActionGuard-CItj3hvh.js" with { type: 'file' };
|
|
50
|
+
import f47 from "../dist/assets/Benchmark-BVjUH9dG.js" with { type: 'file' };
|
|
51
|
+
import f48 from "../dist/assets/JobInspector-DwIfABmI.js" with { type: 'file' };
|
|
52
|
+
import f49 from "../dist/assets/dist-DpZcbP9W.js" with { type: 'file' };
|
|
53
|
+
import f50 from "../dist/assets/S3Backup-Bz3GfoZ9.js" with { type: 'file' };
|
|
54
|
+
import f51 from "../dist/assets/Alerts-D9JojJrj.js" with { type: 'file' };
|
|
55
|
+
import f52 from "../dist/assets/dist-BlWBaCN6.js" with { type: 'file' };
|
|
56
|
+
import f53 from "../dist/assets/jobActions-LQD4KfCc.js" with { type: 'file' };
|
|
57
|
+
import f54 from "../dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2" with { type: 'file' };
|
|
58
|
+
import f55 from "../dist/assets/CronManager-vulcesqJ.js" with { type: 'file' };
|
|
59
|
+
import f56 from "../dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2" with { type: 'file' };
|
|
60
|
+
import f57 from "../dist/assets/Workers-C1wPU6CS.js" with { type: 'file' };
|
|
61
|
+
import f58 from "../dist/assets/dist-1f1fMHVO.js" with { type: 'file' };
|
|
62
|
+
import f59 from "../dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2" with { type: 'file' };
|
|
63
|
+
import f60 from "../dist/assets/Pagination-Bfi4vkpp.js" with { type: 'file' };
|
|
64
|
+
import f61 from "../dist/assets/upstreamPaths-D_LPsv7b.js" with { type: 'file' };
|
|
65
|
+
import f62 from "../dist/assets/index-CAtsVmyh.js" with { type: 'file' };
|
|
66
|
+
import f63 from "../dist/assets/promisePool-BVfQ9n9Q.js" with { type: 'file' };
|
|
67
|
+
import f64 from "../dist/assets/connectionStore-Cd9-3Fw0.js" with { type: 'file' };
|
|
68
|
+
import f65 from "../dist/assets/WorkersPro-B0vEkC0T.js" with { type: 'file' };
|
|
69
|
+
import f66 from "../dist/assets/JobsPro-CS__CJJl.js" with { type: 'file' };
|
|
69
70
|
|
|
70
71
|
export const ASSETS: Record<string, string> = {
|
|
71
72
|
"/og.png": f0,
|
|
72
73
|
"/.vite/manifest.json": f1,
|
|
73
74
|
"/index.html": f2,
|
|
74
75
|
"/favicon.svg": f3,
|
|
75
|
-
"/assets/
|
|
76
|
-
"/assets/
|
|
77
|
-
"/assets/
|
|
78
|
-
"/assets/
|
|
79
|
-
"/assets/
|
|
80
|
-
"/assets/
|
|
81
|
-
"/assets/
|
|
82
|
-
"/assets/
|
|
83
|
-
"/assets/
|
|
84
|
-
"/assets/
|
|
76
|
+
"/assets/QueueDetailPro-DoN25ndy.js": f4,
|
|
77
|
+
"/assets/BulkAddJobs-BHzUCMj_.js": f5,
|
|
78
|
+
"/assets/MetricsPro-xjZno4vg.js": f6,
|
|
79
|
+
"/assets/react-vendor-Bjui4wS4.js": f7,
|
|
80
|
+
"/assets/install-D0eRLf9F.js": f8,
|
|
81
|
+
"/assets/Usage-Ba20p0xd.js": f9,
|
|
82
|
+
"/assets/Queues-CKMJqFHX.js": f10,
|
|
83
|
+
"/assets/QueueDetail-BH59kwm9.js": f11,
|
|
84
|
+
"/assets/Overview-D84aD2ph.js": f12,
|
|
85
|
+
"/assets/Flows-C3-9nXW4.js": f13,
|
|
85
86
|
"/assets/dist-DjvZiKhB.js": f14,
|
|
86
|
-
"/assets/
|
|
87
|
-
"/assets/
|
|
88
|
-
"/assets/
|
|
89
|
-
"/assets/
|
|
90
|
-
"/assets/
|
|
91
|
-
"/assets/
|
|
92
|
-
"/assets/
|
|
93
|
-
"/assets/
|
|
94
|
-
"/assets/
|
|
95
|
-
"/assets/
|
|
96
|
-
"/assets/
|
|
97
|
-
"/assets/
|
|
98
|
-
"/assets/
|
|
99
|
-
"/assets/
|
|
100
|
-
"/assets/
|
|
101
|
-
"/assets/
|
|
102
|
-
"/assets/
|
|
103
|
-
"/assets/
|
|
104
|
-
"/assets/AddJob-
|
|
105
|
-
"/assets/
|
|
106
|
-
"/assets/
|
|
107
|
-
"/assets/
|
|
108
|
-
"/assets/
|
|
109
|
-
"/assets/
|
|
110
|
-
"/assets/
|
|
111
|
-
"/assets/
|
|
112
|
-
"/assets/
|
|
113
|
-
"/assets/index-
|
|
114
|
-
"/assets/
|
|
115
|
-
"/assets/
|
|
116
|
-
"/assets/
|
|
117
|
-
"/assets/
|
|
118
|
-
"/assets/
|
|
119
|
-
"/assets/
|
|
120
|
-
"/assets/
|
|
121
|
-
"/assets/
|
|
122
|
-
"/assets/
|
|
123
|
-
"/assets/dist-
|
|
124
|
-
"/assets/
|
|
125
|
-
"/assets/
|
|
126
|
-
"/assets/
|
|
127
|
-
"/assets/
|
|
128
|
-
"/assets/
|
|
129
|
-
"/assets/
|
|
130
|
-
"/assets/
|
|
131
|
-
"/assets/
|
|
132
|
-
"/assets/
|
|
133
|
-
"/assets/
|
|
134
|
-
"/assets/
|
|
135
|
-
"/assets/
|
|
136
|
-
"/assets/
|
|
87
|
+
"/assets/Metrics-ivcddPwT.js": f15,
|
|
88
|
+
"/assets/flowMutationSafety-CoOp94wS.js": f16,
|
|
89
|
+
"/assets/McpServer-CbaU52l2.js": f17,
|
|
90
|
+
"/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2": f18,
|
|
91
|
+
"/assets/QueuesOverview-BX1lzojl.js": f19,
|
|
92
|
+
"/assets/LogsPro-RNtSQZRT.js": f20,
|
|
93
|
+
"/assets/Diagnostics-DddCUgeR.js": f21,
|
|
94
|
+
"/assets/QueueControl-B5xK_SQ-.js": f22,
|
|
95
|
+
"/assets/useThroughputSeries-DjxGN8ob.js": f23,
|
|
96
|
+
"/assets/S3BackupPro-BC_6-uX-.js": f24,
|
|
97
|
+
"/assets/CopilotPanel-COLw-atS.js": f25,
|
|
98
|
+
"/assets/Jobs-j8tTS3NC.js": f26,
|
|
99
|
+
"/assets/QueueActions-DTbD6uek.js": f27,
|
|
100
|
+
"/assets/Settings-DkqmZUIS.js": f28,
|
|
101
|
+
"/assets/DlqControl-9m0Re_TH.js": f29,
|
|
102
|
+
"/assets/AreaChart-REK4ZsTC.js": f30,
|
|
103
|
+
"/assets/Dlq-DMKrsSMP.js": f31,
|
|
104
|
+
"/assets/Workflows-C8Qmkflf.js": f32,
|
|
105
|
+
"/assets/AddJob-CG28MSxU.js": f33,
|
|
106
|
+
"/assets/exportFile-C7xhE8Yh.js": f34,
|
|
107
|
+
"/assets/Cron-DoEHDHwy.js": f35,
|
|
108
|
+
"/assets/DlqPro-Dmw-0wta.js": f36,
|
|
109
|
+
"/assets/dist-DZL8soAh.js": f37,
|
|
110
|
+
"/assets/cn-CMFYpumL.js": f38,
|
|
111
|
+
"/assets/ServerControl-CSSrN8G5.js": f39,
|
|
112
|
+
"/assets/form-DsUq0w8s.js": f40,
|
|
113
|
+
"/assets/Database-DlB_t04Z.js": f41,
|
|
114
|
+
"/assets/index-BCNzbhhD.css": f42,
|
|
115
|
+
"/assets/Webhooks-CVuuvb0L.js": f43,
|
|
116
|
+
"/assets/Logs-BB-VDPA1.js": f44,
|
|
117
|
+
"/assets/UsagePro-C2pQwjN9.js": f45,
|
|
118
|
+
"/assets/useServerActionGuard-CItj3hvh.js": f46,
|
|
119
|
+
"/assets/Benchmark-BVjUH9dG.js": f47,
|
|
120
|
+
"/assets/JobInspector-DwIfABmI.js": f48,
|
|
121
|
+
"/assets/dist-DpZcbP9W.js": f49,
|
|
122
|
+
"/assets/S3Backup-Bz3GfoZ9.js": f50,
|
|
123
|
+
"/assets/Alerts-D9JojJrj.js": f51,
|
|
124
|
+
"/assets/dist-BlWBaCN6.js": f52,
|
|
125
|
+
"/assets/jobActions-LQD4KfCc.js": f53,
|
|
126
|
+
"/assets/inter-latin-wght-normal-Dx4kXJAl.woff2": f54,
|
|
127
|
+
"/assets/CronManager-vulcesqJ.js": f55,
|
|
128
|
+
"/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2": f56,
|
|
129
|
+
"/assets/Workers-C1wPU6CS.js": f57,
|
|
130
|
+
"/assets/dist-1f1fMHVO.js": f58,
|
|
131
|
+
"/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2": f59,
|
|
132
|
+
"/assets/Pagination-Bfi4vkpp.js": f60,
|
|
133
|
+
"/assets/upstreamPaths-D_LPsv7b.js": f61,
|
|
134
|
+
"/assets/index-CAtsVmyh.js": f62,
|
|
135
|
+
"/assets/promisePool-BVfQ9n9Q.js": f63,
|
|
136
|
+
"/assets/connectionStore-Cd9-3Fw0.js": f64,
|
|
137
|
+
"/assets/WorkersPro-B0vEkC0T.js": f65,
|
|
138
|
+
"/assets/JobsPro-CS__CJJl.js": f66,
|
|
137
139
|
};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./cn-CMFYpumL.js";import{g as t,l as n,r,t as i}from"./react-vendor-Bjui4wS4.js";import{i as a,o}from"./upstreamPaths-nG8N1XAz.js";import{A as s,C as c,S as l,ct as ee,ft as u,h as d,st as f,w as p}from"./index-Dr__4DsT.js";import{a as m,n as h,o as g,t as _}from"./form-DsUq0w8s.js";import{r as te}from"./useServerActionGuard-CItj3hvh.js";var v=e(t(),1),y=i(),b=e=>e==null?``:String(e),x=365*24*60*60*1e3,S=1440*60*1e3,ne=10*1024*1024,C=10*1024*1024;function w(e,t=1/0){let n=0;for(let r=0;r<e.length;r++){let i=e.charCodeAt(r);if(i<=127?n+=1:i<=2047?n+=2:i>=55296&&i<=56319&&r+1<e.length&&e.charCodeAt(r+1)>=56320&&e.charCodeAt(r+1)<=57343?(n+=4,r+=1):n+=3,n>t)return n}return n}function T(e){return e.length>10485760||w(e,10485760)>10485760?`Job data is too large (maximum 10 MiB UTF-8 / 10,485,760 characters)`:null}function E(e){let t=T(e);if(t)return{ok:!1,kind:`size`,msg:t};let n;try{n=JSON.parse(e)}catch(e){return{ok:!1,kind:`json`,msg:`Invalid JSON: ${e.message}`}}let r=JSON.stringify(n);return r.length>10485760||w(r,10485760)>10485760?{ok:!1,kind:`size`,msg:`Job data is too large after JSON encoding (maximum 10 MiB UTF-8)`}:{ok:!0,data:n}}function re(e){let t=[{key:`priority`,label:`Priority`,min:-1e6,max:1e6,integer:!0},{key:`delay`,label:`Delay`,min:0,max:x,integer:!0},{key:`maxAttempts`,label:`Max attempts`,min:1,max:1e3,integer:!0},{key:`backoff`,label:`Backoff`,min:0,max:S,integer:!0},{key:`timeout`,label:`Timeout`,min:0,max:S,integer:!0},{key:`ttl`,label:`TTL`,min:0,max:x,integer:!0}],n={};for(let r of t){let t=(e[r.key]??``).trim();if(!t)continue;let i=Number(t);if(!Number.isFinite(i))return{ok:!1,msg:`${r.label} must be a number`};if(r.integer&&!Number.isSafeInteger(i))return{ok:!1,msg:`${r.label} must be a whole, safe integer`};if(i<r.min||i>r.max)return{ok:!1,msg:`${r.label} must be between ${r.min} and ${r.max}`};n[r.key]=i}return{ok:!0,options:n}}function D(e){let t=o(e);return!e&&t?`Choose a queue`:t}function ie(e,t){return e==null?t?{ok:!1,msg:`Backoff strategy needs a base delay in Backoff (ms)`}:{ok:!0,backoff:void 0}:{ok:!0,backoff:t?{type:t,delay:e}:e}}function ae(e,t){return{ok:!0,msg:`Accepted ${t} job submission${t===1?``:`s`}; server returned ${e} distinct job ID${e===1?``:`s`} (deduplication may reuse existing jobs)`}}function oe(e){if(typeof e!=`object`||!e||e.ok!==!0||typeof e.id!=`string`||!e.id||e.id.length>1024)throw Error(`Add job returned a malformed success response`);return e.id}function O(e,t){let n=e?.ids;if(typeof e!=`object`||!e||e.ok!==!0||!Array.isArray(n)||n.length!==t||n.some(e=>typeof e!=`string`||e.length===0||e.length>1024))throw Error(`Bulk add returned a malformed success response`);return n}function k(e){if(!e.trim())return{ok:!0,repeat:void 0};try{let t=JSON.parse(e);if(typeof t!=`object`||!t||Array.isArray(t))return{ok:!1,msg:`Repeat must be a JSON object`};let n=t,r=new Set([`every`,`limit`,`pattern`]),i=Object.keys(n).filter(e=>!r.has(e));if(i.length)return{ok:!1,msg:`Unknown repeat option${i.length===1?``:`s`}: ${i.join(`, `)}`};if(n.pattern!==void 0)return{ok:!1,msg:`repeat.pattern is unsafe in bunqueue v2.8.55; use repeat.every or a Cron schedule`};let a=n.every;return!Number.isSafeInteger(a)||a<=0||a>x?{ok:!1,msg:`Repeat "every" must be a whole number from 1 to ${x} ms`}:n.limit!==void 0&&(!Number.isSafeInteger(n.limit)||n.limit<1)?{ok:!1,msg:`Repeat "limit" must be a whole number of at least 1`}:{ok:!0,repeat:{every:a,...typeof n.limit==`number`?{limit:n.limit}:{}}}}catch(e){return{ok:!1,msg:`Repeat is not valid JSON: ${e.message}`}}}function se(e){let t=typeof e.backoff==`object`?e.backoff:void 0,n=e.backoffConfig??t;return{backoff:b(n?.delay??(typeof e.backoff==`number`?e.backoff:void 0)),backoffType:n?.type??``,tags:e.tags?.join(`, `)??``,groupId:e.groupId??``,ttl:b(e.ttl)}}function A(){let{data:e,error:t,refetch:i}=s(()=>f.queues(),[],{intervalMs:3e4}),o=n().state?.clone,g=o?.options??{},C=se(g),[w,T]=(0,v.useState)(o?.queue??``),[A,ce]=(0,v.useState)(o?.dataText??`{
|
|
2
|
-
"hello": "world"
|
|
3
|
-
}`),[le,ue]=(0,v.useState)(`1`),[de,fe]=(0,v.useState)(b(g.priority)),[M,pe]=(0,v.useState)(``),[N,me]=(0,v.useState)(``),[P,he]=(0,v.useState)(b(g.maxAttempts)),[F,ge]=(0,v.useState)(C.backoff),[I,_e]=(0,v.useState)(b(g.timeout)),[L,ve]=(0,v.useState)(C.ttl),[R,ye]=(0,v.useState)(``),[z,be]=(0,v.useState)(g.removeOnComplete??!1),[B,xe]=(0,v.useState)(g.removeOnFail??!1),[V,Se]=(0,v.useState)(!1),[H,Ce]=(0,v.useState)(!1),[U,we]=(0,v.useState)(C.backoffType),[W,Te]=(0,v.useState)(C.tags),[G,Ee]=(0,v.useState)(C.groupId),[K,De]=(0,v.useState)(``),[q,Oe]=(0,v.useState)(``),[J,ke]=(0,v.useState)(``),[Y,X]=(0,v.useState)(!1),[Z,Q]=(0,v.useState)(null),[Ae,$]=(0,v.useState)(null),je=te(`add-job`);(0,v.useEffect)(()=>{X(!1),Q(null),$(null)},[je.scopeKey]);let Me=async()=>{Q(null),$(null);let e=w.trim(),t=D(e);if(t){Q({ok:!1,msg:t});return}let n=E(A);if(!n.ok){n.kind===`json`?$(n.msg):Q({ok:!1,msg:n.msg});return}let r=n.data,i=re({priority:de,delay:N.trim()?``:M,maxAttempts:P,backoff:F,timeout:I,ttl:L});if(!i.ok){Q({ok:!1,msg:i.msg});return}let o=i.options.delay;if(N.trim()){let e=new Date(N).getTime();if(!Number.isFinite(e)){Q({ok:!1,msg:`Run at is not a valid date/time`});return}if(o=Math.max(0,e-Date.now()),o>x){Q({ok:!1,msg:`Run at must be within the next 365 days`});return}}let s=ie(i.options.backoff,U);if(!s.ok){Q({ok:!1,msg:s.msg});return}let c=s.backoff,l=W.split(`,`).map(e=>e.trim()).filter(Boolean),d=K.split(`,`).map(e=>e.trim()).filter(Boolean),p=R.trim();if(p){let e=a(p);if(e){Q({ok:!1,msg:`Job ID: ${e}`});return}}for(let e of d){let t=a(e);if(t){Q({ok:!1,msg:`Dependency ID "${e}": ${t}`});return}}let m=k(J);if(!m.ok){Q({ok:!1,msg:m.msg});return}let h={data:r,priority:i.options.priority,delay:o,maxAttempts:i.options.maxAttempts,backoff:c,timeout:i.options.timeout,ttl:i.options.ttl,jobId:p||void 0,removeOnComplete:z||void 0,removeOnFail:B||void 0,durable:V||void 0,lifo:H||void 0,tags:l.length?l:void 0,groupId:G.trim()||void 0,dependsOn:d.length?d:void 0,uniqueKey:q.trim()||void 0,repeat:m.repeat},g=Number(le);if(!Number.isSafeInteger(g)||g<1||g>1e4){Q({ok:!1,msg:`Count must be a whole number from 1 to 10000`});return}let _=je.begin();if(_){X(!0);try{if(g===1){let t=oe(await f.addJob(e,h));if(!_.isCurrent())return;Q({ok:!0,msg:`Accepted job ID ${t} (it may be an existing deduplicated job)`}),u.success(`Job submission accepted`,`${e} · ${t}`)}else{let t=Array.from({length:g},()=>h),n=ee(t);if(n){_.isCurrent()&&Q({ok:!1,msg:n});return}let r=O(await f.addJobsBulk(e,t),g);if(!_.isCurrent())return;let i=ae(new Set(r).size,g);Q(i),u.success(i.msg,`in ${e}`)}}catch(e){if(!_.isCurrent())return;Q({ok:!1,msg:e.message}),u.error(`Add job failed`,e.message)}finally{_.finish()&&X(!1)}}};return(0,y.jsxs)(`div`,{children:[(0,y.jsx)(d,{title:`Add Job`,description:`Enqueue a job with full options.`,actions:(0,y.jsx)(r,{to:`/jobs/bulk-add`,className:`rounded-lg border border-line px-3 py-1.5 text-sm text-muted hover:bg-surface-2 hover:text-fg`,children:`Bulk import`})}),o&&(0,y.jsx)(`div`,{className:`mb-4 flex items-center gap-2 rounded-lg border border-accent/30 bg-accent/[0.06] px-4 py-2 text-sm text-accent`,children:`Pre-filled from an existing job. Review the data and options, then enqueue a fresh job.`}),(0,y.jsxs)(`form`,{className:`grid grid-cols-1 gap-6 lg:grid-cols-2`,onSubmit:e=>{e.preventDefault(),Me()},children:[(0,y.jsxs)(l,{children:[(0,y.jsx)(c,{title:`Job`}),(0,y.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,y.jsxs)(_,{label:`Queue`,children:[(0,y.jsx)(h,{list:`queue-options`,"aria-label":`Queue`,name:`target-queue`,autoComplete:`off`,value:w,onChange:e=>T(e.target.value),placeholder:`queue name (existing or new)`}),(0,y.jsx)(`datalist`,{id:`queue-options`,children:(e?.queues??[]).map(e=>(0,y.jsx)(`option`,{value:e.name},e.name))})]}),t&&(0,y.jsxs)(`p`,{role:`status`,className:`-mt-2 text-xs text-warning`,children:[`Existing queue suggestions unavailable — `,t.message,`. You can still enter a queue name manually.`,` `,(0,y.jsx)(`button`,{type:`button`,onClick:()=>void i(),className:`font-medium underline underline-offset-2 hover:text-fg`,children:`Retry`})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(_,{label:`Data (JSON)`,children:(0,y.jsx)(`textarea`,{name:`job-data`,value:A,onChange:e=>ce(e.target.value),onBlur:()=>{let e=E(A);$(e.ok?null:e.msg)},maxLength:ne,spellCheck:!1,rows:7,className:`w-full rounded-lg border border-line bg-surface-2 p-3 font-mono text-sm text-fg focus:border-accent/60 focus:outline-none focus:ring-2 focus:ring-accent/30`})}),Ae&&(0,y.jsx)(`p`,{role:`alert`,className:`mt-2 text-xs text-danger`,children:Ae})]})]})]}),(0,y.jsxs)(l,{children:[(0,y.jsx)(c,{title:`Options`}),(0,y.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 md:grid-cols-3`,children:[(0,y.jsx)(_,{label:`Priority`,children:(0,y.jsx)(h,{type:`number`,min:-1e6,max:1e6,step:1,name:`priority`,value:de,onChange:e=>fe(e.target.value),placeholder:`0`})}),(0,y.jsx)(_,{label:`Delay (ms)`,children:(0,y.jsx)(h,{type:`number`,min:0,max:x,step:1,name:`delay`,value:M,onChange:e=>pe(e.target.value),placeholder:`0`,disabled:N.trim()!==``})}),(0,y.jsx)(_,{label:`Run at`,hint:N.trim()?`Overrides Delay — derived from this time (local time).`:`(local time)`,children:(0,y.jsx)(h,{type:`datetime-local`,name:`run-at`,value:N,onChange:e=>me(e.target.value)})}),(0,y.jsx)(_,{label:`Max attempts`,hint:`blank = server default`,children:(0,y.jsx)(h,{type:`number`,min:1,max:1e3,step:1,name:`max-attempts`,value:P,onChange:e=>he(e.target.value),placeholder:`3`})}),(0,y.jsx)(_,{label:`Backoff (ms)`,hint:`blank = server default`,children:(0,y.jsx)(h,{type:`number`,min:0,max:S,step:1,name:`backoff`,value:F,onChange:e=>ge(e.target.value),placeholder:`1000`})}),(0,y.jsx)(_,{label:`Backoff strategy`,hint:`flat delay unless set`,children:(0,y.jsxs)(m,{name:`backoff-strategy`,value:U,onChange:e=>we(e.target.value),children:[(0,y.jsx)(`option`,{value:``,children:`flat`}),(0,y.jsx)(`option`,{value:`fixed`,children:`fixed`}),(0,y.jsx)(`option`,{value:`exponential`,children:`exponential`})]})}),(0,y.jsx)(_,{label:`Timeout (ms)`,children:(0,y.jsx)(h,{type:`number`,min:0,max:S,step:1,name:`timeout`,value:I,onChange:e=>_e(e.target.value),placeholder:`—`})}),(0,y.jsx)(_,{label:`TTL (ms)`,hint:`blank = no expiry`,children:(0,y.jsx)(h,{type:`number`,min:0,max:x,step:1,name:`ttl`,value:L,onChange:e=>ve(e.target.value),placeholder:`—`})}),(0,y.jsx)(_,{label:`Custom job ID`,children:(0,y.jsx)(h,{name:`custom-job-id`,value:R,onChange:e=>ye(e.target.value),placeholder:`idempotency key`})})]}),(0,y.jsxs)(`div`,{className:`mt-4 flex flex-wrap gap-6`,children:[(0,y.jsx)(j,{label:`removeOnComplete`,checked:z,onChange:be}),(0,y.jsx)(j,{label:`removeOnFail`,checked:B,onChange:xe}),(0,y.jsx)(j,{label:`durable`,checked:V,onChange:Se}),(0,y.jsx)(j,{label:`lifo`,checked:H,onChange:Ce})]}),(0,y.jsxs)(`div`,{className:`mt-4 border-t border-line pt-4`,children:[(0,y.jsx)(`div`,{className:`mb-3 text-[11px] uppercase tracking-wider text-faint`,children:`Advanced`}),(0,y.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 md:grid-cols-3`,children:[(0,y.jsx)(_,{label:`Tags`,hint:`comma-separated`,children:(0,y.jsx)(h,{name:`tags`,value:W,onChange:e=>Te(e.target.value),placeholder:`email, urgent`})}),(0,y.jsx)(_,{label:`Group ID`,children:(0,y.jsx)(h,{name:`group-id`,value:G,onChange:e=>Ee(e.target.value),placeholder:`—`})}),(0,y.jsx)(_,{label:`Unique key`,hint:`dedup key`,children:(0,y.jsx)(h,{name:`unique-key`,value:q,onChange:e=>Oe(e.target.value),placeholder:`—`})}),(0,y.jsx)(_,{label:`Depends on`,hint:`parent job ids, comma-separated`,children:(0,y.jsx)(h,{name:`depends-on`,value:K,onChange:e=>De(e.target.value),placeholder:`job-id-1, job-id-2`})}),(0,y.jsx)(`div`,{className:`col-span-2 md:col-span-3`,children:(0,y.jsx)(_,{label:`Repeat policy (JSON)`,hint:`v2.8.55-safe form: e.g. {"every":60000,"limit":10}. Use Cron Manager for cron patterns.`,children:(0,y.jsx)(`textarea`,{name:`repeat-policy`,value:J,onChange:e=>ke(e.target.value),rows:2,spellCheck:!1,placeholder:`{"every": 60000}`,className:`w-full rounded-lg border border-line bg-surface-2 px-3 py-2 font-mono text-xs text-fg placeholder:text-faint focus:border-accent/60 focus:outline-none focus:ring-2 focus:ring-accent/30`})})})]})]})]}),(0,y.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3 lg:col-span-2`,children:[(0,y.jsx)(`div`,{className:`w-28`,children:(0,y.jsx)(_,{label:`Count`,hint:`1–10000`,children:(0,y.jsx)(h,{type:`number`,min:1,max:1e4,step:1,name:`count`,value:le,onChange:e=>ue(e.target.value)})})}),(0,y.jsx)(p,{type:`submit`,variant:`accent`,disabled:Y,children:Y?`Adding…`:`Add job`}),Z&&(0,y.jsx)(`span`,{role:Z.ok?`status`:`alert`,className:Z.ok?`text-sm text-success`:`text-sm text-danger`,children:Z.msg})]})]})]})}function j({label:e,checked:t,onChange:n}){return(0,y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,y.jsx)(g,{checked:t,onChange:n,label:e}),(0,y.jsx)(`span`,{className:`font-mono text-xs text-muted`,children:e})]})}export{A as AddJob,C as MAX_JOB_DATA_BYTES,ne as MAX_JOB_DATA_CHARS,O as acceptedBulkIds,E as parseJobData,k as parseRepeat,D as queueNameError,w as utf8ByteLength};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e,t}from"./cn-CMFYpumL.js";import{g as n,t as r}from"./react-vendor-Bjui4wS4.js";import{t as i}from"./upstreamPaths-nG8N1XAz.js";import{A as a,C as o,L as s,S as c,T as l,Y as u,a as d,b as f,c as p,ft as m,h,st as g,v as _,w as v,x as y,y as b}from"./index-Dr__4DsT.js";import{i as x,n as S,o as C,t as w}from"./form-DsUq0w8s.js";import{t as T}from"./Pagination-eotgGQf9.js";import{r as ee}from"./useServerActionGuard-CItj3hvh.js";import{MAX_JOB_DATA_CHARS as te,parseJobData as E,queueNameError as D}from"./AddJob-Cih9F84t.js";var O=e(n(),1),k=[``,`jan`,`feb`,`mar`,`apr`,`may`,`jun`,`jul`,`aug`,`sep`,`oct`,`nov`,`dec`],ne=[`sun`,`mon`,`tue`,`wed`,`thu`,`fri`,`sat`];function A(e,t,n,r){let i=e===`*`||/^\*\/\d+$/.test(e),a=new Set;for(let i of e.split(`,`)){let e=i.trim().toLowerCase();if(e===``)return null;let o=e.match(/^(.+)\/(\d+)$/),s=o?Number(o[2]):1,c=o?o[1]:e;if(s<1)return null;let l,u;if(c===`*`)l=t,u=n;else if(c.includes(`-`)){let[e,t]=c.split(`-`),n=j(e,r),i=j(t,r);if(n==null||i==null)return null;l=n,u=i}else{let e=j(c,r);if(e==null)return null;l=e,u=o?n:e}if(l<t||u>n||l>u)return null;for(let e=l;e<=u;e+=s)a.add(e)}return a.size?{values:a,star:i}:null}function j(e,t){let n=e.trim().toLowerCase();if(n===``)return null;if(t){let e=t.indexOf(n.slice(0,3));if(e!==-1)return e}return/^\d+$/.test(n)?Number(n):null}function re(e,t,n){let r=e.trim().split(/\s+/);if(r.length!==5)return{valid:!1,error:`Expected 5 fields (min hour day month weekday), got ${r.length}.`,runs:[]};let i=A(r[0],0,59),a=A(r[1],0,23),o=A(r[2],1,31),s=A(r[3],1,12,k),c=A(r[4],0,7,ne);if(!i||!a||!o||!s||!c)return{valid:!1,error:`Invalid field syntax.`,runs:[]};let l=new Set;for(let e of c.values)l.add(e===7?0:e);let u={values:l,star:c.star},d=e=>{let t=o.values.has(e.getDate()),n=u.values.has(e.getDay());return o.star||u.star?t&&n:t||n},f=[],p=new Date(n);p.setSeconds(0,0),p.setMinutes(p.getMinutes()+1);let m=n+5*366*864e5;for(let e=0;e<22e5&&f.length<t&&!(p.getTime()>m);e++){if(!s.values.has(p.getMonth()+1)){p.setMonth(p.getMonth()+1,1),p.setHours(0,0,0,0);continue}if(!d(p)){p.setDate(p.getDate()+1),p.setHours(0,0,0,0);continue}if(!a.values.has(p.getHours())){p.setHours(p.getHours()+1,0,0,0);continue}if(!i.values.has(p.getMinutes())){p.setMinutes(p.getMinutes()+1,0,0);continue}f.push(p.getTime()),p.setMinutes(p.getMinutes()+1,0,0)}return{valid:!0,runs:f}}var M=r(),N=365*24*60*60*1e3,P=1440*60*1e3;function F(e){let[t,n]=(0,O.useState)(0);return(0,O.useEffect)(()=>{t>e-1&&n(e-1)},[t,e]),[Math.min(t,e-1),n]}function ie(e){let[t,n]=(0,O.useState)(!1),r=(0,O.useRef)(null),i=()=>{r.current&&clearTimeout(r.current),r.current=null};return(0,O.useEffect)(()=>()=>{r.current&&clearTimeout(r.current)},[]),{on:t,fire:()=>{i(),n(!0),r.current=setTimeout(()=>n(!1),e)},reset:()=>{i(),n(!1)}}}function I(){let{data:e,error:t,loading:n,refetch:r}=a(()=>g.crons(),[]),i=e?.crons??[],v=(0,O.useMemo)(()=>new Set(i.map(e=>e.name)),[i]),[x,S]=F(Math.max(1,Math.ceil(i.length/15))),[C,w]=(0,O.useState)(null),[te,E]=(0,O.useState)(new Set),D=ee(`cron-manager`);(0,O.useEffect)(()=>{w(null),E(new Set)},[D.scopeKey]);let k=async e=>{if(!window.confirm(`Delete cron "${e}"? It will not be recreated automatically; creating a replacement is a separate action.`))return;let t=D.begin(`cron:${e}`);if(t){w(null),E(t=>new Set(t).add(e));try{if(L(await g.deleteCron(e)),!t.isCurrent())return;m.success(`Cron deleted`,e),r()}catch(e){if(!t.isCurrent())return;w(e.message),m.error(`Delete cron failed`,e.message)}finally{t.finish()&&E(t=>{let n=new Set(t);return n.delete(e),n})}}};return(0,M.jsxs)(`div`,{children:[t&&e&&(0,M.jsx)(y,{message:`Cron refresh failed — showing the last successful schedule list.`,onRetry:r}),(0,M.jsx)(h,{title:`Cron Manager`,description:`Submit explicitly acknowledged schedule upserts and manage repeatable jobs.`,live:!!e&&!t}),C&&(0,M.jsx)(`div`,{role:`status`,className:`mb-4 rounded-lg border border-red-500/20 bg-red-500/5 px-4 py-2 text-sm text-danger`,children:C}),(0,M.jsxs)(c,{className:`mb-6`,children:[(0,M.jsx)(o,{title:`Create schedule via upstream upsert`}),(0,M.jsx)(H,{existingNames:v,onCreate:async(e,t)=>{let n=await g.crons();if(!t())throw Error(`Cron creation target changed during preflight`);return z(n,e.name),g.createCron(e)},onAccepted:r,beginCreate:e=>D.begin(`cron:${e}`),scopeKey:D.scopeKey})]}),t&&!e?(0,M.jsx)(b,{error:t,onRetry:r}):n&&!e?(0,M.jsx)(f,{label:`Loading crons…`}):i.length===0?(0,M.jsx)(_,{icon:(0,M.jsx)(s,{}),title:`No scheduled jobs`,hint:`Submit one above.`}):(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(`div`,{className:`overflow-x-auto rounded-xl border border-line bg-surface`,children:(0,M.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,M.jsx)(`thead`,{children:(0,M.jsxs)(`tr`,{className:`border-b border-line text-left text-[11px] uppercase tracking-wider text-faint`,children:[(0,M.jsx)(`th`,{scope:`col`,className:`px-5 py-3 font-medium`,children:`Name`}),(0,M.jsx)(`th`,{scope:`col`,className:`px-5 py-3 font-medium`,children:`Queue`}),(0,M.jsx)(`th`,{scope:`col`,className:`px-5 py-3 font-medium`,children:`Schedule`}),(0,M.jsx)(`th`,{scope:`col`,className:`px-5 py-3 font-medium`,children:`Next Run`}),(0,M.jsx)(`th`,{scope:`col`,className:`px-5 py-3 text-right font-medium`,children:`Runs`}),(0,M.jsx)(`th`,{scope:`col`,className:`w-12 px-5 py-3`})]})}),(0,M.jsx)(`tbody`,{children:i.slice(x*15,x*15+15).map(e=>(0,M.jsxs)(`tr`,{className:`border-b border-line last:border-0 hover:bg-surface-2/40`,children:[(0,M.jsx)(`td`,{className:`px-5 py-3 font-medium text-fg`,children:e.name}),(0,M.jsx)(`td`,{className:`px-5 py-3 font-mono text-xs text-muted`,children:e.queue}),(0,M.jsx)(`td`,{className:`px-5 py-3 font-mono text-xs text-muted`,children:e.schedule??(e.repeatEvery?`every ${e.repeatEvery}ms`:`—`)}),(0,M.jsx)(`td`,{className:`px-5 py-3 text-faint`,children:d(e.nextRun)}),(0,M.jsx)(`td`,{className:`px-5 py-3 text-right tnum text-muted`,children:p(e.executions)}),(0,M.jsx)(`td`,{className:`px-5 py-3 text-right`,children:(0,M.jsx)(l,{"aria-label":`Delete cron ${e.name}`,disabled:te.has(e.name),onClick:()=>k(e.name),children:(0,M.jsx)(u,{className:`size-3.5`})})})]},e.name))})]})}),(0,M.jsx)(T,{page:x,pageSize:15,total:i.length,onPageChange:S,label:`crons`})]})]})}function L(e){if(typeof e!=`object`||!e||e.ok!==!0)throw Error(`Delete cron returned a malformed success response`)}function ae(e,t){let n=e?.cron;if(typeof e!=`object`||!e||e.ok!==!0||typeof n!=`object`||!n||n.name!==t.name||n.queue!==t.queue)throw Error(`Create cron returned a malformed success response`)}var R=e=>`Cron "${e}" already exists. Bunqueue v2.8.55 does not return complete cron definitions, so editing could reset hidden options. Delete it explicitly, wait for the list to refresh, then create the replacement as a separate action.`;function oe(e,t){let n=e.trim();return n&&t.has(n)?R(n):null}function z(e,t){let n=e;if(typeof n!=`object`||!n||n.ok!==!0||!Array.isArray(n.crons)||n.crons.some(e=>typeof e!=`object`||!e||typeof e.name!=`string`))throw Error(`Cannot verify that the cron name is unused; creation was not attempted`);if(n.crons.some(e=>e.name===t.trim()))throw Error(R(t.trim()))}function B(e){let t=Number(e);if(!Number.isInteger(t)||t<=0)return null;if(t<1e3)return`every ${t}ms`;for(let[e,n]of[[864e5,`d`],[36e5,`h`],[6e4,`m`],[1e3,`s`]])if(t>=e){let r=t/e;return`${Number.isInteger(r)?``:`≈ `}every ${Math.round(r*10)/10}${n}`}return null}function V(e,t,n,r){if(!e.trim())return{ok:!0};let i=Number(e);return!Number.isSafeInteger(i)||i<n||i>r?{ok:!1,msg:`${t} must be a whole number from ${n} to ${r}`}:{ok:!0,value:i}}function se(e,t=Date.now()){let n=e.name.trim(),r=e.queue.trim();if(!n)return{ok:!1,msg:`Name is required`};if(n.length>256)return{ok:!1,msg:`Name must be 256 characters or fewer`};let a=i(n,`Name`,256);if(a)return{ok:!1,msg:a};let o=D(r);if(o)return{ok:!1,msg:o};let s={};if(e.dataText.trim()){let t=E(e.dataText);if(!t.ok)return{ok:!1,msg:t.kind===`json`?`Data is not valid JSON`:t.msg};s=t.data}let c={name:n,queue:r,data:s,preventOverlap:e.preventOverlap,skipIfNoWorker:e.skipIfNoWorker,immediately:e.immediately,skipMissedOnRestart:e.skipMissedOnRestart};if(e.mode===`cron`){let t=e.schedule.trim();if(!t)return{ok:!1,msg:`Cron expression required`};c.schedule=t}else{let t=V(e.every,`Interval`,1,N);if(!t.ok||t.value===void 0)return{ok:!1,msg:t.ok?`Interval is required`:t.msg};c.repeatEvery=t.value}let l=e.timezone.trim();if(l){if(e.mode!==`cron`)return{ok:!1,msg:`Timezone applies only to cron expressions, not intervals`};try{new Intl.DateTimeFormat(`en`,{timeZone:l}).format(t)}catch{return{ok:!1,msg:`Timezone must be a valid IANA timezone`}}c.timezone=l}let u=V(e.priority,`Priority`,-1e6,1e6);if(!u.ok)return u;u.value!==void 0&&(c.priority=u.value);let d=V(e.maxLimit,`Max executions`,1,2**53-1);if(!d.ok)return d;d.value!==void 0&&(c.maxLimit=d.value);let f=e.uniqueKey.trim();if(f.length>1024)return{ok:!1,msg:`Unique key must be 1024 characters or fewer`};f&&(c.uniqueKey=f);let p=V(e.dedupTtl,`Dedup TTL`,1,N);if(!p.ok)return p;let m=p.value!==void 0||e.dedupExtend||e.dedupReplace;if(e.dedupExtend&&e.dedupReplace)return{ok:!1,msg:`Dedup extend and replace are mutually exclusive`};if(e.dedupExtend&&p.value===void 0)return{ok:!1,msg:`Dedup extend requires a TTL`};if(m&&!f&&!e.preventOverlap)return{ok:!1,msg:`Dedup options require a unique key or Prevent overlap`};m&&(c.dedup={...p.value===void 0?{}:{ttl:p.value},...e.dedupExtend?{extend:!0}:{},...e.dedupReplace?{replace:!0}:{}});let h=[{raw:e.jobMaxAttempts,label:`Spawned-job max attempts`,min:1,max:1e3,key:`maxAttempts`},{raw:e.jobBackoff,label:`Spawned-job backoff`,min:0,max:P,key:`backoff`},{raw:e.jobTimeout,label:`Spawned-job timeout`,min:0,max:P,key:`timeout`},{raw:e.jobDelay,label:`Spawned-job delay`,min:0,max:N,key:`delay`},{raw:e.jobStallTimeout,label:`Spawned-job stall timeout`,min:0,max:P,key:`stallTimeout`}],g={};for(let e of h){let t=V(e.raw,e.label,e.min,e.max);if(!t.ok)return t;t.value!==void 0&&(g[e.key]=t.value)}return e.jobRemoveOnComplete&&(g.removeOnComplete=!0),e.jobRemoveOnFail&&(g.removeOnFail=!0),Object.keys(g).length&&(c.jobOptions=g),{ok:!0,body:c}}function H({onCreate:e,onAccepted:n,beginCreate:r,scopeKey:i,existingNames:a}){let[o,s]=(0,O.useState)(``),[c,l]=(0,O.useState)(``),[u,f]=(0,O.useState)(`cron`),[p,h]=(0,O.useState)(``),[g,_]=(0,O.useState)(``),[y,b]=(0,O.useState)(`{}`),[T,ee]=(0,O.useState)(!1),[E,D]=(0,O.useState)(``),[k,ne]=(0,O.useState)(``),[A,j]=(0,O.useState)(!0),[F,I]=(0,O.useState)(!1),[L,R]=(0,O.useState)(``),[z,V]=(0,O.useState)(!1),[H,ce]=(0,O.useState)(!0),[U,le]=(0,O.useState)(``),[W,ue]=(0,O.useState)(``),[G,de]=(0,O.useState)(!1),[K,fe]=(0,O.useState)(!1),[q,pe]=(0,O.useState)(``),[J,me]=(0,O.useState)(``),[he,ge]=(0,O.useState)(``),[_e,ve]=(0,O.useState)(``),[ye,be]=(0,O.useState)(``),[xe,Se]=(0,O.useState)(!1),[Ce,we]=(0,O.useState)(!1),[Y,X]=(0,O.useState)(null),[Te,Z]=(0,O.useState)(!1),{on:Ee,fire:De,reset:Oe}=ie(3e3);(0,O.useEffect)(()=>{Z(!1),X(null),Oe()},[i]);let Q=(0,O.useMemo)(()=>u!==`cron`||!p.trim()?null:re(p.trim(),3,Date.now()),[u,p]),$=oe(o,a),ke=async()=>{X(null),Oe();let t=se({name:o,queue:c,mode:u,schedule:p,every:g,dataText:y,timezone:E,priority:k,preventOverlap:A,skipIfNoWorker:F,maxLimit:L,immediately:z,skipMissedOnRestart:H,uniqueKey:U,dedupTtl:W,dedupExtend:G,dedupReplace:K,jobMaxAttempts:q,jobBackoff:J,jobTimeout:he,jobDelay:_e,jobStallTimeout:ye,jobRemoveOnComplete:xe,jobRemoveOnFail:Ce});if(!t.ok){X(t.msg);return}let i=t.body,l=oe(i.name,a);if(l){X(l);return}if(!window.confirm(`Submit an upsert for cron "${i.name}"? Bunqueue v2.8.55 has no atomic create-only condition. The dashboard will recheck immediately before writing, but another client using the same name at the same time could still be replaced. Continue only if you authorize last-writer-wins behavior for this globally unique name.`))return;let d=r(i.name);if(d){Z(!0);try{if(ae(await e(i,d.isCurrent),i),!d.isCurrent())return;s(``),h(``),_(``),De(),m.success(`Cron upsert acknowledged`,i.name),n()}catch(e){if(!d.isCurrent())return;X(e.message)}finally{d.finish()&&Z(!1)}}};return(0,M.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:e=>{e.preventDefault(),ke()},children:[(0,M.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,M.jsx)(w,{label:`Name`,children:(0,M.jsx)(S,{name:`cron-name`,autoComplete:`off`,maxLength:256,value:o,onChange:e=>s(e.target.value),placeholder:`daily-report`})}),(0,M.jsx)(w,{label:`Queue`,children:(0,M.jsx)(S,{name:`cron-queue`,autoComplete:`off`,maxLength:256,value:c,onChange:e=>l(e.target.value),placeholder:`reports`})})]}),(0,M.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3`,children:[(0,M.jsxs)(`fieldset`,{children:[(0,M.jsx)(`legend`,{className:`sr-only`,children:`Schedule type`}),(0,M.jsx)(x,{options:[`cron`,`every`],value:u,onChange:f})]}),u===`cron`?(0,M.jsx)(`div`,{className:`min-w-56 flex-1`,children:(0,M.jsx)(w,{label:`Cron expression`,children:(0,M.jsx)(S,{name:`cron-expression`,value:p,onChange:e=>h(e.target.value),placeholder:`0 9 * * *`})})}):(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(`div`,{className:`w-40`,children:(0,M.jsx)(w,{label:`Every (ms)`,children:(0,M.jsx)(S,{type:`number`,min:1,max:N,step:1,name:`cron-interval`,value:g,onChange:e=>_(e.target.value),placeholder:`30000`})})}),g.trim()!==``&&(0,M.jsx)(`span`,{className:t(`pb-2 text-xs`,B(g)?`text-muted`:`text-danger`),children:B(g)??`not a valid interval`})]})]}),u===`cron`&&p.trim()&&Q&&(0,M.jsx)(`div`,{className:`rounded-lg border border-line bg-surface-2 px-3 py-2 text-xs`,children:Q.valid?Q.runs.length?(0,M.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1`,children:[(0,M.jsxs)(`span`,{className:`text-faint`,children:[`Next runs`,E.trim()?` (local)`:``,`:`]}),Q.runs.map(e=>(0,M.jsx)(`span`,{className:`font-mono text-muted`,children:d(e)},e)),E.trim()&&(0,M.jsxs)(`span`,{className:`text-faint`,children:[`— server evaluates in `,E.trim()]})]}):(0,M.jsx)(`span`,{className:`text-warning`,children:`Valid, but no runs in the next few years.`}):(0,M.jsxs)(`span`,{className:`text-warning`,children:[`Preview unavailable: `,Q.error,` Bunqueue will validate this expression when you create the schedule.`]})}),(0,M.jsx)(w,{label:`Data (JSON)`,children:(0,M.jsx)(`textarea`,{name:`cron-data`,value:y,onChange:e=>b(e.target.value),maxLength:te,rows:3,spellCheck:!1,className:`w-full rounded-lg border border-line bg-surface-2 px-3 py-2 font-mono text-sm text-fg placeholder:text-faint transition-colors focus:border-accent/60 focus:outline-none focus:ring-2 focus:ring-accent/30`})}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`button`,{type:`button`,onClick:()=>ee(e=>!e),"aria-expanded":T,"aria-controls":`cron-advanced-options`,className:`text-xs font-medium text-muted hover:text-fg`,children:T?`− Hide advanced`:`+ Advanced options`}),T&&(0,M.jsxs)(`div`,{id:`cron-advanced-options`,className:`mt-3 grid grid-cols-2 gap-3`,children:[(0,M.jsx)(w,{label:`Timezone (IANA)`,hint:`e.g. Europe/Rome. Default: server timezone.`,children:(0,M.jsx)(S,{name:`cron-timezone`,autoComplete:`off`,value:E,onChange:e=>D(e.target.value),placeholder:`Europe/Rome`})}),(0,M.jsx)(w,{label:`Priority`,children:(0,M.jsx)(S,{type:`number`,min:-1e6,max:1e6,step:1,name:`cron-priority`,value:k,onChange:e=>ne(e.target.value),placeholder:`0`})}),(0,M.jsx)(w,{label:`Max executions`,hint:`blank = unlimited`,children:(0,M.jsx)(S,{type:`number`,min:1,max:2**53-1,step:1,name:`cron-max-executions`,value:L,onChange:e=>R(e.target.value),placeholder:`∞`})}),(0,M.jsx)(w,{label:`Unique key`,hint:`optional deduplication key`,children:(0,M.jsx)(S,{name:`cron-unique-key`,autoComplete:`off`,maxLength:1024,value:U,onChange:e=>le(e.target.value),placeholder:`daily-report`})}),(0,M.jsxs)(`div`,{className:`col-span-2 flex flex-wrap gap-6`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,M.jsx)(C,{checked:A,onChange:j,label:`prevent overlap`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`prevent overlap`})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,M.jsx)(C,{checked:F,onChange:I,label:`skip if no worker`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`skip if no worker`})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,M.jsx)(C,{checked:z,onChange:V,label:`run immediately`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`run immediately`})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,M.jsx)(C,{checked:H,onChange:ce,label:`skip missed on restart`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`skip missed on restart`})]})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`div`,{className:`mb-2 text-[11px] uppercase tracking-wider text-faint`,children:`Cron deduplication`}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-3`,children:[(0,M.jsx)(w,{label:`Dedup TTL (ms)`,hint:`blank = no TTL`,children:(0,M.jsx)(S,{type:`number`,min:1,max:N,step:1,name:`cron-dedup-ttl`,value:W,onChange:e=>ue(e.target.value),placeholder:`60000`})}),(0,M.jsxs)(`div`,{className:`flex items-end gap-2 pb-2`,children:[(0,M.jsx)(C,{checked:G,onChange:de,label:`extend dedup TTL`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`extend TTL`})]}),(0,M.jsxs)(`div`,{className:`flex items-end gap-2 pb-2`,children:[(0,M.jsx)(C,{checked:K,onChange:fe,label:`replace duplicate`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`replace duplicate`})]})]})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`div`,{className:`mb-2 text-[11px] uppercase tracking-wider text-faint`,children:`Spawned-job options`}),(0,M.jsxs)(`div`,{className:`grid grid-cols-2 gap-3 lg:grid-cols-5`,children:[(0,M.jsx)(w,{label:`Max attempts`,children:(0,M.jsx)(S,{type:`number`,min:1,max:1e3,step:1,name:`cron-job-max-attempts`,value:q,onChange:e=>pe(e.target.value),placeholder:`3`})}),(0,M.jsx)(w,{label:`Backoff (ms)`,children:(0,M.jsx)(S,{type:`number`,min:0,max:P,step:1,name:`cron-job-backoff`,value:J,onChange:e=>me(e.target.value),placeholder:`1000`})}),(0,M.jsx)(w,{label:`Timeout (ms)`,children:(0,M.jsx)(S,{type:`number`,min:0,max:P,step:1,name:`cron-job-timeout`,value:he,onChange:e=>ge(e.target.value),placeholder:`—`})}),(0,M.jsx)(w,{label:`Delay (ms)`,children:(0,M.jsx)(S,{type:`number`,min:0,max:N,step:1,name:`cron-job-delay`,value:_e,onChange:e=>ve(e.target.value),placeholder:`0`})}),(0,M.jsx)(w,{label:`Stall timeout (ms)`,children:(0,M.jsx)(S,{type:`number`,min:0,max:P,step:1,name:`cron-job-stall-timeout`,value:ye,onChange:e=>be(e.target.value),placeholder:`server default`})})]}),(0,M.jsxs)(`div`,{className:`mt-3 flex flex-wrap gap-6`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,M.jsx)(C,{checked:xe,onChange:Se,label:`remove spawned jobs on complete`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`remove on complete`})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,M.jsx)(C,{checked:Ce,onChange:we,label:`remove spawned jobs on fail`}),(0,M.jsx)(`span`,{className:`text-sm text-muted`,children:`remove on fail`})]})]})]})]})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,M.jsx)(v,{type:`submit`,variant:`accent`,size:`sm`,disabled:Te||!!$,children:Te?`Saving…`:$?`Name already exists`:`Submit upsert`}),$&&!Y&&(0,M.jsx)(`span`,{role:`alert`,className:`max-w-2xl text-xs text-warning`,children:$}),Y&&(0,M.jsx)(`span`,{role:`alert`,className:`text-xs text-danger`,children:Y}),Ee&&(0,M.jsx)(`span`,{role:`status`,className:`text-xs text-success`,children:`Cron upsert acknowledged ✓`})]}),(0,M.jsx)(`p`,{className:`text-xs text-warning`,children:`Creation is an upstream upsert, not an atomic create-only operation. Use a globally unique name; the fail-closed preflight cannot eliminate a simultaneous write from another client.`})]})}export{I as CronManager};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./cn-CMFYpumL.js";import{f as t,g as n,l as r,r as i,t as a}from"./react-vendor-Bjui4wS4.js";import{i as o,o as s}from"./connectionStore-Cd9-3Fw0.js";import{a as c,n as l}from"./upstreamPaths-nG8N1XAz.js";import{C as u,J as d,O as f,S as p,T as m,a as h,b as ee,g,h as te,o as _,rt as v,st as y,v as ne,w as b,z as x}from"./index-Dr__4DsT.js";import{a as re,n as ie,o as S}from"./form-DsUq0w8s.js";import{r as C}from"./flowMutationSafety-DVD1IMr-.js";import{n as w}from"./exportFile-C7xhE8Yh.js";import{t as T}from"./jobActions-LQD4KfCc.js";var E=e(n(),1);function D(e){let t={};return typeof e.priority==`number`&&(t.priority=e.priority),typeof e.maxAttempts==`number`&&(t.maxAttempts=e.maxAttempts),typeof e.backoff==`number`&&(t.backoff=e.backoff),e.backoffConfig&&typeof e.backoffConfig.delay==`number`&&(t.backoffConfig={type:e.backoffConfig.type,delay:e.backoffConfig.delay},typeof t.backoff!=`number`&&(t.backoff=e.backoffConfig.delay)),typeof e.timeout==`number`&&(t.timeout=e.timeout),typeof e.removeOnComplete==`boolean`&&(t.removeOnComplete=e.removeOnComplete),typeof e.removeOnFail==`boolean`&&(t.removeOnFail=e.removeOnFail),typeof e.ttl==`number`&&(t.ttl=e.ttl),Array.isArray(e.tags)&&e.tags.length&&(t.tags=[...e.tags]),typeof e.groupId==`string`&&e.groupId&&(t.groupId=e.groupId),{clone:{queue:e.queue??``,dataText:JSON.stringify(e.data??{},null,2),options:t}}}var O=a(),k=365*24*60*60*1e3;function A(e,t){if(!e.trim())return{ok:!1,msg:`A value is required`};let n=Number(e);return Number.isFinite(n)?t===`progress`?n>=0&&n<=100?{ok:!0,value:n}:{ok:!1,msg:`Progress must be between 0 and 100`}:Number.isSafeInteger(n)?t===`priority`?n>=-1e6&&n<=1e6?{ok:!0,value:n}:{ok:!1,msg:`Priority must be between -1000000 and 1000000`}:n>=0&&n<=k?{ok:!0,value:n}:{ok:!1,msg:`Delay must be between 0 and ${k} ms`}:{ok:!1,msg:`Value must be a whole, safe integer`}:{ok:!1,msg:`Value must be a finite number`}}function ae({job:e,busy:t,act:n}){let r=T(e.state),i=r.promote||r.setPriority||r.setDelay||e.state===`active`;return(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Actions`}),(0,O.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[r.promote&&(0,O.jsx)(b,{size:`sm`,disabled:t,onClick:()=>n(`Promote`,()=>y.promoteJob(e.id)),children:`Promote (run now)`}),e.state===`failed`&&(0,O.jsx)(`p`,{role:`note`,className:`rounded-lg border border-warning/30 bg-warning/5 p-2 text-xs text-warning`,children:`DLQ retry is unavailable in Bunqueue v2.8.55: its GET and retry POST have no atomic job-generation, state, or flow-topology precondition.`}),e.state===`completed`&&(0,O.jsx)(`p`,{role:`note`,className:`rounded-lg border border-warning/30 bg-warning/5 p-2 text-xs text-warning`,children:`Completed-job requeue is unavailable in Bunqueue v2.8.55 because retry-completed re-inserts a child without rebuilding its flow dependency registration.`}),e.state===`active`&&(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(`p`,{role:`note`,className:`rounded-lg border border-warning/30 bg-warning/5 p-2 text-xs text-warning`,children:`Active-job state changes are unavailable: Bunqueue cannot stop the worker that is already processing this job, so retrying, delaying, discarding or failing it here could run side effects twice.`}),(0,O.jsx)(j,{label:`Set progress (0–100)`,cta:`Progress`,kind:`progress`,disabled:t,onSubmit:t=>n(`Progress`,()=>y.setJobProgress(e.id,t))})]}),r.setPriority&&(0,O.jsx)(M,{disabled:t,onSubmit:(t,r)=>n(`Priority`,()=>y.changePriority(e.id,t,r))}),r.setDelay&&(0,O.jsx)(j,{label:`Set delay (ms)`,cta:`Delay`,kind:`delay`,disabled:t,onSubmit:t=>n(`Delay`,()=>y.changeDelay(e.id,t))}),(0,O.jsxs)(`p`,{role:`note`,className:`text-xs text-faint`,children:[`Cancel/delete/discard: `,C]}),!i&&(0,O.jsxs)(`p`,{className:`text-xs text-faint`,children:[`No actions available for a job in state "`,e.state??`unknown`,`".`]})]})]})}function j({label:e,cta:t,kind:n,disabled:r,onSubmit:i}){let[a,o]=(0,E.useState)(``),s=A(a,n);return(0,O.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),!r&&s.ok&&i(s.value)},children:[(0,O.jsx)(ie,{type:`number`,min:0,max:n===`progress`?100:k,step:n===`progress`?`any`:1,name:n===`progress`?`job-progress`:`job-delay`,value:a,onChange:e=>o(e.target.value),placeholder:e,"aria-label":e,className:`h-8 text-xs`}),(0,O.jsx)(b,{type:`submit`,size:`sm`,disabled:r||!s.ok,children:t}),!s.ok&&a.trim()&&(0,O.jsx)(`span`,{role:`alert`,className:`self-center text-[11px] text-danger`,children:s.msg})]})}function M({disabled:e,onSubmit:t}){let[n,r]=(0,E.useState)(``),[i,a]=(0,E.useState)(!1),o=A(n,`priority`);return(0,O.jsxs)(`form`,{className:`flex flex-wrap items-center gap-2`,onSubmit:n=>{n.preventDefault(),!e&&o.ok&&t(o.value,i)},children:[(0,O.jsx)(ie,{type:`number`,min:-1e6,max:1e6,step:1,name:`job-priority`,value:n,onChange:e=>r(e.target.value),placeholder:`Set priority`,"aria-label":`Set priority`,className:`h-8 min-w-28 flex-1 text-xs`}),(0,O.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,O.jsx)(S,{checked:i,onChange:a,label:`Place first among equal priorities`}),(0,O.jsx)(`span`,{className:`text-xs text-muted`,children:`LIFO`})]}),(0,O.jsx)(b,{type:`submit`,size:`sm`,disabled:e||!o.ok,children:`Set`}),!o.ok&&n.trim()&&(0,O.jsx)(`span`,{role:`alert`,className:`w-full text-[11px] text-danger`,children:o.msg})]})}var N=36e5,oe=10,P=e=>Math.max(e,1);function se(e){return Math.max(0,(e.maxAttempts??0)-P(e.attempts??0))}function ce(e){let t=e.maxAttempts??0,n=e.attempts??0,r=e.backoffConfig,i=r?.maxDelay??N,a=r?.delay??e.backoff??1e3,o=[];for(let e=P(n);e<t&&o.length<oe;e++){let t=r?.type===`fixed`?a:a*2**e;o.push({attempt:e+1,delayMs:Math.min(t,i)})}return o}function le({job:e}){let t=e.maxAttempts??0,n=e.attempts??0;if(t<=1)return(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Backoff`}),(0,O.jsxs)(`p`,{className:`text-xs text-faint`,children:[`No retries configured (max attempts = `,t||1,`).`]})]});if(n>=t)return(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Backoff schedule`}),(0,O.jsx)(`p`,{className:`text-xs text-faint`,children:`Max attempts reached — no further retries will be scheduled.`})]});let r=e.backoffConfig,i=r?r.type:`exponential (default)`,a=se(e),o=ce(e);return(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Backoff schedule`,action:(0,O.jsxs)(`span`,{className:`text-xs capitalize text-faint`,children:[i,r?.maxDelay?` · cap ${_(r.maxDelay)}`:``]})}),(0,O.jsx)(`ul`,{className:`flex flex-col gap-1.5`,children:o.map(e=>(0,O.jsxs)(`li`,{className:`flex items-center justify-between text-sm`,children:[(0,O.jsxs)(`span`,{className:`text-muted`,children:[`Attempt `,e.attempt,` / `,t]}),(0,O.jsxs)(`span`,{className:`font-mono text-xs text-fg`,children:[`~`,_(e.delayMs)]})]},e.attempt))}),a>oe&&(0,O.jsxs)(`p`,{className:`mt-2 text-[11px] text-faint`,children:[`Showing next `,oe,` of `,a,` remaining attempts.`]}),(0,O.jsxs)(`p`,{className:`mt-2 text-[11px] text-faint`,children:[`Approximate — the server applies ±`,r?.type===`fixed`?`20`:`50`,`% jitter at retry time, capped at `,_(r?.maxDelay??N),`.`]})]})}function ue({jobId:e}){let[t,n]=(0,E.useState)(!1),[r,i]=(0,E.useState)(!1),[a,o]=(0,E.useState)(!1),[s,c]=(0,E.useState)(void 0),[l,d]=(0,E.useState)(null),f=async()=>{o(!0),d(null);try{let t=await y.jobChildren(e);c(t.data?.values),i(!0)}catch(e){d(e.message)}finally{o(!1)}},m=()=>{let e=!t;n(e),e&&!r&&!a&&f()},h=s&&typeof s==`object`?Array.isArray(s)?s.length:Object.keys(s).length:0;return(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Child values`,action:(0,O.jsx)(b,{size:`sm`,variant:`ghost`,onClick:m,children:t?`Hide`:`Show`})}),t?a?(0,O.jsx)(`p`,{className:`text-xs text-faint`,children:`Loading child values…`}):l?(0,O.jsx)(`p`,{className:`text-xs text-danger`,children:l}):h===0?(0,O.jsx)(`p`,{className:`text-xs text-faint`,children:`No child values available.`}):(0,O.jsx)(`pre`,{className:`max-h-64 overflow-auto rounded-lg bg-surface-2 p-3 font-mono text-xs text-muted`,children:JSON.stringify(s,null,2)}):(0,O.jsx)(`p`,{className:`text-xs text-faint`,children:`Resolved return values from this flow job's children.`})]})}function de({data:e,busy:t,editable:n,readOnlyReason:r,onSave:i}){let[a,o]=(0,E.useState)(()=>JSON.stringify(e??null,null,2)),[s,c]=(0,E.useState)(null),l=(0,E.useRef)(a);return(0,E.useEffect)(()=>{let t=JSON.stringify(e??null,null,2);t!==l.current&&(l.current=t,o(t),c(null))},[e]),(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Data`,action:n?(0,O.jsx)(b,{size:`sm`,disabled:t,onClick:()=>{let e;try{e=JSON.parse(a)}catch(e){c(`Invalid JSON: ${e.message}`);return}c(null),i(e)},children:`Save data`}):void 0}),(0,O.jsx)(`textarea`,{"aria-label":`Job data JSON`,name:`job-data-json`,value:a,onChange:e=>o(e.target.value),readOnly:!n,spellCheck:!1,rows:8,className:`w-full resize-y rounded-lg border border-line bg-surface-2 p-3 font-mono text-xs text-fg placeholder:text-faint focus:border-accent/60 focus:outline-none focus:ring-2 focus:ring-accent/30`}),!n&&(0,O.jsx)(`p`,{className:`mt-2 text-xs text-faint`,children:r??`Data is read-only after a job starts processing or leaves the runnable queue.`}),s&&(0,O.jsx)(`p`,{role:`alert`,className:`mt-2 text-xs text-danger`,children:s})]})}function fe(e){return e===`waiting`||e===`prioritized`||e===`delayed`}var F=[`__parentId`,`__parentQueue`,`__childrenIds`,`__flowParentId`,`__flowParentIds`];function pe(e,t){if(!fe(e))return`Data is read-only after a job starts processing or leaves the runnable queue.`;let n=t.data,r=typeof n==`object`&&!!n&&!Array.isArray(n)&&F.some(e=>Object.hasOwn(n,e));return t.parentId||(t.childrenIds?.length??0)>0||r?`Data is read-only for Flow jobs because Bunqueue v2.8.55 replaces the full payload and would remove structural metadata.`:null}var me=3e4;function I(){let{token:e}=s.getState();return{baseUrl:o(),authorization:e?`Bearer ${e}`:void 0}}function he(e,t){return e.baseUrl===t.baseUrl&&e.authorization===t.authorization}function ge(e,t,n){return t.aborted&&!n.aborted?new v(`Request timed out`,0):e}async function L(e,t,n,r){let i=AbortSignal.timeout(me),a=AbortSignal.any([r,i]),o=new Headers(n.headers);e.authorization&&o.set(`Authorization`,e.authorization),n.body!=null&&!o.has(`Content-Type`)&&o.set(`Content-Type`,`application/json`);let s;try{a.throwIfAborted(),s=await fetch(`${e.baseUrl}${t}`,{...n,headers:o,signal:a}),a.throwIfAborted()}catch(e){throw ge(e,i,r)}if(s.status===204)return;let c;try{c=await s.text(),a.throwIfAborted()}catch(e){throw ge(e,i,r)}let l,u=!1;if(c)try{l=JSON.parse(c)}catch{u=!0}if(!s.ok){let t=!u&&l&&typeof l==`object`?l.error:void 0;throw s.status===401&&typeof window<`u`&&window.dispatchEvent(new window.CustomEvent(`auth:required`,{detail:{scope:`server`,auth:e.authorization,target:e.baseUrl}})),new v(typeof t==`string`?t:`HTTP ${s.status}`,s.status)}if(c){if(u)throw new v(`Invalid JSON response (HTTP ${s.status})`,s.status);if(l&&typeof l==`object`&&l.ok===!1){let e=l.error;throw new v(typeof e==`string`?e:`Operation failed`,s.status)}return l}}function R(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new v(`Invalid logs response: expected an object envelope`,200);let t=e;if(t.ok!==!0||!t.data||typeof t.data!=`object`)throw new v(`Invalid logs response: expected { ok: true, data }`,200);let n=t.data;if(!Array.isArray(n.logs)||typeof n.count!=`number`||!Number.isSafeInteger(n.count)||n.count<0)throw new v(`Invalid logs response: expected logs[] and a non-negative count`,200);return{logs:n.logs,count:n.count}}function _e({jobId:e}){let t=s(e=>e.baseUrl),n=s(e=>e.token),[r,i]=(0,E.useState)([]),[a,l]=(0,E.useState)(0),[d,f]=(0,E.useState)(!1),[m,h]=(0,E.useState)(null),[ee,g]=(0,E.useState)(``),[te,_]=(0,E.useState)(`info`),[y,ne]=(0,E.useState)(!1),x=(0,E.useRef)(!1),S=(0,E.useRef)(null),C=(0,E.useRef)(0),w=(0,E.useRef)(null),T=(0,E.useRef)(0),D=(0,E.useRef)(null),k=(0,E.useRef)(!1),A=(0,E.useRef)(0);(0,E.useEffect)(()=>{x.current=!0,S.current=e;let t=()=>{C.current+=1,w.current?.abort(),w.current=null,T.current+=1,D.current?.abort(),D.current=null,k.current=!1,A.current+=1,i([]),l(0),f(!1),h(null),g(``),ne(!1)},n=s.subscribe((e,n)=>{e.baseUrl===n.baseUrl&&e.token===n.token||t()});return t(),()=>{x.current=!1,S.current=null,n(),C.current+=1,w.current?.abort(),w.current=null,T.current+=1,D.current?.abort(),D.current=null,k.current=!1}},[e]);let ae=(0,E.useCallback)(async r=>{w.current?.abort();let a=new AbortController;w.current=a;let u=++C.current,d=s.getState(),p=r?.target??(d.baseUrl===t&&d.token===n?{baseUrl:o(),authorization:n?`Bearer ${n}`:void 0}:I()),m=()=>x.current&&S.current===e&&u===C.current&&!a.signal.aborted&&he(p,I());f(!0),h(null);try{let t=R(await L(p,`/jobs/${c(e)}/logs`,{},a.signal));return m()?(i(t.logs),l(t.count),!0):!1}catch(e){if(!m())return!1;let t=e instanceof Error?e.message:String(e);return h(r?.acceptedLabel?`${r.acceptedLabel} succeeded, but couldn't reload logs: ${t}`:t),!1}finally{u===C.current&&(w.current===a&&(w.current=null),x.current&&f(!1))}},[e,t,n]);(0,E.useEffect)(()=>{ae()},[ae]);let j=async(t,n,r)=>{if(k.current)return;k.current=!0;let i=new AbortController;D.current=i;let a=++T.current,o=I();C.current+=1,w.current?.abort(),w.current=null,f(!1),ne(!0),h(null);let s=()=>x.current&&S.current===e&&a===T.current&&!i.signal.aborted&&he(o,I());try{let a=await L(o,`/jobs/${c(e)}/logs`,t,i.signal);if(!a||typeof a!=`object`||Array.isArray(a)||a.ok!==!0)throw new v(`Invalid log mutation response: expected { ok: true }`,200);if(!s())return;r(),await ae({acceptedLabel:n,target:o})}catch(e){s()&&h(e instanceof Error?e.message:String(e))}finally{a===T.current&&(k.current=!1,D.current===i&&(D.current=null),x.current&&ne(!1))}},M=async(e=ee,t=te)=>{if(k.current)return;let n=e.trim();if(!n)return;let r=t===`warn`||t===`error`?t:`info`,i=A.current;g(e),_(r),await j({method:`POST`,body:JSON.stringify({message:n,level:r})},`Log addition`,()=>{A.current===i&&g(``)})};return(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Logs`,action:(0,O.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,O.jsx)(`span`,{className:`font-mono text-xs text-faint`,children:a}),(0,O.jsx)(b,{size:`sm`,variant:`ghost`,disabled:d||y,onClick:()=>void ae(),children:`Refresh`}),(0,O.jsx)(b,{size:`sm`,variant:`danger`,disabled:y||r.length===0,onClick:async()=>{k.current||window.confirm(`Clear all logs for this job?`)&&await j({method:`DELETE`},`Log clearing`,()=>{i([]),l(0)})},children:`Clear logs`})]})}),m&&(0,O.jsx)(`p`,{className:`mb-2 text-xs text-danger`,children:m}),r.length===0?(0,O.jsx)(`p`,{className:`text-xs text-faint`,children:`No log lines recorded for this job.`}):(0,O.jsx)(`ol`,{className:`flex max-h-64 flex-col gap-1 overflow-auto rounded-lg bg-surface-2 p-3`,children:r.map((e,t)=>(0,O.jsx)(`li`,{className:`whitespace-pre-wrap break-words font-mono text-xs text-muted`,children:typeof e==`string`?e:JSON.stringify(e)},t))}),(0,O.jsxs)(`form`,{className:`mt-3 flex gap-2`,onSubmit:e=>{e.preventDefault();let t=e.currentTarget.elements.namedItem(`job-log-message`),n=e.currentTarget.elements.namedItem(`job-log-level`);M(t?.value??ee,n?.value??te)},children:[(0,O.jsx)(ie,{"aria-label":`Log message`,name:`job-log-message`,autoComplete:`off`,value:ee,onInput:e=>{A.current+=1,g(e.currentTarget.value)},placeholder:`Add a log line…`,className:`h-8 flex-1 text-xs`}),(0,O.jsxs)(re,{"aria-label":`Log level`,name:`job-log-level`,value:te,onChange:e=>{A.current+=1,_(e.target.value)},className:`h-8 w-24 text-xs`,children:[(0,O.jsx)(`option`,{value:`info`,children:`info`}),(0,O.jsx)(`option`,{value:`warn`,children:`warn`}),(0,O.jsx)(`option`,{value:`error`,children:`error`})]}),(0,O.jsx)(b,{type:`submit`,size:`sm`,disabled:y||ee.trim()===``,children:`Add`})]})]})}function ve({timeline:e}){let t=e??[];return(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Timeline`}),t.length===0?(0,O.jsx)(`p`,{className:`text-xs text-faint`,children:`No state transitions recorded yet.`}):(0,O.jsx)(`ol`,{className:`flex flex-col gap-0`,children:t.map((e,t)=>(0,O.jsxs)(`li`,{className:`border-b border-line/60 py-2 last:border-0`,children:[(0,O.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,O.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,O.jsx)(g,{status:e.state}),e.attempt!=null&&(0,O.jsxs)(`span`,{className:`font-mono text-[11px] text-faint`,children:[`attempt `,e.attempt]})]}),(0,O.jsx)(`span`,{className:`font-mono text-xs text-muted`,children:h(e.timestamp)})]}),(e.worker||e.error)&&(0,O.jsxs)(`div`,{className:`mt-1 pl-0.5`,children:[e.worker&&(0,O.jsx)(`div`,{className:`font-mono text-[11px] text-faint`,children:e.worker}),e.error&&(0,O.jsx)(`div`,{className:`mt-0.5 text-xs text-danger/90`,children:e.error})]})]},t))})]})}var z=3e4;function B(){let{token:e}=s.getState();return{baseUrl:o(),authorization:e?`Bearer ${e}`:void 0}}function V(e,t){return e?.baseUrl===t.baseUrl&&e.authorization===t.authorization}function H(e,t,n){return t.aborted&&!n?.aborted?new v(`Request timed out`,0):e}async function ye(e,t,n,r=z){let i=AbortSignal.timeout(r),a=n?AbortSignal.any([n,i]):i,o=new Headers;e.authorization&&o.set(`Authorization`,e.authorization);let s;try{a.throwIfAborted(),s=await fetch(`${e.baseUrl}${t}`,{headers:o,signal:a}),a.throwIfAborted()}catch(e){throw H(e,i,n)}if(s.status===204)return;let c;try{c=await s.text(),a.throwIfAborted()}catch(e){throw H(e,i,n)}let l,u=!1;if(c)try{l=JSON.parse(c)}catch{u=!0}if(!s.ok){let t=!u&&l&&typeof l==`object`?l.error:void 0,n=typeof t==`string`?t:`HTTP ${s.status}`;throw s.status===401&&typeof window<`u`&&window.dispatchEvent(new window.CustomEvent(`auth:required`,{detail:{scope:`server`,auth:e.authorization,target:e.baseUrl}})),new v(n,s.status)}if(c){if(u)throw new v(`Invalid JSON response (HTTP ${s.status})`,s.status);if(l&&typeof l==`object`&&l.ok===!1){let e=l.error;throw new v(typeof e==`string`?e:`Operation failed`,s.status)}return l}}function U(e){throw new v(`Invalid job response: ${e}`,200)}function W(e,t,{nullable:n=!1,nonEmpty:r=!1}={},i=`job`){if(!Object.hasOwn(e,t)||e[t]===void 0)return;let a=e[t];n&&a===null||(typeof a!=`string`||r&&!a.trim())&&U(`${i}.${t} must be ${n?`a string or null`:`a string`}${r?` (non-empty)`:``}`)}function G(e,t,{nullable:n=!1,integer:r=!1,min:i,max:a}={},o=`job`){if(!Object.hasOwn(e,t)||e[t]===void 0)return;let s=e[t];n&&s===null||(typeof s!=`number`||!Number.isFinite(s)||r&&!Number.isSafeInteger(s)||i!==void 0&&s<i||a!==void 0&&s>a)&&U(`${o}.${t} must be a valid${r?` safe integer`:` finite number`}`)}function K(e,t){Object.hasOwn(e,t)&&e[t]!==void 0&&typeof e[t]!=`boolean`&&U(`job.${t} must be a boolean`)}function q(e,t,{nullable:n=!1,nonEmpty:r=!1}={}){if(!Object.hasOwn(e,t)||e[t]===void 0)return;let i=e[t];n&&i===null||(!Array.isArray(i)||i.some(e=>typeof e!=`string`||r&&!e.trim()))&&U(`job.${t} must be ${n?`a string array or null`:`a string array`}`)}var J=1e4,Y=100,X=256*1024;function Z(e,t){let n=0,r=0;for(;n<e.length&&r<t;){let t=e.codePointAt(n);n+=t!==void 0&&t>65535?2:1,r+=1}return{text:e.slice(0,n),count:r}}function be(e){let t=[],n=0,r=!1,i=Math.min(e.length,Y);for(let a=0;a<i;a++){let i=+(t.length>0),o=X-n-i;if(o<=0){r=!0;break}let s=e[a]??``,c=Z(s,o);if(t.push(c.text),n+=i+c.count,c.text.length!==s.length){r=!0;break}}return t.length<e.length&&(r=!0),{text:t.join(`
|
|
2
|
-
`),displayedLines:t.length,totalLines:e.length,truncated:r}}function xe(e,t){if(t&&(typeof e.state!=`string`||!e.state.trim())&&U(`canonical job.state must be a non-empty string`),W(e,`state`,{nonEmpty:!0}),t&&(typeof e.queue!=`string`||!e.queue.trim())&&U(`canonical job.queue must be a non-empty string`),W(e,`queue`,{nonEmpty:!0}),W(e,`customId`,{nullable:!0}),W(e,`parentId`,{nullable:!0,nonEmpty:!0}),W(e,`groupId`,{nullable:!0}),W(e,`progressMessage`,{nullable:!0}),q(e,`childrenIds`,{nonEmpty:!0}),q(e,`dependsOn`,{nonEmpty:!0}),q(e,`tags`),q(e,`stacktrace`,{nullable:!0}),Array.isArray(e.stacktrace)&&e.stacktrace.length>J&&U(`job.stacktrace exceeds Bunqueue's ${J}-entry limit`),G(e,`priority`,{integer:!0}),G(e,`createdAt`),G(e,`runAt`),G(e,`startedAt`,{nullable:!0}),G(e,`completedAt`,{nullable:!0}),G(e,`attempts`,{integer:!0,min:0}),G(e,`maxAttempts`,{integer:!0,min:0}),G(e,`backoff`,{integer:!0,min:0}),G(e,`timeout`,{nullable:!0,integer:!0,min:0}),G(e,`ttl`,{nullable:!0,integer:!0,min:0}),G(e,`progress`,{min:0,max:100}),G(e,`lastHeartbeat`),G(e,`stallCount`,{integer:!0,min:0}),K(e,`removeOnComplete`),K(e,`removeOnFail`),Object.hasOwn(e,`backoffConfig`)&&e.backoffConfig!==void 0){let t=e.backoffConfig;if(t!==null){(!t||typeof t!=`object`||Array.isArray(t))&&U(`job.backoffConfig must be an object or null`);let e=t;e.type!==`fixed`&&e.type!==`exponential`&&U(`job.backoffConfig.type must be fixed or exponential`),G(e,`delay`,{integer:!0,min:0},`job.backoffConfig`),(!Object.hasOwn(e,`delay`)||e.delay===void 0)&&U(`job.backoffConfig.delay is required`),G(e,`maxDelay`,{integer:!0,min:0},`job.backoffConfig`)}}if(Object.hasOwn(e,`timeline`)&&e.timeline!==void 0){Array.isArray(e.timeline)||U(`job.timeline must be an array`),e.timeline.length>20&&U(`job.timeline exceeds 20 entries`);for(let[t,n]of e.timeline.entries()){(!n||typeof n!=`object`||Array.isArray(n))&&U(`job.timeline[${t}] must be an object`);let e=n;(typeof e.state!=`string`||!e.state.trim())&&U(`job.timeline[${t}].state must be a non-empty string`),(typeof e.timestamp!=`number`||!Number.isFinite(e.timestamp))&&U(`job.timeline[${t}].timestamp must be a finite number`);let r=`job.timeline[${t}]`;W(e,`worker`,{},r),W(e,`error`,{},r),G(e,`attempt`,{integer:!0,min:0},r)}}}function Se(e,{canonical:t,expectedId:n}){if(!e||typeof e!=`object`||Array.isArray(e))return U(`expected an object envelope`);let r=e;if(r.ok!==!0||!Object.hasOwn(r,`job`))return U(`expected { ok: true, job }`);if(r.job===null)return null;if(!r.job||typeof r.job!=`object`||Array.isArray(r.job))return U(`job must be an object or null`);let i=r.job;return typeof i.id!=`string`||!i.id.trim()?U(`job.id must be a non-empty string`):n!==void 0&&i.id!==n?U(`expected job.id ${JSON.stringify(n)}`):(xe(i,t),i)}function Ce(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new v(`Invalid job result response: expected an object envelope`,200);let n=e;if(n.ok!==!0||n.id!==t)throw new v(`Invalid job result response: expected { ok: true, id, result? }`,200);return{result:n.result}}async function we(e,t,n={}){let r=n.target??B(),i=n.timeoutMs??z,a=Se(await ye(r,t===`custom`?`/jobs/custom/${l(e,`Custom job ID`)}`:`/jobs/${c(e)}`,n.signal,i),{canonical:t===`id`,expectedId:t===`id`?e:void 0});return!a||t===`id`?a:a.customId===e?Se(await ye(r,`/jobs/${c(a.id)}`,n.signal,i),{canonical:!0,expectedId:a.id}):U(`expected job.customId ${JSON.stringify(e)}`)}function Te(e){let t=e.timeline??[];for(let e=t.length-1;e>=0;e--){let n=t[e];if(n.state===`failed`&&n.error)return{message:n.error,attempt:n.attempt,timestamp:n.timestamp}}return null}function Ee(){let e=r(),[n,a]=t(),l=s(e=>e.baseUrl),m=s(e=>e.token),ie=n.get(`custom`),[S,C]=(0,E.useState)(ie??n.get(`id`)??``),[T,k]=(0,E.useState)(ie?`custom`:`id`),[A,j]=(0,E.useState)(null),[M,N]=(0,E.useState)({fetched:!1,value:void 0}),[oe,P]=(0,E.useState)(null),[se,ce]=(0,E.useState)(!1),[fe,F]=(0,E.useState)(!1),[me,I]=(0,E.useState)(null),[he,ge]=(0,E.useState)(!1),L=(0,E.useRef)(0),R=(0,E.useRef)(null),z=(0,E.useRef)(null),H=(0,E.useRef)(null),U=(0,E.useRef)(!1),W=(0,E.useRef)(null),G=(0,E.useRef)(!1),K=(0,E.useRef)(0),q=(0,E.useRef)(!1),J=(0,E.useRef)(null);(0,E.useEffect)(()=>{G.current=!0;let e=s.subscribe((e,t)=>{e.baseUrl===t.baseUrl&&e.token===t.token||(L.current+=1,R.current?.abort(),R.current=null,z.current=null,K.current+=1,J.current=null,q.current=!1,H.current=null,U.current=!1,W.current=null,j(null),N({fetched:!1,value:void 0}),P(null),F(!1),I(null),ce(!1),ge(!1))});return()=>{G.current=!1,e(),L.current+=1,R.current?.abort(),R.current=null,z.current=null,K.current+=1,J.current=null,q.current=!1}},[]);let Y=async(e,t=T,n=!1,r,i=!1)=>{let o=e.trim();if(!o||r===void 0&&q.current&&!i)return;U.current=!1,W.current=null,r===void 0&&(K.current+=1),A!==null&&(t===`id`?A.id!==o:A.customId!==o)&&(H.current=null,j(null),N({fetched:!1,value:void 0}),P(null)),R.current?.abort();let s=new AbortController;R.current=s,z.current={key:o,mode:t};let l=++L.current,u=B();ce(!0),F(!1),n||I(null);try{let e=await we(o,t,{signal:s.signal,target:u});if(!e){if(l!==L.current)return;U.current=!0,W.current=null,j(null),N({fetched:!1,value:void 0}),P(null),F(!0),a({},{replace:!0});return}let n=null,r=null;if(l!==L.current||s.signal.aborted||!V(u,B()))return;if(e.state===`completed`)try{n=Ce(await ye(u,`/jobs/${c(e.id)}/result`,s.signal),e.id)}catch(e){if(s.signal.aborted)throw e;r=e.message}if(l!==L.current||s.signal.aborted||!V(u,B()))return;H.current=u,j(e),t===`custom`?(k(`id`),C(e.id)):C(o),a({id:e.id},{replace:!0}),N(n?{fetched:!0,value:n.result}:{fetched:!1,value:void 0}),P(r)}catch(e){if(l!==L.current||s.signal.aborted)return;e instanceof v&&(e.status===404||/not found/i.test(e.message))?(U.current=!0,W.current=null,j(null),N({fetched:!1,value:void 0}),P(null),F(!0),a({},{replace:!0})):I(n?t=>t?{ok:t.ok,text:`${t.text} — couldn't reload: ${e.message}`}:{ok:!1,text:e.message}:{ok:!1,text:e.message})}finally{l===L.current&&(R.current===s&&(R.current=null,z.current=null),ce(!1))}},X=n.get(`id`),Z=n.get(`custom`),xe={baseUrl:o(),authorization:m?`Bearer ${m}`:void 0},Se=V(H.current,xe);(0,E.useEffect)(()=>{if(U.current){!X&&!Z&&(U.current=!1,W.current=e.key);return}if(!(!X&&!Z&&W.current===e.key))if(W.current=null,Z)if(A?.customId===Z&&Se)k(`id`),C(A.id),a({id:A.id},{replace:!0});else{k(`custom`),C(Z);let e=z.current;(e?.mode!==`custom`||e.key!==Z)&&Y(Z,`custom`,!1,void 0,!0)}else if(X&&(X!==A?.id||!Se)){k(`id`),C(X);let e=z.current;(e?.mode!==`id`||e.key!==X)&&Y(X,`id`,!1,void 0,!0)}else!X&&!Z&&(L.current+=1,R.current?.abort(),R.current=null,z.current=null,K.current+=1,H.current=null,j(null),N({fetched:!1,value:void 0}),P(null),F(!1),I(null),ce(!1),k(`id`),C(``))},[X,Z,A?.id,A?.customId,Se,e.key,l,m]);let Ee=(e,t=T)=>{let n=e.trim();if(!(!n||q.current)){if(t===`id`?X===n&&Z===null:Z===n&&X===null){Y(n,t);return}a(t===`custom`?{custom:n}:{id:n})}},ke=async(e,t,n)=>{if(!A||q.current||R.current)return;let r=B();if(!V(H.current,r)||n&&!window.confirm(n))return;let i=++K.current,o=A.id;J.current=i,q.current=!0,ge(!0),I(null);let s=()=>G.current&&i===K.current&&V(r,B())&&V(H.current,r);try{let n=await t();if(!n||typeof n!=`object`||Array.isArray(n)||n.ok!==!0)throw new v(`Invalid job mutation response: expected { ok: true }`,200);if(!s())return;I({ok:!0,text:`${e} ✓`}),e===`Cancel`?(U.current=!0,W.current=null,L.current+=1,H.current=null,j(null),N({fetched:!1,value:void 0}),P(null),a({},{replace:!0})):await Y(o,`id`,!0,i)}catch(e){s()&&I({ok:!1,text:e.message})}finally{J.current===i&&(J.current=null,q.current=!1,G.current&&ge(!1))}},Ae=A?.state,$=A?Te(A):null,je=A?.stacktrace?.length?be(A.stacktrace):null,Me=je!==null,Ne=(A?.childrenIds?.length??0)>0,Pe=A?pe(Ae,A):null,Fe=Ae===`failed`,Ie=A&&($||Me)?(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Error`}),$&&(0,O.jsxs)(`div`,{className:`mb-3`,children:[(0,O.jsx)(`p`,{className:`text-sm text-danger`,children:$.message}),(0,O.jsxs)(`p`,{className:`mt-1 text-[11px] text-faint`,children:[$.attempt==null?``:`Attempt ${$.attempt} · `,h($.timestamp)]})]}),je&&(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(`pre`,{className:`max-h-80 overflow-auto whitespace-pre-wrap rounded-lg bg-surface-2 p-3 font-mono text-xs text-danger/90`,children:je.text}),je.truncated&&(0,O.jsxs)(`p`,{className:`mt-2 text-xs text-faint`,children:[`Stack preview truncated (`,je.displayedLines,` of `,je.totalLines,` `,`lines, 262,144 characters maximum). Download JSON for the complete stored stack.`]})]})]}):null;return(0,O.jsxs)(`div`,{children:[(0,O.jsx)(te,{title:`Job Inspector`,description:`Look up any job by ID and drive its full lifecycle.`,actions:A?(0,O.jsxs)(O.Fragment,{children:[(Ne||A.parentId)&&(0,O.jsx)(i,{to:`/flows?root=${encodeURIComponent(A.id)}`,className:`rounded-lg border border-line px-3 py-1.5 text-sm text-muted hover:bg-surface-2 hover:text-fg`,children:`View flow`}),(0,O.jsx)(i,{to:`/add-job`,state:D(A),title:`Enqueue a new job pre-filled from this one`,className:`rounded-lg border border-line px-3 py-1.5 text-sm text-muted hover:bg-surface-2 hover:text-fg`,children:`Clone`}),(0,O.jsxs)(b,{size:`sm`,onClick:()=>w(`job-${A.id}`,M.fetched?{...A,result:M.value}:A),children:[(0,O.jsx)(x,{className:`size-3.5`}),` Download JSON`]})]}):void 0}),(0,O.jsxs)(`div`,{className:`mb-6 flex flex-wrap items-center gap-2`,children:[(0,O.jsxs)(re,{name:`job-lookup-mode`,autoComplete:`off`,value:T,"aria-label":`Lookup mode`,onChange:e=>k(e.target.value),className:`w-40`,children:[(0,O.jsx)(`option`,{value:`id`,children:`By job ID`}),(0,O.jsx)(`option`,{value:`custom`,children:`By custom ID`})]}),(0,O.jsxs)(`div`,{className:`relative min-w-56 flex-1`,children:[(0,O.jsx)(d,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-faint`}),(0,O.jsx)(`input`,{value:S,"aria-label":T===`custom`?`Custom job ID`:`Job ID`,name:`job-lookup-id`,autoComplete:`off`,spellCheck:!1,maxLength:1024,onInput:e=>C(e.currentTarget.value),onKeyDown:e=>e.key===`Enter`&&Ee(S),placeholder:T===`custom`?`custom / idempotency id — Enter to look up`:`job id (UUID) — Enter to look up`,className:`h-9 w-full rounded-lg border border-line bg-surface pl-9 pr-3 font-mono text-sm text-fg placeholder:text-faint focus:border-accent/60 focus:outline-none focus:ring-2 focus:ring-accent/30`})]}),(0,O.jsx)(b,{variant:`accent`,disabled:se||he,onClick:()=>Ee(S),children:`Look up`})]}),me&&(0,O.jsx)(`div`,{role:`status`,className:me.ok?`mb-4 text-sm text-success`:`mb-4 text-sm text-danger`,children:me.text}),se&&!A?(0,O.jsx)(ee,{label:`Loading job…`}):fe?(0,O.jsx)(ne,{title:`Job not found`,hint:`Check the ID, or the job may have been removed.`}):A?(0,O.jsxs)(`div`,{className:`grid grid-cols-1 gap-6 lg:grid-cols-3`,children:[(0,O.jsxs)(`div`,{className:`flex flex-col gap-6 lg:col-span-2`,children:[(0,O.jsxs)(p,{children:[(0,O.jsxs)(`div`,{className:`mb-4 flex items-center justify-between gap-3`,children:[(0,O.jsxs)(`div`,{className:`min-w-0`,children:[(0,O.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,O.jsx)(`div`,{className:`truncate font-mono text-sm text-fg`,children:A.id}),(0,O.jsx)(f,{value:A.id})]}),(0,O.jsx)(`div`,{className:`mt-1 font-mono text-xs text-faint`,children:A.queue})]}),(0,O.jsx)(g,{status:Ae??`unknown`})]}),(0,O.jsxs)(`dl`,{className:`grid grid-cols-2 gap-x-6 gap-y-2 text-sm sm:grid-cols-3`,children:[(0,O.jsx)(Q,{k:`Priority`,v:String(A.priority??0)}),(0,O.jsx)(Q,{k:`Attempts`,v:`${A.attempts??0} / ${A.maxAttempts??`?`}`}),(0,O.jsx)(Q,{k:`Progress`,v:`${A.progress??0}%`}),(0,O.jsx)(Q,{k:`Created`,v:h(A.createdAt)}),(0,O.jsx)(Q,{k:`Started`,v:h(A.startedAt??void 0)}),(0,O.jsx)(Q,{k:`Completed`,v:h(A.completedAt??void 0)}),(0,O.jsx)(Q,{k:`Duration`,v:_(A.startedAt&&A.completedAt?A.completedAt-A.startedAt:void 0)}),(0,O.jsxs)(`div`,{children:[(0,O.jsx)(`dt`,{className:`text-[11px] uppercase tracking-wider text-faint`,children:`Custom ID`}),(0,O.jsxs)(`dd`,{className:`flex items-center gap-1 text-fg`,children:[(0,O.jsx)(`span`,{className:`truncate font-mono`,children:A.customId??`—`}),A.customId&&(0,O.jsx)(f,{value:A.customId})]})]})]})]}),Fe&&Ie,(0,O.jsx)(de,{data:A.data,busy:he,editable:Pe===null,readOnlyReason:Pe??void 0,onSave:e=>ke(`Data`,()=>y.updateJobData(A.id,e))},`data-${A.id}`),Ae===`completed`&&(0,O.jsxs)(p,{children:[(0,O.jsx)(u,{title:`Result`,action:M.fetched&&M.value!==void 0&&M.value!==null?(0,O.jsx)(Oe,{value:M.value,filename:`job-${A.id}-result`}):void 0}),M.fetched&&M.value!==void 0&&M.value!==null?(0,O.jsx)(De,{value:M.value}):oe?(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,O.jsxs)(`p`,{className:`text-xs text-danger`,children:[`Couldn't load result — `,oe]}),(0,O.jsx)(b,{size:`sm`,disabled:se,onClick:()=>Y(A.id,`id`),children:`Retry`})]}):(0,O.jsx)(`p`,{className:`text-xs text-faint`,children:`No result stored for this job.`})]}),!Fe&&Ie,(0,O.jsx)(_e,{jobId:A.id},`logs-${A.id}`),Ne&&(0,O.jsx)(ue,{jobId:A.id},`children-${A.id}`),(0,O.jsx)(ve,{timeline:A.timeline}),(0,O.jsx)(le,{job:A})]}),(0,O.jsx)(`div`,{className:`order-first lg:order-none`,children:(0,O.jsx)(ae,{job:A,busy:he,act:ke})})]}):(0,O.jsx)(ne,{title:`No job loaded`,hint:`Enter a job ID above to inspect it.`})]})}function Q({k:e,v:t}){return(0,O.jsxs)(`div`,{children:[(0,O.jsx)(`dt`,{className:`text-[11px] uppercase tracking-wider text-faint`,children:e}),(0,O.jsx)(`dd`,{className:`text-fg`,children:t})]})}function De({value:e}){return(0,O.jsx)(`pre`,{className:`max-h-64 overflow-auto rounded-lg bg-surface-2 p-3 font-mono text-xs text-muted`,children:JSON.stringify(e??null,null,2)})}function Oe({value:e,filename:t}){return(0,O.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,O.jsx)(f,{value:JSON.stringify(e??null,null,2)}),(0,O.jsx)(m,{"aria-label":`Download JSON`,title:`Download JSON`,onClick:()=>w(t,e??null),children:(0,O.jsx)(x,{className:`size-3.5`})})]})}export{Ee as JobInspector};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e,t}from"./cn-CMFYpumL.js";import{f as n,g as r,r as i,t as a}from"./react-vendor-Bjui4wS4.js";import{A as o,B as s,J as c,T as ee,W as te,a as ne,b as l,c as u,ft as d,g as re,h as ie,l as ae,m as f,n as oe,o as se,st as p,w as m,x as h,y as ce,z as le}from"./index-Dr__4DsT.js";import{a as g}from"./form-DsUq0w8s.js";import{t as ue}from"./Pagination-eotgGQf9.js";import{r as de,t as _}from"./useServerActionGuard-CItj3hvh.js";import{t as fe}from"./exportFile-C7xhE8Yh.js";import{t as v}from"./jobActions-LQD4KfCc.js";var y=e(r(),1),b=a(),x=[`all`,`waiting`,`prioritized`,`active`,`delayed`,`waiting-children`,`paused`,`completed`,`failed`],S=25;function pe(e,t){return e===t?`${t} selected`:`${e} of ${t} selected match this filter`}function me(e,t){let n=new Set(e);for(let e of t)n.delete(e);return n}function he(e=0){return e>=10?{t:`HIGH`,c:`text-warning`}:e>=1?{t:`MEDIUM`,c:`text-blue-400`}:{t:`LOW`,c:`text-faint`}}function C(){let[e,r]=n(),[a,C]=(0,y.useState)(e.get(`queue`)??``),[w,ge]=(0,y.useState)(()=>{let t=e.get(`status`);return t&&x.includes(t)?t:`all`}),[T,_e]=(0,y.useState)(``),[E,D]=(0,y.useState)(0),[O,k]=(0,y.useState)(new Set),[ve,A]=(0,y.useState)(new Set),[j,M]=(0,y.useState)(!1),[N,P]=(0,y.useState)(null),{data:F,error:I,loading:ye,refetch:be}=o(()=>p.queuesSummary(),[],{intervalMs:3e4}),{data:L,error:R,refetch:xe}=o(()=>p.stats(),[],{intervalMs:1e4});(0,y.useEffect)(()=>{!a&&F?.length&&C(F[0].name)},[F,a]);let z=`${a}|${w}|${E}`,B=de(`jobs:${a}`),{data:V,error:H,loading:Se,refetch:U}=o((0,y.useCallback)(async()=>{if(!a)return{view:z,jobs:[]};let e=w===`all`?void 0:[w],t=await p.jobsList(a,e,S,E*S);return{view:z,jobs:(t.jobs??[]).map(e=>({...e,queue:e.queue??a}))}},[a,w,E,z]),[a,w,E]),W=V&&V.view===z?V.jobs:null;(0,y.useEffect)(()=>{A(new Set),M(!1),P(null)},[B.scopeKey]);let Ce=(W?.length??0)===S,G=(0,y.useMemo)(()=>{let e=T.trim().toLowerCase();return e?(W??[]).filter(t=>t.id.toLowerCase().includes(e)):W??[]},[W,T]),K=L?.stats,q=(0,y.useMemo)(()=>F?.reduce((e,t)=>e+(t.counts?.failed??0),0)??null,[F]),J=K&&q!=null?oe(K.completed,q):null,Y=e=>K?u(e):`—`,X=()=>D(0),we=(e,t)=>{let n={};e&&(n.queue=e),t!==`all`&&(n.status=t),r(n,{replace:!0})};(0,y.useEffect)(()=>{k(new Set)},[a,w,E]);let Te=e=>k(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),Z=G.length>0&&G.every(e=>O.has(e.id)),Ee=()=>k(()=>Z?new Set:new Set(G.map(e=>e.id))),De=async(e,t,n,r)=>{if(r&&!window.confirm(r))return;let i=B.begin(`job:${e.id}`);if(i){A(t=>new Set(t).add(e.id)),P(null);try{if(_(await n(),t),!i.isCurrent())return;P({ok:!0,text:`${t} ✓`}),d.success(`${t} ✓`,e.id),U()}catch(e){if(!i.isCurrent())return;P({ok:!1,text:`${t} failed: ${e.message}`}),d.error(`${t} failed`,e.message)}finally{i.finish()&&A(t=>{let n=new Set(t);return n.delete(e.id),n})}}},Oe=async(e,t,n,r)=>{let i=G.filter(e=>O.has(e.id)&&n(e));if(i.length===0||r&&!window.confirm(r(i.length)))return;let a=B.begin([`bulk`,...i.map(e=>`job:${e.id}`)]);if(a){M(!0),P(null);try{let n=await Promise.allSettled(i.map(async n=>{_(await t(n),`${e} ${n.id}`)}));if(!a.isCurrent())return;let r=n.filter(e=>e.status===`fulfilled`).length,o=n.length-r,s=`${e}: ${r} succeeded${o?`, ${o} failed`:``}`;P({ok:o===0,text:s}),o===0?d.success(s):d.error(s);let c=i.map(e=>e.id);k(e=>me(e,c)),U()}finally{a.finish()&&M(!1)}}},ke={promote:e=>v(e.state).promote},Q=G.filter(e=>O.has(e.id)),$={promote:Q.some(ke.promote)};return(0,b.jsxs)(`div`,{children:[(0,b.jsx)(ie,{title:`Jobs Explorer`,description:`Browse, inspect, and manage individual jobs.`,live:!!a&&W!=null&&!H&&!I&&!R,actions:(0,b.jsxs)(m,{size:`sm`,disabled:!W||G.length===0,onClick:()=>{if(G.length===0){d.info(`No jobs to export on this page`);return}let e=G.map(e=>({id:e.id,queue:e.queue??a,state:e.state??``,priority:e.priority??0,attempts:e.attempts??0,maxAttempts:e.maxAttempts??``,createdAt:e.createdAt?new Date(e.createdAt).toISOString():``,durationMs:e.startedAt&&e.completedAt?e.completedAt-e.startedAt:``}));fe(`jobs-${a}-${w}`,e,[`id`,`queue`,`state`,`priority`,`attempts`,`maxAttempts`,`createdAt`,`durationMs`])},children:[(0,b.jsx)(le,{className:`size-3.5`}),` Export CSV`]})}),I&&(0,b.jsx)(h,{onRetry:be,message:F?`Queue inventory refresh failed — showing the last successful queue totals. ${I.message}`:`Could not discover queues — ${I.message}. Select an existing queue from the URL or retry.`}),R&&(0,b.jsx)(h,{onRetry:xe,message:L?`Server-wide totals refresh failed — showing the last successful totals. ${R.message}`:`Server-wide job totals are unavailable — ${R.message}. The selected queue page may still be current.`}),(0,b.jsxs)(`div`,{className:`mb-6 grid grid-cols-2 gap-4 md:grid-cols-4 xl:grid-cols-8`,children:[(0,b.jsx)(f,{label:`Total`,value:K&&q!=null?u(K.completed+q+K.waiting+K.prioritized+K.active+K.delayed+K[`waiting-children`]):`—`,hint:`all queues`,compact:!0}),(0,b.jsx)(f,{label:`Waiting`,value:Y(K?.waiting),tone:`amber`,hint:`standard priority`,compact:!0}),(0,b.jsx)(f,{label:`Prioritized`,value:Y(K?.prioritized),tone:`amber`,compact:!0}),(0,b.jsx)(f,{label:`Active`,value:Y(K?.active),tone:`blue`,compact:!0}),(0,b.jsx)(f,{label:`Flow-blocked`,value:Y(K?.[`waiting-children`]),tone:`blue`,compact:!0}),(0,b.jsx)(f,{label:`Completed`,value:Y(K?.completed),tone:`green`,compact:!0}),(0,b.jsx)(f,{label:`Failed`,value:q==null?`—`:u(q),tone:q!=null&&q>0?`red`:`default`,compact:!0}),(0,b.jsx)(f,{label:`Error Rate`,value:J==null?`—`:ae(J),tone:J==null?`default`:J>.05?`red`:`green`,compact:!0})]}),(0,b.jsxs)(`div`,{className:`mb-4 flex flex-wrap items-center gap-3`,children:[(0,b.jsx)(`div`,{className:`w-48`,children:(0,b.jsx)(g,{value:a,"aria-label":`Queue`,name:`jobs-queue`,autoComplete:`off`,onChange:e=>{C(e.target.value),X(),we(e.target.value,w)},children:(F??[]).map(e=>(0,b.jsx)(`option`,{value:e.name,children:e.name},e.name))})}),(0,b.jsx)(`div`,{className:`w-48`,children:(0,b.jsx)(g,{"aria-label":`Job state`,name:`jobs-state`,value:w,onChange:e=>{let t=e.target.value;ge(t),X(),we(a,t)},children:x.map(e=>(0,b.jsx)(`option`,{value:e,children:e===`all`?`All states`:e},e))})}),(0,b.jsxs)(`div`,{className:`relative ml-auto min-w-56 flex-1 md:max-w-xs`,children:[(0,b.jsx)(c,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-faint`}),(0,b.jsx)(`input`,{value:T,onChange:e=>_e(e.target.value),placeholder:`Filter this page by ID…`,"aria-label":`Filter by job ID`,name:`jobs-id-filter`,autoComplete:`off`,className:`h-9 w-full rounded-lg border border-line bg-surface pl-9 pr-3 text-sm text-fg placeholder:text-faint focus:border-accent/60 focus:outline-none focus:ring-2 focus:ring-accent/30`})]})]}),O.size>0&&(0,b.jsxs)(`div`,{className:`mb-3 flex flex-wrap items-center gap-2 rounded-lg border border-line bg-surface-2 px-4 py-2 text-sm`,children:[(0,b.jsx)(`span`,{className:`mr-1 text-muted`,children:pe(Q.length,O.size)}),$.promote&&(0,b.jsx)(m,{size:`sm`,disabled:j,onClick:()=>Oe(`Promote`,e=>p.promoteJob(e.id),ke.promote),children:`Promote selected`}),!$.promote&&(0,b.jsx)(`span`,{className:`text-xs text-faint`,children:Q.length===0?`The selected jobs are hidden by the filter — clear it to act on them.`:`No actions apply to the selected job states.`})]}),N&&(0,b.jsx)(`div`,{role:`status`,className:t(`mb-3 text-sm`,N.ok?`text-success`:`text-danger`),children:N.text}),H&&W&&(0,b.jsx)(h,{message:`Job refresh failed — showing the last successful page.`,onRetry:U}),H&&!W?(0,b.jsx)(ce,{error:H,onRetry:U}):ye&&!F&&!a&&!I?(0,b.jsx)(l,{label:`Discovering queues…`}):Se&&!W?(0,b.jsx)(l,{label:`Loading jobs…`}):(0,b.jsxs)(b.Fragment,{children:[a&&(0,b.jsxs)(`div`,{className:`mb-2 flex items-center gap-2 text-sm`,children:[(0,b.jsx)(`span`,{className:`text-faint`,children:`Jobs in queue`}),(0,b.jsx)(`span`,{className:`rounded-md bg-surface-2 px-2 py-0.5 font-mono text-xs text-fg`,children:a})]}),(0,b.jsx)(`div`,{className:`overflow-x-auto rounded-xl border border-line bg-surface`,children:(0,b.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,b.jsx)(`thead`,{children:(0,b.jsxs)(`tr`,{className:`border-b border-line text-left text-[11px] uppercase tracking-wider text-faint`,children:[(0,b.jsx)(`th`,{scope:`col`,className:`w-10 px-5 py-3`,children:(0,b.jsx)(`input`,{type:`checkbox`,checked:Z,ref:e=>{e&&(e.indeterminate=O.size>0&&!Z)},"aria-checked":O.size>0&&!Z?`mixed`:Z,onChange:Ee,"aria-label":`Select all jobs on page`,className:`accent-accent`})}),(0,b.jsx)(`th`,{scope:`col`,className:`px-5 py-3 font-medium`,children:`Job ID`}),(0,b.jsx)(`th`,{scope:`col`,className:`px-5 py-3 font-medium`,children:`Status`}),(0,b.jsx)(`th`,{scope:`col`,className:`px-5 py-3 font-medium`,children:`Priority`}),(0,b.jsx)(`th`,{scope:`col`,className:`px-5 py-3 text-right font-medium`,children:`Created`}),(0,b.jsx)(`th`,{scope:`col`,className:`px-5 py-3 text-right font-medium`,children:`Duration`}),(0,b.jsx)(`th`,{scope:`col`,className:`w-28 px-5 py-3 text-right font-medium`,children:`Actions`})]})}),(0,b.jsx)(`tbody`,{children:G.length===0?(0,b.jsx)(`tr`,{children:(0,b.jsx)(`td`,{colSpan:7,className:`px-5 py-12 text-center text-sm text-faint`,children:T.trim()?`No jobs on this page match your ID filter.`:a?`No jobs found.`:I?`Queue discovery failed. Retry above.`:`Select a queue.`})}):G.map(e=>{let n=he(e.priority),r=v(e.state),a=j||ve.has(e.id);return(0,b.jsxs)(`tr`,{className:`border-b border-line last:border-0 hover:bg-surface-2/40`,children:[(0,b.jsx)(`td`,{className:`px-5 py-3`,children:(0,b.jsx)(`input`,{type:`checkbox`,checked:O.has(e.id),onChange:()=>Te(e.id),"aria-label":`Select job ${e.id}`,className:`accent-accent`})}),(0,b.jsx)(`td`,{className:`px-5 py-3 font-mono text-xs text-accent/90`,children:(0,b.jsx)(`span`,{className:`block max-w-[16rem] truncate`,title:e.id,children:e.id})}),(0,b.jsx)(`td`,{className:`px-5 py-3`,children:(0,b.jsx)(re,{status:String(e.state??`waiting`)})}),(0,b.jsx)(`td`,{className:t(`px-5 py-3 text-xs font-semibold`,n.c),children:n.t}),(0,b.jsx)(`td`,{className:`px-5 py-3 text-right text-faint`,children:ne(e.createdAt)}),(0,b.jsx)(`td`,{className:`px-5 py-3 text-right tnum text-muted`,children:se(e.startedAt&&e.completedAt?e.completedAt-e.startedAt:void 0)}),(0,b.jsx)(`td`,{className:`px-5 py-3`,children:(0,b.jsxs)(`div`,{className:`flex justify-end gap-1`,children:[(0,b.jsx)(i,{to:`/job?id=${encodeURIComponent(e.id)}`,"aria-label":`Inspect job ${e.id}`,className:`inline-flex size-8 items-center justify-center rounded-lg text-muted transition-colors hover:bg-surface-2 hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50`,children:(0,b.jsx)(s,{className:`size-3.5`})}),r.promote&&(0,b.jsx)(ee,{"aria-label":`Promote job`,disabled:a,onClick:()=>De(e,`Promote`,()=>p.promoteJob(e.id)),children:(0,b.jsx)(te,{className:`size-3.5`})})]})})]},e.id)})})]})}),(0,b.jsx)(ue,{page:E,pageSize:S,hasNext:Ce,onPageChange:D,label:`jobs`})]})]})}export{C as JobsPro};
|