@oddsquad/vite-plugin-lit 0.3.0 → 0.4.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +10 -6
  3. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-BvWe4sTJ.js → browser-agent-rpc-BXhoSh1z-CdtPhBL-.js} +2 -2
  4. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-BvWe4sTJ.js.map → browser-agent-rpc-BXhoSh1z-CdtPhBL-.js.map} +1 -1
  5. package/dist/client/assets/flow-DK8vmxvN.js +745 -0
  6. package/dist/client/assets/flow-DK8vmxvN.js.map +1 -0
  7. package/dist/client/assets/{index-CFrVgNfS.js → index-DVe6M4HV.js} +976 -102
  8. package/dist/client/assets/index-DVe6M4HV.js.map +1 -0
  9. package/dist/client/index.html +1 -1
  10. package/lib/devframe/protocol.d.ts.map +1 -1
  11. package/lib/devframe/protocol.js +1 -0
  12. package/lib/devframe/protocol.js.map +1 -1
  13. package/lib/devframe/vite.d.ts.map +1 -1
  14. package/lib/devframe/vite.js +1 -0
  15. package/lib/devframe/vite.js.map +1 -1
  16. package/lib/options.d.ts +131 -0
  17. package/lib/options.d.ts.map +1 -0
  18. package/lib/options.js +128 -0
  19. package/lib/options.js.map +1 -0
  20. package/lib/plugin.d.ts +6 -148
  21. package/lib/plugin.d.ts.map +1 -1
  22. package/lib/plugin.js +14 -477
  23. package/lib/plugin.js.map +1 -1
  24. package/lib/plugins/css-literals.d.ts +15 -0
  25. package/lib/plugins/css-literals.d.ts.map +1 -0
  26. package/lib/plugins/css-literals.js +154 -0
  27. package/lib/plugins/css-literals.js.map +1 -0
  28. package/lib/plugins/css-queries.d.ts +20 -0
  29. package/lib/plugins/css-queries.d.ts.map +1 -0
  30. package/lib/plugins/css-queries.js +139 -0
  31. package/lib/plugins/css-queries.js.map +1 -0
  32. package/lib/plugins/open-in-editor.d.ts +16 -0
  33. package/lib/plugins/open-in-editor.d.ts.map +1 -0
  34. package/lib/plugins/open-in-editor.js +91 -0
  35. package/lib/plugins/open-in-editor.js.map +1 -0
  36. package/lib/plugins/shared.d.ts +13 -0
  37. package/lib/plugins/shared.d.ts.map +1 -0
  38. package/lib/plugins/shared.js +23 -0
  39. package/lib/plugins/shared.js.map +1 -0
  40. package/lib/plugins/timeline-virtual.d.ts +19 -0
  41. package/lib/plugins/timeline-virtual.d.ts.map +1 -0
  42. package/lib/plugins/timeline-virtual.js +53 -0
  43. package/lib/plugins/timeline-virtual.js.map +1 -0
  44. package/lib/runtime/css.d.ts.map +1 -1
  45. package/lib/runtime/css.js +9 -2
  46. package/lib/runtime/css.js.map +1 -1
  47. package/lib/runtime/inspector/install.js +61 -11
  48. package/lib/runtime/inspector/install.js.map +1 -1
  49. package/lib/runtime/source-overlay/overlay-element.d.ts.map +1 -1
  50. package/lib/runtime/source-overlay/overlay-element.js +19 -6
  51. package/lib/runtime/source-overlay/overlay-element.js.map +1 -1
  52. package/lib/runtime/timeline/install.js +10 -5
  53. package/lib/runtime/timeline/install.js.map +1 -1
  54. package/lib/runtime/timeline/public-api.d.ts +2 -2
  55. package/lib/runtime/timeline/public-api.js +2 -2
  56. package/lib/runtime/timeline/public-api.js.map +1 -1
  57. package/lib/runtime/timeline/render.d.ts +15 -6
  58. package/lib/runtime/timeline/render.d.ts.map +1 -1
  59. package/lib/runtime/timeline/render.js +150 -11
  60. package/lib/runtime/timeline/render.js.map +1 -1
  61. package/package.json +4 -1
  62. package/types/timeline.d.ts +12 -1
  63. package/types/timeline.d.ts.map +1 -1
  64. package/types/timeline.js +2 -0
  65. package/types/timeline.js.map +1 -1
  66. package/dist/client/assets/index-CFrVgNfS.js.map +0 -1
  67. package/lib/timeline-plugin.d.ts +0 -72
  68. package/lib/timeline-plugin.d.ts.map +0 -1
  69. package/lib/timeline-plugin.js +0 -359
  70. package/lib/timeline-plugin.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"overlay-element.js","sourceRoot":"","sources":["../../../src/lib/runtime/source-overlay/overlay-element.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport type {ElementInfo, EditorConfig} from '../../types.js';\nimport {BUILTIN_EDITORS, resolveEditor} from './editors.js';\nimport {\n defaultResolver,\n findSourceAtPoint,\n findSourceHost,\n type ElementResolver,\n} from './source-host.js';\nimport {buildSpotlightClipPath} from './mask-path.js';\nimport {OVERLAY_HTML} from './template.js';\nimport {observeEdgeInsets} from '../edge-panel.js';\nimport {subscribeOverride} from '../overrides.js';\nimport {injectTokens} from '../../tokens.js';\nimport {idOf} from '../timeline/identity.js';\nimport {\n INSPECT_OVERLAY_TOGGLE_CHANNEL,\n INSPECT_DATA_CHANNEL,\n} from '../../../types/inspector.js';\n\nexport interface SourceOverlayInitOptions {\n key?: string;\n editor?: EditorConfig | string;\n workspaceRoot?: string;\n throttleMs?: number;\n exclude?: (el: Element) => boolean;\n onSelect?: (info: ElementInfo) => void;\n openInEditorPath?: string;\n}\n\nclass LitSourceOverlay extends HTMLElement {\n #active = false;\n #hot: {send: (event: string, data: unknown) => void} | undefined;\n #options: SourceOverlayInitOptions = {};\n #editor: EditorConfig = BUILTIN_EDITORS.vscode;\n #resolver: ElementResolver = defaultResolver;\n #dialog: HTMLDialogElement;\n #mask: HTMLElement;\n #highlight: HTMLElement;\n #tooltip: HTMLElement;\n #tag: HTMLElement;\n #path: HTMLElement;\n #info: ElementInfo | null = null;\n #targetEl: Element | null = null;\n #throttleTimer: ReturnType<typeof setTimeout> | undefined;\n #scrollTimer: ReturnType<typeof setTimeout> | undefined;\n #resizeObserver: ResizeObserver | undefined;\n #cursorStyle: HTMLStyleElement | null = null;\n // Whether the Vite HMR WebSocket is currently connected. Used to suppress the\n // editor-URL-scheme fallback once the dev server is gone — otherwise a failed\n // open-in-editor fetch would navigate the tab to `vscode://…`.\n #connected = true;\n #lastMouseX = 0;\n #lastMouseY = 0;\n #edgeDispose: (() => void) | undefined;\n #overrideSubscribed = false;\n\n constructor() {\n super();\n const root = this.attachShadow({mode: 'closed'});\n root.innerHTML = OVERLAY_HTML;\n this.#dialog = root.getElementById('overlay') as HTMLDialogElement;\n this.#mask = root.getElementById('mask')!;\n this.#highlight = root.getElementById('highlight')!;\n this.#tooltip = root.getElementById('tooltip')!;\n this.#tag = root.getElementById('tag')!;\n this.#path = root.getElementById('path')!;\n root.getElementById('open')!.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this.#info !== null) this.#select(this.#info, true);\n });\n root.getElementById('copy')!.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this.#info === null) return;\n const text = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;\n void navigator.clipboard?.writeText(text);\n });\n this.#dialog.addEventListener('cancel', (e) => e.preventDefault());\n }\n\n connectedCallback() {\n injectTokens();\n document.addEventListener('mousemove', this.#onTrackMouse, true);\n document.addEventListener('keydown', this.#onKeyDown, true);\n const hot = (\n import.meta as {\n hot?: {\n on: (event: string, cb: (data?: unknown) => void) => void;\n send: (event: string, data: unknown) => void;\n };\n }\n ).hot;\n this.#hot = hot;\n hot?.on('vite:beforeFullReload', () => this.deactivate());\n hot?.on('vite:ws:disconnect', () => (this.#connected = false));\n hot?.on('vite:ws:connect', () => (this.#connected = true));\n // Toggle from the Vite DevTools command/shortcut (handler runs server-side).\n hot?.on(INSPECT_OVERLAY_TOGGLE_CHANNEL, () => this.toggle());\n // Keep the (bottom-fixed) tooltip clear of the Vite DevTools edge panel.\n this.#edgeDispose = observeEdgeInsets((insets) => {\n this.style.setProperty('--edge-bottom', `${insets.bottom}px`);\n });\n // Apply the panel's editor override live (and on load). Merge so other\n // configured options (key, throttle, …) survive.\n if (!this.#overrideSubscribed) {\n this.#overrideSubscribed = true;\n subscribeOverride(hot, (o) => {\n if (o.sourceOverlayEditor !== undefined) {\n this.#options = {...this.#options, editor: o.sourceOverlayEditor};\n this.#editor = resolveEditor(o.sourceOverlayEditor);\n }\n });\n }\n }\n\n disconnectedCallback() {\n document.removeEventListener('mousemove', this.#onTrackMouse, true);\n document.removeEventListener('keydown', this.#onKeyDown, true);\n this.deactivate();\n this.#edgeDispose?.();\n this.#edgeDispose = undefined;\n }\n\n configure(options: SourceOverlayInitOptions) {\n this.#options = options;\n this.#editor = resolveEditor(options.editor);\n }\n\n activate() {\n if (this.#active) return;\n this.#active = true;\n this.#dialog.showModal();\n this.#mask.style.background = 'rgba(0,0,0,0.35)';\n // The overlay is pointer-events:none, so the cursor reflects the hovered\n // page element. Force a crosshair while inspecting. The closed shadow DOM\n // tooltip is unaffected, so its buttons keep their own pointer cursor.\n if (this.#cursorStyle === null) {\n this.#cursorStyle = document.createElement('style');\n this.#cursorStyle.textContent = '*{cursor:crosshair !important}';\n }\n document.head.append(this.#cursorStyle);\n document.addEventListener('mousemove', this.#onMouseMove, true);\n document.addEventListener('click', this.#onClick, true);\n window.addEventListener('scroll', this.#onScrollOrResize, {passive: true});\n window.addEventListener('resize', this.#onScrollOrResize, {passive: true});\n void this.#resolveAt(this.#lastMouseX, this.#lastMouseY);\n }\n\n deactivate() {\n if (!this.#active) return;\n this.#active = false;\n this.#dialog.close();\n this.#mask.style.background = 'rgba(0,0,0,0)';\n this.#cursorStyle?.remove();\n document.removeEventListener('mousemove', this.#onMouseMove, true);\n document.removeEventListener('click', this.#onClick, true);\n window.removeEventListener('scroll', this.#onScrollOrResize);\n window.removeEventListener('resize', this.#onScrollOrResize);\n if (this.#throttleTimer !== undefined) {\n clearTimeout(this.#throttleTimer);\n this.#throttleTimer = undefined;\n }\n if (this.#scrollTimer !== undefined) {\n clearTimeout(this.#scrollTimer);\n this.#scrollTimer = undefined;\n }\n this.#clearTarget();\n }\n\n toggle() {\n if (this.#active) this.deactivate();\n else this.activate();\n }\n\n #normalizePath(filePath: string): string {\n const root = this.#options.workspaceRoot;\n if (root !== undefined && filePath.startsWith(root)) {\n const rest = filePath.slice(root.length);\n return rest.startsWith('/') ? rest.slice(1) : rest;\n }\n return filePath;\n }\n\n async #openInEditor(filePath: string, lineNumber: number) {\n const path = this.#normalizePath(filePath);\n const endpoint = this.#options.openInEditorPath ?? '/__lit-open-in-editor';\n try {\n const params = new URLSearchParams({\n file: path,\n line: String(lineNumber),\n });\n const res = await fetch(`${endpoint}?${params.toString()}`);\n if (res.ok) return;\n } catch {\n // Fall back to editor URL schemes (e.g. StackBlitz previews).\n }\n // Skip the URL-scheme fallback when the dev server is gone: a fetch failure\n // there means \"server quit\", not \"no endpoint\", and navigating the tab to\n // `vscode://…` on shutdown is jarring and unwanted.\n if (!this.#connected) return;\n window.open(this.#editor.url(path, lineNumber), '_self');\n }\n\n #updateHighlightRect() {\n if (this.#targetEl === null) return;\n const rect = this.#targetEl.getBoundingClientRect();\n const raw = getComputedStyle(this)\n .getPropertyValue('--lit-devtools-radius')\n .trim();\n const r = parseFloat(raw) || 6;\n // The tinted box hugs the element's exact rect — that's the boundary being\n // picked; only the spotlight cutout gets the breathing room of `r`.\n this.#highlight.style.display = 'block';\n this.#highlight.style.left = `${rect.left}px`;\n this.#highlight.style.top = `${rect.top}px`;\n this.#highlight.style.width = `${rect.width}px`;\n this.#highlight.style.height = `${rect.height}px`;\n this.#mask.style.clipPath = buildSpotlightClipPath(\n rect.left - r,\n rect.top - r,\n rect.width + 2 * r,\n rect.height + 2 * r,\n r\n );\n }\n\n #showTooltip() {\n if (this.#info === null) return;\n this.#tag.textContent = `<${this.#info.tagName}>`;\n this.#path.textContent = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;\n this.#tooltip.style.display = 'flex';\n }\n\n #clearTarget() {\n this.#targetEl = null;\n this.#info = null;\n this.#highlight.style.display = 'none';\n this.#highlight.style.left = '0';\n this.#highlight.style.top = '0';\n this.#highlight.style.width = '0';\n this.#highlight.style.height = '0';\n this.#mask.style.clipPath = 'none';\n this.#tooltip.style.display = 'none';\n if (this.#resizeObserver !== undefined) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = undefined;\n }\n }\n\n #shouldSkip(el: Element): boolean {\n if (el === this.#dialog || this.#dialog.contains(el)) return true;\n if (el.tagName === 'IFRAME') return true;\n // Never target devtools' own injected elements (indicator, overlay).\n const tag = el.tagName.toLowerCase();\n if (tag === 'lit-source-overlay' || tag.startsWith('lit-devtools-')) {\n return true;\n }\n const exclude = this.#options.exclude;\n return exclude !== undefined && exclude(el);\n }\n\n async #resolveAt(x: number, y: number) {\n this.#lastMouseX = x;\n this.#lastMouseY = y;\n const el = findSourceAtPoint(x, y, this.#dialog);\n if (el === null || this.#shouldSkip(el)) {\n this.#clearTarget();\n return;\n }\n const host = findSourceHost(el);\n if (host === null) {\n this.#clearTarget();\n return;\n }\n if (host === this.#targetEl && this.#info !== null) {\n this.#updateHighlightRect();\n return;\n }\n this.#targetEl = host;\n if (this.#resizeObserver === undefined) {\n this.#resizeObserver = new ResizeObserver(() =>\n this.#updateHighlightRect()\n );\n } else {\n this.#resizeObserver.disconnect();\n }\n this.#resizeObserver.observe(host);\n const resolved = await this.#resolver.resolveElementInfo(el);\n if (resolved === null) {\n this.#clearTarget();\n return;\n }\n this.#info = resolved;\n this.#updateHighlightRect();\n this.#showTooltip();\n }\n\n #onTrackMouse = (event: MouseEvent) => {\n this.#lastMouseX = event.clientX;\n this.#lastMouseY = event.clientY;\n };\n\n #onKeyDown = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey) {\n const pressed = event.key.toLowerCase();\n const hotkey = (this.#options.key ?? 'e').toLowerCase();\n if (pressed === hotkey) {\n event.preventDefault();\n this.toggle();\n }\n }\n if (this.#active && event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n #onMouseMove = (event: MouseEvent) => {\n if (!this.#active) return;\n // Keep the current selection while hovering the tooltip so its buttons stay\n // clickable — the tooltip isn't a source element, so re-resolving here would\n // clear the target and hide the panel out from under the pointer.\n if (this.#pointInTooltip(event.clientX, event.clientY)) return;\n const throttleMs = this.#options.throttleMs ?? 50;\n if (this.#throttleTimer !== undefined) return;\n this.#throttleTimer = setTimeout(() => {\n this.#throttleTimer = undefined;\n // Resolve against the latest pointer position (kept current by\n // #onTrackMouse), not the coords captured when this timer was scheduled\n // ~throttleMs ago — otherwise the highlight lags the cursor during\n // continuous movement.\n const x = this.#lastMouseX;\n const y = this.#lastMouseY;\n if (this.#pointInTooltip(x, y)) return;\n void this.#resolveAt(x, y);\n }, throttleMs);\n };\n\n #select(info: ElementInfo, openInEditor = false) {\n const target = this.#targetEl;\n // Cancel the whole selection mode on any deliberate pick, before acting —\n // the editor may open via a URL scheme that doesn't navigate this tab away,\n // so we can't rely on the open outcome to dismiss the inspector.\n this.deactivate();\n this.#options.onSelect?.(info);\n if (openInEditor) {\n void this.#openInEditor(info.source.filePath, info.source.lineNumber);\n return;\n }\n // Report the picked element to the DevTools panel, which selects it in the\n // Components tree. Identity matches the inspector runtime via idOf().\n if (target !== null) {\n this.#hot?.send(INSPECT_DATA_CHANNEL, {type: 'pick', id: idOf(target)});\n this.#openDevtoolsPanel();\n }\n }\n\n /**\n * Bring the Lit DevTools dock entry to the front so a pick is visible even\n * when the panel was closed. The panel mirrors this from its own\n * `inspector-activate` handler, but only once its iframe is mounted — and the\n * @vitejs/devtools shell does not mount that iframe until the entry has been\n * opened at least once. This overlay always runs on the page, so calling\n * `switchEntry` here covers the cold-start case where no panel exists yet to\n * receive the `pick` message.\n */\n #openDevtoolsPanel() {\n try {\n const ctx = (\n window as unknown as Record<\n string,\n undefined | {docks?: {switchEntry?: (id: string) => Promise<boolean>}}\n >\n ).__VITE_DEVTOOLS_CLIENT_CONTEXT__;\n void ctx?.docks?.switchEntry?.('lit-devtools');\n } catch {\n // Not running inside the DevTools shell — ignore.\n }\n }\n\n #pointInTooltip(x: number, y: number): boolean {\n if (this.#tooltip.style.display === 'none') return false;\n const r = this.#tooltip.getBoundingClientRect();\n return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;\n }\n\n #onClick = (event: MouseEvent) => {\n if (!this.#active || this.#info === null) return;\n // Clicks on the tooltip panel are handled by its own buttons (open/copy).\n // The overlay's shadow root is closed, so we detect this by hit-rect rather\n // than inspecting the event path, and let the event reach those buttons.\n if (this.#pointInTooltip(event.clientX, event.clientY)) return;\n event.preventDefault();\n event.stopPropagation();\n this.#select(this.#info, event.metaKey || event.ctrlKey);\n };\n\n #onScrollOrResize = () => {\n if (this.#scrollTimer !== undefined) clearTimeout(this.#scrollTimer);\n this.#scrollTimer = setTimeout(() => {\n this.#scrollTimer = undefined;\n if (this.#targetEl !== null) {\n this.#updateHighlightRect();\n }\n }, 50);\n };\n}\n\ncustomElements.define('lit-source-overlay', LitSourceOverlay);\n\nexport const initSourceOverlay = (\n initOptions: SourceOverlayInitOptions = {}\n) => {\n if (typeof window === 'undefined') return;\n const el = document.createElement('lit-source-overlay') as LitSourceOverlay;\n el.configure(initOptions);\n document.body.append(el);\n};\n\nexport const toggleSourceOverlay = () => {\n const el = document.querySelector(\n 'lit-source-overlay'\n ) as LitSourceOverlay | null;\n el?.toggle();\n};\n"]}
