@mastra/playground-ui 53.0.0-alpha.9 → 53.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/dist/{code-DRGJVroV.js → code-D4Vw_fYq.js} +22 -16
- package/dist/code-D4Vw_fYq.js.map +1 -0
- package/dist/{code-BJMC6T9D.cjs → code-DhrdtZce.cjs} +22 -15
- package/dist/code-DhrdtZce.cjs.map +1 -0
- package/dist/{code-block-CBJhDEeB.js → code-block-DeksY23p.js} +2 -2
- package/dist/{code-block-CBJhDEeB.js.map → code-block-DeksY23p.js.map} +1 -1
- package/dist/{code-block-fmv8bHoT.cjs → code-block-DgHrBuR8.cjs} +2 -2
- package/dist/{code-block-fmv8bHoT.cjs.map → code-block-DgHrBuR8.cjs.map} +1 -1
- package/dist/{command-DWFd0d4c.js → command-Be-KrIAX.js} +2 -2
- package/dist/{command-DWFd0d4c.js.map → command-Be-KrIAX.js.map} +1 -1
- package/dist/{command-CUev1UxH.cjs → command-DsTBCmQq.cjs} +2 -2
- package/dist/{command-CUev1UxH.cjs.map → command-DsTBCmQq.cjs.map} +1 -1
- package/dist/components/ChatShell.cjs.js +20 -1
- package/dist/components/ChatShell.cjs.js.map +1 -1
- package/dist/components/ChatShell.es.js +20 -1
- package/dist/components/ChatShell.es.js.map +1 -1
- package/dist/components/Code.cjs.js +3 -1
- package/dist/components/Code.cjs.js.map +1 -1
- package/dist/components/Code.es.js +1 -1
- package/dist/components/CodeBlock.cjs.js +1 -1
- package/dist/components/CodeBlock.es.js +1 -1
- package/dist/components/CodeEditor.cjs.js +2 -1
- package/dist/components/CodeEditor.cjs.js.map +1 -1
- package/dist/components/CodeEditor.es.js +1 -1
- package/dist/components/Command.cjs.js +1 -1
- package/dist/components/Command.es.js +1 -1
- package/dist/components/CommandPalette.cjs.js +1 -1
- package/dist/components/CommandPalette.es.js +1 -1
- package/dist/components/DataCodeSection.cjs.js +1 -1
- package/dist/components/DataCodeSection.es.js +1 -1
- package/dist/components/DataPanel.cjs.js +1 -1
- package/dist/components/DataPanel.es.js +1 -1
- package/dist/components/Dialog.cjs.js +181 -2
- package/dist/components/Dialog.cjs.js.map +1 -1
- package/dist/components/Dialog.es.js +183 -1
- package/dist/components/Dialog.es.js.map +1 -1
- package/dist/components/HorizontalBars.cjs.js +1 -1
- package/dist/components/HorizontalBars.es.js +1 -1
- package/dist/components/IntegrationDialog.cjs.js +105 -0
- package/dist/components/IntegrationDialog.cjs.js.map +1 -0
- package/dist/components/IntegrationDialog.d.ts +2 -0
- package/dist/components/IntegrationDialog.es.js +101 -0
- package/dist/components/IntegrationDialog.es.js.map +1 -0
- package/dist/components/MarkdownRenderer.cjs.js +1 -1
- package/dist/components/MarkdownRenderer.es.js +1 -1
- package/dist/components/ThreadRail.cjs.js +19 -0
- package/dist/components/ThreadRail.cjs.js.map +1 -1
- package/dist/components/ThreadRail.es.js +19 -1
- package/dist/components/ThreadRail.es.js.map +1 -1
- package/dist/components/ai/plan.cjs.js +1 -1
- package/dist/components/ai/plan.es.js +1 -1
- package/dist/components/ai/tool-call.cjs.js +165 -0
- package/dist/components/ai/tool-call.cjs.js.map +1 -1
- package/dist/components/ai/tool-call.es.js +159 -3
- package/dist/components/ai/tool-call.es.js.map +1 -1
- package/dist/{data-code-section-D5I0m1cS.cjs → data-code-section-B_lg_J_0.cjs} +2 -2
- package/dist/{data-code-section-D5I0m1cS.cjs.map → data-code-section-B_lg_J_0.cjs.map} +1 -1
- package/dist/{data-code-section-d3NffL3V.js → data-code-section-Cm_W_XhO.js} +2 -2
- package/dist/{data-code-section-d3NffL3V.js.map → data-code-section-Cm_W_XhO.js.map} +1 -1
- package/dist/{data-panel-Bo2HCylZ.cjs → data-panel-Cv9j_IGQ.cjs} +2 -2
- package/dist/{data-panel-Bo2HCylZ.cjs.map → data-panel-Cv9j_IGQ.cjs.map} +1 -1
- package/dist/{data-panel-T3vp7wTD.js → data-panel-DXxeSnL1.js} +2 -2
- package/dist/{data-panel-T3vp7wTD.js.map → data-panel-DXxeSnL1.js.map} +1 -1
- package/dist/dialog-CZMPDVUj.js +259 -0
- package/dist/dialog-CZMPDVUj.js.map +1 -0
- package/dist/dialog-D-7Hkb3j.cjs +293 -0
- package/dist/dialog-D-7Hkb3j.cjs.map +1 -0
- package/dist/domains/metrics/components/token-usage-by-agent-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/token-usage-by-agent-card-view.es.js +1 -1
- package/dist/domains/metrics/components/traces-volume-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/traces-volume-card-view.es.js +1 -1
- package/dist/domains/traces/components/span-data-panel-view.cjs.js +1 -1
- package/dist/domains/traces/components/span-data-panel-view.es.js +1 -1
- package/dist/domains/traces/components/trace-columns-menu.cjs.js +1 -1
- package/dist/domains/traces/components/trace-columns-menu.es.js +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.es.js +1 -1
- package/dist/domains/traces/hooks/use-branch.cjs.js +2 -6
- package/dist/domains/traces/hooks/use-branch.cjs.js.map +1 -1
- package/dist/domains/traces/hooks/use-branch.es.js +2 -6
- package/dist/domains/traces/hooks/use-branch.es.js.map +1 -1
- package/dist/domains/traces/hooks/use-download-trace-json.cjs.js +4 -1
- package/dist/domains/traces/hooks/use-download-trace-json.cjs.js.map +1 -1
- package/dist/domains/traces/hooks/use-download-trace-json.es.js +4 -1
- package/dist/domains/traces/hooks/use-download-trace-json.es.js.map +1 -1
- package/dist/domains/traces/hooks/use-trace-spans.cjs.js +10 -7
- package/dist/domains/traces/hooks/use-trace-spans.cjs.js.map +1 -1
- package/dist/domains/traces/hooks/use-trace-spans.es.js +10 -7
- package/dist/domains/traces/hooks/use-trace-spans.es.js.map +1 -1
- package/dist/ee/signals/settings/signal-definition-form-dialog.cjs.js +1 -1
- package/dist/ee/signals/settings/signal-definition-form-dialog.es.js +1 -1
- package/dist/{highlight-CSJjjoqh.js → highlight-BmpoELR4.js} +6 -2
- package/dist/{highlight-CSJjjoqh.js.map → highlight-BmpoELR4.js.map} +1 -1
- package/dist/{highlight-CEt2vhD8.cjs → highlight-DK1dn-Fh.cjs} +6 -1
- package/dist/{highlight-CEt2vhD8.cjs.map → highlight-DK1dn-Fh.cjs.map} +1 -1
- package/dist/{horizontal-bars-DZ5J4TKv.js → horizontal-bars-CyP-B-BX.js} +37 -4
- package/dist/horizontal-bars-CyP-B-BX.js.map +1 -0
- package/dist/{horizontal-bars-CE1O-Y6G.cjs → horizontal-bars-Dgq3PYsg.cjs} +37 -4
- package/dist/horizontal-bars-Dgq3PYsg.cjs.map +1 -0
- package/dist/{markdown-renderer-DiJBbnYG.js → markdown-renderer-CaFpZTFS.js} +2 -2
- package/dist/{markdown-renderer-DiJBbnYG.js.map → markdown-renderer-CaFpZTFS.js.map} +1 -1
- package/dist/{markdown-renderer-DGIzNAQY.cjs → markdown-renderer-GVtZLunG.cjs} +2 -2
- package/dist/{markdown-renderer-DGIzNAQY.cjs.map → markdown-renderer-GVtZLunG.cjs.map} +1 -1
- package/dist/src/domains/traces/hooks/use-trace-spans.d.ts +3 -1
- package/dist/src/ds/components/ChatShell/chat-shell.d.ts +19 -2
- package/dist/src/ds/components/ChatShell/index.d.ts +3 -2
- package/dist/src/ds/components/Code/index.d.ts +1 -0
- package/dist/src/ds/components/Code/use-highlight.d.ts +10 -0
- package/dist/src/ds/components/CodeEditor/highlight.d.ts +1 -0
- package/dist/src/ds/components/CodeEditor/index.d.ts +1 -1
- package/dist/src/ds/components/Dialog/dialog-action.d.ts +9 -0
- package/dist/src/ds/components/Dialog/dialog-context.d.ts +16 -0
- package/dist/src/ds/components/Dialog/dialog-new-variant.stories.d.ts +64 -0
- package/dist/src/ds/components/Dialog/dialog.d.ts +15 -6
- package/dist/src/ds/components/Dialog/index.d.ts +2 -0
- package/dist/src/ds/components/HorizontalBars/horizontal-bars.stories.d.ts +2 -0
- package/dist/src/ds/components/IntegrationDialog/__fixtures__/integrations-catalog.d.ts +2 -0
- package/dist/src/ds/components/IntegrationDialog/index.d.ts +2 -0
- package/dist/src/ds/components/IntegrationDialog/integration-dialog.d.ts +28 -0
- package/dist/src/ds/components/IntegrationDialog/integration-dialog.stories.d.ts +24 -0
- package/dist/src/ds/components/ThreadRail/index.d.ts +1 -0
- package/dist/src/ds/components/ThreadRail/turn-groups.d.ts +19 -0
- package/dist/src/ds/components/ai/tool-call/ansi.d.ts +2 -0
- package/dist/src/ds/components/ai/tool-call/group-consecutive.d.ts +17 -0
- package/dist/src/ds/components/ai/tool-call/index.d.ts +4 -0
- package/dist/src/ds/components/ai/tool-call/tool-call-edit.d.ts +4 -0
- package/dist/src/ds/components/ai/tool-call/tool-call-group.d.ts +14 -0
- package/dist/src/ds/components/ai/tool-call/tool-call.d.ts +4 -0
- package/dist/src/ds/components/ai/tool-call/tool-presentation.d.ts +10 -0
- package/dist/style.css +138 -0
- package/package.json +8 -8
- package/dist/code-BJMC6T9D.cjs.map +0 -1
- package/dist/code-DRGJVroV.js.map +0 -1
- package/dist/dialog-CESxLg8S.js +0 -76
- package/dist/dialog-CESxLg8S.js.map +0 -1
- package/dist/dialog-K0q0KOOW.cjs +0 -107
- package/dist/dialog-K0q0KOOW.cjs.map +0 -1
- package/dist/horizontal-bars-CE1O-Y6G.cjs.map +0 -1
- package/dist/horizontal-bars-DZ5J4TKv.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { H as HorizontalBars } from '../../../horizontal-bars-
|
|
3
|
+
import { H as HorizontalBars } from '../../../horizontal-bars-CyP-B-BX.js';
|
|
4
4
|
import { M as MetricsCard } from '../../../metrics-card-BKE1UzWh.js';
|
|
5
5
|
import { T as TabContent } from '../../../tabs-content-CLgmU6S_.js';
|
|
6
6
|
import { a as Tabs, T as TabList } from '../../../tabs-root-BnwVjJbD.js';
|
|
@@ -9,7 +9,7 @@ const domains_traces_components_spanSummaryDescription = require('./span-summary
|
|
|
9
9
|
const domains_traces_components_spanTokenUsage = require('./span-token-usage.cjs.js');
|
|
10
10
|
const buttonsGroup = require('../../../buttons-group-Cn36DWYX.cjs');
|
|
11
11
|
const dataKeysAndValues = require('../../../data-keys-and-values-D1M0xPEy.cjs');
|
|
12
|
-
const dataPanel = require('../../../data-panel-
|
|
12
|
+
const dataPanel = require('../../../data-panel-Cv9j_IGQ.cjs');
|
|
13
13
|
const Notice = require('../../../Notice-D_ji361h.cjs');
|
|
14
14
|
const tabsRoot = require('../../../tabs-root-BNcLC-s6.cjs');
|
|
15
15
|
const tabsTab = require('../../../tabs-tab-Ha0C9Dv3.cjs');
|
|
@@ -5,7 +5,7 @@ import { SpanSummaryDescription } from './span-summary-description.es.js';
|
|
|
5
5
|
import { SpanTokenUsage } from './span-token-usage.es.js';
|
|
6
6
|
import { B as ButtonsGroup } from '../../../buttons-group-BjM12HPx.js';
|
|
7
7
|
import { D as DataKeysAndValues } from '../../../data-keys-and-values-PKPzfxve.js';
|
|
8
|
-
import { D as DataPanel } from '../../../data-panel-
|
|
8
|
+
import { D as DataPanel } from '../../../data-panel-DXxeSnL1.js';
|
|
9
9
|
import { N as Notice } from '../../../Notice-DSUAUUYU.js';
|
|
10
10
|
import { a as Tabs, T as TabList } from '../../../tabs-root-BnwVjJbD.js';
|
|
11
11
|
import { T as Tab } from '../../../tabs-tab-Qlfs2X2g.js';
|
|
@@ -7,7 +7,7 @@ const lucideReact = require('lucide-react');
|
|
|
7
7
|
const React = require('react');
|
|
8
8
|
const domains_traces_traceListColumns = require('../trace-list-columns.cjs.js');
|
|
9
9
|
const Button = require('../../../Button-D10WB4vc.cjs');
|
|
10
|
-
const dialog = require('../../../dialog-
|
|
10
|
+
const dialog = require('../../../dialog-D-7Hkb3j.cjs');
|
|
11
11
|
const dropdownMenu = require('../../../dropdown-menu-qsDhHNES.cjs');
|
|
12
12
|
const input = require('../../../input-DBrWBeUp.cjs');
|
|
13
13
|
const label = require('../../../label-B9ERiuZb.cjs');
|
|
@@ -3,7 +3,7 @@ import { Columns3Icon, PlusIcon } from 'lucide-react';
|
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import { TRACE_USAGE_COLUMNS } from '../trace-list-columns.es.js';
|
|
5
5
|
import { B as Button } from '../../../Button-BsfLQEC6.js';
|
|
6
|
-
import { D as Dialog,
|
|
6
|
+
import { D as Dialog, a as DialogContent, b as DialogHeader, c as DialogTitle, d as DialogDescription, e as DialogBody, f as DialogFooter } from '../../../dialog-CZMPDVUj.js';
|
|
7
7
|
import { D as DropdownMenu } from '../../../dropdown-menu-BYTyEuSa.js';
|
|
8
8
|
import { I as Input } from '../../../input-DNjusDwY.js';
|
|
9
9
|
import { L as Label } from '../../../label-Um4lWyRe.js';
|
|
@@ -13,7 +13,7 @@ const domains_traces_components_traceSummaryDescription = require('./trace-summa
|
|
|
13
13
|
const domains_traces_components_traceTimeline = require('./trace-timeline.cjs.js');
|
|
14
14
|
const Button = require('../../../Button-D10WB4vc.cjs');
|
|
15
15
|
const buttonsGroup = require('../../../buttons-group-Cn36DWYX.cjs');
|
|
16
|
-
const dataPanel = require('../../../data-panel-
|
|
16
|
+
const dataPanel = require('../../../data-panel-Cv9j_IGQ.cjs');
|
|
17
17
|
const dropdownMenu = require('../../../dropdown-menu-qsDhHNES.cjs');
|
|
18
18
|
const searchFieldBlock = require('../../../search-field-block-CiinIsub.cjs');
|
|
19
19
|
const Notice = require('../../../Notice-D_ji361h.cjs');
|
|
@@ -9,7 +9,7 @@ import { TraceSummaryDescription } from './trace-summary-description.es.js';
|
|
|
9
9
|
import { TraceTimeline } from './trace-timeline.es.js';
|
|
10
10
|
import { B as Button } from '../../../Button-BsfLQEC6.js';
|
|
11
11
|
import { B as ButtonsGroup } from '../../../buttons-group-BjM12HPx.js';
|
|
12
|
-
import { D as DataPanel } from '../../../data-panel-
|
|
12
|
+
import { D as DataPanel } from '../../../data-panel-DXxeSnL1.js';
|
|
13
13
|
import { D as DropdownMenu } from '../../../dropdown-menu-BYTyEuSa.js';
|
|
14
14
|
import { S as SearchFieldBlock } from '../../../search-field-block-D51aN1d9.js';
|
|
15
15
|
import { N as Notice } from '../../../Notice-DSUAUUYU.js';
|
|
@@ -7,7 +7,6 @@ const reactQuery = require('@tanstack/react-query');
|
|
|
7
7
|
const domains_traces_utils_toSearchableSpans = require('../utils/to-searchable-spans.cjs.js');
|
|
8
8
|
require('date-fns');
|
|
9
9
|
|
|
10
|
-
const IMMUTABLE_CACHE_TIME = 1e3 * 60 * 60 * 24 * 30;
|
|
11
10
|
function useBranch({
|
|
12
11
|
traceId,
|
|
13
12
|
spanId,
|
|
@@ -25,11 +24,8 @@ function useBranch({
|
|
|
25
24
|
// Builds each span's search haystack once per fetch, cached with the query.
|
|
26
25
|
select: domains_traces_utils_toSearchableSpans.selectSearchableSpans,
|
|
27
26
|
enabled: !!traceId && !!spanId,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const isFinished = data?.spans.every((s) => Boolean(s.endedAt));
|
|
31
|
-
return isFinished ? IMMUTABLE_CACHE_TIME : 0;
|
|
32
|
-
}
|
|
27
|
+
// A finished subtree can still gain spans from a resumed run or delayed export.
|
|
28
|
+
staleTime: 0
|
|
33
29
|
});
|
|
34
30
|
}
|
|
35
31
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-branch.cjs.js","sources":["../../../../src/domains/traces/hooks/use-branch.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\
|
|
1
|
+
{"version":3,"file":"use-branch.cjs.js","sources":["../../../../src/domains/traces/hooks/use-branch.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\nexport interface UseBranchArgs {\n traceId: string | null | undefined;\n spanId: string | null | undefined;\n depth?: number;\n}\n\nexport function useBranch({\n traceId,\n spanId,\n depth,\n}: UseBranchArgs): UseQueryResult<{ traceId: string; spans: SearchableSpan[] } | null> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['branch', traceId, spanId, depth],\n queryFn: async () => {\n if (!traceId || !spanId) {\n throw new Error('traceId and spanId are required');\n }\n return client.getBranch({ traceId, spanId, depth });\n },\n // Builds each span's search haystack once per fetch, cached with the query.\n select: selectSearchableSpans,\n enabled: !!traceId && !!spanId,\n // A finished subtree can still gain spans from a resumed run or delayed export.\n staleTime: 0,\n });\n}\n"],"names":["useMastraClient","useQuery","selectSearchableSpans"],"mappings":";;;;;;;;;AAYO,SAAS,SAAA,CAAU;AAAA,EACxB,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAuF;AACrF,EAAA,MAAM,SAASA,qBAAA,EAAgB;AAE/B,EAAA,OAAOC,mBAAA,CAAS;AAAA,IACd,QAAA,EAAU,CAAC,QAAA,EAAU,OAAA,EAAS,QAAQ,KAAK,CAAA;AAAA,IAC3C,SAAS,YAAY;AACnB,MAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,EAAQ;AACvB,QAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,MACnD;AACA,MAAA,OAAO,OAAO,SAAA,CAAU,EAAE,OAAA,EAAS,MAAA,EAAQ,OAAO,CAAA;AAAA,IACpD,CAAA;AAAA;AAAA,IAEA,MAAA,EAAQC,4DAAA;AAAA,IACR,OAAA,EAAS,CAAC,CAAC,OAAA,IAAW,CAAC,CAAC,MAAA;AAAA;AAAA,IAExB,SAAA,EAAW;AAAA,GACZ,CAAA;AACH;;;;"}
|
|
@@ -3,7 +3,6 @@ import { useQuery } from '@tanstack/react-query';
|
|
|
3
3
|
import { selectSearchableSpans } from '../utils/to-searchable-spans.es.js';
|
|
4
4
|
import 'date-fns';
|
|
5
5
|
|
|
6
|
-
const IMMUTABLE_CACHE_TIME = 1e3 * 60 * 60 * 24 * 30;
|
|
7
6
|
function useBranch({
|
|
8
7
|
traceId,
|
|
9
8
|
spanId,
|
|
@@ -21,11 +20,8 @@ function useBranch({
|
|
|
21
20
|
// Builds each span's search haystack once per fetch, cached with the query.
|
|
22
21
|
select: selectSearchableSpans,
|
|
23
22
|
enabled: !!traceId && !!spanId,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const isFinished = data?.spans.every((s) => Boolean(s.endedAt));
|
|
27
|
-
return isFinished ? IMMUTABLE_CACHE_TIME : 0;
|
|
28
|
-
}
|
|
23
|
+
// A finished subtree can still gain spans from a resumed run or delayed export.
|
|
24
|
+
staleTime: 0
|
|
29
25
|
});
|
|
30
26
|
}
|
|
31
27
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-branch.es.js","sources":["../../../../src/domains/traces/hooks/use-branch.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\
|
|
1
|
+
{"version":3,"file":"use-branch.es.js","sources":["../../../../src/domains/traces/hooks/use-branch.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\nexport interface UseBranchArgs {\n traceId: string | null | undefined;\n spanId: string | null | undefined;\n depth?: number;\n}\n\nexport function useBranch({\n traceId,\n spanId,\n depth,\n}: UseBranchArgs): UseQueryResult<{ traceId: string; spans: SearchableSpan[] } | null> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['branch', traceId, spanId, depth],\n queryFn: async () => {\n if (!traceId || !spanId) {\n throw new Error('traceId and spanId are required');\n }\n return client.getBranch({ traceId, spanId, depth });\n },\n // Builds each span's search haystack once per fetch, cached with the query.\n select: selectSearchableSpans,\n enabled: !!traceId && !!spanId,\n // A finished subtree can still gain spans from a resumed run or delayed export.\n staleTime: 0,\n });\n}\n"],"names":[],"mappings":";;;;;AAYO,SAAS,SAAA,CAAU;AAAA,EACxB,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAuF;AACrF,EAAA,MAAM,SAAS,eAAA,EAAgB;AAE/B,EAAA,OAAO,QAAA,CAAS;AAAA,IACd,QAAA,EAAU,CAAC,QAAA,EAAU,OAAA,EAAS,QAAQ,KAAK,CAAA;AAAA,IAC3C,SAAS,YAAY;AACnB,MAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,EAAQ;AACvB,QAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,MACnD;AACA,MAAA,OAAO,OAAO,SAAA,CAAU,EAAE,OAAA,EAAS,MAAA,EAAQ,OAAO,CAAA;AAAA,IACpD,CAAA;AAAA;AAAA,IAEA,MAAA,EAAQ,qBAAA;AAAA,IACR,OAAA,EAAS,CAAC,CAAC,OAAA,IAAW,CAAC,CAAC,MAAA;AAAA;AAAA,IAExB,SAAA,EAAW;AAAA,GACZ,CAAA;AACH;;;;"}
|
|
@@ -3,17 +3,20 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
const react = require('@mastra/react');
|
|
6
|
+
const reactQuery = require('@tanstack/react-query');
|
|
6
7
|
const React = require('react');
|
|
8
|
+
const domains_traces_hooks_useTraceSpans = require('./use-trace-spans.cjs.js');
|
|
7
9
|
const toast = require('../../../toast-EtbZnj9b.cjs');
|
|
8
10
|
const downloadJson = require('../../../downloadJson-PWUDbzkB.cjs');
|
|
9
11
|
|
|
10
12
|
function useDownloadTraceJson() {
|
|
11
13
|
const client = react.useMastraClient();
|
|
14
|
+
const queryClient = reactQuery.useQueryClient();
|
|
12
15
|
const [isPending, setIsPending] = React.useState(false);
|
|
13
16
|
const download = (traceId) => {
|
|
14
17
|
if (isPending) return;
|
|
15
18
|
setIsPending(true);
|
|
16
|
-
const task =
|
|
19
|
+
const task = queryClient.fetchQuery(domains_traces_hooks_useTraceSpans.traceSpansQueryOptions(client, traceId)).then((trace) => downloadJson.downloadJson(`trace-${traceId}.json`, trace)).finally(() => setIsPending(false));
|
|
17
20
|
toast.toast.promise({
|
|
18
21
|
myPromise: task,
|
|
19
22
|
loadingMessage: "Preparing trace download…",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-download-trace-json.cjs.js","sources":["../../../../src/domains/traces/hooks/use-download-trace-json.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useState } from 'react';\nimport { downloadJson } from '@/lib/file';\nimport { toast } from '@/lib/toast';\n\nexport function useDownloadTraceJson() {\n const client = useMastraClient();\n const [isPending, setIsPending] = useState(false);\n\n const download = (traceId: string) => {\n if (isPending) return;\n setIsPending(true);\n\n //
|
|
1
|
+
{"version":3,"file":"use-download-trace-json.cjs.js","sources":["../../../../src/domains/traces/hooks/use-download-trace-json.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { traceSpansQueryOptions } from './use-trace-spans';\nimport { downloadJson } from '@/lib/file';\nimport { toast } from '@/lib/toast';\n\nexport function useDownloadTraceJson() {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n const [isPending, setIsPending] = useState(false);\n\n const download = (traceId: string) => {\n if (isPending) return;\n setIsPending(true);\n\n // Fetch the full payload into the shared cache so the panel matches the downloaded trace.\n const task = queryClient\n .fetchQuery(traceSpansQueryOptions(client, traceId))\n .then(trace => downloadJson(`trace-${traceId}.json`, trace))\n .finally(() => setIsPending(false));\n\n toast.promise({\n myPromise: task,\n loadingMessage: 'Preparing trace download…',\n successMessage: 'Trace downloaded',\n errorMessage: 'Failed to download trace',\n });\n };\n\n return { download, isPending };\n}\n"],"names":["useMastraClient","useQueryClient","useState","traceSpansQueryOptions","downloadJson","toast"],"mappings":";;;;;;;;;;;AAOO,SAAS,oBAAA,GAAuB;AACrC,EAAA,MAAM,SAASA,qBAAA,EAAgB;AAC/B,EAAA,MAAM,cAAcC,yBAAA,EAAe;AACnC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIC,eAAS,KAAK,CAAA;AAEhD,EAAA,MAAM,QAAA,GAAW,CAAC,OAAA,KAAoB;AACpC,IAAA,IAAI,SAAA,EAAW;AACf,IAAA,YAAA,CAAa,IAAI,CAAA;AAGjB,IAAA,MAAM,IAAA,GAAO,YACV,UAAA,CAAWC,yDAAA,CAAuB,QAAQ,OAAO,CAAC,EAClD,IAAA,CAAK,CAAA,KAAA,KAASC,0BAAa,CAAA,MAAA,EAAS,OAAO,SAAS,KAAK,CAAC,EAC1D,OAAA,CAAQ,MAAM,YAAA,CAAa,KAAK,CAAC,CAAA;AAEpC,IAAAC,WAAA,CAAM,OAAA,CAAQ;AAAA,MACZ,SAAA,EAAW,IAAA;AAAA,MACX,cAAA,EAAgB,2BAAA;AAAA,MAChB,cAAA,EAAgB,kBAAA;AAAA,MAChB,YAAA,EAAc;AAAA,KACf,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAO,EAAE,UAAU,SAAA,EAAU;AAC/B;;;;"}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { useMastraClient } from '@mastra/react';
|
|
2
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
2
3
|
import { useState } from 'react';
|
|
4
|
+
import { traceSpansQueryOptions } from './use-trace-spans.es.js';
|
|
3
5
|
import { t as toast } from '../../../toast-czUGO0aH.js';
|
|
4
6
|
import { d as downloadJson } from '../../../downloadJson-DuPoMa_6.js';
|
|
5
7
|
|
|
6
8
|
function useDownloadTraceJson() {
|
|
7
9
|
const client = useMastraClient();
|
|
10
|
+
const queryClient = useQueryClient();
|
|
8
11
|
const [isPending, setIsPending] = useState(false);
|
|
9
12
|
const download = (traceId) => {
|
|
10
13
|
if (isPending) return;
|
|
11
14
|
setIsPending(true);
|
|
12
|
-
const task =
|
|
15
|
+
const task = queryClient.fetchQuery(traceSpansQueryOptions(client, traceId)).then((trace) => downloadJson(`trace-${traceId}.json`, trace)).finally(() => setIsPending(false));
|
|
13
16
|
toast.promise({
|
|
14
17
|
myPromise: task,
|
|
15
18
|
loadingMessage: "Preparing trace download…",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-download-trace-json.es.js","sources":["../../../../src/domains/traces/hooks/use-download-trace-json.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useState } from 'react';\nimport { downloadJson } from '@/lib/file';\nimport { toast } from '@/lib/toast';\n\nexport function useDownloadTraceJson() {\n const client = useMastraClient();\n const [isPending, setIsPending] = useState(false);\n\n const download = (traceId: string) => {\n if (isPending) return;\n setIsPending(true);\n\n //
|
|
1
|
+
{"version":3,"file":"use-download-trace-json.es.js","sources":["../../../../src/domains/traces/hooks/use-download-trace-json.ts"],"sourcesContent":["import { useMastraClient } from '@mastra/react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { traceSpansQueryOptions } from './use-trace-spans';\nimport { downloadJson } from '@/lib/file';\nimport { toast } from '@/lib/toast';\n\nexport function useDownloadTraceJson() {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n const [isPending, setIsPending] = useState(false);\n\n const download = (traceId: string) => {\n if (isPending) return;\n setIsPending(true);\n\n // Fetch the full payload into the shared cache so the panel matches the downloaded trace.\n const task = queryClient\n .fetchQuery(traceSpansQueryOptions(client, traceId))\n .then(trace => downloadJson(`trace-${traceId}.json`, trace))\n .finally(() => setIsPending(false));\n\n toast.promise({\n myPromise: task,\n loadingMessage: 'Preparing trace download…',\n successMessage: 'Trace downloaded',\n errorMessage: 'Failed to download trace',\n });\n };\n\n return { download, isPending };\n}\n"],"names":[],"mappings":";;;;;;;AAOO,SAAS,oBAAA,GAAuB;AACrC,EAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,EAAA,MAAM,cAAc,cAAA,EAAe;AACnC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAEhD,EAAA,MAAM,QAAA,GAAW,CAAC,OAAA,KAAoB;AACpC,IAAA,IAAI,SAAA,EAAW;AACf,IAAA,YAAA,CAAa,IAAI,CAAA;AAGjB,IAAA,MAAM,IAAA,GAAO,YACV,UAAA,CAAW,sBAAA,CAAuB,QAAQ,OAAO,CAAC,EAClD,IAAA,CAAK,CAAA,KAAA,KAAS,aAAa,CAAA,MAAA,EAAS,OAAO,SAAS,KAAK,CAAC,EAC1D,OAAA,CAAQ,MAAM,YAAA,CAAa,KAAK,CAAC,CAAA;AAEpC,IAAA,KAAA,CAAM,OAAA,CAAQ;AAAA,MACZ,SAAA,EAAW,IAAA;AAAA,MACX,cAAA,EAAgB,2BAAA;AAAA,MAChB,cAAA,EAAgB,kBAAA;AAAA,MAChB,YAAA,EAAc;AAAA,KACf,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAO,EAAE,UAAU,SAAA,EAAU;AAC/B;;;;"}
|
|
@@ -7,7 +7,6 @@ const reactQuery = require('@tanstack/react-query');
|
|
|
7
7
|
const domains_traces_utils_toSearchableSpans = require('../utils/to-searchable-spans.cjs.js');
|
|
8
8
|
require('date-fns');
|
|
9
9
|
|
|
10
|
-
const IMMUTABLE_CACHE_TIME = 1e3 * 60 * 60 * 24 * 30;
|
|
11
10
|
const traceSpansQueryOptions = (client, traceId) => reactQuery.queryOptions({
|
|
12
11
|
queryKey: ["trace-spans", traceId],
|
|
13
12
|
queryFn: async () => {
|
|
@@ -18,16 +17,17 @@ const traceSpansQueryOptions = (client, traceId) => reactQuery.queryOptions({
|
|
|
18
17
|
return res;
|
|
19
18
|
},
|
|
20
19
|
enabled: !!traceId,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const isFinished = data?.spans.every((span) => Boolean(span.endedAt));
|
|
24
|
-
return isFinished ? IMMUTABLE_CACHE_TIME : 0;
|
|
25
|
-
}
|
|
20
|
+
// Resumed runs and delayed exports can append spans even when every known span has ended.
|
|
21
|
+
staleTime: 0
|
|
26
22
|
});
|
|
27
|
-
function useTraceSpans(traceId) {
|
|
23
|
+
function useTraceSpans(traceId, { passive = false } = {}) {
|
|
28
24
|
const client = react.useMastraClient();
|
|
29
25
|
return reactQuery.useQuery({
|
|
30
26
|
...traceSpansQueryOptions(client, traceId),
|
|
27
|
+
// History rows share updates but leave automatic refreshes to the selected detail.
|
|
28
|
+
refetchOnMount: !passive,
|
|
29
|
+
refetchOnWindowFocus: !passive,
|
|
30
|
+
refetchOnReconnect: !passive,
|
|
31
31
|
// Builds each span's search haystack once per fetch, cached with the query.
|
|
32
32
|
select: domains_traces_utils_toSearchableSpans.selectSearchableSpans
|
|
33
33
|
});
|
|
@@ -37,6 +37,9 @@ function useTraceSpansQueries(traceIds, select, fallback) {
|
|
|
37
37
|
return reactQuery.useQueries({
|
|
38
38
|
queries: traceIds.map((traceId) => ({
|
|
39
39
|
...traceSpansQueryOptions(client, traceId),
|
|
40
|
+
refetchOnMount: false,
|
|
41
|
+
refetchOnWindowFocus: false,
|
|
42
|
+
refetchOnReconnect: false,
|
|
40
43
|
select: (data) => select(traceId, data)
|
|
41
44
|
})),
|
|
42
45
|
combine: (results) => results.map(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-trace-spans.cjs.js","sources":["../../../../src/domains/traces/hooks/use-trace-spans.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useMastraClient } from '@mastra/react';\nimport { queryOptions, useQueries, useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\
|
|
1
|
+
{"version":3,"file":"use-trace-spans.cjs.js","sources":["../../../../src/domains/traces/hooks/use-trace-spans.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useMastraClient } from '@mastra/react';\nimport { queryOptions, useQueries, useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\n/**\n * Key, fetcher and stale policy of the `trace-spans` query. Every observer of this key must\n * share these (rather than only the key) so one observer with a stricter `staleTime` does not\n * refetch data another one considers fresh.\n */\nexport const traceSpansQueryOptions = (client: MastraClient, traceId: string | null | undefined) =>\n queryOptions({\n queryKey: ['trace-spans', traceId],\n queryFn: async () => {\n if (!traceId) {\n throw new Error('Trace ID is required');\n }\n const res = await client.getTrace(traceId);\n return res;\n },\n enabled: !!traceId,\n // Resumed runs and delayed exports can append spans even when every known span has ended.\n staleTime: 0,\n });\n\n/**\n * Every span of a single trace, with its full payload.\n *\n * The lightweight projection exists to keep blob columns off the read path of a\n * *list*, where the cost is paid once per trace on screen. A trace that is open\n * has already narrowed that to one, and the panel both renders and searches\n * these spans -- `input`, `output` and `attributes` included -- so the\n * projection would only hide content the reader is looking at.\n */\nexport function useTraceSpans(\n traceId: string | null | undefined,\n { passive = false }: { passive?: boolean } = {},\n): UseQueryResult<{ traceId: string; spans: SearchableSpan[] } | null> {\n const client = useMastraClient();\n\n return useQuery({\n ...traceSpansQueryOptions(client, traceId),\n // History rows share updates but leave automatic refreshes to the selected detail.\n refetchOnMount: !passive,\n refetchOnWindowFocus: !passive,\n refetchOnReconnect: !passive,\n // Builds each span's search haystack once per fetch, cached with the query.\n select: selectSearchableSpans,\n });\n}\n\nexport type TraceSpansData = Awaited<ReturnType<MastraClient['getTrace']>>;\n\n/**\n * Observes the `trace-spans` query of several traces at once and projects each one with `select`.\n * Traces still loading (or failed) yield `fallback(traceId)` so the result always lines up with `traceIds`.\n */\nexport function useTraceSpansQueries<T>(\n traceIds: string[],\n select: (traceId: string, data: TraceSpansData) => T,\n fallback: (traceId: string) => T,\n): T[] {\n const client = useMastraClient();\n\n return useQueries({\n queries: traceIds.map(traceId => ({\n ...traceSpansQueryOptions(client, traceId),\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n select: (data: TraceSpansData) => select(traceId, data),\n })),\n combine: results =>\n results.map((result, index) =>\n result.data === undefined ? fallback(traceIds[index] ?? '') : (result.data as T),\n ),\n });\n}\n"],"names":["queryOptions","useMastraClient","useQuery","selectSearchableSpans","useQueries"],"mappings":";;;;;;;;;AAYO,MAAM,sBAAA,GAAyB,CAAC,MAAA,EAAsB,OAAA,KAC3DA,uBAAA,CAAa;AAAA,EACX,QAAA,EAAU,CAAC,aAAA,EAAe,OAAO,CAAA;AAAA,EACjC,SAAS,YAAY;AACnB,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,MAAM,sBAAsB,CAAA;AAAA,IACxC;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA;AACzC,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AAAA,EACA,OAAA,EAAS,CAAC,CAAC,OAAA;AAAA;AAAA,EAEX,SAAA,EAAW;AACb,CAAC;AAWI,SAAS,cACd,OAAA,EACA,EAAE,UAAU,KAAA,EAAM,GAA2B,EAAC,EACuB;AACrE,EAAA,MAAM,SAASC,qBAAA,EAAgB;AAE/B,EAAA,OAAOC,mBAAA,CAAS;AAAA,IACd,GAAG,sBAAA,CAAuB,MAAA,EAAQ,OAAO,CAAA;AAAA;AAAA,IAEzC,gBAAgB,CAAC,OAAA;AAAA,IACjB,sBAAsB,CAAC,OAAA;AAAA,IACvB,oBAAoB,CAAC,OAAA;AAAA;AAAA,IAErB,MAAA,EAAQC;AAAA,GACT,CAAA;AACH;AAQO,SAAS,oBAAA,CACd,QAAA,EACA,MAAA,EACA,QAAA,EACK;AACL,EAAA,MAAM,SAASF,qBAAA,EAAgB;AAE/B,EAAA,OAAOG,qBAAA,CAAW;AAAA,IAChB,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,CAAA,OAAA,MAAY;AAAA,MAChC,GAAG,sBAAA,CAAuB,MAAA,EAAQ,OAAO,CAAA;AAAA,MACzC,cAAA,EAAgB,KAAA;AAAA,MAChB,oBAAA,EAAsB,KAAA;AAAA,MACtB,kBAAA,EAAoB,KAAA;AAAA,MACpB,MAAA,EAAQ,CAAC,IAAA,KAAyB,MAAA,CAAO,SAAS,IAAI;AAAA,KACxD,CAAE,CAAA;AAAA,IACF,OAAA,EAAS,aACP,OAAA,CAAQ,GAAA;AAAA,MAAI,CAAC,MAAA,EAAQ,KAAA,KACnB,MAAA,CAAO,IAAA,KAAS,MAAA,GAAY,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,IAAK,EAAE,CAAA,GAAK,MAAA,CAAO;AAAA;AACxE,GACH,CAAA;AACH;;;;;;"}
|
|
@@ -3,7 +3,6 @@ import { useQuery, queryOptions, useQueries } from '@tanstack/react-query';
|
|
|
3
3
|
import { selectSearchableSpans } from '../utils/to-searchable-spans.es.js';
|
|
4
4
|
import 'date-fns';
|
|
5
5
|
|
|
6
|
-
const IMMUTABLE_CACHE_TIME = 1e3 * 60 * 60 * 24 * 30;
|
|
7
6
|
const traceSpansQueryOptions = (client, traceId) => queryOptions({
|
|
8
7
|
queryKey: ["trace-spans", traceId],
|
|
9
8
|
queryFn: async () => {
|
|
@@ -14,16 +13,17 @@ const traceSpansQueryOptions = (client, traceId) => queryOptions({
|
|
|
14
13
|
return res;
|
|
15
14
|
},
|
|
16
15
|
enabled: !!traceId,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const isFinished = data?.spans.every((span) => Boolean(span.endedAt));
|
|
20
|
-
return isFinished ? IMMUTABLE_CACHE_TIME : 0;
|
|
21
|
-
}
|
|
16
|
+
// Resumed runs and delayed exports can append spans even when every known span has ended.
|
|
17
|
+
staleTime: 0
|
|
22
18
|
});
|
|
23
|
-
function useTraceSpans(traceId) {
|
|
19
|
+
function useTraceSpans(traceId, { passive = false } = {}) {
|
|
24
20
|
const client = useMastraClient();
|
|
25
21
|
return useQuery({
|
|
26
22
|
...traceSpansQueryOptions(client, traceId),
|
|
23
|
+
// History rows share updates but leave automatic refreshes to the selected detail.
|
|
24
|
+
refetchOnMount: !passive,
|
|
25
|
+
refetchOnWindowFocus: !passive,
|
|
26
|
+
refetchOnReconnect: !passive,
|
|
27
27
|
// Builds each span's search haystack once per fetch, cached with the query.
|
|
28
28
|
select: selectSearchableSpans
|
|
29
29
|
});
|
|
@@ -33,6 +33,9 @@ function useTraceSpansQueries(traceIds, select, fallback) {
|
|
|
33
33
|
return useQueries({
|
|
34
34
|
queries: traceIds.map((traceId) => ({
|
|
35
35
|
...traceSpansQueryOptions(client, traceId),
|
|
36
|
+
refetchOnMount: false,
|
|
37
|
+
refetchOnWindowFocus: false,
|
|
38
|
+
refetchOnReconnect: false,
|
|
36
39
|
select: (data) => select(traceId, data)
|
|
37
40
|
})),
|
|
38
41
|
combine: (results) => results.map(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-trace-spans.es.js","sources":["../../../../src/domains/traces/hooks/use-trace-spans.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useMastraClient } from '@mastra/react';\nimport { queryOptions, useQueries, useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\
|
|
1
|
+
{"version":3,"file":"use-trace-spans.es.js","sources":["../../../../src/domains/traces/hooks/use-trace-spans.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useMastraClient } from '@mastra/react';\nimport { queryOptions, useQueries, useQuery } from '@tanstack/react-query';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport type { SearchableSpan } from '../types';\nimport { selectSearchableSpans } from '../utils';\n\n/**\n * Key, fetcher and stale policy of the `trace-spans` query. Every observer of this key must\n * share these (rather than only the key) so one observer with a stricter `staleTime` does not\n * refetch data another one considers fresh.\n */\nexport const traceSpansQueryOptions = (client: MastraClient, traceId: string | null | undefined) =>\n queryOptions({\n queryKey: ['trace-spans', traceId],\n queryFn: async () => {\n if (!traceId) {\n throw new Error('Trace ID is required');\n }\n const res = await client.getTrace(traceId);\n return res;\n },\n enabled: !!traceId,\n // Resumed runs and delayed exports can append spans even when every known span has ended.\n staleTime: 0,\n });\n\n/**\n * Every span of a single trace, with its full payload.\n *\n * The lightweight projection exists to keep blob columns off the read path of a\n * *list*, where the cost is paid once per trace on screen. A trace that is open\n * has already narrowed that to one, and the panel both renders and searches\n * these spans -- `input`, `output` and `attributes` included -- so the\n * projection would only hide content the reader is looking at.\n */\nexport function useTraceSpans(\n traceId: string | null | undefined,\n { passive = false }: { passive?: boolean } = {},\n): UseQueryResult<{ traceId: string; spans: SearchableSpan[] } | null> {\n const client = useMastraClient();\n\n return useQuery({\n ...traceSpansQueryOptions(client, traceId),\n // History rows share updates but leave automatic refreshes to the selected detail.\n refetchOnMount: !passive,\n refetchOnWindowFocus: !passive,\n refetchOnReconnect: !passive,\n // Builds each span's search haystack once per fetch, cached with the query.\n select: selectSearchableSpans,\n });\n}\n\nexport type TraceSpansData = Awaited<ReturnType<MastraClient['getTrace']>>;\n\n/**\n * Observes the `trace-spans` query of several traces at once and projects each one with `select`.\n * Traces still loading (or failed) yield `fallback(traceId)` so the result always lines up with `traceIds`.\n */\nexport function useTraceSpansQueries<T>(\n traceIds: string[],\n select: (traceId: string, data: TraceSpansData) => T,\n fallback: (traceId: string) => T,\n): T[] {\n const client = useMastraClient();\n\n return useQueries({\n queries: traceIds.map(traceId => ({\n ...traceSpansQueryOptions(client, traceId),\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n select: (data: TraceSpansData) => select(traceId, data),\n })),\n combine: results =>\n results.map((result, index) =>\n result.data === undefined ? fallback(traceIds[index] ?? '') : (result.data as T),\n ),\n });\n}\n"],"names":[],"mappings":";;;;;AAYO,MAAM,sBAAA,GAAyB,CAAC,MAAA,EAAsB,OAAA,KAC3D,YAAA,CAAa;AAAA,EACX,QAAA,EAAU,CAAC,aAAA,EAAe,OAAO,CAAA;AAAA,EACjC,SAAS,YAAY;AACnB,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,MAAM,sBAAsB,CAAA;AAAA,IACxC;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA;AACzC,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AAAA,EACA,OAAA,EAAS,CAAC,CAAC,OAAA;AAAA;AAAA,EAEX,SAAA,EAAW;AACb,CAAC;AAWI,SAAS,cACd,OAAA,EACA,EAAE,UAAU,KAAA,EAAM,GAA2B,EAAC,EACuB;AACrE,EAAA,MAAM,SAAS,eAAA,EAAgB;AAE/B,EAAA,OAAO,QAAA,CAAS;AAAA,IACd,GAAG,sBAAA,CAAuB,MAAA,EAAQ,OAAO,CAAA;AAAA;AAAA,IAEzC,gBAAgB,CAAC,OAAA;AAAA,IACjB,sBAAsB,CAAC,OAAA;AAAA,IACvB,oBAAoB,CAAC,OAAA;AAAA;AAAA,IAErB,MAAA,EAAQ;AAAA,GACT,CAAA;AACH;AAQO,SAAS,oBAAA,CACd,QAAA,EACA,MAAA,EACA,QAAA,EACK;AACL,EAAA,MAAM,SAAS,eAAA,EAAgB;AAE/B,EAAA,OAAO,UAAA,CAAW;AAAA,IAChB,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,CAAA,OAAA,MAAY;AAAA,MAChC,GAAG,sBAAA,CAAuB,MAAA,EAAQ,OAAO,CAAA;AAAA,MACzC,cAAA,EAAgB,KAAA;AAAA,MAChB,oBAAA,EAAsB,KAAA;AAAA,MACtB,kBAAA,EAAoB,KAAA;AAAA,MACpB,MAAA,EAAQ,CAAC,IAAA,KAAyB,MAAA,CAAO,SAAS,IAAI;AAAA,KACxD,CAAE,CAAA;AAAA,IACF,OAAA,EAAS,aACP,OAAA,CAAQ,GAAA;AAAA,MAAI,CAAC,MAAA,EAAQ,KAAA,KACnB,MAAA,CAAO,IAAA,KAAS,MAAA,GAAY,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,IAAK,EAAE,CAAA,GAAK,MAAA,CAAO;AAAA;AACxE,GACH,CAAA;AACH;;;;"}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
const React = require('react');
|
|
7
7
|
const Button = require('../../../Button-D10WB4vc.cjs');
|
|
8
|
-
const dialog = require('../../../dialog-
|
|
8
|
+
const dialog = require('../../../dialog-D-7Hkb3j.cjs');
|
|
9
9
|
const fieldBlock = require('../../../field-block-Dr9fbwQx.cjs');
|
|
10
10
|
const textFieldBlock = require('../../../text-field-block-Dtup2Jqm.cjs');
|
|
11
11
|
const spinner = require('../../../spinner-B_xKBDo_.cjs');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { useId, useState } from 'react';
|
|
3
3
|
import { B as Button } from '../../../Button-BsfLQEC6.js';
|
|
4
|
-
import { D as Dialog,
|
|
4
|
+
import { D as Dialog, a as DialogContent, b as DialogHeader, c as DialogTitle, d as DialogDescription, e as DialogBody, f as DialogFooter } from '../../../dialog-CZMPDVUj.js';
|
|
5
5
|
import { F as FieldBlock } from '../../../field-block-DcGeY-_x.js';
|
|
6
6
|
import { T as TextFieldBlock } from '../../../text-field-block-D7vJZCzd.js';
|
|
7
7
|
import { S as Spinner } from '../../../spinner-BMRlaJFy.js';
|
|
@@ -78,6 +78,10 @@ async function highlight(code, language) {
|
|
|
78
78
|
});
|
|
79
79
|
return tokens;
|
|
80
80
|
}
|
|
81
|
+
function languageForPath(path) {
|
|
82
|
+
const extension = path?.split(".").pop()?.toLowerCase();
|
|
83
|
+
return extension ? langAliases[extension] : void 0;
|
|
84
|
+
}
|
|
81
85
|
|
|
82
|
-
export { highlight as h };
|
|
83
|
-
//# sourceMappingURL=highlight-
|
|
86
|
+
export { highlight as h, languageForPath as l };
|
|
87
|
+
//# sourceMappingURL=highlight-BmpoELR4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"highlight-
|
|
1
|
+
{"version":3,"file":"highlight-BmpoELR4.js","sources":["../src/ds/components/CodeEditor/highlight.ts"],"sourcesContent":["import type { HighlighterCore, ThemedToken } from 'shiki/core';\n\n/**\n * Languages we support for syntax highlighting in code blocks. A superset of\n * the editable CodeMirror `codeLanguages` set: read-only blocks (markdown\n * fences, chat output) also carry yaml, diff, css, html, xml and sql. Using\n * fine-grained Shiki imports (rather than the full `shiki` bundle) means only\n * these grammars are bundled, instead of a chunk for every language Shiki\n * knows about.\n */\nconst langAliases: Record<string, string> = {\n js: 'javascript',\n javascript: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n node: 'javascript',\n ts: 'typescript',\n typescript: 'typescript',\n mts: 'typescript',\n cts: 'typescript',\n tsx: 'tsx',\n jsx: 'jsx',\n json: 'json',\n json5: 'json',\n md: 'markdown',\n markdown: 'markdown',\n py: 'python',\n python: 'python',\n sh: 'bash',\n bash: 'bash',\n shell: 'bash',\n zsh: 'bash',\n yml: 'yaml',\n yaml: 'yaml',\n diff: 'diff',\n patch: 'diff',\n css: 'css',\n scss: 'css',\n html: 'html',\n htm: 'html',\n xml: 'xml',\n svg: 'xml',\n sql: 'sql',\n};\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null;\n\nfunction getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = (async () => {\n const [{ createHighlighterCore }, { createJavaScriptRegexEngine }] = await Promise.all([\n import('shiki/core'),\n import('shiki/engine/javascript'),\n ]);\n\n return createHighlighterCore({\n themes: [import('shiki/themes/github-light.mjs'), import('shiki/themes/github-dark.mjs')],\n langs: [\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/markdown.mjs'),\n import('shiki/langs/python.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/diff.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/xml.mjs'),\n import('shiki/langs/sql.mjs'),\n ],\n engine: createJavaScriptRegexEngine(),\n });\n })();\n }\n\n return highlighterPromise;\n}\n\nexport async function highlight(code: string, language: string): Promise<ThemedToken[][] | null> {\n const lang = langAliases[language?.toLowerCase()];\n if (!lang) return null;\n\n const highlighter = await getHighlighter();\n\n const { tokens } = highlighter.codeToTokens(code, {\n lang,\n defaultColor: false,\n themes: {\n light: 'github-light',\n dark: 'github-dark',\n },\n });\n\n return tokens;\n}\n\nexport function languageForPath(path: string | undefined): string | undefined {\n const extension = path?.split('.').pop()?.toLowerCase();\n return extension ? langAliases[extension] : undefined;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -80,6 +80,11 @@ async function highlight(code, language) {
|
|
|
80
80
|
});
|
|
81
81
|
return tokens;
|
|
82
82
|
}
|
|
83
|
+
function languageForPath(path) {
|
|
84
|
+
const extension = path?.split(".").pop()?.toLowerCase();
|
|
85
|
+
return extension ? langAliases[extension] : void 0;
|
|
86
|
+
}
|
|
83
87
|
|
|
84
88
|
exports.highlight = highlight;
|
|
85
|
-
|
|
89
|
+
exports.languageForPath = languageForPath;
|
|
90
|
+
//# sourceMappingURL=highlight-DK1dn-Fh.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"highlight-
|
|
1
|
+
{"version":3,"file":"highlight-DK1dn-Fh.cjs","sources":["../src/ds/components/CodeEditor/highlight.ts"],"sourcesContent":["import type { HighlighterCore, ThemedToken } from 'shiki/core';\n\n/**\n * Languages we support for syntax highlighting in code blocks. A superset of\n * the editable CodeMirror `codeLanguages` set: read-only blocks (markdown\n * fences, chat output) also carry yaml, diff, css, html, xml and sql. Using\n * fine-grained Shiki imports (rather than the full `shiki` bundle) means only\n * these grammars are bundled, instead of a chunk for every language Shiki\n * knows about.\n */\nconst langAliases: Record<string, string> = {\n js: 'javascript',\n javascript: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n node: 'javascript',\n ts: 'typescript',\n typescript: 'typescript',\n mts: 'typescript',\n cts: 'typescript',\n tsx: 'tsx',\n jsx: 'jsx',\n json: 'json',\n json5: 'json',\n md: 'markdown',\n markdown: 'markdown',\n py: 'python',\n python: 'python',\n sh: 'bash',\n bash: 'bash',\n shell: 'bash',\n zsh: 'bash',\n yml: 'yaml',\n yaml: 'yaml',\n diff: 'diff',\n patch: 'diff',\n css: 'css',\n scss: 'css',\n html: 'html',\n htm: 'html',\n xml: 'xml',\n svg: 'xml',\n sql: 'sql',\n};\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null;\n\nfunction getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = (async () => {\n const [{ createHighlighterCore }, { createJavaScriptRegexEngine }] = await Promise.all([\n import('shiki/core'),\n import('shiki/engine/javascript'),\n ]);\n\n return createHighlighterCore({\n themes: [import('shiki/themes/github-light.mjs'), import('shiki/themes/github-dark.mjs')],\n langs: [\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/markdown.mjs'),\n import('shiki/langs/python.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/diff.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/xml.mjs'),\n import('shiki/langs/sql.mjs'),\n ],\n engine: createJavaScriptRegexEngine(),\n });\n })();\n }\n\n return highlighterPromise;\n}\n\nexport async function highlight(code: string, language: string): Promise<ThemedToken[][] | null> {\n const lang = langAliases[language?.toLowerCase()];\n if (!lang) return null;\n\n const highlighter = await getHighlighter();\n\n const { tokens } = highlighter.codeToTokens(code, {\n lang,\n defaultColor: false,\n themes: {\n light: 'github-light',\n dark: 'github-dark',\n },\n });\n\n return tokens;\n}\n\nexport function languageForPath(path: string | undefined): string | undefined {\n const extension = path?.split('.').pop()?.toLowerCase();\n return extension ? langAliases[extension] : undefined;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,20 @@ import { S as ScrollArea } from './scroll-area-BiHnOfzg.js';
|
|
|
3
3
|
import { T as Tooltip, c as TooltipTrigger, a as TooltipContent } from './tooltip-Bi0pDO5P.js';
|
|
4
4
|
import { c as cn } from './cn-B4oPhFx9.js';
|
|
5
5
|
|
|
6
|
+
function hexLuminance(color) {
|
|
7
|
+
const hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color.trim())?.[1];
|
|
8
|
+
if (!hex) return void 0;
|
|
9
|
+
const full = hex.length === 3 ? [...hex].map((c) => c + c).join("") : hex;
|
|
10
|
+
const linear = (offset) => {
|
|
11
|
+
const channel = parseInt(full.slice(offset, offset + 2), 16) / 255;
|
|
12
|
+
return channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;
|
|
13
|
+
};
|
|
14
|
+
return 0.2126 * linear(0) + 0.7152 * linear(2) + 0.0722 * linear(4);
|
|
15
|
+
}
|
|
16
|
+
function needsDarkLabel(color) {
|
|
17
|
+
const luminance = color ? hexLuminance(color) : void 0;
|
|
18
|
+
return luminance !== void 0 && luminance > 0.25;
|
|
19
|
+
}
|
|
6
20
|
function HorizontalBars({
|
|
7
21
|
data,
|
|
8
22
|
segments,
|
|
@@ -27,14 +41,16 @@ function HorizontalBars({
|
|
|
27
41
|
] }),
|
|
28
42
|
/* @__PURE__ */ jsx("div", { className: "grid gap-3.5", children: sorted.map((d) => {
|
|
29
43
|
const total = d.values.reduce((s, v) => s + v, 0);
|
|
44
|
+
const barWidth = `${maxVal > 0 ? total / maxVal * 100 : 0}%`;
|
|
45
|
+
const darkLabelOnFill = needsDarkLabel(segments[d.values.findIndex((v) => v > 0)]?.color);
|
|
30
46
|
const rowBody = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31
|
-
/* @__PURE__ */ jsxs("div", { className: "relative h-full min-w-0 flex-1", children: [
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: "relative h-full min-w-0 flex-1", style: { "--bar-width": barWidth }, children: [
|
|
32
48
|
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
33
49
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
34
50
|
"div",
|
|
35
51
|
{
|
|
36
52
|
className: cn("absolute inset-y-0 left-0", d.href ? "cursor-pointer" : "cursor-default"),
|
|
37
|
-
style: { width:
|
|
53
|
+
style: { width: barWidth },
|
|
38
54
|
children: segments.map((seg, si) => {
|
|
39
55
|
const val = d.values[si] ?? 0;
|
|
40
56
|
const pct = total > 0 ? val / total * 100 : 0;
|
|
@@ -79,7 +95,24 @@ function HorizontalBars({
|
|
|
79
95
|
/* @__PURE__ */ jsx("span", { className: "ml-auto pl-3", children: fmt(d.values[si] ?? 0) })
|
|
80
96
|
] }, seg.label)) }) })
|
|
81
97
|
] }),
|
|
82
|
-
/* @__PURE__ */ jsx(
|
|
98
|
+
/* @__PURE__ */ jsx(
|
|
99
|
+
"div",
|
|
100
|
+
{
|
|
101
|
+
className: cn(
|
|
102
|
+
"pointer-events-none absolute inset-0 z-10",
|
|
103
|
+
darkLabelOnFill && "dark:[clip-path:inset(0_0_0_var(--bar-width))]"
|
|
104
|
+
),
|
|
105
|
+
children: /* @__PURE__ */ jsx("span", { className: "text-ui-sm text-neutral4 absolute inset-y-0 left-2.5 flex items-center truncate", children: d.name })
|
|
106
|
+
}
|
|
107
|
+
),
|
|
108
|
+
darkLabelOnFill && /* @__PURE__ */ jsx(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
"aria-hidden": true,
|
|
112
|
+
className: "pointer-events-none absolute inset-y-0 left-0 z-10 hidden w-(--bar-width) overflow-hidden dark:block",
|
|
113
|
+
children: /* @__PURE__ */ jsx("span", { className: "text-ui-sm text-neutral1 absolute inset-y-0 left-2.5 flex items-center whitespace-nowrap", children: d.name })
|
|
114
|
+
}
|
|
115
|
+
)
|
|
83
116
|
] }),
|
|
84
117
|
/* @__PURE__ */ jsx("span", { className: "text-ui-md text-neutral4 shrink-0 pr-3 tabular-nums", children: fmt(total) })
|
|
85
118
|
] });
|
|
@@ -103,4 +136,4 @@ function Wrapper({ children }) {
|
|
|
103
136
|
}
|
|
104
137
|
|
|
105
138
|
export { HorizontalBars as H };
|
|
106
|
-
//# sourceMappingURL=horizontal-bars-
|
|
139
|
+
//# sourceMappingURL=horizontal-bars-CyP-B-BX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"horizontal-bars-CyP-B-BX.js","sources":["../src/ds/components/HorizontalBars/horizontal-bars.tsx"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport { ScrollArea } from '@/ds/components/ScrollArea/scroll-area';\nimport { Tooltip, TooltipTrigger, TooltipContent } from '@/ds/components/Tooltip';\nimport type { LinkComponent } from '@/ds/types/link-component';\nimport { cn } from '@/lib/utils';\n\n/** Relative luminance (WCAG) of a hex color, or `undefined` for anything else (e.g. `var(--token)`). */\nfunction hexLuminance(color: string): number | undefined {\n const hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color.trim())?.[1];\n if (!hex) return undefined;\n const full = hex.length === 3 ? [...hex].map(c => c + c).join('') : hex;\n const linear = (offset: number) => {\n const channel = parseInt(full.slice(offset, offset + 2), 16) / 255;\n return channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;\n };\n return 0.2126 * linear(0) + 0.7152 * linear(2) + 0.0722 * linear(4);\n}\n\n/** Bright fills (yellow, orange, green, red) swallow the light label; dark text reads better on them. */\nfunction needsDarkLabel(color: string | undefined): boolean {\n const luminance = color ? hexLuminance(color) : undefined;\n return luminance !== undefined && luminance > 0.25;\n}\n\ntype Segment = { label: string; color: string };\n\ntype HorizontalBarRow = {\n name: string;\n values: number[];\n /** If present, the whole row is rendered as a link to this URL. */\n href?: string;\n /** If present, an individual segment becomes its own link. Indices align with `segments`. */\n hrefs?: Array<string | undefined>;\n};\n\nexport function HorizontalBars({\n data,\n segments,\n maxVal,\n fmt,\n className,\n LinkComponent = 'a',\n}: {\n data: Array<HorizontalBarRow>;\n segments: Segment[];\n maxVal: number;\n fmt: (v: number) => string;\n className?: string;\n /** Override how links produced by `href` / `hrefs` are rendered. Receives `href`,\n * `className`, `aria-label`, and `children`. Defaults to a plain `<a>` element;\n * consumers using a router should pass an adapter that maps `href` to their\n * navigation primitive (e.g. react-router `<Link to={href} />`). */\n LinkComponent?: LinkComponent;\n}) {\n const sorted = [...data].sort((a, b) => {\n const totalB = b.values.reduce((s, v) => s + v, 0);\n const totalA = a.values.reduce((s, v) => s + v, 0);\n return totalB - totalA;\n });\n\n const isStacked = segments.length > 1;\n\n return (\n <ScrollArea className={cn('size-full', className)}>\n <div className=\"mt-2 mb-4 flex items-center gap-3\">\n <div className=\"flex flex-1 items-center gap-4\">\n {segments.map(seg => (\n <div key={seg.label} className=\"flex items-center gap-2\">\n <div className=\"size-2 rounded-full\" style={{ backgroundColor: seg.color }} />\n <span className=\"text-ui-sm text-neutral3\">{seg.label}</span>\n </div>\n ))}\n </div>\n <span className=\"text-ui-sm text-neutral2 shrink-0 pr-2\">Total</span>\n </div>\n <div className=\"grid gap-3.5\">\n {sorted.map(d => {\n const total = d.values.reduce((s, v) => s + v, 0);\n const barWidth = `${maxVal > 0 ? (total / maxVal) * 100 : 0}%`;\n // The label starts over the first filled segment; that fill decides the label tone in dark mode.\n // Light mode fades every fill to 40% (see below), so the default label already reads there.\n const darkLabelOnFill = needsDarkLabel(segments[d.values.findIndex(v => v > 0)]?.color);\n const rowBody = (\n <>\n <div className=\"relative h-full min-w-0 flex-1\" style={{ '--bar-width': barWidth } as CSSProperties}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div\n className={cn('absolute inset-y-0 left-0', d.href ? 'cursor-pointer' : 'cursor-default')}\n style={{ width: barWidth }}\n >\n {segments.map((seg, si) => {\n const val = d.values[si] ?? 0;\n const pct = total > 0 ? (val / total) * 100 : 0;\n const left = d.values.slice(0, si).reduce((s, v) => s + (total > 0 ? (v / total) * 100 : 0), 0);\n const isLastWithValue = d.values.slice(si + 1).every(v => !v);\n // Only honor segment-level links when the row itself is not an anchor.\n // Otherwise we'd render <a> nested inside <a>, which is invalid HTML.\n const segHref = d.href ? undefined : d.hrefs?.[si];\n\n const segmentNode = (\n <div\n className={cn(\n 'absolute inset-y-0 opacity-40 dark:opacity-100',\n isStacked && si === 0 && 'rounded-l',\n isStacked && isLastWithValue && 'rounded-r',\n !isStacked && 'rounded',\n segHref && 'cursor-pointer transition-opacity hover:opacity-70',\n )}\n style={{\n left: isStacked ? `${left}%` : 0,\n width: isStacked ? `${pct}%` : `${pct}%`,\n backgroundColor: seg.color,\n }}\n />\n );\n\n if (segHref) {\n return (\n <LinkComponent\n key={seg.label}\n href={segHref}\n aria-label={`${d.name} — ${seg.label}`}\n className=\"contents\"\n >\n {segmentNode}\n </LinkComponent>\n );\n }\n return <Wrapper key={seg.label}>{segmentNode}</Wrapper>;\n })}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"font-mono\">\n <div className=\"grid gap-1\">\n {segments.map((seg, si) => (\n <div key={seg.label} className=\"flex items-center gap-2\">\n <span>{seg.label}</span>\n <span className=\"ml-auto pl-3\">{fmt(d.values[si] ?? 0)}</span>\n </div>\n ))}\n </div>\n </TooltipContent>\n </Tooltip>\n <div\n className={cn(\n 'pointer-events-none absolute inset-0 z-10',\n darkLabelOnFill && 'dark:[clip-path:inset(0_0_0_var(--bar-width))]',\n )}\n >\n <span className=\"text-ui-sm text-neutral4 absolute inset-y-0 left-2.5 flex items-center truncate\">\n {d.name}\n </span>\n </div>\n {darkLabelOnFill && (\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-y-0 left-0 z-10 hidden w-(--bar-width) overflow-hidden dark:block\"\n >\n <span className=\"text-ui-sm text-neutral1 absolute inset-y-0 left-2.5 flex items-center whitespace-nowrap\">\n {d.name}\n </span>\n </div>\n )}\n </div>\n <span className=\"text-ui-md text-neutral4 shrink-0 pr-3 tabular-nums\">{fmt(total)}</span>\n </>\n );\n\n if (d.href) {\n return (\n <LinkComponent\n key={d.name}\n href={d.href}\n className=\"hover:bg-surface3 focus-visible:bg-surface3 flex h-6 cursor-pointer items-center gap-14 rounded transition-colors outline-none\"\n >\n {rowBody}\n </LinkComponent>\n );\n }\n return (\n <div key={d.name} className=\"flex h-6 items-center gap-14\">\n {rowBody}\n </div>\n );\n })}\n </div>\n </ScrollArea>\n );\n}\n\nfunction Wrapper({ children }: { children: ReactNode }) {\n return <>{children}</>;\n}\n"],"names":[],"mappings":"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"}
|