@dudousxd/nestjs-telescope-ui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +349 -0
- package/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +2 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/telescope-client.d.ts +63 -0
- package/dist/client/telescope-client.d.ts.map +1 -0
- package/dist/client/telescope-client.js +87 -0
- package/dist/client/telescope-client.js.map +1 -0
- package/dist/client/types.d.ts +267 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/react/components/batch-timeline.d.ts +7 -0
- package/dist/react/components/batch-timeline.d.ts.map +1 -0
- package/dist/react/components/batch-timeline.js +10 -0
- package/dist/react/components/batch-timeline.js.map +1 -0
- package/dist/react/components/cache-badge.d.ts +20 -0
- package/dist/react/components/cache-badge.d.ts.map +1 -0
- package/dist/react/components/cache-badge.js +42 -0
- package/dist/react/components/cache-badge.js.map +1 -0
- package/dist/react/components/charts/area-chart-card.d.ts +16 -0
- package/dist/react/components/charts/area-chart-card.d.ts.map +1 -0
- package/dist/react/components/charts/area-chart-card.js +12 -0
- package/dist/react/components/charts/area-chart-card.js.map +1 -0
- package/dist/react/components/charts/bar-chart-card.d.ts +26 -0
- package/dist/react/components/charts/bar-chart-card.d.ts.map +1 -0
- package/dist/react/components/charts/bar-chart-card.js +27 -0
- package/dist/react/components/charts/bar-chart-card.js.map +1 -0
- package/dist/react/components/charts/chart-card.d.ts +11 -0
- package/dist/react/components/charts/chart-card.d.ts.map +1 -0
- package/dist/react/components/charts/chart-card.js +9 -0
- package/dist/react/components/charts/chart-card.js.map +1 -0
- package/dist/react/components/charts/chart-theme.d.ts +41 -0
- package/dist/react/components/charts/chart-theme.d.ts.map +1 -0
- package/dist/react/components/charts/chart-theme.js +53 -0
- package/dist/react/components/charts/chart-theme.js.map +1 -0
- package/dist/react/components/charts/index.d.ts +6 -0
- package/dist/react/components/charts/index.d.ts.map +1 -0
- package/dist/react/components/charts/index.js +6 -0
- package/dist/react/components/charts/index.js.map +1 -0
- package/dist/react/components/charts/stacked-area-chart-card.d.ts +14 -0
- package/dist/react/components/charts/stacked-area-chart-card.d.ts.map +1 -0
- package/dist/react/components/charts/stacked-area-chart-card.js +13 -0
- package/dist/react/components/charts/stacked-area-chart-card.js.map +1 -0
- package/dist/react/components/entries-table.d.ts +11 -0
- package/dist/react/components/entries-table.d.ts.map +1 -0
- package/dist/react/components/entries-table.js +68 -0
- package/dist/react/components/entries-table.js.map +1 -0
- package/dist/react/components/entry-detail.d.ts +6 -0
- package/dist/react/components/entry-detail.d.ts.map +1 -0
- package/dist/react/components/entry-detail.js +110 -0
- package/dist/react/components/entry-detail.js.map +1 -0
- package/dist/react/components/entry-insights.d.ts +5 -0
- package/dist/react/components/entry-insights.d.ts.map +1 -0
- package/dist/react/components/entry-insights.js +107 -0
- package/dist/react/components/entry-insights.js.map +1 -0
- package/dist/react/components/entry-types.d.ts +40 -0
- package/dist/react/components/entry-types.d.ts.map +1 -0
- package/dist/react/components/entry-types.js +44 -0
- package/dist/react/components/entry-types.js.map +1 -0
- package/dist/react/components/export-json-toolbar.d.ts +9 -0
- package/dist/react/components/export-json-toolbar.d.ts.map +1 -0
- package/dist/react/components/export-json-toolbar.js +21 -0
- package/dist/react/components/export-json-toolbar.js.map +1 -0
- package/dist/react/components/export-json.d.ts +14 -0
- package/dist/react/components/export-json.d.ts.map +1 -0
- package/dist/react/components/export-json.js +44 -0
- package/dist/react/components/export-json.js.map +1 -0
- package/dist/react/components/pulse-panel.d.ts +9 -0
- package/dist/react/components/pulse-panel.d.ts.map +1 -0
- package/dist/react/components/pulse-panel.js +20 -0
- package/dist/react/components/pulse-panel.js.map +1 -0
- package/dist/react/components/queue-sparkline.d.ts +5 -0
- package/dist/react/components/queue-sparkline.d.ts.map +1 -0
- package/dist/react/components/queue-sparkline.js +8 -0
- package/dist/react/components/queue-sparkline.js.map +1 -0
- package/dist/react/components/queues/EnqueueJobForm.d.ts +14 -0
- package/dist/react/components/queues/EnqueueJobForm.d.ts.map +1 -0
- package/dist/react/components/queues/EnqueueJobForm.js +61 -0
- package/dist/react/components/queues/EnqueueJobForm.js.map +1 -0
- package/dist/react/components/queues/JobActions.d.ts +38 -0
- package/dist/react/components/queues/JobActions.d.ts.map +1 -0
- package/dist/react/components/queues/JobActions.js +106 -0
- package/dist/react/components/queues/JobActions.js.map +1 -0
- package/dist/react/components/queues/JobDetailDrawer.d.ts +11 -0
- package/dist/react/components/queues/JobDetailDrawer.d.ts.map +1 -0
- package/dist/react/components/queues/JobDetailDrawer.js +45 -0
- package/dist/react/components/queues/JobDetailDrawer.js.map +1 -0
- package/dist/react/components/queues/JobTable.d.ts +13 -0
- package/dist/react/components/queues/JobTable.d.ts.map +1 -0
- package/dist/react/components/queues/JobTable.js +0 -0
- package/dist/react/components/queues/JobTable.js.map +1 -0
- package/dist/react/components/queues/QueueList.d.ts +8 -0
- package/dist/react/components/queues/QueueList.d.ts.map +1 -0
- package/dist/react/components/queues/QueueList.js +27 -0
- package/dist/react/components/queues/QueueList.js.map +1 -0
- package/dist/react/components/queues/QueueStateTabs.d.ts +7 -0
- package/dist/react/components/queues/QueueStateTabs.d.ts.map +1 -0
- package/dist/react/components/queues/QueueStateTabs.js +12 -0
- package/dist/react/components/queues/QueueStateTabs.js.map +1 -0
- package/dist/react/components/queues/index.d.ts +8 -0
- package/dist/react/components/queues/index.d.ts.map +1 -0
- package/dist/react/components/queues/index.js +8 -0
- package/dist/react/components/queues/index.js.map +1 -0
- package/dist/react/components/queues/queue-format.d.ts +8 -0
- package/dist/react/components/queues/queue-format.d.ts.map +1 -0
- package/dist/react/components/queues/queue-format.js +51 -0
- package/dist/react/components/queues/queue-format.js.map +1 -0
- package/dist/react/components/queues-panel.d.ts +6 -0
- package/dist/react/components/queues-panel.d.ts.map +1 -0
- package/dist/react/components/queues-panel.js +8 -0
- package/dist/react/components/queues-panel.js.map +1 -0
- package/dist/react/components/request-timeline.d.ts +14 -0
- package/dist/react/components/request-timeline.d.ts.map +1 -0
- package/dist/react/components/request-timeline.js +30 -0
- package/dist/react/components/request-timeline.js.map +1 -0
- package/dist/react/components/retention-indicator.d.ts +10 -0
- package/dist/react/components/retention-indicator.d.ts.map +1 -0
- package/dist/react/components/retention-indicator.js +38 -0
- package/dist/react/components/retention-indicator.js.map +1 -0
- package/dist/react/components/sparkline.d.ts +7 -0
- package/dist/react/components/sparkline.d.ts.map +1 -0
- package/dist/react/components/sparkline.js +20 -0
- package/dist/react/components/sparkline.js.map +1 -0
- package/dist/react/components/stacked-bars.d.ts +21 -0
- package/dist/react/components/stacked-bars.d.ts.map +1 -0
- package/dist/react/components/stacked-bars.js +51 -0
- package/dist/react/components/stacked-bars.js.map +1 -0
- package/dist/react/components/tag-autocomplete.d.ts +12 -0
- package/dist/react/components/tag-autocomplete.d.ts.map +1 -0
- package/dist/react/components/tag-autocomplete.js +90 -0
- package/dist/react/components/tag-autocomplete.js.map +1 -0
- package/dist/react/components/trace-link.d.ts +6 -0
- package/dist/react/components/trace-link.d.ts.map +1 -0
- package/dist/react/components/trace-link.js +10 -0
- package/dist/react/components/trace-link.js.map +1 -0
- package/dist/react/components/type-tabs.d.ts +5 -0
- package/dist/react/components/type-tabs.d.ts.map +1 -0
- package/dist/react/components/type-tabs.js +8 -0
- package/dist/react/components/type-tabs.js.map +1 -0
- package/dist/react/components/window-select.d.ts +5 -0
- package/dist/react/components/window-select.d.ts.map +1 -0
- package/dist/react/components/window-select.js +6 -0
- package/dist/react/components/window-select.js.map +1 -0
- package/dist/react/index.d.ts +23 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +23 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/telescope-context.d.ts +14 -0
- package/dist/react/telescope-context.d.ts.map +1 -0
- package/dist/react/telescope-context.js +27 -0
- package/dist/react/telescope-context.js.map +1 -0
- package/dist/react/use-telescope-queries.d.ts +244 -0
- package/dist/react/use-telescope-queries.d.ts.map +1 -0
- package/dist/react/use-telescope-queries.js +216 -0
- package/dist/react/use-telescope-queries.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/telescope-ui.controller.d.ts +10 -0
- package/dist/server/telescope-ui.controller.d.ts.map +1 -0
- package/dist/server/telescope-ui.controller.js +105 -0
- package/dist/server/telescope-ui.controller.js.map +1 -0
- package/dist/server/telescope-ui.module.d.ts +6 -0
- package/dist/server/telescope-ui.module.d.ts.map +1 -0
- package/dist/server/telescope-ui.module.js +26 -0
- package/dist/server/telescope-ui.module.js.map +1 -0
- package/dist/server/telescope-ui.options.d.ts +12 -0
- package/dist/server/telescope-ui.options.d.ts.map +1 -0
- package/dist/server/telescope-ui.options.js +2 -0
- package/dist/server/telescope-ui.options.js.map +1 -0
- package/dist/spa/assets/index-BHS361H_.js +135 -0
- package/dist/spa/assets/index-DsBEgxHC.css +1 -0
- package/dist/spa/index.html +13 -0
- package/package.json +97 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueueStateTabs.js","sourceRoot":"","sources":["../../../../src/react/components/queues/QueueStateTabs.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEpE,MAAM,UAAU,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,OAAO,GAKR;IACC,OAAO,CACL,cAAK,SAAS,EAAC,oDAAoD,YAChE,iBAAiB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,SAAS,KAAK,KAAK,CAAC;YACnC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACvC,OAAO,CACL,kBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EACjC,SAAS,EAAE,gFACT,MAAM;oBACJ,CAAC,CAAC,2BAA2B;oBAC7B,CAAC,CAAC,qDACN,EAAE,aAEF,eAAM,SAAS,EAAC,YAAY,YAAE,SAAS,GAAQ,EAC/C,eACE,SAAS,EAAE,4BACT,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,eACrC,EAAE,YAED,KAAK,GACD,KAhBF,SAAS,CAiBP,CACV,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { QueueList } from './QueueList.js';
|
|
2
|
+
export { QueueStateTabs } from './QueueStateTabs.js';
|
|
3
|
+
export { JobTable } from './JobTable.js';
|
|
4
|
+
export { JobDetailDrawer } from './JobDetailDrawer.js';
|
|
5
|
+
export { JobActions, RetryAllFailedButton, RedriveDlqButton, supportsAction, jobActionAllowedForState, } from './JobActions.js';
|
|
6
|
+
export { EnqueueJobForm } from './EnqueueJobForm.js';
|
|
7
|
+
export { QUEUE_STATE_ORDER, STATE_ACCENT, relativeTime, payloadPreview, } from './queue-format.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react/components/queues/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { QueueList } from './QueueList.js';
|
|
2
|
+
export { QueueStateTabs } from './QueueStateTabs.js';
|
|
3
|
+
export { JobTable } from './JobTable.js';
|
|
4
|
+
export { JobDetailDrawer } from './JobDetailDrawer.js';
|
|
5
|
+
export { JobActions, RetryAllFailedButton, RedriveDlqButton, supportsAction, jobActionAllowedForState, } from './JobActions.js';
|
|
6
|
+
export { EnqueueJobForm } from './EnqueueJobForm.js';
|
|
7
|
+
export { QUEUE_STATE_ORDER, STATE_ACCENT, relativeTime, payloadPreview, } from './queue-format.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/react/components/queues/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { QueueState } from '../../../client/index.js';
|
|
2
|
+
export declare const QUEUE_STATE_ORDER: readonly QueueState[];
|
|
3
|
+
/** Per-state accent colors, consistent across list badges and tabs. */
|
|
4
|
+
export declare const STATE_ACCENT: Record<QueueState, string>;
|
|
5
|
+
export declare function relativeTime(timestamp: number | null): string;
|
|
6
|
+
/** One-line, length-capped JSON-ish preview of a job payload. */
|
|
7
|
+
export declare function payloadPreview(data: unknown, max?: number): string;
|
|
8
|
+
//# sourceMappingURL=queue-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-format.d.ts","sourceRoot":"","sources":["../../../../src/react/components/queues/queue-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,eAAO,MAAM,iBAAiB,EAAE,SAAS,UAAU,EAOlD,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAOnD,CAAC;AAEF,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAY7D;AAED,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,SAAK,GAAG,MAAM,CAU9D"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const QUEUE_STATE_ORDER = [
|
|
2
|
+
'waiting',
|
|
3
|
+
'active',
|
|
4
|
+
'delayed',
|
|
5
|
+
'failed',
|
|
6
|
+
'completed',
|
|
7
|
+
'paused',
|
|
8
|
+
];
|
|
9
|
+
/** Per-state accent colors, consistent across list badges and tabs. */
|
|
10
|
+
export const STATE_ACCENT = {
|
|
11
|
+
waiting: 'text-zinc-300',
|
|
12
|
+
active: 'text-sky-400',
|
|
13
|
+
delayed: 'text-amber-400',
|
|
14
|
+
failed: 'text-red-400',
|
|
15
|
+
completed: 'text-emerald-400',
|
|
16
|
+
paused: 'text-violet-400',
|
|
17
|
+
};
|
|
18
|
+
export function relativeTime(timestamp) {
|
|
19
|
+
if (timestamp == null)
|
|
20
|
+
return '—';
|
|
21
|
+
const deltaMs = Date.now() - timestamp;
|
|
22
|
+
if (deltaMs < 0)
|
|
23
|
+
return 'just now';
|
|
24
|
+
const seconds = Math.floor(deltaMs / 1000);
|
|
25
|
+
if (seconds < 60)
|
|
26
|
+
return `${seconds}s ago`;
|
|
27
|
+
const minutes = Math.floor(seconds / 60);
|
|
28
|
+
if (minutes < 60)
|
|
29
|
+
return `${minutes}m ago`;
|
|
30
|
+
const hours = Math.floor(minutes / 60);
|
|
31
|
+
if (hours < 24)
|
|
32
|
+
return `${hours}h ago`;
|
|
33
|
+
const days = Math.floor(hours / 24);
|
|
34
|
+
return `${days}d ago`;
|
|
35
|
+
}
|
|
36
|
+
/** One-line, length-capped JSON-ish preview of a job payload. */
|
|
37
|
+
export function payloadPreview(data, max = 80) {
|
|
38
|
+
if (data === undefined || data === null)
|
|
39
|
+
return '—';
|
|
40
|
+
let text;
|
|
41
|
+
try {
|
|
42
|
+
text = typeof data === 'string' ? data : JSON.stringify(data);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
text = String(data);
|
|
46
|
+
}
|
|
47
|
+
if (text.length <= max)
|
|
48
|
+
return text;
|
|
49
|
+
return `${text.slice(0, max - 1)}…`;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=queue-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-format.js","sourceRoot":"","sources":["../../../../src/react/components/queues/queue-format.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAA0B;IACtD,SAAS;IACT,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,WAAW;IACX,QAAQ;CACT,CAAC;AAEF,uEAAuE;AACvE,MAAM,CAAC,MAAM,YAAY,GAA+B;IACtD,OAAO,EAAE,eAAe;IACxB,MAAM,EAAE,cAAc;IACtB,OAAO,EAAE,gBAAgB;IACzB,MAAM,EAAE,cAAc;IACtB,SAAS,EAAE,kBAAkB;IAC7B,MAAM,EAAE,iBAAiB;CAC1B,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,SAAwB;IACnD,IAAI,SAAS,IAAI,IAAI;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACvC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,OAAO,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,OAAO,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,OAAO,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,IAAI,OAAO,CAAC;AACxB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,GAAG,GAAG,EAAE;IACpD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IACpD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { QueueMetricsReport } from '../../client/index.js';
|
|
2
|
+
export declare function QueuesPanel({ report, sparkline, }: {
|
|
3
|
+
report: QueueMetricsReport;
|
|
4
|
+
sparkline?: (queue: string) => React.ReactNode;
|
|
5
|
+
}): JSX.Element;
|
|
6
|
+
//# sourceMappingURL=queues-panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queues-panel.d.ts","sourceRoot":"","sources":["../../../src/react/components/queues-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM/E,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,SAAS,GACV,EAAE;IACD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAChD,GAAG,GAAG,CAAC,OAAO,CAwCd"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function p95(stats) {
|
|
3
|
+
return stats ? `${Math.round(stats.p95)}ms` : '—';
|
|
4
|
+
}
|
|
5
|
+
export function QueuesPanel({ report, sparkline, }) {
|
|
6
|
+
return (_jsxs("table", { className: "w-full text-left text-xs", children: [_jsx("thead", { className: "text-zinc-500", children: _jsxs("tr", { children: [_jsx("th", { className: "py-2 font-normal", children: "Queue" }), _jsx("th", { className: "font-normal", children: "Total" }), _jsx("th", { className: "font-normal", children: "Failed" }), _jsx("th", { className: "font-normal", children: "Fail %" }), _jsx("th", { className: "font-normal", children: "Per min" }), _jsx("th", { className: "font-normal", children: "Runtime p95" }), _jsx("th", { className: "font-normal", children: "Wait p95" }), sparkline && _jsx("th", { className: "font-normal", children: "Trend" })] }) }), _jsxs("tbody", { children: [report.queues.map((q) => (_jsxs("tr", { className: "border-t border-zinc-900", children: [_jsx("td", { className: "py-1.5 text-emerald-400", children: q.queue }), _jsx("td", { className: "text-zinc-300", children: q.total }), _jsx("td", { className: "text-zinc-300", children: q.failed }), _jsxs("td", { className: q.failureRate > 0 ? 'text-red-400' : 'text-zinc-500', children: [(q.failureRate * 100).toFixed(1), "%"] }), _jsx("td", { className: "text-zinc-400", children: q.throughputPerMinute.toFixed(1) }), _jsx("td", { className: "text-zinc-400", children: p95(q.runtimeMs) }), _jsx("td", { className: "text-zinc-400", children: p95(q.waitMs) }), sparkline && _jsx("td", { className: "text-zinc-400", children: sparkline(q.queue) })] }, q.queue))), report.queues.length === 0 && (_jsx("tr", { children: _jsx("td", { className: "py-2 text-zinc-600", colSpan: sparkline ? 8 : 7, children: "No queue activity in window." }) }))] })] }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=queues-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queues-panel.js","sourceRoot":"","sources":["../../../src/react/components/queues-panel.tsx"],"names":[],"mappings":";AAEA,SAAS,GAAG,CAAC,KAA2B;IACtC,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,MAAM,EACN,SAAS,GAIV;IACC,OAAO,CACL,iBAAO,SAAS,EAAC,0BAA0B,aACzC,gBAAO,SAAS,EAAC,eAAe,YAC9B,yBACE,aAAI,SAAS,EAAC,kBAAkB,sBAAW,EAC3C,aAAI,SAAS,EAAC,aAAa,sBAAW,EACtC,aAAI,SAAS,EAAC,aAAa,uBAAY,EACvC,aAAI,SAAS,EAAC,aAAa,uBAAY,EACvC,aAAI,SAAS,EAAC,aAAa,wBAAa,EACxC,aAAI,SAAS,EAAC,aAAa,4BAAiB,EAC5C,aAAI,SAAS,EAAC,aAAa,yBAAc,EACxC,SAAS,IAAI,aAAI,SAAS,EAAC,aAAa,sBAAW,IACjD,GACC,EACR,4BACG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACxB,cAAkB,SAAS,EAAC,0BAA0B,aACpD,aAAI,SAAS,EAAC,yBAAyB,YAAE,CAAC,CAAC,KAAK,GAAM,EACtD,aAAI,SAAS,EAAC,eAAe,YAAE,CAAC,CAAC,KAAK,GAAM,EAC5C,aAAI,SAAS,EAAC,eAAe,YAAE,CAAC,CAAC,MAAM,GAAM,EAC7C,cAAI,SAAS,EAAE,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,aAChE,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAC9B,EACL,aAAI,SAAS,EAAC,eAAe,YAAE,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAM,EACrE,aAAI,SAAS,EAAC,eAAe,YAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAM,EACrD,aAAI,SAAS,EAAC,eAAe,YAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAM,EACjD,SAAS,IAAI,aAAI,SAAS,EAAC,eAAe,YAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAM,KAV9D,CAAC,CAAC,KAAK,CAWX,CACN,CAAC,EACD,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAC7B,uBACE,aAAI,SAAS,EAAC,oBAAoB,EAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,6CAExD,GACF,CACN,IACK,IACF,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Entry } from '../../client/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Compact waterfall of a request's batch: the request plus every child entry
|
|
4
|
+
* (queries, cache, jobs, …) captured during it, ordered by `sequence`. Each row
|
|
5
|
+
* shows a type dot, a short label, a horizontal duration bar scaled to the
|
|
6
|
+
* slowest entry in the batch, and the `durationMs`. This surfaces "where did the
|
|
7
|
+
* time go in this request" without leaving for a trace viewer.
|
|
8
|
+
*/
|
|
9
|
+
export declare function RequestTimeline({ batch, requestId, onSelect, }: {
|
|
10
|
+
batch: Entry[];
|
|
11
|
+
requestId: string;
|
|
12
|
+
onSelect?: ((id: string) => void) | undefined;
|
|
13
|
+
}): JSX.Element;
|
|
14
|
+
//# sourceMappingURL=request-timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-timeline.d.ts","sourceRoot":"","sources":["../../../src/react/components/request-timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAOnD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,SAAS,EACT,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC/C,GAAG,GAAG,CAAC,OAAO,CA0Bd"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { entryLabel } from './entries-table.js';
|
|
3
|
+
import { dotForType } from './entry-types.js';
|
|
4
|
+
/** Max child rows to render before collapsing into a "+N more" note. */
|
|
5
|
+
const MAX_ROWS = 50;
|
|
6
|
+
/**
|
|
7
|
+
* Compact waterfall of a request's batch: the request plus every child entry
|
|
8
|
+
* (queries, cache, jobs, …) captured during it, ordered by `sequence`. Each row
|
|
9
|
+
* shows a type dot, a short label, a horizontal duration bar scaled to the
|
|
10
|
+
* slowest entry in the batch, and the `durationMs`. This surfaces "where did the
|
|
11
|
+
* time go in this request" without leaving for a trace viewer.
|
|
12
|
+
*/
|
|
13
|
+
export function RequestTimeline({ batch, requestId, onSelect, }) {
|
|
14
|
+
const ordered = [...batch].sort((a, b) => a.sequence - b.sequence);
|
|
15
|
+
const maxDuration = ordered.reduce((max, entry) => (entry.durationMs != null && entry.durationMs > max ? entry.durationMs : max), 0);
|
|
16
|
+
const visible = ordered.slice(0, MAX_ROWS);
|
|
17
|
+
const hidden = ordered.length - visible.length;
|
|
18
|
+
return (_jsxs("div", { children: [_jsx("ol", { className: "space-y-1", children: visible.map((entry) => (_jsx("li", { children: _jsx(TimelineRow, { entry: entry, maxDuration: maxDuration, isRequest: entry.id === requestId, onSelect: onSelect }) }, entry.id))) }), hidden > 0 ? _jsxs("p", { className: "mt-1 px-2 text-[10px] text-zinc-600", children: ["+", hidden, " more"] }) : null] }));
|
|
19
|
+
}
|
|
20
|
+
function TimelineRow({ entry, maxDuration, isRequest, onSelect, }) {
|
|
21
|
+
// Width is the entry's share of the slowest entry in the batch. Null and
|
|
22
|
+
// zero-duration entries collapse to a minimal sliver so the row still reads.
|
|
23
|
+
const fraction = maxDuration > 0 && entry.durationMs != null ? entry.durationMs / maxDuration : 0;
|
|
24
|
+
const widthPercent = Math.max(0, Math.min(100, fraction * 100));
|
|
25
|
+
return (_jsxs("button", { type: "button", onClick: (event) => {
|
|
26
|
+
event.stopPropagation();
|
|
27
|
+
onSelect?.(entry.id);
|
|
28
|
+
}, className: `flex w-full items-center gap-2 rounded px-2 py-1 text-left text-xs ${isRequest ? 'bg-zinc-800 text-emerald-300' : 'text-zinc-400 hover:bg-zinc-900'}`, children: [_jsx("span", { className: `h-2 w-2 shrink-0 rounded-full ${dotForType(entry.type)}`, "aria-hidden": true }), _jsx("span", { className: "w-40 shrink-0 truncate", title: entryLabel(entry), children: entryLabel(entry) }), _jsx("span", { className: "h-2 flex-1 overflow-hidden rounded bg-zinc-900", children: _jsx("span", { className: "block h-full rounded bg-emerald-500/60", style: { width: `${widthPercent}%` }, "aria-hidden": true }) }), _jsx("span", { className: "w-12 shrink-0 text-right tabular-nums text-zinc-500", children: entry.durationMs != null ? `${entry.durationMs}ms` : '—' })] }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=request-timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-timeline.js","sourceRoot":"","sources":["../../../src/react/components/request-timeline.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,wEAAwE;AACxE,MAAM,QAAQ,GAAG,EAAE,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,SAAS,EACT,QAAQ,GAKT;IACC,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAChC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAC7F,CAAC,CACF,CAAC;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE/C,OAAO,CACL,0BACE,aAAI,SAAS,EAAC,WAAW,YACtB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACtB,uBACE,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,KAAK,CAAC,EAAE,KAAK,SAAS,EACjC,QAAQ,EAAE,QAAQ,GAClB,IANK,KAAK,CAAC,EAAE,CAOZ,CACN,CAAC,GACC,EACJ,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAG,SAAS,EAAC,qCAAqC,kBAAG,MAAM,aAAU,CAAC,CAAC,CAAC,IAAI,IACtF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EACnB,KAAK,EACL,WAAW,EACX,SAAS,EACT,QAAQ,GAMT;IACC,yEAAyE;IACzE,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,WAAW,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAClG,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC;IAEhE,OAAO,CACL,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC,EACD,SAAS,EAAE,sEACT,SAAS,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,iCAC/C,EAAE,aAEF,eAAM,SAAS,EAAE,iCAAiC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,wBAAgB,EAC1F,eAAM,SAAS,EAAC,wBAAwB,EAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,YAC9D,UAAU,CAAC,KAAK,CAAC,GACb,EACP,eAAM,SAAS,EAAC,gDAAgD,YAC9D,eACE,SAAS,EAAC,wCAAwC,EAClD,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,GAAG,EAAE,wBAEpC,GACG,EACP,eAAM,SAAS,EAAC,qDAAqD,YAClE,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,GAAG,GACpD,IACA,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Format a millisecond duration to a short human string like `500ms`/`30s`/`5m`/`1h`/`2d`. */
|
|
2
|
+
export declare function formatRetention(afterMs: number): string;
|
|
3
|
+
/** Build a short note like "request sampled @ 25%" for the first type sampled below 1, or null. */
|
|
4
|
+
export declare function samplingNote(sampling: Record<string, number>): string | null;
|
|
5
|
+
/**
|
|
6
|
+
* Subtle header indicator surfacing the configured retention window (or "none"
|
|
7
|
+
* when unbounded) plus a tooltip hint when any entry type is down-sampled.
|
|
8
|
+
*/
|
|
9
|
+
export declare function RetentionIndicator(): JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=retention-indicator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention-indicator.d.ts","sourceRoot":"","sources":["../../../src/react/components/retention-indicator.tsx"],"names":[],"mappings":"AAOA,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED,mGAAmG;AACnG,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAK5E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,OAAO,GAAG,IAAI,CAsBvD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMeta } from '../use-telescope-queries.js';
|
|
3
|
+
const SECOND = 1000;
|
|
4
|
+
const MINUTE = 60 * SECOND;
|
|
5
|
+
const HOUR = 60 * MINUTE;
|
|
6
|
+
const DAY = 24 * HOUR;
|
|
7
|
+
/** Format a millisecond duration to a short human string like `500ms`/`30s`/`5m`/`1h`/`2d`. */
|
|
8
|
+
export function formatRetention(afterMs) {
|
|
9
|
+
if (afterMs >= DAY)
|
|
10
|
+
return `${Math.round(afterMs / DAY)}d`;
|
|
11
|
+
if (afterMs >= HOUR)
|
|
12
|
+
return `${Math.round(afterMs / HOUR)}h`;
|
|
13
|
+
if (afterMs >= MINUTE)
|
|
14
|
+
return `${Math.round(afterMs / MINUTE)}m`;
|
|
15
|
+
if (afterMs >= SECOND)
|
|
16
|
+
return `${Math.round(afterMs / SECOND)}s`;
|
|
17
|
+
return `${afterMs}ms`;
|
|
18
|
+
}
|
|
19
|
+
/** Build a short note like "request sampled @ 25%" for the first type sampled below 1, or null. */
|
|
20
|
+
export function samplingNote(sampling) {
|
|
21
|
+
for (const [type, rate] of Object.entries(sampling)) {
|
|
22
|
+
if (rate < 1)
|
|
23
|
+
return `${type} sampled @ ${Math.round(rate * 100)}%`;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Subtle header indicator surfacing the configured retention window (or "none"
|
|
29
|
+
* when unbounded) plus a tooltip hint when any entry type is down-sampled.
|
|
30
|
+
*/
|
|
31
|
+
export function RetentionIndicator() {
|
|
32
|
+
const { data: meta } = useMeta();
|
|
33
|
+
if (!meta)
|
|
34
|
+
return null;
|
|
35
|
+
const note = samplingNote(meta.sampling ?? {});
|
|
36
|
+
return (_jsxs("span", { className: "flex items-center gap-1.5 text-[11px] text-zinc-500", title: note ?? undefined, children: [_jsx("span", { className: "uppercase tracking-wide text-zinc-600", children: "retention:" }), meta.retention ? (_jsx("span", { className: "text-zinc-400", children: formatRetention(meta.retention.afterMs) })) : (_jsx("span", { className: "text-zinc-600", children: "none" })), note ? (_jsx("span", { "aria-label": note, className: "cursor-help rounded-full border border-zinc-700 px-1 text-[9px] text-zinc-500", children: "?" })) : null] }));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=retention-indicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention-indicator.js","sourceRoot":"","sources":["../../../src/react/components/retention-indicator.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEtD,MAAM,MAAM,GAAG,IAAI,CAAC;AACpB,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC;AAC3B,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC;AACzB,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtB,+FAA+F;AAC/F,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,OAAO,IAAI,GAAG;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC;IAC3D,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;IAC7D,IAAI,OAAO,IAAI,MAAM;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC;IACjE,IAAI,OAAO,IAAI,MAAM;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC;IACjE,OAAO,GAAG,OAAO,IAAI,CAAC;AACxB,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,YAAY,CAAC,QAAgC;IAC3D,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,GAAG,CAAC;YAAE,OAAO,GAAG,IAAI,cAAc,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAC/C,OAAO,CACL,gBAAM,SAAS,EAAC,qDAAqD,EAAC,KAAK,EAAE,IAAI,IAAI,SAAS,aAC5F,eAAM,SAAS,EAAC,uCAAuC,2BAAkB,EACxE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAChB,eAAM,SAAS,EAAC,eAAe,YAAE,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAQ,CACjF,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAC,eAAe,qBAAY,CAC5C,EACA,IAAI,CAAC,CAAC,CAAC,CACN,6BACc,IAAI,EAChB,SAAS,EAAC,+EAA+E,kBAGpF,CACR,CAAC,CAAC,CAAC,IAAI,IACH,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function sparklinePoints(values: number[], width: number, height: number): string;
|
|
2
|
+
export declare function Sparkline({ values, width, height, }: {
|
|
3
|
+
values: number[];
|
|
4
|
+
width?: number;
|
|
5
|
+
height?: number;
|
|
6
|
+
}): JSX.Element;
|
|
7
|
+
//# sourceMappingURL=sparkline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sparkline.d.ts","sourceRoot":"","sources":["../../../src/react/components/sparkline.tsx"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAWvF;AAED,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,KAAW,EACX,MAAW,GACZ,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAkBrE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function sparklinePoints(values, width, height) {
|
|
3
|
+
if (values.length === 0)
|
|
4
|
+
return '';
|
|
5
|
+
const max = Math.max(...values, 1);
|
|
6
|
+
const stepX = values.length > 1 ? width / (values.length - 1) : 0;
|
|
7
|
+
return values
|
|
8
|
+
.map((value, index) => {
|
|
9
|
+
const x = index * stepX;
|
|
10
|
+
const y = height - (value / max) * height;
|
|
11
|
+
return `${x.toFixed(1)},${y.toFixed(1)}`;
|
|
12
|
+
})
|
|
13
|
+
.join(' ');
|
|
14
|
+
}
|
|
15
|
+
export function Sparkline({ values, width = 160, height = 36, }) {
|
|
16
|
+
const points = sparklinePoints(values, width, height);
|
|
17
|
+
const area = points ? `0,${height} ${points} ${width},${height}` : '';
|
|
18
|
+
return (_jsxs("svg", { width: width, height: height, viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "none", role: "img", "aria-label": "throughput", children: [area && _jsx("polygon", { points: area, className: "fill-emerald-500/10" }), points && (_jsx("polyline", { points: points, className: "fill-none stroke-emerald-400", strokeWidth: 1.5 }))] }));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=sparkline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sparkline.js","sourceRoot":"","sources":["../../../src/react/components/sparkline.tsx"],"names":[],"mappings":";AAAA,MAAM,UAAU,eAAe,CAAC,MAAgB,EAAE,KAAa,EAAE,MAAc;IAC7E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;QACxB,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC;QAC1C,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EACxB,MAAM,EACN,KAAK,GAAG,GAAG,EACX,MAAM,GAAG,EAAE,GAC2C;IACtD,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,OAAO,CACL,eACE,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,KAAK,IAAI,MAAM,EAAE,EACjC,mBAAmB,EAAC,MAAM,EAC1B,IAAI,EAAC,KAAK,gBACC,YAAY,aAEtB,IAAI,IAAI,kBAAS,MAAM,EAAE,IAAI,EAAE,SAAS,EAAC,qBAAqB,GAAG,EACjE,MAAM,IAAI,CACT,mBAAU,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC,8BAA8B,EAAC,WAAW,EAAE,GAAG,GAAI,CACxF,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { TimeseriesBucket } from '../../client/index.js';
|
|
2
|
+
/** Tailwind `fill-*` classes per known entry type (extras fall back). */
|
|
3
|
+
export declare const TYPE_COLOR: Record<string, string>;
|
|
4
|
+
export declare function colorForType(type: string): string;
|
|
5
|
+
/** Ordered union of types present across buckets (known order first, then extras). */
|
|
6
|
+
export declare function deriveTypes(buckets: TimeseriesBucket[]): string[];
|
|
7
|
+
export interface BarSegment {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
type: string;
|
|
13
|
+
}
|
|
14
|
+
/** Compute stacked rects (bottom-up) for each bucket × type. Pure + testable. */
|
|
15
|
+
export declare function stackedBarLayout(buckets: TimeseriesBucket[], types: string[], width: number, height: number): BarSegment[];
|
|
16
|
+
export declare function StackedBars({ buckets, width, height, }: {
|
|
17
|
+
buckets: TimeseriesBucket[];
|
|
18
|
+
width?: number;
|
|
19
|
+
height?: number;
|
|
20
|
+
}): JSX.Element;
|
|
21
|
+
//# sourceMappingURL=stacked-bars.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stacked-bars.d.ts","sourceRoot":"","sources":["../../../src/react/components/stacked-bars.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,yEAAyE;AACzE,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAO7C,CAAC;AAGF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAQjE;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,UAAU,EAAE,CAgBd;AAED,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAW,EACX,MAAW,GACZ,EAAE;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAwBhF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/** Tailwind `fill-*` classes per known entry type (extras fall back). */
|
|
3
|
+
export const TYPE_COLOR = {
|
|
4
|
+
request: 'fill-emerald-400',
|
|
5
|
+
query: 'fill-sky-400',
|
|
6
|
+
job: 'fill-violet-400',
|
|
7
|
+
exception: 'fill-red-400',
|
|
8
|
+
http_client: 'fill-amber-400',
|
|
9
|
+
mail: 'fill-pink-400',
|
|
10
|
+
};
|
|
11
|
+
const FALLBACK_COLOR = 'fill-zinc-500';
|
|
12
|
+
export function colorForType(type) {
|
|
13
|
+
return TYPE_COLOR[type] ?? FALLBACK_COLOR;
|
|
14
|
+
}
|
|
15
|
+
/** Ordered union of types present across buckets (known order first, then extras). */
|
|
16
|
+
export function deriveTypes(buckets) {
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
for (const bucket of buckets) {
|
|
19
|
+
for (const type of Object.keys(bucket.byType))
|
|
20
|
+
seen.add(type);
|
|
21
|
+
}
|
|
22
|
+
const known = Object.keys(TYPE_COLOR).filter((type) => seen.has(type));
|
|
23
|
+
const extras = [...seen].filter((type) => !(type in TYPE_COLOR)).sort();
|
|
24
|
+
return [...known, ...extras];
|
|
25
|
+
}
|
|
26
|
+
/** Compute stacked rects (bottom-up) for each bucket × type. Pure + testable. */
|
|
27
|
+
export function stackedBarLayout(buckets, types, width, height) {
|
|
28
|
+
if (buckets.length === 0)
|
|
29
|
+
return [];
|
|
30
|
+
const maxTotal = Math.max(1, ...buckets.map((bucket) => bucket.total));
|
|
31
|
+
const barWidth = width / buckets.length;
|
|
32
|
+
const segments = [];
|
|
33
|
+
buckets.forEach((bucket, index) => {
|
|
34
|
+
let yCursor = height;
|
|
35
|
+
for (const type of types) {
|
|
36
|
+
const value = bucket.byType[type] ?? 0;
|
|
37
|
+
if (value === 0)
|
|
38
|
+
continue;
|
|
39
|
+
const segHeight = (value / maxTotal) * height;
|
|
40
|
+
yCursor -= segHeight;
|
|
41
|
+
segments.push({ x: index * barWidth, y: yCursor, width: barWidth, height: segHeight, type });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return segments;
|
|
45
|
+
}
|
|
46
|
+
export function StackedBars({ buckets, width = 640, height = 48, }) {
|
|
47
|
+
const types = deriveTypes(buckets);
|
|
48
|
+
const segments = stackedBarLayout(buckets, types, width, height);
|
|
49
|
+
return (_jsx("svg", { width: width, height: height, viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "none", role: "img", "aria-label": "throughput by type", children: segments.map((segment, index) => (_jsx("rect", { x: segment.x, y: segment.y, width: Math.max(0, segment.width - 0.5), height: segment.height, className: colorForType(segment.type) }, `${segment.type}-${segment.x}-${index}`))) }));
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=stacked-bars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stacked-bars.js","sourceRoot":"","sources":["../../../src/react/components/stacked-bars.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface TagAutocompleteProps {
|
|
2
|
+
/** Applies the chosen tag as the active entries filter (same effect as the old input). */
|
|
3
|
+
onSelect: (tag: string) => void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Tag filter rendered as an accessible combobox: typing queries `GET /tags?prefix=`
|
|
7
|
+
* and surfaces matching tags with their entry counts. Selecting one applies it as the
|
|
8
|
+
* active `tag` filter and closes the list. Empty input shows no dropdown.
|
|
9
|
+
*/
|
|
10
|
+
export declare function TagAutocomplete({ onSelect }: TagAutocompleteProps): JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=tag-autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-autocomplete.d.ts","sourceRoot":"","sources":["../../../src/react/components/tag-autocomplete.tsx"],"names":[],"mappings":"AAOA,UAAU,oBAAoB;IAC5B,0FAA0F;IAC1F,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAYD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CAiH/E"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
3
|
+
import { useTags } from '../use-telescope-queries.js';
|
|
4
|
+
/** Top-N suggestions shown in the dropdown, sorted by count desc. */
|
|
5
|
+
const MAX_SUGGESTIONS = 10;
|
|
6
|
+
/** Sorts by count desc, caps to the top N, and (defensively) filters by the typed prefix
|
|
7
|
+
* in case a stale/over-broad cache entry is served while a narrower query loads. */
|
|
8
|
+
function rankSuggestions(tags, prefix) {
|
|
9
|
+
const needle = prefix.trim().toLowerCase();
|
|
10
|
+
return tags
|
|
11
|
+
.filter((entry) => needle === '' || entry.tag.toLowerCase().includes(needle))
|
|
12
|
+
.sort((left, right) => right.count - left.count)
|
|
13
|
+
.slice(0, MAX_SUGGESTIONS);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Tag filter rendered as an accessible combobox: typing queries `GET /tags?prefix=`
|
|
17
|
+
* and surfaces matching tags with their entry counts. Selecting one applies it as the
|
|
18
|
+
* active `tag` filter and closes the list. Empty input shows no dropdown.
|
|
19
|
+
*/
|
|
20
|
+
export function TagAutocomplete({ onSelect }) {
|
|
21
|
+
const [input, setInput] = useState('');
|
|
22
|
+
const [open, setOpen] = useState(false);
|
|
23
|
+
const [highlight, setHighlight] = useState(0);
|
|
24
|
+
const containerRef = useRef(null);
|
|
25
|
+
const listboxId = useId();
|
|
26
|
+
const trimmed = input.trim();
|
|
27
|
+
const { data } = useTags(trimmed);
|
|
28
|
+
const suggestions = trimmed === '' ? [] : rankSuggestions(data ?? [], trimmed);
|
|
29
|
+
const showList = open && suggestions.length > 0;
|
|
30
|
+
// Clamp the highlight whenever the suggestion set shrinks.
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
setHighlight((current) => (current >= suggestions.length ? 0 : current));
|
|
33
|
+
}, [suggestions.length]);
|
|
34
|
+
// Close when focus/click leaves the combobox.
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
function onPointerDown(event) {
|
|
37
|
+
const target = event.target;
|
|
38
|
+
if (target instanceof Node && !containerRef.current?.contains(target))
|
|
39
|
+
setOpen(false);
|
|
40
|
+
}
|
|
41
|
+
document.addEventListener('mousedown', onPointerDown);
|
|
42
|
+
return () => document.removeEventListener('mousedown', onPointerDown);
|
|
43
|
+
}, []);
|
|
44
|
+
function choose(tag) {
|
|
45
|
+
onSelect(tag);
|
|
46
|
+
setInput(tag);
|
|
47
|
+
setOpen(false);
|
|
48
|
+
}
|
|
49
|
+
function onKeyDown(event) {
|
|
50
|
+
if (event.key === 'Escape') {
|
|
51
|
+
setOpen(false);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (!showList) {
|
|
55
|
+
if (event.key === 'Enter' && trimmed !== '')
|
|
56
|
+
choose(trimmed);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (event.key === 'ArrowDown') {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
setHighlight((current) => (current + 1) % suggestions.length);
|
|
62
|
+
}
|
|
63
|
+
else if (event.key === 'ArrowUp') {
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
setHighlight((current) => (current - 1 + suggestions.length) % suggestions.length);
|
|
66
|
+
}
|
|
67
|
+
else if (event.key === 'Enter') {
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
const picked = suggestions[highlight];
|
|
70
|
+
if (picked)
|
|
71
|
+
choose(picked.tag);
|
|
72
|
+
else if (trimmed !== '')
|
|
73
|
+
choose(trimmed);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const activeId = showList ? `${listboxId}-option-${highlight}` : undefined;
|
|
77
|
+
return (_jsxs("div", { ref: containerRef, className: "relative", children: [_jsx("input", { type: "text", value: input, onChange: (event) => {
|
|
78
|
+
setInput(event.target.value);
|
|
79
|
+
setOpen(true);
|
|
80
|
+
}, onFocus: () => setOpen(true), onKeyDown: onKeyDown, placeholder: "Filter by tag\u2026", "aria-label": "Filter by tag", role: "combobox", "aria-expanded": showList, "aria-controls": listboxId, "aria-autocomplete": "list", ...(activeId ? { 'aria-activedescendant': activeId } : {}), className: "rounded border border-zinc-800 bg-zinc-950 px-2 py-1 text-xs text-zinc-200 placeholder:text-zinc-600 focus:border-emerald-500 focus:outline-none" }), showList ? (_jsx("div", { id: listboxId,
|
|
81
|
+
// biome-ignore lint/a11y/useSemanticElements: a <select> can't render styled tag+count option rows; ARIA combobox listbox pattern
|
|
82
|
+
role: "listbox", "aria-label": "Tag suggestions", tabIndex: -1, className: "absolute left-0 top-full z-10 mt-1 max-h-64 w-48 overflow-auto rounded border border-zinc-800 bg-zinc-950 py-1 shadow-lg", children: suggestions.map((suggestion, index) => (_jsxs("div", { id: `${listboxId}-option-${index}`,
|
|
83
|
+
// biome-ignore lint/a11y/useSemanticElements: <option> can't host the styled tag+count layout; ARIA combobox option pattern
|
|
84
|
+
role: "option", tabIndex: -1, "aria-selected": index === highlight, onMouseDown: (event) => {
|
|
85
|
+
// mousedown (not click) so the input's blur doesn't close the list first
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
choose(suggestion.tag);
|
|
88
|
+
}, onMouseEnter: () => setHighlight(index), className: `flex cursor-pointer items-center justify-between gap-3 px-2 py-1 text-xs ${index === highlight ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-300'}`, children: [_jsx("span", { className: "truncate", children: suggestion.tag }), _jsx("span", { className: "shrink-0 text-zinc-500", children: suggestion.count })] }, suggestion.tag))) })) : null] }));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=tag-autocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-autocomplete.js","sourceRoot":"","sources":["../../../src/react/components/tag-autocomplete.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a concrete trace URL from a host-configured template by substituting
|
|
3
|
+
* the `{traceId}` / `{spanId}` placeholders. Returns null when no template is set.
|
|
4
|
+
*/
|
|
5
|
+
export declare function buildTraceHref(template: string | null, traceId: string, spanId: string): string | null;
|
|
6
|
+
//# sourceMappingURL=trace-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-link.d.ts","sourceRoot":"","sources":["../../../src/react/components/trace-link.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAGf"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a concrete trace URL from a host-configured template by substituting
|
|
3
|
+
* the `{traceId}` / `{spanId}` placeholders. Returns null when no template is set.
|
|
4
|
+
*/
|
|
5
|
+
export function buildTraceHref(template, traceId, spanId) {
|
|
6
|
+
if (!template)
|
|
7
|
+
return null;
|
|
8
|
+
return template.replaceAll('{traceId}', traceId).replaceAll('{spanId}', spanId);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=trace-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-link.js","sourceRoot":"","sources":["../../../src/react/components/trace-link.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAuB,EACvB,OAAe,EACf,MAAc;IAEd,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAClF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-tabs.d.ts","sourceRoot":"","sources":["../../../src/react/components/type-tabs.tsx"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,QAAQ,GACT,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAmBpE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const TYPES = ['all', 'request', 'query', 'job', 'exception', 'http_client', 'mail'];
|
|
3
|
+
export function TypeTabs({ active, onChange, }) {
|
|
4
|
+
return (_jsx("div", { className: "flex gap-1 border-b border-zinc-800", children: TYPES.map((type) => (_jsx("button", { type: "button", onClick: () => onChange(type), className: `px-3 py-2 text-xs uppercase tracking-wide ${active === type
|
|
5
|
+
? 'border-b-2 border-emerald-400 text-emerald-300'
|
|
6
|
+
: 'text-zinc-500 hover:text-zinc-300'}`, children: type }, type))) }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=type-tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-tabs.js","sourceRoot":"","sources":["../../../src/react/components/type-tabs.tsx"],"names":[],"mappings":";AAAA,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,CAAU,CAAC;AAE9F,MAAM,UAAU,QAAQ,CAAC,EACvB,MAAM,EACN,QAAQ,GAC6C;IACrD,OAAO,CACL,cAAK,SAAS,EAAC,qCAAqC,YACjD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,iBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC7B,SAAS,EAAE,6CACT,MAAM,KAAK,IAAI;gBACb,CAAC,CAAC,gDAAgD;gBAClD,CAAC,CAAC,mCACN,EAAE,YAED,IAAI,IATA,IAAI,CAUF,CACV,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-select.d.ts","sourceRoot":"","sources":["../../../src/react/components/window-select.tsx"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,GACT,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAchE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const WINDOWS = ['15m', '1h', '6h', '24h'];
|
|
3
|
+
export function WindowSelect({ value, onChange, }) {
|
|
4
|
+
return (_jsx("select", { value: value, onChange: (event) => onChange(event.target.value), className: "rounded border border-zinc-800 bg-zinc-900 px-2 py-1 text-xs text-zinc-300", children: WINDOWS.map((w) => (_jsx("option", { value: w, children: w }, w))) }));
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=window-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-select.js","sourceRoot":"","sources":["../../../src/react/components/window-select.tsx"],"names":[],"mappings":";AAAA,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAU,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,GACyC;IACjD,OAAO,CACL,iBACE,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACjD,SAAS,EAAC,4EAA4E,YAErF,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAClB,iBAAgB,KAAK,EAAE,CAAC,YACrB,CAAC,IADS,CAAC,CAEL,CACV,CAAC,GACK,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export * from './telescope-context.js';
|
|
2
|
+
export * from './use-telescope-queries.js';
|
|
3
|
+
export * from './components/entry-types.js';
|
|
4
|
+
export * from './components/type-tabs.js';
|
|
5
|
+
export * from './components/entries-table.js';
|
|
6
|
+
export * from './components/batch-timeline.js';
|
|
7
|
+
export * from './components/entry-detail.js';
|
|
8
|
+
export * from './components/export-json.js';
|
|
9
|
+
export * from './components/export-json-toolbar.js';
|
|
10
|
+
export * from './components/retention-indicator.js';
|
|
11
|
+
export * from './components/cache-badge.js';
|
|
12
|
+
export * from './components/entry-insights.js';
|
|
13
|
+
export * from './components/window-select.js';
|
|
14
|
+
export * from './components/tag-autocomplete.js';
|
|
15
|
+
export * from './components/pulse-panel.js';
|
|
16
|
+
export * from './components/queues-panel.js';
|
|
17
|
+
export * from './components/sparkline.js';
|
|
18
|
+
export * from './components/stacked-bars.js';
|
|
19
|
+
export * from './components/queue-sparkline.js';
|
|
20
|
+
export * from './components/queues/index.js';
|
|
21
|
+
export * from './components/charts/index.js';
|
|
22
|
+
export * from '../client/index.js';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|