@apisurf/wireui 0.1.2 → 0.1.4

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.
Files changed (51) hide show
  1. package/README.md +42 -26
  2. package/bin/wireui.mjs +1 -1
  3. package/dist/nitro.json +1 -1
  4. package/dist/public/assets/environments-CpzEnLw2.js +1 -0
  5. package/dist/public/assets/feed-B8L4GK9D.js +1 -0
  6. package/dist/public/assets/globals-D_ltS-iC.css +1 -0
  7. package/dist/public/assets/history-BIXZHMWn.js +1 -0
  8. package/dist/public/assets/index-3VfD7Ktf.js +11 -0
  9. package/dist/public/assets/kv-table-Dv6o68aD.js +2 -0
  10. package/dist/public/assets/preload-helper-CIs162tl.js +3 -0
  11. package/dist/public/assets/query-DpztusaI.js +19 -0
  12. package/dist/public/assets/requests._requestId-Byq4gM_2.js +1 -0
  13. package/dist/public/assets/rolldown-runtime-CbXtAM7H.js +1 -0
  14. package/dist/public/assets/routes-C9SXJh8z.js +1 -0
  15. package/dist/public/assets/runs._runId-CMFvexqY.js +1 -0
  16. package/dist/public/assets/scoped-CiNsRvyC.js +1 -0
  17. package/dist/public/assets/session-header-DMR_hFkk.js +1 -0
  18. package/dist/public/assets/sessions-C-F6Wmmg.js +1 -0
  19. package/dist/public/assets/split-Ddiw3mOT.js +1 -0
  20. package/dist/public/assets/tabs-C1EijW_Z.js +2 -0
  21. package/dist/server/_ssr/{api-Dw1Zb_PK.mjs → api-DUem3i24.mjs} +28 -17
  22. package/dist/server/_ssr/environments-BFBtf7iL.mjs +146 -0
  23. package/dist/server/_ssr/feed-BgweoqQ4.mjs +108 -0
  24. package/dist/server/_ssr/history-57VNXvbE.mjs +195 -0
  25. package/dist/server/_ssr/{kv-table-DQUkoItO.mjs → kv-table-BONnSOLb.mjs} +2 -2
  26. package/dist/server/_ssr/{router-CPcgc_kh.mjs → prefs-iPvYd_Vz.mjs} +246 -1551
  27. package/dist/server/_ssr/{query-D4so9xiY.mjs → query-D6nNoSN3.mjs} +7 -6
  28. package/dist/server/_ssr/{requests._requestId-BFukRwqL.mjs → requests._requestId-bXoTBGVj.mjs} +7 -23
  29. package/dist/server/_ssr/router-ClsXvW-b.mjs +1068 -0
  30. package/dist/server/_ssr/{routes-DaV9vGHn.mjs → routes-CrmwJhiA.mjs} +18 -8
  31. package/dist/server/_ssr/runs._runId-DM5Y8e6b.mjs +850 -0
  32. package/dist/server/_ssr/{scoped-CnQ56K8h.mjs → scoped-CNX8KOhL.mjs} +2 -2
  33. package/dist/server/_ssr/session-header-BYy6LaSU.mjs +153 -0
  34. package/dist/server/_ssr/{collections-CqidTQpw.mjs → sessions-wsD0b1zm.mjs} +35 -72
  35. package/dist/server/_ssr/{split-DWrMIs7K.mjs → split-qGbYHKc9.mjs} +2 -2
  36. package/dist/server/_ssr/ssr.mjs +10 -14
  37. package/dist/server/_tanstack-start-manifest_v-Ag2qLfrP.mjs +79 -0
  38. package/dist/server/index.mjs +100 -51
  39. package/package.json +8 -6
  40. package/dist/public/assets/collections-CLHcfRfi.js +0 -1
  41. package/dist/public/assets/globals-CZiNFGaK.css +0 -1
  42. package/dist/public/assets/index-D5VFd_3H.js +0 -14
  43. package/dist/public/assets/kv-table-oB5gcq0i.js +0 -2
  44. package/dist/public/assets/query-BKAhHNIi.js +0 -19
  45. package/dist/public/assets/requests._requestId-Bu7E2eoI.js +0 -1
  46. package/dist/public/assets/routes-DDY2CfzA.js +0 -1
  47. package/dist/public/assets/runs._runId-CzwtVjYq.js +0 -1
  48. package/dist/public/assets/scoped-DB8raIWx.js +0 -1
  49. package/dist/public/assets/split-Br1RX2I4.js +0 -1
  50. package/dist/server/_ssr/runs._runId-Df_LmPHa.mjs +0 -836
  51. package/dist/server/_tanstack-start-manifest_v-CARKjHfs.mjs +0 -50