1
+ {"version":3,"file":"overlay-element.js","sourceRoot":"","sources":["../../../src/lib/runtime/source-overlay/overlay-element.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport type {ElementInfo, EditorConfig} from '../../types.js';\nimport {BUILTIN_EDITORS, resolveEditor} from './editors.js';\nimport {\n defaultResolver,\n findSourceAtPoint,\n findSourceHost,\n type ElementResolver,\n} from './source-host.js';\nimport {buildSpotlightClipPath} from './mask-path.js';\nimport {OVERLAY_HTML} from './template.js';\nimport {observeEdgeInsets} from '../edge-panel.js';\nimport {subscribeOverride} from '../overrides.js';\nimport {injectTokens} from '../../tokens.js';\nimport {idOf} from '../timeline/identity.js';\nimport {\n INSPECT_OVERLAY_TOGGLE_CHANNEL,\n INSPECT_DATA_CHANNEL,\n} from '../../../types/inspector.js';\n\nexport interface SourceOverlayInitOptions {\n key?: string;\n editor?: EditorConfig | string;\n workspaceRoot?: string;\n throttleMs?: number;\n exclude?: (el: Element) => boolean;\n onSelect?: (info: ElementInfo) => void;\n openInEditorPath?: string;\n}\n\nclass LitSourceOverlay extends HTMLElement {\n #active = false;\n #hot: {send: (event: string, data: unknown) => void} | undefined;\n #options: SourceOverlayInitOptions = {};\n #editor: EditorConfig = BUILTIN_EDITORS.vscode;\n #resolver: ElementResolver = defaultResolver;\n #dialog: HTMLDialogElement;\n #mask: HTMLElement;\n #highlight: HTMLElement;\n #tooltip: HTMLElement;\n #tag: HTMLElement;\n #path: HTMLElement;\n #info: ElementInfo | null = null;\n #targetEl: Element | null = null;\n #throttleTimer: ReturnType<typeof setTimeout> | undefined;\n #scrollTimer: ReturnType<typeof setTimeout> | undefined;\n #resizeObserver: ResizeObserver | undefined;\n #cursorStyle: HTMLStyleElement | null = null;\n // Whether the Vite HMR WebSocket is currently connected. Used to suppress the\n // editor-URL-scheme fallback once the dev server is gone — otherwise a failed\n // open-in-editor fetch would navigate the tab to `vscode://…`.\n #connected = true;\n #lastMouseX = 0;\n #lastMouseY = 0;\n #edgeDispose: (() => void) | undefined;\n #overrideSubscribed = false;\n #hotOff: (() => void) | undefined;\n\n constructor() {\n super();\n const root = this.attachShadow({mode: 'closed'});\n root.innerHTML = OVERLAY_HTML;\n this.#dialog = root.getElementById('overlay') as HTMLDialogElement;\n this.#mask = root.getElementById('mask')!;\n this.#highlight = root.getElementById('highlight')!;\n this.#tooltip = root.getElementById('tooltip')!;\n this.#tag = root.getElementById('tag')!;\n this.#path = root.getElementById('path')!;\n root.getElementById('open')!.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this.#info !== null) this.#select(this.#info, true);\n });\n root.getElementById('copy')!.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this.#info === null) return;\n const text = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;\n void navigator.clipboard?.writeText(text);\n });\n this.#dialog.addEventListener('cancel', (e) => e.preventDefault());\n }\n\n connectedCallback() {\n injectTokens();\n document.addEventListener('mousemove', this.#onTrackMouse, true);\n document.addEventListener('keydown', this.#onKeyDown, true);\n const hot = (\n import.meta as {\n hot?: {\n on: (event: string, cb: (data?: unknown) => void) => void;\n off: (event: string, cb: (data?: unknown) => void) => void;\n send: (event: string, data: unknown) => void;\n };\n }\n ).hot;\n this.#hot = hot;\n if (hot !== undefined && this.#hotOff === undefined) {\n // Removed again in disconnectedCallback, so a re-attached overlay\n // doesn't stack duplicates and a detached one stops reacting.\n const handlers: Array<[string, (data?: unknown) => void]> = [\n ['vite:beforeFullReload', () => this.deactivate()],\n ['vite:ws:disconnect', () => (this.#connected = false)],\n ['vite:ws:connect', () => (this.#connected = true)],\n // Toggle from the Vite DevTools command/shortcut (handler runs server-side).\n [INSPECT_OVERLAY_TOGGLE_CHANNEL, () => this.toggle()],\n ];\n for (const [event, cb] of handlers) hot.on(event, cb);\n this.#hotOff = () => {\n for (const [event, cb] of handlers) hot.off(event, cb);\n };\n }\n // Keep the (bottom-fixed) tooltip clear of the Vite DevTools edge panel.\n this.#edgeDispose = observeEdgeInsets((insets) => {\n this.style.setProperty('--edge-bottom', `${insets.bottom}px`);\n });\n // Apply the panel's editor override live (and on load). Merge so other\n // configured options (key, throttle, …) survive.\n if (!this.#overrideSubscribed) {\n this.#overrideSubscribed = true;\n subscribeOverride(hot, (o) => {\n if (o.sourceOverlayEditor !== undefined) {\n this.#options = {...this.#options, editor: o.sourceOverlayEditor};\n this.#editor = resolveEditor(o.sourceOverlayEditor);\n }\n });\n }\n }\n\n disconnectedCallback() {\n document.removeEventListener('mousemove', this.#onTrackMouse, true);\n document.removeEventListener('keydown', this.#onKeyDown, true);\n this.deactivate();\n this.#edgeDispose?.();\n this.#edgeDispose = undefined;\n this.#hotOff?.();\n this.#hotOff = undefined;\n }\n\n configure(options: SourceOverlayInitOptions) {\n this.#options = options;\n this.#editor = resolveEditor(options.editor);\n }\n\n activate() {\n if (this.#active) return;\n this.#active = true;\n this.#dialog.showModal();\n this.#mask.style.background = 'rgba(0,0,0,0.35)';\n // The overlay is pointer-events:none, so the cursor reflects the hovered\n // page element. Force a crosshair while inspecting. The closed shadow DOM\n // tooltip is unaffected, so its buttons keep their own pointer cursor.\n if (this.#cursorStyle === null) {\n this.#cursorStyle = document.createElement('style');\n this.#cursorStyle.textContent = '*{cursor:crosshair !important}';\n }\n document.head.append(this.#cursorStyle);\n document.addEventListener('mousemove', this.#onMouseMove, true);\n document.addEventListener('click', this.#onClick, true);\n window.addEventListener('scroll', this.#onScrollOrResize, {passive: true});\n window.addEventListener('resize', this.#onScrollOrResize, {passive: true});\n void this.#resolveAt(this.#lastMouseX, this.#lastMouseY);\n }\n\n deactivate() {\n if (!this.#active) return;\n this.#active = false;\n this.#dialog.close();\n this.#mask.style.background = 'rgba(0,0,0,0)';\n this.#cursorStyle?.remove();\n document.removeEventListener('mousemove', this.#onMouseMove, true);\n document.removeEventListener('click', this.#onClick, true);\n window.removeEventListener('scroll', this.#onScrollOrResize);\n window.removeEventListener('resize', this.#onScrollOrResize);\n if (this.#throttleTimer !== undefined) {\n clearTimeout(this.#throttleTimer);\n this.#throttleTimer = undefined;\n }\n if (this.#scrollTimer !== undefined) {\n clearTimeout(this.#scrollTimer);\n this.#scrollTimer = undefined;\n }\n this.#clearTarget();\n }\n\n toggle() {\n if (this.#active) this.deactivate();\n else this.activate();\n }\n\n #normalizePath(filePath: string): string {\n const root = this.#options.workspaceRoot;\n if (root !== undefined && filePath.startsWith(root)) {\n const rest = filePath.slice(root.length);\n return rest.startsWith('/') ? rest.slice(1) : rest;\n }\n return filePath;\n }\n\n async #openInEditor(filePath: string, lineNumber: number) {\n const path = this.#normalizePath(filePath);\n const endpoint = this.#options.openInEditorPath ?? '/__lit-open-in-editor';\n try {\n const params = new URLSearchParams({\n file: path,\n line: String(lineNumber),\n });\n const res = await fetch(`${endpoint}?${params.toString()}`);\n if (res.ok) return;\n } catch {\n // Fall back to editor URL schemes (e.g. StackBlitz previews).\n }\n // Skip the URL-scheme fallback when the dev server is gone: a fetch failure\n // there means \"server quit\", not \"no endpoint\", and navigating the tab to\n // `vscode://…` on shutdown is jarring and unwanted.\n if (!this.#connected) return;\n window.open(this.#editor.url(path, lineNumber), '_self');\n }\n\n #updateHighlightRect() {\n if (this.#targetEl === null) return;\n const rect = this.#targetEl.getBoundingClientRect();\n const raw = getComputedStyle(this)\n .getPropertyValue('--lit-devtools-radius')\n .trim();\n const r = parseFloat(raw) || 6;\n // The tinted box hugs the element's exact rect — that's the boundary being\n // picked; only the spotlight cutout gets the breathing room of `r`.\n this.#highlight.style.display = 'block';\n this.#highlight.style.left = `${rect.left}px`;\n this.#highlight.style.top = `${rect.top}px`;\n this.#highlight.style.width = `${rect.width}px`;\n this.#highlight.style.height = `${rect.height}px`;\n this.#mask.style.clipPath = buildSpotlightClipPath(\n rect.left - r,\n rect.top - r,\n rect.width + 2 * r,\n rect.height + 2 * r,\n r\n );\n }\n\n #showTooltip() {\n if (this.#info === null) return;\n this.#tag.textContent = `<${this.#info.tagName}>`;\n this.#path.textContent = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;\n this.#tooltip.style.display = 'flex';\n }\n\n #clearTarget() {\n this.#targetEl = null;\n this.#info = null;\n this.#highlight.style.display = 'none';\n this.#highlight.style.left = '0';\n this.#highlight.style.top = '0';\n this.#highlight.style.width = '0';\n this.#highlight.style.height = '0';\n this.#mask.style.clipPath = 'none';\n this.#tooltip.style.display = 'none';\n if (this.#resizeObserver !== undefined) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = undefined;\n }\n }\n\n #shouldSkip(el: Element): boolean {\n if (el === this.#dialog || this.#dialog.contains(el)) return true;\n if (el.tagName === 'IFRAME') return true;\n // Never target devtools' own injected elements (indicator, overlay).\n const tag = el.tagName.toLowerCase();\n if (tag === 'lit-source-overlay' || tag.startsWith('lit-devtools-')) {\n return true;\n }\n const exclude = this.#options.exclude;\n return exclude !== undefined && exclude(el);\n }\n\n async #resolveAt(x: number, y: number) {\n this.#lastMouseX = x;\n this.#lastMouseY = y;\n const el = findSourceAtPoint(x, y, this.#dialog);\n if (el === null || this.#shouldSkip(el)) {\n this.#clearTarget();\n return;\n }\n const host = findSourceHost(el);\n if (host === null) {\n this.#clearTarget();\n return;\n }\n if (host === this.#targetEl && this.#info !== null) {\n this.#updateHighlightRect();\n return;\n }\n this.#targetEl = host;\n if (this.#resizeObserver === undefined) {\n this.#resizeObserver = new ResizeObserver(() =>\n this.#updateHighlightRect()\n );\n } else {\n this.#resizeObserver.disconnect();\n }\n this.#resizeObserver.observe(host);\n const resolved = await this.#resolver.resolveElementInfo(el);\n if (resolved === null) {\n this.#clearTarget();\n return;\n }\n this.#info = resolved;\n this.#updateHighlightRect();\n this.#showTooltip();\n }\n\n #onTrackMouse = (event: MouseEvent) => {\n this.#lastMouseX = event.clientX;\n this.#lastMouseY = event.clientY;\n };\n\n #onKeyDown = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey) {\n const pressed = event.key.toLowerCase();\n const hotkey = (this.#options.key ?? 's').toLowerCase();\n if (pressed === hotkey) {\n event.preventDefault();\n this.toggle();\n }\n }\n if (this.#active && event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n #onMouseMove = (event: MouseEvent) => {\n if (!this.#active) return;\n // Keep the current selection while hovering the tooltip so its buttons stay\n // clickable — the tooltip isn't a source element, so re-resolving here would\n // clear the target and hide the panel out from under the pointer.\n if (this.#pointInTooltip(event.clientX, event.clientY)) return;\n const throttleMs = this.#options.throttleMs ?? 50;\n if (this.#throttleTimer !== undefined) return;\n this.#throttleTimer = setTimeout(() => {\n this.#throttleTimer = undefined;\n // Resolve against the latest pointer position (kept current by\n // #onTrackMouse), not the coords captured when this timer was scheduled\n // ~throttleMs ago — otherwise the highlight lags the cursor during\n // continuous movement.\n const x = this.#lastMouseX;\n const y = this.#lastMouseY;\n if (this.#pointInTooltip(x, y)) return;\n void this.#resolveAt(x, y);\n }, throttleMs);\n };\n\n #select(info: ElementInfo, openInEditor = false) {\n const target = this.#targetEl;\n // Cancel the whole selection mode on any deliberate pick, before acting —\n // the editor may open via a URL scheme that doesn't navigate this tab away,\n // so we can't rely on the open outcome to dismiss the inspector.\n this.deactivate();\n this.#options.onSelect?.(info);\n if (openInEditor) {\n void this.#openInEditor(info.source.filePath, info.source.lineNumber);\n return;\n }\n // Report the picked element to the DevTools panel, which selects it in the\n // Components tree. Identity matches the inspector runtime via idOf().\n if (target !== null) {\n this.#hot?.send(INSPECT_DATA_CHANNEL, {type: 'pick', id: idOf(target)});\n this.#openDevtoolsPanel();\n }\n }\n\n /**\n * Bring the Lit DevTools dock entry to the front so a pick is visible even\n * when the panel was closed. The panel mirrors this from its own\n * `inspector-activate` handler, but only once its iframe is mounted — and the\n * @vitejs/devtools shell does not mount that iframe until the entry has been\n * opened at least once. This overlay always runs on the page, so calling\n * `switchEntry` here covers the cold-start case where no panel exists yet to\n * receive the `pick` message.\n */\n #openDevtoolsPanel() {\n try {\n const ctx = (\n window as unknown as Record<\n string,\n undefined | {docks?: {switchEntry?: (id: string) => Promise<boolean>}}\n >\n ).__VITE_DEVTOOLS_CLIENT_CONTEXT__;\n void ctx?.docks?.switchEntry?.('lit-devtools');\n } catch {\n // Not running inside the DevTools shell — ignore.\n }\n }\n\n #pointInTooltip(x: number, y: number): boolean {\n if (this.#tooltip.style.display === 'none') return false;\n const r = this.#tooltip.getBoundingClientRect();\n return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;\n }\n\n #onClick = (event: MouseEvent) => {\n if (!this.#active || this.#info === null) return;\n // Clicks on the tooltip panel are handled by its own buttons (open/copy).\n // The overlay's shadow root is closed, so we detect this by hit-rect rather\n // than inspecting the event path, and let the event reach those buttons.\n if (this.#pointInTooltip(event.clientX, event.clientY)) return;\n event.preventDefault();\n event.stopPropagation();\n this.#select(this.#info, event.metaKey || event.ctrlKey);\n };\n\n #onScrollOrResize = () => {\n if (this.#scrollTimer !== undefined) clearTimeout(this.#scrollTimer);\n this.#scrollTimer = setTimeout(() => {\n this.#scrollTimer = undefined;\n if (this.#targetEl !== null) {\n this.#updateHighlightRect();\n }\n }, 50);\n };\n}\n\ncustomElements.define('lit-source-overlay', LitSourceOverlay);\n\nexport const initSourceOverlay = (\n initOptions: SourceOverlayInitOptions = {}\n) => {\n if (typeof window === 'undefined') return;\n const el = document.createElement('lit-source-overlay') as LitSourceOverlay;\n el.configure(initOptions);\n document.body.append(el);\n};\n\nexport const toggleSourceOverlay = () => {\n const el = document.querySelector(\n 'lit-source-overlay'\n ) as LitSourceOverlay | null;\n el?.toggle();\n};\n"]}
@@ -27,25 +27,30 @@ const state = {
27
27
  recordingState: false,
28
28
  litLifecycleEnabled: true,
29
29
  litRenderEnabled: true,
30
+ litRenderVerboseEnabled: false,
30
31
  mouseEventEnabled: false,
31
32
  keyboardEventEnabled: false,
32
33
  };
