@mugenlabs/logtape-devtools 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +10 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -572,6 +572,7 @@ var Toolbar = ({
|
|
|
572
572
|
() => new Debouncer(onSearchTextChange, { wait: 200 }),
|
|
573
573
|
[onSearchTextChange]
|
|
574
574
|
);
|
|
575
|
+
useEffect2(() => () => debouncedSearch.cancel(), [debouncedSearch]);
|
|
575
576
|
const handleSearchChange = useCallback2(
|
|
576
577
|
(e) => {
|
|
577
578
|
const value = e.target.value;
|
|
@@ -1127,7 +1128,6 @@ var createLogTapeDevtoolsPlugin = (options) => ({
|
|
|
1127
1128
|
});
|
|
1128
1129
|
|
|
1129
1130
|
// src/sink.ts
|
|
1130
|
-
var counter = 0;
|
|
1131
1131
|
function renderMessage(message) {
|
|
1132
1132
|
return message.map((part) => {
|
|
1133
1133
|
if (typeof part === "string") {
|
|
@@ -1184,9 +1184,9 @@ function captureCallerInfo() {
|
|
|
1184
1184
|
}
|
|
1185
1185
|
return void 0;
|
|
1186
1186
|
}
|
|
1187
|
-
function normalizeRecord(record, captureStack) {
|
|
1187
|
+
function normalizeRecord(record, captureStack, id) {
|
|
1188
1188
|
const normalized = {
|
|
1189
|
-
id
|
|
1189
|
+
id,
|
|
1190
1190
|
timestamp: record.timestamp,
|
|
1191
1191
|
level: record.level,
|
|
1192
1192
|
category: [...record.category],
|
|
@@ -1215,9 +1215,15 @@ function createDevtoolsSink(options) {
|
|
|
1215
1215
|
const store = options?.store ?? defaultLogStore;
|
|
1216
1216
|
const wantsStack = options?.experimentalCaptureStackTrace ?? true;
|
|
1217
1217
|
const captureStack = wantsStack && (options?.forceStackTrace || !isProductionEnv());
|
|
1218
|
+
const sinkId = Math.random().toString(36).slice(2, 8);
|
|
1219
|
+
let counter = 0;
|
|
1218
1220
|
return (record) => {
|
|
1219
1221
|
try {
|
|
1220
|
-
const normalized = normalizeRecord(
|
|
1222
|
+
const normalized = normalizeRecord(
|
|
1223
|
+
record,
|
|
1224
|
+
captureStack,
|
|
1225
|
+
`log-${sinkId}-${++counter}-${record.timestamp}`
|
|
1226
|
+
);
|
|
1221
1227
|
store.addRecord(normalized);
|
|
1222
1228
|
} catch {
|
|
1223
1229
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/store.ts","../src/plugin/logtape-devtools-plugin.tsx","../src/plugin/components/log-list.tsx","../src/plugin/theme.ts","../src/plugin/components/log-row.tsx","../src/plugin/icons.tsx","../src/plugin/components/level-badge.tsx","../src/plugin/components/log-detail.tsx","../src/plugin/components/toolbar.tsx","../src/types.ts","../src/plugin/create-logtape-devtools-plugin.tsx","../src/sink.ts"],"sourcesContent":["import type { DevtoolsLogRecord } from \"./types\";\n\ntype Listener = () => void;\n\nexport interface LogStore {\n addRecord(record: DevtoolsLogRecord): void;\n clear(): void;\n getSnapshot(): DevtoolsLogRecord[];\n setMaxSize(size: number): void;\n subscribe(listener: Listener): () => void;\n}\n\nexport function createLogStore(maxSize = 1000): LogStore {\n let records: DevtoolsLogRecord[] = [];\n let max = maxSize;\n const listeners = new Set<Listener>();\n\n function notify() {\n for (const listener of listeners) {\n listener();\n }\n }\n\n return {\n getSnapshot: () => records,\n addRecord: (record) => {\n // Create new array reference for useSyncExternalStore\n records = [...records, record];\n if (records.length > max) {\n records = records.slice(records.length - max);\n }\n notify();\n },\n clear: () => {\n records = [];\n notify();\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n setMaxSize: (size) => {\n max = size;\n if (records.length > max) {\n records = records.slice(records.length - max);\n notify();\n }\n },\n };\n}\n\n/** Default shared store instance used when no custom store is provided */\nexport const defaultLogStore = createLogStore();\n","import { useCallback, useMemo, useState, useSyncExternalStore } from \"react\";\nimport type { LogStore } from \"../store\";\nimport type { DevtoolsLogRecord, LogLevel } from \"../types\";\nimport { LogList } from \"./components/log-list\";\nimport { Toolbar } from \"./components/toolbar\";\nimport { PanelLeftCloseIcon, PanelLeftOpenIcon, PauseIcon, PlayIcon, Trash2Icon } from \"./icons\";\nimport { theme } from \"./theme\";\n\ninterface Props {\n store: LogStore;\n}\n\nexport const LogTapeDevtoolsPlugin = ({ store }: Props) => {\n const allRecords = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\n const [paused, setPaused] = useState(false);\n const [pausedRecords, setPausedRecords] = useState<DevtoolsLogRecord[]>([]);\n const [levelFilter, setLevelFilter] = useState<Set<LogLevel>>(new Set());\n const [categoryFilter, setCategoryFilter] = useState<string[]>([]);\n const [searchText, setSearchText] = useState(\"\");\n const [expandedId, setExpandedId] = useState<string | null>(null);\n const [sidebarOpen, setSidebarOpen] = useState(true);\n\n const handlePause = useCallback(() => {\n setPaused(true);\n setPausedRecords(store.getSnapshot());\n }, [store]);\n\n const handleResume = useCallback(() => {\n setPaused(false);\n setPausedRecords([]);\n }, []);\n\n const handleClear = useCallback(() => {\n store.clear();\n setPausedRecords([]);\n setExpandedId(null);\n }, [store]);\n\n const records = paused ? pausedRecords : allRecords;\n\n const uniqueCategories = useMemo(() => {\n const seen = new Set<string>();\n for (const r of records) {\n seen.add(r.category.join(\".\"));\n }\n return Array.from(seen).sort();\n }, [records]);\n\n const filteredRecords = useMemo(() => {\n return records.filter((r) => {\n if (levelFilter.size > 0 && !levelFilter.has(r.level)) {\n return false;\n }\n if (categoryFilter.length > 0 && !categoryFilter.includes(r.category.join(\".\"))) {\n return false;\n }\n if (searchText) {\n const term = searchText.toLowerCase();\n if (\n !(\n r.messageText.toLowerCase().includes(term) ||\n r.category.join(\".\").toLowerCase().includes(term)\n )\n ) {\n return false;\n }\n }\n return true;\n });\n }, [records, levelFilter, categoryFilter, searchText]);\n\n return (\n <div\n style={{\n background: theme.colors.background,\n color: theme.colors.textPrimary,\n display: \"flex\",\n flexDirection: \"row\",\n fontFamily: theme.fontFamily.sans,\n height: \"100%\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n borderRight: sidebarOpen ? `1px solid ${theme.colors.border}` : \"none\",\n flexShrink: 0,\n opacity: sidebarOpen ? 1 : 0,\n overflow: \"hidden\",\n transition: \"width 0.2s ease, opacity 0.15s ease\",\n width: sidebarOpen ? \"200px\" : \"0px\",\n }}\n >\n <Toolbar\n categories={uniqueCategories}\n categoryFilter={categoryFilter}\n filteredCount={filteredRecords.length}\n levelFilter={levelFilter}\n onCategoryFilterChange={setCategoryFilter}\n onClear={handleClear}\n onLevelFilterChange={setLevelFilter}\n onPause={handlePause}\n onResume={handleResume}\n onSearchTextChange={setSearchText}\n paused={paused}\n searchText={searchText}\n totalCount={records.length}\n />\n </div>\n\n <div style={{ display: \"flex\", flex: 1, flexDirection: \"column\", overflow: \"hidden\" }}>\n {/* Sidebar toggle bar */}\n <div\n style={{\n alignItems: \"center\",\n borderBottom: `1px solid ${theme.colors.border}`,\n display: \"flex\",\n flexShrink: 0,\n gap: theme.spacing.lg,\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n }}\n >\n <button\n aria-expanded={sidebarOpen}\n data-lt-clear-btn=\"\"\n onClick={() => setSidebarOpen((v) => !v)}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n transition: \"color 0.1s\",\n }}\n title={sidebarOpen ? \"Collapse sidebar\" : \"Expand sidebar\"}\n type=\"button\"\n >\n <span style={{ alignItems: \"center\", display: \"inline-flex\", gap: \"6px\" }}>\n {sidebarOpen ? <PanelLeftCloseIcon size={14} /> : <PanelLeftOpenIcon size={14} />}\n {sidebarOpen ? \"Hide controls\" : \"Show controls\"}\n </span>\n </button>\n\n {!sidebarOpen && (\n <>\n <span\n style={{\n color: theme.colors.textMuted,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n }}\n >\n {filteredRecords.length === records.length\n ? `${records.length} logs`\n : `${filteredRecords.length} / ${records.length} logs`}\n </span>\n <button\n data-lt-interactive=\"\"\n onClick={paused ? handleResume : handlePause}\n style={{\n background: paused\n ? theme.colors.levels.warning.badge\n : theme.colors.surfaceHover,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.sm,\n color: paused ? theme.colors.white : theme.colors.textPrimary,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.sm,\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n transition: \"filter 0.1s\",\n }}\n title={paused ? \"Resume\" : \"Pause\"}\n type=\"button\"\n >\n {paused ? <PlayIcon size={12} /> : <PauseIcon size={12} />}\n </button>\n <button\n data-lt-interactive=\"\"\n onClick={handleClear}\n style={{\n background: theme.colors.surfaceHover,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.sm,\n color: theme.colors.textPrimary,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.sm,\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n transition: \"filter 0.1s\",\n }}\n title=\"Clear\"\n type=\"button\"\n >\n <Trash2Icon size={12} />\n </button>\n </>\n )}\n </div>\n <LogList\n autoScroll={!paused}\n expandedId={expandedId}\n onToggle={setExpandedId}\n records={filteredRecords}\n />\n </div>\n </div>\n );\n};\n","import { useEffect, useRef } from \"react\";\nimport type { DevtoolsLogRecord } from \"../../types\";\nimport { theme } from \"../theme\";\nimport { LogRow } from \"./log-row\";\n\ninterface LogListProps {\n autoScroll: boolean;\n expandedId: string | null;\n onToggle: (id: string | null) => void;\n records: DevtoolsLogRecord[];\n}\n\nexport const LogList = ({ records, expandedId, onToggle, autoScroll }: LogListProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const isAtBottomRef = useRef(true);\n\n const recordCount = records.length;\n // biome-ignore lint/correctness/useExhaustiveDependencies: recordCount triggers scroll on new records\n useEffect(() => {\n const el = containerRef.current;\n if (!(el && autoScroll && isAtBottomRef.current)) {\n return;\n }\n el.scrollTop = el.scrollHeight;\n }, [autoScroll, recordCount]);\n\n const handleScroll = () => {\n const el = containerRef.current;\n if (!el) {\n return;\n }\n // Consider \"at bottom\" if within 40px of the end\n isAtBottomRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 40;\n };\n\n if (records.length === 0) {\n return (\n <div\n data-testid=\"log-list-empty\"\n style={{\n alignItems: \"center\",\n color: theme.colors.textMuted,\n display: \"flex\",\n flex: 1,\n fontSize: theme.fontSize.lg,\n justifyContent: \"center\",\n }}\n >\n No logs yet\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"log-list\"\n onScroll={handleScroll}\n ref={containerRef}\n style={{\n flex: 1,\n overflow: \"auto\",\n scrollbarColor: `${theme.colors.scrollbar} transparent`,\n scrollbarWidth: \"thin\",\n }}\n >\n {records.map((record) => (\n <LogRow\n expanded={expandedId === record.id}\n key={record.id}\n onToggle={onToggle}\n record={record}\n />\n ))}\n </div>\n );\n};\n","export const theme = {\n colors: {\n background: \"#1e1e1e\",\n surface: \"#1a1a1a\",\n surfaceHover: \"#2a2a2a\",\n surfaceSelected: \"#2a2a3a\",\n border: \"#333\",\n borderInput: \"#444\",\n borderFocus: \"#6366f1\",\n\n textPrimary: \"#e0e0e0\",\n textSecondary: \"#888\",\n textMuted: \"#666\",\n textDimmed: \"#555\",\n white: \"#fff\",\n\n accent: \"#6366f1\",\n accentHover: \"#818cf8\",\n\n levels: {\n trace: { bg: \"#1a1a2e\", color: \"#8888bb\", badge: \"#5555aa\" },\n debug: { bg: \"#1a2a1a\", color: \"#88bb88\", badge: \"#55aa55\" },\n info: { bg: \"#1a2a3a\", color: \"#60a5fa\", badge: \"#3b82f6\" },\n warning: { bg: \"#2a2a1a\", color: \"#facc15\", badge: \"#eab308\" },\n error: { bg: \"#2a1a1a\", color: \"#ef4444\", badge: \"#dc2626\" },\n fatal: { bg: \"#3a0a0a\", color: \"#ff6b6b\", badge: \"#b91c1c\" },\n },\n\n scrollbar: \"#444\",\n scrollbarHover: \"#555\",\n },\n\n fontFamily: {\n mono: 'ui-monospace, \"Cascadia Code\", \"Source Code Pro\", Menlo, Consolas, monospace',\n sans: 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif',\n },\n\n fontSize: {\n xs: \"9px\",\n sm: \"10px\",\n md: \"11px\",\n base: \"12px\",\n lg: \"13px\",\n },\n\n radius: {\n sm: \"3px\",\n md: \"4px\",\n lg: \"6px\",\n pill: \"10px\",\n },\n\n spacing: {\n xs: \"2px\",\n sm: \"4px\",\n md: \"6px\",\n lg: \"8px\",\n xl: \"12px\",\n xxl: \"16px\",\n },\n} as const;\n\nexport type LogLevelColors = (typeof theme.colors.levels)[keyof typeof theme.colors.levels];\n","import { useCallback } from \"react\";\nimport type { DevtoolsLogRecord } from \"../../types\";\nimport { ChevronRightIcon } from \"../icons\";\nimport { theme } from \"../theme\";\nimport { LevelBadge } from \"./level-badge\";\nimport { LogDetail } from \"./log-detail\";\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts);\n return d.toLocaleTimeString(undefined, {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n });\n}\n\ninterface LogRowProps {\n expanded: boolean;\n onToggle: (id: string | null) => void;\n record: DevtoolsLogRecord;\n}\n\nexport const LogRow = ({ record, expanded, onToggle }: LogRowProps) => {\n const levelColors = theme.colors.levels[record.level];\n\n const handleClick = useCallback(() => {\n onToggle(expanded ? null : record.id);\n }, [expanded, onToggle, record.id]);\n\n return (\n <div>\n <button\n aria-expanded={expanded}\n data-lt-interactive=\"\"\n data-testid=\"log-row\"\n onClick={handleClick}\n style={{\n alignItems: \"center\",\n background: expanded ? levelColors.bg : \"transparent\",\n border: \"none\",\n borderBottom: `1px solid ${theme.colors.border}`,\n cursor: \"pointer\",\n display: \"flex\",\n gap: theme.spacing.lg,\n padding: `${theme.spacing.md} ${theme.spacing.xl}`,\n textAlign: \"left\",\n transition: \"background 0.1s, filter 0.1s\",\n width: \"100%\",\n }}\n type=\"button\"\n >\n {/* Timestamp */}\n <span\n style={{\n color: theme.colors.textDimmed,\n flexShrink: 0,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n }}\n >\n {formatTime(record.timestamp)}\n </span>\n\n {/* Level badge */}\n <LevelBadge level={record.level} />\n\n {/* Category */}\n <span\n style={{\n color: theme.colors.accent,\n flexShrink: 0,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n maxWidth: \"180px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {record.category.join(\".\")}\n </span>\n\n {/* Message */}\n <span\n style={{\n color: theme.colors.textPrimary,\n flex: 1,\n fontSize: theme.fontSize.base,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {record.messageText}\n </span>\n\n {/* Caller (right-aligned) */}\n {record.caller && (\n <span\n style={{\n color: theme.colors.textDimmed,\n flexShrink: 0,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n maxWidth: \"200px\",\n opacity: 0.7,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {record.caller}\n </span>\n )}\n\n {/* Expand indicator */}\n <span\n style={{\n color: theme.colors.textDimmed,\n display: \"flex\",\n flexShrink: 0,\n transform: expanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.15s\",\n }}\n >\n <ChevronRightIcon size={12} />\n </span>\n </button>\n\n {expanded && <LogDetail record={record} />}\n </div>\n );\n};\n","/**\n * Inline SVG icons based on Lucide (https://lucide.dev) — ISC License.\n * Using inline SVGs avoids adding lucide-react as a runtime dependency.\n */\n\ninterface IconProps {\n color?: string;\n size?: number;\n style?: React.CSSProperties;\n}\n\nconst defaults = { size: 14, color: \"currentColor\" } as const;\n\nconst Svg = ({\n size = defaults.size,\n color = defaults.color,\n style,\n children,\n}: IconProps & { children: React.ReactNode }) => (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height={size}\n stroke={color}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n style={style}\n viewBox=\"0 0 24 24\"\n width={size}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {children}\n </svg>\n);\n\nexport const PlayIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\" />\n </Svg>\n);\n\nexport const PauseIcon = (props: IconProps) => (\n <Svg {...props}>\n <rect height={18} rx={1} width={5} x={14} y={3} />\n <rect height={18} rx={1} width={5} x={5} y={3} />\n </Svg>\n);\n\nexport const XIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </Svg>\n);\n\nexport const CheckIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Svg>\n);\n\nexport const ChevronRightIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"m9 18 6-6-6-6\" />\n </Svg>\n);\n\nexport const PanelLeftCloseIcon = (props: IconProps) => (\n <Svg {...props}>\n <rect height={18} rx={2} width={18} x={3} y={3} />\n <path d=\"M9 3v18\" />\n <path d=\"m16 15-3-3 3-3\" />\n </Svg>\n);\n\nexport const PanelLeftOpenIcon = (props: IconProps) => (\n <Svg {...props}>\n <rect height={18} rx={2} width={18} x={3} y={3} />\n <path d=\"M9 3v18\" />\n <path d=\"m14 9 3 3-3 3\" />\n </Svg>\n);\n\nexport const Trash2Icon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M10 11v6\" />\n <path d=\"M14 11v6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </Svg>\n);\n","import type { LogLevel } from \"../../types\";\nimport { theme } from \"../theme\";\n\nconst LEVEL_LABELS: Record<LogLevel, string> = {\n trace: \"TRC\",\n debug: \"DBG\",\n info: \"INF\",\n warning: \"WRN\",\n error: \"ERR\",\n fatal: \"FTL\",\n};\n\nexport const LevelBadge = ({ level }: { level: LogLevel }) => {\n const colors = theme.colors.levels[level];\n\n return (\n <span\n style={{\n background: colors.badge,\n borderRadius: theme.radius.sm,\n color: theme.colors.white,\n display: \"inline-block\",\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n fontWeight: 600,\n lineHeight: 1,\n minWidth: \"28px\",\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n textAlign: \"center\",\n textTransform: \"uppercase\",\n }}\n >\n {LEVEL_LABELS[level]}\n </span>\n );\n};\n","import type { DevtoolsLogRecord } from \"../../types\";\nimport { theme } from \"../theme\";\n\nfunction formatTimestamp(ts: number): string {\n const d = new Date(ts);\n return d.toLocaleTimeString(undefined, {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n });\n}\n\nfunction safeStringify(value: unknown, indent = 2): string {\n try {\n return JSON.stringify(value, null, indent);\n } catch {\n return String(value);\n }\n}\n\nconst DetailRow = ({ label, children }: { label: string; children: React.ReactNode }) => (\n <div style={{ display: \"flex\", gap: theme.spacing.lg, marginBottom: theme.spacing.md }}>\n <span\n style={{\n color: theme.colors.textMuted,\n flexShrink: 0,\n fontSize: theme.fontSize.md,\n minWidth: \"72px\",\n textAlign: \"right\",\n }}\n >\n {label}\n </span>\n <span style={{ fontSize: theme.fontSize.base, wordBreak: \"break-all\" }}>{children}</span>\n </div>\n);\n\nexport const LogDetail = ({ record }: { record: DevtoolsLogRecord }) => {\n const levelColors = theme.colors.levels[record.level];\n const hasProperties = Object.keys(record.properties).length > 0;\n\n return (\n <div\n data-testid=\"log-detail\"\n style={{\n background: levelColors.bg,\n borderTop: `1px solid ${theme.colors.border}`,\n padding: `${theme.spacing.lg} ${theme.spacing.xl}`,\n }}\n >\n <DetailRow label=\"Time\">{formatTimestamp(record.timestamp)}</DetailRow>\n <DetailRow label=\"Level\">\n <span style={{ color: levelColors.color, fontWeight: 600 }}>{record.level}</span>\n </DetailRow>\n <DetailRow label=\"Category\">\n <span style={{ color: theme.colors.accent, fontFamily: theme.fontFamily.mono }}>\n {record.category.join(\".\")}\n </span>\n </DetailRow>\n {record.caller && (\n <DetailRow label=\"Caller\">\n <span style={{ color: theme.colors.textSecondary, fontFamily: theme.fontFamily.mono }}>\n {record.caller}\n </span>\n </DetailRow>\n )}\n <DetailRow label=\"Message\">\n <span style={{ color: theme.colors.textPrimary }}>{record.messageText}</span>\n </DetailRow>\n\n {hasProperties && (\n <DetailRow label=\"Data\">\n <pre\n style={{\n background: \"rgba(0,0,0,0.3)\",\n borderRadius: theme.radius.md,\n color: theme.colors.textPrimary,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n margin: 0,\n maxHeight: \"200px\",\n overflow: \"auto\",\n padding: theme.spacing.lg,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-all\",\n }}\n >\n {safeStringify(record.properties)}\n </pre>\n </DetailRow>\n )}\n </div>\n );\n};\n","import { Combobox } from \"@base-ui-components/react/combobox\";\nimport { Popover } from \"@base-ui-components/react/popover\";\nimport { Debouncer } from \"@tanstack/pacer\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { LOG_LEVELS, type LogLevel } from \"../../types\";\nimport { CheckIcon, PauseIcon, PlayIcon, Trash2Icon, XIcon } from \"../icons\";\nimport { theme } from \"../theme\";\n\ninterface ToolbarProps {\n categories: string[];\n categoryFilter: string[];\n filteredCount: number;\n levelFilter: Set<LogLevel>;\n onCategoryFilterChange: (value: string[]) => void;\n onClear: () => void;\n onLevelFilterChange: (levels: Set<LogLevel>) => void;\n onPause: () => void;\n onResume: () => void;\n onSearchTextChange: (value: string) => void;\n paused: boolean;\n searchText: string;\n totalCount: number;\n}\n\n// Inject hover styles once (scoped via data attribute to avoid leaking)\nconst HOVER_STYLE_ID = \"logtape-devtools-hover\";\nfunction useHoverStyles() {\n useEffect(() => {\n if (document.getElementById(HOVER_STYLE_ID)) {\n return;\n }\n const style = document.createElement(\"style\");\n style.id = HOVER_STYLE_ID;\n style.textContent = `\n [data-lt-interactive]:hover {\n filter: brightness(1.25);\n }\n [data-lt-interactive]:active {\n filter: brightness(0.9);\n }\n [data-lt-clear-btn]:hover {\n color: ${theme.colors.textPrimary} !important;\n }\n [data-lt-chip-remove]:hover {\n opacity: 1 !important;\n color: ${theme.colors.white} !important;\n }\n `;\n document.head.appendChild(style);\n }, []);\n}\n\nconst buttonStyle = {\n background: theme.colors.surfaceHover,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.md,\n color: theme.colors.textPrimary,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n transition: \"filter 0.1s, background 0.1s, border-color 0.1s\",\n width: \"100%\",\n} as const;\n\nconst inputStyle = {\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.borderInput}`,\n borderRadius: theme.radius.md,\n color: theme.colors.textPrimary,\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n outline: \"none\",\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n transition: \"border-color 0.15s\",\n width: \"100%\",\n} as const;\n\nconst sectionLabelStyle = {\n color: theme.colors.textMuted,\n fontSize: \"9px\",\n fontWeight: 600,\n letterSpacing: \"0.05em\",\n textTransform: \"uppercase\",\n} as const;\n\nconst LevelToggle = ({\n level,\n active,\n onToggle,\n}: {\n level: LogLevel;\n active: boolean;\n onToggle: (level: LogLevel) => void;\n}) => {\n const colors = theme.colors.levels[level];\n const handleClick = useCallback(() => onToggle(level), [level, onToggle]);\n\n return (\n <button\n aria-pressed={active}\n data-lt-interactive=\"\"\n data-testid={`level-toggle-${level}`}\n onClick={handleClick}\n style={{\n background: active ? colors.badge : \"transparent\",\n border: `1px solid ${active ? colors.badge : theme.colors.border}`,\n borderRadius: theme.radius.sm,\n color: active ? theme.colors.white : colors.color,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n fontWeight: 600,\n lineHeight: 1,\n minWidth: \"30px\",\n opacity: active ? 1 : 0.5,\n padding: \"3px 0\",\n textAlign: \"center\" as const,\n transition: \"all 0.15s\",\n }}\n title={`Filter ${level} logs`}\n type=\"button\"\n >\n {level.slice(0, 3).toUpperCase()}\n </button>\n );\n};\n\nexport const Toolbar = ({\n paused,\n onPause,\n onResume,\n onClear,\n levelFilter,\n onLevelFilterChange,\n categories,\n categoryFilter,\n onCategoryFilterChange,\n searchText,\n onSearchTextChange,\n totalCount,\n filteredCount,\n}: ToolbarProps) => {\n useHoverStyles();\n\n const [localSearch, setLocalSearch] = useState(searchText);\n const debouncedSearch = useMemo(\n () => new Debouncer(onSearchTextChange, { wait: 200 }),\n [onSearchTextChange]\n );\n\n const handleSearchChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setLocalSearch(value);\n debouncedSearch.maybeExecute(value);\n },\n [debouncedSearch]\n );\n\n // Sync local state when parent clears search\n useEffect(() => {\n if (searchText === \"\" && localSearch !== \"\") {\n setLocalSearch(\"\");\n }\n }, [searchText, localSearch]);\n\n const handleLevelToggle = useCallback(\n (level: LogLevel) => {\n const next = new Set(levelFilter);\n if (next.has(level)) {\n next.delete(level);\n } else {\n next.add(level);\n }\n onLevelFilterChange(next);\n },\n [levelFilter, onLevelFilterChange]\n );\n\n return (\n <div\n data-testid=\"toolbar\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n flexShrink: 0,\n gap: theme.spacing.xl,\n height: \"100%\",\n minWidth: \"200px\",\n overflow: \"auto\",\n padding: `${theme.spacing.lg} ${theme.spacing.xl}`,\n }}\n >\n {/* Log count */}\n <div style={{ textAlign: \"center\" }}>\n <span\n style={{\n color: theme.colors.textPrimary,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.lg,\n fontWeight: 600,\n }}\n >\n {filteredCount === totalCount ? `${totalCount}` : `${filteredCount} / ${totalCount}`}\n </span>\n <div style={{ color: theme.colors.textMuted, fontSize: theme.fontSize.sm }}>logs</div>\n </div>\n\n {/* Actions */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={sectionLabelStyle}>Actions</div>\n <button\n data-lt-interactive=\"\"\n onClick={paused ? onResume : onPause}\n style={{\n ...buttonStyle,\n background: paused ? theme.colors.levels.warning.badge : buttonStyle.background,\n color: paused ? theme.colors.white : buttonStyle.color,\n }}\n title={paused ? \"Resume live updates\" : \"Pause live updates\"}\n type=\"button\"\n >\n <span style={{ alignItems: \"center\", display: \"inline-flex\", gap: \"6px\" }}>\n {paused ? <PlayIcon size={12} /> : <PauseIcon size={12} />}\n {paused ? \"Resume\" : \"Pause\"}\n </span>\n </button>\n\n <button\n data-lt-interactive=\"\"\n onClick={onClear}\n style={buttonStyle}\n title=\"Clear all logs\"\n type=\"button\"\n >\n <span style={{ alignItems: \"center\", display: \"inline-flex\", gap: \"6px\" }}>\n <Trash2Icon size={12} />\n Clear\n </span>\n </button>\n </div>\n\n {/* Level filters */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={{ alignItems: \"center\", display: \"flex\", justifyContent: \"space-between\" }}>\n <div style={sectionLabelStyle}>Levels</div>\n {levelFilter.size > 0 && (\n <button\n data-lt-clear-btn=\"\"\n onClick={() => onLevelFilterChange(new Set())}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontSize: \"9px\",\n padding: 0,\n transition: \"color 0.1s\",\n }}\n title=\"Show all levels\"\n type=\"button\"\n >\n clear\n </button>\n )}\n </div>\n <div\n style={{\n display: \"grid\",\n gap: theme.spacing.xs,\n gridTemplateColumns: \"repeat(3, 1fr)\",\n }}\n >\n {LOG_LEVELS.map((level) => (\n <LevelToggle\n active={levelFilter.size === 0 || levelFilter.has(level)}\n key={level}\n level={level}\n onToggle={handleLevelToggle}\n />\n ))}\n </div>\n </div>\n\n {/* Category filter (multi-select combobox) */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={{ alignItems: \"center\", display: \"flex\", justifyContent: \"space-between\" }}>\n <div style={sectionLabelStyle}>Category</div>\n {categoryFilter.length > 0 && (\n <button\n data-lt-clear-btn=\"\"\n onClick={() => onCategoryFilterChange([])}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontSize: \"9px\",\n padding: 0,\n transition: \"color 0.1s\",\n }}\n title=\"Clear all categories\"\n type=\"button\"\n >\n clear\n </button>\n )}\n </div>\n {categories.length === 0 ? (\n <Popover.Root>\n <Popover.Trigger\n delay={300}\n nativeButton={false}\n openOnHover\n render={\n <div\n data-testid=\"category-input\"\n style={{\n ...inputStyle,\n color: theme.colors.textMuted,\n cursor: \"not-allowed\",\n opacity: 0.5,\n }}\n >\n Category…\n </div>\n }\n />\n <Popover.Portal>\n <Popover.Positioner sideOffset={6} style={{ zIndex: 999_999 }}>\n <Popover.Popup\n style={{\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.md,\n boxShadow: \"0 8px 24px rgba(0,0,0,0.5)\",\n fontSize: theme.fontSize.sm,\n maxWidth: \"200px\",\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n }}\n >\n <p style={{ color: theme.colors.textMuted, lineHeight: 1.4, margin: 0 }}>\n Waiting for logs to populate available categories.\n </p>\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n ) : (\n <Combobox.Root\n items={categories}\n multiple\n onValueChange={onCategoryFilterChange}\n value={categoryFilter}\n >\n <div\n style={{\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.borderInput}`,\n borderRadius: theme.radius.md,\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"3px\",\n minHeight: \"28px\",\n padding: \"3px\",\n transition: \"border-color 0.15s\",\n }}\n >\n {categoryFilter.map((cat) => (\n <span\n key={cat}\n style={{\n alignItems: \"center\",\n background: \"rgba(99, 102, 241, 0.15)\",\n border: \"1px solid rgba(99, 102, 241, 0.3)\",\n borderRadius: theme.radius.sm,\n color: theme.colors.accentHover,\n display: \"inline-flex\",\n fontFamily: theme.fontFamily.mono,\n fontSize: \"9px\",\n gap: \"3px\",\n lineHeight: 1,\n padding: \"1px 4px\",\n }}\n >\n {cat}\n <button\n data-lt-chip-remove=\"\"\n onClick={() => onCategoryFilterChange(categoryFilter.filter((c) => c !== cat))}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontSize: \"7px\",\n lineHeight: 1,\n opacity: 0.7,\n padding: 0,\n transition: \"color 0.1s, opacity 0.1s\",\n }}\n title={`Remove ${cat}`}\n type=\"button\"\n >\n <XIcon size={7} />\n </button>\n </span>\n ))}\n <Combobox.Input\n data-testid=\"category-input\"\n placeholder={categoryFilter.length === 0 ? \"Category…\" : \"\"}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: theme.colors.textPrimary,\n flex: 1,\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n minWidth: \"40px\",\n outline: \"none\",\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n }}\n />\n </div>\n <Combobox.Portal>\n <Combobox.Positioner style={{ zIndex: 999_999 }}>\n <Combobox.Popup\n style={{\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.md,\n boxShadow: \"0 8px 24px rgba(0,0,0,0.5)\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n padding: theme.spacing.xs,\n }}\n >\n <Combobox.List>\n {(item, index) => (\n <Combobox.Item\n index={index}\n key={String(item)}\n style={{\n alignItems: \"center\",\n borderRadius: theme.radius.sm,\n color: theme.colors.textPrimary,\n cursor: \"pointer\",\n display: \"flex\",\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n gap: theme.spacing.sm,\n justifyContent: \"space-between\",\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n transition: \"background 0.1s\",\n }}\n value={item}\n >\n <span style={{ flex: 1, overflow: \"hidden\", textOverflow: \"ellipsis\" }}>\n {String(item)}\n </span>\n <Combobox.ItemIndicator>\n <CheckIcon color={theme.colors.accent} size={14} />\n </Combobox.ItemIndicator>\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Popup>\n </Combobox.Positioner>\n </Combobox.Portal>\n </Combobox.Root>\n )}\n </div>\n\n {/* Text search */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={sectionLabelStyle}>Search</div>\n <input\n data-testid=\"search-input\"\n onChange={handleSearchChange}\n placeholder=\"Search…\"\n style={inputStyle}\n type=\"text\"\n value={localSearch}\n />\n </div>\n </div>\n );\n};\n","export type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warning\" | \"error\" | \"fatal\";\n\nexport const LOG_LEVELS: LogLevel[] = [\"trace\", \"debug\", \"info\", \"warning\", \"error\", \"fatal\"];\n\nexport interface DevtoolsLogRecord {\n /** Source location of the log call (only present when `experimentalCaptureStackTrace` is enabled). */\n caller?: string;\n category: string[];\n id: string;\n level: LogLevel;\n message: unknown[];\n messageText: string;\n properties: Record<string, unknown>;\n timestamp: number;\n}\n","import { defaultLogStore, type LogStore } from \"../store\";\nimport { LogTapeDevtoolsPlugin } from \"./logtape-devtools-plugin\";\n\nexport interface LogTapeDevtoolsPluginOptions {\n /** Whether to open the devtools panel by default. Default: true */\n defaultOpen?: boolean;\n /** Plugin display name. Default: \"LogTape\" */\n name?: string;\n /** Custom log store instance. Must match the store passed to createDevtoolsSink. */\n store?: LogStore;\n}\n\n/**\n * Creates a TanStack DevTools plugin config object for LogTape.\n *\n * Usage:\n * ```tsx\n * import { TanStackDevtools } from \"@tanstack/react-devtools\";\n * import { createLogTapeDevtoolsPlugin } from \"@mugenlabs/logtape-devtools\";\n *\n * <TanStackDevtools plugins={[createLogTapeDevtoolsPlugin()]} />\n * ```\n */\nexport const createLogTapeDevtoolsPlugin = (options?: LogTapeDevtoolsPluginOptions) => ({\n defaultOpen: options?.defaultOpen ?? true,\n id: \"logtape-devtools-plugin\",\n name: options?.name ?? \"LogTape\",\n render: <LogTapeDevtoolsPlugin store={options?.store ?? defaultLogStore} />,\n});\n","import type { LogRecord, Sink } from \"@logtape/logtape\";\nimport { defaultLogStore, type LogStore } from \"./store\";\nimport type { DevtoolsLogRecord, LogLevel } from \"./types\";\n\nlet counter = 0;\n\nfunction renderMessage(message: readonly unknown[]): string {\n return message\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n }\n if (part === null || part === undefined) {\n return String(part);\n }\n try {\n return JSON.stringify(part);\n } catch {\n return String(part);\n }\n })\n .join(\"\");\n}\n\nfunction safeCloneProperties(properties: Record<string, unknown>): Record<string, unknown> {\n try {\n return JSON.parse(JSON.stringify(properties));\n } catch {\n // Fallback: shallow copy with stringified values for non-serializable entries\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(properties)) {\n try {\n result[key] = JSON.parse(JSON.stringify(value));\n } catch {\n result[key] = String(value);\n }\n }\n return result;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Stack trace parser — extracts the caller frame from `new Error().stack`\n// ---------------------------------------------------------------------------\n\n// V8 (Chrome/Node/Edge): \" at functionName (file:line:col)\"\nconst v8FrameRe = /at\\s+(?:.*?\\s+\\()?(.+?):(\\d+):(\\d+)\\)?$/;\n// SpiderMonkey (Firefox) / JSC (Safari): \"functionName@file:line:col\"\nconst smFrameRe = /(?:^|@)(.+?):(\\d+):(\\d+)$/;\n\nfunction captureCallerInfo(): string | undefined {\n // biome-ignore lint/suspicious/useErrorMessage: we only need the stack trace, not the message\n const stack = new Error().stack;\n if (!stack) {\n return undefined;\n }\n\n const lines = stack.split(\"\\n\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines and the \"Error\" header\n if (!trimmed || trimmed === \"Error\") {\n continue;\n }\n\n // Skip frames from logtape internals (both @logtape/logtape and @mugenlabs/logtape-devtools)\n if (/logtape/i.test(trimmed)) {\n continue;\n }\n\n // Try V8 format first, then SpiderMonkey/JSC\n const match = v8FrameRe.exec(trimmed) ?? smFrameRe.exec(trimmed);\n if (!match) {\n continue;\n }\n\n const [, filePath, lineNo, colNo] = match;\n\n // Extract just the filename from the full path/URL\n const fileName =\n filePath\n .replace(/[?#].*$/, \"\")\n .split(\"/\")\n .pop() ?? filePath;\n\n return `${fileName}:${lineNo}:${colNo}`;\n }\n\n return undefined;\n}\n\nfunction normalizeRecord(record: LogRecord, captureStack: boolean): DevtoolsLogRecord {\n const normalized: DevtoolsLogRecord = {\n id: `log-${++counter}-${record.timestamp}`,\n timestamp: record.timestamp,\n level: record.level as LogLevel,\n category: [...record.category],\n message: [...record.message],\n messageText: renderMessage(record.message),\n properties: safeCloneProperties(record.properties),\n };\n\n if (captureStack) {\n const caller = captureCallerInfo();\n if (caller) {\n normalized.caller = caller;\n }\n }\n\n return normalized;\n}\n\nfunction isProductionEnv(): boolean {\n try {\n // Bundlers (Vite, webpack, etc.) statically replace this at build time\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\") {\n return true;\n }\n } catch {\n // process may not exist in browser environments\n }\n return false;\n}\n\nexport interface DevtoolsSinkOptions {\n /**\n * Capture the source location of each log call via stack trace parsing.\n *\n * **Experimental / dev-only** — relies on `new Error().stack` which is\n * engine-dependent. Automatically disabled in production builds (when\n * `process.env.NODE_ENV === \"production\"`) because minified bundles\n * produce meaningless file/line references. Note that source maps do not\n * help here — browsers do not apply source maps to `Error.stack`.\n *\n * Set `forceStackTrace` to `true` to override the production guard — useful\n * when your production build ships unminified code.\n *\n * @default true\n */\n experimentalCaptureStackTrace?: boolean;\n /**\n * Force stack trace capture even in production builds.\n * Only has an effect when `experimentalCaptureStackTrace` is `true`.\n *\n * @default false\n */\n forceStackTrace?: boolean;\n /** Custom log store instance. Defaults to the shared store. */\n store?: LogStore;\n}\n\n/**\n * Creates a LogTape sink that forwards log records to the devtools panel.\n *\n * Usage:\n * ```ts\n * import { configure } from \"@logtape/logtape\";\n * import { createDevtoolsSink } from \"@mugenlabs/logtape-devtools\";\n *\n * await configure({\n * sinks: { devtools: createDevtoolsSink() },\n * loggers: [\n * { category: [\"app\"], lowestLevel: \"debug\", sinks: [\"devtools\"] },\n * ],\n * });\n * ```\n */\nexport function createDevtoolsSink(options?: DevtoolsSinkOptions): Sink {\n const store = options?.store ?? defaultLogStore;\n const wantsStack = options?.experimentalCaptureStackTrace ?? true;\n const captureStack = wantsStack && (options?.forceStackTrace || !isProductionEnv());\n\n return (record: LogRecord) => {\n try {\n const normalized = normalizeRecord(record, captureStack);\n store.addRecord(normalized);\n } catch {\n // Fail silently — devtools should never break the application\n }\n };\n}\n"],"mappings":"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","names":["useCallback","useMemo","useState","jsx","jsx","jsxs","jsx","jsxs","jsx","useCallback","useEffect","jsx","jsxs","useEffect","useCallback","jsx","jsxs","useState","useCallback","useMemo","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/store.ts","../src/plugin/logtape-devtools-plugin.tsx","../src/plugin/components/log-list.tsx","../src/plugin/theme.ts","../src/plugin/components/log-row.tsx","../src/plugin/icons.tsx","../src/plugin/components/level-badge.tsx","../src/plugin/components/log-detail.tsx","../src/plugin/components/toolbar.tsx","../src/types.ts","../src/plugin/create-logtape-devtools-plugin.tsx","../src/sink.ts"],"sourcesContent":["import type { DevtoolsLogRecord } from \"./types\";\n\ntype Listener = () => void;\n\nexport interface LogStore {\n addRecord(record: DevtoolsLogRecord): void;\n clear(): void;\n getSnapshot(): DevtoolsLogRecord[];\n setMaxSize(size: number): void;\n subscribe(listener: Listener): () => void;\n}\n\nexport function createLogStore(maxSize = 1000): LogStore {\n let records: DevtoolsLogRecord[] = [];\n let max = maxSize;\n const listeners = new Set<Listener>();\n\n function notify() {\n for (const listener of listeners) {\n listener();\n }\n }\n\n return {\n getSnapshot: () => records,\n addRecord: (record) => {\n // Create new array reference for useSyncExternalStore\n records = [...records, record];\n if (records.length > max) {\n records = records.slice(records.length - max);\n }\n notify();\n },\n clear: () => {\n records = [];\n notify();\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n setMaxSize: (size) => {\n max = size;\n if (records.length > max) {\n records = records.slice(records.length - max);\n notify();\n }\n },\n };\n}\n\n/** Default shared store instance used when no custom store is provided */\nexport const defaultLogStore = createLogStore();\n","import { useCallback, useMemo, useState, useSyncExternalStore } from \"react\";\nimport type { LogStore } from \"../store\";\nimport type { DevtoolsLogRecord, LogLevel } from \"../types\";\nimport { LogList } from \"./components/log-list\";\nimport { Toolbar } from \"./components/toolbar\";\nimport { PanelLeftCloseIcon, PanelLeftOpenIcon, PauseIcon, PlayIcon, Trash2Icon } from \"./icons\";\nimport { theme } from \"./theme\";\n\ninterface Props {\n store: LogStore;\n}\n\nexport const LogTapeDevtoolsPlugin = ({ store }: Props) => {\n const allRecords = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\n const [paused, setPaused] = useState(false);\n const [pausedRecords, setPausedRecords] = useState<DevtoolsLogRecord[]>([]);\n const [levelFilter, setLevelFilter] = useState<Set<LogLevel>>(new Set());\n const [categoryFilter, setCategoryFilter] = useState<string[]>([]);\n const [searchText, setSearchText] = useState(\"\");\n const [expandedId, setExpandedId] = useState<string | null>(null);\n const [sidebarOpen, setSidebarOpen] = useState(true);\n\n const handlePause = useCallback(() => {\n setPaused(true);\n setPausedRecords(store.getSnapshot());\n }, [store]);\n\n const handleResume = useCallback(() => {\n setPaused(false);\n setPausedRecords([]);\n }, []);\n\n const handleClear = useCallback(() => {\n store.clear();\n setPausedRecords([]);\n setExpandedId(null);\n }, [store]);\n\n const records = paused ? pausedRecords : allRecords;\n\n const uniqueCategories = useMemo(() => {\n const seen = new Set<string>();\n for (const r of records) {\n seen.add(r.category.join(\".\"));\n }\n return Array.from(seen).sort();\n }, [records]);\n\n const filteredRecords = useMemo(() => {\n return records.filter((r) => {\n if (levelFilter.size > 0 && !levelFilter.has(r.level)) {\n return false;\n }\n if (categoryFilter.length > 0 && !categoryFilter.includes(r.category.join(\".\"))) {\n return false;\n }\n if (searchText) {\n const term = searchText.toLowerCase();\n if (\n !(\n r.messageText.toLowerCase().includes(term) ||\n r.category.join(\".\").toLowerCase().includes(term)\n )\n ) {\n return false;\n }\n }\n return true;\n });\n }, [records, levelFilter, categoryFilter, searchText]);\n\n return (\n <div\n style={{\n background: theme.colors.background,\n color: theme.colors.textPrimary,\n display: \"flex\",\n flexDirection: \"row\",\n fontFamily: theme.fontFamily.sans,\n height: \"100%\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n borderRight: sidebarOpen ? `1px solid ${theme.colors.border}` : \"none\",\n flexShrink: 0,\n opacity: sidebarOpen ? 1 : 0,\n overflow: \"hidden\",\n transition: \"width 0.2s ease, opacity 0.15s ease\",\n width: sidebarOpen ? \"200px\" : \"0px\",\n }}\n >\n <Toolbar\n categories={uniqueCategories}\n categoryFilter={categoryFilter}\n filteredCount={filteredRecords.length}\n levelFilter={levelFilter}\n onCategoryFilterChange={setCategoryFilter}\n onClear={handleClear}\n onLevelFilterChange={setLevelFilter}\n onPause={handlePause}\n onResume={handleResume}\n onSearchTextChange={setSearchText}\n paused={paused}\n searchText={searchText}\n totalCount={records.length}\n />\n </div>\n\n <div style={{ display: \"flex\", flex: 1, flexDirection: \"column\", overflow: \"hidden\" }}>\n {/* Sidebar toggle bar */}\n <div\n style={{\n alignItems: \"center\",\n borderBottom: `1px solid ${theme.colors.border}`,\n display: \"flex\",\n flexShrink: 0,\n gap: theme.spacing.lg,\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n }}\n >\n <button\n aria-expanded={sidebarOpen}\n data-lt-clear-btn=\"\"\n onClick={() => setSidebarOpen((v) => !v)}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n transition: \"color 0.1s\",\n }}\n title={sidebarOpen ? \"Collapse sidebar\" : \"Expand sidebar\"}\n type=\"button\"\n >\n <span style={{ alignItems: \"center\", display: \"inline-flex\", gap: \"6px\" }}>\n {sidebarOpen ? <PanelLeftCloseIcon size={14} /> : <PanelLeftOpenIcon size={14} />}\n {sidebarOpen ? \"Hide controls\" : \"Show controls\"}\n </span>\n </button>\n\n {!sidebarOpen && (\n <>\n <span\n style={{\n color: theme.colors.textMuted,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n }}\n >\n {filteredRecords.length === records.length\n ? `${records.length} logs`\n : `${filteredRecords.length} / ${records.length} logs`}\n </span>\n <button\n data-lt-interactive=\"\"\n onClick={paused ? handleResume : handlePause}\n style={{\n background: paused\n ? theme.colors.levels.warning.badge\n : theme.colors.surfaceHover,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.sm,\n color: paused ? theme.colors.white : theme.colors.textPrimary,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.sm,\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n transition: \"filter 0.1s\",\n }}\n title={paused ? \"Resume\" : \"Pause\"}\n type=\"button\"\n >\n {paused ? <PlayIcon size={12} /> : <PauseIcon size={12} />}\n </button>\n <button\n data-lt-interactive=\"\"\n onClick={handleClear}\n style={{\n background: theme.colors.surfaceHover,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.sm,\n color: theme.colors.textPrimary,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.sm,\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n transition: \"filter 0.1s\",\n }}\n title=\"Clear\"\n type=\"button\"\n >\n <Trash2Icon size={12} />\n </button>\n </>\n )}\n </div>\n <LogList\n autoScroll={!paused}\n expandedId={expandedId}\n onToggle={setExpandedId}\n records={filteredRecords}\n />\n </div>\n </div>\n );\n};\n","import { useEffect, useRef } from \"react\";\nimport type { DevtoolsLogRecord } from \"../../types\";\nimport { theme } from \"../theme\";\nimport { LogRow } from \"./log-row\";\n\ninterface LogListProps {\n autoScroll: boolean;\n expandedId: string | null;\n onToggle: (id: string | null) => void;\n records: DevtoolsLogRecord[];\n}\n\nexport const LogList = ({ records, expandedId, onToggle, autoScroll }: LogListProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const isAtBottomRef = useRef(true);\n\n const recordCount = records.length;\n // biome-ignore lint/correctness/useExhaustiveDependencies: recordCount triggers scroll on new records\n useEffect(() => {\n const el = containerRef.current;\n if (!(el && autoScroll && isAtBottomRef.current)) {\n return;\n }\n el.scrollTop = el.scrollHeight;\n }, [autoScroll, recordCount]);\n\n const handleScroll = () => {\n const el = containerRef.current;\n if (!el) {\n return;\n }\n // Consider \"at bottom\" if within 40px of the end\n isAtBottomRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 40;\n };\n\n if (records.length === 0) {\n return (\n <div\n data-testid=\"log-list-empty\"\n style={{\n alignItems: \"center\",\n color: theme.colors.textMuted,\n display: \"flex\",\n flex: 1,\n fontSize: theme.fontSize.lg,\n justifyContent: \"center\",\n }}\n >\n No logs yet\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"log-list\"\n onScroll={handleScroll}\n ref={containerRef}\n style={{\n flex: 1,\n overflow: \"auto\",\n scrollbarColor: `${theme.colors.scrollbar} transparent`,\n scrollbarWidth: \"thin\",\n }}\n >\n {records.map((record) => (\n <LogRow\n expanded={expandedId === record.id}\n key={record.id}\n onToggle={onToggle}\n record={record}\n />\n ))}\n </div>\n );\n};\n","export const theme = {\n colors: {\n background: \"#1e1e1e\",\n surface: \"#1a1a1a\",\n surfaceHover: \"#2a2a2a\",\n surfaceSelected: \"#2a2a3a\",\n border: \"#333\",\n borderInput: \"#444\",\n borderFocus: \"#6366f1\",\n\n textPrimary: \"#e0e0e0\",\n textSecondary: \"#888\",\n textMuted: \"#666\",\n textDimmed: \"#555\",\n white: \"#fff\",\n\n accent: \"#6366f1\",\n accentHover: \"#818cf8\",\n\n levels: {\n trace: { bg: \"#1a1a2e\", color: \"#8888bb\", badge: \"#5555aa\" },\n debug: { bg: \"#1a2a1a\", color: \"#88bb88\", badge: \"#55aa55\" },\n info: { bg: \"#1a2a3a\", color: \"#60a5fa\", badge: \"#3b82f6\" },\n warning: { bg: \"#2a2a1a\", color: \"#facc15\", badge: \"#eab308\" },\n error: { bg: \"#2a1a1a\", color: \"#ef4444\", badge: \"#dc2626\" },\n fatal: { bg: \"#3a0a0a\", color: \"#ff6b6b\", badge: \"#b91c1c\" },\n },\n\n scrollbar: \"#444\",\n scrollbarHover: \"#555\",\n },\n\n fontFamily: {\n mono: 'ui-monospace, \"Cascadia Code\", \"Source Code Pro\", Menlo, Consolas, monospace',\n sans: 'system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif',\n },\n\n fontSize: {\n xs: \"9px\",\n sm: \"10px\",\n md: \"11px\",\n base: \"12px\",\n lg: \"13px\",\n },\n\n radius: {\n sm: \"3px\",\n md: \"4px\",\n lg: \"6px\",\n pill: \"10px\",\n },\n\n spacing: {\n xs: \"2px\",\n sm: \"4px\",\n md: \"6px\",\n lg: \"8px\",\n xl: \"12px\",\n xxl: \"16px\",\n },\n} as const;\n\nexport type LogLevelColors = (typeof theme.colors.levels)[keyof typeof theme.colors.levels];\n","import { useCallback } from \"react\";\nimport type { DevtoolsLogRecord } from \"../../types\";\nimport { ChevronRightIcon } from \"../icons\";\nimport { theme } from \"../theme\";\nimport { LevelBadge } from \"./level-badge\";\nimport { LogDetail } from \"./log-detail\";\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts);\n return d.toLocaleTimeString(undefined, {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n });\n}\n\ninterface LogRowProps {\n expanded: boolean;\n onToggle: (id: string | null) => void;\n record: DevtoolsLogRecord;\n}\n\nexport const LogRow = ({ record, expanded, onToggle }: LogRowProps) => {\n const levelColors = theme.colors.levels[record.level];\n\n const handleClick = useCallback(() => {\n onToggle(expanded ? null : record.id);\n }, [expanded, onToggle, record.id]);\n\n return (\n <div>\n <button\n aria-expanded={expanded}\n data-lt-interactive=\"\"\n data-testid=\"log-row\"\n onClick={handleClick}\n style={{\n alignItems: \"center\",\n background: expanded ? levelColors.bg : \"transparent\",\n border: \"none\",\n borderBottom: `1px solid ${theme.colors.border}`,\n cursor: \"pointer\",\n display: \"flex\",\n gap: theme.spacing.lg,\n padding: `${theme.spacing.md} ${theme.spacing.xl}`,\n textAlign: \"left\",\n transition: \"background 0.1s, filter 0.1s\",\n width: \"100%\",\n }}\n type=\"button\"\n >\n {/* Timestamp */}\n <span\n style={{\n color: theme.colors.textDimmed,\n flexShrink: 0,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n }}\n >\n {formatTime(record.timestamp)}\n </span>\n\n {/* Level badge */}\n <LevelBadge level={record.level} />\n\n {/* Category */}\n <span\n style={{\n color: theme.colors.accent,\n flexShrink: 0,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n maxWidth: \"180px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {record.category.join(\".\")}\n </span>\n\n {/* Message */}\n <span\n style={{\n color: theme.colors.textPrimary,\n flex: 1,\n fontSize: theme.fontSize.base,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {record.messageText}\n </span>\n\n {/* Caller (right-aligned) */}\n {record.caller && (\n <span\n style={{\n color: theme.colors.textDimmed,\n flexShrink: 0,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n maxWidth: \"200px\",\n opacity: 0.7,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {record.caller}\n </span>\n )}\n\n {/* Expand indicator */}\n <span\n style={{\n color: theme.colors.textDimmed,\n display: \"flex\",\n flexShrink: 0,\n transform: expanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.15s\",\n }}\n >\n <ChevronRightIcon size={12} />\n </span>\n </button>\n\n {expanded && <LogDetail record={record} />}\n </div>\n );\n};\n","/**\n * Inline SVG icons based on Lucide (https://lucide.dev) — ISC License.\n * Using inline SVGs avoids adding lucide-react as a runtime dependency.\n */\n\ninterface IconProps {\n color?: string;\n size?: number;\n style?: React.CSSProperties;\n}\n\nconst defaults = { size: 14, color: \"currentColor\" } as const;\n\nconst Svg = ({\n size = defaults.size,\n color = defaults.color,\n style,\n children,\n}: IconProps & { children: React.ReactNode }) => (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height={size}\n stroke={color}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n style={style}\n viewBox=\"0 0 24 24\"\n width={size}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {children}\n </svg>\n);\n\nexport const PlayIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\" />\n </Svg>\n);\n\nexport const PauseIcon = (props: IconProps) => (\n <Svg {...props}>\n <rect height={18} rx={1} width={5} x={14} y={3} />\n <rect height={18} rx={1} width={5} x={5} y={3} />\n </Svg>\n);\n\nexport const XIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </Svg>\n);\n\nexport const CheckIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Svg>\n);\n\nexport const ChevronRightIcon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"m9 18 6-6-6-6\" />\n </Svg>\n);\n\nexport const PanelLeftCloseIcon = (props: IconProps) => (\n <Svg {...props}>\n <rect height={18} rx={2} width={18} x={3} y={3} />\n <path d=\"M9 3v18\" />\n <path d=\"m16 15-3-3 3-3\" />\n </Svg>\n);\n\nexport const PanelLeftOpenIcon = (props: IconProps) => (\n <Svg {...props}>\n <rect height={18} rx={2} width={18} x={3} y={3} />\n <path d=\"M9 3v18\" />\n <path d=\"m14 9 3 3-3 3\" />\n </Svg>\n);\n\nexport const Trash2Icon = (props: IconProps) => (\n <Svg {...props}>\n <path d=\"M10 11v6\" />\n <path d=\"M14 11v6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </Svg>\n);\n","import type { LogLevel } from \"../../types\";\nimport { theme } from \"../theme\";\n\nconst LEVEL_LABELS: Record<LogLevel, string> = {\n trace: \"TRC\",\n debug: \"DBG\",\n info: \"INF\",\n warning: \"WRN\",\n error: \"ERR\",\n fatal: \"FTL\",\n};\n\nexport const LevelBadge = ({ level }: { level: LogLevel }) => {\n const colors = theme.colors.levels[level];\n\n return (\n <span\n style={{\n background: colors.badge,\n borderRadius: theme.radius.sm,\n color: theme.colors.white,\n display: \"inline-block\",\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n fontWeight: 600,\n lineHeight: 1,\n minWidth: \"28px\",\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n textAlign: \"center\",\n textTransform: \"uppercase\",\n }}\n >\n {LEVEL_LABELS[level]}\n </span>\n );\n};\n","import type { DevtoolsLogRecord } from \"../../types\";\nimport { theme } from \"../theme\";\n\nfunction formatTimestamp(ts: number): string {\n const d = new Date(ts);\n return d.toLocaleTimeString(undefined, {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n });\n}\n\nfunction safeStringify(value: unknown, indent = 2): string {\n try {\n return JSON.stringify(value, null, indent);\n } catch {\n return String(value);\n }\n}\n\nconst DetailRow = ({ label, children }: { label: string; children: React.ReactNode }) => (\n <div style={{ display: \"flex\", gap: theme.spacing.lg, marginBottom: theme.spacing.md }}>\n <span\n style={{\n color: theme.colors.textMuted,\n flexShrink: 0,\n fontSize: theme.fontSize.md,\n minWidth: \"72px\",\n textAlign: \"right\",\n }}\n >\n {label}\n </span>\n <span style={{ fontSize: theme.fontSize.base, wordBreak: \"break-all\" }}>{children}</span>\n </div>\n);\n\nexport const LogDetail = ({ record }: { record: DevtoolsLogRecord }) => {\n const levelColors = theme.colors.levels[record.level];\n const hasProperties = Object.keys(record.properties).length > 0;\n\n return (\n <div\n data-testid=\"log-detail\"\n style={{\n background: levelColors.bg,\n borderTop: `1px solid ${theme.colors.border}`,\n padding: `${theme.spacing.lg} ${theme.spacing.xl}`,\n }}\n >\n <DetailRow label=\"Time\">{formatTimestamp(record.timestamp)}</DetailRow>\n <DetailRow label=\"Level\">\n <span style={{ color: levelColors.color, fontWeight: 600 }}>{record.level}</span>\n </DetailRow>\n <DetailRow label=\"Category\">\n <span style={{ color: theme.colors.accent, fontFamily: theme.fontFamily.mono }}>\n {record.category.join(\".\")}\n </span>\n </DetailRow>\n {record.caller && (\n <DetailRow label=\"Caller\">\n <span style={{ color: theme.colors.textSecondary, fontFamily: theme.fontFamily.mono }}>\n {record.caller}\n </span>\n </DetailRow>\n )}\n <DetailRow label=\"Message\">\n <span style={{ color: theme.colors.textPrimary }}>{record.messageText}</span>\n </DetailRow>\n\n {hasProperties && (\n <DetailRow label=\"Data\">\n <pre\n style={{\n background: \"rgba(0,0,0,0.3)\",\n borderRadius: theme.radius.md,\n color: theme.colors.textPrimary,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n margin: 0,\n maxHeight: \"200px\",\n overflow: \"auto\",\n padding: theme.spacing.lg,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-all\",\n }}\n >\n {safeStringify(record.properties)}\n </pre>\n </DetailRow>\n )}\n </div>\n );\n};\n","import { Combobox } from \"@base-ui-components/react/combobox\";\nimport { Popover } from \"@base-ui-components/react/popover\";\nimport { Debouncer } from \"@tanstack/pacer\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { LOG_LEVELS, type LogLevel } from \"../../types\";\nimport { CheckIcon, PauseIcon, PlayIcon, Trash2Icon, XIcon } from \"../icons\";\nimport { theme } from \"../theme\";\n\ninterface ToolbarProps {\n categories: string[];\n categoryFilter: string[];\n filteredCount: number;\n levelFilter: Set<LogLevel>;\n onCategoryFilterChange: (value: string[]) => void;\n onClear: () => void;\n onLevelFilterChange: (levels: Set<LogLevel>) => void;\n onPause: () => void;\n onResume: () => void;\n onSearchTextChange: (value: string) => void;\n paused: boolean;\n searchText: string;\n totalCount: number;\n}\n\n// Inject hover styles once (scoped via data attribute to avoid leaking)\nconst HOVER_STYLE_ID = \"logtape-devtools-hover\";\nfunction useHoverStyles() {\n useEffect(() => {\n if (document.getElementById(HOVER_STYLE_ID)) {\n return;\n }\n const style = document.createElement(\"style\");\n style.id = HOVER_STYLE_ID;\n style.textContent = `\n [data-lt-interactive]:hover {\n filter: brightness(1.25);\n }\n [data-lt-interactive]:active {\n filter: brightness(0.9);\n }\n [data-lt-clear-btn]:hover {\n color: ${theme.colors.textPrimary} !important;\n }\n [data-lt-chip-remove]:hover {\n opacity: 1 !important;\n color: ${theme.colors.white} !important;\n }\n `;\n document.head.appendChild(style);\n }, []);\n}\n\nconst buttonStyle = {\n background: theme.colors.surfaceHover,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.md,\n color: theme.colors.textPrimary,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n transition: \"filter 0.1s, background 0.1s, border-color 0.1s\",\n width: \"100%\",\n} as const;\n\nconst inputStyle = {\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.borderInput}`,\n borderRadius: theme.radius.md,\n color: theme.colors.textPrimary,\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n outline: \"none\",\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n transition: \"border-color 0.15s\",\n width: \"100%\",\n} as const;\n\nconst sectionLabelStyle = {\n color: theme.colors.textMuted,\n fontSize: \"9px\",\n fontWeight: 600,\n letterSpacing: \"0.05em\",\n textTransform: \"uppercase\",\n} as const;\n\nconst LevelToggle = ({\n level,\n active,\n onToggle,\n}: {\n level: LogLevel;\n active: boolean;\n onToggle: (level: LogLevel) => void;\n}) => {\n const colors = theme.colors.levels[level];\n const handleClick = useCallback(() => onToggle(level), [level, onToggle]);\n\n return (\n <button\n aria-pressed={active}\n data-lt-interactive=\"\"\n data-testid={`level-toggle-${level}`}\n onClick={handleClick}\n style={{\n background: active ? colors.badge : \"transparent\",\n border: `1px solid ${active ? colors.badge : theme.colors.border}`,\n borderRadius: theme.radius.sm,\n color: active ? theme.colors.white : colors.color,\n cursor: \"pointer\",\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.sm,\n fontWeight: 600,\n lineHeight: 1,\n minWidth: \"30px\",\n opacity: active ? 1 : 0.5,\n padding: \"3px 0\",\n textAlign: \"center\" as const,\n transition: \"all 0.15s\",\n }}\n title={`Filter ${level} logs`}\n type=\"button\"\n >\n {level.slice(0, 3).toUpperCase()}\n </button>\n );\n};\n\nexport const Toolbar = ({\n paused,\n onPause,\n onResume,\n onClear,\n levelFilter,\n onLevelFilterChange,\n categories,\n categoryFilter,\n onCategoryFilterChange,\n searchText,\n onSearchTextChange,\n totalCount,\n filteredCount,\n}: ToolbarProps) => {\n useHoverStyles();\n\n const [localSearch, setLocalSearch] = useState(searchText);\n const debouncedSearch = useMemo(\n () => new Debouncer(onSearchTextChange, { wait: 200 }),\n [onSearchTextChange]\n );\n\n useEffect(() => () => debouncedSearch.cancel(), [debouncedSearch]);\n\n const handleSearchChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setLocalSearch(value);\n debouncedSearch.maybeExecute(value);\n },\n [debouncedSearch]\n );\n\n // Sync local state when parent clears search\n useEffect(() => {\n if (searchText === \"\" && localSearch !== \"\") {\n setLocalSearch(\"\");\n }\n }, [searchText, localSearch]);\n\n const handleLevelToggle = useCallback(\n (level: LogLevel) => {\n const next = new Set(levelFilter);\n if (next.has(level)) {\n next.delete(level);\n } else {\n next.add(level);\n }\n onLevelFilterChange(next);\n },\n [levelFilter, onLevelFilterChange]\n );\n\n return (\n <div\n data-testid=\"toolbar\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n flexShrink: 0,\n gap: theme.spacing.xl,\n height: \"100%\",\n minWidth: \"200px\",\n overflow: \"auto\",\n padding: `${theme.spacing.lg} ${theme.spacing.xl}`,\n }}\n >\n {/* Log count */}\n <div style={{ textAlign: \"center\" }}>\n <span\n style={{\n color: theme.colors.textPrimary,\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.lg,\n fontWeight: 600,\n }}\n >\n {filteredCount === totalCount ? `${totalCount}` : `${filteredCount} / ${totalCount}`}\n </span>\n <div style={{ color: theme.colors.textMuted, fontSize: theme.fontSize.sm }}>logs</div>\n </div>\n\n {/* Actions */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={sectionLabelStyle}>Actions</div>\n <button\n data-lt-interactive=\"\"\n onClick={paused ? onResume : onPause}\n style={{\n ...buttonStyle,\n background: paused ? theme.colors.levels.warning.badge : buttonStyle.background,\n color: paused ? theme.colors.white : buttonStyle.color,\n }}\n title={paused ? \"Resume live updates\" : \"Pause live updates\"}\n type=\"button\"\n >\n <span style={{ alignItems: \"center\", display: \"inline-flex\", gap: \"6px\" }}>\n {paused ? <PlayIcon size={12} /> : <PauseIcon size={12} />}\n {paused ? \"Resume\" : \"Pause\"}\n </span>\n </button>\n\n <button\n data-lt-interactive=\"\"\n onClick={onClear}\n style={buttonStyle}\n title=\"Clear all logs\"\n type=\"button\"\n >\n <span style={{ alignItems: \"center\", display: \"inline-flex\", gap: \"6px\" }}>\n <Trash2Icon size={12} />\n Clear\n </span>\n </button>\n </div>\n\n {/* Level filters */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={{ alignItems: \"center\", display: \"flex\", justifyContent: \"space-between\" }}>\n <div style={sectionLabelStyle}>Levels</div>\n {levelFilter.size > 0 && (\n <button\n data-lt-clear-btn=\"\"\n onClick={() => onLevelFilterChange(new Set())}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontSize: \"9px\",\n padding: 0,\n transition: \"color 0.1s\",\n }}\n title=\"Show all levels\"\n type=\"button\"\n >\n clear\n </button>\n )}\n </div>\n <div\n style={{\n display: \"grid\",\n gap: theme.spacing.xs,\n gridTemplateColumns: \"repeat(3, 1fr)\",\n }}\n >\n {LOG_LEVELS.map((level) => (\n <LevelToggle\n active={levelFilter.size === 0 || levelFilter.has(level)}\n key={level}\n level={level}\n onToggle={handleLevelToggle}\n />\n ))}\n </div>\n </div>\n\n {/* Category filter (multi-select combobox) */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={{ alignItems: \"center\", display: \"flex\", justifyContent: \"space-between\" }}>\n <div style={sectionLabelStyle}>Category</div>\n {categoryFilter.length > 0 && (\n <button\n data-lt-clear-btn=\"\"\n onClick={() => onCategoryFilterChange([])}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontSize: \"9px\",\n padding: 0,\n transition: \"color 0.1s\",\n }}\n title=\"Clear all categories\"\n type=\"button\"\n >\n clear\n </button>\n )}\n </div>\n {categories.length === 0 ? (\n <Popover.Root>\n <Popover.Trigger\n delay={300}\n nativeButton={false}\n openOnHover\n render={\n <div\n data-testid=\"category-input\"\n style={{\n ...inputStyle,\n color: theme.colors.textMuted,\n cursor: \"not-allowed\",\n opacity: 0.5,\n }}\n >\n Category…\n </div>\n }\n />\n <Popover.Portal>\n <Popover.Positioner sideOffset={6} style={{ zIndex: 999_999 }}>\n <Popover.Popup\n style={{\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.md,\n boxShadow: \"0 8px 24px rgba(0,0,0,0.5)\",\n fontSize: theme.fontSize.sm,\n maxWidth: \"200px\",\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n }}\n >\n <p style={{ color: theme.colors.textMuted, lineHeight: 1.4, margin: 0 }}>\n Waiting for logs to populate available categories.\n </p>\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n ) : (\n <Combobox.Root\n items={categories}\n multiple\n onValueChange={onCategoryFilterChange}\n value={categoryFilter}\n >\n <div\n style={{\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.borderInput}`,\n borderRadius: theme.radius.md,\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"3px\",\n minHeight: \"28px\",\n padding: \"3px\",\n transition: \"border-color 0.15s\",\n }}\n >\n {categoryFilter.map((cat) => (\n <span\n key={cat}\n style={{\n alignItems: \"center\",\n background: \"rgba(99, 102, 241, 0.15)\",\n border: \"1px solid rgba(99, 102, 241, 0.3)\",\n borderRadius: theme.radius.sm,\n color: theme.colors.accentHover,\n display: \"inline-flex\",\n fontFamily: theme.fontFamily.mono,\n fontSize: \"9px\",\n gap: \"3px\",\n lineHeight: 1,\n padding: \"1px 4px\",\n }}\n >\n {cat}\n <button\n data-lt-chip-remove=\"\"\n onClick={() => onCategoryFilterChange(categoryFilter.filter((c) => c !== cat))}\n style={{\n background: \"none\",\n border: \"none\",\n color: theme.colors.textMuted,\n cursor: \"pointer\",\n fontSize: \"7px\",\n lineHeight: 1,\n opacity: 0.7,\n padding: 0,\n transition: \"color 0.1s, opacity 0.1s\",\n }}\n title={`Remove ${cat}`}\n type=\"button\"\n >\n <XIcon size={7} />\n </button>\n </span>\n ))}\n <Combobox.Input\n data-testid=\"category-input\"\n placeholder={categoryFilter.length === 0 ? \"Category…\" : \"\"}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: theme.colors.textPrimary,\n flex: 1,\n fontFamily: theme.fontFamily.sans,\n fontSize: theme.fontSize.md,\n minWidth: \"40px\",\n outline: \"none\",\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\n }}\n />\n </div>\n <Combobox.Portal>\n <Combobox.Positioner style={{ zIndex: 999_999 }}>\n <Combobox.Popup\n style={{\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radius.md,\n boxShadow: \"0 8px 24px rgba(0,0,0,0.5)\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n padding: theme.spacing.xs,\n }}\n >\n <Combobox.List>\n {(item, index) => (\n <Combobox.Item\n index={index}\n key={String(item)}\n style={{\n alignItems: \"center\",\n borderRadius: theme.radius.sm,\n color: theme.colors.textPrimary,\n cursor: \"pointer\",\n display: \"flex\",\n fontFamily: theme.fontFamily.mono,\n fontSize: theme.fontSize.md,\n gap: theme.spacing.sm,\n justifyContent: \"space-between\",\n padding: `${theme.spacing.sm} ${theme.spacing.lg}`,\n transition: \"background 0.1s\",\n }}\n value={item}\n >\n <span style={{ flex: 1, overflow: \"hidden\", textOverflow: \"ellipsis\" }}>\n {String(item)}\n </span>\n <Combobox.ItemIndicator>\n <CheckIcon color={theme.colors.accent} size={14} />\n </Combobox.ItemIndicator>\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Popup>\n </Combobox.Positioner>\n </Combobox.Portal>\n </Combobox.Root>\n )}\n </div>\n\n {/* Text search */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: theme.spacing.sm }}>\n <div style={sectionLabelStyle}>Search</div>\n <input\n data-testid=\"search-input\"\n onChange={handleSearchChange}\n placeholder=\"Search…\"\n style={inputStyle}\n type=\"text\"\n value={localSearch}\n />\n </div>\n </div>\n );\n};\n","export type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warning\" | \"error\" | \"fatal\";\n\nexport const LOG_LEVELS: LogLevel[] = [\"trace\", \"debug\", \"info\", \"warning\", \"error\", \"fatal\"];\n\nexport interface DevtoolsLogRecord {\n /** Source location of the log call (only present when `experimentalCaptureStackTrace` is enabled). */\n caller?: string;\n category: string[];\n id: string;\n level: LogLevel;\n message: unknown[];\n messageText: string;\n properties: Record<string, unknown>;\n timestamp: number;\n}\n","import { defaultLogStore, type LogStore } from \"../store\";\nimport { LogTapeDevtoolsPlugin } from \"./logtape-devtools-plugin\";\n\nexport interface LogTapeDevtoolsPluginOptions {\n /** Whether to open the devtools panel by default. Default: true */\n defaultOpen?: boolean;\n /** Plugin display name. Default: \"LogTape\" */\n name?: string;\n /** Custom log store instance. Must match the store passed to createDevtoolsSink. */\n store?: LogStore;\n}\n\n/**\n * Creates a TanStack DevTools plugin config object for LogTape.\n *\n * Usage:\n * ```tsx\n * import { TanStackDevtools } from \"@tanstack/react-devtools\";\n * import { createLogTapeDevtoolsPlugin } from \"@mugenlabs/logtape-devtools\";\n *\n * <TanStackDevtools plugins={[createLogTapeDevtoolsPlugin()]} />\n * ```\n */\nexport const createLogTapeDevtoolsPlugin = (options?: LogTapeDevtoolsPluginOptions) => ({\n defaultOpen: options?.defaultOpen ?? true,\n id: \"logtape-devtools-plugin\",\n name: options?.name ?? \"LogTape\",\n render: <LogTapeDevtoolsPlugin store={options?.store ?? defaultLogStore} />,\n});\n","import type { LogRecord, Sink } from \"@logtape/logtape\";\nimport { defaultLogStore, type LogStore } from \"./store\";\nimport type { DevtoolsLogRecord, LogLevel } from \"./types\";\n\nfunction renderMessage(message: readonly unknown[]): string {\n return message\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n }\n if (part === null || part === undefined) {\n return String(part);\n }\n try {\n return JSON.stringify(part);\n } catch {\n return String(part);\n }\n })\n .join(\"\");\n}\n\nfunction safeCloneProperties(properties: Record<string, unknown>): Record<string, unknown> {\n try {\n return JSON.parse(JSON.stringify(properties));\n } catch {\n // Fallback: shallow copy with stringified values for non-serializable entries\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(properties)) {\n try {\n result[key] = JSON.parse(JSON.stringify(value));\n } catch {\n result[key] = String(value);\n }\n }\n return result;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Stack trace parser — extracts the caller frame from `new Error().stack`\n// ---------------------------------------------------------------------------\n\n// V8 (Chrome/Node/Edge): \" at functionName (file:line:col)\"\nconst v8FrameRe = /at\\s+(?:.*?\\s+\\()?(.+?):(\\d+):(\\d+)\\)?$/;\n// SpiderMonkey (Firefox) / JSC (Safari): \"functionName@file:line:col\"\nconst smFrameRe = /(?:^|@)(.+?):(\\d+):(\\d+)$/;\n\nfunction captureCallerInfo(): string | undefined {\n // biome-ignore lint/suspicious/useErrorMessage: we only need the stack trace, not the message\n const stack = new Error().stack;\n if (!stack) {\n return undefined;\n }\n\n const lines = stack.split(\"\\n\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines and the \"Error\" header\n if (!trimmed || trimmed === \"Error\") {\n continue;\n }\n\n // Skip frames from logtape internals (both @logtape/logtape and @mugenlabs/logtape-devtools)\n if (/logtape/i.test(trimmed)) {\n continue;\n }\n\n // Try V8 format first, then SpiderMonkey/JSC\n const match = v8FrameRe.exec(trimmed) ?? smFrameRe.exec(trimmed);\n if (!match) {\n continue;\n }\n\n const [, filePath, lineNo, colNo] = match;\n\n // Extract just the filename from the full path/URL\n const fileName =\n filePath\n .replace(/[?#].*$/, \"\")\n .split(\"/\")\n .pop() ?? filePath;\n\n return `${fileName}:${lineNo}:${colNo}`;\n }\n\n return undefined;\n}\n\nfunction normalizeRecord(record: LogRecord, captureStack: boolean, id: string): DevtoolsLogRecord {\n const normalized: DevtoolsLogRecord = {\n id,\n timestamp: record.timestamp,\n level: record.level as LogLevel,\n category: [...record.category],\n message: [...record.message],\n messageText: renderMessage(record.message),\n properties: safeCloneProperties(record.properties),\n };\n\n if (captureStack) {\n const caller = captureCallerInfo();\n if (caller) {\n normalized.caller = caller;\n }\n }\n\n return normalized;\n}\n\nfunction isProductionEnv(): boolean {\n try {\n // Bundlers (Vite, webpack, etc.) statically replace this at build time\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\") {\n return true;\n }\n } catch {\n // process may not exist in browser environments\n }\n return false;\n}\n\nexport interface DevtoolsSinkOptions {\n /**\n * Capture the source location of each log call via stack trace parsing.\n *\n * **Experimental / dev-only** — relies on `new Error().stack` which is\n * engine-dependent. Automatically disabled in production builds (when\n * `process.env.NODE_ENV === \"production\"`) because minified bundles\n * produce meaningless file/line references. Note that source maps do not\n * help here — browsers do not apply source maps to `Error.stack`.\n *\n * Set `forceStackTrace` to `true` to override the production guard — useful\n * when your production build ships unminified code.\n *\n * @default true\n */\n experimentalCaptureStackTrace?: boolean;\n /**\n * Force stack trace capture even in production builds.\n * Only has an effect when `experimentalCaptureStackTrace` is `true`.\n *\n * @default false\n */\n forceStackTrace?: boolean;\n /** Custom log store instance. Defaults to the shared store. */\n store?: LogStore;\n}\n\n/**\n * Creates a LogTape sink that forwards log records to the devtools panel.\n *\n * Usage:\n * ```ts\n * import { configure } from \"@logtape/logtape\";\n * import { createDevtoolsSink } from \"@mugenlabs/logtape-devtools\";\n *\n * await configure({\n * sinks: { devtools: createDevtoolsSink() },\n * loggers: [\n * { category: [\"app\"], lowestLevel: \"debug\", sinks: [\"devtools\"] },\n * ],\n * });\n * ```\n */\nexport function createDevtoolsSink(options?: DevtoolsSinkOptions): Sink {\n const store = options?.store ?? defaultLogStore;\n const wantsStack = options?.experimentalCaptureStackTrace ?? true;\n const captureStack = wantsStack && (options?.forceStackTrace || !isProductionEnv());\n\n // Per-sink counter, plus a random discriminator so that two sinks sharing a\n // single store cannot emit the same id for records with equal timestamps.\n const sinkId = Math.random().toString(36).slice(2, 8);\n let counter = 0;\n\n return (record: LogRecord) => {\n try {\n const normalized = normalizeRecord(\n record,\n captureStack,\n `log-${sinkId}-${++counter}-${record.timestamp}`\n );\n store.addRecord(normalized);\n } catch {\n // Fail silently — devtools should never break the application\n }\n };\n}\n"],"mappings":"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","names":["useCallback","useMemo","useState","jsx","jsx","jsxs","jsx","jsxs","jsx","useCallback","useEffect","jsx","jsxs","useEffect","useCallback","jsx","jsxs","useState","useCallback","useMemo","jsx"]}
|