@flanksource/clicky-ui 0.3.22 → 0.3.23
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/components/CountryFlag.cjs +55 -0
- package/dist/components/CountryFlag.cjs.map +1 -0
- package/dist/components/CountryFlag.d.ts +8 -0
- package/dist/components/CountryFlag.d.ts.map +1 -0
- package/dist/components/CountryFlag.js +38 -0
- package/dist/components/CountryFlag.js.map +1 -0
- package/dist/components/CountryPicker.cjs +35 -0
- package/dist/components/CountryPicker.cjs.map +1 -0
- package/dist/components/CountryPicker.d.ts +4 -0
- package/dist/components/CountryPicker.d.ts.map +1 -0
- package/dist/components/CountryPicker.js +35 -0
- package/dist/components/CountryPicker.js.map +1 -0
- package/dist/components/SplitButton.cjs +3 -2
- package/dist/components/SplitButton.cjs.map +1 -1
- package/dist/components/SplitButton.d.ts +6 -1
- package/dist/components/SplitButton.d.ts.map +1 -1
- package/dist/components/SplitButton.js +3 -2
- package/dist/components/SplitButton.js.map +1 -1
- package/dist/components/country-options.cjs +34 -0
- package/dist/components/country-options.cjs.map +1 -0
- package/dist/components/country-options.d.ts +8 -0
- package/dist/components/country-options.d.ts.map +1 -0
- package/dist/components/country-options.js +34 -0
- package/dist/components/country-options.js.map +1 -0
- package/dist/components.cjs +11 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +4 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +11 -0
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +4 -1
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +4 -1
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/CodeDiff.cjs +3 -18
- package/dist/data/CodeDiff.cjs.map +1 -1
- package/dist/data/CodeDiff.d.ts.map +1 -1
- package/dist/data/CodeDiff.js +3 -18
- package/dist/data/CodeDiff.js.map +1 -1
- package/dist/data/DataTable.cjs +182 -64
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +9 -1
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.grouping.cjs +26 -0
- package/dist/data/DataTable.grouping.cjs.map +1 -1
- package/dist/data/DataTable.grouping.d.ts +38 -0
- package/dist/data/DataTable.grouping.d.ts.map +1 -1
- package/dist/data/DataTable.grouping.js +26 -0
- package/dist/data/DataTable.grouping.js.map +1 -1
- package/dist/data/DataTable.js +183 -65
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/DataTableGroupingControls.cjs +84 -0
- package/dist/data/DataTableGroupingControls.cjs.map +1 -0
- package/dist/data/DataTableGroupingControls.d.ts +17 -0
- package/dist/data/DataTableGroupingControls.d.ts.map +1 -0
- package/dist/data/DataTableGroupingControls.js +84 -0
- package/dist/data/DataTableGroupingControls.js.map +1 -0
- package/dist/data/HighlightedTokens.cjs +21 -0
- package/dist/data/HighlightedTokens.cjs.map +1 -0
- package/dist/data/HighlightedTokens.d.ts +6 -0
- package/dist/data/HighlightedTokens.d.ts.map +1 -0
- package/dist/data/HighlightedTokens.js +21 -0
- package/dist/data/HighlightedTokens.js.map +1 -0
- package/dist/data/code-highlight.cjs +0 -6
- package/dist/data/code-highlight.cjs.map +1 -1
- package/dist/data/code-highlight.d.ts +4 -3
- package/dist/data/code-highlight.d.ts.map +1 -1
- package/dist/data/code-highlight.js +1 -7
- package/dist/data/code-highlight.js.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +6 -2
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +8 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +6 -2
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.cjs +29 -5
- package/dist/data/diagnostics/ErrorDetails.cjs.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts +3 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.js +29 -5
- package/dist/data/diagnostics/ErrorDetails.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.cjs +54 -24
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts +2 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.js +54 -24
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.utils.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts +3 -0
- package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.utils.js.map +1 -1
- package/dist/data/diagnostics/JvmStackTrace.cjs +14 -30
- package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
- package/dist/data/diagnostics/JvmStackTrace.d.ts +6 -9
- package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
- package/dist/data/diagnostics/JvmStackTrace.js +15 -31
- package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
- package/dist/data/diagnostics/RenderedStackTrace.cjs +14 -144
- package/dist/data/diagnostics/RenderedStackTrace.cjs.map +1 -1
- package/dist/data/diagnostics/RenderedStackTrace.d.ts +6 -6
- package/dist/data/diagnostics/RenderedStackTrace.d.ts.map +1 -1
- package/dist/data/diagnostics/RenderedStackTrace.js +15 -145
- package/dist/data/diagnostics/RenderedStackTrace.js.map +1 -1
- package/dist/data/diagnostics/StackFrameRow.cjs +65 -0
- package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -0
- package/dist/data/diagnostics/StackFrameRow.d.ts +13 -0
- package/dist/data/diagnostics/StackFrameRow.d.ts.map +1 -0
- package/dist/data/diagnostics/StackFrameRow.js +65 -0
- package/dist/data/diagnostics/StackFrameRow.js.map +1 -0
- package/dist/data/diagnostics/ThreadCard.cjs +9 -2
- package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
- package/dist/data/diagnostics/ThreadCard.d.ts +3 -1
- package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
- package/dist/data/diagnostics/ThreadCard.js +9 -2
- package/dist/data/diagnostics/ThreadCard.js.map +1 -1
- package/dist/data/diagnostics/frame-heuristics.cjs +26 -0
- package/dist/data/diagnostics/frame-heuristics.cjs.map +1 -0
- package/dist/data/diagnostics/frame-heuristics.d.ts +5 -0
- package/dist/data/diagnostics/frame-heuristics.d.ts.map +1 -0
- package/dist/data/diagnostics/frame-heuristics.js +26 -0
- package/dist/data/diagnostics/frame-heuristics.js.map +1 -0
- package/dist/data/diagnostics/jvm-stacktrace.cjs +5 -7
- package/dist/data/diagnostics/jvm-stacktrace.cjs.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.js +5 -7
- package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -1
- package/dist/data/diagnostics/stacktrace-parse.cjs +4 -9
- package/dist/data/diagnostics/stacktrace-parse.cjs.map +1 -1
- package/dist/data/diagnostics/stacktrace-parse.d.ts.map +1 -1
- package/dist/data/diagnostics/stacktrace-parse.js +4 -9
- package/dist/data/diagnostics/stacktrace-parse.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +7 -1
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +4 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +8 -2
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +18 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/rpc/CommandForm.cjs +8 -18
- package/dist/rpc/CommandForm.cjs.map +1 -1
- package/dist/rpc/CommandForm.d.ts +8 -2
- package/dist/rpc/CommandForm.d.ts.map +1 -1
- package/dist/rpc/CommandForm.js +9 -19
- package/dist/rpc/CommandForm.js.map +1 -1
- package/dist/rpc/OperationActionDialog.cjs +3 -3
- package/dist/rpc/OperationActionDialog.cjs.map +1 -1
- package/dist/rpc/OperationActionDialog.js +3 -3
- package/dist/rpc/OperationActionDialog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs +7 -7
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js +7 -7
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/apiClient.cjs +17 -3
- package/dist/rpc/apiClient.cjs.map +1 -1
- package/dist/rpc/apiClient.d.ts +4 -4
- package/dist/rpc/apiClient.d.ts.map +1 -1
- package/dist/rpc/apiClient.js +17 -3
- package/dist/rpc/apiClient.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +5 -9
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts +3 -3
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +5 -9
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +1 -0
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/rpc/useOperations.cjs.map +1 -1
- package/dist/rpc/useOperations.d.ts +4 -4
- package/dist/rpc/useOperations.d.ts.map +1 -1
- package/dist/rpc/useOperations.js.map +1 -1
- package/dist/rpc.d.ts +2 -2
- package/dist/rpc.d.ts.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -1
|
@@ -205,11 +205,22 @@ function StackFrameRow({ frame, index }) {
|
|
|
205
205
|
}
|
|
206
206
|
);
|
|
207
207
|
}
|
|
208
|
+
const COPY_BADGE_LAYOUT = {
|
|
209
|
+
clipped: { frame: "items-center overflow-hidden", label: "", value: "truncate", icon: "" },
|
|
210
|
+
wrapped: {
|
|
211
|
+
frame: "items-stretch",
|
|
212
|
+
label: "flex items-center",
|
|
213
|
+
value: "whitespace-normal break-all",
|
|
214
|
+
icon: "self-center"
|
|
215
|
+
}
|
|
216
|
+
};
|
|
208
217
|
function CopyBadge({
|
|
209
218
|
label,
|
|
210
219
|
value,
|
|
211
|
-
className = ""
|
|
220
|
+
className = "",
|
|
221
|
+
wrap = false
|
|
212
222
|
}) {
|
|
223
|
+
const layout = COPY_BADGE_LAYOUT[wrap ? "wrapped" : "clipped"];
|
|
213
224
|
return /* @__PURE__ */ jsxs(
|
|
214
225
|
"button",
|
|
215
226
|
{
|
|
@@ -217,13 +228,26 @@ function CopyBadge({
|
|
|
217
228
|
onClick: () => copyText(value),
|
|
218
229
|
title: `Copy ${label}`,
|
|
219
230
|
className: [
|
|
220
|
-
"inline-flex max-w-full
|
|
231
|
+
"inline-flex max-w-full rounded-md border border-border bg-background/80 text-left text-xs hover:border-primary/40 hover:bg-background",
|
|
232
|
+
layout.frame,
|
|
221
233
|
className
|
|
222
234
|
].filter(Boolean).join(" "),
|
|
223
235
|
children: [
|
|
224
|
-
/* @__PURE__ */ jsx(
|
|
225
|
-
|
|
226
|
-
|
|
236
|
+
/* @__PURE__ */ jsx(
|
|
237
|
+
"span",
|
|
238
|
+
{
|
|
239
|
+
className: ["shrink-0 bg-muted px-2 py-1 font-medium text-muted-foreground", layout.label].filter(Boolean).join(" "),
|
|
240
|
+
children: label
|
|
241
|
+
}
|
|
242
|
+
),
|
|
243
|
+
/* @__PURE__ */ jsx("span", { className: ["min-w-0 px-2 py-1 font-mono text-foreground", layout.value].join(" "), children: value }),
|
|
244
|
+
/* @__PURE__ */ jsx(
|
|
245
|
+
Icon,
|
|
246
|
+
{
|
|
247
|
+
icon: UiCopy,
|
|
248
|
+
className: ["mr-1.5 h-3 w-3 shrink-0 text-muted-foreground", layout.icon].filter(Boolean).join(" ")
|
|
249
|
+
}
|
|
250
|
+
)
|
|
227
251
|
]
|
|
228
252
|
}
|
|
229
253
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorDetails.js","sources":["../../../src/data/diagnostics/ErrorDetails.tsx"],"sourcesContent":["import { useState, type MouseEvent, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport {\n UiCheck,\n UiChevronRight,\n UiCopy,\n UiDebugStepOver,\n UiMethod,\n UiWarningTriangle,\n} from \"../../icons\";\nimport {\n compactStackPath,\n isApplicationStackFrame,\n parseDiagnosticsStackTrace,\n parseInlineJsonContextValue,\n type ErrorDiagnostics,\n type ErrorStackFrame,\n} from \"./error-diagnostics\";\n\nexport type ErrorDetailsProps = {\n diagnostics: ErrorDiagnostics;\n // Heading above the message. Defaults to \"Error\"; callers that already know\n // what failed (\"Failed to load /api/v1/profile/…\") say so instead.\n title?: string;\n // Optional renderer for context values that parse as JSON. Defaults to a\n // CopyBadge with the raw string. MC's playbook view passes a richer JsonView\n // here; smaller consumers (plugin iframes) can leave it unset.\n renderJsonContext?: (entry: { label: string; value: string; data: unknown }) => ReactNode;\n};\n\nexport function ErrorDetails({ diagnostics, title = \"Error\", renderJsonContext }: ErrorDetailsProps) {\n const [copyState, setCopyState] = useState<\"idle\" | \"copied\" | \"failed\">(\"idle\");\n const scalarContext = diagnostics.context.filter(\n ([, value]) => !parseInlineJsonContextValue(value),\n );\n const jsonContext = diagnostics.context\n .map(([label, value]) => ({\n label,\n value,\n data: parseInlineJsonContextValue(value),\n }))\n .filter(\n (entry): entry is { label: string; value: string; data: unknown } => entry.data !== null,\n );\n const copyDiagnostics = async (event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (!navigator.clipboard?.writeText) {\n setCopyState(\"failed\");\n return;\n }\n try {\n await navigator.clipboard.writeText(diagnosticReport(diagnostics, title));\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n };\n return (\n <details className=\"group rounded-md border border-destructive/30 bg-destructive/5\">\n <summary className=\"flex cursor-pointer list-none items-start gap-2 p-3\">\n <Icon icon={UiWarningTriangle} className=\"mt-0.5 shrink-0 text-destructive\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-sm font-semibold text-destructive\">{title}</div>\n <div className=\"mt-1 whitespace-pre-wrap text-sm text-destructive\">\n {diagnostics.message}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-2 text-xs font-medium text-muted-foreground sm:flex-row sm:items-center sm:gap-3\">\n <button\n type=\"button\"\n aria-label={\n copyState === \"copied\"\n ? \"Copied\"\n : copyState === \"failed\"\n ? \"Copy failed\"\n : \"Copy error details\"\n }\n title=\"Copy message, trace, time, context, and stack trace\"\n className=\"inline-flex items-center gap-1 hover:text-foreground\"\n onClick={(event) => void copyDiagnostics(event)}\n >\n <Icon icon={copyState === \"copied\" ? UiCheck : UiCopy} />\n <span aria-live=\"polite\">\n {copyState === \"copied\"\n ? \"Copied\"\n : copyState === \"failed\"\n ? \"Copy failed\"\n : \"Copy\"}\n </span>\n </button>\n <span className=\"inline-flex items-center gap-1 hover:text-foreground\">\n <span className=\"group-open:hidden\">More details</span>\n <span className=\"hidden group-open:inline\">Less details</span>\n <Icon\n icon={UiChevronRight}\n className=\"shrink-0 transition-transform group-open:rotate-90\"\n />\n </span>\n </div>\n </summary>\n <div className=\"grid gap-3 border-t border-destructive/20 p-3 pt-2\">\n {(diagnostics.trace || diagnostics.time) && (\n <div className=\"flex min-w-0 flex-wrap gap-2\">\n {diagnostics.trace && (\n <CopyBadge label=\"Trace\" value={diagnostics.trace} className=\"max-w-full\" />\n )}\n {diagnostics.time && (\n <span className=\"inline-flex max-w-full items-center overflow-hidden rounded-md border border-border bg-background/80 text-xs\">\n <span className=\"shrink-0 bg-muted px-2 py-1 font-medium text-muted-foreground\">\n Time\n </span>\n <span className=\"min-w-0 truncate px-2 py-1 font-mono text-foreground\">\n {diagnostics.time}\n </span>\n </span>\n )}\n </div>\n )}\n {diagnostics.context.length > 0 && (\n <div className=\"min-w-0\">\n <div className=\"mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Context\n </div>\n {scalarContext.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {scalarContext.map(([label, value]) => (\n <CopyBadge key={`${label}:${value}`} label={label} value={value} />\n ))}\n </div>\n )}\n {jsonContext.length > 0 && (\n <div className=\"mt-2 grid gap-2\">\n {jsonContext.map((entry) =>\n renderJsonContext ? (\n <span key={`${entry.label}:${entry.value}`}>{renderJsonContext(entry)}</span>\n ) : (\n <CopyBadge\n key={`${entry.label}:${entry.value}`}\n label={entry.label}\n value={entry.value}\n />\n ),\n )}\n </div>\n )}\n </div>\n )}\n {diagnostics.details?.map((detail) => (\n <div key={detail.label} className=\"min-w-0\">\n <div className=\"mb-1.5 flex min-w-0 items-center justify-between gap-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {detail.label}\n </div>\n <button\n type=\"button\"\n onClick={() => copyText(detail.value)}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiCopy} />\n copy\n </button>\n </div>\n {/* break-all because a response body is one long token as often\n as not, and pre-wrap alone only breaks on whitespace. */}\n <pre className=\"max-h-64 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted p-2 font-mono text-xs leading-5 text-foreground\">\n {detail.value}\n </pre>\n </div>\n ))}\n {diagnostics.stacktrace && (\n <div className=\"min-w-0\">\n <div className=\"mb-1.5 flex min-w-0 items-center justify-between gap-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Stack trace\n </div>\n <button\n type=\"button\"\n onClick={() => copyText(diagnostics.stacktrace ?? \"\")}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiCopy} />\n copy\n </button>\n </div>\n <PrettyStackTrace stacktrace={diagnostics.stacktrace} />\n </div>\n )}\n </div>\n </details>\n );\n}\n\nfunction diagnosticReport(diagnostics: ErrorDiagnostics, title: string): string {\n const lines = [`${title}: ${diagnostics.message}`];\n if (diagnostics.trace) lines.push(`Trace: ${diagnostics.trace}`);\n if (diagnostics.time) lines.push(`Time: ${diagnostics.time}`);\n if (diagnostics.context.length > 0) {\n lines.push(\n \"\",\n \"Context:\",\n ...diagnostics.context.map(([label, value]) => `${label}: ${value}`),\n );\n }\n for (const detail of diagnostics.details ?? []) {\n lines.push(\"\", `${detail.label}:`, detail.value);\n }\n if (diagnostics.stacktrace) {\n lines.push(\"\", \"Stack trace:\", diagnostics.stacktrace);\n }\n return lines.join(\"\\n\");\n}\n\nexport function PrettyStackTrace({ stacktrace }: { stacktrace: string }) {\n const parsed = parseDiagnosticsStackTrace(stacktrace);\n if (parsed.frames.length === 0) {\n return (\n <pre className=\"max-h-72 overflow-auto whitespace-pre-wrap rounded-md bg-slate-950 p-3 font-mono text-xs leading-5 text-slate-200\">\n {stacktrace}\n </pre>\n );\n }\n\n return (\n <div className=\"max-h-96 min-h-40 overflow-auto rounded-md border border-border bg-background p-2\">\n <div className=\"mb-2 flex items-center justify-between gap-2 text-[11px] text-muted-foreground\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"rounded-full bg-red-100 px-2 py-0.5 text-red-700\">error</span>\n <span>{parsed.frames.length} frames</span>\n </div>\n </div>\n {parsed.headline && (\n <div className=\"mb-2 rounded-md bg-red-50 px-2 py-1.5 font-mono text-[11px] leading-4 text-red-700\">\n {parsed.headline}\n </div>\n )}\n <div className=\"space-y-0.5\">\n {parsed.frames.map((frame, index) => (\n <StackFrameRow key={`${frame.file}:${frame.line}:${index}`} frame={frame} index={index} />\n ))}\n </div>\n {parsed.unparsed.length > 0 && (\n <pre className=\"mt-2 whitespace-pre-wrap rounded bg-muted p-2 font-mono text-[11px] leading-4 text-muted-foreground\">\n {parsed.unparsed.join(\"\\n\")}\n </pre>\n )}\n </div>\n );\n}\n\nfunction StackFrameRow({ frame, index }: { frame: ErrorStackFrame; index: number }) {\n const appFrame = isApplicationStackFrame(frame.file);\n return (\n <button\n type=\"button\"\n onClick={() => copyText(frame.raw)}\n title=\"Copy stack frame\"\n className={[\n \"block w-full rounded px-1.5 py-1 text-left hover:bg-accent/50\",\n appFrame ? \"text-foreground\" : \"text-muted-foreground\",\n ].join(\" \")}\n >\n <div className=\"flex min-w-0 items-start gap-1.5\">\n <Icon\n icon={appFrame ? UiMethod : UiDebugStepOver}\n className=\"mt-0.5 shrink-0 text-[11px]\"\n />\n <div className=\"min-w-0\">\n <div className=\"break-all font-mono text-[11px] font-semibold leading-4\">\n <span className=\"mr-2 text-[10px] font-normal opacity-60\">#{index + 1}</span>\n {frame.functionName || \"unknown function\"}\n <span className=\"ml-2 text-[10px] font-normal opacity-80\">\n {compactStackPath(frame.file)}:{frame.line}\n </span>\n </div>\n </div>\n </div>\n </button>\n );\n}\n\nexport function CopyBadge({\n label,\n value,\n className = \"\",\n}: {\n label: string;\n value: string;\n className?: string;\n}) {\n return (\n <button\n type=\"button\"\n onClick={() => copyText(value)}\n title={`Copy ${label}`}\n className={[\n \"inline-flex max-w-full items-center overflow-hidden rounded-md border border-border bg-background/80 text-left text-xs hover:border-primary/40 hover:bg-background\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n <span className=\"shrink-0 bg-muted px-2 py-1 font-medium text-muted-foreground\">{label}</span>\n <span className=\"min-w-0 truncate px-2 py-1 font-mono text-foreground\">{value}</span>\n <Icon icon={UiCopy} className=\"mr-1.5 h-3 w-3 shrink-0 text-muted-foreground\" />\n </button>\n );\n}\n\nfunction copyText(value: string) {\n if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n void navigator.clipboard.writeText(value);\n }\n}\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ErrorDetails.js","sources":["../../../src/data/diagnostics/ErrorDetails.tsx"],"sourcesContent":["import { useState, type MouseEvent, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport {\n UiCheck,\n UiChevronRight,\n UiCopy,\n UiDebugStepOver,\n UiMethod,\n UiWarningTriangle,\n} from \"../../icons\";\nimport {\n compactStackPath,\n isApplicationStackFrame,\n parseDiagnosticsStackTrace,\n parseInlineJsonContextValue,\n type ErrorDiagnostics,\n type ErrorStackFrame,\n} from \"./error-diagnostics\";\n\nexport type ErrorDetailsProps = {\n diagnostics: ErrorDiagnostics;\n // Heading above the message. Defaults to \"Error\"; callers that already know\n // what failed (\"Failed to load /api/v1/profile/…\") say so instead.\n title?: string;\n // Optional renderer for context values that parse as JSON. Defaults to a\n // CopyBadge with the raw string. MC's playbook view passes a richer JsonView\n // here; smaller consumers (plugin iframes) can leave it unset.\n renderJsonContext?: (entry: { label: string; value: string; data: unknown }) => ReactNode;\n};\n\nexport function ErrorDetails({ diagnostics, title = \"Error\", renderJsonContext }: ErrorDetailsProps) {\n const [copyState, setCopyState] = useState<\"idle\" | \"copied\" | \"failed\">(\"idle\");\n const scalarContext = diagnostics.context.filter(\n ([, value]) => !parseInlineJsonContextValue(value),\n );\n const jsonContext = diagnostics.context\n .map(([label, value]) => ({\n label,\n value,\n data: parseInlineJsonContextValue(value),\n }))\n .filter(\n (entry): entry is { label: string; value: string; data: unknown } => entry.data !== null,\n );\n const copyDiagnostics = async (event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (!navigator.clipboard?.writeText) {\n setCopyState(\"failed\");\n return;\n }\n try {\n await navigator.clipboard.writeText(diagnosticReport(diagnostics, title));\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n };\n return (\n <details className=\"group rounded-md border border-destructive/30 bg-destructive/5\">\n <summary className=\"flex cursor-pointer list-none items-start gap-2 p-3\">\n <Icon icon={UiWarningTriangle} className=\"mt-0.5 shrink-0 text-destructive\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-sm font-semibold text-destructive\">{title}</div>\n <div className=\"mt-1 whitespace-pre-wrap text-sm text-destructive\">\n {diagnostics.message}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-2 text-xs font-medium text-muted-foreground sm:flex-row sm:items-center sm:gap-3\">\n <button\n type=\"button\"\n aria-label={\n copyState === \"copied\"\n ? \"Copied\"\n : copyState === \"failed\"\n ? \"Copy failed\"\n : \"Copy error details\"\n }\n title=\"Copy message, trace, time, context, and stack trace\"\n className=\"inline-flex items-center gap-1 hover:text-foreground\"\n onClick={(event) => void copyDiagnostics(event)}\n >\n <Icon icon={copyState === \"copied\" ? UiCheck : UiCopy} />\n <span aria-live=\"polite\">\n {copyState === \"copied\"\n ? \"Copied\"\n : copyState === \"failed\"\n ? \"Copy failed\"\n : \"Copy\"}\n </span>\n </button>\n <span className=\"inline-flex items-center gap-1 hover:text-foreground\">\n <span className=\"group-open:hidden\">More details</span>\n <span className=\"hidden group-open:inline\">Less details</span>\n <Icon\n icon={UiChevronRight}\n className=\"shrink-0 transition-transform group-open:rotate-90\"\n />\n </span>\n </div>\n </summary>\n <div className=\"grid gap-3 border-t border-destructive/20 p-3 pt-2\">\n {(diagnostics.trace || diagnostics.time) && (\n <div className=\"flex min-w-0 flex-wrap gap-2\">\n {diagnostics.trace && (\n <CopyBadge label=\"Trace\" value={diagnostics.trace} className=\"max-w-full\" />\n )}\n {diagnostics.time && (\n <span className=\"inline-flex max-w-full items-center overflow-hidden rounded-md border border-border bg-background/80 text-xs\">\n <span className=\"shrink-0 bg-muted px-2 py-1 font-medium text-muted-foreground\">\n Time\n </span>\n <span className=\"min-w-0 truncate px-2 py-1 font-mono text-foreground\">\n {diagnostics.time}\n </span>\n </span>\n )}\n </div>\n )}\n {diagnostics.context.length > 0 && (\n <div className=\"min-w-0\">\n <div className=\"mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Context\n </div>\n {scalarContext.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {scalarContext.map(([label, value]) => (\n <CopyBadge key={`${label}:${value}`} label={label} value={value} />\n ))}\n </div>\n )}\n {jsonContext.length > 0 && (\n <div className=\"mt-2 grid gap-2\">\n {jsonContext.map((entry) =>\n renderJsonContext ? (\n <span key={`${entry.label}:${entry.value}`}>{renderJsonContext(entry)}</span>\n ) : (\n <CopyBadge\n key={`${entry.label}:${entry.value}`}\n label={entry.label}\n value={entry.value}\n />\n ),\n )}\n </div>\n )}\n </div>\n )}\n {diagnostics.details?.map((detail) => (\n <div key={detail.label} className=\"min-w-0\">\n <div className=\"mb-1.5 flex min-w-0 items-center justify-between gap-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {detail.label}\n </div>\n <button\n type=\"button\"\n onClick={() => copyText(detail.value)}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiCopy} />\n copy\n </button>\n </div>\n {/* break-all because a response body is one long token as often\n as not, and pre-wrap alone only breaks on whitespace. */}\n <pre className=\"max-h-64 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted p-2 font-mono text-xs leading-5 text-foreground\">\n {detail.value}\n </pre>\n </div>\n ))}\n {diagnostics.stacktrace && (\n <div className=\"min-w-0\">\n <div className=\"mb-1.5 flex min-w-0 items-center justify-between gap-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Stack trace\n </div>\n <button\n type=\"button\"\n onClick={() => copyText(diagnostics.stacktrace ?? \"\")}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiCopy} />\n copy\n </button>\n </div>\n <PrettyStackTrace stacktrace={diagnostics.stacktrace} />\n </div>\n )}\n </div>\n </details>\n );\n}\n\nfunction diagnosticReport(diagnostics: ErrorDiagnostics, title: string): string {\n const lines = [`${title}: ${diagnostics.message}`];\n if (diagnostics.trace) lines.push(`Trace: ${diagnostics.trace}`);\n if (diagnostics.time) lines.push(`Time: ${diagnostics.time}`);\n if (diagnostics.context.length > 0) {\n lines.push(\n \"\",\n \"Context:\",\n ...diagnostics.context.map(([label, value]) => `${label}: ${value}`),\n );\n }\n for (const detail of diagnostics.details ?? []) {\n lines.push(\"\", `${detail.label}:`, detail.value);\n }\n if (diagnostics.stacktrace) {\n lines.push(\"\", \"Stack trace:\", diagnostics.stacktrace);\n }\n return lines.join(\"\\n\");\n}\n\nexport function PrettyStackTrace({ stacktrace }: { stacktrace: string }) {\n const parsed = parseDiagnosticsStackTrace(stacktrace);\n if (parsed.frames.length === 0) {\n return (\n <pre className=\"max-h-72 overflow-auto whitespace-pre-wrap rounded-md bg-slate-950 p-3 font-mono text-xs leading-5 text-slate-200\">\n {stacktrace}\n </pre>\n );\n }\n\n return (\n <div className=\"max-h-96 min-h-40 overflow-auto rounded-md border border-border bg-background p-2\">\n <div className=\"mb-2 flex items-center justify-between gap-2 text-[11px] text-muted-foreground\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"rounded-full bg-red-100 px-2 py-0.5 text-red-700\">error</span>\n <span>{parsed.frames.length} frames</span>\n </div>\n </div>\n {parsed.headline && (\n <div className=\"mb-2 rounded-md bg-red-50 px-2 py-1.5 font-mono text-[11px] leading-4 text-red-700\">\n {parsed.headline}\n </div>\n )}\n <div className=\"space-y-0.5\">\n {parsed.frames.map((frame, index) => (\n <StackFrameRow key={`${frame.file}:${frame.line}:${index}`} frame={frame} index={index} />\n ))}\n </div>\n {parsed.unparsed.length > 0 && (\n <pre className=\"mt-2 whitespace-pre-wrap rounded bg-muted p-2 font-mono text-[11px] leading-4 text-muted-foreground\">\n {parsed.unparsed.join(\"\\n\")}\n </pre>\n )}\n </div>\n );\n}\n\nfunction StackFrameRow({ frame, index }: { frame: ErrorStackFrame; index: number }) {\n const appFrame = isApplicationStackFrame(frame.file);\n return (\n <button\n type=\"button\"\n onClick={() => copyText(frame.raw)}\n title=\"Copy stack frame\"\n className={[\n \"block w-full rounded px-1.5 py-1 text-left hover:bg-accent/50\",\n appFrame ? \"text-foreground\" : \"text-muted-foreground\",\n ].join(\" \")}\n >\n <div className=\"flex min-w-0 items-start gap-1.5\">\n <Icon\n icon={appFrame ? UiMethod : UiDebugStepOver}\n className=\"mt-0.5 shrink-0 text-[11px]\"\n />\n <div className=\"min-w-0\">\n <div className=\"break-all font-mono text-[11px] font-semibold leading-4\">\n <span className=\"mr-2 text-[10px] font-normal opacity-60\">#{index + 1}</span>\n {frame.functionName || \"unknown function\"}\n <span className=\"ml-2 text-[10px] font-normal opacity-80\">\n {compactStackPath(frame.file)}:{frame.line}\n </span>\n </div>\n </div>\n </div>\n </button>\n );\n}\n\n/** Wrapping keeps the whole value on screen, so the label block has to stretch to match it. */\nconst COPY_BADGE_LAYOUT = {\n clipped: { frame: \"items-center overflow-hidden\", label: \"\", value: \"truncate\", icon: \"\" },\n wrapped: {\n frame: \"items-stretch\",\n label: \"flex items-center\",\n value: \"whitespace-normal break-all\",\n icon: \"self-center\",\n },\n} as const;\n\nexport function CopyBadge({\n label,\n value,\n className = \"\",\n wrap = false,\n}: {\n label: string;\n value: string;\n className?: string;\n /** Lets a long value run onto further lines instead of being clipped to one. */\n wrap?: boolean;\n}) {\n const layout = COPY_BADGE_LAYOUT[wrap ? \"wrapped\" : \"clipped\"];\n return (\n <button\n type=\"button\"\n onClick={() => copyText(value)}\n title={`Copy ${label}`}\n className={[\n \"inline-flex max-w-full rounded-md border border-border bg-background/80 text-left text-xs hover:border-primary/40 hover:bg-background\",\n layout.frame,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n <span\n className={[\"shrink-0 bg-muted px-2 py-1 font-medium text-muted-foreground\", layout.label]\n .filter(Boolean)\n .join(\" \")}\n >\n {label}\n </span>\n <span className={[\"min-w-0 px-2 py-1 font-mono text-foreground\", layout.value].join(\" \")}>{value}</span>\n <Icon\n icon={UiCopy}\n className={[\"mr-1.5 h-3 w-3 shrink-0 text-muted-foreground\", layout.icon].filter(Boolean).join(\" \")}\n />\n </button>\n );\n}\n\nfunction copyText(value: string) {\n if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n void navigator.clipboard.writeText(value);\n }\n}\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -1,33 +1,63 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const codeHighlight = require("../code-highlight.cjs");
|
|
6
|
+
const HighlightedTokens = require("../HighlightedTokens.cjs");
|
|
7
|
+
function FrameSourceWindow({
|
|
8
|
+
frame,
|
|
9
|
+
className
|
|
10
|
+
}) {
|
|
11
|
+
const lines = react.useMemo(() => frame.sourceLines ?? [], [frame.sourceLines]);
|
|
7
12
|
const start = frame.sourceStartLine ?? 0;
|
|
8
13
|
const numbers = frame.sourceLineNumbers;
|
|
9
14
|
const focal = frame.line ?? -1;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
const language = frame.sourceLanguage;
|
|
16
|
+
const [tokens, setTokens] = react.useState(null);
|
|
17
|
+
react.useEffect(() => {
|
|
18
|
+
if (lines.length === 0) {
|
|
19
|
+
setTokens(null);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
let cancelled = false;
|
|
23
|
+
codeHighlight.highlightToLines(lines.join("\n"), { lang: language }).then((out) => {
|
|
24
|
+
if (!cancelled) setTokens(out);
|
|
25
|
+
});
|
|
26
|
+
return () => {
|
|
27
|
+
cancelled = true;
|
|
28
|
+
};
|
|
29
|
+
}, [lines, language]);
|
|
30
|
+
if (lines.length === 0) return null;
|
|
31
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
className: [
|
|
35
|
+
"mx-3 mb-2 ml-12 overflow-x-auto rounded border border-border/60 bg-muted/30 py-1 font-mono text-[11px] leading-relaxed",
|
|
36
|
+
className
|
|
37
|
+
].filter(Boolean).join(" "),
|
|
38
|
+
children: lines.map((source, i) => {
|
|
39
|
+
const lineNumber = (numbers == null ? void 0 : numbers[i]) ?? start + i;
|
|
40
|
+
const isFocal = lineNumber === focal;
|
|
41
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
42
|
+
"div",
|
|
43
|
+
{
|
|
44
|
+
className: [
|
|
45
|
+
"grid min-w-max grid-cols-[3.5rem_minmax(24rem,1fr)] gap-3 px-2",
|
|
46
|
+
isFocal ? "bg-red-500/10 font-semibold text-red-800 dark:text-red-300" : "text-foreground"
|
|
47
|
+
].join(" "),
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "select-none text-right text-muted-foreground", children: [
|
|
50
|
+
isFocal ? ">" : "",
|
|
51
|
+
lineNumber
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "whitespace-pre", children: source ? /* @__PURE__ */ jsxRuntime.jsx(HighlightedTokens.HighlightedTokens, { tokens: tokens == null ? void 0 : tokens[i], content: source }) : " " })
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
`${lineNumber}-${i}`
|
|
57
|
+
);
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
);
|
|
31
61
|
}
|
|
32
62
|
exports.FrameSourceWindow = FrameSourceWindow;
|
|
33
63
|
//# sourceMappingURL=FrameSourceWindow.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameSourceWindow.cjs","sources":["../../../src/data/diagnostics/FrameSourceWindow.tsx"],"sourcesContent":["import type { FrameSource } from \"./FrameSourceWindow.utils\";\n\n// FrameSourceWindow renders a decompiled / resolved source window beneath a\n// stack frame: a gutter of absolute line numbers with the focal line (the one\n// the frame points at) highlighted. It is the
|
|
1
|
+
{"version":3,"file":"FrameSourceWindow.cjs","sources":["../../../src/data/diagnostics/FrameSourceWindow.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport { highlightToLines, type HighlightedLine } from \"../code-highlight\";\nimport { HighlightedTokens } from \"../HighlightedTokens\";\nimport type { FrameSource } from \"./FrameSourceWindow.utils\";\n\n// FrameSourceWindow renders a decompiled / resolved source window beneath a\n// stack frame: a gutter of absolute line numbers with the focal line (the one\n// the frame points at) highlighted. It is the single source-window renderer,\n// shared by the JVM thread-dump frames, the exception stack-trace frames, and\n// frameless callers that have source but no stack (a template error, a single\n// decompiled class).\n//\n// The gutter is painted explicitly rather than by embedding Shiki's own `<pre>`,\n// because `sourceLineNumbers` is frequently NOT a contiguous run: arthas `jad`\n// returns bytecode-keyed line numbers with gaps. A CSS-counter gutter would\n// silently renumber those. Tokenizing via `highlightToLines` keeps the\n// highlighting while letting us own the numbering — the same trade CodeDiff makes.\nexport function FrameSourceWindow({\n frame,\n className,\n}: {\n frame: FrameSource;\n className?: string;\n}) {\n const lines = useMemo(() => frame.sourceLines ?? [], [frame.sourceLines]);\n const start = frame.sourceStartLine ?? 0;\n const numbers = frame.sourceLineNumbers;\n const focal = frame.line ?? -1;\n // No default language: this renderer is shared by JVM frames, exception frames\n // and frameless callers, so a Go dump or a template error must not be coloured\n // with Java grammar. `highlightToLines` returns null without a language and\n // `HighlightedTokens` then paints the plain source.\n const language = frame.sourceLanguage;\n\n const [tokens, setTokens] = useState<HighlightedLine[] | null>(null);\n\n useEffect(() => {\n if (lines.length === 0) {\n setTokens(null);\n return;\n }\n let cancelled = false;\n highlightToLines(lines.join(\"\\n\"), { lang: language }).then((out) => {\n if (!cancelled) setTokens(out);\n });\n return () => {\n cancelled = true;\n };\n }, [lines, language]);\n\n if (lines.length === 0) return null;\n\n return (\n <div\n className={[\n \"mx-3 mb-2 ml-12 overflow-x-auto rounded border border-border/60 bg-muted/30 py-1 font-mono text-[11px] leading-relaxed\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {lines.map((source, i) => {\n const lineNumber = numbers?.[i] ?? start + i;\n const isFocal = lineNumber === focal;\n return (\n <div\n key={`${lineNumber}-${i}`}\n className={[\n \"grid min-w-max grid-cols-[3.5rem_minmax(24rem,1fr)] gap-3 px-2\",\n isFocal ? \"bg-red-500/10 font-semibold text-red-800 dark:text-red-300\" : \"text-foreground\",\n ].join(\" \")}\n >\n <span className=\"select-none text-right text-muted-foreground\">\n {isFocal ? \">\" : \"\"}\n {lineNumber}\n </span>\n <code className=\"whitespace-pre\">\n {source ? <HighlightedTokens tokens={tokens?.[i]} content={source} /> : \" \"}\n </code>\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["useMemo","useState","useEffect","highlightToLines","jsx","jsxs","HighlightedTokens"],"mappings":";;;;;;AAiBO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AACF,GAGG;AACD,QAAM,QAAQA,MAAAA,QAAQ,MAAM,MAAM,eAAe,IAAI,CAAC,MAAM,WAAW,CAAC;AACxE,QAAM,QAAQ,MAAM,mBAAmB;AACvC,QAAM,UAAU,MAAM;AACtB,QAAM,QAAQ,MAAM,QAAQ;AAK5B,QAAM,WAAW,MAAM;AAEvB,QAAM,CAAC,QAAQ,SAAS,IAAIC,MAAAA,SAAmC,IAAI;AAEnEC,QAAAA,UAAU,MAAM;AACd,QAAI,MAAM,WAAW,GAAG;AACtB,gBAAU,IAAI;AACd;AAAA,IACF;AACA,QAAI,YAAY;AAChBC,kBAAAA,iBAAiB,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,UAAU,EAAE,KAAK,CAAC,QAAQ;AACnE,UAAI,CAAC,UAAW,WAAU,GAAG;AAAA,IAC/B,CAAC;AACD,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MAEV,UAAA,MAAM,IAAI,CAAC,QAAQ,MAAM;AACxB,cAAM,cAAa,mCAAU,OAAM,QAAQ;AAC3C,cAAM,UAAU,eAAe;AAC/B,eACEC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAW;AAAA,cACT;AAAA,cACA,UAAU,+DAA+D;AAAA,YAAA,EACzE,KAAK,GAAG;AAAA,YAEV,UAAA;AAAA,cAAAA,2BAAAA,KAAC,QAAA,EAAK,WAAU,gDACb,UAAA;AAAA,gBAAA,UAAU,MAAM;AAAA,gBAChB;AAAA,cAAA,GACH;AAAA,cACAD,2BAAAA,IAAC,QAAA,EAAK,WAAU,kBACb,mBAASA,+BAACE,kBAAAA,mBAAA,EAAkB,QAAQ,iCAAS,IAAI,SAAS,OAAA,CAAQ,IAAK,IAAA,CAC1E;AAAA,YAAA;AAAA,UAAA;AAAA,UAZK,GAAG,UAAU,IAAI,CAAC;AAAA,QAAA;AAAA,MAe7B,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FrameSource } from './FrameSourceWindow.utils';
|
|
2
|
-
export declare function FrameSourceWindow({ frame }: {
|
|
2
|
+
export declare function FrameSourceWindow({ frame, className, }: {
|
|
3
3
|
frame: FrameSource;
|
|
4
|
+
className?: string;
|
|
4
5
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
5
6
|
//# sourceMappingURL=FrameSourceWindow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameSourceWindow.d.ts","sourceRoot":"","sources":["../../../src/data/diagnostics/FrameSourceWindow.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FrameSourceWindow.d.ts","sourceRoot":"","sources":["../../../src/data/diagnostics/FrameSourceWindow.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAc7D,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,SAAS,GACV,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,kDA6DA"}
|
|
@@ -1,31 +1,61 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { useMemo, useState, useEffect } from "react";
|
|
3
|
+
import { highlightToLines } from "../code-highlight.js";
|
|
4
|
+
import { HighlightedTokens } from "../HighlightedTokens.js";
|
|
5
|
+
function FrameSourceWindow({
|
|
6
|
+
frame,
|
|
7
|
+
className
|
|
8
|
+
}) {
|
|
9
|
+
const lines = useMemo(() => frame.sourceLines ?? [], [frame.sourceLines]);
|
|
5
10
|
const start = frame.sourceStartLine ?? 0;
|
|
6
11
|
const numbers = frame.sourceLineNumbers;
|
|
7
12
|
const focal = frame.line ?? -1;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
13
|
+
const language = frame.sourceLanguage;
|
|
14
|
+
const [tokens, setTokens] = useState(null);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (lines.length === 0) {
|
|
17
|
+
setTokens(null);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let cancelled = false;
|
|
21
|
+
highlightToLines(lines.join("\n"), { lang: language }).then((out) => {
|
|
22
|
+
if (!cancelled) setTokens(out);
|
|
23
|
+
});
|
|
24
|
+
return () => {
|
|
25
|
+
cancelled = true;
|
|
26
|
+
};
|
|
27
|
+
}, [lines, language]);
|
|
28
|
+
if (lines.length === 0) return null;
|
|
29
|
+
return /* @__PURE__ */ jsx(
|
|
30
|
+
"div",
|
|
31
|
+
{
|
|
32
|
+
className: [
|
|
33
|
+
"mx-3 mb-2 ml-12 overflow-x-auto rounded border border-border/60 bg-muted/30 py-1 font-mono text-[11px] leading-relaxed",
|
|
34
|
+
className
|
|
35
|
+
].filter(Boolean).join(" "),
|
|
36
|
+
children: lines.map((source, i) => {
|
|
37
|
+
const lineNumber = (numbers == null ? void 0 : numbers[i]) ?? start + i;
|
|
38
|
+
const isFocal = lineNumber === focal;
|
|
39
|
+
return /* @__PURE__ */ jsxs(
|
|
40
|
+
"div",
|
|
41
|
+
{
|
|
42
|
+
className: [
|
|
43
|
+
"grid min-w-max grid-cols-[3.5rem_minmax(24rem,1fr)] gap-3 px-2",
|
|
44
|
+
isFocal ? "bg-red-500/10 font-semibold text-red-800 dark:text-red-300" : "text-foreground"
|
|
45
|
+
].join(" "),
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsxs("span", { className: "select-none text-right text-muted-foreground", children: [
|
|
48
|
+
isFocal ? ">" : "",
|
|
49
|
+
lineNumber
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ jsx("code", { className: "whitespace-pre", children: source ? /* @__PURE__ */ jsx(HighlightedTokens, { tokens: tokens == null ? void 0 : tokens[i], content: source }) : " " })
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
`${lineNumber}-${i}`
|
|
55
|
+
);
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
);
|
|
29
59
|
}
|
|
30
60
|
export {
|
|
31
61
|
FrameSourceWindow
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameSourceWindow.js","sources":["../../../src/data/diagnostics/FrameSourceWindow.tsx"],"sourcesContent":["import type { FrameSource } from \"./FrameSourceWindow.utils\";\n\n// FrameSourceWindow renders a decompiled / resolved source window beneath a\n// stack frame: a gutter of absolute line numbers with the focal line (the one\n// the frame points at) highlighted. It is the
|
|
1
|
+
{"version":3,"file":"FrameSourceWindow.js","sources":["../../../src/data/diagnostics/FrameSourceWindow.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport { highlightToLines, type HighlightedLine } from \"../code-highlight\";\nimport { HighlightedTokens } from \"../HighlightedTokens\";\nimport type { FrameSource } from \"./FrameSourceWindow.utils\";\n\n// FrameSourceWindow renders a decompiled / resolved source window beneath a\n// stack frame: a gutter of absolute line numbers with the focal line (the one\n// the frame points at) highlighted. It is the single source-window renderer,\n// shared by the JVM thread-dump frames, the exception stack-trace frames, and\n// frameless callers that have source but no stack (a template error, a single\n// decompiled class).\n//\n// The gutter is painted explicitly rather than by embedding Shiki's own `<pre>`,\n// because `sourceLineNumbers` is frequently NOT a contiguous run: arthas `jad`\n// returns bytecode-keyed line numbers with gaps. A CSS-counter gutter would\n// silently renumber those. Tokenizing via `highlightToLines` keeps the\n// highlighting while letting us own the numbering — the same trade CodeDiff makes.\nexport function FrameSourceWindow({\n frame,\n className,\n}: {\n frame: FrameSource;\n className?: string;\n}) {\n const lines = useMemo(() => frame.sourceLines ?? [], [frame.sourceLines]);\n const start = frame.sourceStartLine ?? 0;\n const numbers = frame.sourceLineNumbers;\n const focal = frame.line ?? -1;\n // No default language: this renderer is shared by JVM frames, exception frames\n // and frameless callers, so a Go dump or a template error must not be coloured\n // with Java grammar. `highlightToLines` returns null without a language and\n // `HighlightedTokens` then paints the plain source.\n const language = frame.sourceLanguage;\n\n const [tokens, setTokens] = useState<HighlightedLine[] | null>(null);\n\n useEffect(() => {\n if (lines.length === 0) {\n setTokens(null);\n return;\n }\n let cancelled = false;\n highlightToLines(lines.join(\"\\n\"), { lang: language }).then((out) => {\n if (!cancelled) setTokens(out);\n });\n return () => {\n cancelled = true;\n };\n }, [lines, language]);\n\n if (lines.length === 0) return null;\n\n return (\n <div\n className={[\n \"mx-3 mb-2 ml-12 overflow-x-auto rounded border border-border/60 bg-muted/30 py-1 font-mono text-[11px] leading-relaxed\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {lines.map((source, i) => {\n const lineNumber = numbers?.[i] ?? start + i;\n const isFocal = lineNumber === focal;\n return (\n <div\n key={`${lineNumber}-${i}`}\n className={[\n \"grid min-w-max grid-cols-[3.5rem_minmax(24rem,1fr)] gap-3 px-2\",\n isFocal ? \"bg-red-500/10 font-semibold text-red-800 dark:text-red-300\" : \"text-foreground\",\n ].join(\" \")}\n >\n <span className=\"select-none text-right text-muted-foreground\">\n {isFocal ? \">\" : \"\"}\n {lineNumber}\n </span>\n <code className=\"whitespace-pre\">\n {source ? <HighlightedTokens tokens={tokens?.[i]} content={source} /> : \" \"}\n </code>\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AAiBO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AACF,GAGG;AACD,QAAM,QAAQ,QAAQ,MAAM,MAAM,eAAe,IAAI,CAAC,MAAM,WAAW,CAAC;AACxE,QAAM,QAAQ,MAAM,mBAAmB;AACvC,QAAM,UAAU,MAAM;AACtB,QAAM,QAAQ,MAAM,QAAQ;AAK5B,QAAM,WAAW,MAAM;AAEvB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAmC,IAAI;AAEnE,YAAU,MAAM;AACd,QAAI,MAAM,WAAW,GAAG;AACtB,gBAAU,IAAI;AACd;AAAA,IACF;AACA,QAAI,YAAY;AAChB,qBAAiB,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,UAAU,EAAE,KAAK,CAAC,QAAQ;AACnE,UAAI,CAAC,UAAW,WAAU,GAAG;AAAA,IAC/B,CAAC;AACD,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MAEV,UAAA,MAAM,IAAI,CAAC,QAAQ,MAAM;AACxB,cAAM,cAAa,mCAAU,OAAM,QAAQ;AAC3C,cAAM,UAAU,eAAe;AAC/B,eACE;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAW;AAAA,cACT;AAAA,cACA,UAAU,+DAA+D;AAAA,YAAA,EACzE,KAAK,GAAG;AAAA,YAEV,UAAA;AAAA,cAAA,qBAAC,QAAA,EAAK,WAAU,gDACb,UAAA;AAAA,gBAAA,UAAU,MAAM;AAAA,gBAChB;AAAA,cAAA,GACH;AAAA,cACA,oBAAC,QAAA,EAAK,WAAU,kBACb,mBAAS,oBAAC,mBAAA,EAAkB,QAAQ,iCAAS,IAAI,SAAS,OAAA,CAAQ,IAAK,IAAA,CAC1E;AAAA,YAAA;AAAA,UAAA;AAAA,UAZK,GAAG,UAAU,IAAI,CAAC;AAAA,QAAA;AAAA,MAe7B,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameSourceWindow.utils.cjs","sources":["../../../src/data/diagnostics/FrameSourceWindow.utils.ts"],"sourcesContent":["export interface FrameSource {\n /** Source lines around the focal line. */\n sourceLines?: string[];\n /** Absolute line number for each entry in sourceLines (preferred gutter). */\n sourceLineNumbers?: number[];\n /** Line number of sourceLines[0] when sourceLineNumbers is absent. */\n sourceStartLine?: number;\n /** The frame's focal line, highlighted when it falls inside the window. */\n line?: number;\n}\n\nexport function frameHasSource(frame: FrameSource): boolean {\n return !!frame.sourceLines && frame.sourceLines.length > 0;\n}\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"FrameSourceWindow.utils.cjs","sources":["../../../src/data/diagnostics/FrameSourceWindow.utils.ts"],"sourcesContent":["export interface FrameSource {\n /** Source lines around the focal line. */\n sourceLines?: string[];\n /** Absolute line number for each entry in sourceLines (preferred gutter). */\n sourceLineNumbers?: number[];\n /** Line number of sourceLines[0] when sourceLineNumbers is absent. */\n sourceStartLine?: number;\n /** The frame's focal line, highlighted when it falls inside the window. */\n line?: number;\n /** Highlighter language for the window's contents. Omit when unknown: the\n * window then renders plain, un-tokenized source rather than guessing. */\n sourceLanguage?: string;\n}\n\nexport function frameHasSource(frame: FrameSource): boolean {\n return !!frame.sourceLines && frame.sourceLines.length > 0;\n}\n"],"names":[],"mappings":";;AAcO,SAAS,eAAe,OAA6B;AAC1D,SAAO,CAAC,CAAC,MAAM,eAAe,MAAM,YAAY,SAAS;AAC3D;;"}
|
|
@@ -7,6 +7,9 @@ export interface FrameSource {
|
|
|
7
7
|
sourceStartLine?: number;
|
|
8
8
|
/** The frame's focal line, highlighted when it falls inside the window. */
|
|
9
9
|
line?: number;
|
|
10
|
+
/** Highlighter language for the window's contents. Omit when unknown: the
|
|
11
|
+
* window then renders plain, un-tokenized source rather than guessing. */
|
|
12
|
+
sourceLanguage?: string;
|
|
10
13
|
}
|
|
11
14
|
export declare function frameHasSource(frame: FrameSource): boolean;
|
|
12
15
|
//# sourceMappingURL=FrameSourceWindow.utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameSourceWindow.utils.d.ts","sourceRoot":"","sources":["../../../src/data/diagnostics/FrameSourceWindow.utils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"FrameSourceWindow.utils.d.ts","sourceRoot":"","sources":["../../../src/data/diagnostics/FrameSourceWindow.utils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;+EAC2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameSourceWindow.utils.js","sources":["../../../src/data/diagnostics/FrameSourceWindow.utils.ts"],"sourcesContent":["export interface FrameSource {\n /** Source lines around the focal line. */\n sourceLines?: string[];\n /** Absolute line number for each entry in sourceLines (preferred gutter). */\n sourceLineNumbers?: number[];\n /** Line number of sourceLines[0] when sourceLineNumbers is absent. */\n sourceStartLine?: number;\n /** The frame's focal line, highlighted when it falls inside the window. */\n line?: number;\n}\n\nexport function frameHasSource(frame: FrameSource): boolean {\n return !!frame.sourceLines && frame.sourceLines.length > 0;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FrameSourceWindow.utils.js","sources":["../../../src/data/diagnostics/FrameSourceWindow.utils.ts"],"sourcesContent":["export interface FrameSource {\n /** Source lines around the focal line. */\n sourceLines?: string[];\n /** Absolute line number for each entry in sourceLines (preferred gutter). */\n sourceLineNumbers?: number[];\n /** Line number of sourceLines[0] when sourceLineNumbers is absent. */\n sourceStartLine?: number;\n /** The frame's focal line, highlighted when it falls inside the window. */\n line?: number;\n /** Highlighter language for the window's contents. Omit when unknown: the\n * window then renders plain, un-tokenized source rather than guessing. */\n sourceLanguage?: string;\n}\n\nexport function frameHasSource(frame: FrameSource): boolean {\n return !!frame.sourceLines && frame.sourceLines.length > 0;\n}\n"],"names":[],"mappings":"AAcO,SAAS,eAAe,OAA6B;AAC1D,SAAO,CAAC,CAAC,MAAM,eAAe,MAAM,YAAY,SAAS;AAC3D;"}
|
|
@@ -1,46 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
-
const
|
|
5
|
-
const FrameSourceWindow = require("./FrameSourceWindow.cjs");
|
|
6
|
-
const FrameSourceWindow_utils = require("./FrameSourceWindow.utils.cjs");
|
|
7
|
-
const UiLock = require("../../icons/components/UiLock.cjs");
|
|
8
|
-
const UiSync = require("../../icons/components/UiSync.cjs");
|
|
9
|
-
const UiWatch = require("../../icons/components/UiWatch.cjs");
|
|
10
|
-
const UiChip = require("../../icons/components/UiChip.cjs");
|
|
11
|
-
const UiDebugStepOver = require("../../icons/components/UiDebugStepOver.cjs");
|
|
12
|
-
const UiMethod = require("../../icons/components/UiMethod.cjs");
|
|
4
|
+
const StackFrameRow = require("./StackFrameRow.cjs");
|
|
13
5
|
function JvmStackTrace({
|
|
14
6
|
frames,
|
|
15
7
|
hideRuntimeOnly = false,
|
|
16
8
|
className,
|
|
17
|
-
resolveSource
|
|
9
|
+
resolveSource,
|
|
10
|
+
frameActions
|
|
18
11
|
}) {
|
|
19
12
|
const visibleFrames = hideRuntimeOnly ? frames.filter((frame) => frame.kind !== "frame" || !frame.runtime) : frames;
|
|
20
13
|
if (visibleFrames.length === 0) return null;
|
|
21
14
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: visibleFrames.map((frame, index) => {
|
|
22
15
|
const resolved = resolveSource == null ? void 0 : resolveSource(frame);
|
|
23
|
-
const
|
|
24
|
-
|
|
16
|
+
const { line: _ignored, ...source } = resolved ?? {};
|
|
17
|
+
const withSource = resolved ? { ...frame, ...source } : frame;
|
|
18
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19
|
+
StackFrameRow.StackFrameRow,
|
|
20
|
+
{
|
|
21
|
+
frame: withSource,
|
|
22
|
+
index,
|
|
23
|
+
...frameActions ? { frameActions } : {}
|
|
24
|
+
},
|
|
25
|
+
`${frame.functionName}-${index}`
|
|
26
|
+
);
|
|
25
27
|
}) });
|
|
26
28
|
}
|
|
27
|
-
function JvmStackFrameRow({ frame }) {
|
|
28
|
-
const isAnno = frame.kind !== "frame";
|
|
29
|
-
const icon = isAnno ? frame.kind === "locked" ? UiLock.UiLock : frame.kind === "waiting_to_lock" ? UiSync.UiSync : UiWatch.UiWatch : frame.nativeMethod ? UiChip.UiChip : frame.runtime ? UiDebugStepOver.UiDebugStepOver : UiMethod.UiMethod;
|
|
30
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: frame.runtime ? "text-muted-foreground" : "text-foreground", children: [
|
|
31
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1.5", children: [
|
|
32
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon, className: "mt-0.5 shrink-0 text-[11px]" }),
|
|
33
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "break-all font-mono text-[11px] font-semibold leading-4", children: isAnno ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
34
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-70", children: frame.functionName }),
|
|
35
|
-
frame.annotationText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 font-normal opacity-80", children: frame.annotationText })
|
|
36
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
37
|
-
frame.displayName,
|
|
38
|
-
frame.location && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 text-[10px] font-normal opacity-80", children: frame.location })
|
|
39
|
-
] }) }) })
|
|
40
|
-
] }),
|
|
41
|
-
!isAnno && FrameSourceWindow_utils.frameHasSource(frame) && /* @__PURE__ */ jsxRuntime.jsx(FrameSourceWindow.FrameSourceWindow, { frame })
|
|
42
|
-
] });
|
|
43
|
-
}
|
|
44
|
-
exports.JvmStackFrameRow = JvmStackFrameRow;
|
|
45
29
|
exports.JvmStackTrace = JvmStackTrace;
|
|
46
30
|
//# sourceMappingURL=JvmStackTrace.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JvmStackTrace.cjs","sources":["../../../src/data/diagnostics/JvmStackTrace.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"JvmStackTrace.cjs","sources":["../../../src/data/diagnostics/JvmStackTrace.tsx"],"sourcesContent":["import type { ParsedThreadFrame } from \"./jvm-stacktrace\";\nimport type { FrameSource } from \"./FrameSourceWindow.utils\";\nimport { StackFrameRow, type StackFrameActions } from \"./StackFrameRow\";\n\n// JvmFrameSourceResolver returns a source window for a frame, or undefined when\n// no source is available (a missing class must never blank out the frame). Used\n// to augment the rendered thread dump with decompiled source in place. Shares\n// its return shape with StackTraceSourceResolver so one resolver can serve both\n// the thread-dump and the exception surfaces.\nexport type JvmFrameSourceResolver = (frame: ParsedThreadFrame) => FrameSource | undefined;\n\nexport type JvmStackTraceProps = {\n frames: ParsedThreadFrame[];\n hideRuntimeOnly?: boolean;\n className?: string;\n /** Optional resolver that supplies inline source under each frame. */\n resolveSource?: JvmFrameSourceResolver;\n /** Trailing per-frame actions, revealed on hover/focus. */\n frameActions?: StackFrameActions;\n};\n\n// JvmStackTrace renders a parsed thread dump: frames plus the lock/monitor\n// annotation entries interleaved with them. It is a bare frame list — the\n// thread's own header, state badge and controls belong to the surrounding card\n// (see ThreadCard / DiagnosticsDetailPanel). Frames render through the shared\n// StackFrameRow, so they match an exception stack trace exactly.\nexport function JvmStackTrace({\n frames,\n hideRuntimeOnly = false,\n className,\n resolveSource,\n frameActions,\n}: JvmStackTraceProps) {\n const visibleFrames = hideRuntimeOnly\n ? frames.filter((frame) => frame.kind !== \"frame\" || !frame.runtime)\n : frames;\n\n if (visibleFrames.length === 0) return null;\n\n return (\n <div className={className}>\n {visibleFrames.map((frame, index) => {\n const resolved = resolveSource?.(frame);\n // `line` stays the frame's own — see the note in RenderedStackTrace.\n const { line: _ignored, ...source } = resolved ?? {};\n const withSource = resolved ? { ...frame, ...source } : frame;\n return (\n <StackFrameRow\n key={`${frame.functionName}-${index}`}\n frame={withSource}\n index={index}\n {...(frameActions ? { frameActions } : {})}\n />\n );\n })}\n </div>\n );\n}\n"],"names":["jsx","StackFrameRow"],"mappings":";;;;AA0BO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,gBAAgB,kBAClB,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,WAAW,CAAC,MAAM,OAAO,IACjE;AAEJ,MAAI,cAAc,WAAW,EAAG,QAAO;AAEvC,wCACG,OAAA,EAAI,WACF,wBAAc,IAAI,CAAC,OAAO,UAAU;AACnC,UAAM,WAAW,+CAAgB;AAEjC,UAAM,EAAE,MAAM,UAAU,GAAG,OAAA,IAAW,YAAY,CAAA;AAClD,UAAM,aAAa,WAAW,EAAE,GAAG,OAAO,GAAG,WAAW;AACxD,WACEA,2BAAAA;AAAAA,MAACC,cAAAA;AAAAA,MAAA;AAAA,QAEC,OAAO;AAAA,QACP;AAAA,QACC,GAAI,eAAe,EAAE,iBAAiB,CAAA;AAAA,MAAC;AAAA,MAHnC,GAAG,MAAM,YAAY,IAAI,KAAK;AAAA,IAAA;AAAA,EAMzC,CAAC,EAAA,CACH;AAEJ;;"}
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import { ParsedThreadFrame } from './jvm-stacktrace';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
sourceStartLine?: number;
|
|
6
|
-
} | undefined;
|
|
2
|
+
import { FrameSource } from './FrameSourceWindow.utils';
|
|
3
|
+
import { StackFrameActions } from './StackFrameRow';
|
|
4
|
+
export type JvmFrameSourceResolver = (frame: ParsedThreadFrame) => FrameSource | undefined;
|
|
7
5
|
export type JvmStackTraceProps = {
|
|
8
6
|
frames: ParsedThreadFrame[];
|
|
9
7
|
hideRuntimeOnly?: boolean;
|
|
10
8
|
className?: string;
|
|
11
9
|
/** Optional resolver that supplies inline source under each frame. */
|
|
12
10
|
resolveSource?: JvmFrameSourceResolver;
|
|
11
|
+
/** Trailing per-frame actions, revealed on hover/focus. */
|
|
12
|
+
frameActions?: StackFrameActions;
|
|
13
13
|
};
|
|
14
|
-
export declare function JvmStackTrace({ frames, hideRuntimeOnly, className, resolveSource, }: JvmStackTraceProps): import("react/jsx-runtime").JSX.Element | null;
|
|
15
|
-
export declare function JvmStackFrameRow({ frame }: {
|
|
16
|
-
frame: ParsedThreadFrame;
|
|
17
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function JvmStackTrace({ frames, hideRuntimeOnly, className, resolveSource, frameActions, }: JvmStackTraceProps): import("react/jsx-runtime").JSX.Element | null;
|
|
18
15
|
//# sourceMappingURL=JvmStackTrace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JvmStackTrace.d.ts","sourceRoot":"","sources":["../../../src/data/diagnostics/JvmStackTrace.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"JvmStackTrace.d.ts","sourceRoot":"","sources":["../../../src/data/diagnostics/JvmStackTrace.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAOxE,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,WAAW,GAAG,SAAS,CAAC;AAE3F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,2DAA2D;IAC3D,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC,CAAC;AAOF,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,eAAuB,EACvB,SAAS,EACT,aAAa,EACb,YAAY,GACb,EAAE,kBAAkB,kDAyBpB"}
|