33
34
  const recording = () => state.recordingState;
34
35
  const lifecycleEnabled = () => state.litLifecycleEnabled;
35
36
  const renderEnabled = () => state.litRenderEnabled;
37
+ const renderVerboseEnabled = () => state.litRenderVerboseEnabled;
36
38
  const mouseEnabled = () => state.mouseEventEnabled;
37
39
  const keyboardEnabled = () => state.keyboardEventEnabled;
38
- // Drive Lit's debug event flag from recording × render-layer-enabled so
39
- // lit-html only pays the per-render CustomEvent dispatch cost while we're
40
- // actually capturing the render layer.
40
+ // Drive Lit's debug event flag from recording × (render-layer-enabled OR
41
+ // verbose-layer-enabled) so lit-html only pays the per-render CustomEvent
42
+ // dispatch cost while we're actually capturing one of the two render layers.
41
43
  const syncRenderDebug = () => {
42
- setRenderDebugEnabled(state.recordingState && state.litRenderEnabled);
44
+ setRenderDebugEnabled(
45
+ state.recordingState &&
46
+ (state.litRenderEnabled || state.litRenderVerboseEnabled)
47
+ );
43
48
  };
44
49
  // ---------------------------------------------------------------------------
45
50
  // Capture layer installation
46
51
  // ---------------------------------------------------------------------------
