@lunora/studio 0.0.0 → 1.0.0-alpha.10

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 (80) hide show
  1. package/LICENSE.md +105 -0
  2. package/README.md +123 -9
  3. package/__assets__/package-og.svg +14 -0
  4. package/dist/index.d.ts +1403 -0
  5. package/dist/index.js +41 -0
  6. package/dist/mount.d.ts +21 -0
  7. package/dist/mount.js +26 -0
  8. package/dist/packem_shared/ADMIN_FUNCTIONS-DjXgvJb6.js +46 -0
  9. package/dist/packem_shared/ApiDocsPanel-yVSGHK3H.js +842 -0
  10. package/dist/packem_shared/ApiReferencePanel-1vubqG5s.js +229 -0
  11. package/dist/packem_shared/ApiTab-rwttyQ1-.js +251 -0
  12. package/dist/packem_shared/AuditPanel-D9Eh7j7E.js +200 -0
  13. package/dist/packem_shared/CommandPalette-BtgkBzZI.js +373 -0
  14. package/dist/packem_shared/ConfirmButton-C2eVi2Qv.js +59 -0
  15. package/dist/packem_shared/ConnectionBadge-B2DDM2Tn.js +111 -0
  16. package/dist/packem_shared/DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js +50 -0
  17. package/dist/packem_shared/DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js +89 -0
  18. package/dist/packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js +27 -0
  19. package/dist/packem_shared/DataBrowser-CyckZRwj.js +4480 -0
  20. package/dist/packem_shared/DataFilters-FNquMaiu.js +249 -0
  21. package/dist/packem_shared/ErrorBoundary-BzAApI7J.js +66 -0
  22. package/dist/packem_shared/ExportImportPanel-BGJqFK9X.js +197 -0
  23. package/dist/packem_shared/FileBrowser-0pCpdKPE.js +2932 -0
  24. package/dist/packem_shared/FunctionRunner-7NH3KcTg.js +343 -0
  25. package/dist/packem_shared/FunctionStatsPanel-CXynSuqT.js +375 -0
  26. package/dist/packem_shared/GlobalDataBrowser-DAxzB-Br.js +289 -0
  27. package/dist/packem_shared/HealthPanel-CyLs7qZm.js +648 -0
  28. package/dist/packem_shared/HomePanel-BOkFRbuj.js +1334 -0
  29. package/dist/packem_shared/InsightsPanel-CvXMoZuv.js +461 -0
  30. package/dist/packem_shared/LogsPanel-BrUstOk6.js +827 -0
  31. package/dist/packem_shared/MailPanel-GnnrNqL6.js +440 -0
  32. package/dist/packem_shared/MetricsPanel-BN_uUU-_.js +1611 -0
  33. package/dist/packem_shared/MigrationsPanel-DaZuUHje.js +239 -0
  34. package/dist/packem_shared/OpenRpcReferencePanel-vbcYbv3V.js +191 -0
  35. package/dist/packem_shared/PitrPanel-LJGNP_IX.js +252 -0
  36. package/dist/packem_shared/STUDIO_ROOT_CLASS-D12gX2dV.js +3 -0
  37. package/dist/packem_shared/ScheduledJobs-UmVaMbJy.js +262 -0
  38. package/dist/packem_shared/SchemaViewer-Bam6ylvw.js +2512 -0
  39. package/dist/packem_shared/SecurityAdvisorPanel-DTmjUNqt.js +92 -0
  40. package/dist/packem_shared/SettingsPanel-C2wDK-8F.js +390 -0
  41. package/dist/packem_shared/ShardInput-gx_DZXXn.js +107 -0
  42. package/dist/packem_shared/SqlEditorPanel-D5wMIxcg.js +13 -0
  43. package/dist/packem_shared/Studio-DpgYe4qt.js +33 -0
  44. package/dist/packem_shared/StudioApp-C7aaizqc.js +657 -0
  45. package/dist/packem_shared/StudioI18nProvider-B-tDCZIi.js +48 -0
  46. package/dist/packem_shared/TableEditor-DzK3Z6rL.js +371 -0
  47. package/dist/packem_shared/advisor-view-CGcfMiPq.js +159 -0
  48. package/dist/packem_shared/aggregateMetrics-D4nUHEKU.js +108 -0
  49. package/dist/packem_shared/app.d-Nbhpihxv.d.ts +300 -0
  50. package/dist/packem_shared/badge-B2PKA1-5.js +49 -0
  51. package/dist/packem_shared/bar-chart-CzJAgqkp.js +3245 -0
  52. package/dist/packem_shared/button-BhsN2uZH.js +49 -0
  53. package/dist/packem_shared/card-DURq3ElK.js +175 -0
  54. package/dist/packem_shared/cf-links-2cktDedA.js +8 -0
  55. package/dist/packem_shared/checkbox-UNkzAxl-.js +63 -0
  56. package/dist/packem_shared/data-grid-B5CaV3wS.js +183 -0
  57. package/dist/packem_shared/dropdown-menu-WY4B_eJO.js +280 -0
  58. package/dist/packem_shared/empty-state-DY_oe0k6.js +98 -0
  59. package/dist/packem_shared/grid-features-CzUfqgsM.js +840 -0
  60. package/dist/packem_shared/input-XH4r1Pt1.js +53 -0
  61. package/dist/packem_shared/internal-rXJEAhXS.js +68 -0
  62. package/dist/packem_shared/label-D8ykjn5J.js +46 -0
  63. package/dist/packem_shared/live-status-FZ0psC1z.js +44 -0
  64. package/dist/packem_shared/reference-view-B4E49Lip.js +2180 -0
  65. package/dist/packem_shared/shard-history-DyebH1R5.js +38 -0
  66. package/dist/packem_shared/sparkline-10dG-_f0.js +93 -0
  67. package/dist/packem_shared/sql-editor-panel-Smfl_FDF.js +2562 -0
  68. package/dist/packem_shared/storage-tier-CL98eOvn.js +85 -0
  69. package/dist/packem_shared/studio-9Mq0PdMi.js +10831 -0
  70. package/dist/packem_shared/table-_RzNvy3R.js +246 -0
  71. package/dist/packem_shared/table-list-sidebar-Bg7uzbvC.js +832 -0
  72. package/dist/packem_shared/textarea-D3gaCU_-.js +46 -0
  73. package/dist/packem_shared/use-admin-query-4JQW2rr1.js +88 -0
  74. package/dist/packem_shared/useDebounced-Dxncpg6z.js +32 -0
  75. package/dist/packem_shared/utils-B05Dmz_H.js +8 -0
  76. package/dist/packem_shared/virtual-rect-CVMUskSm.js +10 -0
  77. package/dist/standalone/studio.js +378 -0
  78. package/dist/styles.css +2 -0
  79. package/package.json +78 -17
  80. package/src/theme.css +59 -0
