@flanksource/clicky-ui 0.3.57 → 0.3.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clicky.cjs +3 -1
- package/dist/clicky.d.ts +1 -0
- package/dist/clicky.d.ts.map +1 -1
- package/dist/clicky.js +3 -1
- package/dist/data/Clicky.cjs +22 -270
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts +3 -29
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +10 -259
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/clicky-download.cjs +251 -0
- package/dist/data/clicky-download.cjs.map +1 -0
- package/dist/data/clicky-download.d.ts +55 -0
- package/dist/data/clicky-download.d.ts.map +1 -0
- package/dist/data/clicky-download.js +244 -0
- package/dist/data/clicky-download.js.map +1 -0
- package/dist/data/traces/index.d.ts +2 -0
- package/dist/data/traces/index.d.ts.map +1 -1
- package/dist/data/traces/otel/OtelTraceDetail.cjs +102 -78
- package/dist/data/traces/otel/OtelTraceDetail.cjs.map +1 -1
- package/dist/data/traces/otel/OtelTraceDetail.d.ts +6 -2
- package/dist/data/traces/otel/OtelTraceDetail.d.ts.map +1 -1
- package/dist/data/traces/otel/OtelTraceDetail.js +102 -78
- package/dist/data/traces/otel/OtelTraceDetail.js.map +1 -1
- package/dist/data/traces/otel/OtelTraceTable.cjs +43 -7
- package/dist/data/traces/otel/OtelTraceTable.cjs.map +1 -1
- package/dist/data/traces/otel/OtelTraceTable.d.ts +14 -3
- package/dist/data/traces/otel/OtelTraceTable.d.ts.map +1 -1
- package/dist/data/traces/otel/OtelTraceTable.js +44 -8
- package/dist/data/traces/otel/OtelTraceTable.js.map +1 -1
- package/dist/data/traces/otel/profile-listing.cjs +61 -0
- package/dist/data/traces/otel/profile-listing.cjs.map +1 -0
- package/dist/data/traces/otel/profile-listing.d.ts +23 -0
- package/dist/data/traces/otel/profile-listing.d.ts.map +1 -0
- package/dist/data/traces/otel/profile-listing.js +60 -0
- package/dist/data/traces/otel/profile-listing.js.map +1 -0
- package/dist/data/traces/otel/profile-spans.cjs +22 -0
- package/dist/data/traces/otel/profile-spans.cjs.map +1 -0
- package/dist/data/traces/otel/profile-spans.d.ts +4 -0
- package/dist/data/traces/otel/profile-spans.d.ts.map +1 -0
- package/dist/data/traces/otel/profile-spans.js +22 -0
- package/dist/data/traces/otel/profile-spans.js.map +1 -0
- package/dist/data/traces/otel/span-traces.cjs +7 -1
- package/dist/data/traces/otel/span-traces.cjs.map +1 -1
- package/dist/data/traces/otel/span-traces.d.ts +2 -0
- package/dist/data/traces/otel/span-traces.d.ts.map +1 -1
- package/dist/data/traces/otel/span-traces.js +7 -2
- package/dist/data/traces/otel/span-traces.js.map +1 -1
- package/dist/data/useClickyTableMenu.cjs +33 -0
- package/dist/data/useClickyTableMenu.cjs.map +1 -0
- package/dist/data/useClickyTableMenu.d.ts +17 -0
- package/dist/data/useClickyTableMenu.d.ts.map +1 -0
- package/dist/data/useClickyTableMenu.js +33 -0
- package/dist/data/useClickyTableMenu.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +7 -2
- package/dist/data.js +5 -3
- package/dist/index.cjs +14 -3
- package/dist/index.js +9 -4
- package/dist/rpc/CommandForm.cjs +1 -1
- package/dist/rpc/CommandForm.cjs.map +1 -1
- package/dist/rpc/CommandForm.js +1 -1
- package/dist/rpc/CommandForm.js.map +1 -1
- package/dist/rpc/EntityExplorerApp.cjs +49 -12
- package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
- package/dist/rpc/EntityExplorerApp.d.ts +10 -1
- package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
- package/dist/rpc/EntityExplorerApp.js +51 -14
- package/dist/rpc/EntityExplorerApp.js.map +1 -1
- package/dist/rpc/EntitySurface.cjs +38 -0
- package/dist/rpc/EntitySurface.cjs.map +1 -0
- package/dist/rpc/EntitySurface.d.ts +17 -0
- package/dist/rpc/EntitySurface.d.ts.map +1 -0
- package/dist/rpc/EntitySurface.js +38 -0
- package/dist/rpc/EntitySurface.js.map +1 -0
- package/dist/rpc/ExplorerNav.cjs +48 -0
- package/dist/rpc/ExplorerNav.cjs.map +1 -0
- package/dist/rpc/ExplorerNav.d.ts +12 -0
- package/dist/rpc/ExplorerNav.d.ts.map +1 -0
- package/dist/rpc/ExplorerNav.js +48 -0
- package/dist/rpc/ExplorerNav.js.map +1 -0
- package/dist/rpc/explorer-nav-context.cjs +5 -0
- package/dist/rpc/explorer-nav-context.cjs.map +1 -0
- package/dist/rpc/explorer-nav-context.d.ts +11 -0
- package/dist/rpc/explorer-nav-context.d.ts.map +1 -0
- package/dist/rpc/explorer-nav-context.js +6 -0
- package/dist/rpc/explorer-nav-context.js.map +1 -0
- package/dist/rpc.cjs +4 -0
- package/dist/rpc.d.ts +2 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +3 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,39 +1,75 @@
|
|
|
1
1
|
import { Button } from "../../../components/button.js";
|
|
2
|
+
import { DataTable } from "../../DataTable.js";
|
|
3
|
+
import { ServerTimingBadge } from "../../ServerTimingBadge.js";
|
|
2
4
|
import { OtelTraceDetail } from "./OtelTraceDetail.js";
|
|
3
5
|
import { ResultTable } from "./TraceResults.js";
|
|
4
|
-
import { spanTraces } from "./span-traces.js";
|
|
6
|
+
import { spanTraces, traceRoot } from "./span-traces.js";
|
|
5
7
|
import { useMemo } from "react";
|
|
6
8
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
9
|
// src/data/traces/otel/OtelTraceTable.tsx
|
|
8
|
-
function OtelTraceTable({ spans, selectedTraceId, selectedSpanId, onSelectTrace, onSelectSpan, traceHref, ...tableProps }) {
|
|
10
|
+
function OtelTraceTable({ spans, listing, selectedTraceId, selectedSpanId, onSelectTrace, onSelectSpan, traceHref, renderTraceTitle, serverTiming, ...tableProps }) {
|
|
11
|
+
const listingRows = listing?.rows;
|
|
9
12
|
const result = useMemo(() => {
|
|
10
13
|
try {
|
|
11
|
-
|
|
14
|
+
const traces = spanTraces(spans);
|
|
15
|
+
return {
|
|
16
|
+
traces,
|
|
17
|
+
rows: listingRows && !selectedTraceId ? traces.map((trace) => {
|
|
18
|
+
const root = traceRoot(trace.spans);
|
|
19
|
+
const position = listingRows.findIndex((row) => {
|
|
20
|
+
const span = row._trace;
|
|
21
|
+
return span?.traceId === root.traceId && span.spanId === root.spanId;
|
|
22
|
+
});
|
|
23
|
+
if (position < 0) throw new Error(`Trace ${root.traceId} is missing its mapped root row`);
|
|
24
|
+
return {
|
|
25
|
+
position,
|
|
26
|
+
row: {
|
|
27
|
+
...listingRows[position],
|
|
28
|
+
_traceId: trace.summary.traceId
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}).sort((a, b) => a.position - b.position).map(({ row }) => row) : void 0
|
|
32
|
+
};
|
|
12
33
|
} catch (error) {
|
|
13
34
|
return { error: error instanceof Error ? error.message : String(error) };
|
|
14
35
|
}
|
|
15
|
-
}, [
|
|
36
|
+
}, [
|
|
37
|
+
spans,
|
|
38
|
+
listingRows,
|
|
39
|
+
selectedTraceId
|
|
40
|
+
]);
|
|
16
41
|
const selected = result.traces?.find((trace) => trace.summary.traceId === selectedTraceId);
|
|
17
42
|
return /* @__PURE__ */ jsxs("div", {
|
|
18
|
-
className: "min-h-0 min-w-0
|
|
43
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col gap-3",
|
|
19
44
|
children: [/* @__PURE__ */ jsx("p", {
|
|
20
|
-
className: "text-sm text-muted-foreground",
|
|
45
|
+
className: "shrink-0 text-sm text-muted-foreground",
|
|
21
46
|
children: "Traces from loaded rows. Filters and paging can leave traces incomplete."
|
|
22
47
|
}), result.error ? /* @__PURE__ */ jsxs("p", {
|
|
23
48
|
role: "alert",
|
|
24
49
|
children: ["Cannot render traces: ", result.error]
|
|
25
|
-
}) : selectedTraceId ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
|
|
50
|
+
}) : selectedTraceId ? /* @__PURE__ */ jsxs(Fragment$1, { children: [!renderTraceTitle && /* @__PURE__ */ jsx(Button, {
|
|
26
51
|
variant: "link",
|
|
52
|
+
className: "self-start",
|
|
27
53
|
onClick: () => onSelectTrace(),
|
|
28
54
|
children: "Back to traces"
|
|
29
55
|
}), selected ? /* @__PURE__ */ jsx(OtelTraceDetail, {
|
|
30
56
|
trace: selected,
|
|
31
57
|
...selectedSpanId ? { selectedSpanId } : {},
|
|
58
|
+
...renderTraceTitle ? { renderTitle: renderTraceTitle } : {},
|
|
32
59
|
onSelectSpan
|
|
33
60
|
}) : /* @__PURE__ */ jsx("p", {
|
|
34
61
|
role: "status",
|
|
35
62
|
children: "This trace is not in the loaded rows. Return to traces or adjust the profile filters."
|
|
36
|
-
})] }) : /* @__PURE__ */ jsx(
|
|
63
|
+
})] }) : listing ? /* @__PURE__ */ jsx(DataTable, {
|
|
64
|
+
...tableProps,
|
|
65
|
+
...serverTiming?.length ? { filterBarProps: { trailing: /* @__PURE__ */ jsx(ServerTimingBadge, { metrics: serverTiming }) } } : {},
|
|
66
|
+
data: result.rows,
|
|
67
|
+
columns: listing.columns,
|
|
68
|
+
autoFilter: false,
|
|
69
|
+
getRowId: (row) => String(row._traceId),
|
|
70
|
+
onRowClick: (row) => onSelectTrace(String(row._traceId)),
|
|
71
|
+
...listing.linkRows === false ? {} : { getRowHref: (row) => traceHref(String(row._traceId)) }
|
|
72
|
+
}) : /* @__PURE__ */ jsx(ResultTable, {
|
|
37
73
|
traces: result.traces.map((trace) => trace.summary),
|
|
38
74
|
href: traceHref,
|
|
39
75
|
onOpen: onSelectTrace,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OtelTraceTable.js","names":["_Fragment"],"sources":["../../../../src/data/traces/otel/OtelTraceTable.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { Button } from \"../../../components\";\nimport type { DataTableProps } from \"../../DataTable\";\nimport { OtelTraceDetail } from \"./OtelTraceDetail\";\nimport { ResultTable } from \"./TraceResults\";\nimport type { Span, Summary } from \"./api\";\nimport { spanTraces } from \"./span-traces\";\n\nexport type OtelTraceTableProps = Pick
|
|
1
|
+
{"version":3,"file":"OtelTraceTable.js","names":["_Fragment"],"sources":["../../../../src/data/traces/otel/OtelTraceTable.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from \"react\";\nimport { Button } from \"../../../components\";\nimport type { DataTableProps } from \"../../DataTable\";\nimport { OtelTraceDetail } from \"./OtelTraceDetail\";\nimport { ResultTable } from \"./TraceResults\";\nimport type { Span, Summary } from \"./api\";\nimport { spanTraces, traceRoot } from \"./span-traces\";\nimport { DataTable, type DataTableColumn } from \"../../DataTable\";\nimport { ServerTimingBadge } from \"../../ServerTimingBadge\";\nimport type { ServerTimingMetric } from \"../../server-timing\";\n\nexport type OtelTraceTableProps = Pick<\n DataTableProps<Summary>,\n | \"externalFilters\"\n | \"externalSearch\"\n | \"externalTimeRange\"\n | \"pagination\"\n | \"infinite\"\n | \"loading\"\n | \"menuActions\"\n | \"sort\"\n | \"onSortChange\"\n | \"manualSort\"\n | \"cellFilters\"\n | \"onCellFilterChange\"\n> & {\n spans: readonly Span[];\n listing?: {\n rows: Record<string, unknown>[];\n columns: DataTableColumn<Record<string, unknown>>[];\n linkRows?: boolean;\n };\n selectedTraceId?: string;\n selectedSpanId?: string;\n onSelectTrace: (id?: string) => void;\n onSelectSpan: (id: string) => void;\n traceHref: (id: string) => string;\n /** Places the open trace's title elsewhere (e.g. a breadcrumb in the app shell's top bar), replacing the inline \"Back to traces\" link. */\n renderTraceTitle?: (title: ReactNode) => ReactNode;\n /** The listing response's Server-Timing metrics, shown as a badge in the listing's filter bar. */\n serverTiming?: readonly ServerTimingMetric[];\n};\n\nexport function OtelTraceTable({\n spans,\n listing,\n selectedTraceId,\n selectedSpanId,\n onSelectTrace,\n onSelectSpan,\n traceHref,\n renderTraceTitle,\n serverTiming,\n ...tableProps\n}: OtelTraceTableProps) {\n const listingRows = listing?.rows;\n const result = useMemo(() => {\n try {\n const traces = spanTraces(spans);\n // One row per trace, at its root span's position in the loaded rows: those\n // arrive in the server's sort, which the listing must keep. The detail\n // view does not use them, so they are only mapped while listing.\n const rows =\n listingRows && !selectedTraceId\n ? traces\n .map((trace) => {\n const root = traceRoot(trace.spans);\n const position = listingRows.findIndex((row) => {\n const span = row._trace as Span | undefined;\n return span?.traceId === root.traceId && span.spanId === root.spanId;\n });\n if (position < 0)\n throw new Error(`Trace ${root.traceId} is missing its mapped root row`);\n return { position, row: { ...listingRows[position]!, _traceId: trace.summary.traceId } };\n })\n .sort((a, b) => a.position - b.position)\n .map(({ row }) => row)\n : undefined;\n return { traces, rows };\n } catch (error) {\n return { error: error instanceof Error ? error.message : String(error) };\n }\n }, [spans, listingRows, selectedTraceId]);\n const selected = result.traces?.find(\n (trace) => trace.summary.traceId === selectedTraceId,\n );\n return (\n // A flex column so the listing's DataTable fills a bounded parent: its body\n // scrolls and the pagination footer stays on screen.\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col gap-3\">\n <p className=\"shrink-0 text-sm text-muted-foreground\">\n Traces from loaded rows. Filters and paging can leave traces incomplete.\n </p>\n {result.error ? (\n <p role=\"alert\">Cannot render traces: {result.error}</p>\n ) : selectedTraceId ? (\n <>\n {!renderTraceTitle && (\n <Button variant=\"link\" className=\"self-start\" onClick={() => onSelectTrace()}>\n Back to traces\n </Button>\n )}\n {selected ? (\n <OtelTraceDetail\n trace={selected}\n {...(selectedSpanId ? { selectedSpanId } : {})}\n {...(renderTraceTitle ? { renderTitle: renderTraceTitle } : {})}\n onSelectSpan={onSelectSpan}\n />\n ) : (\n <p role=\"status\">\n This trace is not in the loaded rows. Return to traces or adjust\n the profile filters.\n </p>\n )}\n </>\n ) : listing ? (\n <DataTable\n {...tableProps}\n {...(serverTiming?.length\n ? { filterBarProps: { trailing: <ServerTimingBadge metrics={serverTiming} /> } }\n : {})}\n data={result.rows!}\n columns={listing.columns}\n autoFilter={false}\n getRowId={(row) => String(row._traceId)}\n onRowClick={(row) => onSelectTrace(String(row._traceId))}\n {...(listing.linkRows === false\n ? {}\n : {\n getRowHref: (row: Record<string, unknown>) =>\n traceHref(String(row._traceId)),\n })}\n />\n ) : (\n <ResultTable\n traces={result.traces!.map((trace) => trace.summary)}\n href={traceHref}\n onOpen={onSelectTrace}\n now={Date.now()}\n tableProps={tableProps}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AA2CA,SAAgB,eAAe,EAC7B,OACA,SACA,iBACA,gBACA,eACA,cACA,WACA,kBACA,cACA,GAAG,cACmB;CACtB,MAAM,cAAc,SAAS;CAC7B,MAAM,SAAS,cAAc;EAC3B,IAAI;GACF,MAAM,SAAS,WAAW,KAAK;GAoB/B,OAAO;IAAE;IAAQ,MAff,eAAe,CAAC,kBACZ,OACG,KAAK,UAAU;KACd,MAAM,OAAO,UAAU,MAAM,KAAK;KAClC,MAAM,WAAW,YAAY,WAAW,QAAQ;MAC9C,MAAM,OAAO,IAAI;MACjB,OAAO,MAAM,YAAY,KAAK,WAAW,KAAK,WAAW,KAAK;KAChE,CAAC;KACD,IAAI,WAAW,GACb,MAAM,IAAI,MAAM,SAAS,KAAK,QAAQ,gCAAgC;KACxE,OAAO;MAAE;MAAU,KAAK;OAAE,GAAG,YAAY;OAAY,UAAU,MAAM,QAAQ;MAAQ;KAAE;IACzF,CAAC,CAAC,CACD,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CACvC,KAAK,EAAE,UAAU,GAAG,IACvB,KAAA;GACgB;EACxB,SAAS,OAAO;GACd,OAAO,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;EACzE;CACF,GAAG;EAAC;EAAO;EAAa;CAAe,CAAC;CACxC,MAAM,WAAW,OAAO,QAAQ,MAC7B,UAAU,MAAM,QAAQ,YAAY,eACvC;CACA,OAGE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD;GAAG,WAAU;GAAyC,UAAA;EAEnD,CAAA,GACF,OAAO,QACN,qBAAC,KAAD;GAAG,MAAK;GAAR,UAAA,CAAgB,0BAAuB,OAAO,KAAS;EACrD,CAAA,IAAA,kBACF,qBAAAA,YAAA,EAAA,UAAA,CACG,CAAC,oBACA,oBAAC,QAAD;GAAQ,SAAQ;GAAO,WAAU;GAAa,eAAe,cAAc;GAAG,UAAA;EAEtE,CAAA,GAET,WACC,oBAAC,iBAAD;GACE,OAAO;GACP,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC5C,GAAK,mBAAmB,EAAE,aAAa,iBAAiB,IAAI,CAAC;GAC/C;EACf,CAAA,IAED,oBAAC,KAAD;GAAG,MAAK;GAAS,UAAA;EAGd,CAAA,CAEL,EAAA,CAAA,IACA,UACF,oBAAC,WAAD;GACE,GAAI;GACJ,GAAK,cAAc,SACf,EAAE,gBAAgB,EAAE,UAAU,oBAAC,mBAAD,EAAmB,SAAS,aAAe,CAAA,EAAE,EAAE,IAC7E,CAAC;GACL,MAAM,OAAO;GACb,SAAS,QAAQ;GACjB,YAAY;GACZ,WAAW,QAAQ,OAAO,IAAI,QAAQ;GACtC,aAAa,QAAQ,cAAc,OAAO,IAAI,QAAQ,CAAC;GACvD,GAAK,QAAQ,aAAa,QACtB,CAAC,IACD,EACE,aAAa,QACX,UAAU,OAAO,IAAI,QAAQ,CAAC,EAClC;EACL,CAAA,IAED,oBAAC,aAAD;GACE,QAAQ,OAAO,OAAQ,KAAK,UAAU,MAAM,OAAO;GACnD,MAAM;GACN,QAAQ;GACR,KAAK,KAAK,IAAI;GACF;EACb,CAAA,CAEA;;AAET"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const require_Clicky = require("../../Clicky.cjs");
|
|
2
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
|
+
// src/data/traces/otel/profile-listing.tsx
|
|
4
|
+
var presentedCell = (row, name) => row._presentation[name];
|
|
5
|
+
/**
|
|
6
|
+
* The listing's table sort bound to the server's: a header click becomes the
|
|
7
|
+
* column's `sortKey`, and the server's current sort marks its column. The rows
|
|
8
|
+
* arrive in that order, so the table must not re-sort them itself.
|
|
9
|
+
*/
|
|
10
|
+
function profileListingSort(table, server) {
|
|
11
|
+
const columns = table.columns ?? [];
|
|
12
|
+
const byName = (name) => {
|
|
13
|
+
const column = columns.find((candidate) => candidate.name === name);
|
|
14
|
+
if (!column?.sortKey) throw new Error(`Trace listing column ${name} does not declare a server sort key`);
|
|
15
|
+
return column;
|
|
16
|
+
};
|
|
17
|
+
let sort = null;
|
|
18
|
+
if (server.value) {
|
|
19
|
+
const column = columns.find((candidate) => candidate.sortKey === server.value.key);
|
|
20
|
+
if (!column) throw new Error(`Server sort key ${server.value.key} does not match a trace listing column`);
|
|
21
|
+
sort = {
|
|
22
|
+
key: column.name,
|
|
23
|
+
dir: server.value.dir
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
sort,
|
|
28
|
+
onSortChange: (next) => server.onChange(next ? {
|
|
29
|
+
key: byName(next.key).sortKey,
|
|
30
|
+
dir: next.dir
|
|
31
|
+
} : null),
|
|
32
|
+
manualSort: true
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function profileTraceListing(rows, table) {
|
|
36
|
+
if (table.kind !== "table" || !table.columns || table.rows?.length !== rows.length) throw new Error("Trace listing requires a rendered table matching the span rows");
|
|
37
|
+
return {
|
|
38
|
+
rows: rows.map((row, index) => ({
|
|
39
|
+
...row,
|
|
40
|
+
_presentation: table.rows[index].cells
|
|
41
|
+
})),
|
|
42
|
+
columns: table.columns.filter((column) => !column.defaultHidden).map((column) => ({
|
|
43
|
+
key: column.name,
|
|
44
|
+
label: column.header ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Clicky.ClickyNodeRenderer, { node: column.header }) : column.label ?? column.name,
|
|
45
|
+
render: (_value, row) => {
|
|
46
|
+
const cell = presentedCell(row, column.name);
|
|
47
|
+
return cell ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Clicky.ClickyNodeRenderer, { node: cell }) : null;
|
|
48
|
+
},
|
|
49
|
+
sortable: Boolean(column.sortKey),
|
|
50
|
+
...column.filterable !== void 0 ? { filterable: column.filterable } : {},
|
|
51
|
+
...column.filterKey ? {
|
|
52
|
+
filterKey: column.filterKey,
|
|
53
|
+
serverFilterValue: (value, row) => presentedCell(row, column.name)?.filterValue ?? value
|
|
54
|
+
} : {}
|
|
55
|
+
}))
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
exports.profileListingSort = profileListingSort;
|
|
59
|
+
exports.profileTraceListing = profileTraceListing;
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=profile-listing.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-listing.cjs","names":["ClickyNodeRenderer"],"sources":["../../../../src/data/traces/otel/profile-listing.tsx"],"sourcesContent":["import { ClickyNodeRenderer, type ClickyNode } from \"../../Clicky\";\nimport type { DataTableColumn } from \"../../DataTable\";\nimport type { SortState } from \"../../../hooks/use-sort\";\n\nconst presentedCell = (row: Record<string, unknown>, name: string) =>\n (row._presentation as Record<string, ClickyNode>)[name];\n\n/**\n * The listing's table sort bound to the server's: a header click becomes the\n * column's `sortKey`, and the server's current sort marks its column. The rows\n * arrive in that order, so the table must not re-sort them itself.\n */\nexport function profileListingSort(\n table: ClickyNode,\n server: { value: SortState | null; onChange: (sort: SortState | null) => void },\n): { sort: SortState | null; onSortChange: (sort: SortState | null) => void; manualSort: true } {\n const columns = table.columns ?? [];\n const byName = (name: string) => {\n const column = columns.find((candidate) => candidate.name === name);\n if (!column?.sortKey) throw new Error(`Trace listing column ${name} does not declare a server sort key`);\n return column;\n };\n let sort: SortState | null = null;\n if (server.value) {\n const column = columns.find((candidate) => candidate.sortKey === server.value!.key);\n if (!column) throw new Error(`Server sort key ${server.value.key} does not match a trace listing column`);\n sort = { key: column.name, dir: server.value.dir };\n }\n return {\n sort,\n onSortChange: (next) => server.onChange(next ? { key: byName(next.key).sortKey!, dir: next.dir } : null),\n manualSort: true,\n };\n}\n\nexport function profileTraceListing(\n rows: Record<string, unknown>[],\n table: ClickyNode,\n) {\n if (\n table.kind !== \"table\" ||\n !table.columns ||\n table.rows?.length !== rows.length\n )\n throw new Error(\n \"Trace listing requires a rendered table matching the span rows\",\n );\n const presented = rows.map((row, index) => ({\n ...row,\n _presentation: table.rows![index]!.cells,\n }));\n const columns: DataTableColumn<Record<string, unknown>>[] = table.columns\n .filter((column) => !column.defaultHidden)\n .map((column) => ({\n key: column.name,\n label: column.header ? (\n <ClickyNodeRenderer node={column.header} />\n ) : (\n (column.label ?? column.name)\n ),\n render: (_value, row) => {\n const cell = presentedCell(row, column.name);\n return cell ? <ClickyNodeRenderer node={cell} /> : null;\n },\n sortable: Boolean(column.sortKey),\n ...(column.filterable !== undefined ? { filterable: column.filterable } : {}),\n // The server-filter key is what gives a cell its include/exclude hover\n // actions; the value is the one the server matches, not the display text.\n ...(column.filterKey\n ? {\n filterKey: column.filterKey,\n serverFilterValue: (value: unknown, row: Record<string, unknown>) =>\n presentedCell(row, column.name)?.filterValue ?? value,\n }\n : {}),\n }));\n return { rows: presented, columns };\n}\n"],"mappings":";;;AAIA,IAAM,iBAAiB,KAA8B,SAClD,IAAI,cAA6C;;;;;;AAOpD,SAAgB,mBACd,OACA,QAC8F;CAC9F,MAAM,UAAU,MAAM,WAAW,CAAC;CAClC,MAAM,UAAU,SAAiB;EAC/B,MAAM,SAAS,QAAQ,MAAM,cAAc,UAAU,SAAS,IAAI;EAClE,IAAI,CAAC,QAAQ,SAAS,MAAM,IAAI,MAAM,wBAAwB,KAAK,oCAAoC;EACvG,OAAO;CACT;CACA,IAAI,OAAyB;CAC7B,IAAI,OAAO,OAAO;EAChB,MAAM,SAAS,QAAQ,MAAM,cAAc,UAAU,YAAY,OAAO,MAAO,GAAG;EAClF,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,mBAAmB,OAAO,MAAM,IAAI,uCAAuC;EACxG,OAAO;GAAE,KAAK,OAAO;GAAM,KAAK,OAAO,MAAM;EAAI;CACnD;CACA,OAAO;EACL;EACA,eAAe,SAAS,OAAO,SAAS,OAAO;GAAE,KAAK,OAAO,KAAK,GAAG,CAAC,CAAC;GAAU,KAAK,KAAK;EAAI,IAAI,IAAI;EACvG,YAAY;CACd;AACF;AAEA,SAAgB,oBACd,MACA,OACA;CACA,IACE,MAAM,SAAS,WACf,CAAC,MAAM,WACP,MAAM,MAAM,WAAW,KAAK,QAE5B,MAAM,IAAI,MACR,gEACF;CA8BF,OAAO;EAAE,MA7BS,KAAK,KAAK,KAAK,WAAW;GAC1C,GAAG;GACH,eAAe,MAAM,KAAM,MAAM,CAAE;EACrC,EA0Be;EAAW,SAzBkC,MAAM,QAC/D,QAAQ,WAAW,CAAC,OAAO,aAAa,CAAC,CACzC,KAAK,YAAY;GAChB,KAAK,OAAO;GACZ,OAAO,OAAO,SACZ,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,oBAAD,EAAoB,MAAM,OAAO,OAAS,CAAA,IAEzC,OAAO,SAAS,OAAO;GAE1B,SAAS,QAAQ,QAAQ;IACvB,MAAM,OAAO,cAAc,KAAK,OAAO,IAAI;IAC3C,OAAO,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,oBAAD,EAAoB,MAAM,KAAO,CAAA,IAAI;GACrD;GACA,UAAU,QAAQ,OAAO,OAAO;GAChC,GAAI,OAAO,eAAe,KAAA,IAAY,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;GAG3E,GAAI,OAAO,YACP;IACE,WAAW,OAAO;IAClB,oBAAoB,OAAgB,QAClC,cAAc,KAAK,OAAO,IAAI,CAAC,EAAE,eAAe;GACpD,IACA,CAAC;EACP,EACwB;CAAQ;AACpC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ClickyNode } from '../../Clicky.js';
|
|
2
|
+
import { DataTableColumn } from '../../DataTable.js';
|
|
3
|
+
import { SortState } from '../../../hooks/use-sort.js';
|
|
4
|
+
/**
|
|
5
|
+
* The listing's table sort bound to the server's: a header click becomes the
|
|
6
|
+
* column's `sortKey`, and the server's current sort marks its column. The rows
|
|
7
|
+
* arrive in that order, so the table must not re-sort them itself.
|
|
8
|
+
*/
|
|
9
|
+
export declare function profileListingSort(table: ClickyNode, server: {
|
|
10
|
+
value: SortState | null;
|
|
11
|
+
onChange: (sort: SortState | null) => void;
|
|
12
|
+
}): {
|
|
13
|
+
sort: SortState | null;
|
|
14
|
+
onSortChange: (sort: SortState | null) => void;
|
|
15
|
+
manualSort: true;
|
|
16
|
+
};
|
|
17
|
+
export declare function profileTraceListing(rows: Record<string, unknown>[], table: ClickyNode): {
|
|
18
|
+
rows: {
|
|
19
|
+
_presentation: Record<string, ClickyNode>;
|
|
20
|
+
}[];
|
|
21
|
+
columns: DataTableColumn<Record<string, unknown>>[];
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=profile-listing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-listing.d.ts","sourceRoot":"","sources":["../../../../src/data/traces/otel/profile-listing.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKzD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE;IAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAAC,UAAU,EAAE,IAAI,CAAA;CAAE,CAkB9F;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,KAAK,EAAE,UAAU;;;;;EAwClB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ClickyNodeRenderer } from "../../Clicky.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
// src/data/traces/otel/profile-listing.tsx
|
|
4
|
+
var presentedCell = (row, name) => row._presentation[name];
|
|
5
|
+
/**
|
|
6
|
+
* The listing's table sort bound to the server's: a header click becomes the
|
|
7
|
+
* column's `sortKey`, and the server's current sort marks its column. The rows
|
|
8
|
+
* arrive in that order, so the table must not re-sort them itself.
|
|
9
|
+
*/
|
|
10
|
+
function profileListingSort(table, server) {
|
|
11
|
+
const columns = table.columns ?? [];
|
|
12
|
+
const byName = (name) => {
|
|
13
|
+
const column = columns.find((candidate) => candidate.name === name);
|
|
14
|
+
if (!column?.sortKey) throw new Error(`Trace listing column ${name} does not declare a server sort key`);
|
|
15
|
+
return column;
|
|
16
|
+
};
|
|
17
|
+
let sort = null;
|
|
18
|
+
if (server.value) {
|
|
19
|
+
const column = columns.find((candidate) => candidate.sortKey === server.value.key);
|
|
20
|
+
if (!column) throw new Error(`Server sort key ${server.value.key} does not match a trace listing column`);
|
|
21
|
+
sort = {
|
|
22
|
+
key: column.name,
|
|
23
|
+
dir: server.value.dir
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
sort,
|
|
28
|
+
onSortChange: (next) => server.onChange(next ? {
|
|
29
|
+
key: byName(next.key).sortKey,
|
|
30
|
+
dir: next.dir
|
|
31
|
+
} : null),
|
|
32
|
+
manualSort: true
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function profileTraceListing(rows, table) {
|
|
36
|
+
if (table.kind !== "table" || !table.columns || table.rows?.length !== rows.length) throw new Error("Trace listing requires a rendered table matching the span rows");
|
|
37
|
+
return {
|
|
38
|
+
rows: rows.map((row, index) => ({
|
|
39
|
+
...row,
|
|
40
|
+
_presentation: table.rows[index].cells
|
|
41
|
+
})),
|
|
42
|
+
columns: table.columns.filter((column) => !column.defaultHidden).map((column) => ({
|
|
43
|
+
key: column.name,
|
|
44
|
+
label: column.header ? /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: column.header }) : column.label ?? column.name,
|
|
45
|
+
render: (_value, row) => {
|
|
46
|
+
const cell = presentedCell(row, column.name);
|
|
47
|
+
return cell ? /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: cell }) : null;
|
|
48
|
+
},
|
|
49
|
+
sortable: Boolean(column.sortKey),
|
|
50
|
+
...column.filterable !== void 0 ? { filterable: column.filterable } : {},
|
|
51
|
+
...column.filterKey ? {
|
|
52
|
+
filterKey: column.filterKey,
|
|
53
|
+
serverFilterValue: (value, row) => presentedCell(row, column.name)?.filterValue ?? value
|
|
54
|
+
} : {}
|
|
55
|
+
}))
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export { profileListingSort, profileTraceListing };
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=profile-listing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-listing.js","names":[],"sources":["../../../../src/data/traces/otel/profile-listing.tsx"],"sourcesContent":["import { ClickyNodeRenderer, type ClickyNode } from \"../../Clicky\";\nimport type { DataTableColumn } from \"../../DataTable\";\nimport type { SortState } from \"../../../hooks/use-sort\";\n\nconst presentedCell = (row: Record<string, unknown>, name: string) =>\n (row._presentation as Record<string, ClickyNode>)[name];\n\n/**\n * The listing's table sort bound to the server's: a header click becomes the\n * column's `sortKey`, and the server's current sort marks its column. The rows\n * arrive in that order, so the table must not re-sort them itself.\n */\nexport function profileListingSort(\n table: ClickyNode,\n server: { value: SortState | null; onChange: (sort: SortState | null) => void },\n): { sort: SortState | null; onSortChange: (sort: SortState | null) => void; manualSort: true } {\n const columns = table.columns ?? [];\n const byName = (name: string) => {\n const column = columns.find((candidate) => candidate.name === name);\n if (!column?.sortKey) throw new Error(`Trace listing column ${name} does not declare a server sort key`);\n return column;\n };\n let sort: SortState | null = null;\n if (server.value) {\n const column = columns.find((candidate) => candidate.sortKey === server.value!.key);\n if (!column) throw new Error(`Server sort key ${server.value.key} does not match a trace listing column`);\n sort = { key: column.name, dir: server.value.dir };\n }\n return {\n sort,\n onSortChange: (next) => server.onChange(next ? { key: byName(next.key).sortKey!, dir: next.dir } : null),\n manualSort: true,\n };\n}\n\nexport function profileTraceListing(\n rows: Record<string, unknown>[],\n table: ClickyNode,\n) {\n if (\n table.kind !== \"table\" ||\n !table.columns ||\n table.rows?.length !== rows.length\n )\n throw new Error(\n \"Trace listing requires a rendered table matching the span rows\",\n );\n const presented = rows.map((row, index) => ({\n ...row,\n _presentation: table.rows![index]!.cells,\n }));\n const columns: DataTableColumn<Record<string, unknown>>[] = table.columns\n .filter((column) => !column.defaultHidden)\n .map((column) => ({\n key: column.name,\n label: column.header ? (\n <ClickyNodeRenderer node={column.header} />\n ) : (\n (column.label ?? column.name)\n ),\n render: (_value, row) => {\n const cell = presentedCell(row, column.name);\n return cell ? <ClickyNodeRenderer node={cell} /> : null;\n },\n sortable: Boolean(column.sortKey),\n ...(column.filterable !== undefined ? { filterable: column.filterable } : {}),\n // The server-filter key is what gives a cell its include/exclude hover\n // actions; the value is the one the server matches, not the display text.\n ...(column.filterKey\n ? {\n filterKey: column.filterKey,\n serverFilterValue: (value: unknown, row: Record<string, unknown>) =>\n presentedCell(row, column.name)?.filterValue ?? value,\n }\n : {}),\n }));\n return { rows: presented, columns };\n}\n"],"mappings":";;;AAIA,IAAM,iBAAiB,KAA8B,SAClD,IAAI,cAA6C;;;;;;AAOpD,SAAgB,mBACd,OACA,QAC8F;CAC9F,MAAM,UAAU,MAAM,WAAW,CAAC;CAClC,MAAM,UAAU,SAAiB;EAC/B,MAAM,SAAS,QAAQ,MAAM,cAAc,UAAU,SAAS,IAAI;EAClE,IAAI,CAAC,QAAQ,SAAS,MAAM,IAAI,MAAM,wBAAwB,KAAK,oCAAoC;EACvG,OAAO;CACT;CACA,IAAI,OAAyB;CAC7B,IAAI,OAAO,OAAO;EAChB,MAAM,SAAS,QAAQ,MAAM,cAAc,UAAU,YAAY,OAAO,MAAO,GAAG;EAClF,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,mBAAmB,OAAO,MAAM,IAAI,uCAAuC;EACxG,OAAO;GAAE,KAAK,OAAO;GAAM,KAAK,OAAO,MAAM;EAAI;CACnD;CACA,OAAO;EACL;EACA,eAAe,SAAS,OAAO,SAAS,OAAO;GAAE,KAAK,OAAO,KAAK,GAAG,CAAC,CAAC;GAAU,KAAK,KAAK;EAAI,IAAI,IAAI;EACvG,YAAY;CACd;AACF;AAEA,SAAgB,oBACd,MACA,OACA;CACA,IACE,MAAM,SAAS,WACf,CAAC,MAAM,WACP,MAAM,MAAM,WAAW,KAAK,QAE5B,MAAM,IAAI,MACR,gEACF;CA8BF,OAAO;EAAE,MA7BS,KAAK,KAAK,KAAK,WAAW;GAC1C,GAAG;GACH,eAAe,MAAM,KAAM,MAAM,CAAE;EACrC,EA0Be;EAAW,SAzBkC,MAAM,QAC/D,QAAQ,WAAW,CAAC,OAAO,aAAa,CAAC,CACzC,KAAK,YAAY;GAChB,KAAK,OAAO;GACZ,OAAO,OAAO,SACZ,oBAAC,oBAAD,EAAoB,MAAM,OAAO,OAAS,CAAA,IAEzC,OAAO,SAAS,OAAO;GAE1B,SAAS,QAAQ,QAAQ;IACvB,MAAM,OAAO,cAAc,KAAK,OAAO,IAAI;IAC3C,OAAO,OAAO,oBAAC,oBAAD,EAAoB,MAAM,KAAO,CAAA,IAAI;GACrD;GACA,UAAU,QAAQ,OAAO,OAAO;GAChC,GAAI,OAAO,eAAe,KAAA,IAAY,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;GAG3E,GAAI,OAAO,YACP;IACE,WAAW,OAAO;IAClB,oBAAoB,OAAgB,QAClC,cAAc,KAAK,OAAO,IAAI,CAAC,EAAE,eAAe;GACpD,IACA,CAAC;EACP,EACwB;CAAQ;AACpC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/data/traces/otel/profile-spans.ts
|
|
2
|
+
/** Reads server-normalized spans; source inference belongs to commons-db. */
|
|
3
|
+
function profileSpans(rows) {
|
|
4
|
+
return rows.map((row, index) => {
|
|
5
|
+
const span = row._trace;
|
|
6
|
+
if (!span || typeof span !== "object" || Array.isArray(span)) throw new Error(`Row ${index + 1} is missing its canonical span`);
|
|
7
|
+
const value = span;
|
|
8
|
+
for (const key of [
|
|
9
|
+
"traceId",
|
|
10
|
+
"spanId",
|
|
11
|
+
"startedAt",
|
|
12
|
+
"service",
|
|
13
|
+
"operation",
|
|
14
|
+
"status"
|
|
15
|
+
]) if (typeof value[key] !== "string") throw new Error(`Row ${index + 1} has invalid ${key}`);
|
|
16
|
+
if (typeof value.durationMs !== "number" || !Number.isFinite(value.durationMs) || value.durationMs < 0) throw new Error(`Row ${index + 1} has invalid durationMs`);
|
|
17
|
+
return value;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
exports.profileSpans = profileSpans;
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=profile-spans.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-spans.cjs","names":[],"sources":["../../../../src/data/traces/otel/profile-spans.ts"],"sourcesContent":["import type { Span } from \"./api\";\n\n/** Reads server-normalized spans; source inference belongs to commons-db. */\nexport function profileSpans(rows: readonly Record<string, unknown>[]): Span[] {\n return rows.map((row, index) => {\n const span = row._trace;\n if (!span || typeof span !== \"object\" || Array.isArray(span))\n throw new Error(`Row ${index + 1} is missing its canonical span`);\n const value = span as Record<string, unknown>;\n for (const key of [\n \"traceId\",\n \"spanId\",\n \"startedAt\",\n \"service\",\n \"operation\",\n \"status\",\n ])\n if (typeof value[key] !== \"string\")\n throw new Error(`Row ${index + 1} has invalid ${key}`);\n if (\n typeof value.durationMs !== \"number\" ||\n !Number.isFinite(value.durationMs) ||\n value.durationMs < 0\n )\n throw new Error(`Row ${index + 1} has invalid durationMs`);\n return value as Span;\n });\n}\n"],"mappings":";;AAGA,SAAgB,aAAa,MAAkD;CAC7E,OAAO,KAAK,KAAK,KAAK,UAAU;EAC9B,MAAM,OAAO,IAAI;EACjB,IAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GACzD,MAAM,IAAI,MAAM,OAAO,QAAQ,EAAE,+BAA+B;EAClE,MAAM,QAAQ;EACd,KAAK,MAAM,OAAO;GAChB;GACA;GACA;GACA;GACA;GACA;EACF,GACE,IAAI,OAAO,MAAM,SAAS,UACxB,MAAM,IAAI,MAAM,OAAO,QAAQ,EAAE,eAAe,KAAK;EACzD,IACE,OAAO,MAAM,eAAe,YAC5B,CAAC,OAAO,SAAS,MAAM,UAAU,KACjC,MAAM,aAAa,GAEnB,MAAM,IAAI,MAAM,OAAO,QAAQ,EAAE,wBAAwB;EAC3D,OAAO;CACT,CAAC;AACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-spans.d.ts","sourceRoot":"","sources":["../../../../src/data/traces/otel/profile-spans.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAElC,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,CAwB7E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/data/traces/otel/profile-spans.ts
|
|
2
|
+
/** Reads server-normalized spans; source inference belongs to commons-db. */
|
|
3
|
+
function profileSpans(rows) {
|
|
4
|
+
return rows.map((row, index) => {
|
|
5
|
+
const span = row._trace;
|
|
6
|
+
if (!span || typeof span !== "object" || Array.isArray(span)) throw new Error(`Row ${index + 1} is missing its canonical span`);
|
|
7
|
+
const value = span;
|
|
8
|
+
for (const key of [
|
|
9
|
+
"traceId",
|
|
10
|
+
"spanId",
|
|
11
|
+
"startedAt",
|
|
12
|
+
"service",
|
|
13
|
+
"operation",
|
|
14
|
+
"status"
|
|
15
|
+
]) if (typeof value[key] !== "string") throw new Error(`Row ${index + 1} has invalid ${key}`);
|
|
16
|
+
if (typeof value.durationMs !== "number" || !Number.isFinite(value.durationMs) || value.durationMs < 0) throw new Error(`Row ${index + 1} has invalid durationMs`);
|
|
17
|
+
return value;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export { profileSpans };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=profile-spans.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-spans.js","names":[],"sources":["../../../../src/data/traces/otel/profile-spans.ts"],"sourcesContent":["import type { Span } from \"./api\";\n\n/** Reads server-normalized spans; source inference belongs to commons-db. */\nexport function profileSpans(rows: readonly Record<string, unknown>[]): Span[] {\n return rows.map((row, index) => {\n const span = row._trace;\n if (!span || typeof span !== \"object\" || Array.isArray(span))\n throw new Error(`Row ${index + 1} is missing its canonical span`);\n const value = span as Record<string, unknown>;\n for (const key of [\n \"traceId\",\n \"spanId\",\n \"startedAt\",\n \"service\",\n \"operation\",\n \"status\",\n ])\n if (typeof value[key] !== \"string\")\n throw new Error(`Row ${index + 1} has invalid ${key}`);\n if (\n typeof value.durationMs !== \"number\" ||\n !Number.isFinite(value.durationMs) ||\n value.durationMs < 0\n )\n throw new Error(`Row ${index + 1} has invalid durationMs`);\n return value as Span;\n });\n}\n"],"mappings":";;AAGA,SAAgB,aAAa,MAAkD;CAC7E,OAAO,KAAK,KAAK,KAAK,UAAU;EAC9B,MAAM,OAAO,IAAI;EACjB,IAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GACzD,MAAM,IAAI,MAAM,OAAO,QAAQ,EAAE,+BAA+B;EAClE,MAAM,QAAQ;EACd,KAAK,MAAM,OAAO;GAChB;GACA;GACA;GACA;GACA;GACA;EACF,GACE,IAAI,OAAO,MAAM,SAAS,UACxB,MAAM,IAAI,MAAM,OAAO,QAAQ,EAAE,eAAe,KAAK;EACzD,IACE,OAAO,MAAM,eAAe,YAC5B,CAAC,OAAO,SAAS,MAAM,UAAU,KACjC,MAAM,aAAa,GAEnB,MAAM,IAAI,MAAM,OAAO,QAAQ,EAAE,wBAAwB;EAC3D,OAAO;CACT,CAAC;AACH"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
const require_model = require("./model.cjs");
|
|
2
2
|
// src/data/traces/otel/span-traces.ts
|
|
3
|
+
/** A trace's root among its start-ordered spans: a parentless span, else the first span whose parent is not in the trace, else the first span. */
|
|
4
|
+
function traceRoot(ordered) {
|
|
5
|
+
const ids = new Set(ordered.map((span) => span.spanId));
|
|
6
|
+
return ordered.find((span) => !span.parentId) ?? ordered.find((span) => !ids.has(span.parentId)) ?? ordered[0];
|
|
7
|
+
}
|
|
3
8
|
function spanTraces(spans) {
|
|
4
9
|
const groups = /* @__PURE__ */ new Map();
|
|
5
10
|
for (const span of spans) {
|
|
@@ -13,7 +18,7 @@ function spanTraces(spans) {
|
|
|
13
18
|
const ordered = [...group].sort((a, b) => require_model.micros(a.startedAt) - require_model.micros(b.startedAt) || a.spanId.localeCompare(b.spanId));
|
|
14
19
|
const first = ordered[0];
|
|
15
20
|
const ids = new Set(ordered.map((span) => span.spanId));
|
|
16
|
-
const root =
|
|
21
|
+
const root = traceRoot(ordered);
|
|
17
22
|
const start = require_model.micros(first.startedAt);
|
|
18
23
|
const end = ordered.reduce((latest, span) => Math.max(latest, require_model.micros(span.startedAt) + span.durationMs * 1e3), start);
|
|
19
24
|
const trace = {
|
|
@@ -35,5 +40,6 @@ function spanTraces(spans) {
|
|
|
35
40
|
}).sort((a, b) => require_model.micros(b.summary.startedAt) - require_model.micros(a.summary.startedAt) || a.summary.traceId.localeCompare(b.summary.traceId));
|
|
36
41
|
}
|
|
37
42
|
exports.spanTraces = spanTraces;
|
|
43
|
+
exports.traceRoot = traceRoot;
|
|
38
44
|
|
|
39
45
|
//# sourceMappingURL=span-traces.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"span-traces.cjs","names":["micros","isError"],"sources":["../../../../src/data/traces/otel/span-traces.ts"],"sourcesContent":["import type { Span, Trace } from \"./api\";\nimport { indexTrace, isError, micros } from \"./model\";\n\nexport function spanTraces(spans: readonly Span[]): Trace[] {\n const groups = new Map<string, Span[]>();\n for (const span of spans) {\n if (!span.traceId || !span.spanId || !Number.isFinite(span.durationMs) || span.durationMs < 0)\n throw new Error(\"Trace spans require traceId, spanId and a finite non-negative durationMs\");\n micros(span.startedAt);\n const group = groups.get(span.traceId) ?? [];\n group.push(span);\n groups.set(span.traceId, group);\n }\n return [...groups].map(([traceId, group]) => {\n const ordered = [...group].sort((a, b) => micros(a.startedAt) - micros(b.startedAt) || a.spanId.localeCompare(b.spanId));\n const first = ordered[0]!;\n const ids = new Set(ordered.map(span => span.spanId));\n const root =
|
|
1
|
+
{"version":3,"file":"span-traces.cjs","names":["micros","isError"],"sources":["../../../../src/data/traces/otel/span-traces.ts"],"sourcesContent":["import type { Span, Trace } from \"./api\";\nimport { indexTrace, isError, micros } from \"./model\";\n\n/** A trace's root among its start-ordered spans: a parentless span, else the first span whose parent is not in the trace, else the first span. */\nexport function traceRoot(ordered: readonly Span[]): Span {\n const ids = new Set(ordered.map(span => span.spanId));\n return ordered.find(span => !span.parentId) ?? ordered.find(span => !ids.has(span.parentId!)) ?? ordered[0]!;\n}\n\nexport function spanTraces(spans: readonly Span[]): Trace[] {\n const groups = new Map<string, Span[]>();\n for (const span of spans) {\n if (!span.traceId || !span.spanId || !Number.isFinite(span.durationMs) || span.durationMs < 0)\n throw new Error(\"Trace spans require traceId, spanId and a finite non-negative durationMs\");\n micros(span.startedAt);\n const group = groups.get(span.traceId) ?? [];\n group.push(span);\n groups.set(span.traceId, group);\n }\n return [...groups].map(([traceId, group]) => {\n const ordered = [...group].sort((a, b) => micros(a.startedAt) - micros(b.startedAt) || a.spanId.localeCompare(b.spanId));\n const first = ordered[0]!;\n const ids = new Set(ordered.map(span => span.spanId));\n const root = traceRoot(ordered);\n const start = micros(first.startedAt);\n const end = ordered.reduce((latest, span) => Math.max(latest, micros(span.startedAt) + span.durationMs * 1000), start);\n const trace: Trace = {\n summary: { traceId, service: root.service, operation: root.operation, startedAt: first.startedAt, durationMs: (end - start) / 1000, spanCount: ordered.length, errors: ordered.filter(isError).length, services: [...new Set(ordered.map(span => span.service))].sort() },\n spans: ordered,\n missingParents: [...new Set(ordered.flatMap(span => span.parentId && !ids.has(span.parentId) ? [span.parentId] : []))].sort(),\n };\n indexTrace(trace);\n return trace;\n }).sort((a, b) => micros(b.summary.startedAt) - micros(a.summary.startedAt) || a.summary.traceId.localeCompare(b.summary.traceId));\n}\n"],"mappings":";;;AAIA,SAAgB,UAAU,SAAgC;CACxD,MAAM,MAAM,IAAI,IAAI,QAAQ,KAAI,SAAQ,KAAK,MAAM,CAAC;CACpD,OAAO,QAAQ,MAAK,SAAQ,CAAC,KAAK,QAAQ,KAAK,QAAQ,MAAK,SAAQ,CAAC,IAAI,IAAI,KAAK,QAAS,CAAC,KAAK,QAAQ;AAC3G;AAEA,SAAgB,WAAW,OAAiC;CAC1D,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,CAAC,KAAK,WAAW,CAAC,KAAK,UAAU,CAAC,OAAO,SAAS,KAAK,UAAU,KAAK,KAAK,aAAa,GAC1F,MAAM,IAAI,MAAM,0EAA0E;EAC5F,cAAA,OAAO,KAAK,SAAS;EACrB,MAAM,QAAQ,OAAO,IAAI,KAAK,OAAO,KAAK,CAAC;EAC3C,MAAM,KAAK,IAAI;EACf,OAAO,IAAI,KAAK,SAAS,KAAK;CAChC;CACA,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,WAAW;EAC3C,MAAM,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,MAAMA,cAAAA,OAAO,EAAE,SAAS,IAAIA,cAAAA,OAAO,EAAE,SAAS,KAAK,EAAE,OAAO,cAAc,EAAE,MAAM,CAAC;EACvH,MAAM,QAAQ,QAAQ;EACtB,MAAM,MAAM,IAAI,IAAI,QAAQ,KAAI,SAAQ,KAAK,MAAM,CAAC;EACpD,MAAM,OAAO,UAAU,OAAO;EAC9B,MAAM,QAAQA,cAAAA,OAAO,MAAM,SAAS;EACpC,MAAM,MAAM,QAAQ,QAAQ,QAAQ,SAAS,KAAK,IAAI,QAAQA,cAAAA,OAAO,KAAK,SAAS,IAAI,KAAK,aAAa,GAAI,GAAG,KAAK;EACrH,MAAM,QAAe;GACnB,SAAS;IAAE;IAAS,SAAS,KAAK;IAAS,WAAW,KAAK;IAAW,WAAW,MAAM;IAAW,aAAa,MAAM,SAAS;IAAM,WAAW,QAAQ;IAAQ,QAAQ,QAAQ,OAAOC,cAAAA,OAAO,CAAC,CAAC;IAAQ,UAAU,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAI,SAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK;GAAE;GACxQ,OAAO;GACP,gBAAgB,CAAC,GAAG,IAAI,IAAI,QAAQ,SAAQ,SAAQ,KAAK,YAAY,CAAC,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;EAC9H;EACA,cAAA,WAAW,KAAK;EAChB,OAAO;CACT,CAAC,CAAC,CAAC,MAAM,GAAG,MAAMD,cAAAA,OAAO,EAAE,QAAQ,SAAS,IAAIA,cAAAA,OAAO,EAAE,QAAQ,SAAS,KAAK,EAAE,QAAQ,QAAQ,cAAc,EAAE,QAAQ,OAAO,CAAC;AACnI"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { Span, Trace } from './api.js';
|
|
2
|
+
/** A trace's root among its start-ordered spans: a parentless span, else the first span whose parent is not in the trace, else the first span. */
|
|
3
|
+
export declare function traceRoot(ordered: readonly Span[]): Span;
|
|
2
4
|
export declare function spanTraces(spans: readonly Span[]): Trace[];
|
|
3
5
|
//# sourceMappingURL=span-traces.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"span-traces.d.ts","sourceRoot":"","sources":["../../../../src/data/traces/otel/span-traces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAGzC,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,KAAK,EAAE,CAyB1D"}
|
|
1
|
+
{"version":3,"file":"span-traces.d.ts","sourceRoot":"","sources":["../../../../src/data/traces/otel/span-traces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAGzC,kJAAkJ;AAClJ,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,CAGxD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,KAAK,EAAE,CAyB1D"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { indexTrace, isError, micros } from "./model.js";
|
|
2
2
|
// src/data/traces/otel/span-traces.ts
|
|
3
|
+
/** A trace's root among its start-ordered spans: a parentless span, else the first span whose parent is not in the trace, else the first span. */
|
|
4
|
+
function traceRoot(ordered) {
|
|
5
|
+
const ids = new Set(ordered.map((span) => span.spanId));
|
|
6
|
+
return ordered.find((span) => !span.parentId) ?? ordered.find((span) => !ids.has(span.parentId)) ?? ordered[0];
|
|
7
|
+
}
|
|
3
8
|
function spanTraces(spans) {
|
|
4
9
|
const groups = /* @__PURE__ */ new Map();
|
|
5
10
|
for (const span of spans) {
|
|
@@ -13,7 +18,7 @@ function spanTraces(spans) {
|
|
|
13
18
|
const ordered = [...group].sort((a, b) => micros(a.startedAt) - micros(b.startedAt) || a.spanId.localeCompare(b.spanId));
|
|
14
19
|
const first = ordered[0];
|
|
15
20
|
const ids = new Set(ordered.map((span) => span.spanId));
|
|
16
|
-
const root =
|
|
21
|
+
const root = traceRoot(ordered);
|
|
17
22
|
const start = micros(first.startedAt);
|
|
18
23
|
const end = ordered.reduce((latest, span) => Math.max(latest, micros(span.startedAt) + span.durationMs * 1e3), start);
|
|
19
24
|
const trace = {
|
|
@@ -34,6 +39,6 @@ function spanTraces(spans) {
|
|
|
34
39
|
return trace;
|
|
35
40
|
}).sort((a, b) => micros(b.summary.startedAt) - micros(a.summary.startedAt) || a.summary.traceId.localeCompare(b.summary.traceId));
|
|
36
41
|
}
|
|
37
|
-
export { spanTraces };
|
|
42
|
+
export { spanTraces, traceRoot };
|
|
38
43
|
|
|
39
44
|
//# sourceMappingURL=span-traces.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"span-traces.js","names":[],"sources":["../../../../src/data/traces/otel/span-traces.ts"],"sourcesContent":["import type { Span, Trace } from \"./api\";\nimport { indexTrace, isError, micros } from \"./model\";\n\nexport function spanTraces(spans: readonly Span[]): Trace[] {\n const groups = new Map<string, Span[]>();\n for (const span of spans) {\n if (!span.traceId || !span.spanId || !Number.isFinite(span.durationMs) || span.durationMs < 0)\n throw new Error(\"Trace spans require traceId, spanId and a finite non-negative durationMs\");\n micros(span.startedAt);\n const group = groups.get(span.traceId) ?? [];\n group.push(span);\n groups.set(span.traceId, group);\n }\n return [...groups].map(([traceId, group]) => {\n const ordered = [...group].sort((a, b) => micros(a.startedAt) - micros(b.startedAt) || a.spanId.localeCompare(b.spanId));\n const first = ordered[0]!;\n const ids = new Set(ordered.map(span => span.spanId));\n const root =
|
|
1
|
+
{"version":3,"file":"span-traces.js","names":[],"sources":["../../../../src/data/traces/otel/span-traces.ts"],"sourcesContent":["import type { Span, Trace } from \"./api\";\nimport { indexTrace, isError, micros } from \"./model\";\n\n/** A trace's root among its start-ordered spans: a parentless span, else the first span whose parent is not in the trace, else the first span. */\nexport function traceRoot(ordered: readonly Span[]): Span {\n const ids = new Set(ordered.map(span => span.spanId));\n return ordered.find(span => !span.parentId) ?? ordered.find(span => !ids.has(span.parentId!)) ?? ordered[0]!;\n}\n\nexport function spanTraces(spans: readonly Span[]): Trace[] {\n const groups = new Map<string, Span[]>();\n for (const span of spans) {\n if (!span.traceId || !span.spanId || !Number.isFinite(span.durationMs) || span.durationMs < 0)\n throw new Error(\"Trace spans require traceId, spanId and a finite non-negative durationMs\");\n micros(span.startedAt);\n const group = groups.get(span.traceId) ?? [];\n group.push(span);\n groups.set(span.traceId, group);\n }\n return [...groups].map(([traceId, group]) => {\n const ordered = [...group].sort((a, b) => micros(a.startedAt) - micros(b.startedAt) || a.spanId.localeCompare(b.spanId));\n const first = ordered[0]!;\n const ids = new Set(ordered.map(span => span.spanId));\n const root = traceRoot(ordered);\n const start = micros(first.startedAt);\n const end = ordered.reduce((latest, span) => Math.max(latest, micros(span.startedAt) + span.durationMs * 1000), start);\n const trace: Trace = {\n summary: { traceId, service: root.service, operation: root.operation, startedAt: first.startedAt, durationMs: (end - start) / 1000, spanCount: ordered.length, errors: ordered.filter(isError).length, services: [...new Set(ordered.map(span => span.service))].sort() },\n spans: ordered,\n missingParents: [...new Set(ordered.flatMap(span => span.parentId && !ids.has(span.parentId) ? [span.parentId] : []))].sort(),\n };\n indexTrace(trace);\n return trace;\n }).sort((a, b) => micros(b.summary.startedAt) - micros(a.summary.startedAt) || a.summary.traceId.localeCompare(b.summary.traceId));\n}\n"],"mappings":";;;AAIA,SAAgB,UAAU,SAAgC;CACxD,MAAM,MAAM,IAAI,IAAI,QAAQ,KAAI,SAAQ,KAAK,MAAM,CAAC;CACpD,OAAO,QAAQ,MAAK,SAAQ,CAAC,KAAK,QAAQ,KAAK,QAAQ,MAAK,SAAQ,CAAC,IAAI,IAAI,KAAK,QAAS,CAAC,KAAK,QAAQ;AAC3G;AAEA,SAAgB,WAAW,OAAiC;CAC1D,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,CAAC,KAAK,WAAW,CAAC,KAAK,UAAU,CAAC,OAAO,SAAS,KAAK,UAAU,KAAK,KAAK,aAAa,GAC1F,MAAM,IAAI,MAAM,0EAA0E;EAC5F,OAAO,KAAK,SAAS;EACrB,MAAM,QAAQ,OAAO,IAAI,KAAK,OAAO,KAAK,CAAC;EAC3C,MAAM,KAAK,IAAI;EACf,OAAO,IAAI,KAAK,SAAS,KAAK;CAChC;CACA,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,WAAW;EAC3C,MAAM,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,SAAS,KAAK,EAAE,OAAO,cAAc,EAAE,MAAM,CAAC;EACvH,MAAM,QAAQ,QAAQ;EACtB,MAAM,MAAM,IAAI,IAAI,QAAQ,KAAI,SAAQ,KAAK,MAAM,CAAC;EACpD,MAAM,OAAO,UAAU,OAAO;EAC9B,MAAM,QAAQ,OAAO,MAAM,SAAS;EACpC,MAAM,MAAM,QAAQ,QAAQ,QAAQ,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,SAAS,IAAI,KAAK,aAAa,GAAI,GAAG,KAAK;EACrH,MAAM,QAAe;GACnB,SAAS;IAAE;IAAS,SAAS,KAAK;IAAS,WAAW,KAAK;IAAW,WAAW,MAAM;IAAW,aAAa,MAAM,SAAS;IAAM,WAAW,QAAQ;IAAQ,QAAQ,QAAQ,OAAO,OAAO,CAAC,CAAC;IAAQ,UAAU,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAI,SAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK;GAAE;GACxQ,OAAO;GACP,gBAAgB,CAAC,GAAG,IAAI,IAAI,QAAQ,SAAQ,SAAQ,KAAK,YAAY,CAAC,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;EAC9H;EACA,WAAW,KAAK;EAChB,OAAO;CACT,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,OAAO,EAAE,QAAQ,SAAS,IAAI,OAAO,EAAE,QAAQ,SAAS,KAAK,EAAE,QAAQ,QAAQ,cAAc,EAAE,QAAQ,OAAO,CAAC;AACnI"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const require_useClickyExport = require("./clicky-export/useClickyExport.cjs");
|
|
2
|
+
const require_clicky_download = require("./clicky-download.cjs");
|
|
3
|
+
const require_useDebugAction = require("./useDebugAction.cjs");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
// src/data/useClickyTableMenu.ts
|
|
6
|
+
/**
|
|
7
|
+
* The overflow-menu actions a Clicky result table carries — export (with its
|
|
8
|
+
* dialog) and debug — for a host that renders a result through its own table.
|
|
9
|
+
* Render `dialog` once alongside the table.
|
|
10
|
+
*/
|
|
11
|
+
function useClickyTableMenu({ url, download, pagination }) {
|
|
12
|
+
const debugAction = require_useDebugAction.useDebugAction();
|
|
13
|
+
const exporter = require_useClickyExport.useClickyExport({
|
|
14
|
+
formats: (0, react.useMemo)(() => require_clicky_download.exportFormatOptions({
|
|
15
|
+
url,
|
|
16
|
+
download
|
|
17
|
+
}), [download, url]),
|
|
18
|
+
scopes: (0, react.useMemo)(() => require_clicky_download.exportScopeOptions(download, pagination), [download, pagination]),
|
|
19
|
+
onDownload: (0, react.useCallback)(({ format, scope }) => require_clicky_download.runClickyDownload({
|
|
20
|
+
url: url ?? "",
|
|
21
|
+
format,
|
|
22
|
+
scope,
|
|
23
|
+
download
|
|
24
|
+
}), [download, url])
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
actions: (0, react.useMemo)(() => [exporter.action, debugAction].filter((action) => action !== void 0), [exporter.action, debugAction]),
|
|
28
|
+
dialog: exporter.dialog
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
exports.useClickyTableMenu = useClickyTableMenu;
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=useClickyTableMenu.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClickyTableMenu.cjs","names":["useDebugAction","useClickyExport","useMemo","exportFormatOptions","exportScopeOptions","useCallback","runClickyDownload"],"sources":["../../src/data/useClickyTableMenu.ts"],"sourcesContent":["import { useCallback, useMemo, type ReactNode } from \"react\";\nimport type { DataTableMenuAction, DataTablePagination } from \"./DataTable\";\nimport { useClickyExport } from \"./clicky-export/useClickyExport\";\nimport {\n exportFormatOptions,\n exportScopeOptions,\n runClickyDownload,\n type ClickyDownloadOptions,\n type ClickyDownloadScope,\n type ClickyRemoteFormat,\n} from \"./clicky-download\";\nimport { useDebugAction } from \"./useDebugAction\";\n\n/**\n * The overflow-menu actions a Clicky result table carries — export (with its\n * dialog) and debug — for a host that renders a result through its own table.\n * Render `dialog` once alongside the table.\n */\nexport function useClickyTableMenu({\n url,\n download,\n pagination,\n}: {\n url?: string | undefined;\n download?: ClickyDownloadOptions | undefined;\n pagination?: DataTablePagination | undefined;\n}): { actions: DataTableMenuAction[]; dialog: ReactNode } {\n // The rows never show the query behind them. \"Debug\" reveals the console,\n // which holds the record for the run that produced these rows.\n const debugAction = useDebugAction();\n const exporter = useClickyExport({\n formats: useMemo(() => exportFormatOptions({ url, download }), [download, url]),\n scopes: useMemo(() => exportScopeOptions(download, pagination), [download, pagination]),\n onDownload: useCallback(\n ({ format, scope }: { format: string; scope: string | undefined }) =>\n runClickyDownload({\n url: url ?? \"\",\n format: format as ClickyRemoteFormat,\n scope: scope as ClickyDownloadScope | undefined,\n download,\n }),\n [download, url],\n ),\n });\n const actions = useMemo(\n () =>\n [exporter.action, debugAction].filter(\n (action): action is DataTableMenuAction => action !== undefined,\n ),\n [exporter.action, debugAction],\n );\n return { actions, dialog: exporter.dialog };\n}\n"],"mappings":";;;;;;;;;;AAkBA,SAAgB,mBAAmB,EACjC,KACA,UACA,cAKwD;CAGxD,MAAM,cAAcA,uBAAAA,eAAe;CACnC,MAAM,WAAWC,wBAAAA,gBAAgB;EAC/B,UAAA,GAASC,MAAAA,QAAAA,OAAcC,wBAAAA,oBAAoB;GAAE;GAAK;EAAS,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC;EAC9E,SAAA,GAAQD,MAAAA,QAAAA,OAAcE,wBAAAA,mBAAmB,UAAU,UAAU,GAAG,CAAC,UAAU,UAAU,CAAC;EACtF,aAAA,GAAYC,MAAAA,YAAAA,EACT,EAAE,QAAQ,YACTC,wBAAAA,kBAAkB;GAChB,KAAK,OAAO;GACJ;GACD;GACP;EACF,CAAC,GACH,CAAC,UAAU,GAAG,CAChB;CACF,CAAC;CAQD,OAAO;EAAE,UAAA,GAPOJ,MAAAA,QAAAA,OAEZ,CAAC,SAAS,QAAQ,WAAW,CAAC,CAAC,QAC5B,WAA0C,WAAW,KAAA,CACxD,GACF,CAAC,SAAS,QAAQ,WAAW,CAEtB;EAAS,QAAQ,SAAS;CAAO;AAC5C"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DataTableMenuAction, DataTablePagination } from './DataTable.js';
|
|
3
|
+
import { ClickyDownloadOptions } from './clicky-download.js';
|
|
4
|
+
/**
|
|
5
|
+
* The overflow-menu actions a Clicky result table carries — export (with its
|
|
6
|
+
* dialog) and debug — for a host that renders a result through its own table.
|
|
7
|
+
* Render `dialog` once alongside the table.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useClickyTableMenu({ url, download, pagination, }: {
|
|
10
|
+
url?: string | undefined;
|
|
11
|
+
download?: ClickyDownloadOptions | undefined;
|
|
12
|
+
pagination?: DataTablePagination | undefined;
|
|
13
|
+
}): {
|
|
14
|
+
actions: DataTableMenuAction[];
|
|
15
|
+
dialog: ReactNode;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useClickyTableMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClickyTableMenu.d.ts","sourceRoot":"","sources":["../../src/data/useClickyTableMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAIL,KAAK,qBAAqB,EAG3B,MAAM,mBAAmB,CAAC;AAG3B;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,GAAG,EACH,QAAQ,EACR,UAAU,GACX,EAAE;IACD,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CAC9C,GAAG;IAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CA0BxD"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useClickyExport } from "./clicky-export/useClickyExport.js";
|
|
2
|
+
import { exportFormatOptions, exportScopeOptions, runClickyDownload } from "./clicky-download.js";
|
|
3
|
+
import { useDebugAction } from "./useDebugAction.js";
|
|
4
|
+
import { useCallback, useMemo } from "react";
|
|
5
|
+
// src/data/useClickyTableMenu.ts
|
|
6
|
+
/**
|
|
7
|
+
* The overflow-menu actions a Clicky result table carries — export (with its
|
|
8
|
+
* dialog) and debug — for a host that renders a result through its own table.
|
|
9
|
+
* Render `dialog` once alongside the table.
|
|
10
|
+
*/
|
|
11
|
+
function useClickyTableMenu({ url, download, pagination }) {
|
|
12
|
+
const debugAction = useDebugAction();
|
|
13
|
+
const exporter = useClickyExport({
|
|
14
|
+
formats: useMemo(() => exportFormatOptions({
|
|
15
|
+
url,
|
|
16
|
+
download
|
|
17
|
+
}), [download, url]),
|
|
18
|
+
scopes: useMemo(() => exportScopeOptions(download, pagination), [download, pagination]),
|
|
19
|
+
onDownload: useCallback(({ format, scope }) => runClickyDownload({
|
|
20
|
+
url: url ?? "",
|
|
21
|
+
format,
|
|
22
|
+
scope,
|
|
23
|
+
download
|
|
24
|
+
}), [download, url])
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
actions: useMemo(() => [exporter.action, debugAction].filter((action) => action !== void 0), [exporter.action, debugAction]),
|
|
28
|
+
dialog: exporter.dialog
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export { useClickyTableMenu };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=useClickyTableMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClickyTableMenu.js","names":[],"sources":["../../src/data/useClickyTableMenu.ts"],"sourcesContent":["import { useCallback, useMemo, type ReactNode } from \"react\";\nimport type { DataTableMenuAction, DataTablePagination } from \"./DataTable\";\nimport { useClickyExport } from \"./clicky-export/useClickyExport\";\nimport {\n exportFormatOptions,\n exportScopeOptions,\n runClickyDownload,\n type ClickyDownloadOptions,\n type ClickyDownloadScope,\n type ClickyRemoteFormat,\n} from \"./clicky-download\";\nimport { useDebugAction } from \"./useDebugAction\";\n\n/**\n * The overflow-menu actions a Clicky result table carries — export (with its\n * dialog) and debug — for a host that renders a result through its own table.\n * Render `dialog` once alongside the table.\n */\nexport function useClickyTableMenu({\n url,\n download,\n pagination,\n}: {\n url?: string | undefined;\n download?: ClickyDownloadOptions | undefined;\n pagination?: DataTablePagination | undefined;\n}): { actions: DataTableMenuAction[]; dialog: ReactNode } {\n // The rows never show the query behind them. \"Debug\" reveals the console,\n // which holds the record for the run that produced these rows.\n const debugAction = useDebugAction();\n const exporter = useClickyExport({\n formats: useMemo(() => exportFormatOptions({ url, download }), [download, url]),\n scopes: useMemo(() => exportScopeOptions(download, pagination), [download, pagination]),\n onDownload: useCallback(\n ({ format, scope }: { format: string; scope: string | undefined }) =>\n runClickyDownload({\n url: url ?? \"\",\n format: format as ClickyRemoteFormat,\n scope: scope as ClickyDownloadScope | undefined,\n download,\n }),\n [download, url],\n ),\n });\n const actions = useMemo(\n () =>\n [exporter.action, debugAction].filter(\n (action): action is DataTableMenuAction => action !== undefined,\n ),\n [exporter.action, debugAction],\n );\n return { actions, dialog: exporter.dialog };\n}\n"],"mappings":";;;;;;;;;;AAkBA,SAAgB,mBAAmB,EACjC,KACA,UACA,cAKwD;CAGxD,MAAM,cAAc,eAAe;CACnC,MAAM,WAAW,gBAAgB;EAC/B,SAAS,cAAc,oBAAoB;GAAE;GAAK;EAAS,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC;EAC9E,QAAQ,cAAc,mBAAmB,UAAU,UAAU,GAAG,CAAC,UAAU,UAAU,CAAC;EACtF,YAAY,aACT,EAAE,QAAQ,YACT,kBAAkB;GAChB,KAAK,OAAO;GACJ;GACD;GACP;EACF,CAAC,GACH,CAAC,UAAU,GAAG,CAChB;CACF,CAAC;CAQD,OAAO;EAAE,SAPO,cAEZ,CAAC,SAAS,QAAQ,WAAW,CAAC,CAAC,QAC5B,WAA0C,WAAW,KAAA,CACxD,GACF,CAAC,SAAS,QAAQ,WAAW,CAEtB;EAAS,QAAQ,SAAS;CAAO;AAC5C"}
|
|
@@ -14,9 +14,9 @@ function detectMode() {
|
|
|
14
14
|
/** Resolve build + runtime version metadata. */
|
|
15
15
|
function getVersionInfo() {
|
|
16
16
|
return {
|
|
17
|
-
commit: read(() => "
|
|
18
|
-
tag: read(() => "clicky-ui@0.3.
|
|
19
|
-
date: read(() => "2026-11-
|
|
17
|
+
commit: read(() => "72e079b38", ""),
|
|
18
|
+
tag: read(() => "clicky-ui@0.3.58", ""),
|
|
19
|
+
date: read(() => "2026-11-10T16:45:28.650Z", ""),
|
|
20
20
|
dirty: read(() => true, false),
|
|
21
21
|
mode: detectMode()
|
|
22
22
|
};
|
|
@@ -14,9 +14,9 @@ function detectMode() {
|
|
|
14
14
|
/** Resolve build + runtime version metadata. */
|
|
15
15
|
function getVersionInfo() {
|
|
16
16
|
return {
|
|
17
|
-
commit: read(() => "
|
|
18
|
-
tag: read(() => "clicky-ui@0.3.
|
|
19
|
-
date: read(() => "2026-11-
|
|
17
|
+
commit: read(() => "72e079b38", ""),
|
|
18
|
+
tag: read(() => "clicky-ui@0.3.58", ""),
|
|
19
|
+
date: read(() => "2026-11-10T16:44:55.856Z", ""),
|
|
20
20
|
dirty: read(() => true, false),
|
|
21
21
|
mode: detectMode()
|
|
22
22
|
};
|