@mastra/playground-ui 51.3.1 → 51.4.0-alpha.1
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 +57 -0
- package/dist/Badge-DcllBqFg.cjs +125 -0
- package/dist/Badge-DcllBqFg.cjs.map +1 -0
- package/dist/Badge-uGehUtus.js +123 -0
- package/dist/Badge-uGehUtus.js.map +1 -0
- package/dist/components/Badge.cjs.js +1 -1
- package/dist/components/Badge.es.js +1 -1
- package/dist/components/DataList.cjs.js +4 -4
- package/dist/components/DataList.es.js +4 -4
- package/dist/components/EnvironmentVariablesEditor.cjs.js +1 -1
- package/dist/components/EnvironmentVariablesEditor.es.js +1 -1
- package/dist/components/ItemList.cjs.js +59 -40
- package/dist/components/ItemList.cjs.js.map +1 -1
- package/dist/components/ItemList.es.js +58 -41
- package/dist/components/ItemList.es.js.map +1 -1
- package/dist/components/LogsDataList.cjs.js +2 -3
- package/dist/components/LogsDataList.cjs.js.map +1 -1
- package/dist/components/LogsDataList.es.js +2 -3
- package/dist/components/LogsDataList.es.js.map +1 -1
- package/dist/components/ai/ask-user.cjs.js +3 -3
- package/dist/components/ai/ask-user.cjs.js.map +1 -1
- package/dist/components/ai/ask-user.es.js +3 -3
- package/dist/components/ai/ask-user.es.js.map +1 -1
- package/dist/components/ai/plan.cjs.js +3 -3
- package/dist/components/ai/plan.cjs.js.map +1 -1
- package/dist/components/ai/plan.es.js +3 -3
- package/dist/components/ai/plan.es.js.map +1 -1
- package/dist/{data-list-BOI8fRuk.js → data-list-C3tjx5Vb.js} +2 -2
- package/dist/{data-list-BOI8fRuk.js.map → data-list-C3tjx5Vb.js.map} +1 -1
- package/dist/{data-list-CCacNODd.cjs → data-list-CRDewYj9.cjs} +2 -2
- package/dist/{data-list-CCacNODd.cjs.map → data-list-CRDewYj9.cjs.map} +1 -1
- package/dist/{data-list-skeleton-DDO_OE14.js → data-list-skeleton-BCrkk6wG.js} +2 -2
- package/dist/{data-list-skeleton-DDO_OE14.js.map → data-list-skeleton-BCrkk6wG.js.map} +1 -1
- package/dist/{data-list-skeleton-BHBSIQHN.cjs → data-list-skeleton-CONfqzH2.cjs} +2 -2
- package/dist/{data-list-skeleton-BHBSIQHN.cjs.map → data-list-skeleton-CONfqzH2.cjs.map} +1 -1
- package/dist/{data-list-top-cell-BOXO5s7I.cjs → data-list-top-cell-DAztx3m8.cjs} +6 -1
- package/dist/data-list-top-cell-DAztx3m8.cjs.map +1 -0
- package/dist/{data-list-top-cell-CC5jjv5s.js → data-list-top-cell-hNkk6S-Q.js} +6 -2
- package/dist/data-list-top-cell-hNkk6S-Q.js.map +1 -0
- package/dist/domains/logs/components/logs-list-view.cjs.js +2 -2
- package/dist/domains/logs/components/logs-list-view.es.js +2 -2
- package/dist/domains/metrics/components/memory-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/memory-card-view.es.js +1 -1
- package/dist/domains/metrics/components/model-usage-cost-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/model-usage-cost-card-view.es.js +1 -1
- package/dist/domains/metrics/components/scores-card-view.cjs.js +1 -1
- package/dist/domains/metrics/components/scores-card-view.es.js +1 -1
- package/dist/domains/traces/components/format-hierarchical-spans.cjs.js +2 -1
- package/dist/domains/traces/components/format-hierarchical-spans.cjs.js.map +1 -1
- package/dist/domains/traces/components/format-hierarchical-spans.es.js +2 -1
- package/dist/domains/traces/components/format-hierarchical-spans.es.js.map +1 -1
- package/dist/domains/traces/components/timeline-name-col.cjs.js +10 -1
- package/dist/domains/traces/components/timeline-name-col.cjs.js.map +1 -1
- package/dist/domains/traces/components/timeline-name-col.es.js +10 -1
- package/dist/domains/traces/components/timeline-name-col.es.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js +12 -4
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.es.js +12 -4
- package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
- package/dist/domains/traces/components/traces-list-view.cjs.js +7 -9
- package/dist/domains/traces/components/traces-list-view.cjs.js.map +1 -1
- package/dist/domains/traces/components/traces-list-view.es.js +7 -9
- package/dist/domains/traces/components/traces-list-view.es.js.map +1 -1
- package/dist/domains/traces/hooks/use-trace-search.cjs.js +10 -4
- package/dist/domains/traces/hooks/use-trace-search.cjs.js.map +1 -1
- package/dist/domains/traces/hooks/use-trace-search.es.js +10 -4
- package/dist/domains/traces/hooks/use-trace-search.es.js.map +1 -1
- package/dist/domains/traces/trace-list-columns.cjs.js +1 -1
- package/dist/domains/traces/trace-list-columns.cjs.js.map +1 -1
- package/dist/domains/traces/trace-list-columns.es.js +1 -1
- package/dist/domains/traces/trace-list-columns.es.js.map +1 -1
- package/dist/domains/traces/types.cjs.js.map +1 -1
- package/dist/domains/traces/types.es.js.map +1 -1
- package/dist/ee/topics/components/topic-trace-summary-list.cjs.js +1 -1
- package/dist/ee/topics/components/topic-trace-summary-list.es.js +1 -1
- package/dist/hooks/use-text-highlight.cjs.js +28 -2
- package/dist/hooks/use-text-highlight.cjs.js.map +1 -1
- package/dist/hooks/use-text-highlight.es.js +28 -2
- package/dist/hooks/use-text-highlight.es.js.map +1 -1
- package/dist/{logs-data-list-Xayqbjw4.cjs → logs-data-list-D88JF2lo.cjs} +2 -2
- package/dist/{logs-data-list-Xayqbjw4.cjs.map → logs-data-list-D88JF2lo.cjs.map} +1 -1
- package/dist/{logs-data-list-DRXJ89IZ.js → logs-data-list-DnAXTwr7.js} +2 -2
- package/dist/{logs-data-list-DRXJ89IZ.js.map → logs-data-list-DnAXTwr7.js.map} +1 -1
- package/dist/src/domains/metrics/hooks/use-active-resources-kpi-metrics.d.ts +2 -2
- package/dist/src/domains/metrics/hooks/use-active-threads-kpi-metrics.d.ts +2 -2
- package/dist/src/domains/metrics/hooks/use-agent-runs-kpi-metrics.d.ts +2 -2
- package/dist/src/domains/traces/components/format-hierarchical-spans.d.ts +1 -0
- package/dist/src/domains/traces/components/trace-data-panel-view.d.ts +1 -1
- package/dist/src/domains/traces/hooks/use-trace-search.d.ts +7 -0
- package/dist/src/domains/traces/types.d.ts +5 -0
- package/dist/src/ds/components/Badge/Badge.d.ts +86 -12
- package/dist/src/ds/components/Badge/badge.stories.d.ts +3 -0
- package/dist/src/ds/components/DataList/TracesDataList/traces-data-list.d.ts +2 -3
- package/dist/src/ds/components/DataList/data-list-cells.d.ts +5 -0
- package/dist/src/ds/components/ItemList/helpers.d.ts +8 -0
- package/dist/src/ds/components/ItemList/item-list-link-cell.d.ts +2 -1
- package/dist/src/ds/components/ItemList/item-list-row-button.d.ts +2 -1
- package/dist/src/ds/components/ai/plan/plan.d.ts +1 -1
- package/dist/src/hooks/use-text-highlight.d.ts +5 -0
- package/dist/src/test/highlight-api.d.ts +6 -4
- package/dist/style.css +364 -219
- package/dist/{traces-data-list-BLZgf-Es.cjs → traces-data-list-COksp2d4.cjs} +12 -13
- package/dist/traces-data-list-COksp2d4.cjs.map +1 -0
- package/dist/{traces-data-list-DmXGwe4Q.js → traces-data-list-c5I-8hwt.js} +12 -13
- package/dist/traces-data-list-c5I-8hwt.js.map +1 -0
- package/dist/use-text-highlight.css +8 -0
- package/package.json +7 -7
- package/theme.css +53 -0
- package/dist/Badge-BlJpI3fY.cjs +0 -57
- package/dist/Badge-BlJpI3fY.cjs.map +0 -1
- package/dist/Badge-woV6OD8k.js +0 -55
- package/dist/Badge-woV6OD8k.js.map +0 -1
- package/dist/chip-9P9t0dvN.cjs +0 -68
- package/dist/chip-9P9t0dvN.cjs.map +0 -1
- package/dist/chip-Bg0-95sX.js +0 -66
- package/dist/chip-Bg0-95sX.js.map +0 -1
- package/dist/components/Chip.cjs.js +0 -27
- package/dist/components/Chip.cjs.js.map +0 -1
- package/dist/components/Chip.d.ts +0 -2
- package/dist/components/Chip.es.js +0 -22
- package/dist/components/Chip.es.js.map +0 -1
- package/dist/components/StatusBadge.cjs.js +0 -76
- package/dist/components/StatusBadge.cjs.js.map +0 -1
- package/dist/components/StatusBadge.d.ts +0 -2
- package/dist/components/StatusBadge.es.js +0 -72
- package/dist/components/StatusBadge.es.js.map +0 -1
- package/dist/data-list-top-cell-BOXO5s7I.cjs.map +0 -1
- package/dist/data-list-top-cell-CC5jjv5s.js.map +0 -1
- package/dist/src/ds/components/Chip/chip.d.ts +0 -8
- package/dist/src/ds/components/Chip/chip.stories.d.ts +0 -11
- package/dist/src/ds/components/Chip/chips-group.d.ts +0 -2
- package/dist/src/ds/components/Chip/index.d.ts +0 -2
- package/dist/src/ds/components/StatusBadge/StatusBadge.d.ts +0 -13
- package/dist/src/ds/components/StatusBadge/index.d.ts +0 -2
- package/dist/src/ds/components/StatusBadge/status-badge.stories.d.ts +0 -8
- package/dist/traces-data-list-BLZgf-Es.cjs.map +0 -1
- package/dist/traces-data-list-DmXGwe4Q.js.map +0 -1
|
@@ -9,12 +9,18 @@ require('date-fns');
|
|
|
9
9
|
function useTraceSearch(spans) {
|
|
10
10
|
const [query, setQuery] = React.useState("");
|
|
11
11
|
const deferredQuery = React.useDeferredValue(query);
|
|
12
|
-
const results = React.useMemo(() => {
|
|
12
|
+
const { results, payloadOnlyMatchIds } = React.useMemo(() => {
|
|
13
13
|
const term = deferredQuery.trim().toLowerCase();
|
|
14
|
-
if (!term) return spans;
|
|
15
|
-
|
|
14
|
+
if (!term) return { results: spans, payloadOnlyMatchIds: /* @__PURE__ */ new Set() };
|
|
15
|
+
const payloadOnly = /* @__PURE__ */ new Set();
|
|
16
|
+
const filtered = domains_traces_utils_filterSpansKeepingAncestors.filterSpansKeepingAncestors(spans, (span) => {
|
|
17
|
+
if (!span.searchText.includes(term)) return false;
|
|
18
|
+
if (!span.name.toLowerCase().includes(term)) payloadOnly.add(span.spanId);
|
|
19
|
+
return true;
|
|
20
|
+
});
|
|
21
|
+
return { results: filtered, payloadOnlyMatchIds: payloadOnly };
|
|
16
22
|
}, [spans, deferredQuery]);
|
|
17
|
-
return { query, setQuery, results, isPending: query !== deferredQuery };
|
|
23
|
+
return { query, setQuery, results, payloadOnlyMatchIds, isPending: query !== deferredQuery };
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
exports.useTraceSearch = useTraceSearch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-trace-search.cjs.js","sources":["../../../../src/domains/traces/hooks/use-trace-search.ts"],"sourcesContent":["import { useDeferredValue, useMemo, useState } from 'react';\nimport type { SearchableSpan } from '../types';\nimport { filterSpansKeepingAncestors } from '../utils';\n\nexport interface UseTraceSearchResult {\n /** The immediate, user-facing input value. Bind this to the search field. */\n query: string;\n setQuery: (query: string) => void;\n /** Rows matching the deferred query. An empty query returns the input array reference. */\n results: SearchableSpan[];\n /** True while the deferred value is behind `query` (the list is still catching up). */\n isPending: boolean;\n}\n\n/**\n * Client-side search over a flat span list.\n *\n * Matching is a substring test against `searchText`, the haystack built once per span when\n * the query resolved (see `toSearchableSpans`). That is what makes the open-ended `metadata`\n * and `error` payloads searchable: their shapes are unknown, so no fixed list of fields can\n * read them. Both sides are already lowercased, so the test is a bare `includes`.\n *\n * Filtering is keyed on a deferred copy of the query, so typing stays responsive while a\n * large list re-filters at lower priority — bind the input to `query`, not to the deferred\n * value. A matching span keeps its ancestors and its whole subtree, so the hierarchy stays\n * intact.\n *\n * `spans` is required. Resolving the loading/empty state is the caller's job — a component\n * holding a query result passes `data?.spans ?? []`.\n */\nexport function useTraceSearch(spans: SearchableSpan[]): UseTraceSearchResult {\n const [query, setQuery] = useState('');\n const deferredQuery = useDeferredValue(query);\n\n const results = useMemo(() => {\n const term = deferredQuery.trim().toLowerCase();\n if (!term) return spans;\n
|
|
1
|
+
{"version":3,"file":"use-trace-search.cjs.js","sources":["../../../../src/domains/traces/hooks/use-trace-search.ts"],"sourcesContent":["import { useDeferredValue, useMemo, useState } from 'react';\nimport type { SearchableSpan } from '../types';\nimport { filterSpansKeepingAncestors } from '../utils';\n\nexport interface UseTraceSearchResult {\n /** The immediate, user-facing input value. Bind this to the search field. */\n query: string;\n setQuery: (query: string) => void;\n /** Rows matching the deferred query. An empty query returns the input array reference. */\n results: SearchableSpan[];\n /**\n * Spans that matched somewhere other than their name — in `metadata`, `attributes` or\n * `error`. Their row shows no visible occurrence of the term, so the surface needs to say\n * why it is there. Ancestors kept only to preserve the hierarchy are not in here: they did\n * not match at all. Empty while the query is empty.\n */\n payloadOnlyMatchIds: Set<string>;\n /** True while the deferred value is behind `query` (the list is still catching up). */\n isPending: boolean;\n}\n\n/**\n * Client-side search over a flat span list.\n *\n * Matching is a substring test against `searchText`, the haystack built once per span when\n * the query resolved (see `toSearchableSpans`). That is what makes the open-ended `metadata`\n * and `error` payloads searchable: their shapes are unknown, so no fixed list of fields can\n * read them. Both sides are already lowercased, so the test is a bare `includes`.\n *\n * Filtering is keyed on a deferred copy of the query, so typing stays responsive while a\n * large list re-filters at lower priority — bind the input to `query`, not to the deferred\n * value. A matching span keeps its ancestors and its whole subtree, so the hierarchy stays\n * intact.\n *\n * `spans` is required. Resolving the loading/empty state is the caller's job — a component\n * holding a query result passes `data?.spans ?? []`.\n */\nexport function useTraceSearch(spans: SearchableSpan[]): UseTraceSearchResult {\n const [query, setQuery] = useState('');\n const deferredQuery = useDeferredValue(query);\n\n const { results, payloadOnlyMatchIds } = useMemo(() => {\n const term = deferredQuery.trim().toLowerCase();\n if (!term) return { results: spans, payloadOnlyMatchIds: new Set<string>() };\n\n const payloadOnly = new Set<string>();\n const filtered = filterSpansKeepingAncestors(spans, span => {\n if (!span.searchText.includes(term)) return false;\n // The name is the only part of a span the timeline paints, so a match it doesn't\n // contain came from the payload.\n if (!span.name.toLowerCase().includes(term)) payloadOnly.add(span.spanId);\n return true;\n });\n\n return { results: filtered, payloadOnlyMatchIds: payloadOnly };\n }, [spans, deferredQuery]);\n\n return { query, setQuery, results, payloadOnlyMatchIds, isPending: query !== deferredQuery };\n}\n"],"names":["useState","useDeferredValue","useMemo","filterSpansKeepingAncestors"],"mappings":";;;;;;;;AAqCO,SAAS,eAAe,KAAA,EAA+C;AAC5E,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,EAAE,CAAA;AACrC,EAAA,MAAM,aAAA,GAAgBC,uBAAiB,KAAK,CAAA;AAE5C,EAAA,MAAM,EAAE,OAAA,EAAS,mBAAA,EAAoB,GAAIC,cAAQ,MAAM;AACrD,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,IAAA,EAAK,CAAE,WAAA,EAAY;AAC9C,IAAA,IAAI,CAAC,MAAM,OAAO,EAAE,SAAS,KAAA,EAAO,mBAAA,kBAAqB,IAAI,GAAA,EAAY,EAAE;AAE3E,IAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AACpC,IAAA,MAAM,QAAA,GAAWC,4EAAA,CAA4B,KAAA,EAAO,CAAA,IAAA,KAAQ;AAC1D,MAAA,IAAI,CAAC,IAAA,CAAK,UAAA,CAAW,QAAA,CAAS,IAAI,GAAG,OAAO,KAAA;AAG5C,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAAS,IAAI,CAAA,EAAG,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AACxE,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,OAAO,EAAE,OAAA,EAAS,QAAA,EAAU,mBAAA,EAAqB,WAAA,EAAY;AAAA,EAC/D,CAAA,EAAG,CAAC,KAAA,EAAO,aAAa,CAAC,CAAA;AAEzB,EAAA,OAAO,EAAE,KAAA,EAAO,QAAA,EAAU,SAAS,mBAAA,EAAqB,SAAA,EAAW,UAAU,aAAA,EAAc;AAC7F;;;;"}
|
|
@@ -5,12 +5,18 @@ import 'date-fns';
|
|
|
5
5
|
function useTraceSearch(spans) {
|
|
6
6
|
const [query, setQuery] = useState("");
|
|
7
7
|
const deferredQuery = useDeferredValue(query);
|
|
8
|
-
const results = useMemo(() => {
|
|
8
|
+
const { results, payloadOnlyMatchIds } = useMemo(() => {
|
|
9
9
|
const term = deferredQuery.trim().toLowerCase();
|
|
10
|
-
if (!term) return spans;
|
|
11
|
-
|
|
10
|
+
if (!term) return { results: spans, payloadOnlyMatchIds: /* @__PURE__ */ new Set() };
|
|
11
|
+
const payloadOnly = /* @__PURE__ */ new Set();
|
|
12
|
+
const filtered = filterSpansKeepingAncestors(spans, (span) => {
|
|
13
|
+
if (!span.searchText.includes(term)) return false;
|
|
14
|
+
if (!span.name.toLowerCase().includes(term)) payloadOnly.add(span.spanId);
|
|
15
|
+
return true;
|
|
16
|
+
});
|
|
17
|
+
return { results: filtered, payloadOnlyMatchIds: payloadOnly };
|
|
12
18
|
}, [spans, deferredQuery]);
|
|
13
|
-
return { query, setQuery, results, isPending: query !== deferredQuery };
|
|
19
|
+
return { query, setQuery, results, payloadOnlyMatchIds, isPending: query !== deferredQuery };
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
export { useTraceSearch };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-trace-search.es.js","sources":["../../../../src/domains/traces/hooks/use-trace-search.ts"],"sourcesContent":["import { useDeferredValue, useMemo, useState } from 'react';\nimport type { SearchableSpan } from '../types';\nimport { filterSpansKeepingAncestors } from '../utils';\n\nexport interface UseTraceSearchResult {\n /** The immediate, user-facing input value. Bind this to the search field. */\n query: string;\n setQuery: (query: string) => void;\n /** Rows matching the deferred query. An empty query returns the input array reference. */\n results: SearchableSpan[];\n /** True while the deferred value is behind `query` (the list is still catching up). */\n isPending: boolean;\n}\n\n/**\n * Client-side search over a flat span list.\n *\n * Matching is a substring test against `searchText`, the haystack built once per span when\n * the query resolved (see `toSearchableSpans`). That is what makes the open-ended `metadata`\n * and `error` payloads searchable: their shapes are unknown, so no fixed list of fields can\n * read them. Both sides are already lowercased, so the test is a bare `includes`.\n *\n * Filtering is keyed on a deferred copy of the query, so typing stays responsive while a\n * large list re-filters at lower priority — bind the input to `query`, not to the deferred\n * value. A matching span keeps its ancestors and its whole subtree, so the hierarchy stays\n * intact.\n *\n * `spans` is required. Resolving the loading/empty state is the caller's job — a component\n * holding a query result passes `data?.spans ?? []`.\n */\nexport function useTraceSearch(spans: SearchableSpan[]): UseTraceSearchResult {\n const [query, setQuery] = useState('');\n const deferredQuery = useDeferredValue(query);\n\n const results = useMemo(() => {\n const term = deferredQuery.trim().toLowerCase();\n if (!term) return spans;\n
|
|
1
|
+
{"version":3,"file":"use-trace-search.es.js","sources":["../../../../src/domains/traces/hooks/use-trace-search.ts"],"sourcesContent":["import { useDeferredValue, useMemo, useState } from 'react';\nimport type { SearchableSpan } from '../types';\nimport { filterSpansKeepingAncestors } from '../utils';\n\nexport interface UseTraceSearchResult {\n /** The immediate, user-facing input value. Bind this to the search field. */\n query: string;\n setQuery: (query: string) => void;\n /** Rows matching the deferred query. An empty query returns the input array reference. */\n results: SearchableSpan[];\n /**\n * Spans that matched somewhere other than their name — in `metadata`, `attributes` or\n * `error`. Their row shows no visible occurrence of the term, so the surface needs to say\n * why it is there. Ancestors kept only to preserve the hierarchy are not in here: they did\n * not match at all. Empty while the query is empty.\n */\n payloadOnlyMatchIds: Set<string>;\n /** True while the deferred value is behind `query` (the list is still catching up). */\n isPending: boolean;\n}\n\n/**\n * Client-side search over a flat span list.\n *\n * Matching is a substring test against `searchText`, the haystack built once per span when\n * the query resolved (see `toSearchableSpans`). That is what makes the open-ended `metadata`\n * and `error` payloads searchable: their shapes are unknown, so no fixed list of fields can\n * read them. Both sides are already lowercased, so the test is a bare `includes`.\n *\n * Filtering is keyed on a deferred copy of the query, so typing stays responsive while a\n * large list re-filters at lower priority — bind the input to `query`, not to the deferred\n * value. A matching span keeps its ancestors and its whole subtree, so the hierarchy stays\n * intact.\n *\n * `spans` is required. Resolving the loading/empty state is the caller's job — a component\n * holding a query result passes `data?.spans ?? []`.\n */\nexport function useTraceSearch(spans: SearchableSpan[]): UseTraceSearchResult {\n const [query, setQuery] = useState('');\n const deferredQuery = useDeferredValue(query);\n\n const { results, payloadOnlyMatchIds } = useMemo(() => {\n const term = deferredQuery.trim().toLowerCase();\n if (!term) return { results: spans, payloadOnlyMatchIds: new Set<string>() };\n\n const payloadOnly = new Set<string>();\n const filtered = filterSpansKeepingAncestors(spans, span => {\n if (!span.searchText.includes(term)) return false;\n // The name is the only part of a span the timeline paints, so a match it doesn't\n // contain came from the payload.\n if (!span.name.toLowerCase().includes(term)) payloadOnly.add(span.spanId);\n return true;\n });\n\n return { results: filtered, payloadOnlyMatchIds: payloadOnly };\n }, [spans, deferredQuery]);\n\n return { query, setQuery, results, payloadOnlyMatchIds, isPending: query !== deferredQuery };\n}\n"],"names":[],"mappings":";;;;AAqCO,SAAS,eAAe,KAAA,EAA+C;AAC5E,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA;AACrC,EAAA,MAAM,aAAA,GAAgB,iBAAiB,KAAK,CAAA;AAE5C,EAAA,MAAM,EAAE,OAAA,EAAS,mBAAA,EAAoB,GAAI,QAAQ,MAAM;AACrD,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,IAAA,EAAK,CAAE,WAAA,EAAY;AAC9C,IAAA,IAAI,CAAC,MAAM,OAAO,EAAE,SAAS,KAAA,EAAO,mBAAA,kBAAqB,IAAI,GAAA,EAAY,EAAE;AAE3E,IAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AACpC,IAAA,MAAM,QAAA,GAAW,2BAAA,CAA4B,KAAA,EAAO,CAAA,IAAA,KAAQ;AAC1D,MAAA,IAAI,CAAC,IAAA,CAAK,UAAA,CAAW,QAAA,CAAS,IAAI,GAAG,OAAO,KAAA;AAG5C,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAAS,IAAI,CAAA,EAAG,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AACxE,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,OAAO,EAAE,OAAA,EAAS,QAAA,EAAU,mBAAA,EAAqB,WAAA,EAAY;AAAA,EAC/D,CAAA,EAAG,CAAC,KAAA,EAAO,aAAa,CAAC,CAAA;AAEzB,EAAA,OAAO,EAAE,KAAA,EAAO,QAAA,EAAU,SAAS,mBAAA,EAAqB,SAAA,EAAW,UAAU,aAAA,EAAc;AAC7F;;;;"}
|
|
@@ -58,7 +58,7 @@ function serializeTraceColumnPreferences(preferences) {
|
|
|
58
58
|
}
|
|
59
59
|
function buildTraceListColumns(preferences) {
|
|
60
60
|
const visible = new Set(preferences.visibleColumns);
|
|
61
|
-
const columns = ["
|
|
61
|
+
const columns = ["11rem", visible.has("input") ? "14rem" : "minmax(8rem,1fr)"];
|
|
62
62
|
if (visible.has("input")) columns.push("minmax(8rem,1fr)");
|
|
63
63
|
if (visible.has("entity")) columns.push("14rem");
|
|
64
64
|
columns.push("6rem");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace-list-columns.cjs.js","sources":["../../../src/domains/traces/trace-list-columns.ts"],"sourcesContent":["export const TRACE_OPTIONAL_COLUMNS = [\n 'input',\n 'entity',\n 'duration',\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const;\n\nexport type TraceOptionalColumn = (typeof TRACE_OPTIONAL_COLUMNS)[number];\n\nexport const TRACE_USAGE_COLUMNS = [\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const satisfies readonly TraceOptionalColumn[];\n\nexport type TraceColumnPreferences = {\n readonly visibleColumns: readonly TraceOptionalColumn[];\n readonly metadataKeys: readonly string[];\n};\n\nexport type TraceUsageSummary = {\n inputTokens?: number;\n outputTokens?: number;\n estimatedCost?: number;\n costUnit?: string;\n};\n\nexport const DEFAULT_TRACE_COLUMN_PREFERENCES: TraceColumnPreferences = {\n visibleColumns: ['input', 'entity'],\n metadataKeys: [],\n};\n\nconst TRACE_COLUMN_PREFERENCES_VERSION = 1;\nconst TRACE_COLUMN_SET = new Set<string>(TRACE_OPTIONAL_COLUMNS);\nconst TRACE_USAGE_COLUMN_SET = new Set<TraceOptionalColumn>(TRACE_USAGE_COLUMNS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isTraceOptionalColumn(value: unknown): value is TraceOptionalColumn {\n return typeof value === 'string' && TRACE_COLUMN_SET.has(value);\n}\n\nfunction uniqueMetadataKeys(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n\n const keys = value\n .filter(key => typeof key === 'string')\n .map(key => key.trim())\n .filter(Boolean);\n\n return [...new Set(keys)];\n}\n\nexport function parseTraceColumnPreferences(serialized: string | undefined): TraceColumnPreferences {\n if (!serialized) return DEFAULT_TRACE_COLUMN_PREFERENCES;\n\n try {\n const parsed: unknown = JSON.parse(serialized);\n if (!isRecord(parsed) || parsed.version !== TRACE_COLUMN_PREFERENCES_VERSION) {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n\n const visibleColumns = Array.isArray(parsed.visibleColumns)\n ? [...new Set(parsed.visibleColumns.filter(isTraceOptionalColumn))]\n : [...DEFAULT_TRACE_COLUMN_PREFERENCES.visibleColumns];\n\n return {\n visibleColumns,\n metadataKeys: uniqueMetadataKeys(parsed.metadataKeys),\n };\n } catch {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n}\n\nexport function serializeTraceColumnPreferences(preferences: TraceColumnPreferences): string {\n return JSON.stringify({\n version: TRACE_COLUMN_PREFERENCES_VERSION,\n visibleColumns: preferences.visibleColumns,\n metadataKeys: preferences.metadataKeys,\n });\n}\n\nexport function buildTraceListColumns(preferences: TraceColumnPreferences): string {\n const visible = new Set(preferences.visibleColumns);\n const columns = ['
|
|
1
|
+
{"version":3,"file":"trace-list-columns.cjs.js","sources":["../../../src/domains/traces/trace-list-columns.ts"],"sourcesContent":["export const TRACE_OPTIONAL_COLUMNS = [\n 'input',\n 'entity',\n 'duration',\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const;\n\nexport type TraceOptionalColumn = (typeof TRACE_OPTIONAL_COLUMNS)[number];\n\nexport const TRACE_USAGE_COLUMNS = [\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const satisfies readonly TraceOptionalColumn[];\n\nexport type TraceColumnPreferences = {\n readonly visibleColumns: readonly TraceOptionalColumn[];\n readonly metadataKeys: readonly string[];\n};\n\nexport type TraceUsageSummary = {\n inputTokens?: number;\n outputTokens?: number;\n estimatedCost?: number;\n costUnit?: string;\n};\n\nexport const DEFAULT_TRACE_COLUMN_PREFERENCES: TraceColumnPreferences = {\n visibleColumns: ['input', 'entity'],\n metadataKeys: [],\n};\n\nconst TRACE_COLUMN_PREFERENCES_VERSION = 1;\nconst TRACE_COLUMN_SET = new Set<string>(TRACE_OPTIONAL_COLUMNS);\nconst TRACE_USAGE_COLUMN_SET = new Set<TraceOptionalColumn>(TRACE_USAGE_COLUMNS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isTraceOptionalColumn(value: unknown): value is TraceOptionalColumn {\n return typeof value === 'string' && TRACE_COLUMN_SET.has(value);\n}\n\nfunction uniqueMetadataKeys(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n\n const keys = value\n .filter(key => typeof key === 'string')\n .map(key => key.trim())\n .filter(Boolean);\n\n return [...new Set(keys)];\n}\n\nexport function parseTraceColumnPreferences(serialized: string | undefined): TraceColumnPreferences {\n if (!serialized) return DEFAULT_TRACE_COLUMN_PREFERENCES;\n\n try {\n const parsed: unknown = JSON.parse(serialized);\n if (!isRecord(parsed) || parsed.version !== TRACE_COLUMN_PREFERENCES_VERSION) {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n\n const visibleColumns = Array.isArray(parsed.visibleColumns)\n ? [...new Set(parsed.visibleColumns.filter(isTraceOptionalColumn))]\n : [...DEFAULT_TRACE_COLUMN_PREFERENCES.visibleColumns];\n\n return {\n visibleColumns,\n metadataKeys: uniqueMetadataKeys(parsed.metadataKeys),\n };\n } catch {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n}\n\nexport function serializeTraceColumnPreferences(preferences: TraceColumnPreferences): string {\n return JSON.stringify({\n version: TRACE_COLUMN_PREFERENCES_VERSION,\n visibleColumns: preferences.visibleColumns,\n metadataKeys: preferences.metadataKeys,\n });\n}\n\nexport function buildTraceListColumns(preferences: TraceColumnPreferences): string {\n const visible = new Set(preferences.visibleColumns);\n // Name is bounded when Input is visible so Input (1fr) absorbs the free space;\n // without Input, Name is the flexible track that fills the grid.\n const columns = ['11rem', visible.has('input') ? '14rem' : 'minmax(8rem,1fr)'];\n\n if (visible.has('input')) columns.push('minmax(8rem,1fr)');\n if (visible.has('entity')) columns.push('14rem');\n\n columns.push('6rem');\n\n if (visible.has('duration')) columns.push('7rem');\n if (visible.has('inputTokens')) columns.push('8rem');\n if (visible.has('outputTokens')) columns.push('8rem');\n if (visible.has('estimatedCost')) columns.push('8rem');\n\n for (const _key of preferences.metadataKeys) {\n columns.push('minmax(8rem,14rem)');\n }\n\n return columns.join(' ');\n}\n\nexport function formatTraceMetadataValue(\n metadata: Record<string, unknown> | null | undefined,\n key: string,\n): string | undefined {\n if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, key)) return undefined;\n const value = metadata[key];\n if (value == null) return undefined;\n\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') return String(value);\n\n try {\n return JSON.stringify(value) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function hasTraceColumn(preferences: TraceColumnPreferences, column: TraceOptionalColumn): boolean {\n return preferences.visibleColumns.includes(column);\n}\n\nexport function hasTraceUsageColumn(preferences: TraceColumnPreferences): boolean {\n return preferences.visibleColumns.some(isTraceUsageColumn);\n}\n\nexport function isTraceUsageColumn(column: TraceOptionalColumn): boolean {\n return TRACE_USAGE_COLUMN_SET.has(column);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -54,7 +54,7 @@ function serializeTraceColumnPreferences(preferences) {
|
|
|
54
54
|
}
|
|
55
55
|
function buildTraceListColumns(preferences) {
|
|
56
56
|
const visible = new Set(preferences.visibleColumns);
|
|
57
|
-
const columns = ["
|
|
57
|
+
const columns = ["11rem", visible.has("input") ? "14rem" : "minmax(8rem,1fr)"];
|
|
58
58
|
if (visible.has("input")) columns.push("minmax(8rem,1fr)");
|
|
59
59
|
if (visible.has("entity")) columns.push("14rem");
|
|
60
60
|
columns.push("6rem");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace-list-columns.es.js","sources":["../../../src/domains/traces/trace-list-columns.ts"],"sourcesContent":["export const TRACE_OPTIONAL_COLUMNS = [\n 'input',\n 'entity',\n 'duration',\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const;\n\nexport type TraceOptionalColumn = (typeof TRACE_OPTIONAL_COLUMNS)[number];\n\nexport const TRACE_USAGE_COLUMNS = [\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const satisfies readonly TraceOptionalColumn[];\n\nexport type TraceColumnPreferences = {\n readonly visibleColumns: readonly TraceOptionalColumn[];\n readonly metadataKeys: readonly string[];\n};\n\nexport type TraceUsageSummary = {\n inputTokens?: number;\n outputTokens?: number;\n estimatedCost?: number;\n costUnit?: string;\n};\n\nexport const DEFAULT_TRACE_COLUMN_PREFERENCES: TraceColumnPreferences = {\n visibleColumns: ['input', 'entity'],\n metadataKeys: [],\n};\n\nconst TRACE_COLUMN_PREFERENCES_VERSION = 1;\nconst TRACE_COLUMN_SET = new Set<string>(TRACE_OPTIONAL_COLUMNS);\nconst TRACE_USAGE_COLUMN_SET = new Set<TraceOptionalColumn>(TRACE_USAGE_COLUMNS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isTraceOptionalColumn(value: unknown): value is TraceOptionalColumn {\n return typeof value === 'string' && TRACE_COLUMN_SET.has(value);\n}\n\nfunction uniqueMetadataKeys(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n\n const keys = value\n .filter(key => typeof key === 'string')\n .map(key => key.trim())\n .filter(Boolean);\n\n return [...new Set(keys)];\n}\n\nexport function parseTraceColumnPreferences(serialized: string | undefined): TraceColumnPreferences {\n if (!serialized) return DEFAULT_TRACE_COLUMN_PREFERENCES;\n\n try {\n const parsed: unknown = JSON.parse(serialized);\n if (!isRecord(parsed) || parsed.version !== TRACE_COLUMN_PREFERENCES_VERSION) {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n\n const visibleColumns = Array.isArray(parsed.visibleColumns)\n ? [...new Set(parsed.visibleColumns.filter(isTraceOptionalColumn))]\n : [...DEFAULT_TRACE_COLUMN_PREFERENCES.visibleColumns];\n\n return {\n visibleColumns,\n metadataKeys: uniqueMetadataKeys(parsed.metadataKeys),\n };\n } catch {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n}\n\nexport function serializeTraceColumnPreferences(preferences: TraceColumnPreferences): string {\n return JSON.stringify({\n version: TRACE_COLUMN_PREFERENCES_VERSION,\n visibleColumns: preferences.visibleColumns,\n metadataKeys: preferences.metadataKeys,\n });\n}\n\nexport function buildTraceListColumns(preferences: TraceColumnPreferences): string {\n const visible = new Set(preferences.visibleColumns);\n const columns = ['
|
|
1
|
+
{"version":3,"file":"trace-list-columns.es.js","sources":["../../../src/domains/traces/trace-list-columns.ts"],"sourcesContent":["export const TRACE_OPTIONAL_COLUMNS = [\n 'input',\n 'entity',\n 'duration',\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const;\n\nexport type TraceOptionalColumn = (typeof TRACE_OPTIONAL_COLUMNS)[number];\n\nexport const TRACE_USAGE_COLUMNS = [\n 'inputTokens',\n 'outputTokens',\n 'estimatedCost',\n] as const satisfies readonly TraceOptionalColumn[];\n\nexport type TraceColumnPreferences = {\n readonly visibleColumns: readonly TraceOptionalColumn[];\n readonly metadataKeys: readonly string[];\n};\n\nexport type TraceUsageSummary = {\n inputTokens?: number;\n outputTokens?: number;\n estimatedCost?: number;\n costUnit?: string;\n};\n\nexport const DEFAULT_TRACE_COLUMN_PREFERENCES: TraceColumnPreferences = {\n visibleColumns: ['input', 'entity'],\n metadataKeys: [],\n};\n\nconst TRACE_COLUMN_PREFERENCES_VERSION = 1;\nconst TRACE_COLUMN_SET = new Set<string>(TRACE_OPTIONAL_COLUMNS);\nconst TRACE_USAGE_COLUMN_SET = new Set<TraceOptionalColumn>(TRACE_USAGE_COLUMNS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isTraceOptionalColumn(value: unknown): value is TraceOptionalColumn {\n return typeof value === 'string' && TRACE_COLUMN_SET.has(value);\n}\n\nfunction uniqueMetadataKeys(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n\n const keys = value\n .filter(key => typeof key === 'string')\n .map(key => key.trim())\n .filter(Boolean);\n\n return [...new Set(keys)];\n}\n\nexport function parseTraceColumnPreferences(serialized: string | undefined): TraceColumnPreferences {\n if (!serialized) return DEFAULT_TRACE_COLUMN_PREFERENCES;\n\n try {\n const parsed: unknown = JSON.parse(serialized);\n if (!isRecord(parsed) || parsed.version !== TRACE_COLUMN_PREFERENCES_VERSION) {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n\n const visibleColumns = Array.isArray(parsed.visibleColumns)\n ? [...new Set(parsed.visibleColumns.filter(isTraceOptionalColumn))]\n : [...DEFAULT_TRACE_COLUMN_PREFERENCES.visibleColumns];\n\n return {\n visibleColumns,\n metadataKeys: uniqueMetadataKeys(parsed.metadataKeys),\n };\n } catch {\n return DEFAULT_TRACE_COLUMN_PREFERENCES;\n }\n}\n\nexport function serializeTraceColumnPreferences(preferences: TraceColumnPreferences): string {\n return JSON.stringify({\n version: TRACE_COLUMN_PREFERENCES_VERSION,\n visibleColumns: preferences.visibleColumns,\n metadataKeys: preferences.metadataKeys,\n });\n}\n\nexport function buildTraceListColumns(preferences: TraceColumnPreferences): string {\n const visible = new Set(preferences.visibleColumns);\n // Name is bounded when Input is visible so Input (1fr) absorbs the free space;\n // without Input, Name is the flexible track that fills the grid.\n const columns = ['11rem', visible.has('input') ? '14rem' : 'minmax(8rem,1fr)'];\n\n if (visible.has('input')) columns.push('minmax(8rem,1fr)');\n if (visible.has('entity')) columns.push('14rem');\n\n columns.push('6rem');\n\n if (visible.has('duration')) columns.push('7rem');\n if (visible.has('inputTokens')) columns.push('8rem');\n if (visible.has('outputTokens')) columns.push('8rem');\n if (visible.has('estimatedCost')) columns.push('8rem');\n\n for (const _key of preferences.metadataKeys) {\n columns.push('minmax(8rem,14rem)');\n }\n\n return columns.join(' ');\n}\n\nexport function formatTraceMetadataValue(\n metadata: Record<string, unknown> | null | undefined,\n key: string,\n): string | undefined {\n if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, key)) return undefined;\n const value = metadata[key];\n if (value == null) return undefined;\n\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') return String(value);\n\n try {\n return JSON.stringify(value) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function hasTraceColumn(preferences: TraceColumnPreferences, column: TraceOptionalColumn): boolean {\n return preferences.visibleColumns.includes(column);\n}\n\nexport function hasTraceUsageColumn(preferences: TraceColumnPreferences): boolean {\n return preferences.visibleColumns.some(isTraceUsageColumn);\n}\n\nexport function isTraceUsageColumn(column: TraceOptionalColumn): boolean {\n return TRACE_USAGE_COLUMN_SET.has(column);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../../src/domains/traces/types.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { LightSpanRecord } from '@mastra/core/storage';\nimport type { ReactNode } from 'react';\n\n/**\n * A light span carrying a precomputed haystack of everything it holds.\n *\n * `LightSpanRecord` exposes searchable content across a fixed set of columns\n * plus open-ended payloads whose shape is unknown, so a search cannot read it\n * field by field. `searchText` is that content flattened once — see\n * `flattenToSearchText` — so filtering is a substring test per span instead of\n * a re-walk of every payload on every keystroke.\n *\n * It holds field names as well as values, so a span is findable by the shape of\n * its payload and not only by its content.\n */\nexport type SearchableSpan = LightSpanRecord & {\n searchText: string;\n};\n\nexport type UISpan = {\n id: string;\n name: string;\n type: string;\n latency: number;\n startTime: string;\n endTime?: string;\n spans?: UISpan[];\n parentSpanId?: string | null;\n};\n\nexport type UISpanStyle = {\n icon?: ReactNode;\n color?: string;\n label?: string;\n typePrefix: string;\n};\n\n// -- Trace filtering types ----------------------------------------------------\n\nexport type EntityOptions =\n | { value: string; label: string; type: EntityType.AGENT }\n | { value: string; label: string; type: EntityType.WORKFLOW_RUN }\n | { value: string; label: string; type: 'all' };\n\nexport type TraceDatePreset = 'all' | 'last-24h' | 'last-3d' | 'last-7d' | 'last-14d' | 'last-30d' | 'custom';\n\n/** Tab identifier for SpanDataPanelView. */\nexport type SpanTab = 'details' | 'feedback';\n\n/** Canonical list of context field IDs used for trace filtering and value extraction */\nexport const CONTEXT_FIELD_IDS = [\n 'environment',\n 'serviceName',\n 'source',\n 'scope',\n 'userId',\n 'organizationId',\n 'resourceId',\n 'runId',\n 'sessionId',\n 'threadId',\n 'requestId',\n 'experimentId',\n 'spanType',\n 'entityName',\n 'parentEntityType',\n 'parentEntityId',\n 'parentEntityName',\n 'rootEntityType',\n 'rootEntityId',\n 'rootEntityName',\n] as const;\n"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../../src/domains/traces/types.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { LightSpanRecord } from '@mastra/core/storage';\nimport type { ReactNode } from 'react';\n\n/**\n * A light span carrying a precomputed haystack of everything it holds.\n *\n * `LightSpanRecord` exposes searchable content across a fixed set of columns\n * plus open-ended payloads whose shape is unknown, so a search cannot read it\n * field by field. `searchText` is that content flattened once — see\n * `flattenToSearchText` — so filtering is a substring test per span instead of\n * a re-walk of every payload on every keystroke.\n *\n * It holds field names as well as values, so a span is findable by the shape of\n * its payload and not only by its content.\n */\nexport type SearchableSpan = LightSpanRecord & {\n searchText: string;\n};\n\nexport type UISpan = {\n id: string;\n name: string;\n type: string;\n latency: number;\n startTime: string;\n endTime?: string;\n spans?: UISpan[];\n parentSpanId?: string | null;\n /**\n * Set when the span survived the active search because of its payload, not its name — the\n * timeline paints such a row differently since the term is nowhere on it.\n */\n matchedInPayloadOnly?: boolean;\n};\n\nexport type UISpanStyle = {\n icon?: ReactNode;\n color?: string;\n label?: string;\n typePrefix: string;\n};\n\n// -- Trace filtering types ----------------------------------------------------\n\nexport type EntityOptions =\n | { value: string; label: string; type: EntityType.AGENT }\n | { value: string; label: string; type: EntityType.WORKFLOW_RUN }\n | { value: string; label: string; type: 'all' };\n\nexport type TraceDatePreset = 'all' | 'last-24h' | 'last-3d' | 'last-7d' | 'last-14d' | 'last-30d' | 'custom';\n\n/** Tab identifier for SpanDataPanelView. */\nexport type SpanTab = 'details' | 'feedback';\n\n/** Canonical list of context field IDs used for trace filtering and value extraction */\nexport const CONTEXT_FIELD_IDS = [\n 'environment',\n 'serviceName',\n 'source',\n 'scope',\n 'userId',\n 'organizationId',\n 'resourceId',\n 'runId',\n 'sessionId',\n 'threadId',\n 'requestId',\n 'experimentId',\n 'spanType',\n 'entityName',\n 'parentEntityType',\n 'parentEntityId',\n 'parentEntityName',\n 'rootEntityType',\n 'rootEntityId',\n 'rootEntityName',\n] as const;\n"],"names":[],"mappings":";;;;AAwDO,MAAM,iBAAA,GAAoB;AAAA,EAC/B,aAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.es.js","sources":["../../../src/domains/traces/types.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { LightSpanRecord } from '@mastra/core/storage';\nimport type { ReactNode } from 'react';\n\n/**\n * A light span carrying a precomputed haystack of everything it holds.\n *\n * `LightSpanRecord` exposes searchable content across a fixed set of columns\n * plus open-ended payloads whose shape is unknown, so a search cannot read it\n * field by field. `searchText` is that content flattened once — see\n * `flattenToSearchText` — so filtering is a substring test per span instead of\n * a re-walk of every payload on every keystroke.\n *\n * It holds field names as well as values, so a span is findable by the shape of\n * its payload and not only by its content.\n */\nexport type SearchableSpan = LightSpanRecord & {\n searchText: string;\n};\n\nexport type UISpan = {\n id: string;\n name: string;\n type: string;\n latency: number;\n startTime: string;\n endTime?: string;\n spans?: UISpan[];\n parentSpanId?: string | null;\n};\n\nexport type UISpanStyle = {\n icon?: ReactNode;\n color?: string;\n label?: string;\n typePrefix: string;\n};\n\n// -- Trace filtering types ----------------------------------------------------\n\nexport type EntityOptions =\n | { value: string; label: string; type: EntityType.AGENT }\n | { value: string; label: string; type: EntityType.WORKFLOW_RUN }\n | { value: string; label: string; type: 'all' };\n\nexport type TraceDatePreset = 'all' | 'last-24h' | 'last-3d' | 'last-7d' | 'last-14d' | 'last-30d' | 'custom';\n\n/** Tab identifier for SpanDataPanelView. */\nexport type SpanTab = 'details' | 'feedback';\n\n/** Canonical list of context field IDs used for trace filtering and value extraction */\nexport const CONTEXT_FIELD_IDS = [\n 'environment',\n 'serviceName',\n 'source',\n 'scope',\n 'userId',\n 'organizationId',\n 'resourceId',\n 'runId',\n 'sessionId',\n 'threadId',\n 'requestId',\n 'experimentId',\n 'spanType',\n 'entityName',\n 'parentEntityType',\n 'parentEntityId',\n 'parentEntityName',\n 'rootEntityType',\n 'rootEntityId',\n 'rootEntityName',\n] as const;\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.es.js","sources":["../../../src/domains/traces/types.ts"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport type { LightSpanRecord } from '@mastra/core/storage';\nimport type { ReactNode } from 'react';\n\n/**\n * A light span carrying a precomputed haystack of everything it holds.\n *\n * `LightSpanRecord` exposes searchable content across a fixed set of columns\n * plus open-ended payloads whose shape is unknown, so a search cannot read it\n * field by field. `searchText` is that content flattened once — see\n * `flattenToSearchText` — so filtering is a substring test per span instead of\n * a re-walk of every payload on every keystroke.\n *\n * It holds field names as well as values, so a span is findable by the shape of\n * its payload and not only by its content.\n */\nexport type SearchableSpan = LightSpanRecord & {\n searchText: string;\n};\n\nexport type UISpan = {\n id: string;\n name: string;\n type: string;\n latency: number;\n startTime: string;\n endTime?: string;\n spans?: UISpan[];\n parentSpanId?: string | null;\n /**\n * Set when the span survived the active search because of its payload, not its name — the\n * timeline paints such a row differently since the term is nowhere on it.\n */\n matchedInPayloadOnly?: boolean;\n};\n\nexport type UISpanStyle = {\n icon?: ReactNode;\n color?: string;\n label?: string;\n typePrefix: string;\n};\n\n// -- Trace filtering types ----------------------------------------------------\n\nexport type EntityOptions =\n | { value: string; label: string; type: EntityType.AGENT }\n | { value: string; label: string; type: EntityType.WORKFLOW_RUN }\n | { value: string; label: string; type: 'all' };\n\nexport type TraceDatePreset = 'all' | 'last-24h' | 'last-3d' | 'last-7d' | 'last-14d' | 'last-30d' | 'custom';\n\n/** Tab identifier for SpanDataPanelView. */\nexport type SpanTab = 'details' | 'feedback';\n\n/** Canonical list of context field IDs used for trace filtering and value extraction */\nexport const CONTEXT_FIELD_IDS = [\n 'environment',\n 'serviceName',\n 'source',\n 'scope',\n 'userId',\n 'organizationId',\n 'resourceId',\n 'runId',\n 'sessionId',\n 'threadId',\n 'requestId',\n 'experimentId',\n 'spanType',\n 'entityName',\n 'parentEntityType',\n 'parentEntityId',\n 'parentEntityName',\n 'rootEntityType',\n 'rootEntityId',\n 'rootEntityName',\n] as const;\n"],"names":[],"mappings":"AAwDO,MAAM,iBAAA,GAAoB;AAAA,EAC/B,aAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF;;;;"}
|
|
@@ -7,7 +7,7 @@ const lucideReact = require('lucide-react');
|
|
|
7
7
|
const React = require('react');
|
|
8
8
|
const ee_topics_utils = require('../utils.cjs.js');
|
|
9
9
|
const Button = require('../../../Button-DA5XLUon.cjs');
|
|
10
|
-
const dataList = require('../../../data-list-
|
|
10
|
+
const dataList = require('../../../data-list-CRDewYj9.cjs');
|
|
11
11
|
const useDataListKeyboard = require('../../../use-data-list-keyboard-k5D-WlNX.cjs');
|
|
12
12
|
const inputGroup = require('../../../input-group-4EQi2l7H.cjs');
|
|
13
13
|
|
|
@@ -3,7 +3,7 @@ import { SearchIcon } from 'lucide-react';
|
|
|
3
3
|
import { useState, useMemo } from 'react';
|
|
4
4
|
import { getVisibleTraceSummaries } from '../utils.es.js';
|
|
5
5
|
import { B as Button } from '../../../Button-vr_I4iME.js';
|
|
6
|
-
import { D as DataList } from '../../../data-list-
|
|
6
|
+
import { D as DataList } from '../../../data-list-C3tjx5Vb.js';
|
|
7
7
|
import { u as useDataListKeyboard } from '../../../use-data-list-keyboard-BzZmvqE_.js';
|
|
8
8
|
import { I as InputGroup, a as InputGroupAddon, c as InputGroupInput } from '../../../input-group-U2f3A4Ya.js';
|
|
9
9
|
|
|
@@ -6,8 +6,10 @@ require('../use-text-highlight.css');const React = require('react');
|
|
|
6
6
|
const hooks_useIsomorphicLayoutEffect = require('./use-isomorphic-layout-effect.cjs.js');
|
|
7
7
|
|
|
8
8
|
const HIGHLIGHT_NAME = "search-result";
|
|
9
|
+
const INDIRECT_HIGHLIGHT_NAME = "search-result-indirect";
|
|
9
10
|
const MIN_SEARCH_LENGTH = 2;
|
|
10
11
|
const INCLUDED_SELECTOR = "[data-highlight]";
|
|
12
|
+
const INDIRECT_SELECTOR = "[data-highlight-indirect]";
|
|
11
13
|
function escapeRegExp(value) {
|
|
12
14
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13
15
|
}
|
|
@@ -16,20 +18,36 @@ function useTextHighlight(search) {
|
|
|
16
18
|
hooks_useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
17
19
|
if (!root || search.trim().length < MIN_SEARCH_LENGTH || typeof CSS === "undefined" || !("highlights" in CSS) || typeof StaticRange === "undefined") {
|
|
18
20
|
CSS?.highlights?.delete(HIGHLIGHT_NAME);
|
|
21
|
+
CSS?.highlights?.delete(INDIRECT_HIGHLIGHT_NAME);
|
|
19
22
|
return;
|
|
20
23
|
}
|
|
21
24
|
let animationFrame = null;
|
|
22
25
|
const updateHighlight = () => {
|
|
23
26
|
const ranges = [];
|
|
27
|
+
const indirectRanges = [];
|
|
24
28
|
const regex = new RegExp(escapeRegExp(search), "giu");
|
|
25
29
|
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
26
30
|
acceptNode(node) {
|
|
27
31
|
const parent = node.parentElement;
|
|
28
|
-
return parent.closest(INCLUDED_SELECTOR) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
|
|
32
|
+
return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
|
|
29
33
|
}
|
|
30
34
|
});
|
|
31
35
|
while (walker.nextNode()) {
|
|
32
36
|
const textNode = walker.currentNode;
|
|
37
|
+
const parent = textNode.parentElement;
|
|
38
|
+
if (parent.closest(INDIRECT_SELECTOR)) {
|
|
39
|
+
if (textNode.data.length > 0) {
|
|
40
|
+
indirectRanges.push(
|
|
41
|
+
new StaticRange({
|
|
42
|
+
startContainer: textNode,
|
|
43
|
+
startOffset: 0,
|
|
44
|
+
endContainer: textNode,
|
|
45
|
+
endOffset: textNode.data.length
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
33
51
|
regex.lastIndex = 0;
|
|
34
52
|
let match;
|
|
35
53
|
while ((match = regex.exec(textNode.data)) !== null) {
|
|
@@ -44,6 +62,7 @@ function useTextHighlight(search) {
|
|
|
44
62
|
}
|
|
45
63
|
}
|
|
46
64
|
CSS.highlights.set(HIGHLIGHT_NAME, new Highlight(...ranges));
|
|
65
|
+
CSS.highlights.set(INDIRECT_HIGHLIGHT_NAME, new Highlight(...indirectRanges));
|
|
47
66
|
};
|
|
48
67
|
const scheduleUpdate = () => {
|
|
49
68
|
if (animationFrame !== null) cancelAnimationFrame(animationFrame);
|
|
@@ -54,11 +73,18 @@ function useTextHighlight(search) {
|
|
|
54
73
|
};
|
|
55
74
|
updateHighlight();
|
|
56
75
|
const observer = new MutationObserver(scheduleUpdate);
|
|
57
|
-
observer.observe(root, {
|
|
76
|
+
observer.observe(root, {
|
|
77
|
+
subtree: true,
|
|
78
|
+
childList: true,
|
|
79
|
+
characterData: true,
|
|
80
|
+
attributes: true,
|
|
81
|
+
attributeFilter: ["data-highlight", "data-highlight-indirect"]
|
|
82
|
+
});
|
|
58
83
|
return () => {
|
|
59
84
|
observer.disconnect();
|
|
60
85
|
if (animationFrame !== null) cancelAnimationFrame(animationFrame);
|
|
61
86
|
CSS.highlights.delete(HIGHLIGHT_NAME);
|
|
87
|
+
CSS.highlights.delete(INDIRECT_HIGHLIGHT_NAME);
|
|
62
88
|
};
|
|
63
89
|
}, [root, search]);
|
|
64
90
|
return { ref: setRoot };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-text-highlight.cjs.js","sources":["../../src/hooks/use-text-highlight.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\nimport './use-text-highlight.css';\n\n/** Single registry entry, so only one search surface can be highlighted at a time. */\nconst HIGHLIGHT_NAME = 'search-result';\n\n/**\n * A single character matches almost everywhere, which paints noise instead of results.\n * Highlighting only starts once the term is discriminating enough.\n */\nconst MIN_SEARCH_LENGTH = 2;\n\n/**\n * Opt-in marker: only text inside a `data-highlight` subtree can be painted. Highlighting\n * is a claim about which text is searchable, so surfaces state it explicitly rather than\n * having every piece of surrounding chrome remember to opt out.\n */\nconst INCLUDED_SELECTOR = '[data-highlight]';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface UseTextHighlightResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n}\n\n/**\n * Paints every occurrence of `search` inside the referenced subtree using the CSS Custom\n * Highlight API. Only text under an element carrying `data-highlight` is painted, so a\n * surface names its searchable regions and everything else — headers, labels, metadata —\n * is left alone by default. The DOM is never mutated — no wrapper elements are injected — so text\n * selection, copy/paste and virtualised renderers are unaffected. Styling lives in\n * `use-text-highlight.css` (`::highlight(search-result)`).\n *\n * Terms shorter than two characters are ignored — they match too much to be useful.\n * Matching is case-insensitive and literal (the term is escaped, not a pattern). The\n * subtree is re-scanned on content changes, coalesced to one scan per frame. Browsers\n * without the API simply render nothing highlighted.\n */\nexport function useTextHighlight<TElement extends HTMLElement = HTMLElement>(\n search: string,\n): UseTextHighlightResult<TElement> {\n const [root, setRoot] = useState<TElement | null>(null);\n\n useIsomorphicLayoutEffect(() => {\n if (\n !root ||\n search.trim().length < MIN_SEARCH_LENGTH ||\n typeof CSS === 'undefined' ||\n !('highlights' in CSS) ||\n typeof StaticRange === 'undefined'\n ) {\n CSS?.highlights?.delete(HIGHLIGHT_NAME);\n return;\n }\n\n let animationFrame: number | null = null;\n\n const updateHighlight = () => {\n const ranges: StaticRange[] = [];\n const regex = new RegExp(escapeRegExp(search), 'giu');\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n // Inside a rooted walker every text node has a parent element.\n const parent = node.parentElement as HTMLElement;\n return parent.closest(INCLUDED_SELECTOR)
|
|
1
|
+
{"version":3,"file":"use-text-highlight.cjs.js","sources":["../../src/hooks/use-text-highlight.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\nimport './use-text-highlight.css';\n\n/** Single registry entry, so only one search surface can be highlighted at a time. */\nconst HIGHLIGHT_NAME = 'search-result';\n\n/**\n * Second registry entry for text that carries no occurrence of the term itself, but stands\n * for something elsewhere that does — a span name whose match hides in its metadata. Painted\n * in its own color so the two claims stay distinguishable.\n */\nconst INDIRECT_HIGHLIGHT_NAME = 'search-result-indirect';\n\n/**\n * A single character matches almost everywhere, which paints noise instead of results.\n * Highlighting only starts once the term is discriminating enough.\n */\nconst MIN_SEARCH_LENGTH = 2;\n\n/**\n * Opt-in marker: only text inside a `data-highlight` subtree can be painted. Highlighting\n * is a claim about which text is searchable, so surfaces state it explicitly rather than\n * having every piece of surrounding chrome remember to opt out.\n */\nconst INCLUDED_SELECTOR = '[data-highlight]';\n\n/**\n * Opt-in marker for the indirect highlight: the whole text of such a subtree is painted\n * while a query is active, regardless of what the term is. Marking is the caller's decision\n * — it knows why the row survived the filter, this hook only knows the term.\n */\nconst INDIRECT_SELECTOR = '[data-highlight-indirect]';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface UseTextHighlightResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n}\n\n/**\n * Paints every occurrence of `search` inside the referenced subtree using the CSS Custom\n * Highlight API. Only text under an element carrying `data-highlight` is painted, so a\n * surface names its searchable regions and everything else — headers, labels, metadata —\n * is left alone by default. The DOM is never mutated — no wrapper elements are injected — so text\n * selection, copy/paste and virtualised renderers are unaffected. Styling lives in\n * `use-text-highlight.css` (`::highlight(search-result)`).\n *\n * Text under `data-highlight-indirect` is painted in full, in a second color\n * (`::highlight(search-result-indirect)`), whatever the term is. That is for labels standing\n * in for a match that lives somewhere not on screen — a span name whose hit is in its\n * metadata. It wins over `data-highlight` when both apply, so a text is never painted twice.\n *\n * Terms shorter than two characters are ignored — they match too much to be useful.\n * Matching is case-insensitive and literal (the term is escaped, not a pattern). The\n * subtree is re-scanned on content changes, coalesced to one scan per frame. Browsers\n * without the API simply render nothing highlighted.\n */\nexport function useTextHighlight<TElement extends HTMLElement = HTMLElement>(\n search: string,\n): UseTextHighlightResult<TElement> {\n const [root, setRoot] = useState<TElement | null>(null);\n\n useIsomorphicLayoutEffect(() => {\n if (\n !root ||\n search.trim().length < MIN_SEARCH_LENGTH ||\n typeof CSS === 'undefined' ||\n !('highlights' in CSS) ||\n typeof StaticRange === 'undefined'\n ) {\n CSS?.highlights?.delete(HIGHLIGHT_NAME);\n CSS?.highlights?.delete(INDIRECT_HIGHLIGHT_NAME);\n return;\n }\n\n let animationFrame: number | null = null;\n\n const updateHighlight = () => {\n const ranges: StaticRange[] = [];\n const indirectRanges: StaticRange[] = [];\n const regex = new RegExp(escapeRegExp(search), 'giu');\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n // Inside a rooted walker every text node has a parent element.\n const parent = node.parentElement as HTMLElement;\n return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`)\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_REJECT;\n },\n });\n\n while (walker.nextNode()) {\n const textNode = walker.currentNode as Text;\n const parent = textNode.parentElement as HTMLElement;\n\n // The indirect claim is about the whole text, so there is nothing to search for\n // inside it: the term lives in the payload this text stands for, not in the text.\n if (parent.closest(INDIRECT_SELECTOR)) {\n if (textNode.data.length > 0) {\n indirectRanges.push(\n new StaticRange({\n startContainer: textNode,\n startOffset: 0,\n endContainer: textNode,\n endOffset: textNode.data.length,\n }),\n );\n }\n continue;\n }\n\n regex.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(textNode.data)) !== null) {\n ranges.push(\n new StaticRange({\n startContainer: textNode,\n startOffset: match.index,\n endContainer: textNode,\n endOffset: match.index + match[0].length,\n }),\n );\n }\n }\n\n CSS.highlights.set(HIGHLIGHT_NAME, new Highlight(...ranges));\n CSS.highlights.set(INDIRECT_HIGHLIGHT_NAME, new Highlight(...indirectRanges));\n };\n\n const scheduleUpdate = () => {\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n\n animationFrame = requestAnimationFrame(() => {\n animationFrame = null;\n updateHighlight();\n });\n };\n\n updateHighlight();\n\n // The opt-in attributes are watched too: a region can change which highlight it claims\n // while its text stays put, and that alone must repaint it.\n const observer = new MutationObserver(scheduleUpdate);\n observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['data-highlight', 'data-highlight-indirect'],\n });\n\n return () => {\n observer.disconnect();\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n CSS.highlights.delete(HIGHLIGHT_NAME);\n CSS.highlights.delete(INDIRECT_HIGHLIGHT_NAME);\n };\n }, [root, search]);\n\n return { ref: setRoot };\n}\n"],"names":["useState","useIsomorphicLayoutEffect"],"mappings":"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"}
|
|
@@ -2,8 +2,10 @@ import { useState } from 'react';
|
|
|
2
2
|
import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect.es.js';
|
|
3
3
|
|
|
4
4
|
import '../use-text-highlight.css';const HIGHLIGHT_NAME = "search-result";
|
|
5
|
+
const INDIRECT_HIGHLIGHT_NAME = "search-result-indirect";
|
|
5
6
|
const MIN_SEARCH_LENGTH = 2;
|
|
6
7
|
const INCLUDED_SELECTOR = "[data-highlight]";
|
|
8
|
+
const INDIRECT_SELECTOR = "[data-highlight-indirect]";
|
|
7
9
|
function escapeRegExp(value) {
|
|
8
10
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9
11
|
}
|
|
@@ -12,20 +14,36 @@ function useTextHighlight(search) {
|
|
|
12
14
|
useIsomorphicLayoutEffect(() => {
|
|
13
15
|
if (!root || search.trim().length < MIN_SEARCH_LENGTH || typeof CSS === "undefined" || !("highlights" in CSS) || typeof StaticRange === "undefined") {
|
|
14
16
|
CSS?.highlights?.delete(HIGHLIGHT_NAME);
|
|
17
|
+
CSS?.highlights?.delete(INDIRECT_HIGHLIGHT_NAME);
|
|
15
18
|
return;
|
|
16
19
|
}
|
|
17
20
|
let animationFrame = null;
|
|
18
21
|
const updateHighlight = () => {
|
|
19
22
|
const ranges = [];
|
|
23
|
+
const indirectRanges = [];
|
|
20
24
|
const regex = new RegExp(escapeRegExp(search), "giu");
|
|
21
25
|
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
22
26
|
acceptNode(node) {
|
|
23
27
|
const parent = node.parentElement;
|
|
24
|
-
return parent.closest(INCLUDED_SELECTOR) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
|
|
28
|
+
return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
|
|
25
29
|
}
|
|
26
30
|
});
|
|
27
31
|
while (walker.nextNode()) {
|
|
28
32
|
const textNode = walker.currentNode;
|
|
33
|
+
const parent = textNode.parentElement;
|
|
34
|
+
if (parent.closest(INDIRECT_SELECTOR)) {
|
|
35
|
+
if (textNode.data.length > 0) {
|
|
36
|
+
indirectRanges.push(
|
|
37
|
+
new StaticRange({
|
|
38
|
+
startContainer: textNode,
|
|
39
|
+
startOffset: 0,
|
|
40
|
+
endContainer: textNode,
|
|
41
|
+
endOffset: textNode.data.length
|
|
42
|
+
})
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
29
47
|
regex.lastIndex = 0;
|
|
30
48
|
let match;
|
|
31
49
|
while ((match = regex.exec(textNode.data)) !== null) {
|
|
@@ -40,6 +58,7 @@ function useTextHighlight(search) {
|
|
|
40
58
|
}
|
|
41
59
|
}
|
|
42
60
|
CSS.highlights.set(HIGHLIGHT_NAME, new Highlight(...ranges));
|
|
61
|
+
CSS.highlights.set(INDIRECT_HIGHLIGHT_NAME, new Highlight(...indirectRanges));
|
|
43
62
|
};
|
|
44
63
|
const scheduleUpdate = () => {
|
|
45
64
|
if (animationFrame !== null) cancelAnimationFrame(animationFrame);
|
|
@@ -50,11 +69,18 @@ function useTextHighlight(search) {
|
|
|
50
69
|
};
|
|
51
70
|
updateHighlight();
|
|
52
71
|
const observer = new MutationObserver(scheduleUpdate);
|
|
53
|
-
observer.observe(root, {
|
|
72
|
+
observer.observe(root, {
|
|
73
|
+
subtree: true,
|
|
74
|
+
childList: true,
|
|
75
|
+
characterData: true,
|
|
76
|
+
attributes: true,
|
|
77
|
+
attributeFilter: ["data-highlight", "data-highlight-indirect"]
|
|
78
|
+
});
|
|
54
79
|
return () => {
|
|
55
80
|
observer.disconnect();
|
|
56
81
|
if (animationFrame !== null) cancelAnimationFrame(animationFrame);
|
|
57
82
|
CSS.highlights.delete(HIGHLIGHT_NAME);
|
|
83
|
+
CSS.highlights.delete(INDIRECT_HIGHLIGHT_NAME);
|
|
58
84
|
};
|
|
59
85
|
}, [root, search]);
|
|
60
86
|
return { ref: setRoot };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-text-highlight.es.js","sources":["../../src/hooks/use-text-highlight.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\nimport './use-text-highlight.css';\n\n/** Single registry entry, so only one search surface can be highlighted at a time. */\nconst HIGHLIGHT_NAME = 'search-result';\n\n/**\n * A single character matches almost everywhere, which paints noise instead of results.\n * Highlighting only starts once the term is discriminating enough.\n */\nconst MIN_SEARCH_LENGTH = 2;\n\n/**\n * Opt-in marker: only text inside a `data-highlight` subtree can be painted. Highlighting\n * is a claim about which text is searchable, so surfaces state it explicitly rather than\n * having every piece of surrounding chrome remember to opt out.\n */\nconst INCLUDED_SELECTOR = '[data-highlight]';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface UseTextHighlightResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n}\n\n/**\n * Paints every occurrence of `search` inside the referenced subtree using the CSS Custom\n * Highlight API. Only text under an element carrying `data-highlight` is painted, so a\n * surface names its searchable regions and everything else — headers, labels, metadata —\n * is left alone by default. The DOM is never mutated — no wrapper elements are injected — so text\n * selection, copy/paste and virtualised renderers are unaffected. Styling lives in\n * `use-text-highlight.css` (`::highlight(search-result)`).\n *\n * Terms shorter than two characters are ignored — they match too much to be useful.\n * Matching is case-insensitive and literal (the term is escaped, not a pattern). The\n * subtree is re-scanned on content changes, coalesced to one scan per frame. Browsers\n * without the API simply render nothing highlighted.\n */\nexport function useTextHighlight<TElement extends HTMLElement = HTMLElement>(\n search: string,\n): UseTextHighlightResult<TElement> {\n const [root, setRoot] = useState<TElement | null>(null);\n\n useIsomorphicLayoutEffect(() => {\n if (\n !root ||\n search.trim().length < MIN_SEARCH_LENGTH ||\n typeof CSS === 'undefined' ||\n !('highlights' in CSS) ||\n typeof StaticRange === 'undefined'\n ) {\n CSS?.highlights?.delete(HIGHLIGHT_NAME);\n return;\n }\n\n let animationFrame: number | null = null;\n\n const updateHighlight = () => {\n const ranges: StaticRange[] = [];\n const regex = new RegExp(escapeRegExp(search), 'giu');\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n // Inside a rooted walker every text node has a parent element.\n const parent = node.parentElement as HTMLElement;\n return parent.closest(INCLUDED_SELECTOR)
|
|
1
|
+
{"version":3,"file":"use-text-highlight.es.js","sources":["../../src/hooks/use-text-highlight.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\nimport './use-text-highlight.css';\n\n/** Single registry entry, so only one search surface can be highlighted at a time. */\nconst HIGHLIGHT_NAME = 'search-result';\n\n/**\n * Second registry entry for text that carries no occurrence of the term itself, but stands\n * for something elsewhere that does — a span name whose match hides in its metadata. Painted\n * in its own color so the two claims stay distinguishable.\n */\nconst INDIRECT_HIGHLIGHT_NAME = 'search-result-indirect';\n\n/**\n * A single character matches almost everywhere, which paints noise instead of results.\n * Highlighting only starts once the term is discriminating enough.\n */\nconst MIN_SEARCH_LENGTH = 2;\n\n/**\n * Opt-in marker: only text inside a `data-highlight` subtree can be painted. Highlighting\n * is a claim about which text is searchable, so surfaces state it explicitly rather than\n * having every piece of surrounding chrome remember to opt out.\n */\nconst INCLUDED_SELECTOR = '[data-highlight]';\n\n/**\n * Opt-in marker for the indirect highlight: the whole text of such a subtree is painted\n * while a query is active, regardless of what the term is. Marking is the caller's decision\n * — it knows why the row survived the filter, this hook only knows the term.\n */\nconst INDIRECT_SELECTOR = '[data-highlight-indirect]';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface UseTextHighlightResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n}\n\n/**\n * Paints every occurrence of `search` inside the referenced subtree using the CSS Custom\n * Highlight API. Only text under an element carrying `data-highlight` is painted, so a\n * surface names its searchable regions and everything else — headers, labels, metadata —\n * is left alone by default. The DOM is never mutated — no wrapper elements are injected — so text\n * selection, copy/paste and virtualised renderers are unaffected. Styling lives in\n * `use-text-highlight.css` (`::highlight(search-result)`).\n *\n * Text under `data-highlight-indirect` is painted in full, in a second color\n * (`::highlight(search-result-indirect)`), whatever the term is. That is for labels standing\n * in for a match that lives somewhere not on screen — a span name whose hit is in its\n * metadata. It wins over `data-highlight` when both apply, so a text is never painted twice.\n *\n * Terms shorter than two characters are ignored — they match too much to be useful.\n * Matching is case-insensitive and literal (the term is escaped, not a pattern). The\n * subtree is re-scanned on content changes, coalesced to one scan per frame. Browsers\n * without the API simply render nothing highlighted.\n */\nexport function useTextHighlight<TElement extends HTMLElement = HTMLElement>(\n search: string,\n): UseTextHighlightResult<TElement> {\n const [root, setRoot] = useState<TElement | null>(null);\n\n useIsomorphicLayoutEffect(() => {\n if (\n !root ||\n search.trim().length < MIN_SEARCH_LENGTH ||\n typeof CSS === 'undefined' ||\n !('highlights' in CSS) ||\n typeof StaticRange === 'undefined'\n ) {\n CSS?.highlights?.delete(HIGHLIGHT_NAME);\n CSS?.highlights?.delete(INDIRECT_HIGHLIGHT_NAME);\n return;\n }\n\n let animationFrame: number | null = null;\n\n const updateHighlight = () => {\n const ranges: StaticRange[] = [];\n const indirectRanges: StaticRange[] = [];\n const regex = new RegExp(escapeRegExp(search), 'giu');\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n // Inside a rooted walker every text node has a parent element.\n const parent = node.parentElement as HTMLElement;\n return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`)\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_REJECT;\n },\n });\n\n while (walker.nextNode()) {\n const textNode = walker.currentNode as Text;\n const parent = textNode.parentElement as HTMLElement;\n\n // The indirect claim is about the whole text, so there is nothing to search for\n // inside it: the term lives in the payload this text stands for, not in the text.\n if (parent.closest(INDIRECT_SELECTOR)) {\n if (textNode.data.length > 0) {\n indirectRanges.push(\n new StaticRange({\n startContainer: textNode,\n startOffset: 0,\n endContainer: textNode,\n endOffset: textNode.data.length,\n }),\n );\n }\n continue;\n }\n\n regex.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(textNode.data)) !== null) {\n ranges.push(\n new StaticRange({\n startContainer: textNode,\n startOffset: match.index,\n endContainer: textNode,\n endOffset: match.index + match[0].length,\n }),\n );\n }\n }\n\n CSS.highlights.set(HIGHLIGHT_NAME, new Highlight(...ranges));\n CSS.highlights.set(INDIRECT_HIGHLIGHT_NAME, new Highlight(...indirectRanges));\n };\n\n const scheduleUpdate = () => {\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n\n animationFrame = requestAnimationFrame(() => {\n animationFrame = null;\n updateHighlight();\n });\n };\n\n updateHighlight();\n\n // The opt-in attributes are watched too: a region can change which highlight it claims\n // while its text stays put, and that alone must repaint it.\n const observer = new MutationObserver(scheduleUpdate);\n observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['data-highlight', 'data-highlight-indirect'],\n });\n\n return () => {\n observer.disconnect();\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n CSS.highlights.delete(HIGHLIGHT_NAME);\n CSS.highlights.delete(INDIRECT_HIGHLIGHT_NAME);\n };\n }, [root, search]);\n\n return { ref: setRoot };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const dataListTopCell = require('./data-list-top-cell-
|
|
3
|
+
const dataListTopCell = require('./data-list-top-cell-DAztx3m8.cjs');
|
|
4
4
|
const jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
const icons_AgentIcon = require('./icons/AgentIcon.cjs.js');
|
|
6
6
|
const icons_ToolsIcon = require('./icons/ToolsIcon.cjs.js');
|
|
@@ -78,4 +78,4 @@ const LogsDataList = Object.assign(dataListTopCell.DataListRoot, {
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
exports.LogsDataList = LogsDataList;
|
|
81
|
-
//# sourceMappingURL=logs-data-list-
|
|
81
|
+
//# sourceMappingURL=logs-data-list-D88JF2lo.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-data-list-
|
|
1
|
+
{"version":3,"file":"logs-data-list-D88JF2lo.cjs","sources":["../src/ds/components/LogsDataList/logs-data-list-cells.tsx","../src/ds/components/LogsDataList/logs-data-list.tsx"],"sourcesContent":["import { DataListCell, DataListTextCell } from '../DataList/data-list-cells';\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';\nimport { AgentIcon } from '@/ds/icons/AgentIcon';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { WorkflowIcon } from '@/ds/icons/WorkflowIcon';\nimport { cn } from '@/lib/utils';\n\nconst LEVEL_CONFIG: Record<LogLevel, { label: string; color: string }> = {\n debug: { label: 'DEBUG', color: '#71717a' },\n info: { label: 'INFO', color: '#60a5fa' },\n warn: { label: 'WARN', color: '#facc15' },\n error: { label: 'ERROR', color: '#f87171' },\n fatal: { label: 'FATAL', color: '#dc2626' },\n};\n\n// ---------------------------------------------------------------------------\n// LevelCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListLevelCellProps {\n level: LogLevel;\n}\n\nexport function LogsDataListLevelCell({ level }: LogsDataListLevelCellProps) {\n const config = LEVEL_CONFIG[level];\n\n return (\n <DataListCell>\n <span className=\"text-ui-sm font-semibold uppercase\" style={{ color: config.color }}>\n {config.label}\n </span>\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// EntityCell\n// ---------------------------------------------------------------------------\n\nfunction EntityTypeIcon({ entityType, className }: { entityType: string; className?: string }) {\n const iconClass = cn('size-3.5 shrink-0 text-neutral2', className);\n const normalizedEntityType = entityType.toLowerCase();\n\n switch (normalizedEntityType) {\n case 'agent':\n return <AgentIcon className={iconClass} aria-hidden />;\n case 'workflow':\n case 'workflow_run':\n return <WorkflowIcon className={iconClass} aria-hidden />;\n case 'tool':\n return <ToolsIcon className={iconClass} aria-hidden />;\n default:\n return null;\n }\n}\n\nexport interface LogsDataListEntityCellProps {\n entityType?: string | null;\n entityName?: string | null;\n}\n\nexport function LogsDataListEntityCell({ entityType, entityName }: LogsDataListEntityCellProps) {\n const type = entityType ?? '';\n\n return (\n <DataListCell className=\"flex min-w-0 items-center gap-2\">\n <EntityTypeIcon entityType={type} />\n {entityName ? <span className=\"text-ui-smd min-w-0 truncate\">{entityName}</span> : '-'}\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// MessageCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListMessageCellProps {\n message: string;\n}\n\nexport function LogsDataListMessageCell({ message }: LogsDataListMessageCellProps) {\n return <DataListCell className=\"text-ui-smd text-neutral4 min-w-0 truncate font-mono\">{message}</DataListCell>;\n}\n\n// ---------------------------------------------------------------------------\n// DataCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListDataCellProps {\n data?: Record<string, unknown> | null;\n}\n\nexport function LogsDataListDataCell({ data }: LogsDataListDataCellProps) {\n if (!data || Object.keys(data).length === 0) {\n return <DataListCell>{null}</DataListCell>;\n }\n\n const summary = Object.entries(data)\n .map(([k, v]) => {\n if (typeof v === 'string') return `${k}: ${v}`;\n try {\n return `${k}: ${JSON.stringify(v)}`;\n } catch {\n return `${k}: <unserializable>`;\n }\n })\n .join(', ');\n\n return <DataListTextCell font=\"mono\">{summary}</DataListTextCell>;\n}\n","import { DataListDateCell, DataListTimeCell } from '../DataList/data-list-cells';\nimport { DataListNextPageLoading } from '../DataList/data-list-next-page-loading';\nimport { DataListNoMatch } from '../DataList/data-list-no-match';\nimport { DataListRoot } from '../DataList/data-list-root';\nimport { DataListRowButton } from '../DataList/data-list-row-button';\nimport { DataListRowLink } from '../DataList/data-list-row-link';\nimport { DataListRowWrapper } from '../DataList/data-list-row-wrapper';\nimport { DataListSpacer } from '../DataList/data-list-spacer';\nimport { DataListTop } from '../DataList/data-list-top';\nimport { DataListTopCell, DataListTopCellWithTooltip, DataListTopCellSmart } from '../DataList/data-list-top-cell';\nimport {\n LogsDataListLevelCell,\n LogsDataListEntityCell,\n LogsDataListMessageCell,\n LogsDataListDataCell,\n} from './logs-data-list-cells';\n\nexport const LogsDataList = Object.assign(DataListRoot, {\n Top: DataListTop,\n TopCell: DataListTopCell,\n TopCellWithTooltip: DataListTopCellWithTooltip,\n TopCellSmart: DataListTopCellSmart,\n RowWrapper: DataListRowWrapper,\n RowButton: DataListRowButton,\n RowLink: DataListRowLink,\n Spacer: DataListSpacer,\n NoMatch: DataListNoMatch,\n DateCell: DataListDateCell,\n TimeCell: DataListTimeCell,\n LevelCell: LogsDataListLevelCell,\n EntityCell: LogsDataListEntityCell,\n MessageCell: LogsDataListMessageCell,\n DataCell: LogsDataListDataCell,\n NextPageLoading: DataListNextPageLoading,\n});\n"],"names":["jsx","DataListCell","cn","AgentIcon","WorkflowIcon","ToolsIcon","jsxs","DataListTextCell","DataListRoot","DataListTop","DataListTopCell","DataListTopCellWithTooltip","DataListTopCellSmart","DataListRowWrapper","DataListRowButton","DataListRowLink","DataListSpacer","DataListNoMatch","DataListDateCell","DataListTimeCell","DataListNextPageLoading"],"mappings":";;;;;;;;;AAOA,MAAM,YAAA,GAAmE;AAAA,EACvE,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA,EAAU;AAAA,EAC1C,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAO,SAAA,EAAU;AAAA,EACxC,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAO,SAAA,EAAU;AAAA,EACxC,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA,EAAU;AAAA,EAC1C,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA;AAClC,CAAA;AAUO,SAAS,qBAAA,CAAsB,EAAE,KAAA,EAAM,EAA+B;AAC3E,EAAA,MAAM,MAAA,GAAS,aAAa,KAAK,CAAA;AAEjC,EAAA,uBACEA,cAAA,CAACC,4BAAA,EAAA,EACC,QAAA,kBAAAD,cAAA,CAAC,MAAA,EAAA,EAAK,WAAU,oCAAA,EAAqC,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAM,EAC/E,QAAA,EAAA,MAAA,CAAO,OACV,CAAA,EACF,CAAA;AAEJ;AAMA,SAAS,cAAA,CAAe,EAAE,UAAA,EAAY,SAAA,EAAU,EAA+C;AAC7F,EAAA,MAAM,SAAA,GAAYE,WAAA,CAAG,iCAAA,EAAmC,SAAS,CAAA;AACjE,EAAA,MAAM,oBAAA,GAAuB,WAAW,WAAA,EAAY;AAEpD,EAAA,QAAQ,oBAAA;AAAsB,IAC5B,KAAK,OAAA;AACH,MAAA,uBAAOF,cAAA,CAACG,yBAAA,EAAA,EAAU,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACtD,KAAK,UAAA;AAAA,IACL,KAAK,cAAA;AACH,MAAA,uBAAOH,cAAA,CAACI,+BAAA,EAAA,EAAa,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACzD,KAAK,MAAA;AACH,MAAA,uBAAOJ,cAAA,CAACK,yBAAA,EAAA,EAAU,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACtD;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAOO,SAAS,sBAAA,CAAuB,EAAE,UAAA,EAAY,UAAA,EAAW,EAAgC;AAC9F,EAAA,MAAM,OAAO,UAAA,IAAc,EAAA;AAE3B,EAAA,uBACEC,eAAA,CAACL,4BAAA,EAAA,EAAa,SAAA,EAAU,iCAAA,EACtB,QAAA,EAAA;AAAA,oBAAAD,cAAA,CAAC,cAAA,EAAA,EAAe,YAAY,IAAA,EAAM,CAAA;AAAA,IACjC,6BAAaA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,sBAAW,CAAA,GAAU;AAAA,GAAA,EACrF,CAAA;AAEJ;AAUO,SAAS,uBAAA,CAAwB,EAAE,OAAA,EAAQ,EAAiC;AACjF,EAAA,uBAAOA,cAAA,CAACC,4BAAA,EAAA,EAAa,SAAA,EAAU,sDAAA,EAAwD,QAAA,EAAA,OAAA,EAAQ,CAAA;AACjG;AAUO,SAAS,oBAAA,CAAqB,EAAE,IAAA,EAAK,EAA8B;AACxE,EAAA,IAAI,CAAC,IAAA,IAAQ,MAAA,CAAO,KAAK,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AAC3C,IAAA,uBAAOD,cAAA,CAACC,gCAAc,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,CAChC,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM;AACf,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,SAAiB,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAC5C,IAAA,IAAI;AACF,MAAA,OAAO,GAAG,CAAC,CAAA,EAAA,EAAK,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA;AAAA,IACnC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,GAAG,CAAC,CAAA,kBAAA,CAAA;AAAA,IACb;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,uBAAOD,cAAA,CAACO,gCAAA,EAAA,EAAiB,IAAA,EAAK,MAAA,EAAQ,QAAA,EAAA,OAAA,EAAQ,CAAA;AAChD;;AC5FO,MAAM,YAAA,GAAe,MAAA,CAAO,MAAA,CAAOC,4BAAA,EAAc;AAAA,EACtD,GAAA,EAAKC,2BAAA;AAAA,EACL,OAAA,EAASC,+BAAA;AAAA,EACT,kBAAA,EAAoBC,0CAAA;AAAA,EACpB,YAAA,EAAcC,oCAAA;AAAA,EACd,UAAA,EAAYC,kCAAA;AAAA,EACZ,SAAA,EAAWC,iCAAA;AAAA,EACX,OAAA,EAASC,+BAAA;AAAA,EACT,MAAA,EAAQC,8BAAA;AAAA,EACR,OAAA,EAASC,+BAAA;AAAA,EACT,QAAA,EAAUC,gCAAA;AAAA,EACV,QAAA,EAAUC,gCAAA;AAAA,EACV,SAAA,EAAW,qBAAA;AAAA,EACX,UAAA,EAAY,sBAAA;AAAA,EACZ,WAAA,EAAa,uBAAA;AAAA,EACb,QAAA,EAAU,oBAAA;AAAA,EACV,eAAA,EAAiBC;AACnB,CAAC;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as DataListCell, b as DataListTextCell, D as DataListRoot, c as DataListNextPageLoading, e as DataListTimeCell, f as DataListDateCell, g as DataListNoMatch, h as DataListSpacer, i as DataListRowLink, j as DataListRowButton, k as DataListRowWrapper, l as DataListTopCellSmart, m as DataListTopCellWithTooltip, n as DataListTopCell, o as DataListTop } from './data-list-top-cell-
|
|
1
|
+
import { a as DataListCell, b as DataListTextCell, D as DataListRoot, c as DataListNextPageLoading, e as DataListTimeCell, f as DataListDateCell, g as DataListNoMatch, h as DataListSpacer, i as DataListRowLink, j as DataListRowButton, k as DataListRowWrapper, l as DataListTopCellSmart, m as DataListTopCellWithTooltip, n as DataListTopCell, o as DataListTop } from './data-list-top-cell-hNkk6S-Q.js';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { AgentIcon } from './icons/AgentIcon.es.js';
|
|
4
4
|
import { ToolsIcon } from './icons/ToolsIcon.es.js';
|
|
@@ -76,4 +76,4 @@ const LogsDataList = Object.assign(DataListRoot, {
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
export { LogsDataList as L };
|
|
79
|
-
//# sourceMappingURL=logs-data-list-
|
|
79
|
+
//# sourceMappingURL=logs-data-list-DnAXTwr7.js.map
|