@@ -0,0 +1,1068 @@
1
+ import { __toESM } from "../_runtime.mjs";
2
+ import { HeadContent, Link, Outlet, Scripts, createFileRoute, createRootRoute, createRouter, getRouteApi, lazyRouteComponent, notFound, require_jsx_runtime, require_react, useNavigate, useRouterState } from "../_libs/@tanstack/react-router+[...].mjs";
3
+ import { TSS_SERVER_FUNCTION, createServerFn, getServerFnById } from "./ssr.mjs";
4
+ import { Dot, Empty, FilterInput, IconButton, IconChevronLeft, IconChevronRight, IconClose, IconDatabase, IconEnvironments, IconHistory, IconMonitor, IconMoon, IconOverview, IconRefresh, IconRequest, IconRun, IconSessions, IconSplitSide, IconSplitStacked, IconSun, MethodBadge, NotFound, PrefsProvider, RouteError, THEME_BOOT_SCRIPT, TabsProvider, basename, css, cx, formatAgo, formatBytes, formatCount, matchesEnv, mono, runTone, runVerdict, tabKey, truncate, useNow, usePrefs, useTabs } from "./prefs-iPvYd_Vz.mjs";
5
+ //#region node_modules/.nitro/vite/services/ssr/assets/api-BM3HZHc4.js
6
+ var createSsrRpc = (functionId) => {
7
+ const url = "/_serverFn/" + functionId;
8
+ const serverFnMeta = { id: functionId };
9
+ const fn = async (...args) => {
10
+ return (await getServerFnById(functionId, { origin: "server" }))(...args);
11
+ };
12
+ return Object.assign(fn, {
13
+ url,
14
+ serverFnMeta,
15
+ [TSS_SERVER_FUNCTION]: true
16
+ });
17
+ };
18
+ function record(input) {
19
+ return input && typeof input === "object" ? input : {};
20
+ }
21
+ function id(value, name) {
22
+ const n = typeof value === "string" ? Number(value) : value;
23
+ if (typeof n !== "number" || !Number.isInteger(n) || n <= 0) throw new Error(`${name} must be a positive integer`);
24
+ return n;
25
+ }
26
+ function optionalString(value) {
27
+ return typeof value === "string" ? value : void 0;
28
+ }
29
+ /** `undefined` → every environment, `null` → runs recorded without one. */
30
+ function env(value) {
31
+ if (value === null) return null;
32
+ return typeof value === "string" ? value : void 0;
33
+ }
34
+ /** The open database when its schema is one these queries can read, else null. */
35
+ var getWorkspace = createServerFn({ method: "GET" }).handler(createSsrRpc("65bc418eb60581304ebde68d2b8b775b58aa758789bcdd2e616a2bdd5657ef20"));
36
+ var getOverview = createServerFn({ method: "GET" }).validator((input) => ({ env: env(record(input).env) })).handler(createSsrRpc("edb0cb28f3af0347a499a4c076ecc5f8247f0ace0fb524957f40f6a706d7224d"));
37
+ var getHistory = createServerFn({ method: "GET" }).validator((input) => {
38
+ const r = record(input);
39
+ const kind = r.kind === "http" || r.kind === "stream" ? r.kind : void 0;
40
+ return {
41
+ q: optionalString(r.q),
42
+ env: env(r.env),
43
+ kind,
44
+ failed: r.failed === true,
45
+ bodies: r.bodies === true,
46
+ limit: typeof r.limit === "number" ? r.limit : void 0
47
+ };
48
+ }).handler(createSsrRpc("c1e4e973ed505d1515bcb9192482c65b1680975a5daa6973befb704515a618e3"));
49
+ var getScript = createServerFn({ method: "GET" }).validator((input) => {
50
+ const r = record(input);
51
+ const entry = optionalString(r.entry);
52
+ if (!entry) throw new Error("entry is required");
53
+ return {
54
+ entry,
55
+ env: env(r.env)
56
+ };
57
+ }).handler(createSsrRpc("5eff62884e56f81742c81b44dc7dcd1afc2e67323a30591a8b94b8895eda0dc9"));
58
+ var getRun = createServerFn({ method: "GET" }).validator((input) => ({ runId: id(record(input).runId, "runId") })).handler(createSsrRpc("56c165307cd91159eb72bfa882932f9552f05a5bbd6b5725f0fd5f4ad6b8295d"));
59
+ var getRequest = createServerFn({ method: "GET" }).validator((input) => ({ requestId: id(record(input).requestId, "requestId") })).handler(createSsrRpc("3772b5ea3e53d85a63e4df11f128b1c907e508d82cca6e71e6ee48dba1664133"));
60
+ var getSchema = createServerFn({ method: "GET" }).handler(createSsrRpc("06ff3639e7164884f56665ea621dc233dbfc78fa1557b1cb20105ff2fa90521e"));
61
+ var runSql = createServerFn({ method: "POST" }).validator((input) => {
62
+ const sql = optionalString(record(input).sql)?.trim();
63
+ if (!sql) throw new Error("sql is required");
64
+ return { sql };
65
+ }).handler(createSsrRpc("0f45629470ab3fbe618e9693d8685920d6ce48b2384512e5d9eb88f6b46ec2d9"));
66
+ //#endregion
67
+ //#region node_modules/.nitro/vite/services/ssr/assets/router-ClsXvW-b.js
68
+ var import_react = /* @__PURE__ */ __toESM(require_react());
69
+ var import_jsx_runtime = require_jsx_runtime();
70
+ var __defProp = Object.defineProperty;
71
+ var __exportAll = (all, no_symbols) => {
72
+ let target = {};
73
+ for (var name in all) __defProp(target, name, {
74
+ get: all[name],
75
+ enumerable: true
76
+ });
77
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
78
+ return target;
79
+ };
80
+ function useActiveEntry() {
81
+ return useRouterState({ select: (state) => {
82
+ let entry = null;
83
+ for (const match of state.matches) {
84
+ const data = match.loaderData;
85
+ if (!data || typeof data !== "object") continue;
86
+ if (data.run) entry = data.run.entry;
87
+ if (data.script) entry = data.script.entry;
88
+ }
89
+ return entry;
90
+ } });
91
+ }
92
+ var root$2 = getRouteApi("__root__");
93
+ /** Every session in scope, most recently run first. */
94
+ function useSessions() {
95
+ const ws = root$2.useLoaderData();
96
+ const { prefs } = usePrefs();
97
+ return import_react.useMemo(() => {
98
+ const byEntry = /* @__PURE__ */ new Map();
99
+ for (const row of ws.scriptEnvs) {
100
+ if (!matchesEnv(prefs.env, row.env)) continue;
101
+ const seen = byEntry.get(row.entry);
102
+ if (!seen) byEntry.set(row.entry, {
103
+ runCount: row.run_count,
104
+ latest: row
105
+ });
106
+ else {
107
+ seen.runCount += row.run_count;
108
+ if (row.last_started_at > seen.latest.last_started_at) seen.latest = row;
109
+ }
110
+ }
111
+ const out = [];
112
+ for (const script of ws.scripts) {
113
+ const scoped = byEntry.get(script.entry);
114
+ if (scoped) out.push({
115
+ script,
116
+ ...scoped
117
+ });
118
+ }
119
+ return out.toSorted((a, b) => b.latest.last_started_at - a.latest.last_started_at);
120
+ }, [
121
+ ws.scripts,
122
+ ws.scriptEnvs,
123
+ prefs.env
124
+ ]);
125
+ }
126
+ /** One session, or null when it has no runs in the selected environment. */
127
+ function useSession(entry) {
128
+ return useSessions().find((c) => c.script.entry === entry) ?? null;
129
+ }
130
+ var root$1 = getRouteApi("__root__");
131
+ var row = css({
132
+ display: "flex",
133
+ alignItems: "center",
134
+ gap: "1.5",
135
+ h: "26px",
136
+ pl: "2",
137
+ pr: "2",
138
+ rounded: "sm",
139
+ cursor: "pointer",
140
+ color: "fg",
141
+ textDecoration: "none",
142
+ userSelect: "none",
143
+ minW: "0",
144
+ _hover: { bg: "hover" },
145
+ "&[data-active=true]": { bg: "selected" }
146
+ });
147
+ var groupHeading = css({
148
+ fontSize: "10.5px",
149
+ color: "faint",
150
+ px: "2",
151
+ pt: "1.5",
152
+ pb: "0.5",
153
+ fontFamily: "mono"
154
+ });
155
+ function SessionsPanel({ filterRef }) {
156
+ const ws = root$1.useLoaderData();
157
+ const sessions = useSessions();
158
+ const active = useActiveEntry();
159
+ const [filter, setFilter] = import_react.useState("");
160
+ const needle = filter.trim().toLowerCase();
161
+ const groups = import_react.useMemo(() => {
162
+ const byDir = /* @__PURE__ */ new Map();
163
+ for (const session of sessions) {
164
+ const { script } = session;
165
+ if (needle && !script.rel.toLowerCase().includes(needle) && !(script.label ?? "").toLowerCase().includes(needle)) continue;
166
+ const list = byDir.get(script.dir) ?? [];
167
+ list.push(session);
168
+ byDir.set(script.dir, list);
169
+ }
170
+ return [...byDir.entries()];
171
+ }, [sessions, needle]);
172
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
173
+ className: css({
174
+ display: "flex",
175
+ flexDir: "column",
176
+ h: "full",
177
+ minH: "0"
178
+ }),
179
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
180
+ className: css({
181
+ px: "2.5",
182
+ pb: "2",
183
+ flexShrink: 0
184
+ }),
185
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FilterInput, {
186
+ ref: filterRef,
187
+ placeholder: "Filter sessions",
188
+ shortcut: "/",
189
+ value: filter,
190
+ onChange: (e) => setFilter(e.target.value)
191
+ })
192
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
193
+ className: css({
194
+ flex: "1",
195
+ minH: "0",
196
+ overflow: "auto",
197
+ px: "1.5",
198
+ pb: "3"
199
+ }),
200
+ children: groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, {
201
+ title: ws.scripts.length === 0 ? "No sessions yet" : "No matches",
202
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconSessions, { size: 20 }),
203
+ children: ws.scripts.length === 0 ? "Every script you record with wire execute becomes a session here." : "No script matches the filter in this environment."
204
+ }) : groups.map(([dir, list]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
205
+ className: css({ mb: "2" }),
206
+ children: [dir ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
207
+ title: dir,
208
+ className: cx(truncate, groupHeading),
209
+ children: dir
210
+ }) : null, list.map((session) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SessionRow, {
211
+ session,
212
+ active: active === session.script.entry
213
+ }, session.script.entry))]
214
+ }, dir))
215
+ })]
216
+ });
217
+ }
218
+ function SessionRow({ session, active }) {
219
+ const ws = root$1.useLoaderData();
220
+ const now = useNow(ws.now, 6e4);
221
+ const { pin } = useTabs();
222
+ const { script, runCount, latest } = session;
223
+ const tone = runTone(latest);
224
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
225
+ to: "/sessions",
226
+ search: { entry: script.entry },
227
+ "data-active": active,
228
+ className: row,
229
+ onDoubleClick: () => pin(tabKey.script(script.entry)),
230
+ title: `${script.rel} · last ran ${formatAgo(now, latest.last_started_at)}`,
231
+ children: [
232
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
233
+ className: css({
234
+ color: "muted",
235
+ display: "inline-flex"
236
+ }),
237
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconSessions, { size: 14 })
238
+ }),
239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
240
+ className: cx(truncate, css({
241
+ flex: "1",
242
+ fontWeight: "500"
243
+ })),
244
+ children: script.file
245
+ }),
246
+ tone === "bad" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dot, {
247
+ tone: "bad",
248
+ title: `Latest run: ${runVerdict(latest)}`
249
+ }) : null,
250
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
251
+ className: css({
252
+ fontSize: "11px",
253
+ color: "faint",
254
+ fontVariantNumeric: "tabular-nums"
255
+ }),
256
+ title: `${runCount} runs`,
257
+ children: runCount
258
+ })
259
+ ]
260
+ });
261
+ }
262
+ var root = getRouteApi("__root__");
263
+ function Shell({ children }) {
264
+ const { prefs } = usePrefs();
265
+ const filterRef = import_react.useRef(null);
266
+ useSlashToFilter(filterRef);
267
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
268
+ className: css({
269
+ display: "flex",
270
+ flexDir: "column",
271
+ h: "100vh",
272
+ bg: "chrome"
273
+ }),
274
+ children: [
275
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TopBar, {}),
276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
277
+ className: css({
278
+ display: "flex",
279
+ flex: "1",
280
+ minH: "0"
281
+ }),
282
+ children: [
283
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Rail, {}),
284
+ prefs.sidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sidebar, { filterRef }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsedSidebar, {}),
285
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", {
286
+ className: css({
287
+ display: "flex",
288
+ flexDir: "column",
289
+ flex: "1",
290
+ minW: "0",
291
+ bg: "canvas",
292
+ borderLeft: "1px solid",
293
+ borderTop: "1px solid",
294
+ borderColor: "line",
295
+ roundedTopLeft: "lg",
296
+ overflow: "hidden"
297
+ }),
298
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabStrip, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
299
+ className: css({
300
+ flex: "1",
301
+ minH: "0",
302
+ display: "flex",
303
+ flexDir: "column"
304
+ }),
305
+ children
306
+ })]
307
+ })
308
+ ]
309
+ }),
310
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusBar, {})
311
+ ]
312
+ });
313
+ }
314
+ /**
315
+ * `/` focuses a filter, as in most tools with one: the page's own when it has
316
+ * one (History), else the session sidebar's.
317
+ */
318
+ function useSlashToFilter(ref) {
319
+ const { prefs, set } = usePrefs();
320
+ import_react.useEffect(() => {
321
+ const onKey = (event) => {
322
+ if (event.key !== "/" || event.metaKey || event.ctrlKey || event.altKey) return;
323
+ const target = event.target;
324
+ if (target && (target.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(target.tagName))) return;
325
+ event.preventDefault();
326
+ const own = document.querySelector("main input[data-page-filter]");
327
+ if (own) {
328
+ own.focus();
329
+ return;
330
+ }
331
+ if (!prefs.sidebarOpen) set("sidebarOpen", true);
332
+ window.requestAnimationFrame(() => ref.current?.focus());
333
+ };
334
+ window.addEventListener("keydown", onKey);
335
+ return () => window.removeEventListener("keydown", onKey);
336
+ }, [
337
+ prefs.sidebarOpen,
338
+ set,
339
+ ref
340
+ ]);
341
+ }
342
+ var THEME_NEXT = {
343
+ system: "light",
344
+ light: "dark",
345
+ dark: "system"
346
+ };
347
+ function TopBar() {
348
+ const ws = root.useLoaderData();
349
+ const { prefs, set, refresh } = usePrefs();
350
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
351
+ className: css({
352
+ display: "flex",
353
+ alignItems: "center",
354
+ gap: "3",
355
+ h: "44px",
356
+ px: "3",
357
+ flexShrink: 0
358
+ }),
359
+ children: [
360
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
361
+ to: "/",
362
+ className: css({
363
+ display: "flex",
364
+ alignItems: "center",
365
+ gap: "2",
366
+ color: "fg",
367
+ textDecoration: "none"
368
+ }),
369
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
370
+ src: "/favicon.svg",
371
+ alt: "",
372
+ width: 22,
373
+ height: 22
374
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
375
+ className: css({
376
+ fontWeight: "700",
377
+ letterSpacing: "-0.01em",
378
+ fontSize: "14px"
379
+ }),
380
+ children: ["wire", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
381
+ className: css({
382
+ color: "muted",
383
+ fontWeight: "500"
384
+ }),
385
+ children: "ui"
386
+ })]
387
+ })]
388
+ }),
389
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
390
+ className: css({ color: "lineStrong" }),
391
+ children: "/"
392
+ }),
393
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
394
+ title: ws.path,
395
+ className: cx(mono, truncate, css({
396
+ color: "muted",
397
+ minW: "0"
398
+ })),
399
+ children: basename(ws.path)
400
+ }),
401
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
402
+ className: css({
403
+ ml: "auto",
404
+ display: "flex",
405
+ alignItems: "center",
406
+ gap: "1.5"
407
+ }),
408
+ children: [
409
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnvSelect, {}),
410
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
411
+ type: "button",
412
+ "aria-pressed": prefs.live,
413
+ onClick: () => set("live", !prefs.live),
414
+ title: prefs.live ? "Live: re-reading the file every 2 s" : "Follow the file as runs write to it",
415
+ className: css({
416
+ display: "inline-flex",
417
+ alignItems: "center",
418
+ gap: "1.5",
419
+ h: "28px",
420
+ px: "2.5",
421
+ rounded: "md",
422
+ border: "1px solid",
423
+ borderColor: "line",
424
+ bg: "raised",
425
+ color: "muted",
426
+ cursor: "pointer",
427
+ fontSize: "12px",
428
+ fontWeight: "500",
429
+ _hover: { color: "fg" },
430
+ "&[aria-pressed=true]": {
431
+ color: "ok",
432
+ borderColor: "ok",
433
+ bg: "okSoft"
434
+ }
435
+ }),
436
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: cx(css({
437
+ w: "7px",
438
+ h: "7px",
439
+ rounded: "full",
440
+ bg: "faint"
441
+ }), prefs.live && css({
442
+ bg: "ok",
443
+ animation: "pulse 1.6s ease-in-out infinite"
444
+ })) }), "Live"]
445
+ }),
446
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, {
447
+ label: "Refresh",
448
+ onClick: refresh,
449
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconRefresh, {})
450
+ }),
451
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, {
452
+ label: prefs.layout === "side" ? "Stack request above response" : "Request and response side by side",
453
+ onClick: () => set("layout", prefs.layout === "side" ? "stacked" : "side"),
454
+ children: prefs.layout === "side" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconSplitSide, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconSplitStacked, {})
455
+ }),
456
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, {
457
+ label: `Theme: ${prefs.theme}`,
458
+ onClick: () => set("theme", THEME_NEXT[prefs.theme]),
459
+ children: prefs.theme === "system" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconMonitor, {}) : prefs.theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconSun, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconMoon, {})
460
+ })
461
+ ]
462
+ })
463
+ ]
464
+ });
465
+ }
466
+ function EnvSelect() {
467
+ const ws = root.useLoaderData();
468
+ const { prefs, set } = usePrefs();
469
+ const known = ws.envs.map((e) => e.env ?? "");
470
+ const value = prefs.env === "*" || known.includes(prefs.env) ? prefs.env : "*";
471
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
472
+ className: css({
473
+ display: "inline-flex",
474
+ alignItems: "center",
475
+ gap: "1.5",
476
+ h: "28px",
477
+ pl: "2",
478
+ pr: "1",
479
+ rounded: "md",
480
+ border: "1px solid",
481
+ borderColor: value === "*" ? "line" : "accent",
482
+ bg: value === "*" ? "raised" : "accentSoft",
483
+ color: value === "*" ? "muted" : "accent"
484
+ }),
485
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconEnvironments, { size: 14 }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
486
+ "aria-label": "Environment",
487
+ value,
488
+ onChange: (e) => set("env", e.target.value),
489
+ className: css({
490
+ border: "none",
491
+ bg: "transparent",
492
+ outline: "none",
493
+ fontSize: "12px",
494
+ fontWeight: "500",
495
+ color: "fg",
496
+ cursor: "pointer",
497
+ maxW: "180px"
498
+ }),
499
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
500
+ value: "*",
501
+ children: "All environments"
502
+ }), ws.envs.map((e) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
503
+ value: e.env ?? "",
504
+ children: e.env ?? "No environment"
505
+ }, e.env ?? ""))]
506
+ })]
507
+ });
508
+ }
509
+ var railButton = css({
510
+ display: "flex",
511
+ flexDir: "column",
512
+ alignItems: "center",
513
+ gap: "0.5",
514
+ w: "56px",
515
+ py: "1.5",
516
+ rounded: "md",
517
+ border: "none",
518
+ bg: "transparent",
519
+ color: "muted",
520
+ cursor: "pointer",
521
+ fontSize: "10px",
522
+ fontWeight: "500",
523
+ textDecoration: "none",
524
+ _hover: {
525
+ color: "fg",
526
+ bg: "hover"
527
+ },
528
+ "&[data-active=true]": {
529
+ color: "fg",
530
+ bg: "hover"
531
+ },
532
+ "&[data-active=true] svg": { color: "accent" }
533
+ });
534
+ /** The pages, in the order the rail lists them. */
535
+ var PAGES = [
536
+ {
537
+ to: "/",
538
+ label: "Overview",
539
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconOverview, { size: 18 }),
540
+ exact: true
541
+ },
542
+ {
543
+ to: "/history",
544
+ label: "History",
545
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconHistory, { size: 18 }),
546
+ exact: false
547
+ },
548
+ {
549
+ to: "/environments",
550
+ label: "Envs",
551
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconEnvironments, { size: 18 }),
552
+ exact: false
553
+ },
554
+ {
555
+ to: "/query",
556
+ label: "SQL",
557
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconDatabase, { size: 18 }),
558
+ exact: false
559
+ }
560
+ ];
561
+ function Rail() {
562
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", {
563
+ "aria-label": "Sections",
564
+ className: css({
565
+ display: "flex",
566
+ flexDir: "column",
567
+ alignItems: "center",
568
+ gap: "1",
569
+ w: "64px",
570
+ pt: "1",
571
+ pb: "2",
572
+ flexShrink: 0
573
+ }),
574
+ children: PAGES.map((page) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
575
+ to: page.to,
576
+ className: railButton,
577
+ activeProps: { "data-active": true },
578
+ activeOptions: {
579
+ exact: page.exact,
580
+ includeSearch: false
581
+ },
582
+ children: [page.icon, page.label]
583
+ }, page.to))
584
+ });
585
+ }
586
+ var MIN_SIDEBAR = 220;
587
+ var MAX_SIDEBAR = 560;
588
+ function Sidebar({ filterRef }) {
589
+ const { prefs, set } = usePrefs();
590
+ const [dragging, setDragging] = import_react.useState(false);
591
+ const [width, setWidth] = import_react.useState(prefs.sidebarWidth);
592
+ import_react.useEffect(() => setWidth(prefs.sidebarWidth), [prefs.sidebarWidth]);
593
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
594
+ className: css({
595
+ position: "relative",
596
+ display: "flex",
597
+ flexDir: "column",
598
+ flexShrink: 0,
599
+ minH: "0",
600
+ pt: "1"
601
+ }),
602
+ style: { width },
603
+ children: [
604
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
605
+ className: css({
606
+ display: "flex",
607
+ alignItems: "center",
608
+ justifyContent: "space-between",
609
+ h: "30px",
610
+ pl: "3",
611
+ pr: "1.5",
612
+ flexShrink: 0
613
+ }),
614
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
615
+ className: css({
616
+ fontWeight: "600",
617
+ fontSize: "12px"
618
+ }),
619
+ children: "Sessions"
620
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, {
621
+ label: "Collapse sessions",
622
+ onClick: () => set("sidebarOpen", false),
623
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconChevronLeft, { size: 14 })
624
+ })]
625
+ }),
626
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
627
+ className: css({
628
+ flex: "1",
629
+ minH: "0"
630
+ }),
631
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SessionsPanel, { filterRef })
632
+ }),
633
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
634
+ role: "separator",
635
+ "aria-orientation": "vertical",
636
+ "aria-label": "Resize sidebar",
637
+ onPointerDown: (e) => {
638
+ e.preventDefault();
639
+ e.target.setPointerCapture(e.pointerId);
640
+ setDragging(true);
641
+ },
642
+ onPointerMove: (e) => {
643
+ if (!dragging) return;
644
+ const aside = e.target.parentElement;
645
+ if (!aside) return;
646
+ const left = aside.getBoundingClientRect().left;
647
+ setWidth(Math.min(MAX_SIDEBAR, Math.max(MIN_SIDEBAR, e.clientX - left)));
648
+ },
649
+ onPointerUp: () => {
650
+ if (!dragging) return;
651
+ setDragging(false);
652
+ set("sidebarWidth", width);
653
+ },
654
+ className: cx(css({
655
+ position: "absolute",
656
+ top: "0",
657
+ bottom: "0",
658
+ right: "-3px",
659
+ w: "6px",
660
+ cursor: "col-resize",
661
+ zIndex: "2",
662
+ _hover: {
663
+ bg: "accent",
664
+ opacity: .4
665
+ }
666
+ }), dragging && css({
667
+ bg: "accent",
668
+ opacity: .4
669
+ }))
670
+ })
671
+ ]
672
+ });
673
+ }
674
+ /** What the sidebar leaves when collapsed: a strip that expands it again. */
675
+ function CollapsedSidebar() {
676
+ const { set } = usePrefs();
677
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
678
+ type: "button",
679
+ "aria-label": "Expand sessions",
680
+ title: "Expand sessions",
681
+ onClick: () => set("sidebarOpen", true),
682
+ className: css({
683
+ display: "flex",
684
+ flexDir: "column",
685
+ alignItems: "center",
686
+ gap: "2",
687
+ w: "28px",
688
+ pt: "2",
689
+ flexShrink: 0,
690
+ border: "none",
691
+ bg: "transparent",
692
+ color: "muted",
693
+ cursor: "pointer",
694
+ rounded: "md",
695
+ _hover: {
696
+ color: "fg",
697
+ bg: "hover"
698
+ }
699
+ }),
700
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconChevronRight, { size: 14 }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
701
+ className: css({
702
+ writingMode: "vertical-rl",
703
+ fontSize: "12px",
704
+ fontWeight: "600",
705
+ letterSpacing: "0.02em"
706
+ }),
707
+ children: "Sessions"
708
+ })]
709
+ });
710
+ }
711
+ function TabStrip() {
712
+ const { tabs, activeKey, pin, close } = useTabs();
713
+ const navigate = useNavigate();
714
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
715
+ role: "tablist",
716
+ "aria-label": "Open tabs",
717
+ className: css({
718
+ display: "flex",
719
+ alignItems: "stretch",
720
+ h: "36px",
721
+ flexShrink: 0,
722
+ bg: "chrome",
723
+ borderBottom: "1px solid",
724
+ borderColor: "line",
725
+ overflowX: "auto",
726
+ scrollbarWidth: "none"
727
+ }),
728
+ children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
729
+ role: "tab",
730
+ tabIndex: 0,
731
+ "aria-selected": tab.key === activeKey,
732
+ "data-preview": tab.preview,
733
+ title: tab.preview ? `${tab.title} — preview; double-click to keep open` : tab.title,
734
+ onClick: () => void navigate({ href: tab.href }),
735
+ onKeyDown: (e) => {
736
+ if (e.key === "Enter") navigate({ href: tab.href });
737
+ },
738
+ onDoubleClick: () => pin(tab.key),
739
+ onAuxClick: (e) => {
740
+ if (e.button === 1) close(tab.key);
741
+ },
742
+ className: css({
743
+ position: "relative",
744
+ display: "flex",
745
+ alignItems: "center",
746
+ gap: "1.5",
747
+ pl: "3",
748
+ pr: "1",
749
+ minW: "0",
750
+ maxW: "220px",
751
+ flexShrink: 0,
752
+ borderRight: "1px solid",
753
+ borderColor: "line",
754
+ cursor: "pointer",
755
+ color: "muted",
756
+ userSelect: "none",
757
+ _hover: {
758
+ color: "fg",
759
+ bg: "hover"
760
+ },
761
+ "&[aria-selected=true]": {
762
+ bg: "canvas",
763
+ color: "fg",
764
+ _before: {
765
+ content: "\"\"",
766
+ position: "absolute",
767
+ left: "0",
768
+ right: "0",
769
+ top: "0",
770
+ h: "2px",
771
+ bg: "accent"
772
+ }
773
+ },
774
+ "&[data-preview=true] .tab-title": { fontStyle: "italic" },
775
+ "& .tab-close": { opacity: 0 },
776
+ "&:hover .tab-close, &[aria-selected=true] .tab-close": { opacity: 1 }
777
+ }),
778
+ children: [
779
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabGlyph, { tab }),
780
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
781
+ className: cx("tab-title", truncate, css({ fontSize: "12px" }), tab.failed ? css({ color: "bad" }) : void 0),
782
+ children: tab.title
783
+ }),
784
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, {
785
+ label: "Close tab",
786
+ className: cx("tab-close", css({
787
+ w: "20px",
788
+ h: "20px"
789
+ })),
790
+ onClick: (e) => {
791
+ e.stopPropagation();
792
+ close(tab.key);
793
+ },
794
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconClose, { size: 12 })
795
+ })
796
+ ]
797
+ }, tab.key))
798
+ });
799
+ }
800
+ function TabGlyph({ tab }) {
801
+ if (tab.icon === "request" && tab.method) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MethodBadge, {
802
+ method: tab.method,
803
+ kind: tab.kind
804
+ });
805
+ const glyph = {
806
+ overview: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconOverview, { size: 13 }),
807
+ history: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconHistory, { size: 13 }),
808
+ environments: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconEnvironments, { size: 13 }),
809
+ session: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconSessions, { size: 13 }),
810
+ run: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconRun, { size: 12 }),
811
+ request: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconRequest, { size: 13 }),
812
+ query: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconDatabase, { size: 13 })
813
+ }[tab.icon];
814
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
815
+ className: css({
816
+ display: "inline-flex",
817
+ color: "faint",
818
+ flexShrink: 0
819
+ }),
820
+ children: glyph
821
+ });
822
+ }
823
+ function StatusBar() {
824
+ const ws = root.useLoaderData();
825
+ const { prefs, lastRefresh } = usePrefs();
826
+ const now = useNow(ws.now, 1e3);
827
+ const c = ws.counts;
828
+ const item = css({
829
+ display: "inline-flex",
830
+ alignItems: "center",
831
+ gap: "1",
832
+ whiteSpace: "nowrap"
833
+ });
834
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("footer", {
835
+ className: css({
836
+ display: "flex",
837
+ alignItems: "center",
838
+ gap: "4",
839
+ h: "24px",
840
+ px: "3",
841
+ flexShrink: 0,
842
+ fontSize: "11px",
843
+ color: "muted",
844
+ borderTop: "1px solid",
845
+ borderColor: "line",
846
+ overflow: "hidden"
847
+ }),
848
+ children: [
849
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
850
+ className: cx(item, mono, truncate, css({
851
+ minW: "0",
852
+ flexShrink: 1
853
+ })),
854
+ title: ws.path,
855
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconDatabase, { size: 12 }), ws.path]
856
+ }),
857
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
858
+ className: item,
859
+ children: formatBytes(ws.bytes)
860
+ }),
861
+ c ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
862
+ className: item,
863
+ children: [
864
+ formatCount(c.runs),
865
+ " runs · ",
866
+ formatCount(c.requests + c.connections),
867
+ " requests"
868
+ ]
869
+ }) : null,
870
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
871
+ className: item,
872
+ children: ["schema v", ws.schema.file]
873
+ }),
874
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
875
+ className: cx(item, css({ ml: "auto" })),
876
+ children: [prefs.live ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
877
+ className: css({ color: "ok" }),
878
+ children: "● Live"
879
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Read-only" }), lastRefresh ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
880
+ className: css({ color: "faint" }),
881
+ children: ["· read ", formatAgo(now, lastRefresh)]
882
+ }) : null]
883
+ })
884
+ ]
885
+ });
886
+ }
887
+ var globals_default = "/assets/globals-D_ltS-iC.css";
888
+ var Route$7 = createRootRoute({
889
+ head: () => ({
890
+ meta: [
891
+ { charSet: "utf-8" },
892
+ {
893
+ name: "viewport",
894
+ content: "width=device-width, initial-scale=1"
895
+ },
896
+ {
897
+ name: "color-scheme",
898
+ content: "light dark"
899
+ },
900
+ { title: "wireui" }
901
+ ],
902
+ links: [{
903
+ rel: "stylesheet",
904
+ href: globals_default
905
+ }, {
906
+ rel: "icon",
907
+ href: "/favicon.svg",
908
+ type: "image/svg+xml"
909
+ }]
910
+ }),
911
+ loader: () => getWorkspace(),
912
+ staleTime: 0,
913
+ errorComponent: RouteError,
914
+ notFoundComponent: NotFound,
915
+ component: RootLayout,
916
+ shellComponent: RootDocument
917
+ });
918
+ function RootLayout() {
919
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Frame, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Outlet, {}) });
920
+ }
921
+ function Frame({ children }) {
922
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PrefsProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children }) }) });
923
+ }
924
+ function RootDocument({ children }) {
925
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("html", {
926
+ lang: "en",
927
+ suppressHydrationWarning: true,
928
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("head", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("script", { dangerouslySetInnerHTML: { __html: THEME_BOOT_SCRIPT } }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HeadContent, {})] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("body", { children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Scripts, {})] })]
929
+ });
930
+ }
931
+ var $$splitComponentImporter$6 = () => import("./routes-CrmwJhiA.mjs");
932
+ var Route$6 = createFileRoute("/")({
933
+ loader: () => getOverview({ data: {} }),
934
+ component: lazyRouteComponent($$splitComponentImporter$6, "component")
935
+ });
936
+ var $$splitComponentImporter$5 = () => import("./environments-BFBtf7iL.mjs");
937
+ var Route$5 = createFileRoute("/environments")({ component: lazyRouteComponent($$splitComponentImporter$5, "component") });
938
+ var $$splitComponentImporter$4 = () => import("./history-57VNXvbE.mjs");
939
+ var Route$4 = createFileRoute("/history")({
940
+ validateSearch: (search) => ({
941
+ q: typeof search.q === "string" && search.q ? search.q : void 0,
942
+ kind: search.kind === "http" || search.kind === "stream" ? search.kind : void 0,
943
+ failed: search.failed === true ? true : void 0,
944
+ bodies: search.bodies === true ? true : void 0
945
+ }),
946
+ loaderDeps: ({ search }) => search,
947
+ loader: ({ deps }) => getHistory({ data: {
948
+ ...deps,
949
+ limit: 500
950
+ } }),
951
+ staleTime: 0,
952
+ component: lazyRouteComponent($$splitComponentImporter$4, "component")
953
+ });
954
+ var $$splitComponentImporter$3 = () => import("./query-D6nNoSN3.mjs");
955
+ var Route$3 = createFileRoute("/query")({
956
+ validateSearch: (search) => ({ sql: typeof search.sql === "string" ? search.sql : void 0 }),
957
+ loader: () => getSchema(),
958
+ component: lazyRouteComponent($$splitComponentImporter$3, "component")
959
+ });
960
+ var $$splitComponentImporter$2 = () => import("./sessions-wsD0b1zm.mjs");
961
+ var Route$2 = createFileRoute("/sessions")({
962
+ validateSearch: (search) => ({
963
+ entry: typeof search.entry === "string" ? search.entry : "",
964
+ tab: search.tab === "requests" || search.tab === "checks" ? search.tab : void 0
965
+ }),
966
+ loaderDeps: ({ search }) => ({ entry: search.entry }),
967
+ loader: async ({ deps }) => {
968
+ if (!deps.entry) throw notFound();
969
+ const page = await getScript({ data: { entry: deps.entry } });
970
+ if (!page) throw notFound();
971
+ return page;
972
+ },
973
+ component: lazyRouteComponent($$splitComponentImporter$2, "component")
974
+ });
975
+ /** Most recent {@link STRIP_RUNS} runs as bars, oldest on the left. */
976
+ var $$splitComponentImporter$1 = () => import("./requests._requestId-bXoTBGVj.mjs");
977
+ var REQ_TABS = [
978
+ "params",
979
+ "headers",
980
+ "body",
981
+ "cookies",
982
+ "tags"
983
+ ];
984
+ var RES_TABS = [
985
+ "body",
986
+ "messages",
987
+ "headers",
988
+ "cookies",
989
+ "timeline"
990
+ ];
991
+ var Route$1 = createFileRoute("/requests/$requestId")({
992
+ validateSearch: (search) => ({
993
+ req: REQ_TABS.includes(search.req) ? search.req : void 0,
994
+ res: RES_TABS.includes(search.res) ? search.res : void 0
995
+ }),
996
+ loader: async ({ params }) => {
997
+ const page = await getRequest({ data: { requestId: params.requestId } });
998
+ if (!page) throw notFound();
999
+ return page;
1000
+ },
1001
+ component: lazyRouteComponent($$splitComponentImporter$1, "component")
1002
+ });
1003
+ var $$splitComponentImporter = () => import("./runs._runId-DM5Y8e6b.mjs");
1004
+ var RUN_TABS = [
1005
+ "requests",
1006
+ "checks",
1007
+ "details"
1008
+ ];
1009
+ var Route = createFileRoute("/runs/$runId")({
1010
+ validateSearch: (search) => ({ tab: search.tab === "insights" ? "requests" : RUN_TABS.includes(search.tab) ? search.tab : void 0 }),
1011
+ loader: async ({ params }) => {
1012
+ const page = await getRun({ data: { runId: params.runId } });
1013
+ if (!page) throw notFound();
1014
+ return page;
1015
+ },
1016
+ component: lazyRouteComponent($$splitComponentImporter, "component")
1017
+ });
1018
+ var rootRouteChildren = {
1019
+ IndexRoute: Route$6.update({
1020
+ id: "/",
1021
+ path: "/",
1022
+ getParentRoute: () => Route$7
1023
+ }),
1024
+ EnvironmentsRoute: Route$5.update({
1025
+ id: "/environments",
1026
+ path: "/environments",
1027
+ getParentRoute: () => Route$7
1028
+ }),
1029
+ HistoryRoute: Route$4.update({
1030
+ id: "/history",
1031
+ path: "/history",
1032
+ getParentRoute: () => Route$7
1033
+ }),
1034
+ QueryRoute: Route$3.update({
1035
+ id: "/query",
1036
+ path: "/query",
1037
+ getParentRoute: () => Route$7
1038
+ }),
1039
+ SessionsRoute: Route$2.update({
1040
+ id: "/sessions",
1041
+ path: "/sessions",
1042
+ getParentRoute: () => Route$7
1043
+ }),
1044
+ RequestsRequestIdRoute: Route$1.update({
1045
+ id: "/requests/$requestId",
1046
+ path: "/requests/$requestId",
1047
+ getParentRoute: () => Route$7
1048
+ }),
1049
+ RunsRunIdRoute: Route.update({
1050
+ id: "/runs/$runId",
1051
+ path: "/runs/$runId",
1052
+ getParentRoute: () => Route$7
1053
+ })
1054
+ };
1055
+ var routeTree = Route$7._addFileChildren(rootRouteChildren)._addFileTypes();
1056
+ var router_exports = /* @__PURE__ */ __exportAll({ getRouter: () => getRouter });
1057
+ function getRouter() {
1058
+ return createRouter({
1059
+ routeTree,
1060
+ defaultPreload: "intent",
1061
+ defaultPreloadStaleTime: 0,
1062
+ scrollRestoration: true,
1063
+ defaultNotFoundComponent: NotFound,
1064
+ defaultErrorComponent: RouteError
1065
+ });
1066
+ }
1067
+ //#endregion
1068
+ export { Route, Route$1, Route$2, Route$3, Route$4, Route$6, getHistory, getOverview, getScript, router_exports, runSql, useSession };