@junctionjs/debug 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/README.md +49 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.js +1200 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts","../src/styles.ts","../src/panel.ts","../src/index.ts"],"sourcesContent":["/**\n * @junctionjs/debug - Event Store\n *\n * Ring buffer that captures all collector events for the debug panel.\n * Subscribes to the collector's event system and maintains an in-memory\n * log with aggregate counters.\n */\n\nimport type { Collector, CollectorEvent, CollectorEventHandler, JctEvent } from \"@junctionjs/core\";\n\n// ─── Types ──────────────────────────────────────────────────────\n\nexport interface DebugEntry {\n /** Auto-incrementing ID */\n id: number;\n /** ISO timestamp from the collector event */\n timestamp: string;\n /** Collector event type */\n type: CollectorEvent;\n /** Raw payload from the event */\n payload: unknown;\n}\n\nexport interface DebugCounters {\n total: number;\n valid: number;\n invalid: number;\n sent: Record<string, number>;\n errors: Record<string, number>;\n consentChanges: number;\n queueFlushes: number;\n}\n\nexport interface DebugStore {\n /** Get all stored entries (newest last) */\n getEntries: () => DebugEntry[];\n /** Get entries filtered by type */\n getByType: (type: CollectorEvent) => DebugEntry[];\n /** Get aggregate counters */\n getCounters: () => DebugCounters;\n /** Clear all entries and reset counters */\n clear: () => void;\n /** Subscribe to updates (called on every new entry) */\n onUpdate: (callback: () => void) => () => void;\n /** Unsubscribe from all collector events and clean up */\n destroy: () => void;\n}\n\n// ─── Implementation ─────────────────────────────────────────────\n\nexport function createDebugStore(collector: Collector, maxEvents: number = 500): DebugStore {\n let entries: DebugEntry[] = [];\n let nextId = 1;\n const listeners = new Set<() => void>();\n const unsubscribers: Array<() => void> = [];\n\n const counters: DebugCounters = {\n total: 0,\n valid: 0,\n invalid: 0,\n sent: {},\n errors: {},\n consentChanges: 0,\n queueFlushes: 0,\n };\n\n function addEntry(type: CollectorEvent, payload: unknown, timestamp: string): void {\n const entry: DebugEntry = { id: nextId++, timestamp, type, payload };\n\n entries.push(entry);\n\n // Ring buffer: drop oldest when full\n if (entries.length > maxEvents) {\n entries = entries.slice(entries.length - maxEvents);\n }\n\n // Update counters\n switch (type) {\n case \"event\":\n counters.total++;\n break;\n case \"event:valid\":\n counters.valid++;\n break;\n case \"event:invalid\":\n counters.invalid++;\n break;\n case \"destination:send\": {\n const dest = (payload as { destination?: string })?.destination ?? \"unknown\";\n counters.sent[dest] = (counters.sent[dest] ?? 0) + 1;\n break;\n }\n case \"destination:error\": {\n const errDest = (payload as { destination?: string })?.destination ?? \"unknown\";\n counters.errors[errDest] = (counters.errors[errDest] ?? 0) + 1;\n break;\n }\n case \"consent\":\n counters.consentChanges++;\n break;\n case \"queue:flush\":\n counters.queueFlushes++;\n break;\n }\n\n // Notify listeners\n for (const cb of listeners) {\n try { cb(); } catch { /* swallow */ }\n }\n }\n\n // Subscribe to all collector event types\n const eventTypes: CollectorEvent[] = [\n \"event\",\n \"event:valid\",\n \"event:invalid\",\n \"consent\",\n \"destination:send\",\n \"destination:error\",\n \"destination:init\",\n \"queue:flush\",\n \"error\",\n ];\n\n for (const type of eventTypes) {\n const handler: CollectorEventHandler = (data) => {\n addEntry(type, data.payload, data.timestamp);\n };\n unsubscribers.push(collector.on(type, handler));\n }\n\n return {\n getEntries() {\n return [...entries];\n },\n\n getByType(type: CollectorEvent) {\n return entries.filter((e) => e.type === type);\n },\n\n getCounters() {\n return { ...counters, sent: { ...counters.sent }, errors: { ...counters.errors } };\n },\n\n clear() {\n entries = [];\n counters.total = 0;\n counters.valid = 0;\n counters.invalid = 0;\n counters.sent = {};\n counters.errors = {};\n counters.consentChanges = 0;\n counters.queueFlushes = 0;\n for (const cb of listeners) {\n try { cb(); } catch { /* swallow */ }\n }\n },\n\n onUpdate(callback: () => void) {\n listeners.add(callback);\n return () => { listeners.delete(callback); };\n },\n\n destroy() {\n for (const unsub of unsubscribers) {\n unsub();\n }\n unsubscribers.length = 0;\n listeners.clear();\n },\n };\n}\n","/**\n * @junctionjs/debug - Styles\n *\n * Complete CSS for the debug panel, injected into shadow root.\n * Dark theme, monospace for data, system font for chrome.\n * No external dependencies.\n */\n\nexport const PANEL_STYLES = /* css */ `\n :host {\n --jd-bg: #1a1a2e;\n --jd-bg-surface: #16213e;\n --jd-bg-hover: #1f2f50;\n --jd-bg-active: #0f3460;\n --jd-border: #2a2a4a;\n --jd-text: #e0e0e0;\n --jd-text-dim: #888;\n --jd-text-bright: #fff;\n --jd-accent: #e94560;\n --jd-green: #4ade80;\n --jd-yellow: #fbbf24;\n --jd-red: #f87171;\n --jd-blue: #60a5fa;\n --jd-purple: #a78bfa;\n --jd-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --jd-mono: \"SF Mono\", \"Fira Code\", \"Cascadia Code\", Consolas, monospace;\n --jd-radius: 6px;\n\n all: initial;\n font-family: var(--jd-font);\n font-size: 12px;\n color: var(--jd-text);\n line-height: 1.4;\n }\n\n /* ─── FAB (collapsed state) ─── */\n\n .jd-fab {\n position: fixed;\n z-index: 2147483646;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--jd-accent);\n color: #fff;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 16px;\n font-family: var(--jd-mono);\n box-shadow: 0 2px 12px rgba(0,0,0,0.4);\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n user-select: none;\n }\n\n .jd-fab:hover {\n transform: scale(1.1);\n box-shadow: 0 4px 20px rgba(233,69,96,0.4);\n }\n\n .jd-fab .jd-fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 8px;\n background: var(--jd-green);\n color: #000;\n font-size: 9px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n /* ─── Position variants ─── */\n\n .jd-pos-bottom-right { bottom: 16px; right: 16px; }\n .jd-pos-bottom-left { bottom: 16px; left: 16px; }\n .jd-pos-top-right { top: 16px; right: 16px; }\n .jd-pos-top-left { top: 16px; left: 16px; }\n\n .jd-panel.jd-pos-bottom-right { bottom: 60px; right: 16px; }\n .jd-panel.jd-pos-bottom-left { bottom: 60px; left: 16px; }\n .jd-panel.jd-pos-top-right { top: 60px; right: 16px; }\n .jd-panel.jd-pos-top-left { top: 60px; left: 16px; }\n\n /* ─── Panel (expanded state) ─── */\n\n .jd-panel {\n position: fixed;\n z-index: 2147483646;\n width: 420px;\n height: 360px;\n background: var(--jd-bg);\n border: 1px solid var(--jd-border);\n border-radius: var(--jd-radius);\n box-shadow: 0 8px 32px rgba(0,0,0,0.5);\n display: none;\n flex-direction: column;\n overflow: hidden;\n }\n\n .jd-panel.jd-open {\n display: flex;\n }\n\n /* ─── Header ─── */\n\n .jd-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 10px;\n background: var(--jd-bg-surface);\n border-bottom: 1px solid var(--jd-border);\n cursor: default;\n user-select: none;\n }\n\n .jd-header-title {\n font-weight: 600;\n font-size: 11px;\n color: var(--jd-text-bright);\n letter-spacing: 0.5px;\n text-transform: uppercase;\n }\n\n .jd-header-title span {\n color: var(--jd-accent);\n }\n\n .jd-header-actions {\n display: flex;\n gap: 6px;\n }\n\n .jd-header-btn {\n background: none;\n border: none;\n color: var(--jd-text-dim);\n cursor: pointer;\n padding: 2px 4px;\n font-size: 12px;\n border-radius: 3px;\n }\n\n .jd-header-btn:hover {\n color: var(--jd-text-bright);\n background: var(--jd-bg-hover);\n }\n\n /* ─── Tabs ─── */\n\n .jd-tabs {\n display: flex;\n gap: 0;\n background: var(--jd-bg-surface);\n border-bottom: 1px solid var(--jd-border);\n }\n\n .jd-tab {\n flex: 1;\n padding: 6px 8px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n color: var(--jd-text-dim);\n cursor: pointer;\n font-size: 11px;\n font-family: var(--jd-font);\n transition: color 0.1s, border-color 0.1s;\n text-align: center;\n }\n\n .jd-tab:hover {\n color: var(--jd-text);\n }\n\n .jd-tab.jd-active {\n color: var(--jd-accent);\n border-bottom-color: var(--jd-accent);\n }\n\n .jd-tab-badge {\n display: inline-block;\n min-width: 14px;\n height: 14px;\n padding: 0 3px;\n margin-left: 4px;\n border-radius: 7px;\n background: var(--jd-bg-hover);\n font-size: 9px;\n line-height: 14px;\n text-align: center;\n vertical-align: middle;\n }\n\n /* ─── Tab content area ─── */\n\n .jd-content {\n flex: 1;\n overflow: hidden;\n position: relative;\n }\n\n .jd-tab-panel {\n display: none;\n position: absolute;\n inset: 0;\n overflow-y: auto;\n padding: 0;\n }\n\n .jd-tab-panel.jd-active {\n display: block;\n }\n\n .jd-tab-panel::-webkit-scrollbar { width: 6px; }\n .jd-tab-panel::-webkit-scrollbar-track { background: transparent; }\n .jd-tab-panel::-webkit-scrollbar-thumb { background: var(--jd-border); border-radius: 3px; }\n\n /* ─── Filter bar ─── */\n\n .jd-filter {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n border-bottom: 1px solid var(--jd-border);\n background: var(--jd-bg-surface);\n }\n\n .jd-filter input {\n flex: 1;\n background: var(--jd-bg);\n border: 1px solid var(--jd-border);\n border-radius: 3px;\n color: var(--jd-text);\n padding: 3px 6px;\n font-size: 11px;\n font-family: var(--jd-mono);\n outline: none;\n }\n\n .jd-filter input:focus {\n border-color: var(--jd-accent);\n }\n\n .jd-filter input::placeholder {\n color: var(--jd-text-dim);\n }\n\n /* ─── Event list ─── */\n\n .jd-event-list {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .jd-event-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px;\n border-bottom: 1px solid var(--jd-border);\n cursor: pointer;\n transition: background 0.1s;\n font-size: 11px;\n }\n\n .jd-event-row:hover {\n background: var(--jd-bg-hover);\n }\n\n .jd-event-time {\n color: var(--jd-text-dim);\n font-family: var(--jd-mono);\n font-size: 10px;\n flex-shrink: 0;\n width: 55px;\n }\n\n .jd-event-badge {\n display: inline-block;\n padding: 1px 6px;\n border-radius: 3px;\n font-family: var(--jd-mono);\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n }\n\n .jd-badge-event { background: #1e3a5f; color: var(--jd-blue); }\n .jd-badge-valid { background: #1a3d2e; color: var(--jd-green); }\n .jd-badge-invalid { background: #3d1a1a; color: var(--jd-red); }\n .jd-badge-send { background: #1e3a5f; color: var(--jd-blue); }\n .jd-badge-error { background: #3d1a1a; color: var(--jd-red); }\n .jd-badge-consent { background: #2e1a3d; color: var(--jd-purple); }\n .jd-badge-init { background: #1a3d2e; color: var(--jd-green); }\n .jd-badge-queue { background: #3d3a1a; color: var(--jd-yellow); }\n\n .jd-event-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--jd-mono);\n }\n\n .jd-event-dest {\n color: var(--jd-text-dim);\n font-size: 10px;\n flex-shrink: 0;\n }\n\n /* ─── Event detail (expanded) ─── */\n\n .jd-event-detail {\n display: none;\n padding: 6px 8px 8px 8px;\n background: var(--jd-bg-surface);\n border-bottom: 1px solid var(--jd-border);\n font-family: var(--jd-mono);\n font-size: 10px;\n white-space: pre-wrap;\n word-break: break-all;\n color: var(--jd-text);\n max-height: 200px;\n overflow-y: auto;\n }\n\n .jd-event-detail.jd-expanded {\n display: block;\n }\n\n .jd-detail-key {\n color: var(--jd-purple);\n }\n\n .jd-detail-string {\n color: var(--jd-green);\n }\n\n .jd-detail-number {\n color: var(--jd-yellow);\n }\n\n .jd-detail-bool {\n color: var(--jd-blue);\n }\n\n .jd-detail-null {\n color: var(--jd-text-dim);\n }\n\n /* ─── Consent tab ─── */\n\n .jd-consent-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n padding: 8px;\n }\n\n .jd-consent-card {\n background: var(--jd-bg-surface);\n border: 1px solid var(--jd-border);\n border-radius: var(--jd-radius);\n padding: 8px 10px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .jd-consent-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: capitalize;\n }\n\n .jd-consent-status {\n font-size: 14px;\n cursor: pointer;\n user-select: none;\n }\n\n .jd-consent-granted { color: var(--jd-green); }\n .jd-consent-denied { color: var(--jd-red); }\n .jd-consent-pending { color: var(--jd-yellow); }\n\n .jd-consent-info {\n padding: 8px;\n font-size: 11px;\n color: var(--jd-text-dim);\n text-align: center;\n border-top: 1px solid var(--jd-border);\n }\n\n /* ─── Destinations tab ─── */\n\n .jd-dest-list {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .jd-dest-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-bottom: 1px solid var(--jd-border);\n }\n\n .jd-dest-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .jd-dest-ok { background: var(--jd-green); }\n .jd-dest-err { background: var(--jd-red); }\n .jd-dest-pending { background: var(--jd-yellow); }\n\n .jd-dest-info {\n flex: 1;\n }\n\n .jd-dest-name {\n font-weight: 600;\n font-size: 11px;\n color: var(--jd-text-bright);\n }\n\n .jd-dest-meta {\n font-size: 10px;\n color: var(--jd-text-dim);\n font-family: var(--jd-mono);\n }\n\n .jd-dest-count {\n font-family: var(--jd-mono);\n font-size: 11px;\n color: var(--jd-text-dim);\n text-align: right;\n flex-shrink: 0;\n }\n\n .jd-dest-count strong {\n color: var(--jd-text-bright);\n }\n\n /* ─── Context tab ─── */\n\n .jd-context-section {\n padding: 6px 8px;\n border-bottom: 1px solid var(--jd-border);\n }\n\n .jd-context-heading {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--jd-text-dim);\n margin-bottom: 4px;\n }\n\n .jd-context-row {\n display: flex;\n justify-content: space-between;\n padding: 2px 0;\n font-size: 11px;\n }\n\n .jd-context-key {\n color: var(--jd-text-dim);\n }\n\n .jd-context-val {\n color: var(--jd-text-bright);\n font-family: var(--jd-mono);\n text-align: right;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* ─── Empty state ─── */\n\n .jd-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--jd-text-dim);\n font-size: 12px;\n padding: 20px;\n text-align: center;\n }\n\n /* ─── Status bar ─── */\n\n .jd-statusbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 8px;\n background: var(--jd-bg-surface);\n border-top: 1px solid var(--jd-border);\n font-size: 10px;\n color: var(--jd-text-dim);\n user-select: none;\n }\n\n .jd-statusbar-counters {\n display: flex;\n gap: 10px;\n }\n\n .jd-statusbar-counter {\n display: flex;\n align-items: center;\n gap: 3px;\n }\n\n .jd-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n display: inline-block;\n }\n\n .jd-dot-green { background: var(--jd-green); }\n .jd-dot-red { background: var(--jd-red); }\n .jd-dot-yellow { background: var(--jd-yellow); }\n .jd-dot-blue { background: var(--jd-blue); }\n`;\n","/**\n * @junctionjs/debug - Panel\n *\n * DOM construction for the debug overlay. All rendering uses vanilla DOM\n * inside a shadow root for complete style isolation.\n *\n * 4 tabs: Events | Consent | Destinations | Context\n */\n\nimport type { Collector, CollectorEvent, ConsentState, JctEvent } from \"@junctionjs/core\";\nimport { PANEL_STYLES } from \"./styles.js\";\nimport type { DebugStore, DebugEntry } from \"./store.js\";\n\n// ─── Types ──────────────────────────────────────────────────────\n\nexport type PanelPosition = \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n\nexport interface PanelOptions {\n position: PanelPosition;\n startOpen: boolean;\n}\n\nexport interface Panel {\n host: HTMLElement;\n open: () => void;\n close: () => void;\n toggle: () => void;\n destroy: () => void;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string>,\n ...children: (Node | string)[]\n): HTMLElementTagNameMap[K] {\n const elem = document.createElement(tag);\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"class\") elem.className = v;\n else elem.setAttribute(k, v);\n }\n }\n for (const child of children) {\n if (typeof child === \"string\") elem.appendChild(document.createTextNode(child));\n else elem.appendChild(child);\n }\n return elem;\n}\n\nfunction formatTime(iso: string): string {\n try {\n const d = new Date(iso);\n return d.toLocaleTimeString(\"en-US\", { hour12: false, hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\" });\n } catch {\n return \"??:??:??\";\n }\n}\n\nfunction badgeClass(type: CollectorEvent): string {\n const map: Record<string, string> = {\n \"event\": \"jd-badge-event\",\n \"event:valid\": \"jd-badge-valid\",\n \"event:invalid\": \"jd-badge-invalid\",\n \"destination:send\": \"jd-badge-send\",\n \"destination:error\": \"jd-badge-error\",\n \"destination:init\": \"jd-badge-init\",\n \"consent\": \"jd-badge-consent\",\n \"queue:flush\": \"jd-badge-queue\",\n \"error\": \"jd-badge-error\",\n };\n return map[type] ?? \"jd-badge-event\";\n}\n\nfunction eventLabel(entry: DebugEntry): string {\n const p = entry.payload as Record<string, unknown> | JctEvent | undefined;\n if (!p) return entry.type;\n\n // JctEvent payloads (event, event:valid)\n if (\"entity\" in p && \"action\" in p) {\n return `${p.entity}:${p.action}`;\n }\n\n // Object payloads with nested event\n if (\"event\" in p) {\n const evt = p.event as JctEvent;\n if (evt?.entity && evt?.action) return `${evt.entity}:${evt.action}`;\n }\n\n // destination:init\n if (\"destination\" in p) {\n return `${p.destination}`;\n }\n\n // consent\n if (\"state\" in p) return \"state updated\";\n\n // queue:flush\n if (\"count\" in p) return `${p.count} events`;\n\n return entry.type;\n}\n\nfunction destLabel(entry: DebugEntry): string {\n const p = entry.payload as Record<string, unknown> | undefined;\n if (!p) return \"\";\n if (\"destination\" in p && typeof p.destination === \"string\") return p.destination;\n return \"\";\n}\n\nfunction syntaxHighlight(obj: unknown, indent = 0): string {\n if (obj === null || obj === undefined) {\n return `<span class=\"jd-detail-null\">${String(obj)}</span>`;\n }\n if (typeof obj === \"string\") {\n const escaped = obj.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n return `<span class=\"jd-detail-string\">\"${escaped}\"</span>`;\n }\n if (typeof obj === \"number\") {\n return `<span class=\"jd-detail-number\">${obj}</span>`;\n }\n if (typeof obj === \"boolean\") {\n return `<span class=\"jd-detail-bool\">${obj}</span>`;\n }\n if (Array.isArray(obj)) {\n if (obj.length === 0) return \"[]\";\n const pad = \" \".repeat(indent + 1);\n const closePad = \" \".repeat(indent);\n const items = obj.map((v) => `${pad}${syntaxHighlight(v, indent + 1)}`).join(\",\\n\");\n return `[\\n${items}\\n${closePad}]`;\n }\n if (typeof obj === \"object\") {\n const entries = Object.entries(obj as Record<string, unknown>);\n if (entries.length === 0) return \"{}\";\n const pad = \" \".repeat(indent + 1);\n const closePad = \" \".repeat(indent);\n const items = entries\n .map(([k, v]) => `${pad}<span class=\"jd-detail-key\">${k}</span>: ${syntaxHighlight(v, indent + 1)}`)\n .join(\",\\n\");\n return `{\\n${items}\\n${closePad}}`;\n }\n return String(obj);\n}\n\n// ─── Panel Factory ──────────────────────────────────────────────\n\nexport function createPanel(\n collector: Collector,\n store: DebugStore,\n options: PanelOptions,\n): Panel {\n const posClass = `jd-pos-${options.position}`;\n\n // ── Shadow host ──\n const host = document.createElement(\"junction-debug\");\n const shadow = host.attachShadow({ mode: \"open\" });\n\n // Inject styles\n const style = document.createElement(\"style\");\n style.textContent = PANEL_STYLES;\n shadow.appendChild(style);\n\n // ── State ──\n let isOpen = options.startOpen;\n let activeTab = \"events\";\n let filterText = \"\";\n let expandedEventId: number | null = null;\n\n // ── FAB ──\n const fab = el(\"button\", { class: `jd-fab ${posClass}` }, \"J\");\n const fabBadge = el(\"span\", { class: \"jd-fab-badge\" }, \"0\");\n fab.appendChild(fabBadge);\n fab.addEventListener(\"click\", toggle);\n shadow.appendChild(fab);\n\n // ── Panel container ──\n const panel = el(\"div\", { class: `jd-panel ${posClass} ${isOpen ? \"jd-open\" : \"\"}` });\n shadow.appendChild(panel);\n\n // ── Header ──\n const clearBtn = el(\"button\", { class: \"jd-header-btn\", title: \"Clear\" }, \"\\u2715 Clear\");\n clearBtn.addEventListener(\"click\", () => { store.clear(); render(); });\n\n const closeBtn = el(\"button\", { class: \"jd-header-btn\", title: \"Close\" }, \"\\u2715\");\n closeBtn.addEventListener(\"click\", close);\n\n const header = el(\"div\", { class: \"jd-header\" },\n el(\"div\", { class: \"jd-header-title\" },\n el(\"span\", {}, \"J\"),\n \" unction Debug\",\n ),\n el(\"div\", { class: \"jd-header-actions\" }, clearBtn, closeBtn),\n );\n panel.appendChild(header);\n\n // ── Tabs ──\n const tabDefs = [\n { id: \"events\", label: \"Events\" },\n { id: \"consent\", label: \"Consent\" },\n { id: \"destinations\", label: \"Dests\" },\n { id: \"context\", label: \"Context\" },\n ];\n\n const tabBar = el(\"div\", { class: \"jd-tabs\" });\n const tabBtns: Record<string, HTMLButtonElement> = {};\n for (const td of tabDefs) {\n const btn = el(\"button\", { class: `jd-tab ${td.id === activeTab ? \"jd-active\" : \"\"}` }, td.label);\n btn.addEventListener(\"click\", () => { switchTab(td.id); });\n tabBtns[td.id] = btn;\n tabBar.appendChild(btn);\n }\n panel.appendChild(tabBar);\n\n // ── Content area ──\n const content = el(\"div\", { class: \"jd-content\" });\n panel.appendChild(content);\n\n // Tab panels\n const tabPanels: Record<string, HTMLDivElement> = {};\n for (const td of tabDefs) {\n const tp = el(\"div\", { class: `jd-tab-panel ${td.id === activeTab ? \"jd-active\" : \"\"}` });\n tp.dataset.tab = td.id;\n tabPanels[td.id] = tp;\n content.appendChild(tp);\n }\n\n // ── Status bar ──\n const statusbar = el(\"div\", { class: \"jd-statusbar\" });\n panel.appendChild(statusbar);\n\n // ── Tab switching ──\n function switchTab(id: string) {\n activeTab = id;\n for (const [key, btn] of Object.entries(tabBtns)) {\n btn.classList.toggle(\"jd-active\", key === id);\n }\n for (const [key, tp] of Object.entries(tabPanels)) {\n tp.classList.toggle(\"jd-active\", key === id);\n }\n render();\n }\n\n // ── Open / Close ──\n function open() {\n isOpen = true;\n panel.classList.add(\"jd-open\");\n fab.style.display = \"none\";\n render();\n }\n\n function close() {\n isOpen = false;\n panel.classList.remove(\"jd-open\");\n fab.style.display = \"flex\";\n }\n\n function toggle() {\n if (isOpen) close(); else open();\n }\n\n // ── Render functions ──\n\n function render() {\n renderFab();\n renderStatusBar();\n if (!isOpen) return;\n\n switch (activeTab) {\n case \"events\": renderEvents(); break;\n case \"consent\": renderConsent(); break;\n case \"destinations\": renderDestinations(); break;\n case \"context\": renderContext(); break;\n }\n }\n\n function renderFab() {\n const c = store.getCounters();\n fabBadge.textContent = String(c.total);\n fabBadge.style.display = c.total > 0 ? \"flex\" : \"none\";\n }\n\n function renderStatusBar() {\n const c = store.getCounters();\n statusbar.innerHTML = \"\";\n const counters = el(\"div\", { class: \"jd-statusbar-counters\" });\n\n const addCounter = (dotClass: string, label: string, count: number) => {\n const item = el(\"span\", { class: \"jd-statusbar-counter\" });\n item.appendChild(el(\"span\", { class: `jd-dot ${dotClass}` }));\n item.appendChild(document.createTextNode(` ${count} ${label}`));\n counters.appendChild(item);\n };\n\n addCounter(\"jd-dot-green\", \"valid\", c.valid);\n addCounter(\"jd-dot-red\", \"invalid\", c.invalid);\n addCounter(\"jd-dot-blue\", \"sent\", Object.values(c.sent).reduce((a, b) => a + b, 0));\n\n statusbar.appendChild(counters);\n statusbar.appendChild(document.createTextNode(`${store.getEntries().length} entries`));\n }\n\n // ── Events tab ──\n\n function renderEvents() {\n const tp = tabPanels.events;\n tp.innerHTML = \"\";\n\n // Filter bar\n const filter = el(\"div\", { class: \"jd-filter\" });\n const input = el(\"input\", { type: \"text\", placeholder: \"Filter events...\" });\n input.value = filterText;\n input.addEventListener(\"input\", () => {\n filterText = input.value;\n renderEventList(list);\n });\n filter.appendChild(input);\n tp.appendChild(filter);\n\n // Event list container\n const list = el(\"ul\", { class: \"jd-event-list\" });\n tp.appendChild(list);\n renderEventList(list);\n }\n\n function renderEventList(list: HTMLUListElement) {\n list.innerHTML = \"\";\n\n let entries = store.getEntries();\n\n // Filter\n if (filterText) {\n const lower = filterText.toLowerCase();\n entries = entries.filter((e) => {\n const label = eventLabel(e).toLowerCase();\n const type = e.type.toLowerCase();\n return label.includes(lower) || type.includes(lower);\n });\n }\n\n if (entries.length === 0) {\n list.appendChild(el(\"div\", { class: \"jd-empty\" }, filterText ? \"No matching events\" : \"Waiting for events\\u2026\"));\n return;\n }\n\n // Render in reverse (newest first)\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n const row = el(\"li\", { class: \"jd-event-row\" });\n\n row.appendChild(el(\"span\", { class: \"jd-event-time\" }, formatTime(entry.timestamp)));\n row.appendChild(el(\"span\", { class: `jd-event-badge ${badgeClass(entry.type)}` }, entry.type.replace(\"destination:\", \"dest:\")));\n row.appendChild(el(\"span\", { class: \"jd-event-name\" }, eventLabel(entry)));\n\n const dl = destLabel(entry);\n if (dl) {\n row.appendChild(el(\"span\", { class: \"jd-event-dest\" }, dl));\n }\n\n // Detail area\n const detail = el(\"div\", { class: \"jd-event-detail\" });\n detail.innerHTML = syntaxHighlight(entry.payload);\n\n row.addEventListener(\"click\", () => {\n if (expandedEventId === entry.id) {\n expandedEventId = null;\n detail.classList.remove(\"jd-expanded\");\n } else {\n // Collapse previous\n const prev = list.querySelector(\".jd-event-detail.jd-expanded\");\n if (prev) prev.classList.remove(\"jd-expanded\");\n expandedEventId = entry.id;\n detail.classList.add(\"jd-expanded\");\n }\n });\n\n list.appendChild(row);\n list.appendChild(detail);\n }\n }\n\n // ── Consent tab ──\n\n function renderConsent() {\n const tp = tabPanels.consent;\n tp.innerHTML = \"\";\n\n const state = collector.getConsent();\n const categories = [\"necessary\", \"analytics\", \"marketing\", \"personalization\", \"social\"];\n\n const grid = el(\"div\", { class: \"jd-consent-grid\" });\n\n for (const cat of categories) {\n const value = (state as Record<string, boolean | undefined>)[cat];\n const card = el(\"div\", { class: \"jd-consent-card\" });\n\n card.appendChild(el(\"span\", { class: \"jd-consent-label\" }, cat));\n\n let statusText: string;\n let statusClass: string;\n if (value === true) {\n statusText = \"\\u2713\"; statusClass = \"jd-consent-granted\";\n } else if (value === false) {\n statusText = \"\\u2717\"; statusClass = \"jd-consent-denied\";\n } else {\n statusText = \"\\u25CB\"; statusClass = \"jd-consent-pending\";\n }\n\n const statusEl = el(\"span\", { class: `jd-consent-status ${statusClass}`, title: \"Click to toggle (testing)\" }, statusText);\n\n // Click to toggle for testing\n if (cat !== \"necessary\") {\n statusEl.addEventListener(\"click\", () => {\n const current = (collector.getConsent() as Record<string, boolean | undefined>)[cat];\n const next = current === true ? false : true;\n collector.consent({ [cat]: next });\n // Re-render after a tick\n requestAnimationFrame(() => renderConsent());\n });\n }\n\n card.appendChild(statusEl);\n grid.appendChild(card);\n }\n\n tp.appendChild(grid);\n\n // Counters\n const counters = store.getCounters();\n tp.appendChild(el(\"div\", { class: \"jd-consent-info\" },\n `${counters.consentChanges} consent changes \\u00B7 ${counters.queueFlushes} queue flushes \\u00B7 Click status to toggle (testing only)`,\n ));\n }\n\n // ── Destinations tab ──\n\n function renderDestinations() {\n const tp = tabPanels.destinations;\n tp.innerHTML = \"\";\n\n const counters = store.getCounters();\n const initEntries = store.getByType(\"destination:init\");\n const errorEntries = store.getByType(\"destination:error\");\n\n const initNames = new Set(\n initEntries.map((e) => (e.payload as Record<string, unknown>)?.destination as string).filter(Boolean),\n );\n const errorNames = new Set(\n errorEntries.map((e) => (e.payload as Record<string, unknown>)?.destination as string).filter(Boolean),\n );\n\n // Collect all known destination names\n const allNames = new Set([\n ...Object.keys(counters.sent),\n ...Object.keys(counters.errors),\n ...initNames,\n ...errorNames,\n ]);\n\n if (allNames.size === 0) {\n tp.appendChild(el(\"div\", { class: \"jd-empty\" }, \"No destinations registered yet\"));\n return;\n }\n\n const list = el(\"ul\", { class: \"jd-dest-list\" });\n\n for (const name of allNames) {\n const row = el(\"li\", { class: \"jd-dest-row\" });\n\n const hasError = errorNames.has(name) && !initNames.has(name);\n const isInit = initNames.has(name);\n const statusClass = hasError ? \"jd-dest-err\" : isInit ? \"jd-dest-ok\" : \"jd-dest-pending\";\n\n row.appendChild(el(\"span\", { class: `jd-dest-status ${statusClass}` }));\n\n const info = el(\"div\", { class: \"jd-dest-info\" });\n info.appendChild(el(\"div\", { class: \"jd-dest-name\" }, name));\n\n const statusLabel = hasError ? \"error\" : isInit ? \"ready\" : \"initializing\";\n info.appendChild(el(\"div\", { class: \"jd-dest-meta\" }, statusLabel));\n row.appendChild(info);\n\n const sentCount = counters.sent[name] ?? 0;\n const errCount = counters.errors[name] ?? 0;\n const countEl = el(\"div\", { class: \"jd-dest-count\" });\n countEl.innerHTML = `<strong>${sentCount}</strong> sent${errCount > 0 ? ` \\u00B7 <span style=\"color:var(--jd-red)\">${errCount} err</span>` : \"\"}`;\n row.appendChild(countEl);\n\n list.appendChild(row);\n }\n\n tp.appendChild(list);\n }\n\n // ── Context tab ──\n\n function renderContext() {\n const tp = tabPanels.context;\n tp.innerHTML = \"\";\n\n // Try to get latest event for context\n const entries = store.getEntries();\n const latestEvent = [...entries].reverse().find((e) =>\n e.type === \"event:valid\" || e.type === \"event\",\n );\n\n const event = latestEvent?.payload as JctEvent | undefined;\n\n // Page\n const addSection = (title: string, rows: [string, string | undefined][]) => {\n const section = el(\"div\", { class: \"jd-context-section\" });\n section.appendChild(el(\"div\", { class: \"jd-context-heading\" }, title));\n for (const [key, val] of rows) {\n if (val === undefined || val === \"\") continue;\n const row = el(\"div\", { class: \"jd-context-row\" });\n row.appendChild(el(\"span\", { class: \"jd-context-key\" }, key));\n row.appendChild(el(\"span\", { class: \"jd-context-val\" }, val));\n section.appendChild(row);\n }\n tp.appendChild(section);\n };\n\n if (event?.context?.page) {\n const p = event.context.page;\n addSection(\"Page\", [\n [\"URL\", p.url],\n [\"Path\", p.path],\n [\"Title\", p.title],\n [\"Referrer\", p.referrer],\n ]);\n } else {\n addSection(\"Page\", [\n [\"URL\", window.location.href],\n [\"Path\", window.location.pathname],\n [\"Title\", document.title],\n [\"Referrer\", document.referrer],\n ]);\n }\n\n if (event?.context?.device) {\n const d = event.context.device;\n addSection(\"Device\", [\n [\"Type\", d.type],\n [\"Language\", d.language],\n [\"Viewport\", d.viewport ? `${d.viewport.width}\\u00D7${d.viewport.height}` : undefined],\n [\"Screen\", d.screenResolution ? `${d.screenResolution.width}\\u00D7${d.screenResolution.height}` : undefined],\n ]);\n }\n\n if (event?.context?.campaign) {\n const c = event.context.campaign;\n addSection(\"Campaign\", [\n [\"Source\", c.source],\n [\"Medium\", c.medium],\n [\"Campaign\", c.campaign],\n [\"Term\", c.term],\n [\"Content\", c.content],\n ]);\n }\n\n if (event?.user) {\n addSection(\"User\", [\n [\"Anonymous ID\", event.user.anonymousId],\n [\"User ID\", event.user.userId],\n ...(event.user.traits\n ? Object.entries(event.user.traits).map(([k, v]) => [k, String(v)] as [string, string])\n : []),\n ]);\n }\n\n if (event?.context?.session) {\n const s = event.context.session;\n addSection(\"Session\", [\n [\"ID\", s.id],\n [\"New\", String(s.isNew)],\n [\"Count\", String(s.count)],\n ]);\n }\n\n // Consent state\n const consent = collector.getConsent();\n const consentRows: [string, string][] = Object.entries(consent).map(\n ([k, v]) => [k, v === true ? \"\\u2713 granted\" : v === false ? \"\\u2717 denied\" : \"\\u25CB pending\"],\n );\n if (consentRows.length > 0) {\n addSection(\"Consent\", consentRows);\n }\n\n if (!event) {\n tp.appendChild(el(\"div\", { class: \"jd-consent-info\" }, \"Context will populate after the first event fires\"));\n }\n }\n\n // ── Subscribe to store updates ──\n const unsubStore = store.onUpdate(() => {\n render();\n });\n\n // ── Initial render ──\n document.body.appendChild(host);\n if (isOpen) {\n fab.style.display = \"none\";\n }\n render();\n\n // ── Cleanup ──\n function destroy() {\n unsubStore();\n host.remove();\n }\n\n return { host, open, close, toggle, destroy };\n}\n","/**\n * @junctionjs/debug\n *\n * In-page debug overlay for Junction. Shows real-time event flow,\n * consent state, destination status, and context snapshot.\n *\n * Zero dependencies. Vanilla DOM in a shadow root. ~5KB gzipped.\n *\n * Usage:\n * import { createDebugPanel } from \"@junctionjs/debug\";\n *\n * const panel = createDebugPanel(window.jct, {\n * shortcut: \"ctrl+shift+j\",\n * startOpen: false,\n * position: \"bottom-right\",\n * });\n *\n * // Or for Astro integration:\n * // The panel auto-injects when debug: true in your junction config.\n */\n\nimport type { Collector } from \"@junctionjs/core\";\nimport { createDebugStore, type DebugStore } from \"./store.js\";\nimport { createPanel, type Panel, type PanelPosition } from \"./panel.js\";\n\n// ─── Public Types ───────────────────────────────────────────────\n\nexport interface DebugPanelOptions {\n /**\n * Keyboard shortcut to toggle the panel (default: \"ctrl+shift+j\").\n * Format: modifier keys joined with \"+\" followed by a key.\n * Examples: \"ctrl+shift+j\", \"meta+shift+d\", \"ctrl+shift+.\"\n */\n shortcut?: string;\n\n /** Maximum events to retain in the ring buffer (default: 500) */\n maxEvents?: number;\n\n /** Start with the panel open (default: false) */\n startOpen?: boolean;\n\n /** Panel position on screen (default: \"bottom-right\") */\n position?: PanelPosition;\n}\n\nexport interface DebugPanelInstance {\n /** Open the debug panel */\n open: () => void;\n /** Close the debug panel */\n close: () => void;\n /** Toggle open/close */\n toggle: () => void;\n /** Remove the panel from the DOM and unsubscribe from all events */\n destroy: () => void;\n /** Access the underlying event store (for programmatic use) */\n store: DebugStore;\n}\n\n// ─── Keyboard Shortcut Parser ───────────────────────────────────\n\ninterface ShortcutDef {\n ctrl: boolean;\n meta: boolean;\n shift: boolean;\n alt: boolean;\n key: string;\n}\n\nfunction parseShortcut(shortcut: string): ShortcutDef {\n const parts = shortcut.toLowerCase().split(\"+\").map((s) => s.trim());\n const key = parts.pop() ?? \"\";\n\n return {\n ctrl: parts.includes(\"ctrl\") || parts.includes(\"control\"),\n meta: parts.includes(\"meta\") || parts.includes(\"cmd\") || parts.includes(\"command\"),\n shift: parts.includes(\"shift\"),\n alt: parts.includes(\"alt\") || parts.includes(\"option\"),\n key,\n };\n}\n\nfunction matchesShortcut(event: KeyboardEvent, def: ShortcutDef): boolean {\n return (\n event.ctrlKey === def.ctrl &&\n event.metaKey === def.meta &&\n event.shiftKey === def.shift &&\n event.altKey === def.alt &&\n event.key.toLowerCase() === def.key\n );\n}\n\n// ─── Factory ────────────────────────────────────────────────────\n\nexport function createDebugPanel(\n collector: Collector,\n options?: DebugPanelOptions,\n): DebugPanelInstance {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n // SSR / non-browser: return a noop instance\n const noopStore: DebugStore = {\n getEntries: () => [],\n getByType: () => [],\n getCounters: () => ({\n total: 0, valid: 0, invalid: 0, sent: {}, errors: {},\n consentChanges: 0, queueFlushes: 0,\n }),\n clear: () => {},\n onUpdate: () => () => {},\n destroy: () => {},\n };\n return {\n open: () => {},\n close: () => {},\n toggle: () => {},\n destroy: () => {},\n store: noopStore,\n };\n }\n\n const maxEvents = options?.maxEvents ?? 500;\n const position = options?.position ?? \"bottom-right\";\n const startOpen = options?.startOpen ?? false;\n const shortcut = options?.shortcut ?? \"ctrl+shift+j\";\n\n // Create store\n const store = createDebugStore(collector, maxEvents);\n\n // Create panel\n const panel = createPanel(collector, store, { position, startOpen });\n\n // Keyboard shortcut\n const shortcutDef = parseShortcut(shortcut);\n function onKeyDown(e: KeyboardEvent) {\n if (matchesShortcut(e, shortcutDef)) {\n e.preventDefault();\n panel.toggle();\n }\n }\n document.addEventListener(\"keydown\", onKeyDown);\n\n return {\n open: panel.open,\n close: panel.close,\n toggle: panel.toggle,\n destroy() {\n document.removeEventListener(\"keydown\", onKeyDown);\n store.destroy();\n panel.destroy();\n },\n store,\n };\n}\n\n// Re-export types\nexport type { DebugStore, DebugEntry, DebugCounters } from \"./store.js\";\nexport type { PanelPosition } from \"./panel.js\";\n"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@junctionjs/debug",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "In-page debug panel for Junction — real-time event flow, consent state, destination status",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "README.md"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format esm --dts --sourcemap --target es2022 --no-config --external @junctionjs/core",
|
|
17
|
+
"dev": "tsup src/index.ts --format esm --dts --watch --no-config --external @junctionjs/core",
|
|
18
|
+
"clean": "rm -rf dist",
|
|
19
|
+
"typecheck": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@junctionjs/core": "*"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@junctionjs/core": "*",
|
|
26
|
+
"tsup": "^8.0.0",
|
|
27
|
+
"typescript": "^5.5.0"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18.0.0"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/tyssejc/junction.git",
|
|
36
|
+
"directory": "packages/debug"
|
|
37
|
+
},
|
|
38
|
+
"keywords": ["analytics", "debug", "devtools", "event-collection", "junction"]
|
|
39
|
+
}
|