@lunora/studio 1.0.0-alpha.57 → 1.0.0-alpha.59

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 (115) hide show
  1. package/dist/index.d.ts +61 -4
  2. package/dist/index.js +8 -6
  3. package/dist/mount.d.ts +1 -1
  4. package/dist/mount.js +1 -1
  5. package/dist/packem_chunks/ApiTab.js +1 -1
  6. package/dist/packem_chunks/AuditPanel.js +1 -1
  7. package/dist/packem_chunks/DeploymentHealthPanel.js +664 -0
  8. package/dist/packem_chunks/ExportImportPanel.js +1 -1
  9. package/dist/packem_chunks/FileBrowser.js +1 -1
  10. package/dist/packem_chunks/FunctionRunner.js +1 -1
  11. package/dist/packem_chunks/FunctionStatsPanel.js +1 -1
  12. package/dist/packem_chunks/HealthPanel.js +1 -1
  13. package/dist/packem_chunks/InsightsPanel.js +1 -1
  14. package/dist/packem_chunks/LogsPanel.js +1 -1
  15. package/dist/packem_chunks/MailPanel.js +1 -1
  16. package/dist/packem_chunks/MetricsPanel.js +473 -242
  17. package/dist/packem_chunks/MigrationsPanel.js +1 -1
  18. package/dist/packem_chunks/NotificationsPanel.js +306 -0
  19. package/dist/packem_chunks/PitrPanel.js +1 -1
  20. package/dist/packem_chunks/SchemaViewer.js +1 -1
  21. package/dist/packem_chunks/SecurityAdvisorPanel.js +1 -1
  22. package/dist/packem_chunks/SettingsPanel.js +1 -1
  23. package/dist/packem_chunks/SqlEditorPanel.js +1 -1
  24. package/dist/packem_chunks/TableEditor.js +1 -1
  25. package/dist/packem_chunks/agents-panel.js +1 -1
  26. package/dist/packem_chunks/auth-audit-panel.js +247 -0
  27. package/dist/packem_chunks/containers-panel.js +1 -1
  28. package/dist/packem_chunks/dashboards-panel.js +1 -1
  29. package/dist/packem_chunks/fanout-panel.js +1 -1
  30. package/dist/packem_chunks/flags-panel.js +1 -1
  31. package/dist/packem_chunks/issues-panel.js +1 -1
  32. package/dist/packem_chunks/kv-browser.js +1 -1
  33. package/dist/packem_chunks/payments-panel.js +28 -1
  34. package/dist/packem_chunks/permissions-panel.js +1 -1
  35. package/dist/packem_chunks/queues-panel.js +1 -1
  36. package/dist/packem_chunks/rls-panel.js +1 -1
  37. package/dist/packem_chunks/storage-rules-panel.js +1 -1
  38. package/dist/packem_chunks/subscriptions-panel.js +1 -1
  39. package/dist/packem_chunks/traces-panel.js +125 -112
  40. package/dist/packem_chunks/workflows-panel.js +1 -1
  41. package/dist/packem_shared/{ADMIN_FUNCTIONS-C1LXrovV.js → ADMIN_FUNCTIONS-P2UzJscH.js} +3 -0
  42. package/dist/packem_shared/{ApiDocsPanel-BBvinlRD.js → ApiDocsPanel-DNDpeR5O.js} +1 -1
  43. package/dist/packem_shared/{DataBrowser-BoinTGxr.js → DataBrowser-obTn4sKX.js} +1 -1
  44. package/dist/packem_shared/{HomePanel-BpdGcW4L.js → HomePanel-DCRj3hGB.js} +2 -2
  45. package/dist/packem_shared/{Studio-BpnYw3lc.js → Studio-DnlPCbID.js} +2 -2
  46. package/dist/packem_shared/{StudioApp-DRGVBnFx.js → StudioApp-CzqlB4zO.js} +1 -1
  47. package/dist/packem_shared/{app.d-C-kxb-1T.d.ts → app.d-bRPJhby-.d.ts} +1 -1
  48. package/dist/packem_shared/{home-panel-Dmg4sNiv.js → home-panel-BRAA2UlM.js} +1 -1
  49. package/dist/packem_shared/{studio-LL4iP8fZ.js → studio-8QSXbZ98.js} +682 -607
  50. package/dist/packem_shared/trace-handoff-CGolF3KS.js +38 -0
  51. package/dist/standalone/{chunk-C7UZEQZ7.js → chunk-3LJEGSMK.js} +2 -2
  52. package/dist/standalone/{chunk-SAQU44MF.js → chunk-56XQYNUJ.js} +1 -1
  53. package/dist/standalone/chunk-5QT5JRXD.js +3 -0
  54. package/dist/standalone/{chunk-JM3ZISDM.js → chunk-6RLPR7PL.js} +1 -1
  55. package/dist/standalone/{chunk-T3R6VHAT.js → chunk-6V74EUPK.js} +1 -1
  56. package/dist/standalone/{chunk-27JTW53L.js → chunk-7EE33WLB.js} +1 -1
  57. package/dist/standalone/{chunk-R4ALMCZA.js → chunk-AXNGWSBM.js} +1 -1
  58. package/dist/standalone/{chunk-OHCGUIOG.js → chunk-AXZILWRM.js} +1 -1
  59. package/dist/standalone/{chunk-J2DQ63SR.js → chunk-C7RHEBOH.js} +1 -1
  60. package/dist/standalone/chunk-CSWIYOB3.js +1 -0
  61. package/dist/standalone/{chunk-NV5LO5I6.js → chunk-D3VAON25.js} +1 -1
  62. package/dist/standalone/{chunk-HQ2CPGA4.js → chunk-DDLQN67F.js} +1 -1
  63. package/dist/standalone/chunk-DGHW5JG5.js +1 -0
  64. package/dist/standalone/{chunk-EFYZYQUA.js → chunk-DMCSOTAE.js} +1 -1
  65. package/dist/standalone/{chunk-MBG7XWNH.js → chunk-E3BKETAS.js} +1 -1
  66. package/dist/standalone/{chunk-IMVAYDPK.js → chunk-E3OXNN6O.js} +1 -1
  67. package/dist/standalone/chunk-E6BOGDIS.js +1 -0
  68. package/dist/standalone/{chunk-2ICZ6HXQ.js → chunk-F7GE4X2U.js} +1 -1
  69. package/dist/standalone/{chunk-CENYZ5GF.js → chunk-FAVUOGJR.js} +1 -1
  70. package/dist/standalone/{chunk-NIC6UYAQ.js → chunk-FXP6256Q.js} +1 -1
  71. package/dist/standalone/{chunk-X34PHGZF.js → chunk-G6CTAYHJ.js} +1 -1
  72. package/dist/standalone/chunk-H42W62SE.js +1 -0
  73. package/dist/standalone/{chunk-LABWKVKR.js → chunk-HTF5ZX4I.js} +1 -1
  74. package/dist/standalone/{chunk-AYHAJL3Z.js → chunk-I2PS4L74.js} +1 -1
  75. package/dist/standalone/{chunk-MJ4HATA2.js → chunk-J7OGP4NN.js} +1 -1
  76. package/dist/standalone/{chunk-2XUT4Z4W.js → chunk-L2LN3MK4.js} +1 -1
  77. package/dist/standalone/{chunk-2BSDITP4.js → chunk-LT3FH6MW.js} +1 -1
  78. package/dist/standalone/{chunk-ZXLEXF4X.js → chunk-LXULVPEM.js} +3 -3
  79. package/dist/standalone/{chunk-RIZDNIW7.js → chunk-LZUWZBPE.js} +1 -1
  80. package/dist/standalone/{chunk-W3EYW2EA.js → chunk-M4JM3TOY.js} +1 -1
  81. package/dist/standalone/{chunk-P7MZQ6VJ.js → chunk-MLA5ZAEB.js} +1 -1
  82. package/dist/standalone/{chunk-67YMILPJ.js → chunk-MRBI5HNQ.js} +1 -1
  83. package/dist/standalone/{chunk-53J4JZ2D.js → chunk-NKFXMDOD.js} +1 -1
  84. package/dist/standalone/{chunk-WAX3RSAI.js → chunk-NPSNKFHE.js} +1 -1
  85. package/dist/standalone/{chunk-ZVQMTQYX.js → chunk-O7FVPUCO.js} +1 -1
  86. package/dist/standalone/{chunk-227DORM6.js → chunk-OKQXTLFX.js} +1 -1
  87. package/dist/standalone/{chunk-OPSAI5PZ.js → chunk-QAIM6KWT.js} +1 -1
  88. package/dist/standalone/{chunk-7YGTGBP7.js → chunk-QCPMTB6W.js} +1 -1
  89. package/dist/standalone/{chunk-XAGYDGI6.js → chunk-QQ2LOSZL.js} +1 -1
  90. package/dist/standalone/{chunk-Y26ZIWUZ.js → chunk-R2GMHLJY.js} +1 -1
  91. package/dist/standalone/{chunk-2YUYNNHQ.js → chunk-RD5UG2YL.js} +1 -1
  92. package/dist/standalone/chunk-RJTIP3WF.js +1 -0
  93. package/dist/standalone/{chunk-BIA2DLBR.js → chunk-SOC5CY3F.js} +1 -1
  94. package/dist/standalone/{chunk-GF6GF6CF.js → chunk-SS7JLF2I.js} +1 -1
  95. package/dist/standalone/{chunk-PYPWIYI2.js → chunk-SWWYUGPL.js} +1 -1
  96. package/dist/standalone/chunk-TEWVD66F.js +1 -0
  97. package/dist/standalone/{chunk-QAW6AWOE.js → chunk-TTXRHJUP.js} +1 -1
  98. package/dist/standalone/{chunk-4Q66FL5S.js → chunk-UKDHGVOC.js} +1 -1
  99. package/dist/standalone/{chunk-5IGHDPEP.js → chunk-UPNTMJFF.js} +1 -1
  100. package/dist/standalone/{chunk-PRHAIUWS.js → chunk-XN6QYJQ6.js} +1 -1
  101. package/dist/standalone/chunk-Y4U6CC22.js +1 -0
  102. package/dist/standalone/{chunk-SWMBBYJU.js → chunk-Y7PD5KP4.js} +1 -1
  103. package/dist/standalone/chunk-YFIPHCEC.js +1 -0
  104. package/dist/standalone/chunk-YJXOWLFJ.js +1 -0
  105. package/dist/standalone/{chunk-CURAOCQJ.js → chunk-YNN6NFRZ.js} +1 -1
  106. package/dist/standalone/{chunk-LFORIMS7.js → chunk-YUGHRVPD.js} +1 -1
  107. package/dist/standalone/studio.js +1 -1
  108. package/dist/styles.css +1 -1
  109. package/package.json +6 -6
  110. package/dist/standalone/chunk-EXNK5XAW.js +0 -1
  111. package/dist/standalone/chunk-LT2HPR6R.js +0 -3
  112. package/dist/standalone/chunk-MHGJUKCZ.js +0 -1
  113. package/dist/standalone/chunk-N2E4TKRD.js +0 -1
  114. package/dist/standalone/chunk-S6PTK7Y2.js +0 -1
  115. package/dist/standalone/chunk-X3VAERRH.js +0 -1