47
52
  installLifecycleLayer(emit, recording, lifecycleEnabled);
48
- installRenderLayer(emit, recording, renderEnabled);
53
+ installRenderLayer(emit, recording, renderEnabled, renderVerboseEnabled);
49
54
  installMouseLayer(emit, recording, mouseEnabled);
50
55
  installKeyboardLayer(emit, recording, keyboardEnabled);
51
56
  // Flash-on-update rides the lifecycle wrappers but not the recording gate:
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/install.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Timeline runtime install entry point.\n *\n * Injected by the plugin into the host page via `transformIndexHtml` when\n * `timeline: true` is set. Sets up all capture layers and wires them to the\n * transport.\n *\n * Recording starts off; the panel iframe toggles it via the Vite HMR channel\n * (Phase 0/1) or devframe shared state (Phase 2+).\n */\n\nimport {emit, setHotClient} from './transport.js';\nimport {resetClock} from './clock.js';\nimport {installLifecycleLayer, setUpdateHook} from './lifecycle.js';\nimport {installRenderLayer, setRenderDebugEnabled} from './render.js';\nimport {installMouseLayer, installKeyboardLayer} from './input.js';\nimport {flashUpdate, setFlashEnabled, setFlashRamp} from './flash.js';\nimport {subscribeOverride} from '../overrides.js';\nimport type {TimelineLayersState} from '../../../types/timeline.js';\n\n// ---------------------------------------------------------------------------\n// Recording state — written by the panel toggle, read by all capture layers.\n// ---------------------------------------------------------------------------\n\nconst state: TimelineLayersState = {\n recordingState: false,\n litLifecycleEnabled: true,\n litRenderEnabled: true,\n mouseEventEnabled: false,\n keyboardEventEnabled: false,\n};\n\nconst recording = (): boolean => state.recordingState;\nconst lifecycleEnabled = (): boolean => state.litLifecycleEnabled;\nconst renderEnabled = (): boolean => state.litRenderEnabled;\nconst mouseEnabled = (): boolean => state.mouseEventEnabled;\nconst keyboardEnabled = (): boolean => state.keyboardEventEnabled;\n\n// Drive Lit's debug event flag from recording × render-layer-enabled so\n// lit-html only pays the per-render CustomEvent dispatch cost while we're\n// actually capturing the render layer.\nconst syncRenderDebug = (): void => {\n setRenderDebugEnabled(state.recordingState && state.litRenderEnabled);\n};\n\n// ---------------------------------------------------------------------------\n// Capture layer installation\n// ---------------------------------------------------------------------------\n\ninstallLifecycleLayer(emit, recording, lifecycleEnabled);\ninstallRenderLayer(emit, recording, renderEnabled);\ninstallMouseLayer(emit, recording, mouseEnabled);\ninstallKeyboardLayer(emit, recording, keyboardEnabled);\n\n// Flash-on-update rides the lifecycle wrappers but not the recording gate:\n// it's a page-side visual the panel toggles as a preference, so it follows the\n// settings override (read at boot, pushed live) rather than the layer state.\nsetUpdateHook(flashUpdate);\n\n// ---------------------------------------------------------------------------\n// HMR channel wiring (Phase 0/1 transport)\n// ---------------------------------------------------------------------------\n\n// `import.meta.hot` exists in Vite dev builds; the tsconfig lib set doesn't\n// include it, so we access it through the un-typed global shape.\ntype ViteHot = {\n send: (event: string, data: unknown) => void;\n on: (event: string, handler: (data: unknown) => void) => void;\n};\nconst hot = (import.meta as {hot?: ViteHot}).hot;\n\nsubscribeOverride(hot, (o) => {\n setFlashEnabled(o.flashUpdates ?? false);\n setFlashRamp(o.flashUpdatesRamp ?? false);\n});\n\nif (hot !== undefined) {\n setHotClient(hot);\n\n // Panel → app: toggle recording and per-layer flags.\n hot.on('lit:timeline:recording-changed', (data) => {\n const next = (data as {recording: boolean}).recording;\n // Re-zero the timeline clock on the rising edge so event times read as\n // \"ms since recording started\" rather than since page load.\n if (next && !state.recordingState) resetClock();\n state.recordingState = next;\n syncRenderDebug();\n });\n\n hot.on('lit:timeline:layers-changed', (data) => {\n Object.assign(state, data as Partial<TimelineLayersState>);\n syncRenderDebug();\n });\n\n // Announce readiness so the panel can detect the runtime.\n hot.send('lit:timeline:runtime-ready', {});\n}\n"]}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/install.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Timeline runtime install entry point.\n *\n * Injected by the plugin into the host page via `transformIndexHtml` when\n * `timeline: true` is set. Sets up all capture layers and wires them to the\n * transport.\n *\n * Recording starts off; the panel iframe toggles it via the Vite HMR channel\n * (Phase 0/1) or devframe shared state (Phase 2+).\n */\n\nimport {emit, setHotClient} from './transport.js';\nimport {resetClock} from './clock.js';\nimport {installLifecycleLayer, setUpdateHook} from './lifecycle.js';\nimport {installRenderLayer, setRenderDebugEnabled} from './render.js';\nimport {installMouseLayer, installKeyboardLayer} from './input.js';\nimport {flashUpdate, setFlashEnabled, setFlashRamp} from './flash.js';\nimport {subscribeOverride} from '../overrides.js';\nimport type {TimelineLayersState} from '../../../types/timeline.js';\n\n// ---------------------------------------------------------------------------\n// Recording state — written by the panel toggle, read by all capture layers.\n// ---------------------------------------------------------------------------\n\nconst state: TimelineLayersState = {\n recordingState: false,\n litLifecycleEnabled: true,\n litRenderEnabled: true,\n litRenderVerboseEnabled: false,\n mouseEventEnabled: false,\n keyboardEventEnabled: false,\n};\n\nconst recording = (): boolean => state.recordingState;\nconst lifecycleEnabled = (): boolean => state.litLifecycleEnabled;\nconst renderEnabled = (): boolean => state.litRenderEnabled;\nconst renderVerboseEnabled = (): boolean => state.litRenderVerboseEnabled;\nconst mouseEnabled = (): boolean => state.mouseEventEnabled;\nconst keyboardEnabled = (): boolean => state.keyboardEventEnabled;\n\n// Drive Lit's debug event flag from recording × (render-layer-enabled OR\n// verbose-layer-enabled) so lit-html only pays the per-render CustomEvent\n// dispatch cost while we're actually capturing one of the two render layers.\nconst syncRenderDebug = (): void => {\n setRenderDebugEnabled(\n state.recordingState &&\n (state.litRenderEnabled || state.litRenderVerboseEnabled)\n );\n};\n\n// ---------------------------------------------------------------------------\n// Capture layer installation\n// ---------------------------------------------------------------------------\n\ninstallLifecycleLayer(emit, recording, lifecycleEnabled);\ninstallRenderLayer(emit, recording, renderEnabled, renderVerboseEnabled);\ninstallMouseLayer(emit, recording, mouseEnabled);\ninstallKeyboardLayer(emit, recording, keyboardEnabled);\n\n// Flash-on-update rides the lifecycle wrappers but not the recording gate:\n// it's a page-side visual the panel toggles as a preference, so it follows the\n// settings override (read at boot, pushed live) rather than the layer state.\nsetUpdateHook(flashUpdate);\n\n// ---------------------------------------------------------------------------\n// HMR channel wiring (Phase 0/1 transport)\n// ---------------------------------------------------------------------------\n\n// `import.meta.hot` exists in Vite dev builds; the tsconfig lib set doesn't\n// include it, so we access it through the un-typed global shape.\ntype ViteHot = {\n send: (event: string, data: unknown) => void;\n on: (event: string, handler: (data: unknown) => void) => void;\n};\nconst hot = (import.meta as {hot?: ViteHot}).hot;\n\nsubscribeOverride(hot, (o) => {\n setFlashEnabled(o.flashUpdates ?? false);\n setFlashRamp(o.flashUpdatesRamp ?? false);\n});\n\nif (hot !== undefined) {\n setHotClient(hot);\n\n // Panel → app: toggle recording and per-layer flags.\n hot.on('lit:timeline:recording-changed', (data) => {\n const next = (data as {recording: boolean}).recording;\n // Re-zero the timeline clock on the rising edge so event times read as\n // \"ms since recording started\" rather than since page load.\n if (next && !state.recordingState) resetClock();\n state.recordingState = next;\n syncRenderDebug();\n });\n\n hot.on('lit:timeline:layers-changed', (data) => {\n Object.assign(state, data as Partial<TimelineLayersState>);\n syncRenderDebug();\n });\n\n // Announce readiness so the panel can detect the runtime.\n hot.send('lit:timeline:runtime-ready', {});\n}\n"]}
@@ -10,8 +10,8 @@ export type { TimelineEvent, TimelineLayer };
10
10
  *
