@oddsquad/vite-plugin-lit 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +2 -0
  3. package/bin.mjs +20 -0
  4. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-CRHFLjFo.js → browser-agent-rpc-BXhoSh1z-F2EfZsFX.js} +3 -3
  5. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-CRHFLjFo.js.map → browser-agent-rpc-BXhoSh1z-F2EfZsFX.js.map} +1 -1
  6. package/dist/client/assets/{index-Gn4Hk_9s.js → index-B2HYO7lk.js} +52 -19
  7. package/dist/client/assets/index-B2HYO7lk.js.map +1 -0
  8. package/dist/client/index.html +1 -1
  9. package/lib/confine.d.ts +22 -0
  10. package/lib/confine.d.ts.map +1 -0
  11. package/lib/confine.js +39 -0
  12. package/lib/confine.js.map +1 -0
  13. package/lib/devframe/definition.d.ts +10 -2
  14. package/lib/devframe/definition.d.ts.map +1 -1
  15. package/lib/devframe/definition.js +31 -9
  16. package/lib/devframe/definition.js.map +1 -1
  17. package/lib/devframe/protocol.d.ts +7 -3
  18. package/lib/devframe/protocol.d.ts.map +1 -1
  19. package/lib/devframe/protocol.js.map +1 -1
  20. package/lib/devframe/vite.d.ts.map +1 -1
  21. package/lib/devframe/vite.js +3 -0
  22. package/lib/devframe/vite.js.map +1 -1
  23. package/lib/http.d.ts +5 -0
  24. package/lib/http.d.ts.map +1 -1
  25. package/lib/http.js +5 -0
  26. package/lib/http.js.map +1 -1
  27. package/lib/plugins/open-in-editor.d.ts.map +1 -1
  28. package/lib/plugins/open-in-editor.js +11 -19
  29. package/lib/plugins/open-in-editor.js.map +1 -1
  30. package/lib/runtime/timeline/chrome-tracks.d.ts +22 -0
  31. package/lib/runtime/timeline/chrome-tracks.d.ts.map +1 -0
  32. package/lib/runtime/timeline/chrome-tracks.js +74 -0
  33. package/lib/runtime/timeline/chrome-tracks.js.map +1 -0
  34. package/lib/runtime/timeline/clock.d.ts +6 -0
  35. package/lib/runtime/timeline/clock.d.ts.map +1 -1
  36. package/lib/runtime/timeline/clock.js +6 -0
  37. package/lib/runtime/timeline/clock.js.map +1 -1
  38. package/lib/runtime/timeline/install.js +27 -9
  39. package/lib/runtime/timeline/install.js.map +1 -1
  40. package/lib/snapshot.d.ts +2 -1
  41. package/lib/snapshot.d.ts.map +1 -1
  42. package/lib/snapshot.js +17 -1
  43. package/lib/snapshot.js.map +1 -1
  44. package/lib/source-meta.d.ts.map +1 -1
  45. package/lib/source-meta.js +40 -1
  46. package/lib/source-meta.js.map +1 -1
  47. package/package.json +6 -6
  48. package/types/timeline.d.ts +6 -0
  49. package/types/timeline.d.ts.map +1 -1
  50. package/types/timeline.js.map +1 -1
  51. package/dist/client/assets/index-Gn4Hk_9s.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/lib/snapshot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAYtD,yEAAyE;AACzE,MAAM,UAAU,GAAG,CAAC,KAA+B,EAAU,EAAE,CAC7D,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,QAAyB,EACzB,OAIC,EAC6B,EAAE;IAChC,MAAM,EAAC,WAAW,EAAC,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,iBAAiB,CAAC;QACnC,qEAAqE;QACrE,8DAA8D;QAC9D,MAAM,EAAE,gBAAgB,EAAE;QAC1B,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;IAEH,MAAM,WAAW,CAAC,UAAU,EAAE;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,wEAAwE;QACxE,0EAA0E;QAC1E,sCAAsC;QACtC,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;QAC9B,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;QACtC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM;KACjC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Freezing a live session into a static panel someone else can open.\n *\n * Capture needs no transport: by the time a developer wants to export, the\n * node side is already holding the timeline buffer, the component tree, the\n * details of everything that was inspected, and the HMR incompatibility list.\n * The export reads its own state and hands it to devframe's build adapter as\n * a second, replaying definition.\n *\n * The output is a plain directory: the panel SPA, a `__connection.json` that\n * says `backend: 'static'`, and the baked RPC dump. It is mount-path agnostic,\n * so it works opened from a file server at any base — zip it onto an issue.\n */\n\nimport {createLitDevframe} from './devframe/definition.js';\nimport {createNullSource} from './devframe/source.js';\nimport type {FeatureSettings} from '../types/timeline.js';\nimport type {SessionSnapshot} from '../types/snapshot.js';\n\n/** What {@link buildSnapshot} reports back to whoever asked for the export. */\nexport interface SnapshotBuildResult {\n outDir: string;\n events: number;\n components: number;\n details: number;\n}\n\n/** Count the nodes of a tree, so the caller can say what it exported. */\nconst countNodes = (nodes: SessionSnapshot['roots']): number =>\n nodes.reduce((total, node) => total + 1 + countNodes(node.children), 0);\n\n/**\n * Write `snapshot` to `outDir` as a self-contained static panel.\n *\n * The build adapter is imported dynamically: it reaches for `node:fs`, and\n * `definition.ts` is deliberately framework- and environment-neutral, so a\n * static import would drag filesystem code into every context that merely\n * builds the definition.\n */\nexport const buildSnapshot = async (\n snapshot: SessionSnapshot,\n options: {\n outDir: string;\n features: FeatureSettings | null;\n clientAssets?: string;\n }\n): Promise<SnapshotBuildResult> => {\n const {createBuild} = await import('devframe/adapters/build');\n const definition = createLitDevframe({\n // Nothing to attach to: the page this session describes is gone, and\n // every answer the frozen panel needs is already in `replay`.\n source: createNullSource(),\n version: snapshot.version,\n features: () => options.features,\n clientAssets: options.clientAssets,\n replay: snapshot,\n });\n\n await createBuild(definition, {\n outDir: options.outDir,\n // The Vite plugin declares `capabilities.build: false` because there is\n // nothing to render during `vite build` — a *recorded* session is the one\n // case where a build does make sense.\n force: true,\n });\n\n return {\n outDir: options.outDir,\n events: snapshot.events.length,\n components: countNodes(snapshot.roots),\n details: snapshot.details.length,\n };\n};\n"]}
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/lib/snapshot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAYtD,yEAAyE;AACzE,MAAM,UAAU,GAAG,CAAC,KAA+B,EAAU,EAAE,CAC7D,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,QAAyB,EACzB,OAIC,EAC6B,EAAE;IAChC,MAAM,EAAC,WAAW,EAAC,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;IAC9D,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,4CAA4C;IAC5C,MAAM,EAAC,UAAU,EAAC,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACzC,IACE,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1B,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,EACtD,CAAC;QACD,MAAM,IAAI,KAAK,CACb,kBAAkB,OAAO,CAAC,MAAM,iCAAiC;YAC/D,wBAAwB,CAC3B,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,iBAAiB,CAAC;QACnC,qEAAqE;QACrE,8DAA8D;QAC9D,MAAM,EAAE,gBAAgB,EAAE;QAC1B,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;IAEH,MAAM,WAAW,CAAC,UAAU,EAAE;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,wEAAwE;QACxE,0EAA0E;QAC1E,sCAAsC;QACtC,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;QAC9B,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;QACtC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM;KACjC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Freezing a live session into a static panel someone else can open.\n *\n * Capture needs no transport: by the time a developer wants to export, the\n * node side is already holding the timeline buffer, the component tree, the\n * details of everything that was inspected, and the HMR incompatibility list.\n * The export reads its own state and hands it to devframe's build adapter as\n * a second, replaying definition.\n *\n * The output is a plain directory: the panel SPA, a `__connection.json` that\n * says `backend: 'static'`, and the baked RPC dump. It is mount-path agnostic,\n * so it works opened from a file server at any base — zip it onto an issue.\n */\n\nimport {createLitDevframe} from './devframe/definition.js';\nimport {createNullSource} from './devframe/source.js';\nimport type {FeatureSettings} from '../types/timeline.js';\nimport type {SessionSnapshot} from '../types/snapshot.js';\n\n/** What {@link buildSnapshot} reports back to whoever asked for the export. */\nexport interface SnapshotBuildResult {\n outDir: string;\n events: number;\n components: number;\n details: number;\n}\n\n/** Count the nodes of a tree, so the caller can say what it exported. */\nconst countNodes = (nodes: SessionSnapshot['roots']): number =>\n nodes.reduce((total, node) => total + 1 + countNodes(node.children), 0);\n\n/**\n * Write `snapshot` to `outDir` as a self-contained static panel, replacing an\n * earlier snapshot there. Any other existing directory is refused.\n *\n * The build adapter is imported dynamically: it reaches for `node:fs`, and\n * `definition.ts` is deliberately framework- and environment-neutral, so a\n * static import would drag filesystem code into every context that merely\n * builds the definition.\n */\nexport const buildSnapshot = async (\n snapshot: SessionSnapshot,\n options: {\n outDir: string;\n features: FeatureSettings | null;\n clientAssets?: string;\n }\n): Promise<SnapshotBuildResult> => {\n const {createBuild} = await import('devframe/adapters/build');\n // `createBuild` deletes `outDir` recursively before writing. Replacing an\n // earlier export is the point, but a typo'd `outDir` that names the project\n // (or `src`) must not cost the developer their tree: only a directory that\n // already holds a snapshot may be replaced.\n const {existsSync} = await import('node:fs');\n const {join} = await import('node:path');\n if (\n existsSync(options.outDir) &&\n !existsSync(join(options.outDir, '__connection.json'))\n ) {\n throw new Error(\n `[lit-devtools] ${options.outDir} exists and is not a snapshot; ` +\n 'refusing to replace it'\n );\n }\n const definition = createLitDevframe({\n // Nothing to attach to: the page this session describes is gone, and\n // every answer the frozen panel needs is already in `replay`.\n source: createNullSource(),\n version: snapshot.version,\n features: () => options.features,\n clientAssets: options.clientAssets,\n replay: snapshot,\n });\n\n await createBuild(definition, {\n outDir: options.outDir,\n // The Vite plugin declares `capabilities.build: false` because there is\n // nothing to render during `vite build` — a *recorded* session is the one\n // case where a build does make sense.\n force: true,\n });\n\n return {\n outDir: options.outDir,\n events: snapshot.events.length,\n components: countNodes(snapshot.roots),\n details: snapshot.details.length,\n };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"source-meta.d.ts","sourceRoot":"","sources":["../src/lib/source-meta.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,WAAW,MAAM,cAAc,CAAC;AAE5C,yEAAyE;AACzE,eAAO,MAAM,eAAe,qCAAqC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,eAAe,mDAAqC,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,uDAAuD;AACvD,eAAO,MAAM,YAAY,SAAU,MAAM,SAAS,MAAM,KAAG,MAClB,CAAC;AA8I1C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,SACrB,MAAM,YACF,MAAM,MACZ,WAAW,KACd,OAiEF,CAAC"}
1
+ {"version":3,"file":"source-meta.d.ts","sourceRoot":"","sources":["../src/lib/source-meta.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,WAAW,MAAM,cAAc,CAAC;AAE5C,yEAAyE;AACzE,eAAO,MAAM,eAAe,qCAAqC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,eAAe,mDAAqC,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,uDAAuD;AACvD,eAAO,MAAM,YAAY,SAAU,MAAM,SAAS,MAAM,KAAG,MAClB,CAAC;AAsL1C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,SACrB,MAAM,YACF,MAAM,MACZ,WAAW,KACd,OAiEF,CAAC"}
@@ -13,6 +13,45 @@ export const SOURCE_META_SYM = `Symbol.for('${SOURCE_META_KEY}')`;
13
13
  /** 1-based line number for an index in source text. */
14
14
  export const lineNumberAt = (code, index) =>
15
15
  code.slice(0, index).split('\n').length;
16
+ /**
17
+ * Finds the `{` that opens the body of the class starting at `classStart`:
18
+ * the first one at the top level of the heading. The heading can hold braces
19
+ * of its own — type literals in generic arguments
20
+ * (`extends Dialog<{open: boolean}>`), options passed to a mixin
21
+ * (`extends Mixin(Base, {shadow: true})`) — so anything nested in `<…>`,
22
+ * `(…)` or `[…]` is skipped, along with strings and comments. The `>` of an
23
+ * arrow type (`() => void`) doesn't close a `<`.
24
+ */
25
+ const findClassBodyOpen = (code, classStart) => {
26
+ let depth = 0;
27
+ for (let i = classStart + 'class'.length; i < code.length; i++) {
28
+ const ch = code[i];
29
+ if (ch === '"' || ch === "'" || ch === '`') {
30
+ i++;
31
+ while (i < code.length && code[i] !== ch) {
32
+ if (code[i] === '\\') i++;
33
+ i++;
34
+ }
35
+ } else if (ch === '/' && code[i + 1] === '/') {
36
+ i = code.indexOf('\n', i);
37
+ if (i === -1) return -1;
38
+ } else if (ch === '/' && code[i + 1] === '*') {
39
+ i = code.indexOf('*/', i + 2);
40
+ if (i === -1) return -1;
41
+ i++;
42
+ } else if (ch === '{') {
43
+ if (depth === 0) return i;
44
+ depth++;
45
+ } else if (ch === '(' || ch === '[' || ch === '<') {
46
+ depth++;
47
+ } else if (ch === '}' || ch === ')' || ch === ']') {
48
+ depth--;
49
+ } else if (ch === '>' && code[i - 1] !== '=') {
50
+ depth--;
51
+ }
52
+ }
53
+ return -1;
54
+ };
16
55
  /**
17
56
  * Finds the index after the closing `}` of a class body starting at
18
57
  * `classStart`. Skips braces inside strings, comments, regex literals, and
@@ -20,7 +59,7 @@ export const lineNumberAt = (code, index) =>
20
59
  * templates (Lit's `html\`…\`` inside `.map()` etc.) recurse arbitrarily.
21
60
  */
22
61
  const findClassBodyEnd = (code, classStart) => {
23
- const open = code.indexOf('{', classStart);
62
+ const open = findClassBodyOpen(code, classStart);
24
63
  if (open === -1) return -1;
25
64
  // Brace depth of the code scope currently being scanned. Entering a `${…}`
26
65
  // interpolation pushes the enclosing scope's depth and restarts at 1 (the
@@ -1 +1 @@
1
- {"version":3,"file":"source-meta.js","sourceRoot":"","sources":["../src/lib/source-meta.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 MagicString from 'magic-string';\n\n/** Stable key shared between transform output and runtime resolution. */\nexport const SOURCE_META_KEY = '@lit-labs/vite-plugin-lit#source';\n\n/**\n * The expression string used in generated code to reference the shared\n * symbol at runtime.\n */\nexport const SOURCE_META_SYM = `Symbol.for('${SOURCE_META_KEY}')`;\n\nexport interface InjectedSourceMeta {\n filePath: string;\n lineNumber: number;\n componentName?: string;\n}\n\n/** 1-based line number for an index in source text. */\nexport const lineNumberAt = (code: string, index: number): number =>\n code.slice(0, index).split('\\n').length;\n\n/**\n * Finds the index after the closing `}` of a class body starting at\n * `classStart`. Skips braces inside strings, comments, regex literals, and\n * template literals — including code in `${…}` interpolations, where nested\n * templates (Lit's `html\\`…\\`` inside `.map()` etc.) recurse arbitrarily.\n */\nconst findClassBodyEnd = (code: string, classStart: number): number => {\n const open = code.indexOf('{', classStart);\n if (open === -1) return -1;\n // Brace depth of the code scope currently being scanned. Entering a `${…}`\n // interpolation pushes the enclosing scope's depth and restarts at 1 (the\n // `${` counts as the open brace); balancing it pops back into the template.\n let depth = 1;\n const interpolationStack: number[] = [];\n let inTemplate = false;\n let i = open + 1;\n while (i < code.length) {\n const ch = code[i];\n if (inTemplate) {\n if (ch === '\\\\') {\n i += 2;\n continue;\n }\n if (ch === '`') {\n inTemplate = false;\n i++;\n continue;\n }\n if (ch === '$' && code[i + 1] === '{') {\n interpolationStack.push(depth);\n depth = 1;\n inTemplate = false;\n i += 2;\n continue;\n }\n i++;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n i++;\n while (i < code.length && code[i] !== quote) {\n if (code[i] === '\\\\') i++;\n i++;\n }\n i++;\n continue;\n }\n if (ch === '`') {\n inTemplate = true;\n i++;\n continue;\n }\n if (ch === '/') {\n const next = code[i + 1];\n if (next === '/') {\n i = code.indexOf('\\n', i);\n if (i === -1) return -1;\n continue;\n }\n if (next === '*') {\n i = code.indexOf('*/', i + 2);\n if (i === -1) return -1;\n i += 2;\n continue;\n }\n // Regex literal vs division: scan back over whitespace to the last\n // significant char — a regex can only follow an operator, opening\n // punctuation, or a keyword like `return`. `a / b` has an identifier\n // there, so it's division and scans on as plain code.\n let j = i - 1;\n while (j >= 0 && /\\s/.test(code[j])) j--;\n const prev = j >= 0 ? code[j] : '';\n const regexPossible =\n j < 0 ||\n /[=:(,+\\-!&|?{}[;]/.test(prev) ||\n /(?:^|[^\\w$])(?:return|typeof|case|instanceof|in|of|new|delete|void|throw|do|else|yield|await)$/.test(\n code.slice(Math.max(0, j - 11), j + 1)\n );\n if (regexPossible) {\n let k = i + 1;\n let inCharClass = false;\n while (\n k < code.length &&\n code[k] !== '\\n' &&\n (inCharClass || code[k] !== '/')\n ) {\n if (code[k] === '\\\\') k++;\n else if (code[k] === '[') inCharClass = true;\n else if (code[k] === ']') inCharClass = false;\n k++;\n }\n if (code[k] === '/') {\n i = k + 1;\n continue;\n }\n // No closing `/` before the line ends — not a regex after all.\n }\n }\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const enclosing = interpolationStack.pop();\n if (enclosing === undefined) {\n return i + 1;\n }\n depth = enclosing;\n inTemplate = true;\n }\n }\n i++;\n }\n return -1;\n};\n\nconst makeAssignment = (\n className: string,\n filePath: string,\n lineNumber: number\n) =>\n `${className}[${SOURCE_META_SYM}]={filePath:${JSON.stringify(filePath)},lineNumber:${lineNumber},componentName:${JSON.stringify(className)}};`;\n\n/**\n * True when `className` is declared at module top level (column 0). Nested\n * declarations are skipped deliberately: the metadata assignment for this path\n * is appended at the end of the module, where a function/block-scoped binding\n * would not be in scope (a `ReferenceError` at module evaluation).\n */\nconst isClassDeclaredInModule = (code: string, className: string): boolean =>\n new RegExp(\n `^(?:export\\\\s+)?(?:class|let|const|var)\\\\s+${className}\\\\b`,\n 'm'\n ).test(code);\n\n/** True when `index` starts a line (module top level in emitted output). */\nconst isAtLineStart = (code: string, index: number): boolean =>\n index === 0 || code[index - 1] === '\\n';\n\n/**\n * Injects component source metadata onto custom element class constructors.\n * Returns whether any injection was made.\n */\nexport const injectSourceMeta = (\n code: string,\n filePath: string,\n ms: MagicString\n): boolean => {\n if (code.includes(SOURCE_META_SYM)) {\n return false;\n }\n let changed = false;\n const injected = new Set<string>();\n\n const injectAtClassEnd = (\n className: string,\n matchIndex: number,\n match: string\n ) => {\n if (injected.has(className)) return;\n const classOffset = match.indexOf('class');\n if (classOffset === -1) return;\n const classStart = matchIndex + classOffset;\n const end = findClassBodyEnd(code, classStart);\n if (end === -1) return;\n // Report the match start (the `@customElement` decorator) rather than the\n // `class` keyword, so the overlay points at the top of the component.\n const line = lineNumberAt(code, matchIndex);\n // Insert right after the class body so the assignment lives in the same\n // scope as the declaration — appending at module end breaks for a class\n // declared inside a function or block.\n ms.appendLeft(end, '\\n' + makeAssignment(className, filePath, line));\n injected.add(className);\n changed = true;\n };\n\n // @customElement(...) class Foo (any whitespace between them)\n for (const m of code.matchAll(\n /@customElement\\s*\\([^)]*\\)\\s+(?:export\\s+)?class\\s+(\\w+)/g\n )) {\n injectAtClassEnd(m[1], m.index, m[0]);\n }\n\n // customElements.define('tag', ClassName)\n for (const m of code.matchAll(\n /customElements\\.define\\s*\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*(\\w+)/g\n )) {\n const className = m[1];\n if (injected.has(className) || !isClassDeclaredInModule(code, className)) {\n continue;\n }\n const line = lineNumberAt(code, m.index);\n ms.append('\\n' + makeAssignment(className, filePath, line));\n injected.add(className);\n changed = true;\n }\n\n // TypeScript experimental-decorators / esbuild output\n // e.g. `Foo = __decorateClass([customElement(...)], Foo)`\n // `Foo = _decorate([customElement(...)], Foo)`\n for (const m of code.matchAll(\n /(\\w+)\\s*=\\s*__decorate\\w*\\(\\s*\\[[\\s\\S]*?customElement\\s*\\([^)]*\\)[\\s\\S]*?\\],\\s*\\1\\)/g\n )) {\n const className = m[1];\n if (injected.has(className) || !isAtLineStart(code, m.index)) continue;\n const line = lineNumberAt(code, m.index);\n ms.append('\\n' + makeAssignment(className, filePath, line));\n injected.add(className);\n changed = true;\n }\n\n return changed;\n};\n"]}
1
+ {"version":3,"file":"source-meta.js","sourceRoot":"","sources":["../src/lib/source-meta.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 MagicString from 'magic-string';\n\n/** Stable key shared between transform output and runtime resolution. */\nexport const SOURCE_META_KEY = '@lit-labs/vite-plugin-lit#source';\n\n/**\n * The expression string used in generated code to reference the shared\n * symbol at runtime.\n */\nexport const SOURCE_META_SYM = `Symbol.for('${SOURCE_META_KEY}')`;\n\nexport interface InjectedSourceMeta {\n filePath: string;\n lineNumber: number;\n componentName?: string;\n}\n\n/** 1-based line number for an index in source text. */\nexport const lineNumberAt = (code: string, index: number): number =>\n code.slice(0, index).split('\\n').length;\n\n/**\n * Finds the `{` that opens the body of the class starting at `classStart`:\n * the first one at the top level of the heading. The heading can hold braces\n * of its own — type literals in generic arguments\n * (`extends Dialog<{open: boolean}>`), options passed to a mixin\n * (`extends Mixin(Base, {shadow: true})`) — so anything nested in `<…>`,\n * `(…)` or `[…]` is skipped, along with strings and comments. The `>` of an\n * arrow type (`() => void`) doesn't close a `<`.\n */\nconst findClassBodyOpen = (code: string, classStart: number): number => {\n let depth = 0;\n for (let i = classStart + 'class'.length; i < code.length; i++) {\n const ch = code[i];\n if (ch === '\"' || ch === \"'\" || ch === '`') {\n i++;\n while (i < code.length && code[i] !== ch) {\n if (code[i] === '\\\\') i++;\n i++;\n }\n } else if (ch === '/' && code[i + 1] === '/') {\n i = code.indexOf('\\n', i);\n if (i === -1) return -1;\n } else if (ch === '/' && code[i + 1] === '*') {\n i = code.indexOf('*/', i + 2);\n if (i === -1) return -1;\n i++;\n } else if (ch === '{') {\n if (depth === 0) return i;\n depth++;\n } else if (ch === '(' || ch === '[' || ch === '<') {\n depth++;\n } else if (ch === '}' || ch === ')' || ch === ']') {\n depth--;\n } else if (ch === '>' && code[i - 1] !== '=') {\n depth--;\n }\n }\n return -1;\n};\n\n/**\n * Finds the index after the closing `}` of a class body starting at\n * `classStart`. Skips braces inside strings, comments, regex literals, and\n * template literals — including code in `${…}` interpolations, where nested\n * templates (Lit's `html\\`…\\`` inside `.map()` etc.) recurse arbitrarily.\n */\nconst findClassBodyEnd = (code: string, classStart: number): number => {\n const open = findClassBodyOpen(code, classStart);\n if (open === -1) return -1;\n // Brace depth of the code scope currently being scanned. Entering a `${…}`\n // interpolation pushes the enclosing scope's depth and restarts at 1 (the\n // `${` counts as the open brace); balancing it pops back into the template.\n let depth = 1;\n const interpolationStack: number[] = [];\n let inTemplate = false;\n let i = open + 1;\n while (i < code.length) {\n const ch = code[i];\n if (inTemplate) {\n if (ch === '\\\\') {\n i += 2;\n continue;\n }\n if (ch === '`') {\n inTemplate = false;\n i++;\n continue;\n }\n if (ch === '$' && code[i + 1] === '{') {\n interpolationStack.push(depth);\n depth = 1;\n inTemplate = false;\n i += 2;\n continue;\n }\n i++;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n i++;\n while (i < code.length && code[i] !== quote) {\n if (code[i] === '\\\\') i++;\n i++;\n }\n i++;\n continue;\n }\n if (ch === '`') {\n inTemplate = true;\n i++;\n continue;\n }\n if (ch === '/') {\n const next = code[i + 1];\n if (next === '/') {\n i = code.indexOf('\\n', i);\n if (i === -1) return -1;\n continue;\n }\n if (next === '*') {\n i = code.indexOf('*/', i + 2);\n if (i === -1) return -1;\n i += 2;\n continue;\n }\n // Regex literal vs division: scan back over whitespace to the last\n // significant char — a regex can only follow an operator, opening\n // punctuation, or a keyword like `return`. `a / b` has an identifier\n // there, so it's division and scans on as plain code.\n let j = i - 1;\n while (j >= 0 && /\\s/.test(code[j])) j--;\n const prev = j >= 0 ? code[j] : '';\n const regexPossible =\n j < 0 ||\n /[=:(,+\\-!&|?{}[;]/.test(prev) ||\n /(?:^|[^\\w$])(?:return|typeof|case|instanceof|in|of|new|delete|void|throw|do|else|yield|await)$/.test(\n code.slice(Math.max(0, j - 11), j + 1)\n );\n if (regexPossible) {\n let k = i + 1;\n let inCharClass = false;\n while (\n k < code.length &&\n code[k] !== '\\n' &&\n (inCharClass || code[k] !== '/')\n ) {\n if (code[k] === '\\\\') k++;\n else if (code[k] === '[') inCharClass = true;\n else if (code[k] === ']') inCharClass = false;\n k++;\n }\n if (code[k] === '/') {\n i = k + 1;\n continue;\n }\n // No closing `/` before the line ends — not a regex after all.\n }\n }\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const enclosing = interpolationStack.pop();\n if (enclosing === undefined) {\n return i + 1;\n }\n depth = enclosing;\n inTemplate = true;\n }\n }\n i++;\n }\n return -1;\n};\n\nconst makeAssignment = (\n className: string,\n filePath: string,\n lineNumber: number\n) =>\n `${className}[${SOURCE_META_SYM}]={filePath:${JSON.stringify(filePath)},lineNumber:${lineNumber},componentName:${JSON.stringify(className)}};`;\n\n/**\n * True when `className` is declared at module top level (column 0). Nested\n * declarations are skipped deliberately: the metadata assignment for this path\n * is appended at the end of the module, where a function/block-scoped binding\n * would not be in scope (a `ReferenceError` at module evaluation).\n */\nconst isClassDeclaredInModule = (code: string, className: string): boolean =>\n new RegExp(\n `^(?:export\\\\s+)?(?:class|let|const|var)\\\\s+${className}\\\\b`,\n 'm'\n ).test(code);\n\n/** True when `index` starts a line (module top level in emitted output). */\nconst isAtLineStart = (code: string, index: number): boolean =>\n index === 0 || code[index - 1] === '\\n';\n\n/**\n * Injects component source metadata onto custom element class constructors.\n * Returns whether any injection was made.\n */\nexport const injectSourceMeta = (\n code: string,\n filePath: string,\n ms: MagicString\n): boolean => {\n if (code.includes(SOURCE_META_SYM)) {\n return false;\n }\n let changed = false;\n const injected = new Set<string>();\n\n const injectAtClassEnd = (\n className: string,\n matchIndex: number,\n match: string\n ) => {\n if (injected.has(className)) return;\n const classOffset = match.indexOf('class');\n if (classOffset === -1) return;\n const classStart = matchIndex + classOffset;\n const end = findClassBodyEnd(code, classStart);\n if (end === -1) return;\n // Report the match start (the `@customElement` decorator) rather than the\n // `class` keyword, so the overlay points at the top of the component.\n const line = lineNumberAt(code, matchIndex);\n // Insert right after the class body so the assignment lives in the same\n // scope as the declaration — appending at module end breaks for a class\n // declared inside a function or block.\n ms.appendLeft(end, '\\n' + makeAssignment(className, filePath, line));\n injected.add(className);\n changed = true;\n };\n\n // @customElement(...) class Foo (any whitespace between them)\n for (const m of code.matchAll(\n /@customElement\\s*\\([^)]*\\)\\s+(?:export\\s+)?class\\s+(\\w+)/g\n )) {\n injectAtClassEnd(m[1], m.index, m[0]);\n }\n\n // customElements.define('tag', ClassName)\n for (const m of code.matchAll(\n /customElements\\.define\\s*\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*(\\w+)/g\n )) {\n const className = m[1];\n if (injected.has(className) || !isClassDeclaredInModule(code, className)) {\n continue;\n }\n const line = lineNumberAt(code, m.index);\n ms.append('\\n' + makeAssignment(className, filePath, line));\n injected.add(className);\n changed = true;\n }\n\n // TypeScript experimental-decorators / esbuild output\n // e.g. `Foo = __decorateClass([customElement(...)], Foo)`\n // `Foo = _decorate([customElement(...)], Foo)`\n for (const m of code.matchAll(\n /(\\w+)\\s*=\\s*__decorate\\w*\\(\\s*\\[[\\s\\S]*?customElement\\s*\\([^)]*\\)[\\s\\S]*?\\],\\s*\\1\\)/g\n )) {\n const className = m[1];\n if (injected.has(className) || !isAtLineStart(code, m.index)) continue;\n const line = lineNumberAt(code, m.index);\n ms.append('\\n' + makeAssignment(className, filePath, line));\n injected.add(className);\n changed = true;\n }\n\n return changed;\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oddsquad/vite-plugin-lit",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
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)",
@@ -44,13 +44,13 @@
44
44
  "url": "https://github.com/oddcelot/vite-plugin-lit/issues"
45
45
  },
46
46
  "dependencies": {
47
- "devframe": "1.0.0",
47
+ "devframe": "^1.1.0",
48
48
  "es-module-lexer": "^3.0.2",
49
49
  "launch-editor": "^2.14.1",
50
50
  "magic-string": "^1.4.1"
51
51
  },
52
52
  "peerDependencies": {
53
- "@devframes/agentic": "1.0.0",
53
+ "@devframes/agentic": "^1.0.0",
54
54
  "@vitejs/devtools-kit": "^0.7.5",
55
55
  "cac": "^7.0.0",
56
56
  "lightningcss": "^1.30.0",
@@ -72,14 +72,14 @@
72
72
  }
73
73
  },
74
74
  "devDependencies": {
75
- "@devframes/agentic": "1.0.0",
76
- "@devframes/service-open": "1.0.0",
75
+ "@devframes/agentic": "1.1.0",
76
+ "@devframes/service-open": "1.1.0",
77
77
  "@lit-labs/signals": "^0.3.0",
78
78
  "@lit-labs/virtualizer": "^2.1.1",
79
79
  "@lit/context": "^1.1.6",
80
80
  "@lit/task": "^1.0.3",
81
81
  "@types/node": "^26.6.1",
82
- "@vitejs/devtools-kit": "0.7.5",
82
+ "@vitejs/devtools-kit": "0.7.6",
83
83
  "cac": "7.0.0",
84
84
  "git-cliff": "^2.13.1",
85
85
  "lightningcss": "^1.33.0",
@@ -128,6 +128,12 @@ export interface SettingsOverride {
128
128
  * {@link SettingsOverride.flashUpdates}.
129
129
  */
130
130
  flashUpdatesRamp?: boolean;
131
+ /**
132
+ * Mirror the timeline into Chrome DevTools' Performance panel as custom
133
+ * tracks (via `console.timeStamp`), independent of panel recording. Pure
134
+ * preference (no config-time baseline), so `undefined` reads as off.
135
+ */
136
+ chromeTracks?: boolean;
131
137
  }
132
138
  /**
133
139
  * Built-in editors the source overlay can open files in. Keep in sync with
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/types/timeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/types/timeline.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../src/types/timeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkDH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,EAAC,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAC;IAC9D,EAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAC;IACxD,EAAC,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,QAAQ,EAAC;IAC1E,EAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAC;IAC9C,EAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAC;CACrD,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAwB;IACvD,cAAc,EAAE,KAAK;IACrB,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,IAAI;IACtB,uBAAuB,EAAE,KAAK;IAC9B,iBAAiB,EAAE,KAAK;IACxB,oBAAoB,EAAE,KAAK;CAC5B,CAAC;AAkFF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAG9B;IACH,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAC;IACnC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;IAClC,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAC;IAC5B,EAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAC;IAClC,EAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAC;CACvC,CAAC;AAEF,6DAA6D;AAC7D,MAAM,CAAC,MAAM,wBAAwB,GAAG,wBAAwB,CAAC;AAmBjE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,yBAAyB,GAAG,iCAAiC,CAAC;AAE3E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,yBAAyB,GAAG,gCAAgC,CAAC;AAE1E;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GACxC,oCAAoC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nexport interface TimelineLayer {\n id: string;\n label: string;\n color: number; // 0xRRGGBB\n}\n\nexport interface TimelineEvent<TData = unknown> {\n /**\n * Stable identity, stamped on the Node side (`${epoch}-${seq}`) when the\n * event is received, so it survives the stream, `recent-events` and a\n * snapshot export. Absent on events still in the page runtime.\n */\n id?: string;\n layerId: string;\n /**\n * Milliseconds since recording started, stamped in the browser page\n * (`performance.now()` re-zeroed on each recording start; see\n * `runtime/timeline/clock.ts`). Not comparable to any Node-side clock.\n */\n time: number;\n data: TData;\n title?: string;\n subtitle?: string;\n /** Pairs a start event with its matching end event in the same update group. */\n groupId?: number | string;\n logType?: 'default' | 'warning' | 'error';\n meta?: {\n elementId?: number;\n tagName?: string;\n source?: {file: string; line: number};\n };\n}\n\nexport interface TimelineLayersState {\n recordingState: boolean;\n litLifecycleEnabled: boolean;\n litRenderEnabled: boolean;\n /**\n * Per-part `lit-debug` events (`template updating`, `set part`, `commit\n * *`, …) — one per binding on *every* render, so a ticking clock or\n * animation floods the layer. Off by default; the `lit-render` layer's\n * begin/end render pair already covers the common case.\n */\n litRenderVerboseEnabled: boolean;\n mouseEventEnabled: boolean;\n keyboardEventEnabled: boolean;\n}\n\nexport const TIMELINE_LAYERS: readonly TimelineLayer[] = [\n {id: 'lit-lifecycle', label: 'Lit Lifecycle', color: 0x4d63ff},\n {id: 'lit-render', label: 'Lit Render', color: 0x325cff},\n {id: 'lit-render-verbose', label: 'Lit Render (verbose)', color: 0x99aeff},\n {id: 'mouse', label: 'Mouse', color: 0xa451af},\n {id: 'keyboard', label: 'Keyboard', color: 0x8151af},\n];\n\nexport const DEFAULT_LAYERS_STATE: TimelineLayersState = {\n recordingState: false,\n litLifecycleEnabled: true,\n litRenderEnabled: true,\n litRenderVerboseEnabled: false,\n mouseEventEnabled: false,\n keyboardEventEnabled: false,\n};\n\n/**\n * Snapshot of the plugin's resolved feature settings, surfaced in the panel's\n * Settings tab. The plugin produces this at config time (explicit options >\n * LIT_PLUGIN_* env > defaults) and serves it from the panel server. It's the\n * baseline the panel shows; some HMR settings can then be overridden live (see\n * {@link SettingsOverride}).\n */\nexport interface FeatureSettings {\n hmr: {\n enabled: boolean;\n reconnect: boolean;\n onIncompatible: 'reload' | 'warn';\n indicatorEnabled: boolean;\n indicatorCount: boolean;\n };\n sourceOverlay: {\n enabled: boolean;\n /** Hotkey letter combined with Ctrl+Shift to toggle the overlay. */\n key: string;\n editor: string;\n throttleMs: number;\n };\n timeline: boolean;\n /**\n * Which layer supplied each setting, keyed like {@link SettingsOverride}\n * (plus the read-only source-overlay rows). Lets the panel label a value\n * \"Zed (env)\" and name the baseline a panel override replaced. Optional so\n * older producers (and snapshots) without it still type-check.\n */\n sources?: SettingSources;\n}\n\n/**\n * Where a resolved setting came from, in precedence order after a panel\n * override: an explicit `litPlugin({...})` option, a `LIT_PLUGIN_*` env var,\n * or the built-in default.\n */\nexport type SettingSource = 'option' | 'env' | 'default';\n\n/** Per-setting {@link SettingSource}, as carried on {@link FeatureSettings}. */\nexport interface SettingSources {\n hmrReconnect?: SettingSource;\n hmrOnIncompatible?: SettingSource;\n hmrIndicatorVisible?: SettingSource;\n hmrIndicatorCount?: SettingSource;\n sourceOverlayEditor?: SettingSource;\n sourceOverlayKey?: SettingSource;\n sourceOverlayThrottleMs?: SettingSource;\n}\n\n/**\n * Runtime overrides the panel applies on top of the resolved env config, for\n * settings whose runtime is already injected (so they can change live). A\n * feature disabled at config time has no runtime, so it can't be enabled here\n * — only the behaviour of already-enabled features is overridable.\n *\n * Persisted under {@link SETTINGS_OVERRIDE_LS_KEY} (the panel and app share an\n * origin) so overrides survive reloads, and pushed live over\n * {@link SETTINGS_OVERRIDE_CHANNEL} via Vite HMR for immediate effect.\n */\nexport interface SettingsOverride {\n hmrReconnect?: boolean;\n hmrOnIncompatible?: 'reload' | 'warn';\n hmrIndicatorVisible?: boolean;\n hmrIndicatorCount?: boolean;\n /** Built-in editor key for the source overlay's open-in-editor target. */\n sourceOverlayEditor?: string;\n /**\n * Flash a short outline over every Lit element that completes an update.\n * Pure preference (no config-time baseline), so `undefined` reads as off.\n */\n flashUpdates?: boolean;\n /**\n * Colour the flash by how often the element updated in the last second,\n * calm to hot, instead of one flat colour. Only meaningful with\n * {@link SettingsOverride.flashUpdates}.\n */\n flashUpdatesRamp?: boolean;\n}\n\n/**\n * Built-in editors the source overlay can open files in. Keep in sync with\n * BUILTIN_EDITORS in lib/runtime/source-overlay/editors.ts.\n */\nexport const SOURCE_OVERLAY_EDITORS: ReadonlyArray<{\n value: string;\n label: string;\n}> = [\n {value: 'vscode', label: 'VS Code'},\n {value: 'cursor', label: 'Cursor'},\n {value: 'zed', label: 'Zed'},\n {value: 'idea', label: 'IntelliJ'},\n {value: 'windsurf', label: 'Windsurf'},\n];\n\n/** localStorage key holding the {@link SettingsOverride}. */\nexport const SETTINGS_OVERRIDE_LS_KEY = 'lit-devtools-overrides';\n\n/**\n * The resolved config value each overridden key was set against, recorded so\n * the Settings tab can notice when `.env` or plugin options moved on. Kept\n * beside the {@link SettingsOverride}, never inside it: the runtime applies and\n * receives the override as-is and has no use for these.\n */\nexport type OverrideBaselines = Partial<\n Record<\n | 'hmrReconnect'\n | 'hmrOnIncompatible'\n | 'hmrIndicatorVisible'\n | 'hmrIndicatorCount'\n | 'sourceOverlayEditor',\n unknown\n >\n>;\n\n/** localStorage key holding the {@link OverrideBaselines}. */\nexport const OVERRIDE_BASELINES_LS_KEY = 'lit-devtools-override-baselines';\n\n/** Vite HMR channel the server uses to push overrides to the app runtime. */\nexport const SETTINGS_OVERRIDE_CHANNEL = 'lit-devtools:settings-override';\n\n/**\n * Vite HMR channel the DevTools \"toggle source overlay\" command uses to tell\n * the app runtime to toggle the overlay (the command handler runs server-side).\n */\nexport const SOURCE_OVERLAY_TOGGLE_CHANNEL =\n 'lit-devtools:toggle-source-overlay';\n"]}
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../src/types/timeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkDH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,EAAC,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAC;IAC9D,EAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAC;IACxD,EAAC,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,QAAQ,EAAC;IAC1E,EAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAC;IAC9C,EAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAC;CACrD,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAwB;IACvD,cAAc,EAAE,KAAK;IACrB,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,IAAI;IACtB,uBAAuB,EAAE,KAAK;IAC9B,iBAAiB,EAAE,KAAK;IACxB,oBAAoB,EAAE,KAAK;CAC5B,CAAC;AAwFF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAG9B;IACH,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAC;IACnC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;IAClC,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAC;IAC5B,EAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAC;IAClC,EAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAC;CACvC,CAAC;AAEF,6DAA6D;AAC7D,MAAM,CAAC,MAAM,wBAAwB,GAAG,wBAAwB,CAAC;AAmBjE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,yBAAyB,GAAG,iCAAiC,CAAC;AAE3E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,yBAAyB,GAAG,gCAAgC,CAAC;AAE1E;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GACxC,oCAAoC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nexport interface TimelineLayer {\n id: string;\n label: string;\n color: number; // 0xRRGGBB\n}\n\nexport interface TimelineEvent<TData = unknown> {\n /**\n * Stable identity, stamped on the Node side (`${epoch}-${seq}`) when the\n * event is received, so it survives the stream, `recent-events` and a\n * snapshot export. Absent on events still in the page runtime.\n */\n id?: string;\n layerId: string;\n /**\n * Milliseconds since recording started, stamped in the browser page\n * (`performance.now()` re-zeroed on each recording start; see\n * `runtime/timeline/clock.ts`). Not comparable to any Node-side clock.\n */\n time: number;\n data: TData;\n title?: string;\n subtitle?: string;\n /** Pairs a start event with its matching end event in the same update group. */\n groupId?: number | string;\n logType?: 'default' | 'warning' | 'error';\n meta?: {\n elementId?: number;\n tagName?: string;\n source?: {file: string; line: number};\n };\n}\n\nexport interface TimelineLayersState {\n recordingState: boolean;\n litLifecycleEnabled: boolean;\n litRenderEnabled: boolean;\n /**\n * Per-part `lit-debug` events (`template updating`, `set part`, `commit\n * *`, …) — one per binding on *every* render, so a ticking clock or\n * animation floods the layer. Off by default; the `lit-render` layer's\n * begin/end render pair already covers the common case.\n */\n litRenderVerboseEnabled: boolean;\n mouseEventEnabled: boolean;\n keyboardEventEnabled: boolean;\n}\n\nexport const TIMELINE_LAYERS: readonly TimelineLayer[] = [\n {id: 'lit-lifecycle', label: 'Lit Lifecycle', color: 0x4d63ff},\n {id: 'lit-render', label: 'Lit Render', color: 0x325cff},\n {id: 'lit-render-verbose', label: 'Lit Render (verbose)', color: 0x99aeff},\n {id: 'mouse', label: 'Mouse', color: 0xa451af},\n {id: 'keyboard', label: 'Keyboard', color: 0x8151af},\n];\n\nexport const DEFAULT_LAYERS_STATE: TimelineLayersState = {\n recordingState: false,\n litLifecycleEnabled: true,\n litRenderEnabled: true,\n litRenderVerboseEnabled: false,\n mouseEventEnabled: false,\n keyboardEventEnabled: false,\n};\n\n/**\n * Snapshot of the plugin's resolved feature settings, surfaced in the panel's\n * Settings tab. The plugin produces this at config time (explicit options >\n * LIT_PLUGIN_* env > defaults) and serves it from the panel server. It's the\n * baseline the panel shows; some HMR settings can then be overridden live (see\n * {@link SettingsOverride}).\n */\nexport interface FeatureSettings {\n hmr: {\n enabled: boolean;\n reconnect: boolean;\n onIncompatible: 'reload' | 'warn';\n indicatorEnabled: boolean;\n indicatorCount: boolean;\n };\n sourceOverlay: {\n enabled: boolean;\n /** Hotkey letter combined with Ctrl+Shift to toggle the overlay. */\n key: string;\n editor: string;\n throttleMs: number;\n };\n timeline: boolean;\n /**\n * Which layer supplied each setting, keyed like {@link SettingsOverride}\n * (plus the read-only source-overlay rows). Lets the panel label a value\n * \"Zed (env)\" and name the baseline a panel override replaced. Optional so\n * older producers (and snapshots) without it still type-check.\n */\n sources?: SettingSources;\n}\n\n/**\n * Where a resolved setting came from, in precedence order after a panel\n * override: an explicit `litPlugin({...})` option, a `LIT_PLUGIN_*` env var,\n * or the built-in default.\n */\nexport type SettingSource = 'option' | 'env' | 'default';\n\n/** Per-setting {@link SettingSource}, as carried on {@link FeatureSettings}. */\nexport interface SettingSources {\n hmrReconnect?: SettingSource;\n hmrOnIncompatible?: SettingSource;\n hmrIndicatorVisible?: SettingSource;\n hmrIndicatorCount?: SettingSource;\n sourceOverlayEditor?: SettingSource;\n sourceOverlayKey?: SettingSource;\n sourceOverlayThrottleMs?: SettingSource;\n}\n\n/**\n * Runtime overrides the panel applies on top of the resolved env config, for\n * settings whose runtime is already injected (so they can change live). A\n * feature disabled at config time has no runtime, so it can't be enabled here\n * — only the behaviour of already-enabled features is overridable.\n *\n * Persisted under {@link SETTINGS_OVERRIDE_LS_KEY} (the panel and app share an\n * origin) so overrides survive reloads, and pushed live over\n * {@link SETTINGS_OVERRIDE_CHANNEL} via Vite HMR for immediate effect.\n */\nexport interface SettingsOverride {\n hmrReconnect?: boolean;\n hmrOnIncompatible?: 'reload' | 'warn';\n hmrIndicatorVisible?: boolean;\n hmrIndicatorCount?: boolean;\n /** Built-in editor key for the source overlay's open-in-editor target. */\n sourceOverlayEditor?: string;\n /**\n * Flash a short outline over every Lit element that completes an update.\n * Pure preference (no config-time baseline), so `undefined` reads as off.\n */\n flashUpdates?: boolean;\n /**\n * Colour the flash by how often the element updated in the last second,\n * calm to hot, instead of one flat colour. Only meaningful with\n * {@link SettingsOverride.flashUpdates}.\n */\n flashUpdatesRamp?: boolean;\n /**\n * Mirror the timeline into Chrome DevTools' Performance panel as custom\n * tracks (via `console.timeStamp`), independent of panel recording. Pure\n * preference (no config-time baseline), so `undefined` reads as off.\n */\n chromeTracks?: boolean;\n}\n\n/**\n * Built-in editors the source overlay can open files in. Keep in sync with\n * BUILTIN_EDITORS in lib/runtime/source-overlay/editors.ts.\n */\nexport const SOURCE_OVERLAY_EDITORS: ReadonlyArray<{\n value: string;\n label: string;\n}> = [\n {value: 'vscode', label: 'VS Code'},\n {value: 'cursor', label: 'Cursor'},\n {value: 'zed', label: 'Zed'},\n {value: 'idea', label: 'IntelliJ'},\n {value: 'windsurf', label: 'Windsurf'},\n];\n\n/** localStorage key holding the {@link SettingsOverride}. */\nexport const SETTINGS_OVERRIDE_LS_KEY = 'lit-devtools-overrides';\n\n/**\n * The resolved config value each overridden key was set against, recorded so\n * the Settings tab can notice when `.env` or plugin options moved on. Kept\n * beside the {@link SettingsOverride}, never inside it: the runtime applies and\n * receives the override as-is and has no use for these.\n */\nexport type OverrideBaselines = Partial<\n Record<\n | 'hmrReconnect'\n | 'hmrOnIncompatible'\n | 'hmrIndicatorVisible'\n | 'hmrIndicatorCount'\n | 'sourceOverlayEditor',\n unknown\n >\n>;\n\n/** localStorage key holding the {@link OverrideBaselines}. */\nexport const OVERRIDE_BASELINES_LS_KEY = 'lit-devtools-override-baselines';\n\n/** Vite HMR channel the server uses to push overrides to the app runtime. */\nexport const SETTINGS_OVERRIDE_CHANNEL = 'lit-devtools:settings-override';\n\n/**\n * Vite HMR channel the DevTools \"toggle source overlay\" command uses to tell\n * the app runtime to toggle the overlay (the command handler runs server-side).\n */\nexport const SOURCE_OVERLAY_TOGGLE_CHANNEL =\n 'lit-devtools:toggle-source-overlay';\n"]}