@@ -1,47 +1,192 @@
1
1
  import { c } from 'react/compiler-runtime';
2
2
  import { useLunora } from '@lunora/react';
3
+ import { useNavigate } from '@tanstack/react-router';
3
4
  import { useState, useRef, useEffect, useMemo } from 'react';
4
5
  import { L as LiveError } from '../packem_shared/live-status-FZ0psC1z.js';
5
6
  import { ShardInput } from '../packem_shared/ShardInput-CZnpHILL.js';
6
7
  import { B as Button } from '../packem_shared/button-BhsN2uZH.js';
7
8
  import { C as Card, a as CardContent, c as CardHeader, b as CardTitle, d as CardDescription } from '../packem_shared/card-F2vH_aj2.js';
8
- import { T as Table, c as TableHead, a as TableHeader, b as TableRow, d as TableBody, e as TableCell } from '../packem_shared/table-DsCa9Qp9.js';
9
+ import { b as TableRow, e as TableCell, T as Table, c as TableHead, a as TableHeader, d as TableBody } from '../packem_shared/table-DsCa9Qp9.js';
9
10
  import { u as useAdminQuery } from '../packem_shared/use-admin-query-C7JNuQp-.js';
10
11
  import useDebounced from '../packem_shared/useDebounced-Dxncpg6z.js';