@@ -0,0 +1,1334 @@
1
+ import { c } from 'react/compiler-runtime';
2
+ import { useNavigate } from '@tanstack/react-router';
3
+ import { B as Bar, E as EvilBarChart } from './bar-chart-CzJAgqkp.js';
4
+ import { B as Badge } from './badge-B2PKA1-5.js';
5
+ import { C as Card, a as CardContent } from './card-DURq3ElK.js';
6
+ import { E as EmptyState } from './empty-state-DY_oe0k6.js';
7
+ import { u as useAdminQuery } from './use-admin-query-4JQW2rr1.js';
8
+ import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
9
+ import { ADMIN_FUNCTIONS } from './ADMIN_FUNCTIONS-DjXgvJb6.js';
10
+ import { d as formatBytes, f as fireAndForget } from './internal-rXJEAhXS.js';
11
+ import { c as cn } from './utils-B05Dmz_H.js';
12
+ import { deriveInsights } from './DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js';
13
+ import { jsxDEV } from 'react/jsx-dev-runtime';
14
+
15
+ const formatMs = (ms) => {
16
+ if (ms < 1e3) {
17
+ return `${String(Math.round(ms))}ms`;
18
+ }
19
+ const digits = ms >= 1e4 ? 0 : 1;
20
+ return `${(ms / 1e3).toFixed(digits)}s`;
21
+ };
22
+ const relativeTime = (ts, now) => {
23
+ const seconds = Math.max(0, Math.round((now - ts) / 1e3));
24
+ if (seconds < 60) {
25
+ return `${String(seconds)}s ago`;
26
+ }
27
+ const minutes = Math.round(seconds / 60);
28
+ if (minutes < 60) {
29
+ return `${String(minutes)}m ago`;
30
+ }
31
+ const hours = Math.round(minutes / 60);
32
+ return hours < 24 ? `${String(hours)}h ago` : `${String(Math.round(hours / 24))}d ago`;
33
+ };
34
+ const SPARKLINE_CONFIG = {
35
+ value: {
36
+ colors: {
37
+ dark: ["var(--foreground)"],
38
+ light: ["var(--foreground)"]
39
+ },
40
+ label: ""
41
+ }
42
+ };
43
+ const Sparkline = (t0) => {
44
+ const $ = c(6);
45
+ const {
46
+ data
47
+ } = t0;
48
+ let t1;
49
+ let t2;
50
+ if ($[0] !== data) {
51
+ t2 = /* @__PURE__ */ Symbol.for("react.early_return_sentinel");
52
+ bb0: {
53
+ const bars = data.slice(-16);
54
+ if (bars.length < 3) {
55
+ t2 = null;
56
+ break bb0;
57
+ }
58
+ t1 = bars.map(_temp);
59
+ }
60
+ $[0] = data;
61
+ $[1] = t1;
62
+ $[2] = t2;
63
+ } else {
64
+ t1 = $[1];
65
+ t2 = $[2];
66
+ }
67
+ if (t2 !== /* @__PURE__ */ Symbol.for("react.early_return_sentinel")) {
68
+ return t2;
69
+ }
70
+ const rows = t1;
71
+ let t3;
72
+ if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
73
+ t3 = /* @__PURE__ */ jsxDEV(Bar, {
74
+ dataKey: "value"
75
+ }, void 0, false);
76
+ $[3] = t3;
77
+ } else {
78
+ t3 = $[3];
79
+ }
80
+ let t4;
81
+ if ($[4] !== rows) {
82
+ t4 = /* @__PURE__ */ jsxDEV("div", {
83
+ "aria-hidden": "true",
84
+ className: "h-8 w-28",
85
+ children: /* @__PURE__ */ jsxDEV(EvilBarChart, {
86
+ animationType: "none",
87
+ barCategoryGap: 1,
88
+ className: "h-8 w-full",
89
+ config: SPARKLINE_CONFIG,
90
+ data: rows,
91
+ children: t3
92
+ }, void 0, false)
93
+ }, void 0, false);
94
+ $[4] = rows;
95
+ $[5] = t4;
96
+ } else {
97
+ t4 = $[5];
98
+ }
99
+ return t4;
100
+ };
101
+ const bucketSeries = (history, field) => {
102
+ if (history === void 0 || history.length === 0) {
103
+ return [];
104
+ }
105
+ const byBucket = /* @__PURE__ */ new Map();
106
+ for (const bucket of history) {
107
+ byBucket.set(bucket.bucketMs, (byBucket.get(bucket.bucketMs) ?? 0) + bucket[field]);
108
+ }
109
+ return [...byBucket.entries()].toSorted(([a], [b]) => a - b).map(([, total]) => total);
110
+ };
111
+ const seriesDelta = (series, higherIsBetter = true) => {
112
+ if (series.length < 4) {
113
+ return null;
114
+ }
115
+ const mid = Math.floor(series.length / 2);
116
+ const earlier = series.slice(0, mid).reduce((sum, value) => sum + value, 0);
117
+ const recent = series.slice(mid).reduce((sum, value) => sum + value, 0);
118
+ if (earlier === 0) {
119
+ return null;
120
+ }
121
+ const pct = (recent - earlier) / earlier * 100;
122
+ return {
123
+ positive: higherIsBetter ? pct >= 0 : pct <= 0,
124
+ text: `${pct >= 0 ? "+" : ""}${pct.toFixed(1)}%`
125
+ };
126
+ };
127
+ const StatCard = (t0) => {
128
+ const $ = c(24);
129
+ const {
130
+ delta,
131
+ footer,
132
+ label,
133
+ trend,
134
+ unit,
135
+ value
136
+ } = t0;
137
+ const t = useT();
138
+ let t1;
139
+ if ($[0] !== label) {
140
+ t1 = /* @__PURE__ */ jsxDEV("span", {
141
+ className: "font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
142
+ children: label
143
+ }, void 0, false);
144
+ $[0] = label;
145
+ $[1] = t1;
146
+ } else {
147
+ t1 = $[1];
148
+ }
149
+ let t2;
150
+ if ($[2] !== value) {
151
+ t2 = /* @__PURE__ */ jsxDEV("span", {
152
+ className: "text-2xl font-semibold tabular-nums text-foreground",
153
+ children: value
154
+ }, void 0, false);
155
+ $[2] = value;
156
+ $[3] = t2;
157
+ } else {
158
+ t2 = $[3];
159
+ }
160
+ let t3;
161
+ if ($[4] !== unit) {
162
+ t3 = unit !== void 0 && /* @__PURE__ */ jsxDEV("span", {
163
+ className: "text-xs text-muted-foreground",
164
+ children: unit
165
+ }, void 0, false);
166
+ $[4] = unit;
167
+ $[5] = t3;
168
+ } else {
169
+ t3 = $[5];
170
+ }
171
+ let t4;
172
+ if ($[6] !== t2 || $[7] !== t3) {
173
+ t4 = /* @__PURE__ */ jsxDEV("span", {
174
+ className: "flex items-baseline gap-1.5",
175
+ children: [t2, t3]
176
+ }, void 0, true);
177
+ $[6] = t2;
178
+ $[7] = t3;
179
+ $[8] = t4;
180
+ } else {
181
+ t4 = $[8];
182
+ }
183
+ let t5;
184
+ if ($[9] !== trend) {
185
+ t5 = trend !== void 0 && /* @__PURE__ */ jsxDEV(Sparkline, {
186
+ data: trend
187
+ }, void 0, false);
188
+ $[9] = trend;
189
+ $[10] = t5;
190
+ } else {
191
+ t5 = $[10];
192
+ }
193
+ let t6;
194
+ if ($[11] !== t4 || $[12] !== t5) {
195
+ t6 = /* @__PURE__ */ jsxDEV("div", {
196
+ className: "flex items-center justify-between gap-3",
197
+ children: [t4, t5]
198
+ }, void 0, true);
199
+ $[11] = t4;
200
+ $[12] = t5;
201
+ $[13] = t6;
202
+ } else {
203
+ t6 = $[13];
204
+ }
205
+ let t7;
206
+ if ($[14] !== t1 || $[15] !== t6) {
207
+ t7 = /* @__PURE__ */ jsxDEV("div", {
208
+ className: "flex flex-col gap-2.5 p-4",
209
+ children: [t1, t6]
210
+ }, void 0, true);
211
+ $[14] = t1;
212
+ $[15] = t6;
213
+ $[16] = t7;
214
+ } else {
215
+ t7 = $[16];
216
+ }
217
+ let t8;
218
+ if ($[17] !== delta || $[18] !== footer || $[19] !== t) {
219
+ t8 = delta == null ? footer != null && /* @__PURE__ */ jsxDEV("div", {
220
+ className: "border-t border-border bg-muted/50 px-4 py-2.5 text-[11px] text-muted-foreground",
221
+ children: footer
222
+ }, void 0, false) : /* @__PURE__ */ jsxDEV("div", {
223
+ className: "border-t border-border bg-muted/50 px-4 py-2.5 text-[11px]",
224
+ children: [/* @__PURE__ */ jsxDEV("span", {
225
+ className: cn("font-semibold", delta.positive ? "text-success" : "text-destructive"),
226
+ children: delta.text
227
+ }, void 0, false), " ", /* @__PURE__ */ jsxDEV("span", {
228
+ className: "text-muted-foreground",
229
+ children: t("vs. prev.")
230
+ }, void 0, false)]
231
+ }, void 0, true);
232
+ $[17] = delta;
233
+ $[18] = footer;
234
+ $[19] = t;
235
+ $[20] = t8;
236
+ } else {
237
+ t8 = $[20];
238
+ }
239
+ let t9;
240
+ if ($[21] !== t7 || $[22] !== t8) {
241
+ t9 = /* @__PURE__ */ jsxDEV(Card, {
242
+ className: "justify-between gap-0 py-0",
243
+ children: [t7, t8]
244
+ }, void 0, true);
245
+ $[21] = t7;
246
+ $[22] = t8;
247
+ $[23] = t9;
248
+ } else {
249
+ t9 = $[23];
250
+ }
251
+ return t9;
252
+ };
253
+ const ChevronRight = () => {
254
+ const $ = c(1);
255
+ let t0;
256
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
257
+ t0 = /* @__PURE__ */ jsxDEV("svg", {
258
+ "aria-hidden": "true",
259
+ className: "size-3.5",
260
+ fill: "none",
261
+ stroke: "currentColor",
262
+ strokeLinecap: "round",
263
+ strokeLinejoin: "round",
264
+ strokeWidth: 1.8,
265
+ viewBox: "0 0 24 24",
266
+ children: /* @__PURE__ */ jsxDEV("path", {
267
+ d: "m9 6 6 6-6 6"
268
+ }, void 0, false)
269
+ }, void 0, false);
270
+ $[0] = t0;
271
+ } else {
272
+ t0 = $[0];
273
+ }
274
+ return t0;
275
+ };
276
+ const ConnectCard = (t0) => {
277
+ const $ = c(7);
278
+ const {
279
+ command,
280
+ label
281
+ } = t0;
282
+ let t1;
283
+ if ($[0] !== label) {
284
+ t1 = /* @__PURE__ */ jsxDEV("div", {
285
+ className: "p-4",
286
+ children: /* @__PURE__ */ jsxDEV("span", {
287
+ className: "text-sm font-medium text-foreground",
288
+ children: label
289
+ }, void 0, false)
290
+ }, void 0, false);
291
+ $[0] = label;
292
+ $[1] = t1;
293
+ } else {
294
+ t1 = $[1];
295
+ }
296
+ let t2;
297
+ if ($[2] !== command) {
298
+ t2 = /* @__PURE__ */ jsxDEV("div", {
299
+ className: "border-t border-border bg-muted/50 px-4 py-2.5",
300
+ children: /* @__PURE__ */ jsxDEV("code", {
301
+ className: "font-mono text-xs text-muted-foreground",
302
+ children: command
303
+ }, void 0, false)
304
+ }, void 0, false);
305
+ $[2] = command;
306
+ $[3] = t2;
307
+ } else {
308
+ t2 = $[3];
309
+ }
310
+ let t3;
311
+ if ($[4] !== t1 || $[5] !== t2) {
312
+ t3 = /* @__PURE__ */ jsxDEV(Card, {
313
+ className: "justify-between gap-0 py-0",
314
+ children: [t1, t2]
315
+ }, void 0, true);
316
+ $[4] = t1;
317
+ $[5] = t2;
318
+ $[6] = t3;
319
+ } else {
320
+ t3 = $[6];
321
+ }
322
+ return t3;
323
+ };
324
+ const AdvisorCard = (t0) => {
325
+ const $ = c(18);
326
+ const {
327
+ count,
328
+ onView,
329
+ testId,
330
+ title
331
+ } = t0;
332
+ const t = useT();
333
+ let t1;
334
+ if ($[0] !== title) {
335
+ t1 = /* @__PURE__ */ jsxDEV("span", {
336
+ className: "font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
337
+ children: title
338
+ }, void 0, false);
339
+ $[0] = title;
340
+ $[1] = t1;
341
+ } else {
342
+ t1 = $[1];
343
+ }
344
+ let t2;
345
+ if ($[2] !== count || $[3] !== t) {
346
+ t2 = count === null ? /* @__PURE__ */ jsxDEV("span", {
347
+ className: "text-xs text-muted-foreground",
348
+ children: t("No data yet")
349
+ }, void 0, false) : /* @__PURE__ */ jsxDEV(Badge, {
350
+ variant: count > 0 ? "destructive" : "success",
351
+ children: count > 0 ? count : t("All clear")
352
+ }, void 0, false);
353
+ $[2] = count;
354
+ $[3] = t;
355
+ $[4] = t2;
356
+ } else {
357
+ t2 = $[4];
358
+ }
359
+ let t3;
360
+ if ($[5] !== t1 || $[6] !== t2) {
361
+ t3 = /* @__PURE__ */ jsxDEV("div", {
362
+ className: "flex items-start justify-between gap-2 p-4",
363
+ children: [t1, t2]
364
+ }, void 0, true);
365
+ $[5] = t1;
366
+ $[6] = t2;
367
+ $[7] = t3;
368
+ } else {
369
+ t3 = $[7];
370
+ }
371
+ let t4;
372
+ if ($[8] !== t) {
373
+ t4 = t("View");
374
+ $[8] = t;
375
+ $[9] = t4;
376
+ } else {
377
+ t4 = $[9];
378
+ }
379
+ let t5;
380
+ if ($[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
381
+ t5 = /* @__PURE__ */ jsxDEV(ChevronRight, {}, void 0, false);
382
+ $[10] = t5;
383
+ } else {
384
+ t5 = $[10];
385
+ }
386
+ let t6;
387
+ if ($[11] !== onView || $[12] !== t4) {
388
+ t6 = /* @__PURE__ */ jsxDEV("button", {
389
+ className: "flex items-center gap-1 border-t border-border bg-muted/50 px-4 py-2.5 text-[12px] font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:bg-muted",
390
+ onClick: onView,
391
+ type: "button",
392
+ children: [t4, t5]
393
+ }, void 0, true);
394
+ $[11] = onView;
395
+ $[12] = t4;
396
+ $[13] = t6;
397
+ } else {
398
+ t6 = $[13];
399
+ }
400
+ let t7;
401
+ if ($[14] !== t3 || $[15] !== t6 || $[16] !== testId) {
402
+ t7 = /* @__PURE__ */ jsxDEV(Card, {
403
+ className: "justify-between gap-0 py-0",
404
+ "data-testid": testId,
405
+ children: [t3, t6]
406
+ }, void 0, true);
407
+ $[14] = t3;
408
+ $[15] = t6;
409
+ $[16] = testId;
410
+ $[17] = t7;
411
+ } else {
412
+ t7 = $[17];
413
+ }
414
+ return t7;
415
+ };
416
+ const TopFunctionsCard = (t0) => {
417
+ const $ = c(7);
418
+ const {
419
+ functions
420
+ } = t0;
421
+ const t = useT();
422
+ let t1;
423
+ if ($[0] !== functions || $[1] !== t) {
424
+ const top = [...functions].toSorted(_temp2).slice(0, 5);
425
+ let t2;
426
+ if ($[3] !== t) {
427
+ t2 = t("Top functions");
428
+ $[3] = t;
429
+ $[4] = t2;
430
+ } else {
431
+ t2 = $[4];
432
+ }
433
+ let t3;
434
+ if ($[5] !== t2) {
435
+ t3 = /* @__PURE__ */ jsxDEV("div", {
436
+ className: "border-b border-border px-4 py-3",
437
+ children: /* @__PURE__ */ jsxDEV("span", {
438
+ className: "font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
439
+ children: t2
440
+ }, void 0, false)
441
+ }, void 0, false);
442
+ $[5] = t2;
443
+ $[6] = t3;
444
+ } else {
445
+ t3 = $[6];
446
+ }
447
+ t1 = /* @__PURE__ */ jsxDEV(Card, {
448
+ className: "gap-0 py-0",
449
+ "data-testid": "home-top-functions",
450
+ children: [t3, top.length === 0 ? /* @__PURE__ */ jsxDEV("p", {
451
+ className: "px-4 py-8 text-center text-xs text-muted-foreground",
452
+ children: t("No functions called yet.")
453
+ }, void 0, false) : /* @__PURE__ */ jsxDEV("div", {
454
+ className: "divide-y divide-border",
455
+ children: [/* @__PURE__ */ jsxDEV("div", {
456
+ className: "grid grid-cols-[1fr_auto_auto_auto] gap-4 px-4 py-1.5 font-mono text-[10px] tracking-wide text-muted-foreground uppercase",
457
+ children: [/* @__PURE__ */ jsxDEV("span", {
458
+ children: t("Function")
459
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
460
+ className: "text-end",
461
+ children: t("Calls")
462
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
463
+ className: "w-12 text-end",
464
+ children: t("Avg")
465
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
466
+ className: "w-8 text-end",
467
+ children: t("Err")
468
+ }, void 0, false)]
469
+ }, void 0, true), top.map(_temp3)]
470
+ }, void 0, true)]
471
+ }, void 0, true);
472
+ $[0] = functions;
473
+ $[1] = t;
474
+ $[2] = t1;
475
+ } else {
476
+ t1 = $[2];
477
+ }
478
+ return t1;
479
+ };
480
+ const LiveConnectionsCard = (t0) => {
481
+ const $ = c(26);
482
+ const {
483
+ subs
484
+ } = t0;
485
+ const t = useT();
486
+ let t1;
487
+ if ($[0] !== t) {
488
+ t1 = t("Live connections");
489
+ $[0] = t;
490
+ $[1] = t1;
491
+ } else {
492
+ t1 = $[1];
493
+ }
494
+ let t2;
495
+ if ($[2] !== t1) {
496
+ t2 = /* @__PURE__ */ jsxDEV("span", {
497
+ className: "font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
498
+ children: t1
499
+ }, void 0, false);
500
+ $[2] = t1;
501
+ $[3] = t2;
502
+ } else {
503
+ t2 = $[3];
504
+ }
505
+ const t3 = subs?.totalConnections ?? 0;
506
+ let t4;
507
+ if ($[4] !== t3) {
508
+ t4 = t3.toLocaleString();
509
+ $[4] = t3;
510
+ $[5] = t4;
511
+ } else {
512
+ t4 = $[5];
513
+ }
514
+ let t5;
515
+ if ($[6] !== t4) {
516
+ t5 = /* @__PURE__ */ jsxDEV("span", {
517
+ className: "text-2xl font-semibold tabular-nums text-foreground",
518
+ children: t4
519
+ }, void 0, false);
520
+ $[6] = t4;
521
+ $[7] = t5;
522
+ } else {
523
+ t5 = $[7];
524
+ }
525
+ let t6;
526
+ if ($[8] !== t) {
527
+ t6 = t("sockets");
528
+ $[8] = t;
529
+ $[9] = t6;
530
+ } else {
531
+ t6 = $[9];
532
+ }
533
+ let t7;
534
+ if ($[10] !== t6) {
535
+ t7 = /* @__PURE__ */ jsxDEV("span", {
536
+ className: "text-xs text-muted-foreground",
537
+ children: t6
538
+ }, void 0, false);
539
+ $[10] = t6;
540
+ $[11] = t7;
541
+ } else {
542
+ t7 = $[11];
543
+ }
544
+ let t8;
545
+ if ($[12] !== t5 || $[13] !== t7) {
546
+ t8 = /* @__PURE__ */ jsxDEV("span", {
547
+ className: "flex items-baseline gap-1.5",
548
+ children: [t5, t7]
549
+ }, void 0, true);
550
+ $[12] = t5;
551
+ $[13] = t7;
552
+ $[14] = t8;
553
+ } else {
554
+ t8 = $[14];
555
+ }
556
+ const t9 = subs?.totalSubscriptions ?? 0;
557
+ let t10;
558
+ if ($[15] !== t9) {
559
+ t10 = t9.toLocaleString();
560
+ $[15] = t9;
561
+ $[16] = t10;
562
+ } else {
563
+ t10 = $[16];
564
+ }
565
+ let t11;
566
+ if ($[17] !== t) {
567
+ t11 = t("active subscriptions");
568
+ $[17] = t;
569
+ $[18] = t11;
570
+ } else {
571
+ t11 = $[18];
572
+ }
573
+ let t12;
574
+ if ($[19] !== t10 || $[20] !== t11) {
575
+ t12 = /* @__PURE__ */ jsxDEV("span", {
576
+ className: "text-[11px] text-muted-foreground",
577
+ children: [t10, " ", t11]
578
+ }, void 0, true);
579
+ $[19] = t10;
580
+ $[20] = t11;
581
+ $[21] = t12;
582
+ } else {
583
+ t12 = $[21];
584
+ }
585
+ let t13;
586
+ if ($[22] !== t12 || $[23] !== t2 || $[24] !== t8) {
587
+ t13 = /* @__PURE__ */ jsxDEV(Card, {
588
+ "data-testid": "home-live-connections",
589
+ children: /* @__PURE__ */ jsxDEV(CardContent, {
590
+ className: "flex flex-col gap-2.5 py-4",
591
+ children: [t2, t8, t12]
592
+ }, void 0, true)
593
+ }, void 0, false);
594
+ $[22] = t12;
595
+ $[23] = t2;
596
+ $[24] = t8;
597
+ $[25] = t13;
598
+ } else {
599
+ t13 = $[25];
600
+ }
601
+ return t13;
602
+ };
603
+ const RecentActivityCard = (t0) => {
604
+ const $ = c(7);
605
+ const {
606
+ entries
607
+ } = t0;
608
+ const t = useT();
609
+ let t1;
610
+ if ($[0] !== entries || $[1] !== t) {
611
+ const now = Date.now();
612
+ let t2;
613
+ if ($[3] !== t) {
614
+ t2 = t("Recent activity");
615
+ $[3] = t;
616
+ $[4] = t2;
617
+ } else {
618
+ t2 = $[4];
619
+ }
620
+ let t3;
621
+ if ($[5] !== t2) {
622
+ t3 = /* @__PURE__ */ jsxDEV("div", {
623
+ className: "border-b border-border px-4 py-3",
624
+ children: /* @__PURE__ */ jsxDEV("span", {
625
+ className: "font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
626
+ children: t2
627
+ }, void 0, false)
628
+ }, void 0, false);
629
+ $[5] = t2;
630
+ $[6] = t3;
631
+ } else {
632
+ t3 = $[6];
633
+ }
634
+ t1 = /* @__PURE__ */ jsxDEV(Card, {
635
+ className: "gap-0 py-0",
636
+ "data-testid": "home-recent-activity",
637
+ children: [t3, entries.length === 0 ? /* @__PURE__ */ jsxDEV("p", {
638
+ className: "px-4 py-8 text-center text-xs text-muted-foreground",
639
+ children: t("No recent activity.")
640
+ }, void 0, false) : /* @__PURE__ */ jsxDEV("ul", {
641
+ className: "divide-y divide-border",
642
+ children: entries.slice(0, 5).map((entry) => /* @__PURE__ */ jsxDEV("li", {
643
+ className: "flex items-center justify-between gap-3 px-4 py-2 text-[13px]",
644
+ children: [/* @__PURE__ */ jsxDEV("span", {
645
+ className: "flex min-w-0 items-center gap-2",
646
+ children: [/* @__PURE__ */ jsxDEV("span", {
647
+ "aria-hidden": "true",
648
+ className: "size-1.5 shrink-0 rounded-full bg-muted-foreground/40"
649
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
650
+ className: "truncate text-foreground",
651
+ children: [entry.op, entry.table !== void 0 && /* @__PURE__ */ jsxDEV("span", {
652
+ className: "text-muted-foreground",
653
+ children: [" · ", entry.table, entry.id === void 0 ? "" : `#${entry.id}`]
654
+ }, void 0, true)]
655
+ }, void 0, true)]
656
+ }, void 0, true), /* @__PURE__ */ jsxDEV("span", {
657
+ className: "shrink-0 text-xs tabular-nums text-muted-foreground",
658
+ children: relativeTime(entry.ts, now)
659
+ }, void 0, false)]
660
+ }, entry.seq, true))
661
+ }, void 0, false)]
662
+ }, void 0, true);
663
+ $[0] = entries;
664
+ $[1] = t;
665
+ $[2] = t1;
666
+ } else {
667
+ t1 = $[2];
668
+ }
669
+ return t1;
670
+ };
671
+ const averageLatencyMs = (functions) => {
672
+ const calls = functions.reduce((sum, function_) => sum + function_.calls, 0);
673
+ if (calls === 0) {
674
+ return null;
675
+ }
676
+ return functions.reduce((sum, function_) => sum + function_.totalDurationMs, 0) / calls;
677
+ };
678
+ const HomePanel = (t0) => {
679
+ const $ = c(149);
680
+ const {
681
+ initialShardKey
682
+ } = t0;
683
+ const t = useT();
684
+ const navigate = useNavigate();
685
+ const shard = initialShardKey ?? "";
686
+ let t1;
687
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
688
+ t1 = {};
689
+ $[0] = t1;
690
+ } else {
691
+ t1 = $[0];
692
+ }
693
+ let t2;
694
+ if ($[1] !== shard) {
695
+ t2 = {
696
+ shardKey: shard
697
+ };
698
+ $[1] = shard;
699
+ $[2] = t2;
700
+ } else {
701
+ t2 = $[2];
702
+ }
703
+ const metricsQuery = useAdminQuery(ADMIN_FUNCTIONS.getMetrics, t1, t2);
704
+ let t3;
705
+ if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
706
+ t3 = {};
707
+ $[3] = t3;
708
+ } else {
709
+ t3 = $[3];
710
+ }
711
+ let t4;
712
+ if ($[4] !== shard) {
713
+ t4 = {
714
+ shardKey: shard
715
+ };
716
+ $[4] = shard;
717
+ $[5] = t4;
718
+ } else {
719
+ t4 = $[5];
720
+ }
721
+ const statsQuery = useAdminQuery(ADMIN_FUNCTIONS.getFunctionStats, t3, t4);
722
+ let t5;
723
+ let t6;
724
+ if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
725
+ t5 = {};
726
+ t6 = {
727
+ shardKey: ""
728
+ };
729
+ $[6] = t5;
730
+ $[7] = t6;
731
+ } else {
732
+ t5 = $[6];
733
+ t6 = $[7];
734
+ }
735
+ const auditQuery = useAdminQuery(ADMIN_FUNCTIONS.getSecurityAudit, t5, t6);
736
+ let t7;
737
+ if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
738
+ t7 = {};
739
+ $[8] = t7;
740
+ } else {
741
+ t7 = $[8];
742
+ }
743
+ let t8;
744
+ if ($[9] !== shard) {
745
+ t8 = {
746
+ shardKey: shard
747
+ };
748
+ $[9] = shard;
749
+ $[10] = t8;
750
+ } else {
751
+ t8 = $[10];
752
+ }
753
+ const subscriptionsQuery = useAdminQuery(ADMIN_FUNCTIONS.listSubscriptions, t7, t8);
754
+ let t9;
755
+ if ($[11] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
756
+ t9 = {};
757
+ $[11] = t9;
758
+ } else {
759
+ t9 = $[11];
760
+ }
761
+ let t10;
762
+ if ($[12] !== shard) {
763
+ t10 = {
764
+ shardKey: shard
765
+ };
766
+ $[12] = shard;
767
+ $[13] = t10;
768
+ } else {
769
+ t10 = $[13];
770
+ }
771
+ const auditLogQuery = useAdminQuery(ADMIN_FUNCTIONS.getAuditLog, t9, t10);
772
+ const metrics = metricsQuery.data ?? null;
773
+ let T0;
774
+ let activity;
775
+ let cacheHitRate;
776
+ let functions;
777
+ let performanceCount;
778
+ let securityCount;
779
+ let subscriptions;
780
+ let t11;
781
+ let t12;
782
+ let t13;
783
+ let t14;
784
+ let t15;
785
+ let t16;
786
+ let t17;
787
+ let t18;
788
+ let t19;
789
+ let viewPerformance;
790
+ let viewSecurity;
791
+ if ($[14] !== auditLogQuery.data || $[15] !== auditQuery.data || $[16] !== metrics || $[17] !== metricsQuery.data || $[18] !== navigate || $[19] !== statsQuery.data || $[20] !== subscriptionsQuery.data || $[21] !== t) {
792
+ functions = Array.isArray(statsQuery.data?.functions) ? statsQuery.data.functions : [];
793
+ subscriptions = subscriptionsQuery.data ?? null;
794
+ let t202;
795
+ if ($[40] !== auditLogQuery.data) {
796
+ t202 = Array.isArray(auditLogQuery.data?.entries) ? auditLogQuery.data.entries : [];
797
+ $[40] = auditLogQuery.data;
798
+ $[41] = t202;
799
+ } else {
800
+ t202 = $[41];
801
+ }
802
+ activity = t202;
803
+ performanceCount = metricsQuery.data === void 0 || statsQuery.data === void 0 ? null : deriveInsights(metrics, functions).length;
804
+ securityCount = Array.isArray(auditQuery.data?.findings) ? auditQuery.data.findings.length : null;
805
+ let t212;
806
+ if ($[42] !== navigate) {
807
+ t212 = () => {
808
+ fireAndForget(navigate({
809
+ to: "/security"
810
+ }));
811
+ };
812
+ $[42] = navigate;
813
+ $[43] = t212;
814
+ } else {
815
+ t212 = $[43];
816
+ }
817
+ viewSecurity = t212;
818
+ let t222;
819
+ if ($[44] !== navigate) {
820
+ t222 = () => {
821
+ fireAndForget(navigate({
822
+ to: "/insights"
823
+ }));
824
+ };
825
+ $[44] = navigate;
826
+ $[45] = t222;
827
+ } else {
828
+ t222 = $[45];
829
+ }
830
+ viewPerformance = t222;
831
+ const requestSeries = bucketSeries(metrics?.history, "calls");
832
+ const errorSeries = bucketSeries(metrics?.history, "errors");
833
+ const avgLatency = averageLatencyMs(functions);
834
+ const maxLatency = Math.max(0, ...functions.map(_temp4));
835
+ const cache = metrics?.cache;
836
+ let t232;
837
+ if ($[46] !== cache) {
838
+ t232 = cache != null && cache.hits + cache.misses > 0 ? Math.round(cache.hits / (cache.hits + cache.misses) * 100) : null;
839
+ $[46] = cache;
840
+ $[47] = t232;
841
+ } else {
842
+ t232 = $[47];
843
+ }
844
+ cacheHitRate = t232;
845
+ t18 = "flex flex-col gap-6";
846
+ t19 = "lunora-home";
847
+ t14 = "grid gap-3 sm:grid-cols-2 xl:grid-cols-4";
848
+ t15 = "home-health";
849
+ const t242 = seriesDelta(requestSeries);
850
+ let t252;
851
+ if ($[48] !== t) {
852
+ t252 = t("Requests");
853
+ $[48] = t;
854
+ $[49] = t252;
855
+ } else {
856
+ t252 = $[49];
857
+ }
858
+ const t262 = metrics?.requests ?? 0;
859
+ let t272;
860
+ if ($[50] !== t262) {
861
+ t272 = t262.toLocaleString();
862
+ $[50] = t262;
863
+ $[51] = t272;
864
+ } else {
865
+ t272 = $[51];
866
+ }
867
+ if ($[52] !== requestSeries || $[53] !== t242 || $[54] !== t252 || $[55] !== t272) {
868
+ t16 = /* @__PURE__ */ jsxDEV(StatCard, {
869
+ delta: t242,
870
+ label: t252,
871
+ trend: requestSeries,
872
+ value: t272
873
+ }, void 0, false);
874
+ $[52] = requestSeries;
875
+ $[53] = t242;
876
+ $[54] = t252;
877
+ $[55] = t272;
878
+ $[56] = t16;
879
+ } else {
880
+ t16 = $[56];
881
+ }
882
+ const t282 = seriesDelta(errorSeries, false);
883
+ let t292;
884
+ if ($[57] !== t) {
885
+ t292 = t("Errors");
886
+ $[57] = t;
887
+ $[58] = t292;
888
+ } else {
889
+ t292 = $[58];
890
+ }
891
+ const t302 = metrics?.errors ?? 0;
892
+ let t312;
893
+ if ($[59] !== t302) {
894
+ t312 = t302.toLocaleString();
895
+ $[59] = t302;
896
+ $[60] = t312;
897
+ } else {
898
+ t312 = $[60];
899
+ }
900
+ if ($[61] !== errorSeries || $[62] !== t282 || $[63] !== t292 || $[64] !== t312) {
901
+ t17 = /* @__PURE__ */ jsxDEV(StatCard, {
902
+ delta: t282,
903
+ label: t292,
904
+ trend: errorSeries,
905
+ value: t312
906
+ }, void 0, false);
907
+ $[61] = errorSeries;
908
+ $[62] = t282;
909
+ $[63] = t292;
910
+ $[64] = t312;
911
+ $[65] = t17;
912
+ } else {
913
+ t17 = $[65];
914
+ }
915
+ T0 = StatCard;
916
+ if ($[66] !== maxLatency || $[67] !== t) {
917
+ t11 = maxLatency > 0 ? `${t("max")} ${formatMs(maxLatency)}` : void 0;
918
+ $[66] = maxLatency;
919
+ $[67] = t;
920
+ $[68] = t11;
921
+ } else {
922
+ t11 = $[68];
923
+ }
924
+ if ($[69] !== t) {
925
+ t12 = t("Avg latency");
926
+ $[69] = t;
927
+ $[70] = t12;
928
+ } else {
929
+ t12 = $[70];
930
+ }
931
+ t13 = avgLatency === null ? "—" : formatMs(avgLatency);
932
+ $[14] = auditLogQuery.data;
933
+ $[15] = auditQuery.data;
934
+ $[16] = metrics;
935
+ $[17] = metricsQuery.data;
936
+ $[18] = navigate;
937
+ $[19] = statsQuery.data;
938
+ $[20] = subscriptionsQuery.data;
939
+ $[21] = t;
940
+ $[22] = T0;
941
+ $[23] = activity;
942
+ $[24] = cacheHitRate;
943
+ $[25] = functions;
944
+ $[26] = performanceCount;
945
+ $[27] = securityCount;
946
+ $[28] = subscriptions;
947
+ $[29] = t11;
948
+ $[30] = t12;
949
+ $[31] = t13;
950
+ $[32] = t14;
951
+ $[33] = t15;
952
+ $[34] = t16;
953
+ $[35] = t17;
954
+ $[36] = t18;
955
+ $[37] = t19;
956
+ $[38] = viewPerformance;
957
+ $[39] = viewSecurity;
958
+ } else {
959
+ T0 = $[22];
960
+ activity = $[23];
961
+ cacheHitRate = $[24];
962
+ functions = $[25];
963
+ performanceCount = $[26];
964
+ securityCount = $[27];
965
+ subscriptions = $[28];
966
+ t11 = $[29];
967
+ t12 = $[30];
968
+ t13 = $[31];
969
+ t14 = $[32];
970
+ t15 = $[33];
971
+ t16 = $[34];
972
+ t17 = $[35];
973
+ t18 = $[36];
974
+ t19 = $[37];
975
+ viewPerformance = $[38];
976
+ viewSecurity = $[39];
977
+ }
978
+ let t20;
979
+ if ($[71] !== T0 || $[72] !== t11 || $[73] !== t12 || $[74] !== t13) {
980
+ t20 = /* @__PURE__ */ jsxDEV(T0, {
981
+ footer: t11,
982
+ label: t12,
983
+ value: t13
984
+ }, void 0, false);
985
+ $[71] = T0;
986
+ $[72] = t11;
987
+ $[73] = t12;
988
+ $[74] = t13;
989
+ $[75] = t20;
990
+ } else {
991
+ t20 = $[75];
992
+ }
993
+ let t21;
994
+ if ($[76] !== cacheHitRate || $[77] !== t) {
995
+ t21 = cacheHitRate === null ? void 0 : `${String(cacheHitRate)}% ${t("cache hit")}`;
996
+ $[76] = cacheHitRate;
997
+ $[77] = t;
998
+ $[78] = t21;
999
+ } else {
1000
+ t21 = $[78];
1001
+ }
1002
+ let t22;
1003
+ if ($[79] !== t) {
1004
+ t22 = t("Database size");
1005
+ $[79] = t;
1006
+ $[80] = t22;
1007
+ } else {
1008
+ t22 = $[80];
1009
+ }
1010
+ const t23 = metrics?.databaseSize ?? null;
1011
+ let t24;
1012
+ if ($[81] !== t23) {
1013
+ t24 = formatBytes(t23);
1014
+ $[81] = t23;
1015
+ $[82] = t24;
1016
+ } else {
1017
+ t24 = $[82];
1018
+ }
1019
+ let t25;
1020
+ if ($[83] !== t21 || $[84] !== t22 || $[85] !== t24) {
1021
+ t25 = /* @__PURE__ */ jsxDEV(StatCard, {
1022
+ footer: t21,
1023
+ label: t22,
1024
+ value: t24
1025
+ }, void 0, false);
1026
+ $[83] = t21;
1027
+ $[84] = t22;
1028
+ $[85] = t24;
1029
+ $[86] = t25;
1030
+ } else {
1031
+ t25 = $[86];
1032
+ }
1033
+ let t26;
1034
+ if ($[87] !== t14 || $[88] !== t15 || $[89] !== t16 || $[90] !== t17 || $[91] !== t20 || $[92] !== t25) {
1035
+ t26 = /* @__PURE__ */ jsxDEV("div", {
1036
+ className: t14,
1037
+ "data-testid": t15,
1038
+ children: [t16, t17, t20, t25]
1039
+ }, void 0, true);
1040
+ $[87] = t14;
1041
+ $[88] = t15;
1042
+ $[89] = t16;
1043
+ $[90] = t17;
1044
+ $[91] = t20;
1045
+ $[92] = t25;
1046
+ $[93] = t26;
1047
+ } else {
1048
+ t26 = $[93];
1049
+ }
1050
+ let t27;
1051
+ if ($[94] !== functions) {
1052
+ t27 = /* @__PURE__ */ jsxDEV("div", {
1053
+ className: "lg:col-span-2",
1054
+ children: /* @__PURE__ */ jsxDEV(TopFunctionsCard, {
1055
+ functions
1056
+ }, void 0, false)
1057
+ }, void 0, false);
1058
+ $[94] = functions;
1059
+ $[95] = t27;
1060
+ } else {
1061
+ t27 = $[95];
1062
+ }
1063
+ let t28;
1064
+ if ($[96] !== subscriptions) {
1065
+ t28 = /* @__PURE__ */ jsxDEV(LiveConnectionsCard, {
1066
+ subs: subscriptions
1067
+ }, void 0, false);
1068
+ $[96] = subscriptions;
1069
+ $[97] = t28;
1070
+ } else {
1071
+ t28 = $[97];
1072
+ }
1073
+ let t29;
1074
+ if ($[98] !== activity) {
1075
+ t29 = /* @__PURE__ */ jsxDEV(RecentActivityCard, {
1076
+ entries: activity
1077
+ }, void 0, false);
1078
+ $[98] = activity;
1079
+ $[99] = t29;
1080
+ } else {
1081
+ t29 = $[99];
1082
+ }
1083
+ let t30;
1084
+ if ($[100] !== t28 || $[101] !== t29) {
1085
+ t30 = /* @__PURE__ */ jsxDEV("div", {
1086
+ className: "flex flex-col gap-3",
1087
+ children: [t28, t29]
1088
+ }, void 0, true);
1089
+ $[100] = t28;
1090
+ $[101] = t29;
1091
+ $[102] = t30;
1092
+ } else {
1093
+ t30 = $[102];
1094
+ }
1095
+ let t31;
1096
+ if ($[103] !== t27 || $[104] !== t30) {
1097
+ t31 = /* @__PURE__ */ jsxDEV("div", {
1098
+ className: "grid gap-3 lg:grid-cols-3",
1099
+ children: [t27, t30]
1100
+ }, void 0, true);
1101
+ $[103] = t27;
1102
+ $[104] = t30;
1103
+ $[105] = t31;
1104
+ } else {
1105
+ t31 = $[105];
1106
+ }
1107
+ let t32;
1108
+ if ($[106] !== t) {
1109
+ t32 = t("Advisors");
1110
+ $[106] = t;
1111
+ $[107] = t32;
1112
+ } else {
1113
+ t32 = $[107];
1114
+ }
1115
+ let t33;
1116
+ if ($[108] !== t32) {
1117
+ t33 = /* @__PURE__ */ jsxDEV("h2", {
1118
+ className: "text-sm font-semibold tracking-tight text-foreground",
1119
+ children: t32
1120
+ }, void 0, false);
1121
+ $[108] = t32;
1122
+ $[109] = t33;
1123
+ } else {
1124
+ t33 = $[109];
1125
+ }
1126
+ let t34;
1127
+ if ($[110] !== performanceCount || $[111] !== securityCount || $[112] !== t || $[113] !== viewPerformance || $[114] !== viewSecurity) {
1128
+ t34 = securityCount === 0 && performanceCount === 0 ? /* @__PURE__ */ jsxDEV(EmptyState, {
1129
+ description: t("No security or performance issues detected."),
1130
+ icon: /* @__PURE__ */ jsxDEV("svg", {
1131
+ "aria-hidden": "true",
1132
+ fill: "none",
1133
+ stroke: "currentColor",
1134
+ strokeLinecap: "round",
1135
+ strokeLinejoin: "round",
1136
+ strokeWidth: 1.6,
1137
+ viewBox: "0 0 24 24",
1138
+ children: [/* @__PURE__ */ jsxDEV("path", {
1139
+ d: "M12 3 4 6v5c0 5 3.4 8.5 8 10 4.6-1.5 8-5 8-10V6l-8-3Z"
1140
+ }, void 0, false), /* @__PURE__ */ jsxDEV("path", {
1141
+ d: "m9 12 2 2 4-4"
1142
+ }, void 0, false)]
1143
+ }, void 0, true),
1144
+ testId: "home-advisors-clear",
1145
+ title: t("No issues found")
1146
+ }, void 0, false) : /* @__PURE__ */ jsxDEV("div", {
1147
+ className: "grid gap-3 sm:grid-cols-2",
1148
+ children: [/* @__PURE__ */ jsxDEV(AdvisorCard, {
1149
+ count: securityCount,
1150
+ onView: viewSecurity,
1151
+ testId: "home-security",
1152
+ title: t("Security findings")
1153
+ }, void 0, false), /* @__PURE__ */ jsxDEV(AdvisorCard, {
1154
+ count: performanceCount,
1155
+ onView: viewPerformance,
1156
+ testId: "home-performance",
1157
+ title: t("Performance issues")
1158
+ }, void 0, false)]
1159
+ }, void 0, true);
1160
+ $[110] = performanceCount;
1161
+ $[111] = securityCount;
1162
+ $[112] = t;
1163
+ $[113] = viewPerformance;
1164
+ $[114] = viewSecurity;
1165
+ $[115] = t34;
1166
+ } else {
1167
+ t34 = $[115];
1168
+ }
1169
+ let t35;
1170
+ if ($[116] !== t33 || $[117] !== t34) {
1171
+ t35 = /* @__PURE__ */ jsxDEV("section", {
1172
+ className: "flex flex-col gap-3",
1173
+ "data-testid": "home-advisors",
1174
+ children: [t33, t34]
1175
+ }, void 0, true);
1176
+ $[116] = t33;
1177
+ $[117] = t34;
1178
+ $[118] = t35;
1179
+ } else {
1180
+ t35 = $[118];
1181
+ }
1182
+ let t36;
1183
+ if ($[119] !== t) {
1184
+ t36 = t("Get connected");
1185
+ $[119] = t;
1186
+ $[120] = t36;
1187
+ } else {
1188
+ t36 = $[120];
1189
+ }
1190
+ let t37;
1191
+ if ($[121] !== t36) {
1192
+ t37 = /* @__PURE__ */ jsxDEV("h2", {
1193
+ className: "text-sm font-semibold tracking-tight text-foreground",
1194
+ children: t36
1195
+ }, void 0, false);
1196
+ $[121] = t36;
1197
+ $[122] = t37;
1198
+ } else {
1199
+ t37 = $[122];
1200
+ }
1201
+ let t38;
1202
+ if ($[123] !== t) {
1203
+ t38 = t("Client SDK");
1204
+ $[123] = t;
1205
+ $[124] = t38;
1206
+ } else {
1207
+ t38 = $[124];
1208
+ }
1209
+ let t39;
1210
+ if ($[125] !== t38) {
1211
+ t39 = /* @__PURE__ */ jsxDEV(ConnectCard, {
1212
+ command: "npm i @lunora/client",
1213
+ label: t38
1214
+ }, void 0, false);
1215
+ $[125] = t38;
1216
+ $[126] = t39;
1217
+ } else {
1218
+ t39 = $[126];
1219
+ }
1220
+ let t40;
1221
+ if ($[127] !== t) {
1222
+ t40 = t("React");
1223
+ $[127] = t;
1224
+ $[128] = t40;
1225
+ } else {
1226
+ t40 = $[128];
1227
+ }
1228
+ let t41;
1229
+ if ($[129] !== t40) {
1230
+ t41 = /* @__PURE__ */ jsxDEV(ConnectCard, {
1231
+ command: "npm i @lunora/react",
1232
+ label: t40
1233
+ }, void 0, false);
1234
+ $[129] = t40;
1235
+ $[130] = t41;
1236
+ } else {
1237
+ t41 = $[130];
1238
+ }
1239
+ let t42;
1240
+ if ($[131] !== t) {
1241
+ t42 = t("CLI");
1242
+ $[131] = t;
1243
+ $[132] = t42;
1244
+ } else {
1245
+ t42 = $[132];
1246
+ }
1247
+ let t43;
1248
+ if ($[133] !== t42) {
1249
+ t43 = /* @__PURE__ */ jsxDEV(ConnectCard, {
1250
+ command: "lunora dev",
1251
+ label: t42
1252
+ }, void 0, false);
1253
+ $[133] = t42;
1254
+ $[134] = t43;
1255
+ } else {
1256
+ t43 = $[134];
1257
+ }
1258
+ let t44;
1259
+ if ($[135] !== t39 || $[136] !== t41 || $[137] !== t43) {
1260
+ t44 = /* @__PURE__ */ jsxDEV("div", {
1261
+ className: "grid gap-3 sm:grid-cols-3",
1262
+ children: [t39, t41, t43]
1263
+ }, void 0, true);
1264
+ $[135] = t39;
1265
+ $[136] = t41;
1266
+ $[137] = t43;
1267
+ $[138] = t44;
1268
+ } else {
1269
+ t44 = $[138];
1270
+ }
1271
+ let t45;
1272
+ if ($[139] !== t37 || $[140] !== t44) {
1273
+ t45 = /* @__PURE__ */ jsxDEV("section", {
1274
+ className: "flex flex-col gap-3",
1275
+ "data-testid": "home-get-connected",
1276
+ children: [t37, t44]
1277
+ }, void 0, true);
1278
+ $[139] = t37;
1279
+ $[140] = t44;
1280
+ $[141] = t45;
1281
+ } else {
1282
+ t45 = $[141];
1283
+ }
1284
+ let t46;
1285
+ if ($[142] !== t18 || $[143] !== t19 || $[144] !== t26 || $[145] !== t31 || $[146] !== t35 || $[147] !== t45) {
1286
+ t46 = /* @__PURE__ */ jsxDEV("div", {
1287
+ className: t18,
1288
+ "data-testid": t19,
1289
+ children: [t26, t31, t35, t45]
1290
+ }, void 0, true);
1291
+ $[142] = t18;
1292
+ $[143] = t19;
1293
+ $[144] = t26;
1294
+ $[145] = t31;
1295
+ $[146] = t35;
1296
+ $[147] = t45;
1297
+ $[148] = t46;
1298
+ } else {
1299
+ t46 = $[148];
1300
+ }
1301
+ return t46;
1302
+ };
1303
+ function _temp(value, index) {
1304
+ return {
1305
+ index,
1306
+ value
1307
+ };
1308
+ }
1309
+ function _temp2(a, b) {
1310
+ return b.calls - a.calls;
1311
+ }
1312
+ function _temp3(function_) {
1313
+ return /* @__PURE__ */ jsxDEV("div", {
1314
+ className: "grid grid-cols-[1fr_auto_auto_auto] items-center gap-4 px-4 py-2 text-[13px]",
1315
+ children: [/* @__PURE__ */ jsxDEV("span", {
1316
+ className: "truncate font-mono text-xs text-foreground",
1317
+ children: function_.path
1318
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
1319
+ className: "text-end tabular-nums",
1320
+ children: function_.calls.toLocaleString()
1321
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
1322
+ className: "w-12 text-end tabular-nums text-muted-foreground",
1323
+ children: formatMs(function_.calls > 0 ? function_.totalDurationMs / function_.calls : 0)
1324
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
1325
+ className: cn("w-8 text-end tabular-nums", function_.errors > 0 ? "text-destructive" : "text-muted-foreground"),
1326
+ children: function_.errors
1327
+ }, void 0, false)]
1328
+ }, function_.path, true);
1329
+ }
1330
+ function _temp4(function_) {
1331
+ return function_.maxDurationMs;
1332
+ }
1333
+
1334
+ export { HomePanel };