11
11
  * The event is forwarded to the Timeline panel when recording is active.
12
12
  * Use a custom `layerId` registered with `addTimelineLayer`, or one of the
13
- * built-in layer ids (`'lit-lifecycle'`, `'lit-render'`, `'mouse'`,
14
- * `'keyboard'`).
13
+ * built-in layer ids (`'lit-lifecycle'`, `'lit-render'`,
14
+ * `'lit-render-verbose'`, `'mouse'`, `'keyboard'`).
15
15
  *
16
16
  * No-ops in production (the HMR channel is absent; events are dropped in the
17
17
  * transport queue).
@@ -17,8 +17,8 @@ import {emit, setHotClientCallback} from './transport.js';
17
17
  *
18
18
  * The event is forwarded to the Timeline panel when recording is active.
19
19
  * Use a custom `layerId` registered with `addTimelineLayer`, or one of the
20
- * built-in layer ids (`'lit-lifecycle'`, `'lit-render'`, `'mouse'`,
21
- * `'keyboard'`).
20
+ * built-in layer ids (`'lit-lifecycle'`, `'lit-render'`,
21
+ * `'lit-render-verbose'`, `'mouse'`, `'keyboard'`).
22
22
  *
23
23
  * No-ops in production (the HMR channel is absent; events are dropped in the
24
24
  * transport queue).
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/public-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AAEH,OAAO,EAAC,IAAI,EAAE,oBAAoB,EAAC,MAAM,gBAAgB,CAAC;AAK1D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAoB,EAAQ,EAAE;IAC7D,IAAI,CAAC,KAAK,CAAC,CAAC;AACd,CAAC,CAAC;AAIF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAoB,EAAQ,EAAE;IAC7D,MAAM,IAAI,GAAG,GAAS,EAAE;QACrB,OAAO,IAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,2BAA2B,EAAE;YACtE,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CAAC;IACF,oBAAoB,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Public timeline API — re-exported by the `virtual:lit-plugin/timeline`\n * virtual module so app code and other plugins can contribute events and\n * custom layers without reaching into plugin internals.\n *\n * This module shares the same `transport.ts` instance as `install.ts`, so\n * events emitted here flow through the same batched HMR channel to the panel.\n */\n\nimport {emit, setHotClientCallback} from './transport.js';\nimport type {TimelineEvent, TimelineLayer} from '../../../types/timeline.js';\n\nexport type {TimelineEvent, TimelineLayer};\n\n/**\n * Emit a custom timeline event from app code.\n *\n * The event is forwarded to the Timeline panel when recording is active.\n * Use a custom `layerId` registered with `addTimelineLayer`, or one of the\n * built-in layer ids (`'lit-lifecycle'`, `'lit-render'`, `'mouse'`,\n * `'keyboard'`).\n *\n * No-ops in production (the HMR channel is absent; events are dropped in the\n * transport queue).\n */\nexport const addTimelineEvent = (event: TimelineEvent): void => {\n emit(event);\n};\n\ntype ViteHot = {send: (event: string, data: unknown) => void};\n\n/**\n * Register a custom timeline layer and announce it to the panel.\n *\n * The panel adds the layer to its toggle strip after the built-in layers.\n * The registration message is sent once on first call; duplicate ids are\n * ignored.\n */\nexport const addTimelineLayer = (layer: TimelineLayer): void => {\n const send = (): void => {\n (import.meta as {hot?: ViteHot}).hot?.send('lit:timeline:custom-layer', {\n layer,\n });\n };\n setHotClientCallback(send);\n};\n"]}
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/public-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AAEH,OAAO,EAAC,IAAI,EAAE,oBAAoB,EAAC,MAAM,gBAAgB,CAAC;AAK1D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAoB,EAAQ,EAAE;IAC7D,IAAI,CAAC,KAAK,CAAC,CAAC;AACd,CAAC,CAAC;AAIF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAoB,EAAQ,EAAE;IAC7D,MAAM,IAAI,GAAG,GAAS,EAAE;QACrB,OAAO,IAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,2BAA2B,EAAE;YACtE,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CAAC;IACF,oBAAoB,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Public timeline API — re-exported by the `virtual:lit-plugin/timeline`\n * virtual module so app code and other plugins can contribute events and\n * custom layers without reaching into plugin internals.\n *\n * This module shares the same `transport.ts` instance as `install.ts`, so\n * events emitted here flow through the same batched HMR channel to the panel.\n */\n\nimport {emit, setHotClientCallback} from './transport.js';\nimport type {TimelineEvent, TimelineLayer} from '../../../types/timeline.js';\n\nexport type {TimelineEvent, TimelineLayer};\n\n/**\n * Emit a custom timeline event from app code.\n *\n * The event is forwarded to the Timeline panel when recording is active.\n * Use a custom `layerId` registered with `addTimelineLayer`, or one of the\n * built-in layer ids (`'lit-lifecycle'`, `'lit-render'`,\n * `'lit-render-verbose'`, `'mouse'`, `'keyboard'`).\n *\n * No-ops in production (the HMR channel is absent; events are dropped in the\n * transport queue).\n */\nexport const addTimelineEvent = (event: TimelineEvent): void => {\n emit(event);\n};\n\ntype ViteHot = {send: (event: string, data: unknown) => void};\n\n/**\n * Register a custom timeline layer and announce it to the panel.\n *\n * The panel adds the layer to its toggle strip after the built-in layers.\n * The registration message is sent once on first call; duplicate ids are\n * ignored.\n */\nexport const addTimelineLayer = (layer: TimelineLayer): void => {\n const send = (): void => {\n (import.meta as {hot?: ViteHot}).hot?.send('lit:timeline:custom-layer', {\n layer,\n });\n };\n setHotClientCallback(send);\n};\n"]}
@@ -4,29 +4,38 @@
4
4
  * SPDX-License-Identifier: BSD-3-Clause