11
12
  import { useT } from '../packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js';
12
- import { ADMIN_FUNCTIONS } from '../packem_shared/ADMIN_FUNCTIONS-C1LXrovV.js';
13
+ import { ADMIN_FUNCTIONS } from '../packem_shared/ADMIN_FUNCTIONS-P2UzJscH.js';
13
14
  import { c as CLOUDFLARE_DURABLE_OBJECTS_URL } from '../packem_shared/cf-links-SIbyi4Y1.js';
14
15
  import { k as formatBytes, f as fireAndForget, c as callOptions, e as errorMessage, a as adminRef } from '../packem_shared/internal-DzHCc2Rq.js';
15
16
  import { r as recordShard, l as loadRecentShards } from '../packem_shared/shard-history-AxiJ1WPP.js';
17
+ import { w as writePendingTraceFilter } from '../packem_shared/trace-handoff-CGolF3KS.js';
16
18
  import { f as formatLogFields } from '../packem_shared/log-fields-jEH83H2G.js';
17
19
  import { B as Badge } from '../packem_shared/badge-B2PKA1-5.js';
20
+ import { S as Sparkline } from '../packem_shared/sparkline-BnA1kC9X.js';
18
21
  import { jsxDEV, Fragment } from 'react/jsx-dev-runtime';
19
22
  import { aggregateMetrics, computeLatencyPercentiles, enrichQueryStats, shardsToAggregate } from '../packem_shared/aggregateMetrics-D4nUHEKU.js';
20
23
  import { b as SelectValue, a as SelectTrigger, d as SelectItem, c as SelectContent, S as Select } from '../packem_shared/select-D9OwHEch.js';
21
- import { S as Sparkline } from '../packem_shared/sparkline-BnA1kC9X.js';
22
24
 
