@oddsquad/vite-plugin-lit 0.6.1 → 0.8.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/CHANGELOG.md +68 -0
- package/LICENSE +1 -1
- package/README.md +40 -17
- package/bin.mjs +89 -13
- package/client.d.ts +0 -6
- package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-F2EfZsFX.js → browser-agent-rpc-BXhoSh1z-ybEeG-x9.js} +2 -2
- package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-F2EfZsFX.js.map → browser-agent-rpc-BXhoSh1z-ybEeG-x9.js.map} +1 -1
- package/dist/client/assets/{index-B2HYO7lk.js → index-CgkhETVR.js} +22 -145
- package/dist/client/assets/index-CgkhETVR.js.map +1 -0
- package/dist/client/index.html +1 -1
- package/dist/standalone/lit-devtools.js +6717 -0
- package/index.d.ts +0 -5
- package/index.d.ts.map +1 -1
- package/index.js +1 -5
- package/index.js.map +1 -1
- package/lib/color-scheme.d.ts +0 -5
- package/lib/color-scheme.d.ts.map +1 -1
- package/lib/color-scheme.js +0 -5
- package/lib/color-scheme.js.map +1 -1
- package/lib/confine.d.ts +0 -5
- package/lib/confine.d.ts.map +1 -1
- package/lib/confine.js +0 -5
- package/lib/confine.js.map +1 -1
- package/lib/devframe/allowed-origins.d.ts +21 -0
- package/lib/devframe/allowed-origins.d.ts.map +1 -0
- package/lib/devframe/allowed-origins.js +58 -0
- package/lib/devframe/allowed-origins.js.map +1 -0
- package/lib/devframe/definition.d.ts +7 -3
- package/lib/devframe/definition.d.ts.map +1 -1
- package/lib/devframe/definition.js +1 -6
- package/lib/devframe/definition.js.map +1 -1
- package/lib/devframe/icon.d.ts +0 -5
- package/lib/devframe/icon.d.ts.map +1 -1
- package/lib/devframe/icon.js +0 -5
- package/lib/devframe/icon.js.map +1 -1
- package/lib/devframe/launch-editor.d.ts +0 -5
- package/lib/devframe/launch-editor.d.ts.map +1 -1
- package/lib/devframe/launch-editor.js +0 -5
- package/lib/devframe/launch-editor.js.map +1 -1
- package/lib/devframe/paths.d.ts +8 -3
- package/lib/devframe/paths.d.ts.map +1 -1
- package/lib/devframe/paths.js +0 -5
- package/lib/devframe/paths.js.map +1 -1
- package/lib/devframe/protocol.d.ts +6 -3
- package/lib/devframe/protocol.d.ts.map +1 -1
- package/lib/devframe/protocol.js +0 -5
- package/lib/devframe/protocol.js.map +1 -1
- package/lib/devframe/rpc-source.d.ts +15 -3
- package/lib/devframe/rpc-source.d.ts.map +1 -1
- package/lib/devframe/rpc-source.js +0 -5
- package/lib/devframe/rpc-source.js.map +1 -1
- package/lib/devframe/source.d.ts +0 -5
- package/lib/devframe/source.d.ts.map +1 -1
- package/lib/devframe/source.js +7 -3
- package/lib/devframe/source.js.map +1 -1
- package/lib/devframe/vite.d.ts +0 -5
- package/lib/devframe/vite.d.ts.map +1 -1
- package/lib/devframe/vite.js +16 -3
- package/lib/devframe/vite.js.map +1 -1
- package/lib/http.d.ts +0 -5
- package/lib/http.d.ts.map +1 -1
- package/lib/http.js +0 -5
- package/lib/http.js.map +1 -1
- package/lib/icons.d.ts +0 -5
- package/lib/icons.d.ts.map +1 -1
- package/lib/icons.js +0 -5
- package/lib/icons.js.map +1 -1
- package/lib/options.d.ts +26 -5
- package/lib/options.d.ts.map +1 -1
- package/lib/options.js +19 -5
- package/lib/options.js.map +1 -1
- package/lib/override-baselines.d.ts +0 -5
- package/lib/override-baselines.d.ts.map +1 -1
- package/lib/override-baselines.js +0 -5
- package/lib/override-baselines.js.map +1 -1
- package/lib/plugin.d.ts +0 -5
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +3 -5
- package/lib/plugin.js.map +1 -1
- package/lib/plugins/css-literals.d.ts +0 -5
- package/lib/plugins/css-literals.d.ts.map +1 -1
- package/lib/plugins/css-literals.js +0 -5
- package/lib/plugins/css-literals.js.map +1 -1
- package/lib/plugins/css-queries.d.ts +0 -5
- package/lib/plugins/css-queries.d.ts.map +1 -1
- package/lib/plugins/css-queries.js +0 -5
- package/lib/plugins/css-queries.js.map +1 -1
- package/lib/plugins/open-in-editor.d.ts +0 -5
- package/lib/plugins/open-in-editor.d.ts.map +1 -1
- package/lib/plugins/open-in-editor.js +0 -5
- package/lib/plugins/open-in-editor.js.map +1 -1
- package/lib/plugins/private-fields.d.ts +22 -0
- package/lib/plugins/private-fields.d.ts.map +1 -0
- package/lib/plugins/private-fields.js +254 -0
- package/lib/plugins/private-fields.js.map +1 -0
- package/lib/plugins/shared.d.ts +0 -5
- package/lib/plugins/shared.d.ts.map +1 -1
- package/lib/plugins/shared.js +0 -5
- package/lib/plugins/shared.js.map +1 -1
- package/lib/plugins/timeline-virtual.d.ts +0 -5
- package/lib/plugins/timeline-virtual.d.ts.map +1 -1
- package/lib/plugins/timeline-virtual.js +0 -5
- package/lib/plugins/timeline-virtual.js.map +1 -1
- package/lib/runtime/child-state.d.ts +95 -0
- package/lib/runtime/child-state.d.ts.map +1 -0
- package/lib/runtime/child-state.js +461 -0
- package/lib/runtime/child-state.js.map +1 -0
- package/lib/runtime/css.d.ts +14 -3
- package/lib/runtime/css.d.ts.map +1 -1
- package/lib/runtime/css.js +3 -5
- package/lib/runtime/css.js.map +1 -1
- package/lib/runtime/edge-panel.d.ts +8 -3
- package/lib/runtime/edge-panel.d.ts.map +1 -1
- package/lib/runtime/edge-panel.js +0 -5
- package/lib/runtime/edge-panel.js.map +1 -1
- package/lib/runtime/fonts.d.ts +0 -5
- package/lib/runtime/fonts.d.ts.map +1 -1
- package/lib/runtime/fonts.js +0 -5
- package/lib/runtime/fonts.js.map +1 -1
- package/lib/runtime/indicator.d.ts +3 -3
- package/lib/runtime/indicator.js +0 -5
- package/lib/runtime/indicator.js.map +1 -1
- package/lib/runtime/inspector/collect.d.ts +3 -3
- package/lib/runtime/inspector/collect.d.ts.map +1 -1
- package/lib/runtime/inspector/collect.js +0 -5
- package/lib/runtime/inspector/collect.js.map +1 -1
- package/lib/runtime/inspector/highlight.d.ts +10 -3
- package/lib/runtime/inspector/highlight.d.ts.map +1 -1
- package/lib/runtime/inspector/highlight.js +0 -5
- package/lib/runtime/inspector/highlight.js.map +1 -1
- package/lib/runtime/inspector/install.d.ts +6 -3
- package/lib/runtime/inspector/install.d.ts.map +1 -1
- package/lib/runtime/inspector/install.js +4 -6
- package/lib/runtime/inspector/install.js.map +1 -1
- package/lib/runtime/inspector/serialize.d.ts +4 -3
- package/lib/runtime/inspector/serialize.d.ts.map +1 -1
- package/lib/runtime/inspector/serialize.js +0 -5
- package/lib/runtime/inspector/serialize.js.map +1 -1
- package/lib/runtime/intern.d.ts +11 -3
- package/lib/runtime/intern.d.ts.map +1 -1
- package/lib/runtime/intern.js +11 -3
- package/lib/runtime/intern.js.map +1 -1
- package/lib/runtime/overrides.d.ts +3 -3
- package/lib/runtime/overrides.d.ts.map +1 -1
- package/lib/runtime/overrides.js +0 -5
- package/lib/runtime/overrides.js.map +1 -1
- package/lib/runtime/page-channel.d.ts +0 -5
- package/lib/runtime/page-channel.d.ts.map +1 -1
- package/lib/runtime/page-channel.js +13 -3
- package/lib/runtime/page-channel.js.map +1 -1
- package/lib/runtime/patch.d.ts +22 -3
- package/lib/runtime/patch.d.ts.map +1 -1
- package/lib/runtime/patch.js +22 -6
- package/lib/runtime/patch.js.map +1 -1
- package/lib/runtime/rpc-transport.d.ts +21 -3
- package/lib/runtime/rpc-transport.d.ts.map +1 -1
- package/lib/runtime/rpc-transport.js +4 -5
- package/lib/runtime/rpc-transport.js.map +1 -1
- package/lib/runtime/source-meta.d.ts +0 -5
- package/lib/runtime/source-meta.d.ts.map +1 -1
- package/lib/runtime/source-meta.js +0 -5
- package/lib/runtime/source-meta.js.map +1 -1
- package/lib/runtime/source-overlay/editors.d.ts +0 -5
- package/lib/runtime/source-overlay/editors.d.ts.map +1 -1
- package/lib/runtime/source-overlay/editors.js +9 -9
- package/lib/runtime/source-overlay/editors.js.map +1 -1
- package/lib/runtime/source-overlay/mask-path.d.ts +0 -5
- package/lib/runtime/source-overlay/mask-path.d.ts.map +1 -1
- package/lib/runtime/source-overlay/mask-path.js +0 -5
- package/lib/runtime/source-overlay/mask-path.js.map +1 -1
- package/lib/runtime/source-overlay/overlay-element.d.ts +0 -5
- package/lib/runtime/source-overlay/overlay-element.d.ts.map +1 -1
- package/lib/runtime/source-overlay/overlay-element.js +0 -5
- package/lib/runtime/source-overlay/overlay-element.js.map +1 -1
- package/lib/runtime/source-overlay/source-host.d.ts +0 -5
- package/lib/runtime/source-overlay/source-host.d.ts.map +1 -1
- package/lib/runtime/source-overlay/source-host.js +0 -5
- package/lib/runtime/source-overlay/source-host.js.map +1 -1
- package/lib/runtime/source-overlay/template.d.ts +0 -5
- package/lib/runtime/source-overlay/template.d.ts.map +1 -1
- package/lib/runtime/source-overlay/template.js +0 -5
- package/lib/runtime/source-overlay/template.js.map +1 -1
- package/lib/runtime/source-overlay.d.ts +0 -5
- package/lib/runtime/source-overlay.d.ts.map +1 -1
- package/lib/runtime/source-overlay.js +0 -5
- package/lib/runtime/source-overlay.js.map +1 -1
- package/lib/runtime/standalone.d.ts +22 -0
- package/lib/runtime/standalone.d.ts.map +1 -0
- package/lib/runtime/standalone.js +45 -0
- package/lib/runtime/standalone.js.map +1 -0
- package/lib/runtime/timeline/chrome-tracks.d.ts +0 -5
- package/lib/runtime/timeline/chrome-tracks.d.ts.map +1 -1
- package/lib/runtime/timeline/chrome-tracks.js +5 -3
- package/lib/runtime/timeline/chrome-tracks.js.map +1 -1
- package/lib/runtime/timeline/clock.d.ts +7 -3
- package/lib/runtime/timeline/clock.d.ts.map +1 -1
- package/lib/runtime/timeline/clock.js +0 -5
- package/lib/runtime/timeline/clock.js.map +1 -1
- package/lib/runtime/timeline/flash.d.ts +0 -5
- package/lib/runtime/timeline/flash.d.ts.map +1 -1
- package/lib/runtime/timeline/flash.js +15 -3
- package/lib/runtime/timeline/flash.js.map +1 -1
- package/lib/runtime/timeline/identity.d.ts +0 -5
- package/lib/runtime/timeline/identity.d.ts.map +1 -1
- package/lib/runtime/timeline/identity.js +9 -3
- package/lib/runtime/timeline/identity.js.map +1 -1
- package/lib/runtime/timeline/input.d.ts +0 -5
- package/lib/runtime/timeline/input.d.ts.map +1 -1
- package/lib/runtime/timeline/input.js +2 -3
- package/lib/runtime/timeline/input.js.map +1 -1
- package/lib/runtime/timeline/install.d.ts +11 -3
- package/lib/runtime/timeline/install.d.ts.map +1 -1
- package/lib/runtime/timeline/install.js +4 -7
- package/lib/runtime/timeline/install.js.map +1 -1
- package/lib/runtime/timeline/lifecycle.d.ts +13 -3
- package/lib/runtime/timeline/lifecycle.d.ts.map +1 -1
- package/lib/runtime/timeline/lifecycle.js +5 -6
- package/lib/runtime/timeline/lifecycle.js.map +1 -1
- package/lib/runtime/timeline/public-api.d.ts +6 -3
- package/lib/runtime/timeline/public-api.d.ts.map +1 -1
- package/lib/runtime/timeline/public-api.js +0 -5
- package/lib/runtime/timeline/public-api.js.map +1 -1
- package/lib/runtime/timeline/render.d.ts +0 -5
- package/lib/runtime/timeline/render.d.ts.map +1 -1
- package/lib/runtime/timeline/render.js +21 -3
- package/lib/runtime/timeline/render.js.map +1 -1
- package/lib/runtime/timeline/transport.d.ts +0 -5
- package/lib/runtime/timeline/transport.d.ts.map +1 -1
- package/lib/runtime/timeline/transport.js +10 -3
- package/lib/runtime/timeline/transport.js.map +1 -1
- package/lib/segmented-tabs.d.ts +0 -5
- package/lib/segmented-tabs.d.ts.map +1 -1
- package/lib/segmented-tabs.js +0 -5
- package/lib/segmented-tabs.js.map +1 -1
- package/lib/snapshot.d.ts +11 -3
- package/lib/snapshot.d.ts.map +1 -1
- package/lib/snapshot.js +0 -5
- package/lib/snapshot.js.map +1 -1
- package/lib/source-meta.d.ts +0 -5
- package/lib/source-meta.d.ts.map +1 -1
- package/lib/source-meta.js +0 -5
- package/lib/source-meta.js.map +1 -1
- package/lib/timeline/derive.d.ts +0 -5
- package/lib/timeline/derive.d.ts.map +1 -1
- package/lib/timeline/derive.js +22 -3
- package/lib/timeline/derive.js.map +1 -1
- package/lib/timeline/filter.d.ts +0 -5
- package/lib/timeline/filter.d.ts.map +1 -1
- package/lib/timeline/filter.js +6 -3
- package/lib/timeline/filter.js.map +1 -1
- package/lib/timeline/tracks.d.ts +0 -5
- package/lib/timeline/tracks.d.ts.map +1 -1
- package/lib/timeline/tracks.js +12 -3
- package/lib/timeline/tracks.js.map +1 -1
- package/lib/tokens.d.ts +0 -5
- package/lib/tokens.d.ts.map +1 -1
- package/lib/tokens.js +0 -5
- package/lib/tokens.js.map +1 -1
- package/lib/transform.d.ts +0 -5
- package/lib/transform.d.ts.map +1 -1
- package/lib/transform.js +0 -5
- package/lib/transform.js.map +1 -1
- package/lib/types.d.ts +10 -5
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +0 -5
- package/lib/types.js.map +1 -1
- package/lib/wrap-table.d.ts +0 -5
- package/lib/wrap-table.d.ts.map +1 -1
- package/lib/wrap-table.js +12 -3
- package/lib/wrap-table.js.map +1 -1
- package/package.json +14 -10
- package/types/hmr-incompatibility.d.ts +0 -5
- package/types/hmr-incompatibility.d.ts.map +1 -1
- package/types/hmr-incompatibility.js +13 -3
- package/types/hmr-incompatibility.js.map +1 -1
- package/types/in-page.d.ts +0 -5
- package/types/in-page.d.ts.map +1 -1
- package/types/in-page.js +0 -5
- package/types/in-page.js.map +1 -1
- package/types/inspector.d.ts +0 -5
- package/types/inspector.d.ts.map +1 -1
- package/types/inspector.js +13 -3
- package/types/inspector.js.map +1 -1
- package/types/snapshot.d.ts +0 -5
- package/types/snapshot.d.ts.map +1 -1
- package/types/snapshot.js +12 -3
- package/types/snapshot.js.map +1 -1
- package/types/timeline.d.ts +4 -6
- package/types/timeline.d.ts.map +1 -1
- package/types/timeline.js +0 -5
- package/types/timeline.js.map +1 -1
- package/dist/client/assets/index-B2HYO7lk.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flash.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/flash.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"flash.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/flash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,gBAAgB,CAAC;AAoB/C;;;GAGG;AACH,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,MAKzC,CAAC;AAwIF,uEAAuE;AACvE,eAAO,MAAM,eAAe,OAAQ,OAAO,KAAG,IAI7C,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,YAAY,OAAQ,OAAO,KAAG,IAE1C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,UAMzB,CAAC"}
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* "Flash on update": a short, non-interactive outline over every Lit element
|
|
3
|
+
* that just finished an update cycle, so re-render churn is visible on the
|
|
4
|
+
* page itself rather than only in the Updates tab.
|
|
5
|
+
*
|
|
6
|
+
* Sibling of the inspector's hover outline, not a reuse of it — many elements
|
|
7
|
+
* can flash in the same frame, and each box has its own fade. Same drawing
|
|
8
|
+
* rules though: one `position: fixed` layer with `pointer-events: none` so the
|
|
9
|
+
* page stays fully interactive underneath.
|
|
10
|
+
*
|
|
11
|
+
* Fed by the lifecycle layer's update hook (see `setUpdateHook` in
|
|
12
|
+
* `lifecycle.ts`), which fires whether or not the timeline is recording. Rects
|
|
13
|
+
* are measured once per animation frame for every element that updated in it,
|
|
14
|
+
* so a tick that updates a hundred components costs one layout, not a hundred.
|
|
15
|
+
*
|
|
16
|
+
* Off by default; the panel turns it on through the settings override.
|
|
5
17
|
*/
|
|
6
18
|
/** Fade length; long enough to catch, short enough not to smear. */
|
|
7
19
|
const DURATION_MS = 450;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flash.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/flash.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 * \"Flash on update\": a short, non-interactive outline over every Lit element\n * that just finished an update cycle, so re-render churn is visible on the\n * page itself rather than only in the Updates tab.\n *\n * Sibling of the inspector's hover outline, not a reuse of it — many elements\n * can flash in the same frame, and each box has its own fade. Same drawing\n * rules though: one `position: fixed` layer with `pointer-events: none` so the\n * page stays fully interactive underneath.\n *\n * Fed by the lifecycle layer's update hook (see `setUpdateHook` in\n * `lifecycle.ts`), which fires whether or not the timeline is recording. Rects\n * are measured once per animation frame for every element that updated in it,\n * so a tick that updates a hundred components costs one layout, not a hundred.\n *\n * Off by default; the panel turns it on through the settings override.\n */\n\nimport type {UpdateHook} from './lifecycle.js';\n\n/** Fade length; long enough to catch, short enough not to smear. */\nconst DURATION_MS = 450;\n\n/** How far back the ramp counts updates for one element. */\nconst RAMP_WINDOW_MS = 1000;\n\n/**\n * Outline/fill colours by heat level. Level 0 is also the flat colour used\n * when the ramp is off. Deliberately not the selection blue, so a hovered\n * element and a flashing one read differently.\n */\nconst COLORS: readonly string[] = [\n 'hsl(158 74% 53%)', // calm — one update\n '#f4bf4f', // warm\n '#f4844f', // hot\n '#ef4444', // on fire\n];\n\n/**\n * Heat level for `count` updates of one element inside the ramp window.\n * Exported for the unit test; the thresholds are the whole behaviour.\n */\nexport const rampLevel = (count: number): number => {\n if (count >= 8) return 3;\n if (count >= 4) return 2;\n if (count >= 2) return 1;\n return 0;\n};\n\nlet enabled = false;\nlet ramp = false;\n\nlet layer: HTMLElement | null = null;\n\n/** Elements that updated since the last flush, with \"was a first update\". */\nconst pending = new Map<Element, boolean>();\nlet frame: number | null = null;\n\n/** Boxes currently on screen, so a re-flash restarts instead of stacking. */\nconst active = new Map<Element, {box: HTMLElement; anim: Animation}>();\n\n/** Recent update timestamps per element, for the ramp. */\nconst history = new WeakMap<Element, number[]>();\n\nconst ensureLayer = (): HTMLElement => {\n if (layer === null) {\n layer = document.createElement('div');\n layer.setAttribute('data-lit-devtools-flash-layer', '');\n Object.assign(layer.style, {\n position: 'fixed',\n inset: '0',\n zIndex: '2147483645',\n pointerEvents: 'none',\n overflow: 'hidden',\n } satisfies Partial<CSSStyleDeclaration>);\n document.body.append(layer);\n }\n return layer;\n};\n\n/** The runtime's own UI (indicator, panels) must not flash itself. */\nconst isDevtoolsElement = (el: Element): boolean =>\n el.localName.startsWith('lit-devtools-');\n\nconst recordUpdate = (el: Element, at: number): number => {\n let times = history.get(el);\n if (times === undefined) {\n times = [];\n history.set(el, times);\n }\n times.push(at);\n const cutoff = at - RAMP_WINDOW_MS;\n while (times.length > 0 && times[0]! < cutoff) times.shift();\n return times.length;\n};\n\nconst removeBox = (el: Element, anim: Animation): void => {\n const entry = active.get(el);\n // A newer flash may have replaced this one; only the owner cleans up.\n if (entry === undefined || entry.anim !== anim) return;\n entry.box.remove();\n active.delete(el);\n};\n\nconst paint = (\n el: Element,\n rect: DOMRect,\n level: number,\n first: boolean\n): void => {\n const color = COLORS[level] ?? COLORS[0]!;\n let entry = active.get(el);\n if (entry === undefined) {\n const box = document.createElement('div');\n box.setAttribute('data-lit-devtools-flash', '');\n Object.assign(box.style, {\n position: 'absolute',\n boxSizing: 'border-box',\n borderRadius: '2px',\n willChange: 'opacity',\n } satisfies Partial<CSSStyleDeclaration>);\n ensureLayer().append(box);\n entry = {box, anim: box.animate([], {duration: 0})};\n active.set(el, entry);\n } else {\n entry.anim.cancel();\n }\n const {box} = entry;\n box.setAttribute('data-level', String(level));\n Object.assign(box.style, {\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n outline: `2px solid ${color}`,\n outlineOffset: '-1px',\n background: color,\n } satisfies Partial<CSSStyleDeclaration>);\n // Mounts flash fainter: a page filling in is not the churn we're hunting.\n const peak = first ? 0.35 : 0.75;\n const anim = box.animate(\n [{opacity: peak}, {opacity: peak, offset: 0.3}, {opacity: 0}],\n {duration: DURATION_MS, easing: 'ease-out', fill: 'forwards'}\n );\n entry.anim = anim;\n anim.onfinish = () => removeBox(el, anim);\n anim.oncancel = () => {\n /* replaced by a newer flash; that one owns cleanup */\n };\n};\n\nconst flush = (): void => {\n frame = null;\n if (!enabled) {\n pending.clear();\n return;\n }\n const now = performance.now();\n for (const [el, first] of pending) {\n if (!el.isConnected) continue;\n const rect = el.getBoundingClientRect();\n // `display: contents` hosts, hidden elements, and off-DOM work have no\n // box worth drawing.\n if (rect.width === 0 || rect.height === 0) continue;\n const count = recordUpdate(el, now);\n paint(el, rect, ramp ? rampLevel(count) : 0, first);\n }\n pending.clear();\n};\n\nconst clearAll = (): void => {\n pending.clear();\n if (frame !== null) {\n cancelAnimationFrame(frame);\n frame = null;\n }\n for (const {box, anim} of active.values()) {\n anim.cancel();\n box.remove();\n }\n active.clear();\n};\n\n/** Turn the overlay on or off; off also wipes whatever is mid-fade. */\nexport const setFlashEnabled = (on: boolean): void => {\n if (enabled === on) return;\n enabled = on;\n if (!on) clearAll();\n};\n\n/** Colour by update frequency instead of the flat colour. */\nexport const setFlashRamp = (on: boolean): void => {\n ramp = on;\n};\n\n/**\n * The lifecycle layer's update hook. Cheap on the hot path: one Map write and,\n * at most, one `requestAnimationFrame` per frame; all measuring happens in\n * the flush.\n */\nexport const flashUpdate: UpdateHook = (el, first) => {\n if (!enabled || isDevtoolsElement(el)) return;\n // Several updates of one element in the same frame collapse into one box;\n // it only counts as a mount if every one of them was the first update.\n pending.set(el, (pending.get(el) ?? true) && first);\n if (frame === null) frame = requestAnimationFrame(flush);\n};\n"]}
|
|
1
|
+
{"version":3,"file":"flash.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/flash.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * \"Flash on update\": a short, non-interactive outline over every Lit element\n * that just finished an update cycle, so re-render churn is visible on the\n * page itself rather than only in the Updates tab.\n *\n * Sibling of the inspector's hover outline, not a reuse of it — many elements\n * can flash in the same frame, and each box has its own fade. Same drawing\n * rules though: one `position: fixed` layer with `pointer-events: none` so the\n * page stays fully interactive underneath.\n *\n * Fed by the lifecycle layer's update hook (see `setUpdateHook` in\n * `lifecycle.ts`), which fires whether or not the timeline is recording. Rects\n * are measured once per animation frame for every element that updated in it,\n * so a tick that updates a hundred components costs one layout, not a hundred.\n *\n * Off by default; the panel turns it on through the settings override.\n */\n\nimport type {UpdateHook} from './lifecycle.js';\n\n/** Fade length; long enough to catch, short enough not to smear. */\nconst DURATION_MS = 450;\n\n/** How far back the ramp counts updates for one element. */\nconst RAMP_WINDOW_MS = 1000;\n\n/**\n * Outline/fill colours by heat level. Level 0 is also the flat colour used\n * when the ramp is off. Deliberately not the selection blue, so a hovered\n * element and a flashing one read differently.\n */\nconst COLORS: readonly string[] = [\n 'hsl(158 74% 53%)', // calm — one update\n '#f4bf4f', // warm\n '#f4844f', // hot\n '#ef4444', // on fire\n];\n\n/**\n * Heat level for `count` updates of one element inside the ramp window.\n * Exported for the unit test; the thresholds are the whole behaviour.\n */\nexport const rampLevel = (count: number): number => {\n if (count >= 8) return 3;\n if (count >= 4) return 2;\n if (count >= 2) return 1;\n return 0;\n};\n\nlet enabled = false;\nlet ramp = false;\n\nlet layer: HTMLElement | null = null;\n\n/** Elements that updated since the last flush, with \"was a first update\". */\nconst pending = new Map<Element, boolean>();\nlet frame: number | null = null;\n\n/** Boxes currently on screen, so a re-flash restarts instead of stacking. */\nconst active = new Map<Element, {box: HTMLElement; anim: Animation}>();\n\n/** Recent update timestamps per element, for the ramp. */\nconst history = new WeakMap<Element, number[]>();\n\nconst ensureLayer = (): HTMLElement => {\n if (layer === null) {\n layer = document.createElement('div');\n layer.setAttribute('data-lit-devtools-flash-layer', '');\n Object.assign(layer.style, {\n position: 'fixed',\n inset: '0',\n zIndex: '2147483645',\n pointerEvents: 'none',\n overflow: 'hidden',\n } satisfies Partial<CSSStyleDeclaration>);\n document.body.append(layer);\n }\n return layer;\n};\n\n/** The runtime's own UI (indicator, panels) must not flash itself. */\nconst isDevtoolsElement = (el: Element): boolean =>\n el.localName.startsWith('lit-devtools-');\n\nconst recordUpdate = (el: Element, at: number): number => {\n let times = history.get(el);\n if (times === undefined) {\n times = [];\n history.set(el, times);\n }\n times.push(at);\n const cutoff = at - RAMP_WINDOW_MS;\n while (times.length > 0 && times[0]! < cutoff) times.shift();\n return times.length;\n};\n\nconst removeBox = (el: Element, anim: Animation): void => {\n const entry = active.get(el);\n // A newer flash may have replaced this one; only the owner cleans up.\n if (entry === undefined || entry.anim !== anim) return;\n entry.box.remove();\n active.delete(el);\n};\n\nconst paint = (\n el: Element,\n rect: DOMRect,\n level: number,\n first: boolean\n): void => {\n const color = COLORS[level] ?? COLORS[0]!;\n let entry = active.get(el);\n if (entry === undefined) {\n const box = document.createElement('div');\n box.setAttribute('data-lit-devtools-flash', '');\n Object.assign(box.style, {\n position: 'absolute',\n boxSizing: 'border-box',\n borderRadius: '2px',\n willChange: 'opacity',\n } satisfies Partial<CSSStyleDeclaration>);\n ensureLayer().append(box);\n entry = {box, anim: box.animate([], {duration: 0})};\n active.set(el, entry);\n } else {\n entry.anim.cancel();\n }\n const {box} = entry;\n box.setAttribute('data-level', String(level));\n Object.assign(box.style, {\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n outline: `2px solid ${color}`,\n outlineOffset: '-1px',\n background: color,\n } satisfies Partial<CSSStyleDeclaration>);\n // Mounts flash fainter: a page filling in is not the churn we're hunting.\n const peak = first ? 0.35 : 0.75;\n const anim = box.animate(\n [{opacity: peak}, {opacity: peak, offset: 0.3}, {opacity: 0}],\n {duration: DURATION_MS, easing: 'ease-out', fill: 'forwards'}\n );\n entry.anim = anim;\n anim.onfinish = () => removeBox(el, anim);\n anim.oncancel = () => {\n /* replaced by a newer flash; that one owns cleanup */\n };\n};\n\nconst flush = (): void => {\n frame = null;\n if (!enabled) {\n pending.clear();\n return;\n }\n const now = performance.now();\n for (const [el, first] of pending) {\n if (!el.isConnected) continue;\n const rect = el.getBoundingClientRect();\n // `display: contents` hosts, hidden elements, and off-DOM work have no\n // box worth drawing.\n if (rect.width === 0 || rect.height === 0) continue;\n const count = recordUpdate(el, now);\n paint(el, rect, ramp ? rampLevel(count) : 0, first);\n }\n pending.clear();\n};\n\nconst clearAll = (): void => {\n pending.clear();\n if (frame !== null) {\n cancelAnimationFrame(frame);\n frame = null;\n }\n for (const {box, anim} of active.values()) {\n anim.cancel();\n box.remove();\n }\n active.clear();\n};\n\n/** Turn the overlay on or off; off also wipes whatever is mid-fade. */\nexport const setFlashEnabled = (on: boolean): void => {\n if (enabled === on) return;\n enabled = on;\n if (!on) clearAll();\n};\n\n/** Colour by update frequency instead of the flat colour. */\nexport const setFlashRamp = (on: boolean): void => {\n ramp = on;\n};\n\n/**\n * The lifecycle layer's update hook. Cheap on the hot path: one Map write and,\n * at most, one `requestAnimationFrame` per frame; all measuring happens in\n * the flush.\n */\nexport const flashUpdate: UpdateHook = (el, first) => {\n if (!enabled || isDevtoolsElement(el)) return;\n // Several updates of one element in the same frame collapse into one box;\n // it only counts as a mount if every one of them was the first update.\n pending.set(el, (pending.get(el) ?? true) && first);\n if (frame === null) frame = requestAnimationFrame(flush);\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/identity.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AA8BD,0EAA0E;AAC1E,eAAO,MAAM,IAAI,OAAQ,MAAM,KAAG,MASjC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,OAAQ,MAAM,KAAG,OAAO,GAAG,SAOlD,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,QAAQ,OAAQ,MAAM,KAAG,aAAa,GAAG,SAQrD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,YAAa,OAAO,KAAG,MAAM,EAAE,GAAG,SAKzD,CAAC"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Stable per-instance id and source-meta lookup for the timeline.
|
|
3
|
+
*
|
|
4
|
+
* Assigns monotonic numeric ids to ReactiveElement instances via a WeakMap
|
|
5
|
+
* so we never mutate the elements themselves and ids survive HMR (same
|
|
6
|
+
* instance identity after in-place patching).
|
|
7
|
+
*
|
|
8
|
+
* Source metadata is read from the Symbol injected by the source-meta
|
|
9
|
+
* transform — the same one the source-overlay feature uses — so timeline
|
|
10
|
+
* events can deep-link to the component's definition file.
|
|
5
11
|
*/
|
|
6
12
|
const SOURCE_META_KEY = Symbol.for('@lit-labs/vite-plugin-lit#source');
|
|
7
13
|
/** WeakMap avoids retaining elements after disconnection + GC. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/identity.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;AAEvE,kEAAkE;AAClE,MAAM,GAAG,GAAG,IAAI,OAAO,EAAkB,CAAC;AAC1C,IAAI,MAAM,GAAG,CAAC,CAAC;AAEf;;;;GAIG;AACH,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,YAAY,GAChB,OAAO,oBAAoB,KAAK,UAAU;IACxC,CAAC,CAAC,IAAI,oBAAoB,CAAS,CAAC,EAAE,EAAE,EAAE;QACtC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC;IACJ,CAAC,CAAC,SAAS,CAAC;AAEhB,0EAA0E;AAC1E,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,EAAU,EAAU,EAAE;IACzC,IAAI,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrB,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,EAAE,GAAG,MAAM,EAAE,CAAC;QACd,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAChB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,YAAY,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAU,EAAuB,EAAE;IAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;IACjC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,EAAa,CAAC;AACvB,CAAC,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAU,EAA6B,EAAE;IAChE,MAAM,IAAI,GAAI,EAA8C,CAAC,WAAW,CAAC;IACzE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAEpB,CAAC;IACd,IAAI,IAAI,EAAE,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACnD,OAAO,EAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC,EAAC,CAAC;AAC3D,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAgB,EAAwB,EAAE;IACpE,IAAI,CAAC,CAAC,OAAO,YAAY,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAChD,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACnC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CACjD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * Stable per-instance id and source-meta lookup for the timeline.\n *\n * Assigns monotonic numeric ids to ReactiveElement instances via a WeakMap\n * so we never mutate the elements themselves and ids survive HMR (same\n * instance identity after in-place patching).\n *\n * Source metadata is read from the Symbol injected by the source-meta\n * transform — the same one the source-overlay feature uses — so timeline\n * events can deep-link to the component's definition file.\n */\n\nexport interface ElementSource {\n file: string;\n line: number;\n}\n\nconst SOURCE_META_KEY = Symbol.for('@lit-labs/vite-plugin-lit#source');\n\n/** WeakMap avoids retaining elements after disconnection + GC. */\nconst ids = new WeakMap<object, number>();\nlet nextId = 0;\n\n/**\n * Reverse map for {@link elementById}, so a panel request (which only carries\n * an id) can be resolved back to the live instance. WeakRef-valued so we never\n * keep an element alive past GC; dead entries are pruned on lookup.\n */\nconst byId = new Map<number, WeakRef<object>>();\n\n/**\n * Drops `byId` entries as their elements are garbage-collected. The `WeakRef`\n * already lets the element itself be reclaimed, but the Map slot (id + WeakRef\n * wrapper) would otherwise linger until the next `elementById(id)` lookup —\n * which only happens on a panel request for that specific id, so on a churning\n * page (a list re-rendering thousands of rows) dead entries accumulate for the\n * whole dev session. Guarded for environments without `FinalizationRegistry`.\n */\nconst byIdRegistry =\n typeof FinalizationRegistry === 'function'\n ? new FinalizationRegistry<number>((id) => {\n byId.delete(id);\n })\n : undefined;\n\n/** Returns (and memoises) a stable numeric id for an element instance. */\nexport const idOf = (el: object): number => {\n let id = ids.get(el);\n if (id === undefined) {\n id = nextId++;\n ids.set(el, id);\n byId.set(id, new WeakRef(el));\n byIdRegistry?.register(el, id);\n }\n return id;\n};\n\n/**\n * Resolves an id back to its element instance, or `undefined` if it was never\n * seen or has since been garbage-collected. Used by the inspector to act on the\n * id the panel sends (details, watch, highlight).\n */\nexport const elementById = (id: number): Element | undefined => {\n const el = byId.get(id)?.deref();\n if (el === undefined) {\n byId.delete(id);\n return undefined;\n }\n return el as Element;\n};\n\n/** Reads the file/line source metadata injected by the plugin transform. */\nexport const sourceOf = (el: object): ElementSource | undefined => {\n const ctor = (el as {constructor?: Record<symbol, unknown>}).constructor;\n if (ctor === undefined) return undefined;\n const meta = ctor[SOURCE_META_KEY] as\n | {filePath?: string; lineNumber?: number}\n | undefined;\n if (meta?.filePath === undefined) return undefined;\n return {file: meta.filePath, line: meta.lineNumber ?? 1};\n};\n\n/**\n * Extracts the changed property keys from a PropertyValues argument.\n * Returns undefined when `changed` is not a Map (e.g. for lifecycle hooks\n * that don't receive a changed-properties argument).\n */\nexport const changedKeys = (changed: unknown): string[] | undefined => {\n if (!(changed instanceof Map)) return undefined;\n return [...changed.keys()].map((k) =>\n typeof k === 'symbol' ? k.toString() : String(k)\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/input.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/input.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAG9D,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAC7C,KAAK,WAAW,GAAG,MAAM,OAAO,CAAC;AAyEjC,eAAO,MAAM,iBAAiB,SACtB,MAAM,aACD,WAAW,gBACR,MAAM,OAAO,KAC1B,IAWF,CAAC;AAEF,eAAO,MAAM,oBAAoB,SACzB,MAAM,aACD,WAAW,cACV,MAAM,OAAO,KACxB,IAWF,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
* Mouse and keyboard timeline layers — plain window listeners, direct port
|
|
3
|
+
* of the Vue DevTools timeline input capture pattern.
|
|
5
4
|
*/
|
|
6
5
|
import {now} from './clock.js';
|
|
7
6
|
const MOUSE_EVENTS = ['mousedown', 'mouseup', 'click', 'dblclick'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/input.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/input.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mouse and keyboard timeline layers — plain window listeners, direct port\n * of the Vue DevTools timeline input capture pattern.\n */\n\nimport type {TimelineEvent} from '../../../types/timeline.js';\nimport {now} from './clock.js';\n\ntype EmitFn = (event: TimelineEvent) => void;\ntype RecordingFn = () => boolean;\n\nconst MOUSE_EVENTS = [\n 'mousedown',\n 'mouseup',\n 'click',\n 'dblclick',\n] as const satisfies readonly string[];\n\nconst KEY_EVENTS = ['keydown', 'keyup'] as const satisfies readonly string[];\n\ninterface MouseData {\n type: string;\n x: number;\n y: number;\n button: number;\n}\n\ninterface KeyData {\n type: string;\n key: string;\n code: string;\n modifiers: string[];\n}\n\nconst mouseHandler =\n (emit: EmitFn, recording: RecordingFn, mouseEnabled: () => boolean) =>\n (e: Event): void => {\n if (!recording() || !mouseEnabled()) return;\n const me = e as MouseEvent;\n const data: MouseData = {\n type: e.type,\n x: Math.round(me.clientX),\n y: Math.round(me.clientY),\n button: me.button,\n };\n emit({\n layerId: 'mouse',\n time: now(),\n title: e.type,\n subtitle: `(${data.x}, ${data.y})`,\n data,\n });\n };\n\nconst keyHandler =\n (emit: EmitFn, recording: RecordingFn, keyEnabled: () => boolean) =>\n (e: Event): void => {\n if (!recording() || !keyEnabled()) return;\n const ke = e as KeyboardEvent;\n const modifiers: string[] = [];\n if (ke.ctrlKey) modifiers.push('Ctrl');\n if (ke.metaKey) modifiers.push('Meta');\n if (ke.altKey) modifiers.push('Alt');\n if (ke.shiftKey) modifiers.push('Shift');\n const data: KeyData = {\n type: e.type,\n key: ke.key,\n code: ke.code,\n modifiers,\n };\n emit({\n layerId: 'keyboard',\n time: now(),\n title: ke.key,\n subtitle: modifiers.length ? modifiers.join('+') : undefined,\n data,\n });\n };\n\nlet mouseCleanup: (() => void) | null = null;\nlet keyCleanup: (() => void) | null = null;\n\nexport const installMouseLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n mouseEnabled: () => boolean\n): void => {\n if (mouseCleanup !== null) return;\n const handler = mouseHandler(emit, recording, mouseEnabled);\n for (const type of MOUSE_EVENTS) {\n window.addEventListener(type, handler, {capture: true, passive: true});\n }\n mouseCleanup = () => {\n for (const type of MOUSE_EVENTS) {\n window.removeEventListener(type, handler, {capture: true});\n }\n };\n};\n\nexport const installKeyboardLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n keyEnabled: () => boolean\n): void => {\n if (keyCleanup !== null) return;\n const handler = keyHandler(emit, recording, keyEnabled);\n for (const type of KEY_EVENTS) {\n window.addEventListener(type, handler, {capture: true, passive: true});\n }\n keyCleanup = () => {\n for (const type of KEY_EVENTS) {\n window.removeEventListener(type, handler, {capture: true});\n }\n };\n};\n"]}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Timeline runtime install entry point.
|
|
3
|
+
*
|
|
4
|
+
* Injected by the plugin into the host page via `transformIndexHtml` when
|
|
5
|
+
* `timeline: true` is set. Sets up all capture layers and wires them to the
|
|
6
|
+
* transport.
|
|
7
|
+
*
|
|
8
|
+
* Recording starts off; the panel iframe toggles it via the Vite HMR channel
|
|
9
|
+
* (Phase 0/1) or devframe shared state (Phase 2+). Layers capture while the
|
|
10
|
+
* panel is recording OR the "chrome performance tracks" preference is on; the
|
|
11
|
+
* panel transport only receives events while recording, the Chrome tracks sink
|
|
12
|
+
* only while the preference is on.
|
|
5
13
|
*/
|
|
6
14
|
export {};
|
|
7
15
|
//# sourceMappingURL=install.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/install.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
5
|
-
*/
|
|
6
1
|
/**
|
|
7
2
|
* Timeline runtime install entry point.
|
|
8
3
|
*
|
|
@@ -86,8 +81,10 @@ subscribeOverride(hot, (o) => {
|
|
|
86
81
|
syncRenderDebug();
|
|
87
82
|
}
|
|
88
83
|
});
|
|
89
|
-
if (hot !== undefined)
|
|
90
|
-
|
|
84
|
+
if (hot !== undefined) pageChannel.useViteHot(hot);
|
|
85
|
+
// Wired whether or not Vite is present: a page outside Vite gets its carrier
|
|
86
|
+
// later from `connectToDevServer()`, and these listeners move onto it then.
|
|
87
|
+
{
|
|
91
88
|
setHotClient(pageChannel);
|
|
92
89
|
// Panel → app: toggle recording and per-layer flags.
|
|
93
90
|
pageChannel.on('lit:timeline:recording-changed', (data) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/install.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/install.ts"],"names":[],"mappings":"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","sourcesContent":["/**\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+). Layers capture while the\n * panel is recording OR the \"chrome performance tracks\" preference is on; the\n * panel transport only receives events while recording, the Chrome tracks sink\n * only while the preference is on.\n */\n\nimport {emit, setHotClient} from './transport.js';\nimport {resetClock} from './clock.js';\nimport {createChromeTracksSink} from './chrome-tracks.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 {pageChannel} from '../page-channel.js';\nimport type {ViteHotLike} from '../page-channel.js';\nimport type {\n TimelineEvent,\n TimelineLayersState,\n} 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\n// Mirror to Chrome DevTools' Performance panel; a page-side preference driven\n// by the settings override, independent of panel recording.\nlet chromeTracks = false;\nconst sink = createChromeTracksSink();\n\n// Layers run when either consumer wants events.\nconst capturing = (): boolean => state.recordingState || chromeTracks;\nconst out = (e: TimelineEvent): void => {\n if (state.recordingState) emit(e);\n if (chromeTracks) sink.push(e);\n};\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 capturing × (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 capturing() && (state.litRenderEnabled || state.litRenderVerboseEnabled)\n );\n};\n\n// ---------------------------------------------------------------------------\n// Capture layer installation\n// ---------------------------------------------------------------------------\n\ninstallLifecycleLayer(out, capturing, lifecycleEnabled);\ninstallRenderLayer(out, capturing, renderEnabled, renderVerboseEnabled);\ninstallMouseLayer(out, capturing, mouseEnabled);\ninstallKeyboardLayer(out, capturing, 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// Page channel wiring\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.\nconst hot = (import.meta as {hot?: ViteHotLike}).hot;\n\nsubscribeOverride(hot, (o) => {\n setFlashEnabled(o.flashUpdates ?? false);\n setFlashRamp(o.flashUpdatesRamp ?? false);\n const next = o.chromeTracks ?? false;\n if (next !== chromeTracks) {\n chromeTracks = next;\n if (!next) sink.reset();\n syncRenderDebug();\n }\n});\n\nif (hot !== undefined) pageChannel.useViteHot(hot);\n\n// Wired whether or not Vite is present: a page outside Vite gets its carrier\n// later from `connectToDevServer()`, and these listeners move onto it then.\n{\n setHotClient(pageChannel);\n\n // Panel → app: toggle recording and per-layer flags.\n pageChannel.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 pageChannel.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 pageChannel.send('lit:timeline:runtime-ready', {});\n // A carrier attached later starts with no idea a runtime exists.\n pageChannel.onAttach(() =>\n pageChannel.send('lit:timeline:runtime-ready', {})\n );\n}\n"]}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* ReactiveElement prototype instrumentation for the lifecycle timeline layer.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the lifecycle methods listed in PHASES on the prototype of the
|
|
5
|
+
* ReactiveElement class loaded by the app — not by importing lit directly,
|
|
6
|
+
* to avoid multi-copy issues. The proto is resolved from the already-defined
|
|
7
|
+
* custom element registry (same mechanism as the HMR patch module).
|
|
8
|
+
*
|
|
9
|
+
* Each wrapped method emits a paired start/end TimelineEvent so the panel
|
|
10
|
+
* can render duration bars. performUpdate brackets the whole update tick and
|
|
11
|
+
* bumps a per-instance tick counter that becomes the groupId shared by all
|
|
12
|
+
* phase events within that tick.
|
|
13
|
+
*
|
|
14
|
+
* Gated by the recording flag so overhead is near-zero when idle.
|
|
5
15
|
*/
|
|
6
16
|
import type { TimelineEvent } from '../../../types/timeline.js';
|
|
7
17
|
type EmitFn = (event: TimelineEvent) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/lifecycle.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAE9D,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAC7C,KAAK,WAAW,GAAG,MAAM,OAAO,CAAC;AACjC,KAAK,cAAc,GAAG,MAAM,OAAO,CAAC;AAEpC;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAI/D,yEAAyE;AACzE,eAAO,MAAM,aAAa,SAAU,UAAU,GAAG,IAAI,KAAG,IAEvD,CAAC;AAmMF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,SAC1B,MAAM,aACD,WAAW,WACb,cAAc,KACtB,IA6BF,CAAC"}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
5
|
-
*/
|
|
6
1
|
/**
|
|
7
2
|
* ReactiveElement prototype instrumentation for the lifecycle timeline layer.
|
|
8
3
|
*
|
|
@@ -211,12 +206,16 @@ export const installLifecycleLayer = (emit, recording, enabled) => {
|
|
|
211
206
|
// per prototype+method), so re-running once the shared bases are wrapped is a
|
|
212
207
|
// cheap no-op.
|
|
213
208
|
const origDefine = customElements.define.bind(customElements);
|
|
209
|
+
// Patch before defining: the platform reads connectedCallback and
|
|
210
|
+
// disconnectedCallback off the prototype at define() time, so wrapping them
|
|
211
|
+
// afterwards would miss the first component defined on a page with no Lit
|
|
212
|
+
// element yet.
|
|
214
213
|
customElements.define = (name, ctor, options) => {
|
|
215
|
-
origDefine(name, ctor, options);
|
|
216
214
|
const p = ctor?.prototype;
|
|
217
215
|
if (p != null && 'performUpdate' in p) {
|
|
218
216
|
patchBases(p, emit, recording, enabled);
|
|
219
217
|
}
|
|
218
|
+
origDefine(name, ctor, options);
|
|
220
219
|
};
|
|
221
220
|
};
|
|
222
221
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/lifecycle.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 * ReactiveElement prototype instrumentation for the lifecycle timeline layer.\n *\n * Wraps the lifecycle methods listed in PHASES on the prototype of the\n * ReactiveElement class loaded by the app — not by importing lit directly,\n * to avoid multi-copy issues. The proto is resolved from the already-defined\n * custom element registry (same mechanism as the HMR patch module).\n *\n * Each wrapped method emits a paired start/end TimelineEvent so the panel\n * can render duration bars. performUpdate brackets the whole update tick and\n * bumps a per-instance tick counter that becomes the groupId shared by all\n * phase events within that tick.\n *\n * Gated by the recording flag so overhead is near-zero when idle.\n */\n\nimport {idOf, sourceOf, changedKeys} from './identity.js';\nimport {now} from './clock.js';\nimport type {TimelineEvent} from '../../../types/timeline.js';\n\ntype EmitFn = (event: TimelineEvent) => void;\ntype RecordingFn = () => boolean;\ntype LayerEnabledFn = () => boolean;\n\n/**\n * Called once per completed `performUpdate`, with the element and whether that\n * was its first update. Independent of the recording gate: the flash overlay\n * wants every update while it is on, whether or not the timeline is recording.\n */\nexport type UpdateHook = (el: Element, first: boolean) => void;\n\nlet updateHook: UpdateHook | null = null;\n\n/** Install (or clear, with `null`) the per-update hook. One consumer. */\nexport const setUpdateHook = (hook: UpdateHook | null): void => {\n updateHook = hook;\n};\n\n/** Runs the update hook, never letting a consumer's throw reach the app. */\nconst notifyUpdated = (el: object, first: boolean): void => {\n if (updateHook === null) return;\n try {\n updateHook(el as Element, first);\n } catch {\n // dev tool — an overlay bug must not break the app's update cycle\n }\n};\n\n/** `ReactiveElement.hasUpdated`, read before the update flips it. */\nconst isFirstUpdate = (el: object): boolean =>\n (el as {hasUpdated?: boolean}).hasUpdated !== true;\n\n/** Phases to instrument with start/end pairs. */\nconst UPDATE_PHASES = [\n 'performUpdate',\n 'willUpdate',\n 'update',\n 'updated',\n 'firstUpdated',\n] as const;\n\n/** Point-in-time lifecycle events (no end bracket). */\nconst POINT_PHASES = ['connectedCallback', 'disconnectedCallback'] as const;\n\nconst BRAND = Symbol.for('@lit-labs/vite-plugin-lit#timeline-lifecycle');\n\n/** Per-instance update tick counter (bumped inside performUpdate wrapper). */\nconst ticks = new WeakMap<object, number>();\n\nconst tickOf = (el: object): number => ticks.get(el) ?? 0;\n\ntype AnyFn = (...args: unknown[]) => unknown;\ntype Proto = Record<string | symbol, AnyFn | undefined>;\n\n/** Returns true if `proto[name]` is already our wrapper (idempotent install). */\nconst isWrapped = (proto: Proto, name: string): boolean => {\n const fn = proto[name];\n return (\n typeof fn === 'function' && (fn as AnyFn & {[BRAND]?: true})[BRAND] === true\n );\n};\n\n/**\n * Wrap `proto[name]` with a start/end pair emitting to `emit`.\n * `isPoint` methods only emit a single event (no end bracket).\n */\nconst wrap = (\n proto: Proto,\n name: string,\n isPoint: boolean,\n emit: EmitFn,\n recording: RecordingFn,\n enabled: LayerEnabledFn\n): void => {\n if (isWrapped(proto, name)) return;\n const orig = proto[name];\n\n const wrapper: AnyFn & {[BRAND]?: true} = function (\n this: object,\n ...args: unknown[]\n ) {\n const isUpdate = name === 'performUpdate';\n if (!recording() || !enabled()) {\n if (!isUpdate || updateHook === null) return orig?.apply(this, args);\n const first = isFirstUpdate(this);\n const result = orig?.apply(this, args);\n notifyUpdated(this, first);\n return result;\n }\n const first = isUpdate && isFirstUpdate(this);\n\n // Bump the per-instance tick at the *start* of each performUpdate, before\n // computing the groupId, so this whole update cycle — performUpdate and the\n // willUpdate/update/updated phases it nests — shares one groupId, distinct\n // from the previous cycle's. (Reading the tick before bumping put\n // performUpdate in a different group from its own phases and let adjacent\n // cycles collide on the same tick.)\n if (name === 'performUpdate') {\n ticks.set(this, tickOf(this) + 1);\n }\n\n const elementId = idOf(this);\n const tagName = (this as Element).localName ?? 'unknown';\n const source = sourceOf(this);\n const tick = tickOf(this);\n const groupId = `${elementId}:${tick}`;\n const time = now();\n const changed = changedKeys(args[0]);\n\n if (!isPoint) {\n emit({\n layerId: 'lit-lifecycle',\n time,\n groupId,\n title: name + ':start',\n subtitle: tagName,\n data: {phase: name, changed},\n meta: {elementId, tagName, source},\n });\n }\n\n let result: unknown;\n try {\n result = orig?.apply(this, args);\n } finally {\n if (!isPoint) {\n emit({\n layerId: 'lit-lifecycle',\n time: now(),\n groupId,\n title: name + ':end',\n subtitle: tagName,\n data: {phase: name},\n meta: {elementId, tagName, source},\n });\n } else {\n emit({\n layerId: 'lit-lifecycle',\n time,\n title: name,\n subtitle: tagName,\n data: {phase: name},\n meta: {elementId, tagName, source},\n });\n }\n }\n // After the bracket, not in it: a throwing update never completed, so it\n // doesn't count as one.\n if (isUpdate) notifyUpdated(this, first);\n return result;\n };\n wrapper[BRAND] = true;\n\n try {\n Object.defineProperty(proto, name, {\n value: wrapper,\n writable: true,\n configurable: true,\n });\n } catch {\n // Non-configurable slot; instrumentation degrades gracefully.\n }\n};\n\n/**\n * Finds the prototype in `proto`'s chain that *owns* `name` as an own property,\n * or null if none does.\n */\nconst ownerOf = (proto: Proto, name: string): Proto | null => {\n let p: Proto | null = proto;\n while (p !== null && !Object.prototype.hasOwnProperty.call(p, name)) {\n p = Object.getPrototypeOf(p) as Proto | null;\n }\n return p;\n};\n\n/**\n * Returns any defined Lit element's prototype (duck-typed by `performUpdate`),\n * or null if none can be found yet. One sample is enough: its chain leads to\n * the shared ReactiveElement/LitElement base prototypes every component\n * inherits.\n *\n * Tries the non-standard `_registry` map first, then falls back to sampling a\n * live upgraded element from the DOM — `_registry` isn't present in every\n * engine (e.g. some Chrome builds), and without this fallback an app whose\n * components were all defined before the runtime installed gets no lifecycle\n * instrumentation at all.\n */\nconst findLitElementProto = (): Proto | null => {\n const registry = (\n customElements as unknown as {\n _registry?: Record<string, CustomElementConstructor>;\n }\n )._registry;\n if (registry !== undefined) {\n for (const ctor of Object.values(registry)) {\n const proto = ctor?.prototype;\n if (proto != null && 'performUpdate' in proto) return proto as Proto;\n }\n }\n if (typeof document !== 'undefined') {\n for (const el of document.querySelectorAll('*')) {\n const proto = Object.getPrototypeOf(el) as Proto | null;\n if (proto != null && 'performUpdate' in proto) return proto;\n }\n }\n return null;\n};\n\nlet installed = false;\n\n/**\n * Install lifecycle instrumentation for *every* Lit element on the page.\n *\n * The phases live on the shared ReactiveElement/LitElement base prototypes, so\n * wrapping them there instruments all components at once — not just the first\n * one registered (the old behavior, which also silently no-op'd when Vite\n * served the production Lit build, since that omits the `reactiveElementVersions`\n * sentinel the resolver gated on).\n *\n * A component that overrides `willUpdate`/`updated`/`firstUpdated` *without*\n * calling `super` shadows the base no-op and won't report that phase — an\n * accepted limitation; the common case and `super`-calling overrides report.\n *\n * Idempotent — wrapping is brand-guarded per prototype+method.\n */\nexport const installLifecycleLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n enabled: LayerEnabledFn\n): void => {\n if (installed) return;\n installed = true;\n\n // Instrument from a sample already on the page (covers components defined\n // before the runtime installed — the common case, since the runtime is\n // injected after the app's modules).\n const proto = findLitElementProto();\n if (proto !== null) {\n patchBases(proto, emit, recording, enabled);\n }\n\n // Also instrument on future defines — both for components registered later\n // and for the case where none were discoverable above. Kept installed for\n // the page's lifetime; `patchBases` is idempotent (wrapping is brand-guarded\n // per prototype+method), so re-running once the shared bases are wrapped is a\n // cheap no-op.\n const origDefine = customElements.define.bind(customElements);\n customElements.define = (name, ctor, options) => {\n origDefine(name, ctor, options);\n const p = ctor?.prototype as Proto | null;\n if (p != null && 'performUpdate' in p) {\n patchBases(p, emit, recording, enabled);\n }\n };\n};\n\n/**\n * Wraps the lifecycle phases on the shared base prototypes reachable from\n * `sample`. `performUpdate` is never overridden by app code, so walking up from\n * any Lit element lands on `ReactiveElement.prototype` — which owns the update/\n * connect lifecycle, shared by all components. `update` is wrapped on its\n * effective owner instead (`LitElement.prototype` overrides it to drive\n * `render()`), so the timed call is the one that actually runs.\n */\nconst patchBases = (\n sample: Proto,\n emit: EmitFn,\n recording: RecordingFn,\n enabled: LayerEnabledFn\n): void => {\n const reProto = ownerOf(sample, 'performUpdate');\n if (reProto === null) return;\n for (const name of UPDATE_PHASES) {\n const owner = name === 'update' ? ownerOf(sample, 'update') : reProto;\n if (owner !== null) wrap(owner, name, false, emit, recording, enabled);\n }\n for (const name of POINT_PHASES) {\n wrap(reProto, name, true, emit, recording, enabled);\n }\n};\n"]}
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAC,GAAG,EAAC,MAAM,YAAY,CAAC;AAc/B,IAAI,UAAU,GAAsB,IAAI,CAAC;AAEzC,yEAAyE;AACzE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAuB,EAAQ,EAAE;IAC7D,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC,CAAC;AAEF,4EAA4E;AAC5E,MAAM,aAAa,GAAG,CAAC,EAAU,EAAE,KAAc,EAAQ,EAAE;IACzD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO;IAChC,IAAI,CAAC;QACH,UAAU,CAAC,EAAa,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;AACH,CAAC,CAAC;AAEF,qEAAqE;AACrE,MAAM,aAAa,GAAG,CAAC,EAAU,EAAW,EAAE,CAC3C,EAA6B,CAAC,UAAU,KAAK,IAAI,CAAC;AAErD,iDAAiD;AACjD,MAAM,aAAa,GAAG;IACpB,eAAe;IACf,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,cAAc;CACN,CAAC;AAEX,uDAAuD;AACvD,MAAM,YAAY,GAAG,CAAC,mBAAmB,EAAE,sBAAsB,CAAU,CAAC;AAE5E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;AAEzE,8EAA8E;AAC9E,MAAM,KAAK,GAAG,IAAI,OAAO,EAAkB,CAAC;AAE5C,MAAM,MAAM,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AAK1D,iFAAiF;AACjF,MAAM,SAAS,GAAG,CAAC,KAAY,EAAE,IAAY,EAAW,EAAE;IACxD,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CACL,OAAO,EAAE,KAAK,UAAU,IAAK,EAA+B,CAAC,KAAK,CAAC,KAAK,IAAI,CAC7E,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,IAAI,GAAG,CACX,KAAY,EACZ,IAAY,EACZ,OAAgB,EAChB,IAAY,EACZ,SAAsB,EACtB,OAAuB,EACjB,EAAE;IACR,IAAI,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC;QAAE,OAAO;IACnC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAEzB,MAAM,OAAO,GAA6B,UAExC,GAAG,IAAe;QAElB,MAAM,QAAQ,GAAG,IAAI,KAAK,eAAe,CAAC;QAC1C,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,IAAI,UAAU,KAAK,IAAI;gBAAE,OAAO,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACvC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC3B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;QAE9C,0EAA0E;QAC1E,4EAA4E;QAC5E,2EAA2E;QAC3E,kEAAkE;QAClE,0EAA0E;QAC1E,oCAAoC;QACpC,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;YAC7B,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAI,IAAgB,CAAC,SAAS,IAAI,SAAS,CAAC;QACzD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAErC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,OAAO,EAAE,eAAe;gBACxB,IAAI;gBACJ,OAAO;gBACP,KAAK,EAAE,IAAI,GAAG,QAAQ;gBACtB,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAC;gBAC5B,IAAI,EAAE,EAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAC;aACnC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC;oBACH,OAAO,EAAE,eAAe;oBACxB,IAAI,EAAE,GAAG,EAAE;oBACX,OAAO;oBACP,KAAK,EAAE,IAAI,GAAG,MAAM;oBACpB,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC;oBACnB,IAAI,EAAE,EAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAC;iBACnC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,OAAO,EAAE,eAAe;oBACxB,IAAI;oBACJ,KAAK,EAAE,IAAI;oBACX,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC;oBACnB,IAAI,EAAE,EAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAC;iBACnC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,yEAAyE;QACzE,wBAAwB;QACxB,IAAI,QAAQ;YAAE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAEtB,IAAI,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE;YACjC,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,IAAY,EAAgB,EAAE;IAC3D,IAAI,CAAC,GAAiB,KAAK,CAAC;IAC5B,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;QACpE,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAiB,CAAC;IAC/C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,mBAAmB,GAAG,GAAiB,EAAE;IAC7C,MAAM,QAAQ,GACZ,cAGD,CAAC,SAAS,CAAC;IACZ,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,EAAE,SAAS,CAAC;YAC9B,IAAI,KAAK,IAAI,IAAI,IAAI,eAAe,IAAI,KAAK;gBAAE,OAAO,KAAc,CAAC;QACvE,CAAC;IACH,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,CAAiB,CAAC;YACxD,IAAI,KAAK,IAAI,IAAI,IAAI,eAAe,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC9D,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,IAAY,EACZ,SAAsB,EACtB,OAAuB,EACjB,EAAE;IACR,IAAI,SAAS;QAAE,OAAO;IACtB,SAAS,GAAG,IAAI,CAAC;IAEjB,0EAA0E;IAC1E,uEAAuE;IACvE,qCAAqC;IACrC,MAAM,KAAK,GAAG,mBAAmB,EAAE,CAAC;IACpC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,8EAA8E;IAC9E,eAAe;IACf,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC9D,kEAAkE;IAClE,4EAA4E;IAC5E,0EAA0E;IAC1E,eAAe;IACf,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC9C,MAAM,CAAC,GAAG,IAAI,EAAE,SAAyB,CAAC;QAC1C,IAAI,CAAC,IAAI,IAAI,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;YACtC,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CACjB,MAAa,EACb,IAAY,EACZ,SAAsB,EACtB,OAAuB,EACjB,EAAE;IACR,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO;IAC7B,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACtE,IAAI,KAAK,KAAK,IAAI;YAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACzE,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;AACH,CAAC,CAAC","sourcesContent":["/**\n * ReactiveElement prototype instrumentation for the lifecycle timeline layer.\n *\n * Wraps the lifecycle methods listed in PHASES on the prototype of the\n * ReactiveElement class loaded by the app — not by importing lit directly,\n * to avoid multi-copy issues. The proto is resolved from the already-defined\n * custom element registry (same mechanism as the HMR patch module).\n *\n * Each wrapped method emits a paired start/end TimelineEvent so the panel\n * can render duration bars. performUpdate brackets the whole update tick and\n * bumps a per-instance tick counter that becomes the groupId shared by all\n * phase events within that tick.\n *\n * Gated by the recording flag so overhead is near-zero when idle.\n */\n\nimport {idOf, sourceOf, changedKeys} from './identity.js';\nimport {now} from './clock.js';\nimport type {TimelineEvent} from '../../../types/timeline.js';\n\ntype EmitFn = (event: TimelineEvent) => void;\ntype RecordingFn = () => boolean;\ntype LayerEnabledFn = () => boolean;\n\n/**\n * Called once per completed `performUpdate`, with the element and whether that\n * was its first update. Independent of the recording gate: the flash overlay\n * wants every update while it is on, whether or not the timeline is recording.\n */\nexport type UpdateHook = (el: Element, first: boolean) => void;\n\nlet updateHook: UpdateHook | null = null;\n\n/** Install (or clear, with `null`) the per-update hook. One consumer. */\nexport const setUpdateHook = (hook: UpdateHook | null): void => {\n updateHook = hook;\n};\n\n/** Runs the update hook, never letting a consumer's throw reach the app. */\nconst notifyUpdated = (el: object, first: boolean): void => {\n if (updateHook === null) return;\n try {\n updateHook(el as Element, first);\n } catch {\n // dev tool — an overlay bug must not break the app's update cycle\n }\n};\n\n/** `ReactiveElement.hasUpdated`, read before the update flips it. */\nconst isFirstUpdate = (el: object): boolean =>\n (el as {hasUpdated?: boolean}).hasUpdated !== true;\n\n/** Phases to instrument with start/end pairs. */\nconst UPDATE_PHASES = [\n 'performUpdate',\n 'willUpdate',\n 'update',\n 'updated',\n 'firstUpdated',\n] as const;\n\n/** Point-in-time lifecycle events (no end bracket). */\nconst POINT_PHASES = ['connectedCallback', 'disconnectedCallback'] as const;\n\nconst BRAND = Symbol.for('@lit-labs/vite-plugin-lit#timeline-lifecycle');\n\n/** Per-instance update tick counter (bumped inside performUpdate wrapper). */\nconst ticks = new WeakMap<object, number>();\n\nconst tickOf = (el: object): number => ticks.get(el) ?? 0;\n\ntype AnyFn = (...args: unknown[]) => unknown;\ntype Proto = Record<string | symbol, AnyFn | undefined>;\n\n/** Returns true if `proto[name]` is already our wrapper (idempotent install). */\nconst isWrapped = (proto: Proto, name: string): boolean => {\n const fn = proto[name];\n return (\n typeof fn === 'function' && (fn as AnyFn & {[BRAND]?: true})[BRAND] === true\n );\n};\n\n/**\n * Wrap `proto[name]` with a start/end pair emitting to `emit`.\n * `isPoint` methods only emit a single event (no end bracket).\n */\nconst wrap = (\n proto: Proto,\n name: string,\n isPoint: boolean,\n emit: EmitFn,\n recording: RecordingFn,\n enabled: LayerEnabledFn\n): void => {\n if (isWrapped(proto, name)) return;\n const orig = proto[name];\n\n const wrapper: AnyFn & {[BRAND]?: true} = function (\n this: object,\n ...args: unknown[]\n ) {\n const isUpdate = name === 'performUpdate';\n if (!recording() || !enabled()) {\n if (!isUpdate || updateHook === null) return orig?.apply(this, args);\n const first = isFirstUpdate(this);\n const result = orig?.apply(this, args);\n notifyUpdated(this, first);\n return result;\n }\n const first = isUpdate && isFirstUpdate(this);\n\n // Bump the per-instance tick at the *start* of each performUpdate, before\n // computing the groupId, so this whole update cycle — performUpdate and the\n // willUpdate/update/updated phases it nests — shares one groupId, distinct\n // from the previous cycle's. (Reading the tick before bumping put\n // performUpdate in a different group from its own phases and let adjacent\n // cycles collide on the same tick.)\n if (name === 'performUpdate') {\n ticks.set(this, tickOf(this) + 1);\n }\n\n const elementId = idOf(this);\n const tagName = (this as Element).localName ?? 'unknown';\n const source = sourceOf(this);\n const tick = tickOf(this);\n const groupId = `${elementId}:${tick}`;\n const time = now();\n const changed = changedKeys(args[0]);\n\n if (!isPoint) {\n emit({\n layerId: 'lit-lifecycle',\n time,\n groupId,\n title: name + ':start',\n subtitle: tagName,\n data: {phase: name, changed},\n meta: {elementId, tagName, source},\n });\n }\n\n let result: unknown;\n try {\n result = orig?.apply(this, args);\n } finally {\n if (!isPoint) {\n emit({\n layerId: 'lit-lifecycle',\n time: now(),\n groupId,\n title: name + ':end',\n subtitle: tagName,\n data: {phase: name},\n meta: {elementId, tagName, source},\n });\n } else {\n emit({\n layerId: 'lit-lifecycle',\n time,\n title: name,\n subtitle: tagName,\n data: {phase: name},\n meta: {elementId, tagName, source},\n });\n }\n }\n // After the bracket, not in it: a throwing update never completed, so it\n // doesn't count as one.\n if (isUpdate) notifyUpdated(this, first);\n return result;\n };\n wrapper[BRAND] = true;\n\n try {\n Object.defineProperty(proto, name, {\n value: wrapper,\n writable: true,\n configurable: true,\n });\n } catch {\n // Non-configurable slot; instrumentation degrades gracefully.\n }\n};\n\n/**\n * Finds the prototype in `proto`'s chain that *owns* `name` as an own property,\n * or null if none does.\n */\nconst ownerOf = (proto: Proto, name: string): Proto | null => {\n let p: Proto | null = proto;\n while (p !== null && !Object.prototype.hasOwnProperty.call(p, name)) {\n p = Object.getPrototypeOf(p) as Proto | null;\n }\n return p;\n};\n\n/**\n * Returns any defined Lit element's prototype (duck-typed by `performUpdate`),\n * or null if none can be found yet. One sample is enough: its chain leads to\n * the shared ReactiveElement/LitElement base prototypes every component\n * inherits.\n *\n * Tries the non-standard `_registry` map first, then falls back to sampling a\n * live upgraded element from the DOM — `_registry` isn't present in every\n * engine (e.g. some Chrome builds), and without this fallback an app whose\n * components were all defined before the runtime installed gets no lifecycle\n * instrumentation at all.\n */\nconst findLitElementProto = (): Proto | null => {\n const registry = (\n customElements as unknown as {\n _registry?: Record<string, CustomElementConstructor>;\n }\n )._registry;\n if (registry !== undefined) {\n for (const ctor of Object.values(registry)) {\n const proto = ctor?.prototype;\n if (proto != null && 'performUpdate' in proto) return proto as Proto;\n }\n }\n if (typeof document !== 'undefined') {\n for (const el of document.querySelectorAll('*')) {\n const proto = Object.getPrototypeOf(el) as Proto | null;\n if (proto != null && 'performUpdate' in proto) return proto;\n }\n }\n return null;\n};\n\nlet installed = false;\n\n/**\n * Install lifecycle instrumentation for *every* Lit element on the page.\n *\n * The phases live on the shared ReactiveElement/LitElement base prototypes, so\n * wrapping them there instruments all components at once — not just the first\n * one registered (the old behavior, which also silently no-op'd when Vite\n * served the production Lit build, since that omits the `reactiveElementVersions`\n * sentinel the resolver gated on).\n *\n * A component that overrides `willUpdate`/`updated`/`firstUpdated` *without*\n * calling `super` shadows the base no-op and won't report that phase — an\n * accepted limitation; the common case and `super`-calling overrides report.\n *\n * Idempotent — wrapping is brand-guarded per prototype+method.\n */\nexport const installLifecycleLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n enabled: LayerEnabledFn\n): void => {\n if (installed) return;\n installed = true;\n\n // Instrument from a sample already on the page (covers components defined\n // before the runtime installed — the common case, since the runtime is\n // injected after the app's modules).\n const proto = findLitElementProto();\n if (proto !== null) {\n patchBases(proto, emit, recording, enabled);\n }\n\n // Also instrument on future defines — both for components registered later\n // and for the case where none were discoverable above. Kept installed for\n // the page's lifetime; `patchBases` is idempotent (wrapping is brand-guarded\n // per prototype+method), so re-running once the shared bases are wrapped is a\n // cheap no-op.\n const origDefine = customElements.define.bind(customElements);\n // Patch before defining: the platform reads connectedCallback and\n // disconnectedCallback off the prototype at define() time, so wrapping them\n // afterwards would miss the first component defined on a page with no Lit\n // element yet.\n customElements.define = (name, ctor, options) => {\n const p = ctor?.prototype as Proto | null;\n if (p != null && 'performUpdate' in p) {\n patchBases(p, emit, recording, enabled);\n }\n origDefine(name, ctor, options);\n };\n};\n\n/**\n * Wraps the lifecycle phases on the shared base prototypes reachable from\n * `sample`. `performUpdate` is never overridden by app code, so walking up from\n * any Lit element lands on `ReactiveElement.prototype` — which owns the update/\n * connect lifecycle, shared by all components. `update` is wrapped on its\n * effective owner instead (`LitElement.prototype` overrides it to drive\n * `render()`), so the timed call is the one that actually runs.\n */\nconst patchBases = (\n sample: Proto,\n emit: EmitFn,\n recording: RecordingFn,\n enabled: LayerEnabledFn\n): void => {\n const reProto = ownerOf(sample, 'performUpdate');\n if (reProto === null) return;\n for (const name of UPDATE_PHASES) {\n const owner = name === 'update' ? ownerOf(sample, 'update') : reProto;\n if (owner !== null) wrap(owner, name, false, emit, recording, enabled);\n }\n for (const name of POINT_PHASES) {\n wrap(reProto, name, true, emit, recording, enabled);\n }\n};\n"]}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Public timeline API — re-exported by the `virtual:lit-plugin/timeline`
|
|
3
|
+
* virtual module so app code and other plugins can contribute events and
|
|
4
|
+
* custom layers without reaching into plugin internals.
|
|
5
|
+
*
|
|
6
|
+
* This module shares the same `transport.ts` instance as `install.ts`, so
|
|
7
|
+
* events emitted here flow through the same batched HMR channel to the panel.
|
|
5
8
|
*/
|
|
6
9
|
import type { TimelineEvent, TimelineLayer } from '../../../types/timeline.js';
|
|
7
10
|
export type { TimelineEvent, TimelineLayer };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/public-api.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/public-api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAC,aAAa,EAAE,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAE7E,YAAY,EAAC,aAAa,EAAE,aAAa,EAAC,CAAC;AAE3C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,UAAW,aAAa,KAAG,IAEvD,CAAC;AAYF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,UAAW,aAAa,KAAG,IAMvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/public-api.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/public-api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAC/C,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;AAEF,MAAM,eAAe,GAAoB,EAAE,CAAC;AAE5C,8EAA8E;AAC9E,kEAAkE;AAClE,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE;IACxB,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,WAAW,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAC,KAAK,EAAC,CAAC,CAAC;IACzD,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAoB,EAAQ,EAAE;IAC7D,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,WAAW,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAC,KAAK,EAAC,CAAC,CAAC;IACzD,CAAC,CAAC;IACF,oBAAoB,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC","sourcesContent":["/**\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 {pageChannel} from '../page-channel.js';\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\nconst announcedLayers: TimelineLayer[] = [];\n\n// A carrier attached later (the dev server's own RPC link, say) never saw the\n// layers registered before it, so they are announced to it again.\npageChannel.onAttach(() => {\n for (const layer of announcedLayers) {\n pageChannel.send('lit:timeline:custom-layer', {layer});\n }\n});\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 announcedLayers.push(layer);\n pageChannel.send('lit:timeline:custom-layer', {layer});\n };\n setHotClientCallback(send);\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;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"}
|
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* lit-render timeline layers — listen to the built-in lit-debug CustomEvents
|
|
3
|
+
* instead of patching prototypes, so they're zero-cost when the Lit debug
|
|
4
|
+
* flag is off and perfectly accurate for the render layers.
|
|
5
|
+
*
|
|
6
|
+
* `globalThis.emitLitDebugLogEvents = true` gates the events, and lit-html
|
|
7
|
+
* dispatches a CustomEvent per render whenever it's set — a real per-render
|
|
8
|
+
* cost. So the caller drives the flag via {@link setRenderDebugEnabled} from
|
|
9
|
+
* `recording × (lit-render OR lit-render-verbose enabled)` rather than
|
|
10
|
+
* leaving it on for the whole session.
|
|
11
|
+
* The events are tagged `*Unstable` in the Lit source; we tolerate missing
|
|
12
|
+
* `kind` values gracefully.
|
|
13
|
+
*
|
|
14
|
+
* begin render / end render share a numeric `id` → we use it as groupId so
|
|
15
|
+
* the panel can show a duration bar for each render call.
|
|
16
|
+
*
|
|
17
|
+
* `template updating` / `template instantiated[ and updated]` / `set part` /
|
|
18
|
+
* `commit *` fire once per template-bound part on *every* render — extremely
|
|
19
|
+
* high volume (a ticking clock or animation floods the layer). They're
|
|
20
|
+
* emitted on the separate opt-in `lit-render-verbose` layer rather than
|
|
21
|
+
* `lit-render`, so the common case (the begin/end render duration bar) stays
|
|
22
|
+
* quiet by default.
|
|
5
23
|
*/
|
|
6
24
|
import {idOf, sourceOf} from './identity.js';
|
|
7
25
|
import {now} from './clock.js';
|