@neuradigi/debug-console 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/dist/index.cjs +266 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +158 -0
- package/dist/index.d.ts +158 -0
- package/dist/index.js +266 -0
- package/dist/index.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/icons.ts","../src/logger.ts","../src/styles.ts","../src/console-element.ts","../src/index.ts"],"names":["svg","paths","icons","LEVELS","LoggerCore","options","listener","con","level","original","args","event","text","entry","arg","value","seen","_key","val","logger","STYLES","FILTERS","pad","n","len","fmtTime","d","fmtDateTime","fmtFileStamp","HTMLElementBase","DebugConsoleElement","filtersEl","def","chip","selector","row","time","tag","errors","warnings","total","badge","open","c","entries","content","e","blob","url","link","ELEMENT_NAME","defineDebugConsole","name","startCapture","initDebugConsole","existing","element","mount"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Inline, line-style SVG icons (currentColor-driven, no icon-font dependency).\n * 24×24 viewBox, 2px stroke — resolution-independent and themeable via `color`.\n */\nconst svg = (paths: string): string =>\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">${paths}</svg>`;\n\nexport const icons = {\n /** Terminal window with a prompt — launcher + panel title. */\n terminal: svg('<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"/><path d=\"m7 9 3 3-3 3\"/><path d=\"M13 15h4\"/>'),\n /** Pin — \"pinned to the newest line\" (auto-scroll on). */\n pin: svg('<path d=\"M12 17v5\"/><path d=\"M9 10.8V6a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8\"/><path d=\"M9 10.8a2 2 0 0 1-1.1 1.8l-1.8.9A2 2 0 0 0 5 15.2V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.8a2 2 0 0 0-1.1-1.7l-1.8-.9A2 2 0 0 1 15 10.8V6a1 1 0 0 0-1-1\"/>'),\n /** Double chevron down — jump to latest. */\n chevronsDown: svg('<path d=\"m7 6 5 5 5-5\"/><path d=\"m7 13 5 5 5-5\"/>'),\n /** Tray with down arrow — download. */\n download: svg('<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><path d=\"m7 10 5 5 5-5\"/><path d=\"M12 15V3\"/>'),\n /** Trash — clear. */\n trash: svg('<path d=\"M3 6h18\"/><path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/><path d=\"m19 6-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/>'),\n /** X — close. */\n close: svg('<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>')\n} as const;\n","import type { LogEntry, LogLevel } from './types';\n\n/** Emitted to subscribers whenever the buffer changes. */\nexport type LogEvent = { type: 'add'; entry: LogEntry } | { type: 'clear' };\n\ntype LogListener = (event: LogEvent) => void;\n\nconst LEVELS: readonly LogLevel[] = ['log', 'info', 'warn', 'error', 'debug'];\n\n/**\n * Framework-agnostic capture core. Patches the global `console`, buffers entries\n * (bounded, oldest dropped), captures uncaught errors, and notifies subscribers.\n * A single shared instance is exported as {@link logger}.\n *\n * Patched methods always call the original first, so DevTools keeps working —\n * this MIRRORS console output, it never swallows it.\n */\nclass LoggerCore {\n private readonly _entries: LogEntry[] = [];\n private readonly listeners = new Set<LogListener>();\n private nextId = 0;\n private max = 500;\n private patched = false;\n private errorsHooked = false;\n\n /** The current buffer, oldest → newest (read-only). */\n get entries(): readonly LogEntry[] {\n return this._entries;\n }\n\n /** The configured buffer cap. */\n get limit(): number {\n return this.max;\n }\n\n /** Patch the console and (optionally) global error handlers. Idempotent. */\n init(options: { max?: number; captureGlobalErrors?: boolean } = {}): void {\n if (typeof options.max === 'number' && options.max > 0) {\n this.max = Math.floor(options.max);\n }\n this.patchConsole();\n if (options.captureGlobalErrors !== false) {\n this.captureGlobalErrors();\n }\n }\n\n /** Subscribe to buffer changes. Returns an unsubscribe function. */\n subscribe(listener: LogListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /** Empty the buffer (does not unpatch the console). */\n clear(): void {\n this._entries.length = 0;\n this.emit({ type: 'clear' });\n }\n\n private patchConsole(): void {\n if (this.patched || typeof console === 'undefined') {\n return;\n }\n this.patched = true;\n\n // Cast to a writable record of only the levels we patch; every other native\n // console method is left untouched.\n const con = console as unknown as Record<LogLevel, (...args: unknown[]) => void>;\n for (const level of LEVELS) {\n const original = con[level].bind(console);\n con[level] = (...args: unknown[]): void => {\n original(...args); // mirror — forward to the real console first\n this.push(level, this.stringifyArgs(args));\n };\n }\n }\n\n private captureGlobalErrors(): void {\n if (this.errorsHooked || typeof window === 'undefined') {\n return;\n }\n this.errorsHooked = true;\n\n window.addEventListener('error', (event: ErrorEvent): void => {\n const text = event.error != null ? this.stringifyValue(event.error) : event.message || 'Uncaught error';\n this.push('error', text);\n });\n\n window.addEventListener('unhandledrejection', (event: PromiseRejectionEvent): void => {\n this.push('error', `Unhandled promise rejection: ${this.stringifyValue(event.reason)}`);\n });\n }\n\n private push(level: LogLevel, text: string): void {\n const entry: LogEntry = { id: this.nextId++, level, time: new Date(), text };\n this._entries.push(entry);\n if (this._entries.length > this.max) {\n this._entries.splice(0, this._entries.length - this.max);\n }\n this.emit({ type: 'add', entry });\n }\n\n private emit(event: LogEvent): void {\n // A subscriber error must never break the patched console it was triggered from.\n this.listeners.forEach(listener => {\n try {\n listener(event);\n } catch {\n /* swallow — the mirror must not affect the app's own console call */\n }\n });\n }\n\n private stringifyArgs(args: unknown[]): string {\n return args.map(arg => this.stringifyValue(arg)).join(' ');\n }\n\n private stringifyValue(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n if (value instanceof Error) {\n return `${value.name}: ${value.message}`;\n }\n\n try {\n const seen = new WeakSet<object>();\n const json = JSON.stringify(\n value,\n (_key: string, val: unknown) => {\n if (typeof val === 'bigint') {\n return val.toString();\n }\n if (typeof val === 'object' && val !== null) {\n if (seen.has(val)) {\n return '[Circular]';\n }\n seen.add(val);\n }\n return val;\n },\n 2\n );\n return json ?? String(value);\n } catch {\n return String(value);\n }\n }\n}\n\n/** The shared capture core (console is global, so there is exactly one). */\nexport const logger = new LoggerCore();\n","/**\n * Shadow-DOM stylesheet for the debug console. Self-contained fixed dark\n * \"terminal\" palette (theme-independent), with a handful of `--dc-*` custom\n * properties consumers can override (e.g. `--dc-accent`). Because it lives in a\n * shadow root, none of these rules leak into or out of the host application.\n */\nexport const STYLES = `\n:host {\n --dc-bg: #0b0e14;\n --dc-surface: #11151f;\n --dc-border: #232a3a;\n --dc-text: #c9d1d9;\n --dc-muted: #8b949e;\n --dc-row-hover: rgba(255, 255, 255, 0.04);\n --dc-shadow: 0 10px 34px rgba(0, 0, 0, 0.5);\n --dc-accent: linear-gradient(135deg, #57bdff, #4f77fb, #3a5fcc);\n --dc-error: #ff6b6b;\n --dc-warn: #ffc107;\n --dc-info: #57bdff;\n --dc-badge-error: #dc3545;\n --dc-badge-warn: #ffc107;\n font-family: 'Cascadia Code', 'Fira Code', 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n[hidden] { display: none !important; }\n\n/* ===== Launcher ===== */\n.dc-launcher {\n position: fixed;\n top: 16px;\n right: 16px;\n z-index: 2147483000;\n width: 44px;\n height: 44px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 50%;\n background: var(--dc-accent);\n color: #fff;\n cursor: pointer;\n box-shadow: var(--dc-shadow);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n.dc-launcher svg { width: 22px; height: 22px; }\n.dc-launcher:hover { transform: scale(1.05); box-shadow: 0 6px 20px rgba(79, 119, 251, 0.45); }\n:host([data-position=\"top-left\"]) .dc-launcher { top: 16px; left: 16px; right: auto; }\n:host([data-position=\"bottom-right\"]) .dc-launcher { top: auto; bottom: 16px; right: 16px; }\n:host([data-position=\"bottom-left\"]) .dc-launcher { top: auto; bottom: 16px; left: 16px; right: auto; }\n\n/* ===== Badge ===== */\n.dc-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n border-radius: 999px;\n border: 2px solid var(--dc-bg);\n}\n.dc-badge--error { background: var(--dc-badge-error); color: #fff; }\n.dc-badge--warn { background: var(--dc-badge-warn); color: #000; }\n\n/* ===== Panel ===== */\n.dc-panel {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2147482000;\n display: flex;\n flex-direction: column;\n max-height: 50vh;\n background: var(--dc-bg);\n color: var(--dc-text);\n border-bottom: 1px solid var(--dc-border);\n box-shadow: var(--dc-shadow);\n transform: translateY(-100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.dc-panel--open { transform: translateY(0); }\n\n/* ===== Header ===== */\n.dc-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 8px 16px;\n background: var(--dc-surface);\n border-bottom: 1px solid var(--dc-border);\n flex-shrink: 0;\n}\n.dc-title { display: flex; align-items: center; gap: 8px; min-width: 0; }\n.dc-title-icon { display: inline-flex; color: var(--dc-info); }\n.dc-title-icon svg { width: 20px; height: 20px; }\n.dc-title-text { font-size: 14px; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap; color: var(--dc-text); }\n.dc-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 18px;\n padding: 0 6px;\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n color: #fff;\n background: var(--dc-accent);\n border-radius: 999px;\n}\n\n/* ===== Actions ===== */\n.dc-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }\n.dc-action {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n color: var(--dc-muted);\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: color 0.2s ease, background-color 0.2s ease;\n}\n.dc-action svg { width: 18px; height: 18px; }\n.dc-action:hover:not(:disabled) { color: var(--dc-text); background: var(--dc-row-hover); }\n.dc-action:disabled { opacity: 0.35; cursor: default; }\n.dc-action--active { color: var(--dc-info); }\n\n/* ===== Tooltips (self-contained; no host overlay layer) ===== */\n.dc-action[data-tip]:hover::after,\n.dc-launcher[data-tip]:hover::after {\n content: attr(data-tip);\n position: absolute;\n padding: 4px 8px;\n border-radius: 6px;\n background: #000;\n color: #fff;\n font-size: 11px;\n font-family: system-ui, -apple-system, sans-serif;\n font-weight: 500;\n white-space: nowrap;\n pointer-events: none;\n z-index: 10;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);\n}\n.dc-action[data-tip]:hover::after {\n top: calc(100% + 6px);\n left: 50%;\n transform: translateX(-50%);\n}\n.dc-launcher[data-tip]:hover::after {\n top: 50%;\n right: calc(100% + 8px);\n transform: translateY(-50%);\n}\n:host([data-position=\"top-left\"]) .dc-launcher[data-tip]:hover::after,\n:host([data-position=\"bottom-left\"]) .dc-launcher[data-tip]:hover::after {\n right: auto;\n left: calc(100% + 8px);\n}\n\n/* ===== Filter chips ===== */\n.dc-filters {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n padding: 8px 16px;\n background: var(--dc-surface);\n border-bottom: 1px solid var(--dc-border);\n flex-shrink: 0;\n}\n.dc-chip {\n padding: 3px 12px;\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.03em;\n color: var(--dc-muted);\n background: transparent;\n border: 1px solid var(--dc-border);\n border-radius: 999px;\n cursor: pointer;\n font-family: inherit;\n transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;\n}\n.dc-chip:hover { color: var(--dc-text); border-color: #4f77fb; }\n.dc-chip--active { color: #fff; border-color: transparent; background: var(--dc-accent); }\n\n/* ===== List ===== */\n.dc-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 4px 0;\n scrollbar-width: thin;\n scrollbar-color: var(--dc-border) transparent;\n}\n.dc-list::-webkit-scrollbar { width: 10px; }\n.dc-list::-webkit-scrollbar-thumb { background: var(--dc-border); border-radius: 999px; }\n.dc-list::-webkit-scrollbar-track { background: transparent; }\n\n.dc-row {\n display: grid;\n grid-template-columns: auto auto minmax(0, 1fr);\n gap: 8px;\n align-items: baseline;\n padding: 4px 16px;\n border-left: 3px solid transparent;\n font-size: 12px;\n line-height: 1.5;\n}\n.dc-row:hover { background: var(--dc-row-hover); }\n.dc-row--error { border-left-color: var(--dc-error); }\n.dc-row--error .dc-tag, .dc-row--error .dc-text { color: var(--dc-error); }\n.dc-row--warn { border-left-color: var(--dc-warn); }\n.dc-row--warn .dc-tag { color: var(--dc-warn); }\n.dc-row--info { border-left-color: var(--dc-info); }\n.dc-row--info .dc-tag { color: var(--dc-info); }\n.dc-row--log, .dc-row--debug { border-left-color: var(--dc-muted); }\n.dc-row--log .dc-tag, .dc-row--debug .dc-tag { color: var(--dc-muted); }\n\n.dc-time { color: var(--dc-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }\n.dc-tag { min-width: 42px; font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; white-space: nowrap; }\n.dc-text { margin: 0; min-width: 0; font-family: inherit; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; color: var(--dc-text); }\n\n.dc-empty { padding: 24px 16px; text-align: center; font-size: 13px; color: var(--dc-muted); }\n\n@media (max-width: 600px) {\n .dc-panel { max-height: 65vh; }\n}\n`;\n","import { icons } from './icons';\nimport { logger, type LogEvent } from './logger';\nimport { STYLES } from './styles';\nimport type { LogEntry, LogLevel } from './types';\n\ninterface FilterDef {\n value: string;\n label: string;\n match: (level: LogLevel) => boolean;\n}\n\nconst FILTERS: readonly FilterDef[] = [\n { value: 'all', label: 'All', match: () => true },\n { value: 'log', label: 'Log', match: level => level === 'log' || level === 'debug' },\n { value: 'info', label: 'Info', match: level => level === 'info' },\n { value: 'warn', label: 'Warn', match: level => level === 'warn' },\n { value: 'error', label: 'Error', match: level => level === 'error' }\n];\n\nconst pad = (n: number, len = 2): string => String(n).padStart(len, '0');\nconst fmtTime = (d: Date): string => `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${pad(d.getMilliseconds(), 3)}`;\nconst fmtDateTime = (d: Date): string => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${fmtTime(d)}`;\nconst fmtFileStamp = (d: Date): string =>\n `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;\n\n// SSR-safe base: in a non-browser runtime `HTMLElement` is undefined, so extend\n// a harmless stub. The DOM-touching methods only ever run in the browser.\nconst HTMLElementBase: typeof HTMLElement =\n typeof HTMLElement !== 'undefined' ? HTMLElement : (class {} as unknown as typeof HTMLElement);\n\n/**\n * `<debug-console>` custom element. Renders the launcher + panel inside a shadow\n * root (full style isolation) and mirrors {@link logger}'s buffer in real time.\n * Register it with `defineDebugConsole()` or mount it via `initDebugConsole()`.\n */\nexport class DebugConsoleElement extends HTMLElementBase {\n private readonly root: ShadowRoot;\n\n private launcherEl!: HTMLButtonElement;\n private badgeEl!: HTMLElement;\n private panelEl!: HTMLElement;\n private countEl!: HTMLElement;\n private listEl!: HTMLElement;\n private emptyEl!: HTMLElement;\n private autoScrollBtn!: HTMLButtonElement;\n private downloadBtn!: HTMLButtonElement;\n private clearBtn!: HTMLButtonElement;\n\n private unsubscribe: (() => void) | null = null;\n private isOpen = false;\n private autoScroll = true;\n private filter: FilterDef = FILTERS[0];\n\n constructor() {\n super();\n this.root = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback(): void {\n this.render();\n this.replayExisting();\n this.unsubscribe = logger.subscribe(event => this.onLog(event));\n }\n\n disconnectedCallback(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n\n /** Open the panel. */\n show(): void {\n this.setOpen(true);\n }\n\n /** Close the panel. */\n hide(): void {\n this.setOpen(false);\n }\n\n /** Toggle the panel. */\n toggle(): void {\n this.setOpen(!this.isOpen);\n }\n\n private render(): void {\n this.root.innerHTML = `\n <style>${STYLES}</style>\n <button class=\"dc-launcher\" type=\"button\" part=\"launcher\" data-tip=\"Show application logs\" aria-label=\"Show application logs\">\n ${icons.terminal}\n <span class=\"dc-badge\" hidden></span>\n </button>\n <section class=\"dc-panel\" part=\"panel\" role=\"log\" aria-live=\"polite\" aria-label=\"Application logs\">\n <header class=\"dc-header\">\n <div class=\"dc-title\">\n <span class=\"dc-title-icon\">${icons.terminal}</span>\n <span class=\"dc-title-text\">Application Logs</span>\n <span class=\"dc-count\" hidden>0</span>\n </div>\n <div class=\"dc-actions\">\n <button class=\"dc-action dc-action--active\" type=\"button\" data-act=\"autoscroll\" data-tip=\"Auto-scroll: on (following newest)\" aria-label=\"Toggle auto-scroll\">${icons.pin}</button>\n <button class=\"dc-action\" type=\"button\" data-act=\"bottom\" data-tip=\"Scroll to bottom\" aria-label=\"Scroll to bottom\">${icons.chevronsDown}</button>\n <button class=\"dc-action\" type=\"button\" data-act=\"download\" data-tip=\"Download logs\" aria-label=\"Download logs\" disabled>${icons.download}</button>\n <button class=\"dc-action\" type=\"button\" data-act=\"clear\" data-tip=\"Clear logs\" aria-label=\"Clear logs\" disabled>${icons.trash}</button>\n <button class=\"dc-action\" type=\"button\" data-act=\"close\" data-tip=\"Close\" aria-label=\"Close application logs\">${icons.close}</button>\n </div>\n </header>\n <div class=\"dc-filters\"></div>\n <div class=\"dc-list\"></div>\n <div class=\"dc-empty\">No log entries captured yet.</div>\n </section>\n `;\n\n this.launcherEl = this.query('.dc-launcher');\n this.badgeEl = this.query('.dc-badge');\n this.panelEl = this.query('.dc-panel');\n this.countEl = this.query('.dc-count');\n this.listEl = this.query('.dc-list');\n this.emptyEl = this.query('.dc-empty');\n this.autoScrollBtn = this.query('[data-act=\"autoscroll\"]');\n this.downloadBtn = this.query('[data-act=\"download\"]');\n this.clearBtn = this.query('[data-act=\"clear\"]');\n\n this.launcherEl.addEventListener('click', () => this.setOpen(true));\n\n this.query('.dc-actions').addEventListener('click', (event: Event) => {\n const btn = (event.target as HTMLElement).closest('.dc-action') as HTMLElement | null;\n switch (btn?.dataset['act']) {\n case 'autoscroll':\n this.toggleAutoScroll();\n break;\n case 'bottom':\n this.scrollToBottom();\n break;\n case 'download':\n this.download();\n break;\n case 'clear':\n logger.clear();\n break;\n case 'close':\n this.setOpen(false);\n break;\n }\n });\n\n const filtersEl = this.query('.dc-filters');\n for (const def of FILTERS) {\n const chip = document.createElement('button');\n chip.type = 'button';\n chip.className = 'dc-chip' + (def === this.filter ? ' dc-chip--active' : '');\n chip.textContent = def.label;\n chip.addEventListener('click', () => this.setFilter(def, chip));\n filtersEl.appendChild(chip);\n }\n }\n\n private query<T extends Element>(selector: string): T {\n return this.root.querySelector(selector) as T;\n }\n\n private replayExisting(): void {\n for (const entry of logger.entries) {\n this.appendRow(entry);\n }\n this.refresh();\n this.scrollToBottomIfFollowing();\n }\n\n private onLog(event: LogEvent): void {\n if (event.type === 'clear') {\n this.listEl.replaceChildren();\n } else {\n this.appendRow(event.entry);\n }\n this.refresh();\n if (event.type === 'add') {\n this.scrollToBottomIfFollowing();\n }\n }\n\n /** Build one row (XSS-safe via textContent) and trim the DOM to the buffer cap. */\n private appendRow(entry: LogEntry): void {\n const row = document.createElement('div');\n row.className = `dc-row dc-row--${entry.level}`;\n row.dataset['level'] = entry.level;\n row.hidden = !this.filter.match(entry.level);\n\n const time = document.createElement('span');\n time.className = 'dc-time';\n time.textContent = fmtTime(entry.time);\n\n const tag = document.createElement('span');\n tag.className = 'dc-tag';\n tag.textContent = entry.level;\n\n const text = document.createElement('pre');\n text.className = 'dc-text';\n text.textContent = entry.text;\n\n row.append(time, tag, text);\n this.listEl.appendChild(row);\n\n while (this.listEl.childElementCount > logger.limit) {\n this.listEl.firstElementChild?.remove();\n }\n }\n\n /** Recompute counts, badge, count pill, disabled states and the empty message. */\n private refresh(): void {\n let errors = 0;\n let warnings = 0;\n for (const entry of logger.entries) {\n if (entry.level === 'error') {\n errors++;\n } else if (entry.level === 'warn') {\n warnings++;\n }\n }\n const total = logger.entries.length;\n\n this.countEl.textContent = String(total);\n this.countEl.hidden = total === 0;\n\n const badge = errors + warnings;\n this.badgeEl.hidden = this.isOpen || badge === 0;\n this.badgeEl.textContent = String(badge);\n this.badgeEl.className = 'dc-badge ' + (errors > 0 ? 'dc-badge--error' : 'dc-badge--warn');\n\n this.downloadBtn.disabled = total === 0;\n this.clearBtn.disabled = total === 0;\n\n this.emptyEl.hidden = !!this.listEl.querySelector('.dc-row:not([hidden])');\n }\n\n private setOpen(open: boolean): void {\n this.isOpen = open;\n this.panelEl.classList.toggle('dc-panel--open', open);\n this.launcherEl.hidden = open;\n this.refresh();\n if (open) {\n this.scrollToBottomIfFollowing();\n }\n }\n\n private toggleAutoScroll(): void {\n this.autoScroll = !this.autoScroll;\n this.autoScrollBtn.classList.toggle('dc-action--active', this.autoScroll);\n this.autoScrollBtn.dataset['tip'] = this.autoScroll ? 'Auto-scroll: on (following newest)' : 'Auto-scroll: off';\n this.scrollToBottomIfFollowing();\n }\n\n private setFilter(def: FilterDef, chip: HTMLElement): void {\n this.filter = def;\n this.root.querySelectorAll('.dc-chip').forEach(c => c.classList.toggle('dc-chip--active', c === chip));\n this.listEl.querySelectorAll<HTMLElement>('.dc-row').forEach(row => {\n row.hidden = !def.match(row.dataset['level'] as LogLevel);\n });\n this.refresh();\n this.scrollToBottomIfFollowing();\n }\n\n private scrollToBottom(): void {\n this.listEl.scrollTop = this.listEl.scrollHeight;\n }\n\n private scrollToBottomIfFollowing(): void {\n if (!this.isOpen || !this.autoScroll) {\n return;\n }\n requestAnimationFrame(() => {\n this.listEl.scrollTop = this.listEl.scrollHeight;\n });\n }\n\n private download(): void {\n const entries = logger.entries;\n if (entries.length === 0) {\n return;\n }\n const content = entries.map(e => `[${fmtDateTime(e.time)}] ${e.level.toUpperCase()} ${e.text}`).join('\\n');\n const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `application-logs-${fmtFileStamp(new Date())}.log`;\n document.body.appendChild(link);\n link.click();\n link.remove();\n URL.revokeObjectURL(url);\n }\n}\n","import { DebugConsoleElement } from './console-element';\nimport { logger } from './logger';\nimport type { DebugConsoleHandle, DebugConsoleOptions } from './types';\n\n/** The custom element tag name. */\nexport const ELEMENT_NAME = 'debug-console';\n\n/**\n * Register the `<debug-console>` custom element (idempotent, browser-only).\n * Call this if you want to place `<debug-console>` in your own markup/JSX/template\n * instead of using {@link initDebugConsole}. You still need to call\n * {@link startCapture} (or `initDebugConsole`) once to begin capturing.\n */\nexport function defineDebugConsole(name: string = ELEMENT_NAME): void {\n if (typeof customElements === 'undefined') {\n return;\n }\n if (!customElements.get(name)) {\n customElements.define(name, DebugConsoleElement);\n }\n}\n\n/**\n * Begin patching the console + capturing errors, without mounting any UI.\n * Useful when you render `<debug-console>` yourself. Idempotent.\n */\nexport function startCapture(options: Pick<DebugConsoleOptions, 'max' | 'captureGlobalErrors'> = {}): void {\n logger.init({ max: options.max, captureGlobalErrors: options.captureGlobalErrors });\n}\n\n/**\n * One-call setup: start capturing and mount the overlay at the document root.\n *\n * Returns a handle to control/destroy it, or `null` when disabled or when there\n * is no DOM (SSR). When `enabled` is `false` the console is NOT patched and no\n * element is mounted.\n */\nexport function initDebugConsole(options: DebugConsoleOptions = {}): DebugConsoleHandle | null {\n if (options.enabled === false || typeof document === 'undefined') {\n return null;\n }\n\n startCapture(options);\n defineDebugConsole();\n\n // Idempotent: reuse an already-mounted overlay (e.g. a second call, or dev HMR)\n // instead of stacking a second launcher/panel on top.\n const existing = document.querySelector(ELEMENT_NAME) as DebugConsoleElement | null;\n const element: DebugConsoleElement = existing ?? (document.createElement(ELEMENT_NAME) as DebugConsoleElement);\n\n if (!existing) {\n if (options.position) {\n element.setAttribute('data-position', options.position);\n }\n if (options.accent) {\n element.style.setProperty('--dc-accent', options.accent);\n }\n\n const mount = (): void => {\n document.body.appendChild(element);\n if (options.open) {\n element.show();\n }\n };\n if (document.body) {\n mount();\n } else {\n window.addEventListener('DOMContentLoaded', mount, { once: true });\n }\n }\n\n return {\n element,\n show: () => element.show(),\n hide: () => element.hide(),\n toggle: () => element.toggle(),\n clear: () => logger.clear(),\n destroy: () => element.remove()\n };\n}\n\nexport { logger } from './logger';\nexport { DebugConsoleElement } from './console-element';\nexport type { LogEvent } from './logger';\nexport type { DebugConsoleHandle, DebugConsoleOptions, LauncherPosition, LogEntry, LogLevel } from './types';\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neuradigi/debug-console",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework-agnostic in-app console overlay that mirrors console.* and uncaught errors into a floating debug panel. Works in Angular, React, Vue, Svelte, or plain HTML — zero runtime dependencies.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"console",
|
|
33
|
+
"logging",
|
|
34
|
+
"logger",
|
|
35
|
+
"debug",
|
|
36
|
+
"devtools",
|
|
37
|
+
"overlay",
|
|
38
|
+
"web-component",
|
|
39
|
+
"custom-element",
|
|
40
|
+
"angular",
|
|
41
|
+
"react",
|
|
42
|
+
"vue",
|
|
43
|
+
"svelte"
|
|
44
|
+
],
|
|
45
|
+
"author": "Neuradigi Technologies <hello@neuradigi.com> (https://neuradigi.com)",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/neuradigi/debug-console.git"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/neuradigi/debug-console#readme",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/neuradigi/debug-console/issues"
|
|
54
|
+
},
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"tsup": "^8.3.0",
|
|
60
|
+
"typescript": "^5.6.0"
|
|
61
|
+
}
|
|
62
|
+
}
|