23
- const metricHeadline = (series) => {
24
- if (series.kind === "gauge") {
25
- return series.last;
25
+ const compareKeys = (a, b) => {
26
+ if (a < b) {
27
+ return -1;
28
+ }
29
+ return a > b ? 1 : 0;
30
+ };
31
+ const stableStringify = (value) => {
32
+ if (value === void 0) {
33
+ return "null";
34
+ }
35
+ if (typeof value === "bigint") {
36
+ throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");
37
+ }
38
+ if (value === null || typeof value !== "object") {
39
+ return JSON.stringify(value);
40
+ }
41
+ if (Array.isArray(value)) {
42
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
43
+ }
44
+ const proto = Object.getPrototypeOf(value);
45
+ if (proto !== null && proto !== Object.prototype) {
46
+ const name = value.constructor?.name ?? "value";
47
+ throw new TypeError(`stableStringify: cannot use a ${name} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`);
48
+ }
49
+ const record = value;
50
+ const keys = Object.keys(record).toSorted(compareKeys);
51
+ const parts = [];
52
+ for (const key of keys) {
53
+ const raw = record[key];
54
+ if (raw === void 0) {
55
+ continue;
56
+ }
57
+ parts.push(`${JSON.stringify(key)}:${stableStringify(raw)}`);
58
+ }
59
+ return `{${parts.join(",")}}`;
60
+ };
61
+
62
+ const seriesMatchKey = (kind, name, attributes) => `${kind}:${name}:${stableStringify(attributes ?? {})}`;
63
+ const projectByKind = (kind, metric) => {
64
+ if (kind === "gauge") {
65
+ return metric.last;
26
66
  }
27
- if (series.kind === "histogram") {
28
- return series.sum / Math.max(1, series.count);
67
+ if (kind === "histogram") {
68
+ return metric.sum / Math.max(1, metric.count);
29
69
  }
30
- return series.sum;
70
+ return metric.sum;
31
71
  };
72
+ const pointValue = (kind, point) => projectByKind(kind, point);
73
+ const metricHeadline = (series) => projectByKind(series.kind, series);
32
74
  const formatMetricValue = (value) => Number.isInteger(value) ? value.toLocaleString() : value.toLocaleString(void 0, {
33
75
  maximumFractionDigits: 2
34
76
  });
35
77
 
36
78
  const seriesOf = (result) => Array.isArray(result?.series) ? result.series : [];
79
+ const historyByKey = (result) => {
80
+ const map = /* @__PURE__ */ new Map();
81
+ if (!Array.isArray(result?.series)) {
82
+ return map;
83
+ }
84
+ for (const entry of result.series) {
85
+ map.set(seriesMatchKey(entry.kind, entry.name, entry.attributes), entry.points);
86
+ }
87
+ return map;
88
+ };
37
89
  const KIND_VARIANT = {
38
90
  counter: "secondary",
39
91
  gauge: "default",
40
92
  histogram: "outline"
41
93
  };
94
+ const TraceExemplar = (t0) => {
95
+ const $ = c(18);
96
+ const {
97
+ name,
98
+ onOpenTrace,
99
+ traceId
100
+ } = t0;
101
+ const t = useT();
102
+ if (traceId === void 0) {
103
+ let t12;
104
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
105
+ t12 = /* @__PURE__ */ jsxDEV("span", {
106
+ className: "text-muted-foreground",
107
+ children: "—"
108
+ }, void 0, false);
109
+ $[0] = t12;
110
+ } else {
111
+ t12 = $[0];
112
+ }
113
+ return t12;
114
+ }
115
+ let t1;
116
+ if ($[1] !== traceId) {
117
+ t1 = traceId.slice(0, 8);
118
+ $[1] = traceId;
119
+ $[2] = t1;
120
+ } else {
121
+ t1 = $[2];
122
+ }
123
+ const short = t1;
124
+ if (onOpenTrace === void 0) {
125
+ const t22 = `mt-instrument-trace-${name}`;
126
+ let t32;
127
+ if ($[3] !== short || $[4] !== t22 || $[5] !== traceId) {
128
+ t32 = /* @__PURE__ */ jsxDEV("span", {
129
+ className: "text-muted-foreground",
130
+ "data-testid": t22,
131
+ title: traceId,
132
+ children: short
133
+ }, void 0, false);
134
+ $[3] = short;
135
+ $[4] = t22;
136
+ $[5] = traceId;
137
+ $[6] = t32;
138
+ } else {
139
+ t32 = $[6];
140
+ }
141
+ return t32;
142
+ }
143
+ const t2 = `mt-instrument-trace-${name}`;
144
+ let t3;
145
+ if ($[7] !== onOpenTrace || $[8] !== traceId) {
146
+ t3 = () => {
147
+ onOpenTrace(traceId);
148
+ };
149
+ $[7] = onOpenTrace;
150
+ $[8] = traceId;
151
+ $[9] = t3;
152
+ } else {
153
+ t3 = $[9];
154
+ }
155
+ let t4;
156
+ if ($[10] !== t || $[11] !== traceId) {
157
+ t4 = t("Open the exemplar trace {trace}", {
158
+ trace: traceId
159
+ });
160
+ $[10] = t;
161
+ $[11] = traceId;
162
+ $[12] = t4;
163
+ } else {
164
+ t4 = $[12];
165
+ }
166
+ let t5;
167
+ if ($[13] !== short || $[14] !== t2 || $[15] !== t3 || $[16] !== t4) {
168
+ t5 = /* @__PURE__ */ jsxDEV("button", {
169
+ className: "text-primary underline-offset-4 hover:underline",
170
+ "data-testid": t2,
171
+ onClick: t3,
172
+ title: t4,
173
+ type: "button",
174
+ children: short
175
+ }, void 0, false);
176
+ $[13] = short;
177
+ $[14] = t2;
178
+ $[15] = t3;
179
+ $[16] = t4;
180
+ $[17] = t5;
181
+ } else {
182
+ t5 = $[17];
183
+ }
184
+ return t5;
185
+ };
42
186
  const InstrumentsTable = (t0) => {
43
- const $ = c(79);
187
+ const $ = c(92);
44
188
  const {
189
+ onOpenTrace,
45
190
  shardKey
46
191
  } = t0;
47
192
  const t = useT();
@@ -67,30 +212,52 @@ const InstrumentsTable = (t0) => {
67
212
  data,
68
213
  error
69
214
  } = useAdminQuery(ADMIN_FUNCTIONS.getMetricSeries, t1, t2);
215
+ let t3;
216
+ if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
217
+ t3 = {};
218
+ $[3] = t3;
219
+ } else {
220
+ t3 = $[3];
221
+ }
222
+ let t4;
223
+ if ($[4] !== shardKey) {
224
+ t4 = {
225
+ live: true,
226
+ shardKey
227
+ };
228
+ $[4] = shardKey;
229
+ $[5] = t4;
230
+ } else {
231
+ t4 = $[5];
232
+ }
233
+ const {
234
+ data: history
235
+ } = useAdminQuery(ADMIN_FUNCTIONS.getMetricHistory, t3, t4);
70
236
  let T0;
71
237
  let T1;
72
238
  let T2;
73
239
  let T3;
74
240
  let t10;
75
241
  let t11;
76
- let t3;
77
- let t4;
242
+ let t12;
243
+ let t13;
78
244
  let t5;
79
245
  let t6;
80
246
  let t7;
81
247
  let t8;
82
248
  let t9;
83
- if ($[3] !== data || $[4] !== error || $[5] !== t) {
84
- t11 = /* @__PURE__ */ Symbol.for("react.early_return_sentinel");
249
+ if ($[6] !== data || $[7] !== error || $[8] !== history || $[9] !== onOpenTrace || $[10] !== t) {
250
+ t13 = /* @__PURE__ */ Symbol.for("react.early_return_sentinel");
85
251
  bb0: {
86
252
  const series = seriesOf(data);
87
253
  if (error !== null || series.length === 0) {
88
- t11 = null;
254
+ t13 = null;
89
255
  break bb0;
90
256
  }
91
- let t122;
92
- if ($[19] !== t) {
93
- t122 = (kind) => {
257
+ const trends = historyByKey(history);
258
+ let t142;
259
+ if ($[24] !== t) {
260
+ t142 = (kind) => {
94
261
  if (kind === "counter") {
95
262
  return t("Counter");
96
263
  }
@@ -99,307 +266,360 @@ const InstrumentsTable = (t0) => {
99
266
  }
100
267
  return t("Histogram");
101
268
  };
102
- $[19] = t;
103
- $[20] = t122;
269
+ $[24] = t;
270
+ $[25] = t142;
104
271
  } else {
105
- t122 = $[20];
272
+ t142 = $[25];
106
273
  }
107
- const kindLabel = t122;
108
- t8 = "flex flex-col gap-2";
109
- t9 = "mt-instruments";
110
- let t132;
111
- if ($[21] !== t) {
112
- t132 = t("Instruments");
113
- $[21] = t;
114
- $[22] = t132;
274
+ const kindLabel = t142;
275
+ t10 = "flex flex-col gap-2";
276
+ t11 = "mt-instruments";
277
+ let t152;
278
+ if ($[26] !== t) {
279
+ t152 = t("Instruments");
280
+ $[26] = t;
281
+ $[27] = t152;
115
282
  } else {
116
- t132 = $[22];
283
+ t152 = $[27];
117
284
  }
118
- if ($[23] !== t132) {
119
- t10 = /* @__PURE__ */ jsxDEV("h3", {
285
+ if ($[28] !== t152) {
286
+ t12 = /* @__PURE__ */ jsxDEV("h3", {
120
287
  className: "text-sm font-semibold text-foreground",
121
- children: t132
288
+ children: t152
122
289
  }, void 0, false);
123
- $[23] = t132;
124
- $[24] = t10;
290
+ $[28] = t152;
291
+ $[29] = t12;
125
292
  } else {
126
- t10 = $[24];
293
+ t12 = $[29];
127
294
  }
128
295
  T3 = Card;
129
- t7 = "overflow-hidden py-0";
296
+ t9 = "overflow-hidden py-0";
130
297
  T2 = CardContent;
131
- t6 = "px-0";
298
+ t8 = "px-0";
132
299
  T1 = Table;
133
- t4 = "mt-instruments-table";
134
- let t142;
135
- if ($[25] !== t) {
136
- t142 = t("name");
137
- $[25] = t;
138
- $[26] = t142;
139
- } else {
140
- t142 = $[26];
141
- }
142
- let t152;
143
- if ($[27] !== t142) {
144
- t152 = /* @__PURE__ */ jsxDEV(TableHead, {
145
- children: t142
146
- }, void 0, false);
147
- $[27] = t142;
148
- $[28] = t152;
149
- } else {
150
- t152 = $[28];
151
- }
300
+ t6 = "mt-instruments-table";
152
301
  let t162;
153
- if ($[29] !== t) {
154
- t162 = t("kind");
155
- $[29] = t;
156
- $[30] = t162;
302
+ if ($[30] !== t) {
303
+ t162 = t("name");
304
+ $[30] = t;
305
+ $[31] = t162;
157
306
  } else {
158
- t162 = $[30];
307
+ t162 = $[31];
159
308
  }
160
- let t17;
161
- if ($[31] !== t162) {
162
- t17 = /* @__PURE__ */ jsxDEV(TableHead, {
309
+ let t172;
310
+ if ($[32] !== t162) {
311
+ t172 = /* @__PURE__ */ jsxDEV(TableHead, {
163
312
  children: t162
164
313
  }, void 0, false);
165
- $[31] = t162;
166
- $[32] = t17;
314
+ $[32] = t162;
315
+ $[33] = t172;
167
316
  } else {
168
- t17 = $[32];
317
+ t172 = $[33];
169
318
  }
170
- let t18;
171
- if ($[33] !== t) {
172
- t18 = t("value");
173
- $[33] = t;
174
- $[34] = t18;
319
+ let t182;
320
+ if ($[34] !== t) {
321
+ t182 = t("kind");
322
+ $[34] = t;
323
+ $[35] = t182;
175
324
  } else {
176
- t18 = $[34];
325
+ t182 = $[35];
177
326
  }
178
327
  let t19;
179
- if ($[35] !== t18) {
328
+ if ($[36] !== t182) {
180
329
  t19 = /* @__PURE__ */ jsxDEV(TableHead, {
181
- className: "text-right",
182
- children: t18
330
+ children: t182
183
331
  }, void 0, false);
184
- $[35] = t18;
185
- $[36] = t19;
332
+ $[36] = t182;
333
+ $[37] = t19;
186
334
  } else {
187
- t19 = $[36];
335
+ t19 = $[37];
188
336
  }
189
337
  let t20;
190
- if ($[37] !== t) {
191
- t20 = t("count");
192
- $[37] = t;
193
- $[38] = t20;
338
+ if ($[38] !== t) {
339
+ t20 = t("value");
340
+ $[38] = t;
341
+ $[39] = t20;
194
342
  } else {
195
- t20 = $[38];
343
+ t20 = $[39];
196
344
  }
197
345
  let t21;
198
- if ($[39] !== t20) {
346
+ if ($[40] !== t20) {
199
347
  t21 = /* @__PURE__ */ jsxDEV(TableHead, {
200
348
  className: "text-right",
201
349
  children: t20
202
350
  }, void 0, false);
203
- $[39] = t20;
204
- $[40] = t21;
351
+ $[40] = t20;
352
+ $[41] = t21;
205
353
  } else {
206
- t21 = $[40];
354
+ t21 = $[41];
207
355
  }
208
356
  let t22;
209
- if ($[41] !== t) {
210
- t22 = t("range");
211
- $[41] = t;
212
- $[42] = t22;
357
+ if ($[42] !== t) {
358
+ t22 = t("count");
359
+ $[42] = t;
360
+ $[43] = t22;
213
361
  } else {
214
- t22 = $[42];
362
+ t22 = $[43];
215
363
  }
216
364
  let t23;
217
- if ($[43] !== t22) {
365
+ if ($[44] !== t22) {
218
366
  t23 = /* @__PURE__ */ jsxDEV(TableHead, {
219
367
  className: "text-right",
220
368
  children: t22
221
369
  }, void 0, false);
222
- $[43] = t22;
223
- $[44] = t23;
370
+ $[44] = t22;
371
+ $[45] = t23;
224
372
  } else {
225
- t23 = $[44];
373
+ t23 = $[45];
226
374
  }
227
375
  let t24;
228
- if ($[45] !== t) {
229
- t24 = t("dimensions");
230
- $[45] = t;
231
- $[46] = t24;
376
+ if ($[46] !== t) {
377
+ t24 = t("range");
378
+ $[46] = t;
379
+ $[47] = t24;
232
380
  } else {
233
- t24 = $[46];
381
+ t24 = $[47];
234
382
  }
235
383
  let t25;
236
- if ($[47] !== t24) {
384
+ if ($[48] !== t24) {
237
385
  t25 = /* @__PURE__ */ jsxDEV(TableHead, {
386
+ className: "text-right",
238
387
  children: t24
239
388
  }, void 0, false);
240
- $[47] = t24;
241
- $[48] = t25;
389
+ $[48] = t24;
390
+ $[49] = t25;
391
+ } else {
392
+ t25 = $[49];
393
+ }
394
+ let t26;
395
+ if ($[50] !== t) {
396
+ t26 = t("trend");
397
+ $[50] = t;
398
+ $[51] = t26;
399
+ } else {
400
+ t26 = $[51];
401
+ }
402
+ let t27;
403
+ if ($[52] !== t26) {
404
+ t27 = /* @__PURE__ */ jsxDEV(TableHead, {
405
+ children: t26
406
+ }, void 0, false);
407
+ $[52] = t26;
408
+ $[53] = t27;
409
+ } else {
410
+ t27 = $[53];
411
+ }
412
+ let t28;
413
+ if ($[54] !== t) {
414
+ t28 = t("trace");
415
+ $[54] = t;
416
+ $[55] = t28;
417
+ } else {
418
+ t28 = $[55];
419
+ }
420
+ let t29;
421
+ if ($[56] !== t28) {
422
+ t29 = /* @__PURE__ */ jsxDEV(TableHead, {
423
+ children: t28
424
+ }, void 0, false);
425
+ $[56] = t28;
426
+ $[57] = t29;
242
427
  } else {
243
- t25 = $[48];
428
+ t29 = $[57];
244
429
  }
245
- if ($[49] !== t152 || $[50] !== t17 || $[51] !== t19 || $[52] !== t21 || $[53] !== t23 || $[54] !== t25) {
246
- t5 = /* @__PURE__ */ jsxDEV(TableHeader, {
430
+ let t30;
431
+ if ($[58] !== t) {
432
+ t30 = t("dimensions");
433
+ $[58] = t;
434
+ $[59] = t30;
435
+ } else {
436
+ t30 = $[59];
437
+ }
438
+ let t31;
439
+ if ($[60] !== t30) {
440
+ t31 = /* @__PURE__ */ jsxDEV(TableHead, {
441
+ children: t30
442
+ }, void 0, false);
443
+ $[60] = t30;
444
+ $[61] = t31;
445
+ } else {
446
+ t31 = $[61];
447
+ }
448
+ if ($[62] !== t172 || $[63] !== t19 || $[64] !== t21 || $[65] !== t23 || $[66] !== t25 || $[67] !== t27 || $[68] !== t29 || $[69] !== t31) {
449
+ t7 = /* @__PURE__ */ jsxDEV(TableHeader, {
247
450
  children: /* @__PURE__ */ jsxDEV(TableRow, {
248
- children: [t152, t17, t19, t21, t23, t25]
451
+ children: [t172, t19, t21, t23, t25, t27, t29, t31]
249
452
  }, void 0, true)
250
453
  }, void 0, false);
251
- $[49] = t152;
252
- $[50] = t17;
253
- $[51] = t19;
254
- $[52] = t21;
255
- $[53] = t23;
256
- $[54] = t25;
257
- $[55] = t5;
454
+ $[62] = t172;
455
+ $[63] = t19;
456
+ $[64] = t21;
457
+ $[65] = t23;
458
+ $[66] = t25;
459
+ $[67] = t27;
460
+ $[68] = t29;
461
+ $[69] = t31;
462
+ $[70] = t7;
258
463
  } else {
259
- t5 = $[55];
464
+ t7 = $[70];
260
465
  }
261
466
  T0 = TableBody;
262
- let t26;
263
- if ($[56] !== kindLabel) {
264
- t26 = (s) => {
265
- const dimensions = formatLogFields(s.attributes);
266
- const key = `${s.kind}:${s.name}:${dimensions}`;
267
- return /* @__PURE__ */ jsxDEV(TableRow, {
268
- "data-testid": `mt-instrument-${s.name}`,
269
- children: [/* @__PURE__ */ jsxDEV(TableCell, {
270
- className: "font-mono text-xs",
271
- title: s.functionPath,
272
- children: s.name
273
- }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
274
- children: /* @__PURE__ */ jsxDEV(Badge, {
275
- variant: KIND_VARIANT[s.kind],
276
- children: kindLabel(s.kind)
277
- }, void 0, false)
278
- }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
279
- className: "text-right font-mono tabular-nums",
280
- "data-testid": `mt-instrument-value-${s.name}`,
281
- children: formatMetricValue(metricHeadline(s))
282
- }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
283
- className: "text-right tabular-nums text-muted-foreground",
284
- children: s.count.toLocaleString()
285
- }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
286
- className: "text-right font-mono text-xs tabular-nums text-muted-foreground",
287
- children: s.min === s.max ? "—" : `${formatMetricValue(s.min)}–${formatMetricValue(s.max)}`
288
- }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
289
- className: "max-w-64 truncate font-mono text-xs text-muted-foreground",
290
- title: dimensions,
291
- children: dimensions === "" ? "—" : dimensions
292
- }, void 0, false)]
293
- }, key, true);
294
- };
295
- $[56] = kindLabel;
296
- $[57] = t26;
297
- } else {
298
- t26 = $[57];
299
- }
300
- t3 = series.map(t26);
467
+ t5 = series.map((s) => {
468
+ const dimensions = formatLogFields(s.attributes);
469
+ const key = seriesMatchKey(s.kind, s.name, s.attributes);
470
+ const points = trends.get(key) ?? [];
471
+ const trend = points.map((point) => pointValue(s.kind, point));
472
+ return /* @__PURE__ */ jsxDEV(TableRow, {
473
+ "data-testid": `mt-instrument-${s.name}`,
474
+ children: [/* @__PURE__ */ jsxDEV(TableCell, {
475
+ className: "font-mono text-xs",
476
+ title: s.functionPath,
477
+ children: s.name
478
+ }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
479
+ children: /* @__PURE__ */ jsxDEV(Badge, {
480
+ variant: KIND_VARIANT[s.kind],
481
+ children: kindLabel(s.kind)
482
+ }, void 0, false)
483
+ }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
484
+ className: "text-right font-mono tabular-nums",
485
+ "data-testid": `mt-instrument-value-${s.name}`,
486
+ children: formatMetricValue(metricHeadline(s))
487
+ }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
488
+ className: "text-right tabular-nums text-muted-foreground",
489
+ children: s.count.toLocaleString()
490
+ }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
491
+ className: "text-right font-mono text-xs tabular-nums text-muted-foreground",
492
+ children: s.min === s.max ? "—" : `${formatMetricValue(s.min)}–${formatMetricValue(s.max)}`
493
+ }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
494
+ children: trend.length >= 2 ? /* @__PURE__ */ jsxDEV(Sparkline, {
495
+ ariaLabel: t("{name} trend", {
496
+ name: s.name
497
+ }),
498
+ className: "h-6 w-24 text-foreground",
499
+ series: trend,
500
+ testId: `mt-instrument-trend-${s.name}`
501
+ }, void 0, false) : /* @__PURE__ */ jsxDEV("span", {
502
+ className: "text-xs text-muted-foreground",
503
+ children: "—"
504
+ }, void 0, false)
505
+ }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
506
+ className: "font-mono text-xs",
507
+ children: /* @__PURE__ */ jsxDEV(TraceExemplar, {
508
+ name: s.name,
509
+ onOpenTrace,
510
+ traceId: s.exemplarTraceId
511
+ }, void 0, false)
512
+ }, void 0, false), /* @__PURE__ */ jsxDEV(TableCell, {
513
+ className: "max-w-64 truncate font-mono text-xs text-muted-foreground",
514
+ title: dimensions,
515
+ children: dimensions === "" ? "—" : dimensions
516
+ }, void 0, false)]
517
+ }, key, true);
518
+ });
301
519
  }
302
- $[3] = data;
303
- $[4] = error;
304
- $[5] = t;
305
- $[6] = T0;
306
- $[7] = T1;
307
- $[8] = T2;
308
- $[9] = T3;
309
- $[10] = t10;
310
- $[11] = t11;
311
- $[12] = t3;
312
- $[13] = t4;
313
- $[14] = t5;
314
- $[15] = t6;
315
- $[16] = t7;
316
- $[17] = t8;
317
- $[18] = t9;
318
- } else {
319
- T0 = $[6];
320
- T1 = $[7];
321
- T2 = $[8];
322
- T3 = $[9];
323
- t10 = $[10];
324
- t11 = $[11];
325
- t3 = $[12];
326
- t4 = $[13];
327
- t5 = $[14];
328
- t6 = $[15];
329
- t7 = $[16];
330
- t8 = $[17];
331
- t9 = $[18];
520
+ $[6] = data;
521
+ $[7] = error;
522
+ $[8] = history;
523
+ $[9] = onOpenTrace;
524
+ $[10] = t;
525
+ $[11] = T0;
526
+ $[12] = T1;
527
+ $[13] = T2;
528
+ $[14] = T3;
529
+ $[15] = t10;
530
+ $[16] = t11;
531
+ $[17] = t12;
532
+ $[18] = t13;
533
+ $[19] = t5;
534
+ $[20] = t6;
535
+ $[21] = t7;
536
+ $[22] = t8;
537
+ $[23] = t9;
538
+ } else {
539
+ T0 = $[11];
540
+ T1 = $[12];
541
+ T2 = $[13];
542
+ T3 = $[14];
543
+ t10 = $[15];
544
+ t11 = $[16];
545
+ t12 = $[17];
546
+ t13 = $[18];
547
+ t5 = $[19];
548
+ t6 = $[20];
549
+ t7 = $[21];
550
+ t8 = $[22];
551
+ t9 = $[23];
552
+ }
553
+ if (t13 !== /* @__PURE__ */ Symbol.for("react.early_return_sentinel")) {
554
+ return t13;
332
555
  }
333
- if (t11 !== /* @__PURE__ */ Symbol.for("react.early_return_sentinel")) {
334
- return t11;
335
- }
336
- let t12;
337
- if ($[58] !== T0 || $[59] !== t3) {
338
- t12 = /* @__PURE__ */ jsxDEV(T0, {
339
- children: t3
556
+ let t14;
557
+ if ($[71] !== T0 || $[72] !== t5) {
558
+ t14 = /* @__PURE__ */ jsxDEV(T0, {
559
+ children: t5
340
560
  }, void 0, false);
341
- $[58] = T0;
342
- $[59] = t3;
343
- $[60] = t12;
561
+ $[71] = T0;
562
+ $[72] = t5;
563
+ $[73] = t14;
344
564
  } else {
345
- t12 = $[60];
565
+ t14 = $[73];
346
566
  }
347
- let t13;
348
- if ($[61] !== T1 || $[62] !== t12 || $[63] !== t4 || $[64] !== t5) {
349
- t13 = /* @__PURE__ */ jsxDEV(T1, {
350
- "data-testid": t4,
351
- children: [t5, t12]
567
+ let t15;
568
+ if ($[74] !== T1 || $[75] !== t14 || $[76] !== t6 || $[77] !== t7) {
569
+ t15 = /* @__PURE__ */ jsxDEV(T1, {
570
+ "data-testid": t6,
571
+ children: [t7, t14]
352
572
  }, void 0, true);
353
- $[61] = T1;
354
- $[62] = t12;
355
- $[63] = t4;
356
- $[64] = t5;
357
- $[65] = t13;
573
+ $[74] = T1;
574
+ $[75] = t14;
575
+ $[76] = t6;
576
+ $[77] = t7;
577
+ $[78] = t15;
358
578
  } else {
359
- t13 = $[65];
579
+ t15 = $[78];
360
580
  }
361
- let t14;
362
- if ($[66] !== T2 || $[67] !== t13 || $[68] !== t6) {
363
- t14 = /* @__PURE__ */ jsxDEV(T2, {
364
- className: t6,
365
- children: t13
581
+ let t16;
582
+ if ($[79] !== T2 || $[80] !== t15 || $[81] !== t8) {
583
+ t16 = /* @__PURE__ */ jsxDEV(T2, {
584
+ className: t8,
585
+ children: t15
366
586
  }, void 0, false);
367
- $[66] = T2;
368
- $[67] = t13;
369
- $[68] = t6;
370
- $[69] = t14;
587
+ $[79] = T2;
588
+ $[80] = t15;
589
+ $[81] = t8;
590
+ $[82] = t16;
371
591
  } else {
372
- t14 = $[69];
592
+ t16 = $[82];
373
593
  }
374
- let t15;
375
- if ($[70] !== T3 || $[71] !== t14 || $[72] !== t7) {
376
- t15 = /* @__PURE__ */ jsxDEV(T3, {
377
- className: t7,
378
- children: t14
594
+ let t17;
595
+ if ($[83] !== T3 || $[84] !== t16 || $[85] !== t9) {
596
+ t17 = /* @__PURE__ */ jsxDEV(T3, {
597
+ className: t9,
598
+ children: t16
379
599
  }, void 0, false);
380
- $[70] = T3;
381
- $[71] = t14;
382
- $[72] = t7;
383
- $[73] = t15;
600
+ $[83] = T3;
601
+ $[84] = t16;
602
+ $[85] = t9;
603
+ $[86] = t17;
384
604
  } else {
385
- t15 = $[73];
605
+ t17 = $[86];
386
606
  }
387
- let t16;
388
- if ($[74] !== t10 || $[75] !== t15 || $[76] !== t8 || $[77] !== t9) {
389
- t16 = /* @__PURE__ */ jsxDEV("section", {
390
- className: t8,
391
- "data-testid": t9,
392
- children: [t10, t15]
607
+ let t18;
608
+ if ($[87] !== t10 || $[88] !== t11 || $[89] !== t12 || $[90] !== t17) {
609
+ t18 = /* @__PURE__ */ jsxDEV("section", {
610
+ className: t10,
611
+ "data-testid": t11,
612
+ children: [t12, t17]
393
613
  }, void 0, true);
394
- $[74] = t10;
395
- $[75] = t15;
396
- $[76] = t8;
397
- $[77] = t9;
398
- $[78] = t16;
614
+ $[87] = t10;
615
+ $[88] = t11;
616
+ $[89] = t12;
617
+ $[90] = t17;
618
+ $[91] = t18;
399
619
  } else {
400
- t16 = $[78];
620
+ t18 = $[91];
401
621
  }
402
- return t16;
622
+ return t18;
403
623
  };
404
624
 
405
625
  const performanceLevel = (avgMs) => {
@@ -1413,6 +1633,7 @@ const MetricsPanel = ({
1413
1633
  }) => {
1414
1634
  const client = useLunora();
1415
1635
  const t = useT();
1636
+ const navigate = useNavigate();
1416
1637
  const [shardKey, setShardKey] = useState(initialShardKey ?? "");
1417
1638
  const [activeTab, setActiveTab] = useState("overview");
1418
1639
  const [history, setHistory] = useState([]);
@@ -1426,6 +1647,15 @@ const MetricsPanel = ({
1426
1647
  };
1427
1648
  }, []);
1428
1649
  const debouncedShard = useDebounced(shardKey.trim(), 400);
1650
+ const openTrace = (traceId) => {
1651
+ writePendingTraceFilter({
1652
+ shardKey: debouncedShard,
1653
+ traceId
1654
+ });
1655
+ fireAndForget(navigate({
1656
+ to: "/traces"
1657
+ }));
1658
+ };
1429
1659
  const {
1430
1660
  data,
1431
1661
  error,
@@ -1645,6 +1875,7 @@ const MetricsPanel = ({
1645
1875
  })
1646
1876
  }, void 0, false)]
1647
1877
  }, void 0, true), effectiveTab === "overview" && metrics === null && null, effectiveTab === "overview" && /* @__PURE__ */ jsxDEV(InstrumentsTable, {
1878
+ onOpenTrace: openTrace,
1648
1879
  shardKey: debouncedShard
1649
1880
  }, void 0, false), effectiveTab === "overview" && aggregate !== null && shardResults !== null && /* @__PURE__ */ jsxDEV("div", {
1650
1881
  className: "flex flex-col gap-4",