5
5
  */
6
6
  /**
7
- * lit-render timeline layer — listens to the built-in lit-debug CustomEvents
8
- * instead of patching prototypes, so it's zero-cost when the Lit debug flag
9
- * is off and perfectly accurate for the render layer.
7
+ * lit-render timeline layers — listen to the built-in lit-debug CustomEvents
8
+ * instead of patching prototypes, so they're zero-cost when the Lit debug
9
+ * flag is off and perfectly accurate for the render layers.
10
10
  *
11
11
  * `globalThis.emitLitDebugLogEvents = true` gates the events, and lit-html
12
12
  * dispatches a CustomEvent per render whenever it's set — a real per-render
13
13
  * cost. So the caller drives the flag via {@link setRenderDebugEnabled} from
14
- * `recording × layer-enabled` rather than leaving it on for the whole session.
14
+ * `recording × (lit-render OR lit-render-verbose enabled)` rather than
15
+ * leaving it on for the whole session.
15
16
  * The events are tagged `*Unstable` in the Lit source; we tolerate missing
16
17
  * `kind` values gracefully.
17
18
  *
18
19
  * begin render / end render share a numeric `id` → we use it as groupId so
19
20
  * the panel can show a duration bar for each render call.
21
+ *
22
+ * `template updating` / `template instantiated[ and updated]` / `set part` /
23
+ * `commit *` fire once per template-bound part on *every* render — extremely
24
+ * high volume (a ticking clock or animation floods the layer). They're
25
+ * emitted on the separate opt-in `lit-render-verbose` layer rather than
26
+ * `lit-render`, so the common case (the begin/end render duration bar) stays
27
+ * quiet by default.
20
28
  */
21
29
  import type { TimelineEvent } from '../../../types/timeline.js';
22
30
  type EmitFn = (event: TimelineEvent) => void;
23
31
  type RecordingFn = () => boolean;
24
32
  type LayerEnabledFn = () => boolean;
25
33
  /**
26
- * Install the lit-debug render layer.
34
+ * Install the lit-debug render layers (`lit-render` and the opt-in
35
+ * `lit-render-verbose`).
27
36
  * Idempotent — calling again when already installed is a no-op.
28
37
  */
29
- export declare const installRenderLayer: (emit: EmitFn, recording: RecordingFn, layerEnabled: LayerEnabledFn) => void;
38
+ export declare const installRenderLayer: (emit: EmitFn, recording: RecordingFn, renderEnabled: LayerEnabledFn, verboseEnabled: LayerEnabledFn) => void;
30
39
  /**
31
40
  * Toggle Lit's debug event system. Enabling makes lit-html dispatch a
32
41
  * CustomEvent on every render (dev-only; no-op in prod builds), so the caller
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAI9D,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAC7C,KAAK,WAAW,GAAG,MAAM,OAAO,CAAC;AACjC,KAAK,cAAc,GAAG,MAAM,OAAO,CAAC;AAmGpC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,SACvB,MAAM,aACD,WAAW,gBACR,cAAc,KAC3B,IASF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,YAAa,OAAO,KAAG,IAGxD,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,QAAO,IAIvC,CAAC"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAI9D,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAC7C,KAAK,WAAW,GAAG,MAAM,OAAO,CAAC;AACjC,KAAK,cAAc,GAAG,MAAM,OAAO,CAAC;AA2QpC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,SACvB,MAAM,aACD,WAAW,iBACP,cAAc,kBACb,cAAc,KAC7B,IAUF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,YAAa,OAAO,KAAG,IAGxD,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,QAAO,IAIvC,CAAC"}
@@ -20,15 +20,52 @@ const hostMeta = (host) => {
20
20
  source: sourceOf(host),
21
21
  };
22
22
  };
23
+ /** Reads the render `host` off a `Part` for the one kind (`set part`) whose
24
+ * detail carries the part instead of the render `options` directly. */
25
+ const partHost = (part) => part?.options?.host;
23
26
  let removeListener = null;
24
- const onLitDebug = (e, emit, recording, layerEnabled) => {
25
- if (!recording() || !layerEnabled()) return;
27
+ /**
28
+ * Reduces an arbitrary lit-html binding value to a small JSON-serializable
29
+ * summary for the verbose layer's `data` field. Never puts the value itself
30
+ * in `data` — it may be a DOM Node, a TemplateResult, a function, or hold a
31
+ * reference back to the host element, none of which survive (or belong in) a
32
+ * structured-clone over the HMR channel.
33
+ */
34
+ const describeValue = (value) => {
35
+ if (value === null) return 'null';
36
+ if (value === undefined) return 'undefined';
37
+ if (typeof value === 'string') {
38
+ return value.length > 40
39
+ ? `string:"${value.slice(0, 40)}…"`
40
+ : `string:"${value}"`;
41
+ }
42
+ if (typeof value === 'number') return `number:${value}`;
43
+ if (typeof value === 'boolean') return `boolean:${value}`;
44
+ if (typeof value === 'function') {
45
+ return `function:${value.name || 'anonymous'}`;
46
+ }
47
+ // lit's sentinels (`nothing`, `noChange`) are symbols.
48
+ if (typeof value === 'symbol') return `symbol:${value.description ?? ''}`;
49
+ if (Array.isArray(value)) return `array(${value.length})`;
50
+ if (typeof value === 'object' && '_$litType$' in value) return 'template';
51
+ if (typeof Node !== 'undefined' && value instanceof Node) {
52
+ const tag = value.tagName?.toLowerCase();
53
+ return tag ? `node:<${tag}>` : `node:#${value.nodeType}`;
54
+ }
55
+ const ctor = value?.constructor?.name;
56
+ return `object:${ctor ?? 'Object'}`;
57
+ };
58
+ /** Summarizes each entry of a template-instance's `values` array. */
59
+ const describeValues = (values) => values?.map(describeValue);
60
+ const onLitDebug = (e, emit, recording, renderEnabled, verboseEnabled) => {
61
+ if (!recording() || (!renderEnabled() && !verboseEnabled())) return;
26
62
  const detail = e.detail;
27
63
  if (!detail?.kind) return;
28
64
  const time = now();
29
65
  const {kind, id} = detail;
30
66
  switch (kind) {
31
67
  case 'begin render': {
68
+ if (!renderEnabled()) break;
32
69
  const meta = hostMeta(detail.options?.host);
33
70
  emit({
34
71
  layerId: 'lit-render',
@@ -42,6 +79,7 @@ const onLitDebug = (e, emit, recording, layerEnabled) => {
42
79
  break;
43
80
  }
44
81
  case 'end render': {
82
+ if (!renderEnabled()) break;
45
83
  const meta = hostMeta(detail.options?.host);
46
84
  emit({
47
85
  layerId: 'lit-render',
@@ -57,6 +95,7 @@ const onLitDebug = (e, emit, recording, layerEnabled) => {
57
95
  // `template prep` fires once per *unique* template, the first time it's
58
96
  // compiled — low volume, useful as a "new template" marker.
59
97
  case 'template prep':
98
+ if (!renderEnabled()) break;
60
99
  emit({
61
100
  layerId: 'lit-render',
62
101
  time,
@@ -64,26 +103,126 @@ const onLitDebug = (e, emit, recording, layerEnabled) => {
64
103
  data: {kind, id},
65
104
  });
66
105
  break;
67
- // `template updating` / `template instantiated` / `…and updated` fire once
68
- // per template-bound ChildPart on *every* render — extremely high volume
69
- // (a ticking clock or animation floods the layer). The begin/end render
70
- // pair above already captures each render as a grouped duration, so these
71
- // add noise without signal. Skip them; re-expose behind a "verbose" toggle
72
- // if per-part detail is ever needed. Same rationale for commit * / set part.
106
+ // The events below fire once per template-bound part on *every* render —
107
+ // extremely high volume (a ticking clock or animation floods the layer).
108
+ // The begin/end render pair above already captures each render as a
109
+ // grouped duration, so these live on the separate opt-in
110
+ // `lit-render-verbose` layer instead of adding noise to `lit-render`.
111
+ case 'template updating':
112
+ case 'template instantiated':
113
+ case 'template instantiated and updated': {
114
+ if (!verboseEnabled()) break;
115
+ const meta = hostMeta(detail.options?.host);
116
+ emit({
117
+ layerId: 'lit-render-verbose',
118
+ time,
119
+ title: kind,
120
+ subtitle: meta?.tagName,
121
+ data: {kind, values: describeValues(detail.values)},
122
+ meta,
123
+ });
124
+ break;
125
+ }
126
+ case 'set part': {
127
+ if (!verboseEnabled()) break;
128
+ const meta = hostMeta(partHost(detail.part));
129
+ emit({
130
+ layerId: 'lit-render-verbose',
131
+ time,
132
+ title: kind,
133
+ subtitle: meta?.tagName,
134
+ data: {
135
+ kind,
136
+ valueIndex: detail.valueIndex,
137
+ value: describeValue(detail.value),
138
+ },
139
+ meta,
140
+ });
141
+ break;
142
+ }
143
+ case 'commit nothing to child': {
144
+ if (!verboseEnabled()) break;
145
+ const meta = hostMeta(detail.options?.host);
146
+ emit({
147
+ layerId: 'lit-render-verbose',
148
+ time,
149
+ title: kind,
150
+ subtitle: meta?.tagName,
151
+ data: {kind},
152
+ meta,
153
+ });
154
+ break;
155
+ }
156
+ case 'commit text':
157
+ case 'commit node':
158
+ case 'commit to element binding': {
159
+ if (!verboseEnabled()) break;
160
+ const meta = hostMeta(detail.options?.host);
161
+ emit({
162
+ layerId: 'lit-render-verbose',
163
+ time,
164
+ title: kind,
165
+ subtitle: meta?.tagName,
166
+ data: {kind, value: describeValue(detail.value)},
167
+ meta,
168
+ });
169
+ break;
170
+ }
171
+ case 'commit attribute':
172
+ case 'commit property':
173
+ case 'commit boolean attribute': {
174
+ if (!verboseEnabled()) break;
175
+ const meta = hostMeta(detail.options?.host);
176
+ emit({
177
+ layerId: 'lit-render-verbose',
178
+ time,
179
+ title: kind,
180
+ subtitle: meta?.tagName,
181
+ data: {kind, name: detail.name, value: describeValue(detail.value)},
182
+ meta,
183
+ });
184
+ break;
185
+ }
186
+ case 'commit event listener': {
187
+ if (!verboseEnabled()) break;
188
+ const meta = hostMeta(detail.options?.host);
189
+ emit({
190
+ layerId: 'lit-render-verbose',
191
+ time,
192
+ title: kind,
193
+ subtitle: meta?.tagName,
194
+ data: {
195
+ kind,
196
+ name: detail.name,
197
+ addListener: detail.addListener,
198
+ removeListener: detail.removeListener,
199
+ },
200
+ meta,
201
+ });
202
+ break;
203
+ }
204
+ // Unknown or future `*Unstable` kind — ignore rather than guess a shape.
73
205
  default:
74
206
  break;
75
207
  }
76
208
  };
77
209
  /**
78
- * Install the lit-debug render layer.
210
+ * Install the lit-debug render layers (`lit-render` and the opt-in
211
+ * `lit-render-verbose`).
79
212
  * Idempotent — calling again when already installed is a no-op.
80
213
  */
81
- export const installRenderLayer = (emit, recording, layerEnabled) => {
214
+ export const installRenderLayer = (
215
+ emit,
216
+ recording,
217
+ renderEnabled,
218
+ verboseEnabled
219
+ ) => {
82
220
  if (removeListener !== null) return;
83
221
  // The listener is cheap and always attached; the per-render cost lives in the
84
222
  // `emitLitDebugLogEvents` flag, which the caller toggles via
85
223
  // `setRenderDebugEnabled` only while actively capturing.
86
- const handler = (e) => onLitDebug(e, emit, recording, layerEnabled);
224
+ const handler = (e) =>
225
+ onLitDebug(e, emit, recording, renderEnabled, verboseEnabled);
87
226
  window.addEventListener('lit-debug', handler);
88
227
  removeListener = () => window.removeEventListener('lit-debug', handler);
89
228
  };
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * lit-render timeline layer — listens to the built-in lit-debug CustomEvents\n * instead of patching prototypes, so it's zero-cost when the Lit debug flag\n * is off and perfectly accurate for the render layer.\n *\n * `globalThis.emitLitDebugLogEvents = true` gates the events, and lit-html\n * dispatches a CustomEvent per render whenever it's set — a real per-render\n * cost. So the caller drives the flag via {@link setRenderDebugEnabled} from\n * `recording × layer-enabled` rather than leaving it on for the whole session.\n * The events are tagged `*Unstable` in the Lit source; we tolerate missing\n * `kind` values gracefully.\n *\n * begin render / end render share a numeric `id` → we use it as groupId so\n * the panel can show a duration bar for each render call.\n */\n\nimport type {TimelineEvent} from '../../../types/timeline.js';\nimport {idOf, sourceOf} from './identity.js';\nimport {now} from './clock.js';\n\ntype EmitFn = (event: TimelineEvent) => void;\ntype RecordingFn = () => boolean;\ntype LayerEnabledFn = () => boolean;\n\n/** Minimal shape of the lit-debug event detail we care about. */\ninterface LitDebugDetail {\n kind: string;\n id?: number;\n template?: unknown;\n instance?: unknown;\n /** Render options passed to lit-html's `render()`; `host` is the element. */\n options?: {host?: unknown};\n}\n\n/**\n * Builds the element-identity `meta` for a render event from the render\n * `host` (the LitElement whose `render()` produced these debug events).\n * Uses the same id/source maps as the lifecycle layer so an element keeps one\n * stable id across both layers. Returns undefined for host-less renders\n * (e.g. a bare lit-html `render()` call not driven by a LitElement).\n */\nconst hostMeta = (\n host: unknown\n): NonNullable<TimelineEvent['meta']> | undefined => {\n if (host === null || typeof host !== 'object') return undefined;\n return {\n elementId: idOf(host),\n tagName: (host as Element).localName ?? 'unknown',\n source: sourceOf(host),\n };\n};\n\ntype LitDebugEvent = CustomEvent<LitDebugDetail>;\n\nlet removeListener: (() => void) | null = null;\n\nconst onLitDebug = (\n e: Event,\n emit: EmitFn,\n recording: RecordingFn,\n layerEnabled: LayerEnabledFn\n): void => {\n if (!recording() || !layerEnabled()) return;\n\n const detail = (e as LitDebugEvent).detail;\n if (!detail?.kind) return;\n\n const time = now();\n const {kind, id} = detail;\n\n switch (kind) {\n case 'begin render': {\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:start',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n case 'end render': {\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:end',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n // `template prep` fires once per *unique* template, the first time it's\n // compiled — low volume, useful as a \"new template\" marker.\n case 'template prep':\n emit({\n layerId: 'lit-render',\n time,\n title: kind,\n data: {kind, id},\n });\n break;\n\n // `template updating` / `template instantiated` / `…and updated` fire once\n // per template-bound ChildPart on *every* render — extremely high volume\n // (a ticking clock or animation floods the layer). The begin/end render\n // pair above already captures each render as a grouped duration, so these\n // add noise without signal. Skip them; re-expose behind a \"verbose\" toggle\n // if per-part detail is ever needed. Same rationale for commit * / set part.\n default:\n break;\n }\n};\n\n/**\n * Install the lit-debug render layer.\n * Idempotent — calling again when already installed is a no-op.\n */\nexport const installRenderLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n layerEnabled: LayerEnabledFn\n): void => {\n if (removeListener !== null) return;\n\n // The listener is cheap and always attached; the per-render cost lives in the\n // `emitLitDebugLogEvents` flag, which the caller toggles via\n // `setRenderDebugEnabled` only while actively capturing.\n const handler = (e: Event) => onLitDebug(e, emit, recording, layerEnabled);\n window.addEventListener('lit-debug', handler);\n removeListener = () => window.removeEventListener('lit-debug', handler);\n};\n\n/**\n * Toggle Lit's debug event system. Enabling makes lit-html dispatch a\n * CustomEvent on every render (dev-only; no-op in prod builds), so the caller\n * keeps it off unless the render layer is actively recording.\n */\nexport const setRenderDebugEnabled = (enabled: boolean): void => {\n (globalThis as {emitLitDebugLogEvents?: boolean}).emitLitDebugLogEvents =\n enabled;\n};\n\n/** Remove the listener and clear the Lit debug flag. */\nexport const uninstallRenderLayer = (): void => {\n removeListener?.();\n removeListener = null;\n setRenderDebugEnabled(false);\n};\n"]}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * lit-render timeline layers — listen to the built-in lit-debug CustomEvents\n * instead of patching prototypes, so they're zero-cost when the Lit debug\n * flag is off and perfectly accurate for the render layers.\n *\n * `globalThis.emitLitDebugLogEvents = true` gates the events, and lit-html\n * dispatches a CustomEvent per render whenever it's set — a real per-render\n * cost. So the caller drives the flag via {@link setRenderDebugEnabled} from\n * `recording × (lit-render OR lit-render-verbose enabled)` rather than\n * leaving it on for the whole session.\n * The events are tagged `*Unstable` in the Lit source; we tolerate missing\n * `kind` values gracefully.\n *\n * begin render / end render share a numeric `id` → we use it as groupId so\n * the panel can show a duration bar for each render call.\n *\n * `template updating` / `template instantiated[ and updated]` / `set part` /\n * `commit *` fire once per template-bound part on *every* render — extremely\n * high volume (a ticking clock or animation floods the layer). They're\n * emitted on the separate opt-in `lit-render-verbose` layer rather than\n * `lit-render`, so the common case (the begin/end render duration bar) stays\n * quiet by default.\n */\n\nimport type {TimelineEvent} from '../../../types/timeline.js';\nimport {idOf, sourceOf} from './identity.js';\nimport {now} from './clock.js';\n\ntype EmitFn = (event: TimelineEvent) => void;\ntype RecordingFn = () => boolean;\ntype LayerEnabledFn = () => boolean;\n\n/**\n * Minimal shape of the lit-debug event detail we care about. Broader than any\n * single `kind` needs — see lit-html's `LitUnstable.DebugLog.Entry` union in\n * `packages/lit-html/src/lit-html.ts` for the exact per-kind shapes; fields\n * below are the ones this layer reads across all of them.\n */\ninterface LitDebugDetail {\n kind: string;\n id?: number;\n template?: unknown;\n instance?: unknown;\n /** Render options passed to lit-html's `render()`; `host` is the element. */\n options?: {host?: unknown};\n /** `template updating` / `template instantiated[ and updated]`. */\n values?: unknown[];\n /** `set part` / most `commit *` kinds. */\n value?: unknown;\n /**\n * `set part` only. Unlike every other kind, `set part` carries no\n * top-level `options` — the host lives on the `Part` instance itself\n * (`ChildPart` / `AttributePart` / `EventPart` / `ElementPart` all expose a\n * public `options: RenderOptions | undefined`), so the host is derived via\n * {@link partHost} instead of `options?.host` directly.\n */\n part?: {options?: {host?: unknown}};\n /** `set part`. */\n valueIndex?: number;\n /** `commit attribute` / `commit property` / `commit boolean attribute` /\n * `commit event listener`. */\n name?: string;\n /** `commit event listener`. */\n addListener?: boolean;\n removeListener?: boolean;\n}\n\n/**\n * Builds the element-identity `meta` for a render event from the render\n * `host` (the LitElement whose `render()` produced these debug events).\n * Uses the same id/source maps as the lifecycle layer so an element keeps one\n * stable id across both layers. Returns undefined for host-less renders\n * (e.g. a bare lit-html `render()` call not driven by a LitElement).\n */\nconst hostMeta = (\n host: unknown\n): NonNullable<TimelineEvent['meta']> | undefined => {\n if (host === null || typeof host !== 'object') return undefined;\n return {\n elementId: idOf(host),\n tagName: (host as Element).localName ?? 'unknown',\n source: sourceOf(host),\n };\n};\n\n/** Reads the render `host` off a `Part` for the one kind (`set part`) whose\n * detail carries the part instead of the render `options` directly. */\nconst partHost = (part: LitDebugDetail['part']): unknown => part?.options?.host;\n\ntype LitDebugEvent = CustomEvent<LitDebugDetail>;\n\nlet removeListener: (() => void) | null = null;\n\n/**\n * Reduces an arbitrary lit-html binding value to a small JSON-serializable\n * summary for the verbose layer's `data` field. Never puts the value itself\n * in `data` — it may be a DOM Node, a TemplateResult, a function, or hold a\n * reference back to the host element, none of which survive (or belong in) a\n * structured-clone over the HMR channel.\n */\nconst describeValue = (value: unknown): string => {\n if (value === null) return 'null';\n if (value === undefined) return 'undefined';\n if (typeof value === 'string') {\n return value.length > 40\n ? `string:\"${value.slice(0, 40)}…\"`\n : `string:\"${value}\"`;\n }\n if (typeof value === 'number') return `number:${value}`;\n if (typeof value === 'boolean') return `boolean:${value}`;\n if (typeof value === 'function') {\n return `function:${value.name || 'anonymous'}`;\n }\n // lit's sentinels (`nothing`, `noChange`) are symbols.\n if (typeof value === 'symbol') return `symbol:${value.description ?? ''}`;\n if (Array.isArray(value)) return `array(${value.length})`;\n if (typeof value === 'object' && '_$litType$' in value) return 'template';\n if (typeof Node !== 'undefined' && value instanceof Node) {\n const tag = (value as Partial<Element>).tagName?.toLowerCase();\n return tag ? `node:<${tag}>` : `node:#${value.nodeType}`;\n }\n const ctor = (value as {constructor?: {name?: string}})?.constructor?.name;\n return `object:${ctor ?? 'Object'}`;\n};\n\n/** Summarizes each entry of a template-instance's `values` array. */\nconst describeValues = (values: unknown[] | undefined): string[] | undefined =>\n values?.map(describeValue);\n\nconst onLitDebug = (\n e: Event,\n emit: EmitFn,\n recording: RecordingFn,\n renderEnabled: LayerEnabledFn,\n verboseEnabled: LayerEnabledFn\n): void => {\n if (!recording() || (!renderEnabled() && !verboseEnabled())) return;\n\n const detail = (e as LitDebugEvent).detail;\n if (!detail?.kind) return;\n\n const time = now();\n const {kind, id} = detail;\n\n switch (kind) {\n case 'begin render': {\n if (!renderEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:start',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n case 'end render': {\n if (!renderEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:end',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n // `template prep` fires once per *unique* template, the first time it's\n // compiled — low volume, useful as a \"new template\" marker.\n case 'template prep':\n if (!renderEnabled()) break;\n emit({\n layerId: 'lit-render',\n time,\n title: kind,\n data: {kind, id},\n });\n break;\n\n // The events below fire once per template-bound part on *every* render —\n // extremely high volume (a ticking clock or animation floods the layer).\n // The begin/end render pair above already captures each render as a\n // grouped duration, so these live on the separate opt-in\n // `lit-render-verbose` layer instead of adding noise to `lit-render`.\n case 'template updating':\n case 'template instantiated':\n case 'template instantiated and updated': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind, values: describeValues(detail.values)},\n meta,\n });\n break;\n }\n\n case 'set part': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(partHost(detail.part));\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {\n kind,\n valueIndex: detail.valueIndex,\n value: describeValue(detail.value),\n },\n meta,\n });\n break;\n }\n\n case 'commit nothing to child': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind},\n meta,\n });\n break;\n }\n\n case 'commit text':\n case 'commit node':\n case 'commit to element binding': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind, value: describeValue(detail.value)},\n meta,\n });\n break;\n }\n\n case 'commit attribute':\n case 'commit property':\n case 'commit boolean attribute': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind, name: detail.name, value: describeValue(detail.value)},\n meta,\n });\n break;\n }\n\n case 'commit event listener': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {\n kind,\n name: detail.name,\n addListener: detail.addListener,\n removeListener: detail.removeListener,\n },\n meta,\n });\n break;\n }\n\n // Unknown or future `*Unstable` kind — ignore rather than guess a shape.\n default:\n break;\n }\n};\n\n/**\n * Install the lit-debug render layers (`lit-render` and the opt-in\n * `lit-render-verbose`).\n * Idempotent — calling again when already installed is a no-op.\n */\nexport const installRenderLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n renderEnabled: LayerEnabledFn,\n verboseEnabled: LayerEnabledFn\n): void => {\n if (removeListener !== null) return;\n\n // The listener is cheap and always attached; the per-render cost lives in the\n // `emitLitDebugLogEvents` flag, which the caller toggles via\n // `setRenderDebugEnabled` only while actively capturing.\n const handler = (e: Event) =>\n onLitDebug(e, emit, recording, renderEnabled, verboseEnabled);\n window.addEventListener('lit-debug', handler);\n removeListener = () => window.removeEventListener('lit-debug', handler);\n};\n\n/**\n * Toggle Lit's debug event system. Enabling makes lit-html dispatch a\n * CustomEvent on every render (dev-only; no-op in prod builds), so the caller\n * keeps it off unless the render layer is actively recording.\n */\nexport const setRenderDebugEnabled = (enabled: boolean): void => {\n (globalThis as {emitLitDebugLogEvents?: boolean}).emitLitDebugLogEvents =\n enabled;\n};\n\n/** Remove the listener and clear the Lit debug flag. */\nexport const uninstallRenderLayer = (): void => {\n removeListener?.();\n removeListener = null;\n setRenderDebugEnabled(false);\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oddsquad/vite-plugin-lit",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Vite plugin providing true HMR for Lit components, plus CSS helpers and a DevTools panel",
5
5
  "license": "BSD-3-Clause",
6
6
  "author": "Oddsquad (based on @lit-labs/vite-hmr by Google LLC)",
@@ -77,6 +77,7 @@
77
77
  "@types/node": "^26.6.1",
78
78
  "@vitejs/devtools-kit": "0.7.5",
79
79
  "cac": "7.0.0",
80
+ "git-cliff": "^2.13.1",
80
81
  "lightningcss": "^1.33.0",
81
82
  "lit": "^3.3.3",
82
83
  "playwright-core": "^1.63.0",
@@ -107,10 +108,12 @@
107
108
  "test": "pnpm run test:unit && pnpm run test:e2e",
108
109
  "test:unit": "node scripts/check-client-types.mjs && vp test run --project unit",
109
110
  "test:e2e": "pnpm run build && vp test run --project e2e",
111
+ "changelog": "git-cliff --unreleased",
110
112
  "bench": "node bench/run.mjs",
111
113
  "bench:serve": "node bench/run.mjs --serve",
112
114
  "docs:dev": "pnpm --filter ./docs dev",
113
115
  "docs:build": "pnpm --filter ./docs build",
116
+ "docs:shots": "pnpm run build && node scripts/docs-shots.mjs",
114
117
  "format": "vp fmt \"**/*.{cjs,html,js,json,md,mdx,ts,yaml}\"",
115
118
  "format:check": "vp fmt \"**/*.{cjs,html,js,json,md,mdx,ts,yaml}\" --check",
116
119
  "build:panel": "vp build src/panel"