@oddsquad/vite-plugin-lit 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +28 -12
  3. package/bin.mjs +87 -5
  4. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-F2EfZsFX.js → browser-agent-rpc-BXhoSh1z-BuCvPGjS.js} +2 -2
  5. package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-F2EfZsFX.js.map → browser-agent-rpc-BXhoSh1z-BuCvPGjS.js.map} +1 -1
  6. package/dist/client/assets/{index-B2HYO7lk.js → index-D632jo79.js} +22 -3
  7. package/dist/client/assets/index-D632jo79.js.map +1 -0
  8. package/dist/client/index.html +1 -1
  9. package/dist/standalone/lit-devtools.js +6820 -0
  10. package/lib/devframe/allowed-origins.d.ts +13 -0
  11. package/lib/devframe/allowed-origins.d.ts.map +1 -0
  12. package/lib/devframe/allowed-origins.js +63 -0
  13. package/lib/devframe/allowed-origins.js.map +1 -0
  14. package/lib/options.d.ts +26 -0
  15. package/lib/options.d.ts.map +1 -1
  16. package/lib/options.js +19 -0
  17. package/lib/options.js.map +1 -1
  18. package/lib/plugin.d.ts.map +1 -1
  19. package/lib/plugin.js +3 -0
  20. package/lib/plugin.js.map +1 -1
  21. package/lib/plugins/private-fields.d.ts +27 -0
  22. package/lib/plugins/private-fields.d.ts.map +1 -0
  23. package/lib/plugins/private-fields.js +259 -0
  24. package/lib/plugins/private-fields.js.map +1 -0
  25. package/lib/runtime/child-state.d.ts +100 -0
  26. package/lib/runtime/child-state.d.ts.map +1 -0
  27. package/lib/runtime/child-state.js +446 -0
  28. package/lib/runtime/child-state.js.map +1 -0
  29. package/lib/runtime/inspector/install.js +4 -1
  30. package/lib/runtime/inspector/install.js.map +1 -1
  31. package/lib/runtime/patch.d.ts +24 -0
  32. package/lib/runtime/patch.d.ts.map +1 -1
  33. package/lib/runtime/patch.js +22 -1
  34. package/lib/runtime/patch.js.map +1 -1
  35. package/lib/runtime/rpc-transport.d.ts +8 -0
  36. package/lib/runtime/rpc-transport.d.ts.map +1 -1
  37. package/lib/runtime/rpc-transport.js +1 -0
  38. package/lib/runtime/rpc-transport.js.map +1 -1
  39. package/lib/runtime/source-overlay/editors.d.ts.map +1 -1
  40. package/lib/runtime/source-overlay/editors.js +9 -4
  41. package/lib/runtime/source-overlay/editors.js.map +1 -1
  42. package/lib/runtime/standalone.d.ts +27 -0
  43. package/lib/runtime/standalone.d.ts.map +1 -0
  44. package/lib/runtime/standalone.js +50 -0
  45. package/lib/runtime/standalone.js.map +1 -0
  46. package/lib/runtime/timeline/install.js +4 -2
  47. package/lib/runtime/timeline/install.js.map +1 -1
  48. package/lib/runtime/timeline/lifecycle.d.ts.map +1 -1
  49. package/lib/runtime/timeline/lifecycle.js +5 -1
  50. package/lib/runtime/timeline/lifecycle.js.map +1 -1
  51. package/package.json +13 -9
  52. package/types/timeline.d.ts +4 -1
  53. package/types/timeline.d.ts.map +1 -1
  54. package/types/timeline.js.map +1 -1
  55. package/dist/client/assets/index-B2HYO7lk.js.map +0 -1
@@ -0,0 +1,446 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ /** `Symbol.for` description prefix of the dev-only `#private` rewrite. */
7
+ export const PRIVATE_KEY_PREFIX = '@oddsquad/vite-plugin-lit#private:';
8
+ /** Hard cap on how long a transfer window stays open. */
9
+ export const WINDOW_CAP_MS = 1000;
10
+ const ATTRIBUTE_PART = 1;
11
+ const CHILD_PART = 2;
12
+ const PROPERTY_PART = 3;
13
+ const BOOLEAN_PART = 4;
14
+ /** Dev name, then the stable minified name from lit-html's prod build. */
15
+ const COMMITTED = ['_$committedValue', '_$AH'];
16
+ const TEMPLATE = ['_$template', '_$AD'];
17
+ const PARTS = ['_$parts', '_$AV'];
18
+ const START = ['_$startNode', '_$AA'];
19
+ const END = ['_$endNode', '_$AB'];
20
+ const LIT_PART = '_$litPart$';
21
+ const internal = (o, [dev, prod]) => {
22
+ if (o === null || typeof o !== 'object') {
23
+ return undefined;
24
+ }
25
+ const r = o;
26
+ return dev in r ? r[dev] : r[prod];
27
+ };
28
+ const isPart = (p) =>
29
+ p !== null && typeof p === 'object' && typeof p.type === 'number';
30
+ const MAX_PARTS = 100_000;
31
+ /** Pushes `part` and, through child parts' committed values, every part below. */
32
+ const walkParts = (part, out) => {
33
+ if (out.length > MAX_PARTS) {
34
+ throw new Error('part tree too large');
35
+ }
36
+ out.push(part);
37
+ if (part.type !== CHILD_PART) {
38
+ return;
39
+ }
40
+ const value = internal(part, COMMITTED);
41
+ if (Array.isArray(value)) {
42
+ // An iterable's committed value is an array of ChildParts.
43
+ for (const child of value) {
44
+ if (isPart(child)) {
45
+ walkParts(child, out);
46
+ }
47
+ }
48
+ return;
49
+ }
50
+ const parts = internal(value, PARTS);
51
+ if (Array.isArray(parts) && internal(value, TEMPLATE) !== undefined) {
52
+ for (const child of parts) {
53
+ // Entries may be undefined (parts removed by the polyfill/hydration).
54
+ if (isPart(child)) {
55
+ walkParts(child, out);
56
+ }
57
+ }
58
+ }
59
+ };
60
+ /**
61
+ * Every lit-html part rendered into the tree `el` lives in: the parts of each
62
+ * render container (`_$litPart$`) among `el`'s ancestors up to its root.
63
+ * `undefined` when `el` isn't in a tree or the walk hits a surprise.
64
+ */
65
+ export const partsAround = (el) => {
66
+ try {
67
+ const out = [];
68
+ let node = el.parentNode;
69
+ if (node === null) {
70
+ return undefined;
71
+ }
72
+ while (node !== null) {
73
+ const root = node[LIT_PART];
74
+ if (isPart(root)) {
75
+ walkParts(root, out);
76
+ }
77
+ node = node.parentNode;
78
+ }
79
+ return out;
80
+ } catch {
81
+ return undefined;
82
+ }
83
+ };
84
+ /** Attribute name → reactive property key for an element's class. */
85
+ const attributeMap = (ctor) => {
86
+ // Dev builds keep the name; prod mangles it, so rebuild from options.
87
+ const own = ctor.__attributeToPropertyMap;
88
+ if (own instanceof Map) {
89
+ return own;
90
+ }
91
+ const map = new Map();
92
+ const props = ctor.elementProperties;
93
+ if (!(props instanceof Map)) {
94
+ return map;
95
+ }
96
+ for (const [key, options] of props) {
97
+ const attribute = options?.attribute;
98
+ if (attribute === false) {
99
+ continue;
100
+ }
101
+ if (typeof attribute === 'string') {
102
+ map.set(attribute, key);
103
+ } else if (typeof key === 'string') {
104
+ map.set(key.toLowerCase(), key);
105
+ }
106
+ }
107
+ return map;
108
+ };
109
+ const propertyKeys = (ctor) => {
110
+ const props = ctor?.elementProperties;
111
+ return props instanceof Map ? [...props.keys()] : [];
112
+ };
113
+ /**
114
+ * Reactive property keys the new element already got from its template:
115
+ * keys whose attribute is present on it (static attributes), plus, when the
116
+ * part tree could be read, keys bound by a property, boolean or attribute
117
+ * part targeting it.
118
+ */
119
+ export const templateDrivenKeys = (el, parts) => {
120
+ const keys = new Set();
121
+ const ctor = el.constructor;
122
+ const attrs = attributeMap(ctor);
123
+ try {
124
+ for (const attr of Array.from(el.attributes)) {
125
+ const key = attrs.get(attr.name.toLowerCase());
126
+ if (key !== undefined) {
127
+ keys.add(key);
128
+ }
129
+ }
130
+ } catch {
131
+ // No attributes to read.
132
+ }
133
+ for (const part of parts ?? []) {
134
+ if (part.element !== el || typeof part.name !== 'string') {
135
+ continue;
136
+ }
137
+ if (part.type === PROPERTY_PART) {
138
+ keys.add(part.name);
139
+ } else if (part.type === ATTRIBUTE_PART || part.type === BOOLEAN_PART) {
140
+ keys.add(attrs.get(part.name.toLowerCase()) ?? part.name);
141
+ }
142
+ }
143
+ return keys;
144
+ };
145
+ /** Own symbol keys of `el` minted by the dev-only `#private` rewrite. */
146
+ export const privateKeys = (el) =>
147
+ Object.getOwnPropertySymbols(el).filter((sym) =>
148
+ (Symbol.keyFor(sym) ?? '').startsWith(PRIVATE_KEY_PREFIX)
149
+ );
150
+ /**
151
+ * Copies `from`'s state onto `to`: reactive properties not driven by `to`'s
152
+ * template, and the `#private` members the dev rewrite turned into
153
+ * `Symbol.for` keys. Nothing else — Lit's own bookkeeping lives in string
154
+ * keys and must stay per-instance.
155
+ */
156
+ export const transferState = (from, to, parts) => {
157
+ const skip = templateDrivenKeys(to, parts);
158
+ const keys = new Set([
159
+ ...propertyKeys(to.constructor),
160
+ ...propertyKeys(from.constructor),
161
+ ]);
162
+ const src = from;
163
+ const dst = to;
164
+ for (const key of keys) {
165
+ if (skip.has(key)) {
166
+ continue;
167
+ }
168
+ try {
169
+ dst[key] = src[key];
170
+ } catch {
171
+ // A throwing setter; leave the default.
172
+ }
173
+ }
174
+ for (const sym of privateKeys(from)) {
175
+ try {
176
+ Object.defineProperty(
177
+ to,
178
+ sym,
179
+ Object.getOwnPropertyDescriptor(from, sym)
180
+ );
181
+ } catch {
182
+ // Non-configurable on the target; leave it.
183
+ }
184
+ }
185
+ };
186
+ const inside = (el, node) =>
187
+ node !== null &&
188
+ typeof node === 'object' &&
189
+ typeof node.nodeType === 'number' &&
190
+ el.contains(node);
191
+ /**
192
+ * Whether `el` (and its light DOM) carries no bindings, so another element
193
+ * can take its place without lit-html noticing: no part targets it or an
194
+ * element inside it, no child part's markers or parent lie inside it, and
195
+ * nothing rendered into it as a container. `false` when `parts` is unknown.
196
+ */
197
+ export const isReuseSafe = (el, parts) => {
198
+ if (parts === undefined) {
199
+ return false;
200
+ }
201
+ try {
202
+ if (LIT_PART in el) {
203
+ return false;
204
+ }
205
+ for (const part of parts) {
206
+ if (inside(el, part.element)) {
207
+ return false;
208
+ }
209
+ if (part.type === CHILD_PART) {
210
+ const start = internal(part, START);
211
+ const end = internal(part, END);
212
+ if (
213
+ inside(el, start) ||
214
+ inside(el, end) ||
215
+ inside(el, start?.parentNode) ||
216
+ inside(el, end?.parentNode)
217
+ ) {
218
+ return false;
219
+ }
220
+ }
221
+ }
222
+ return true;
223
+ } catch {
224
+ return false;
225
+ }
226
+ };
227
+ /**
228
+ * Puts `old` back where `fresh` is: `old` takes `fresh`'s attributes and
229
+ * light-DOM children, then replaces it. `old` keeps its identity, state,
230
+ * shadow DOM and controllers, and reconnects.
231
+ */
232
+ export const swapBack = (old, fresh) => {
233
+ for (const attr of Array.from(old.attributes)) {
234
+ if (!fresh.hasAttribute(attr.name)) {
235
+ old.removeAttribute(attr.name);
236
+ }
237
+ }
238
+ for (const attr of Array.from(fresh.attributes)) {
239
+ if (old.getAttribute(attr.name) !== attr.value) {
240
+ old.setAttribute(attr.name, attr.value);
241
+ }
242
+ }
243
+ old.replaceChildren(...Array.from(fresh.childNodes));
244
+ fresh.replaceWith(old);
245
+ };
246
+ export const createChildState = (options) => {
247
+ const capMs = options.capMs ?? WINDOW_CAP_MS;
248
+ /** The root each element was last connected in. */
249
+ const rootOf = new WeakMap();
250
+ let current;
251
+ const close = (w) => {
252
+ if (current !== w) {
253
+ return;
254
+ }
255
+ current = undefined;
256
+ clearTimeout(w.idle);
257
+ clearTimeout(w.cap);
258
+ // Reuse only once everything we waited on has settled; on the hard cap
259
+ // with updates still outstanding, the transferred state stands.
260
+ if (w.mode !== 'reuse' || w.waiting > 0) {
261
+ return;
262
+ }
263
+ for (const [old, fresh] of w.pairs) {
264
+ // A pair inside an element that was itself swapped back is moot:
265
+ // the old element's shadow DOM came back intact with it.
266
+ if (!fresh.isConnected || old.isConnected) {
267
+ continue;
268
+ }
269
+ try {
270
+ if (isReuseSafe(fresh, partsAround(fresh))) {
271
+ swapBack(old, fresh);
272
+ }
273
+ } catch {
274
+ // Leave the new element (it already has the transferred state).
275
+ }
276
+ }
277
+ };
278
+ /** Close once a macrotask passes with no tracked activity. */
279
+ const settle = (w) => {
280
+ if (current !== w || w.waiting > 0) {
281
+ return;
282
+ }
283
+ clearTimeout(w.idle);
284
+ w.idle = setTimeout(() => close(w), 0);
285
+ };
286
+ /** The pending-queue root for an element now connected in `root`. */
287
+ const keyRoot = (w, root) => {
288
+ const host = root.host;
289
+ const old = host === undefined ? undefined : w.pairOf.get(host);
290
+ if (old !== undefined) {
291
+ // Re-created inside a new element's shadow: match against what was
292
+ // dropped from the old element's shadow.
293
+ const oldRoot = old.renderRoot ?? old.shadowRoot;
294
+ if (oldRoot !== undefined && oldRoot !== null && w.pending.has(oldRoot)) {
295
+ return oldRoot;
296
+ }
297
+ }
298
+ return root;
299
+ };
300
+ const unqueue = (w, el) => {
301
+ const at = w.pendingOf.get(el);
302
+ if (at === undefined) {
303
+ return;
304
+ }
305
+ w.pendingOf.delete(el);
306
+ const queue = w.pending.get(at.root)?.get(at.tag);
307
+ const i = queue?.indexOf(el) ?? -1;
308
+ if (i >= 0) {
309
+ queue.splice(i, 1);
310
+ }
311
+ };
312
+ const pair = (w, fresh, root) => {
313
+ const queue = w.pending.get(keyRoot(w, root))?.get(fresh.localName);
314
+ const old = queue?.shift();
315
+ if (old === undefined) {
316
+ return;
317
+ }
318
+ w.pendingOf.delete(old);
319
+ w.pairOf.set(fresh, old);
320
+ const origin = w.originOf.get(old) ?? old;
321
+ w.originOf.set(fresh, origin);
322
+ w.pairs.push([origin, fresh]);
323
+ // lit-html assigns the new template instance to its part only after the
324
+ // fragment is inserted, so the parts targeting `fresh` aren't reachable
325
+ // yet. Queued before the original connectedCallback enables updating,
326
+ // this runs ahead of `fresh`'s first update.
327
+ queueMicrotask(() => {
328
+ try {
329
+ transferState(old, fresh, partsAround(fresh));
330
+ } catch {
331
+ // Keep the defaults.
332
+ }
333
+ });
334
+ };
335
+ return {
336
+ connected(el, fresh) {
337
+ let root;
338
+ try {
339
+ root = el.getRootNode();
340
+ } catch {
341
+ root = undefined;
342
+ }
343
+ const w = current;
344
+ if (w !== undefined) {
345
+ try {
346
+ if (fresh && root !== undefined && el.hasUpdated !== true) {
347
+ pair(w, el, root);
348
+ } else {
349
+ // Moved, not re-created: it can't be anyone's replacement.
350
+ unqueue(w, el);
351
+ }
352
+ } catch {
353
+ // Pairing is best-effort.
354
+ }
355
+ settle(w);
356
+ }
357
+ if (root !== undefined) {
358
+ rootOf.set(el, root);
359
+ }
360
+ },
361
+ disconnected(el) {
362
+ const w = current;
363
+ if (w === undefined) {
364
+ return;
365
+ }
366
+ const root = rootOf.get(el);
367
+ if (root !== undefined) {
368
+ const tag = el.localName;
369
+ let byTag = w.pending.get(root);
370
+ if (byTag === undefined) {
371
+ w.pending.set(root, (byTag = new Map()));
372
+ }
373
+ let queue = byTag.get(tag);
374
+ if (queue === undefined) {
375
+ byTag.set(tag, (queue = []));
376
+ }
377
+ unqueue(w, el);
378
+ queue.push(el);
379
+ w.pendingOf.set(el, {root, tag});
380
+ }
381
+ settle(w);
382
+ },
383
+ open() {
384
+ const mode = options.mode();
385
+ if (mode !== 'transfer' && mode !== 'reuse') {
386
+ return;
387
+ }
388
+ let w = current;
389
+ if (w === undefined) {
390
+ w = current = {
391
+ mode,
392
+ pending: new Map(),
393
+ pendingOf: new Map(),
394
+ pairs: [],
395
+ pairOf: new Map(),
396
+ originOf: new Map(),
397
+ waiting: 0,
398
+ };
399
+ }
400
+ w.mode = mode;
401
+ clearTimeout(w.cap);
402
+ const opened = w;
403
+ w.cap = setTimeout(() => close(opened), capMs);
404
+ settle(w);
405
+ },
406
+ watch(els) {
407
+ const w = current;
408
+ if (w === undefined) {
409
+ return;
410
+ }
411
+ const promises = [];
412
+ for (const el of els) {
413
+ try {
414
+ const p = el.updateComplete;
415
+ if (p instanceof Promise) {
416
+ promises.push(p);
417
+ }
418
+ } catch {
419
+ // No update promise to wait on.
420
+ }
421
+ }
422
+ w.waiting++;
423
+ clearTimeout(w.idle);
424
+ let left = promises.length + 1;
425
+ const done = () => {
426
+ if (--left === 0) {
427
+ w.waiting--;
428
+ settle(w);
429
+ }
430
+ };
431
+ for (const p of promises) {
432
+ // Rethrow: a failed update must still surface as an unhandled
433
+ // rejection, exactly as it would with nobody watching.
434
+ void p.then(done, (e) => {
435
+ done();
436
+ throw e;
437
+ });
438
+ }
439
+ queueMicrotask(done);
440
+ },
441
+ get active() {
442
+ return current !== undefined;
443
+ },
444
+ };
445
+ };
446
+ //# sourceMappingURL=child-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-state.js","sourceRoot":"","sources":["../../src/lib/runtime/child-state.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 * Carries child element state across a template re-instantiation.\n *\n * When a hot patch changes a template's text, lit-html sees a new template,\n * clones fresh DOM and swaps it in: every custom element inside the edited\n * template is re-created and starts from its defaults. For a short window\n * after a hot patch this module pairs each element dropped from a root with\n * the next freshly created element of the same tag connected in that root\n * (FIFO, i.e. document order), then either copies the old element's state\n * onto the new one (`'transfer'`) or, where the new element carries no\n * bindings, puts the old element back in its place (`'reuse'`).\n *\n * Dependency-free and duck-typed like `patch.ts`. The lit-html internals it\n * reads (`_$litPart$`, `_$committedValue`, `_$template`, `_$parts`,\n * `_$startNode`, `_$endNode`) are looked up by their development names first\n * and then by the stable minified names lit's prod build gives them\n * (`_$AH`, `_$AD`, `_$AV`, `_$AA`, `_$AB`). Every access is guarded; when the\n * part tree can't be read, transfer skips only attribute-driven keys and\n * reuse falls back to transfer.\n */\n\nexport type ChildStateMode = 'reset' | 'transfer' | 'reuse';\n\n/** `Symbol.for` description prefix of the dev-only `#private` rewrite. */\nexport const PRIVATE_KEY_PREFIX = '@oddsquad/vite-plugin-lit#private:';\n\n/** Hard cap on how long a transfer window stays open. */\nexport const WINDOW_CAP_MS = 1000;\n\nconst ATTRIBUTE_PART = 1;\nconst CHILD_PART = 2;\nconst PROPERTY_PART = 3;\nconst BOOLEAN_PART = 4;\n\n/** Dev name, then the stable minified name from lit-html's prod build. */\nconst COMMITTED = ['_$committedValue', '_$AH'] as const;\nconst TEMPLATE = ['_$template', '_$AD'] as const;\nconst PARTS = ['_$parts', '_$AV'] as const;\nconst START = ['_$startNode', '_$AA'] as const;\nconst END = ['_$endNode', '_$AB'] as const;\nconst LIT_PART = '_$litPart$';\n\n/** Duck-typed lit-html part. */\nexport interface PartLike {\n type: number;\n element?: unknown;\n name?: unknown;\n}\n\n/** Duck-typed element the window works with. */\nexport type ElementLike = HTMLElement & {\n renderRoot?: unknown;\n hasUpdated?: boolean;\n updateComplete?: unknown;\n};\n\ninterface CtorLike {\n elementProperties?: Map<PropertyKey, {attribute?: unknown} | undefined>;\n __attributeToPropertyMap?: unknown;\n}\n\nconst internal = (\n o: unknown,\n [dev, prod]: readonly [string, string]\n): unknown => {\n if (o === null || typeof o !== 'object') {\n return undefined;\n }\n const r = o as Record<string, unknown>;\n return dev in r ? r[dev] : r[prod];\n};\n\nconst isPart = (p: unknown): p is PartLike =>\n p !== null &&\n typeof p === 'object' &&\n typeof (p as PartLike).type === 'number';\n\nconst MAX_PARTS = 100_000;\n\n/** Pushes `part` and, through child parts' committed values, every part below. */\nconst walkParts = (part: PartLike, out: PartLike[]): void => {\n if (out.length > MAX_PARTS) {\n throw new Error('part tree too large');\n }\n out.push(part);\n if (part.type !== CHILD_PART) {\n return;\n }\n const value = internal(part, COMMITTED);\n if (Array.isArray(value)) {\n // An iterable's committed value is an array of ChildParts.\n for (const child of value) {\n if (isPart(child)) {\n walkParts(child, out);\n }\n }\n return;\n }\n const parts = internal(value, PARTS);\n if (Array.isArray(parts) && internal(value, TEMPLATE) !== undefined) {\n for (const child of parts) {\n // Entries may be undefined (parts removed by the polyfill/hydration).\n if (isPart(child)) {\n walkParts(child, out);\n }\n }\n }\n};\n\n/**\n * Every lit-html part rendered into the tree `el` lives in: the parts of each\n * render container (`_$litPart$`) among `el`'s ancestors up to its root.\n * `undefined` when `el` isn't in a tree or the walk hits a surprise.\n */\nexport const partsAround = (el: Node): PartLike[] | undefined => {\n try {\n const out: PartLike[] = [];\n let node: Node | null = el.parentNode;\n if (node === null) {\n return undefined;\n }\n while (node !== null) {\n const root = (node as unknown as Record<string, unknown>)[LIT_PART];\n if (isPart(root)) {\n walkParts(root, out);\n }\n node = node.parentNode;\n }\n return out;\n } catch {\n return undefined;\n }\n};\n\n/** Attribute name → reactive property key for an element's class. */\nconst attributeMap = (ctor: CtorLike): Map<string, PropertyKey> => {\n // Dev builds keep the name; prod mangles it, so rebuild from options.\n const own = ctor.__attributeToPropertyMap;\n if (own instanceof Map) {\n return own as Map<string, PropertyKey>;\n }\n const map = new Map<string, PropertyKey>();\n const props = ctor.elementProperties;\n if (!(props instanceof Map)) {\n return map;\n }\n for (const [key, options] of props) {\n const attribute = options?.attribute;\n if (attribute === false) {\n continue;\n }\n if (typeof attribute === 'string') {\n map.set(attribute, key);\n } else if (typeof key === 'string') {\n map.set(key.toLowerCase(), key);\n }\n }\n return map;\n};\n\nconst propertyKeys = (ctor: CtorLike | undefined): PropertyKey[] => {\n const props = ctor?.elementProperties;\n return props instanceof Map ? [...props.keys()] : [];\n};\n\n/**\n * Reactive property keys the new element already got from its template:\n * keys whose attribute is present on it (static attributes), plus, when the\n * part tree could be read, keys bound by a property, boolean or attribute\n * part targeting it.\n */\nexport const templateDrivenKeys = (\n el: ElementLike,\n parts: readonly PartLike[] | undefined\n): Set<PropertyKey> => {\n const keys = new Set<PropertyKey>();\n const ctor = el.constructor as CtorLike;\n const attrs = attributeMap(ctor);\n try {\n for (const attr of Array.from(el.attributes)) {\n const key = attrs.get(attr.name.toLowerCase());\n if (key !== undefined) {\n keys.add(key);\n }\n }\n } catch {\n // No attributes to read.\n }\n for (const part of parts ?? []) {\n if (part.element !== el || typeof part.name !== 'string') {\n continue;\n }\n if (part.type === PROPERTY_PART) {\n keys.add(part.name);\n } else if (part.type === ATTRIBUTE_PART || part.type === BOOLEAN_PART) {\n keys.add(attrs.get(part.name.toLowerCase()) ?? part.name);\n }\n }\n return keys;\n};\n\n/** Own symbol keys of `el` minted by the dev-only `#private` rewrite. */\nexport const privateKeys = (el: object): symbol[] =>\n Object.getOwnPropertySymbols(el).filter((sym) =>\n (Symbol.keyFor(sym) ?? '').startsWith(PRIVATE_KEY_PREFIX)\n );\n\n/**\n * Copies `from`'s state onto `to`: reactive properties not driven by `to`'s\n * template, and the `#private` members the dev rewrite turned into\n * `Symbol.for` keys. Nothing else — Lit's own bookkeeping lives in string\n * keys and must stay per-instance.\n */\nexport const transferState = (\n from: ElementLike,\n to: ElementLike,\n parts: readonly PartLike[] | undefined\n): void => {\n const skip = templateDrivenKeys(to, parts);\n const keys = new Set<PropertyKey>([\n ...propertyKeys(to.constructor as CtorLike),\n ...propertyKeys(from.constructor as CtorLike),\n ]);\n const src = from as unknown as Record<PropertyKey, unknown>;\n const dst = to as unknown as Record<PropertyKey, unknown>;\n for (const key of keys) {\n if (skip.has(key)) {\n continue;\n }\n try {\n dst[key] = src[key];\n } catch {\n // A throwing setter; leave the default.\n }\n }\n for (const sym of privateKeys(from)) {\n try {\n Object.defineProperty(\n to,\n sym,\n Object.getOwnPropertyDescriptor(from, sym)!\n );\n } catch {\n // Non-configurable on the target; leave it.\n }\n }\n};\n\nconst inside = (el: Node, node: unknown): boolean =>\n node !== null &&\n typeof node === 'object' &&\n typeof (node as Node).nodeType === 'number' &&\n el.contains(node as Node);\n\n/**\n * Whether `el` (and its light DOM) carries no bindings, so another element\n * can take its place without lit-html noticing: no part targets it or an\n * element inside it, no child part's markers or parent lie inside it, and\n * nothing rendered into it as a container. `false` when `parts` is unknown.\n */\nexport const isReuseSafe = (\n el: ElementLike,\n parts: readonly PartLike[] | undefined\n): boolean => {\n if (parts === undefined) {\n return false;\n }\n try {\n if (LIT_PART in el) {\n return false;\n }\n for (const part of parts) {\n if (inside(el, part.element)) {\n return false;\n }\n if (part.type === CHILD_PART) {\n const start = internal(part, START) as Node | null | undefined;\n const end = internal(part, END) as Node | null | undefined;\n if (\n inside(el, start) ||\n inside(el, end) ||\n inside(el, start?.parentNode) ||\n inside(el, end?.parentNode)\n ) {\n return false;\n }\n }\n }\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Puts `old` back where `fresh` is: `old` takes `fresh`'s attributes and\n * light-DOM children, then replaces it. `old` keeps its identity, state,\n * shadow DOM and controllers, and reconnects.\n */\nexport const swapBack = (old: ElementLike, fresh: ElementLike): void => {\n for (const attr of Array.from(old.attributes)) {\n if (!fresh.hasAttribute(attr.name)) {\n old.removeAttribute(attr.name);\n }\n }\n for (const attr of Array.from(fresh.attributes)) {\n if (old.getAttribute(attr.name) !== attr.value) {\n old.setAttribute(attr.name, attr.value);\n }\n }\n old.replaceChildren(...Array.from(fresh.childNodes));\n fresh.replaceWith(old);\n};\n\ninterface Pending {\n root: Node;\n tag: string;\n}\n\ninterface TransferWindow {\n mode: 'transfer' | 'reuse';\n /** Elements dropped during the window, by root then tag, in drop order. */\n pending: Map<Node, Map<string, ElementLike[]>>;\n pendingOf: Map<ElementLike, Pending>;\n /** (old, new) in pairing order; `old` is the chain's original element. */\n pairs: Array<[ElementLike, ElementLike]>;\n /** New element → the element it replaced (immediate predecessor). */\n pairOf: Map<ElementLike, ElementLike>;\n /** New element → the first element of its replacement chain. */\n originOf: Map<ElementLike, ElementLike>;\n /** Outstanding `watch()` batches. */\n waiting: number;\n idle?: ReturnType<typeof setTimeout>;\n cap?: ReturnType<typeof setTimeout>;\n}\n\nexport interface ChildStateOptions {\n /** Read at every `open()`. */\n mode: () => ChildStateMode;\n /** Hard cap on a window's lifetime. Defaults to {@link WINDOW_CAP_MS}. */\n capMs?: number;\n}\n\nexport interface ChildState {\n /**\n * From the instrumented `connectedCallback`, before the original runs.\n * `fresh` is whether the element has never been connected before.\n */\n connected(el: ElementLike, fresh: boolean): void;\n /** From the instrumented `disconnectedCallback`. */\n disconnected(el: ElementLike): void;\n /** A hot patch is about to re-render instances: open (or extend) a window. */\n open(): void;\n /** Keep the window open until these instances' updates complete. */\n watch(els: Iterable<ElementLike>): void;\n /** Whether a window is currently open. */\n readonly active: boolean;\n}\n\nexport const createChildState = (options: ChildStateOptions): ChildState => {\n const capMs = options.capMs ?? WINDOW_CAP_MS;\n /** The root each element was last connected in. */\n const rootOf = new WeakMap<ElementLike, Node>();\n let current: TransferWindow | undefined;\n\n const close = (w: TransferWindow): void => {\n if (current !== w) {\n return;\n }\n current = undefined;\n clearTimeout(w.idle);\n clearTimeout(w.cap);\n // Reuse only once everything we waited on has settled; on the hard cap\n // with updates still outstanding, the transferred state stands.\n if (w.mode !== 'reuse' || w.waiting > 0) {\n return;\n }\n for (const [old, fresh] of w.pairs) {\n // A pair inside an element that was itself swapped back is moot:\n // the old element's shadow DOM came back intact with it.\n if (!fresh.isConnected || old.isConnected) {\n continue;\n }\n try {\n if (isReuseSafe(fresh, partsAround(fresh))) {\n swapBack(old, fresh);\n }\n } catch {\n // Leave the new element (it already has the transferred state).\n }\n }\n };\n\n /** Close once a macrotask passes with no tracked activity. */\n const settle = (w: TransferWindow): void => {\n if (current !== w || w.waiting > 0) {\n return;\n }\n clearTimeout(w.idle);\n w.idle = setTimeout(() => close(w), 0);\n };\n\n /** The pending-queue root for an element now connected in `root`. */\n const keyRoot = (w: TransferWindow, root: Node): Node => {\n const host = (root as Partial<ShadowRoot>).host as ElementLike | undefined;\n const old = host === undefined ? undefined : w.pairOf.get(host);\n if (old !== undefined) {\n // Re-created inside a new element's shadow: match against what was\n // dropped from the old element's shadow.\n const oldRoot = (old.renderRoot ?? old.shadowRoot) as Node | undefined;\n if (oldRoot !== undefined && oldRoot !== null && w.pending.has(oldRoot)) {\n return oldRoot;\n }\n }\n return root;\n };\n\n const unqueue = (w: TransferWindow, el: ElementLike): void => {\n const at = w.pendingOf.get(el);\n if (at === undefined) {\n return;\n }\n w.pendingOf.delete(el);\n const queue = w.pending.get(at.root)?.get(at.tag);\n const i = queue?.indexOf(el) ?? -1;\n if (i >= 0) {\n queue!.splice(i, 1);\n }\n };\n\n const pair = (w: TransferWindow, fresh: ElementLike, root: Node): void => {\n const queue = w.pending.get(keyRoot(w, root))?.get(fresh.localName);\n const old = queue?.shift();\n if (old === undefined) {\n return;\n }\n w.pendingOf.delete(old);\n w.pairOf.set(fresh, old);\n const origin = w.originOf.get(old) ?? old;\n w.originOf.set(fresh, origin);\n w.pairs.push([origin, fresh]);\n // lit-html assigns the new template instance to its part only after the\n // fragment is inserted, so the parts targeting `fresh` aren't reachable\n // yet. Queued before the original connectedCallback enables updating,\n // this runs ahead of `fresh`'s first update.\n queueMicrotask(() => {\n try {\n transferState(old, fresh, partsAround(fresh));\n } catch {\n // Keep the defaults.\n }\n });\n };\n\n return {\n connected(el, fresh) {\n let root: Node | undefined;\n try {\n root = el.getRootNode();\n } catch {\n root = undefined;\n }\n const w = current;\n if (w !== undefined) {\n try {\n if (fresh && root !== undefined && el.hasUpdated !== true) {\n pair(w, el, root);\n } else {\n // Moved, not re-created: it can't be anyone's replacement.\n unqueue(w, el);\n }\n } catch {\n // Pairing is best-effort.\n }\n settle(w);\n }\n if (root !== undefined) {\n rootOf.set(el, root);\n }\n },\n disconnected(el) {\n const w = current;\n if (w === undefined) {\n return;\n }\n const root = rootOf.get(el);\n if (root !== undefined) {\n const tag = el.localName;\n let byTag = w.pending.get(root);\n if (byTag === undefined) {\n w.pending.set(root, (byTag = new Map()));\n }\n let queue = byTag.get(tag);\n if (queue === undefined) {\n byTag.set(tag, (queue = []));\n }\n unqueue(w, el);\n queue.push(el);\n w.pendingOf.set(el, {root, tag});\n }\n settle(w);\n },\n open() {\n const mode = options.mode();\n if (mode !== 'transfer' && mode !== 'reuse') {\n return;\n }\n let w = current;\n if (w === undefined) {\n w = current = {\n mode,\n pending: new Map(),\n pendingOf: new Map(),\n pairs: [],\n pairOf: new Map(),\n originOf: new Map(),\n waiting: 0,\n };\n }\n w.mode = mode;\n clearTimeout(w.cap);\n const opened = w;\n w.cap = setTimeout(() => close(opened), capMs);\n settle(w);\n },\n watch(els) {\n const w = current;\n if (w === undefined) {\n return;\n }\n const promises: Promise<unknown>[] = [];\n for (const el of els) {\n try {\n const p = el.updateComplete;\n if (p instanceof Promise) {\n promises.push(p);\n }\n } catch {\n // No update promise to wait on.\n }\n }\n w.waiting++;\n clearTimeout(w.idle);\n let left = promises.length + 1;\n const done = () => {\n if (--left === 0) {\n w.waiting--;\n settle(w);\n }\n };\n for (const p of promises) {\n // Rethrow: a failed update must still surface as an unhandled\n // rejection, exactly as it would with nobody watching.\n void p.then(done, (e: unknown) => {\n done();\n throw e;\n });\n }\n queueMicrotask(done);\n },\n get active() {\n return current !== undefined;\n },\n };\n};\n"]}
@@ -39,7 +39,7 @@ if (typeof window !== 'undefined') {
39
39
  // and an outline left painted over the app is worse than a missing one.
40
40
  channel.events.on('panel:disconnected', () => clearHighlight());
41
41
  }
42
- if (hot !== undefined && typeof window !== 'undefined') {
42
+ if (typeof window !== 'undefined') {
43
43
  const send = (msg) => {
44
44
  try {
45
45
  pageChannel.send(INSPECT_DATA_CHANNEL, msg);
@@ -252,5 +252,8 @@ if (hot !== undefined && typeof window !== 'undefined') {
252
252
  });
253
253
  // Announce readiness so a panel that loaded first re-requests the tree.
254
254
  send({type: 'ready'});
255
+ // A carrier attached later (a standalone dev server) starts with no idea a
256
+ // runtime exists.
257
+ pageChannel.onAttach(() => send({type: 'ready'}));
255
258
  }
256
259
  //# sourceMappingURL=install.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/lib/runtime/inspector/install.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Components inspector runtime.\n *\n * Injected into the host page (alongside the timeline runtime) when the\n * DevTools panel is enabled. Answers the panel's tree/details requests over the\n * Vite HMR channel, keeps a watched element's details fresh as it updates, and\n * outlines elements the panel hovers in its tree.\n */\n\nimport {createPageScriptChannel} from 'devframe/in-page-channel';\nimport {elementById} from '../timeline/identity.js';\nimport {pageChannel} from '../page-channel.js';\nimport type {ViteHotLike} from '../page-channel.js';\nimport {buildTree, collectDetails} from './collect.js';\nimport {clearHighlight, highlightById} from './highlight.js';\nimport {\n LIT_IN_PAGE_CHANNEL,\n type LitInPageProtocol,\n} from '../../../types/in-page.js';\nimport {\n INSPECT_CMD_CHANNEL,\n INSPECT_DATA_CHANNEL,\n type InspectorCommand,\n type InspectorMessage,\n} from '../../../types/inspector.js';\n\nconst hot = (import.meta as {hot?: ViteHotLike}).hot;\nif (hot !== undefined) pageChannel.useViteHot(hot);\n\n// The direct panel channel, outside the `hot` gate on purpose: it is the one\n// part of the inspector that does not need a dev server, which is what lets\n// the hover outline keep working in a static snapshot of the panel. Answering\n// handshakes costs nothing until a panel actually sends one.\nif (typeof window !== 'undefined') {\n const channel = createPageScriptChannel<LitInPageProtocol>({\n name: LIT_IN_PAGE_CHANNEL,\n functions: {},\n events: {\n highlight: {handler: (id) => highlightById(id)},\n },\n });\n // A panel that goes away mid-hover never gets to send its `highlight(null)`,\n // and an outline left painted over the app is worse than a missing one.\n channel.events.on('panel:disconnected', () => clearHighlight());\n}\n\nif (hot !== undefined && typeof window !== 'undefined') {\n const send = (msg: InspectorMessage): void => {\n try {\n pageChannel.send(INSPECT_DATA_CHANNEL, msg);\n } catch {\n // HMR channel temporarily unavailable; the panel can re-request.\n }\n };\n\n // -------------------------------------------------------------------------\n // Live-watch: re-push details whenever the watched element finishes updating.\n // We wrap the instance's `updated` (not the prototype) so the hook is scoped\n // to one element and trivially removable, and it works without the timeline's\n // recording gate.\n // -------------------------------------------------------------------------\n\n type Updatable = Element & {\n updated?: (changed: unknown) => void;\n };\n // Hold the watched element via a WeakRef so an active watch doesn't keep a\n // removed element alive: the override and `restore` only reach `el` through\n // the ref, leaving the DOM as its sole strong root.\n let watched: {ref: WeakRef<Updatable>; restore: () => void} | null = null;\n\n const unwatch = (): void => {\n watched?.restore();\n watched = null;\n };\n\n const watch = (id: number): void => {\n unwatch();\n const el = elementById(id) as Updatable | undefined;\n if (el === undefined) {\n send({type: 'gone', id});\n return;\n }\n const hadOwn = Object.prototype.hasOwnProperty.call(el, 'updated');\n // Only an *own* `updated` is stable across an HMR hot patch. A prototype\n // implementation is replaced in place on every patch (`syncOwnMembers` in\n // ../patch.ts), so caching it here would pin the watched instance to the\n // pre-edit code for the life of the watch — resolve it through the\n // prototype chain on each call instead. Our wrapper is an own property, so\n // the lookup skips it and cannot recurse.\n const ownPrev = hadOwn ? el.updated : undefined;\n const ref = new WeakRef(el);\n el.updated = function (this: Updatable, changed: unknown) {\n const current =\n ownPrev ?? (Object.getPrototypeOf(this) as Updatable | null)?.updated;\n current?.call(this, changed);\n const cur = ref.deref();\n if (cur !== undefined) {\n send({type: 'details', details: collectDetails(cur)});\n }\n };\n watched = {\n ref,\n restore: () => {\n const cur = ref.deref();\n if (cur === undefined) return;\n if (hadOwn) cur.updated = ownPrev;\n else delete cur.updated;\n },\n };\n // Push an immediate snapshot so the panel doesn't wait for the next update.\n send({type: 'details', details: collectDetails(el)});\n };\n\n // -------------------------------------------------------------------------\n // Opt-in live tree: watch the DOM (light + every shadow root) and push a\n // fresh tree when the component hierarchy actually changes. Off by default.\n // childList-only (no attributes), so cosmetic changes — including our own\n // highlight box toggling — don't churn; identical rebuilds are also deduped.\n // Batches that only move text or comment nodes (most Lit re-renders) are\n // dropped before the debounce, and only added subtrees are walked for new\n // shadow roots, so a busy page no longer costs a full-page walk per batch.\n // -------------------------------------------------------------------------\n\n let observer: MutationObserver | null = null;\n let observeTimer: ReturnType<typeof setTimeout> | undefined;\n let lastTreeJson = '';\n // Added elements whose subtrees still need their shadow roots observed.\n let pendingRoots: Element[] = [];\n\n /** Observe every shadow root at or under `root` (and `root`'s subtree). */\n const observeShadowRoots = (\n obs: MutationObserver,\n root: ParentNode\n ): void => {\n if (root instanceof Element && root.shadowRoot !== null) {\n obs.observe(root.shadowRoot, {childList: true, subtree: true});\n observeShadowRoots(obs, root.shadowRoot);\n }\n for (const el of root.querySelectorAll('*')) {\n if (el.shadowRoot !== null) {\n obs.observe(el.shadowRoot, {childList: true, subtree: true});\n observeShadowRoots(obs, el.shadowRoot);\n }\n }\n };\n\n /** Re-attach the observer to the body and every shadow root in the page. */\n const syncObserverTargets = (obs: MutationObserver): void => {\n obs.disconnect();\n obs.observe(document.body, {childList: true, subtree: true});\n observeShadowRoots(obs, document);\n };\n\n const pushTreeIfChanged = (): void => {\n const roots = buildTree();\n const json = JSON.stringify(roots);\n if (json === lastTreeJson) return;\n lastTreeJson = json;\n send({type: 'tree', roots});\n };\n\n /** Whether a subtree holds anything the tree (or observer) cares about. */\n const mayHoldComponents = (node: Node): node is Element => {\n if (!(node instanceof Element)) return false;\n const matters = (el: Element): boolean =>\n el.localName.includes('-') || el.shadowRoot !== null;\n if (matters(node)) return true;\n for (const el of node.querySelectorAll('*')) if (matters(el)) return true;\n return false;\n };\n\n const onMutation = (records: MutationRecord[]): void => {\n // The tree only has custom elements in it, so a batch that adds or\n // removes none (text, comments, plain markup) can't change it.\n let relevant = false;\n for (const record of records) {\n for (const node of record.addedNodes) {\n if (mayHoldComponents(node)) {\n pendingRoots.push(node);\n relevant = true;\n }\n }\n if (!relevant) {\n for (const node of record.removedNodes) {\n if (mayHoldComponents(node)) {\n relevant = true;\n break;\n }\n }\n }\n }\n if (!relevant) return;\n if (observeTimer !== undefined) clearTimeout(observeTimer);\n observeTimer = setTimeout(() => {\n observeTimer = undefined;\n // Walk added subtrees now rather than on arrival: a custom element\n // attaches its shadow root when it upgrades, which can be after insert.\n // Removed roots need no bookkeeping; a detached shadow root just stops\n // producing records.\n const roots = pendingRoots;\n pendingRoots = [];\n if (observer !== null) {\n for (const root of roots) {\n if (root.isConnected) observeShadowRoots(observer, root);\n }\n }\n pushTreeIfChanged();\n }, 100);\n };\n\n const setObserving = (enabled: boolean): void => {\n if (enabled) {\n if (observer === null) observer = new MutationObserver(onMutation);\n lastTreeJson = '';\n syncObserverTargets(observer);\n pushTreeIfChanged();\n } else if (observer !== null) {\n observer.disconnect();\n observer = null;\n pendingRoots = [];\n if (observeTimer !== undefined) {\n clearTimeout(observeTimer);\n observeTimer = undefined;\n }\n }\n };\n\n // -------------------------------------------------------------------------\n // SPA navigation: a route change swaps the component tree without any HMR\n // or panel event, so the snapshot went stale until a manual refresh. Push a\n // deduped tree after each navigation — twice, since routes typically\n // lazy-load and render async. Redundant while the live observer watches.\n // -------------------------------------------------------------------------\n\n const onNavigation = (): void => {\n if (observer !== null) return;\n for (const delay of [150, 1000]) {\n setTimeout(pushTreeIfChanged, delay);\n }\n };\n window.addEventListener('popstate', onNavigation);\n window.addEventListener('hashchange', onNavigation);\n for (const method of ['pushState', 'replaceState'] as const) {\n const original = history[method].bind(history);\n history[method] = (...args: Parameters<History['pushState']>) => {\n original(...args);\n onNavigation();\n };\n }\n\n // -------------------------------------------------------------------------\n // Command dispatch\n // -------------------------------------------------------------------------\n\n pageChannel.on(INSPECT_CMD_CHANNEL, (data) => {\n const cmd = data as InspectorCommand;\n switch (cmd.type) {\n case 'tree': {\n const roots = buildTree();\n lastTreeJson = JSON.stringify(roots);\n send({type: 'tree', roots});\n break;\n }\n case 'details': {\n const el = elementById(cmd.id);\n if (el !== undefined) {\n send({type: 'details', details: collectDetails(el)});\n } else {\n send({type: 'gone', id: cmd.id});\n }\n break;\n }\n case 'watch':\n if (cmd.id === null) unwatch();\n else watch(cmd.id);\n break;\n case 'highlight':\n // Fallback path. A panel that handshaked over the in-page channel\n // emits there instead and never reaches this.\n highlightById(cmd.id);\n break;\n case 'observe':\n setObserving(cmd.enabled);\n break;\n }\n });\n\n // Announce readiness so a panel that loaded first re-requests the tree.\n send({type: 'ready'});\n}\n"]}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/lib/runtime/inspector/install.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Components inspector runtime.\n *\n * Injected into the host page (alongside the timeline runtime) when the\n * DevTools panel is enabled. Answers the panel's tree/details requests over the\n * Vite HMR channel, keeps a watched element's details fresh as it updates, and\n * outlines elements the panel hovers in its tree.\n */\n\nimport {createPageScriptChannel} from 'devframe/in-page-channel';\nimport {elementById} from '../timeline/identity.js';\nimport {pageChannel} from '../page-channel.js';\nimport type {ViteHotLike} from '../page-channel.js';\nimport {buildTree, collectDetails} from './collect.js';\nimport {clearHighlight, highlightById} from './highlight.js';\nimport {\n LIT_IN_PAGE_CHANNEL,\n type LitInPageProtocol,\n} from '../../../types/in-page.js';\nimport {\n INSPECT_CMD_CHANNEL,\n INSPECT_DATA_CHANNEL,\n type InspectorCommand,\n type InspectorMessage,\n} from '../../../types/inspector.js';\n\nconst hot = (import.meta as {hot?: ViteHotLike}).hot;\nif (hot !== undefined) pageChannel.useViteHot(hot);\n\n// The direct panel channel, outside the `hot` gate on purpose: it is the one\n// part of the inspector that does not need a dev server, which is what lets\n// the hover outline keep working in a static snapshot of the panel. Answering\n// handshakes costs nothing until a panel actually sends one.\nif (typeof window !== 'undefined') {\n const channel = createPageScriptChannel<LitInPageProtocol>({\n name: LIT_IN_PAGE_CHANNEL,\n functions: {},\n events: {\n highlight: {handler: (id) => highlightById(id)},\n },\n });\n // A panel that goes away mid-hover never gets to send its `highlight(null)`,\n // and an outline left painted over the app is worse than a missing one.\n channel.events.on('panel:disconnected', () => clearHighlight());\n}\n\nif (typeof window !== 'undefined') {\n const send = (msg: InspectorMessage): void => {\n try {\n pageChannel.send(INSPECT_DATA_CHANNEL, msg);\n } catch {\n // HMR channel temporarily unavailable; the panel can re-request.\n }\n };\n\n // -------------------------------------------------------------------------\n // Live-watch: re-push details whenever the watched element finishes updating.\n // We wrap the instance's `updated` (not the prototype) so the hook is scoped\n // to one element and trivially removable, and it works without the timeline's\n // recording gate.\n // -------------------------------------------------------------------------\n\n type Updatable = Element & {\n updated?: (changed: unknown) => void;\n };\n // Hold the watched element via a WeakRef so an active watch doesn't keep a\n // removed element alive: the override and `restore` only reach `el` through\n // the ref, leaving the DOM as its sole strong root.\n let watched: {ref: WeakRef<Updatable>; restore: () => void} | null = null;\n\n const unwatch = (): void => {\n watched?.restore();\n watched = null;\n };\n\n const watch = (id: number): void => {\n unwatch();\n const el = elementById(id) as Updatable | undefined;\n if (el === undefined) {\n send({type: 'gone', id});\n return;\n }\n const hadOwn = Object.prototype.hasOwnProperty.call(el, 'updated');\n // Only an *own* `updated` is stable across an HMR hot patch. A prototype\n // implementation is replaced in place on every patch (`syncOwnMembers` in\n // ../patch.ts), so caching it here would pin the watched instance to the\n // pre-edit code for the life of the watch — resolve it through the\n // prototype chain on each call instead. Our wrapper is an own property, so\n // the lookup skips it and cannot recurse.\n const ownPrev = hadOwn ? el.updated : undefined;\n const ref = new WeakRef(el);\n el.updated = function (this: Updatable, changed: unknown) {\n const current =\n ownPrev ?? (Object.getPrototypeOf(this) as Updatable | null)?.updated;\n current?.call(this, changed);\n const cur = ref.deref();\n if (cur !== undefined) {\n send({type: 'details', details: collectDetails(cur)});\n }\n };\n watched = {\n ref,\n restore: () => {\n const cur = ref.deref();\n if (cur === undefined) return;\n if (hadOwn) cur.updated = ownPrev;\n else delete cur.updated;\n },\n };\n // Push an immediate snapshot so the panel doesn't wait for the next update.\n send({type: 'details', details: collectDetails(el)});\n };\n\n // -------------------------------------------------------------------------\n // Opt-in live tree: watch the DOM (light + every shadow root) and push a\n // fresh tree when the component hierarchy actually changes. Off by default.\n // childList-only (no attributes), so cosmetic changes — including our own\n // highlight box toggling — don't churn; identical rebuilds are also deduped.\n // Batches that only move text or comment nodes (most Lit re-renders) are\n // dropped before the debounce, and only added subtrees are walked for new\n // shadow roots, so a busy page no longer costs a full-page walk per batch.\n // -------------------------------------------------------------------------\n\n let observer: MutationObserver | null = null;\n let observeTimer: ReturnType<typeof setTimeout> | undefined;\n let lastTreeJson = '';\n // Added elements whose subtrees still need their shadow roots observed.\n let pendingRoots: Element[] = [];\n\n /** Observe every shadow root at or under `root` (and `root`'s subtree). */\n const observeShadowRoots = (\n obs: MutationObserver,\n root: ParentNode\n ): void => {\n if (root instanceof Element && root.shadowRoot !== null) {\n obs.observe(root.shadowRoot, {childList: true, subtree: true});\n observeShadowRoots(obs, root.shadowRoot);\n }\n for (const el of root.querySelectorAll('*')) {\n if (el.shadowRoot !== null) {\n obs.observe(el.shadowRoot, {childList: true, subtree: true});\n observeShadowRoots(obs, el.shadowRoot);\n }\n }\n };\n\n /** Re-attach the observer to the body and every shadow root in the page. */\n const syncObserverTargets = (obs: MutationObserver): void => {\n obs.disconnect();\n obs.observe(document.body, {childList: true, subtree: true});\n observeShadowRoots(obs, document);\n };\n\n const pushTreeIfChanged = (): void => {\n const roots = buildTree();\n const json = JSON.stringify(roots);\n if (json === lastTreeJson) return;\n lastTreeJson = json;\n send({type: 'tree', roots});\n };\n\n /** Whether a subtree holds anything the tree (or observer) cares about. */\n const mayHoldComponents = (node: Node): node is Element => {\n if (!(node instanceof Element)) return false;\n const matters = (el: Element): boolean =>\n el.localName.includes('-') || el.shadowRoot !== null;\n if (matters(node)) return true;\n for (const el of node.querySelectorAll('*')) if (matters(el)) return true;\n return false;\n };\n\n const onMutation = (records: MutationRecord[]): void => {\n // The tree only has custom elements in it, so a batch that adds or\n // removes none (text, comments, plain markup) can't change it.\n let relevant = false;\n for (const record of records) {\n for (const node of record.addedNodes) {\n if (mayHoldComponents(node)) {\n pendingRoots.push(node);\n relevant = true;\n }\n }\n if (!relevant) {\n for (const node of record.removedNodes) {\n if (mayHoldComponents(node)) {\n relevant = true;\n break;\n }\n }\n }\n }\n if (!relevant) return;\n if (observeTimer !== undefined) clearTimeout(observeTimer);\n observeTimer = setTimeout(() => {\n observeTimer = undefined;\n // Walk added subtrees now rather than on arrival: a custom element\n // attaches its shadow root when it upgrades, which can be after insert.\n // Removed roots need no bookkeeping; a detached shadow root just stops\n // producing records.\n const roots = pendingRoots;\n pendingRoots = [];\n if (observer !== null) {\n for (const root of roots) {\n if (root.isConnected) observeShadowRoots(observer, root);\n }\n }\n pushTreeIfChanged();\n }, 100);\n };\n\n const setObserving = (enabled: boolean): void => {\n if (enabled) {\n if (observer === null) observer = new MutationObserver(onMutation);\n lastTreeJson = '';\n syncObserverTargets(observer);\n pushTreeIfChanged();\n } else if (observer !== null) {\n observer.disconnect();\n observer = null;\n pendingRoots = [];\n if (observeTimer !== undefined) {\n clearTimeout(observeTimer);\n observeTimer = undefined;\n }\n }\n };\n\n // -------------------------------------------------------------------------\n // SPA navigation: a route change swaps the component tree without any HMR\n // or panel event, so the snapshot went stale until a manual refresh. Push a\n // deduped tree after each navigation — twice, since routes typically\n // lazy-load and render async. Redundant while the live observer watches.\n // -------------------------------------------------------------------------\n\n const onNavigation = (): void => {\n if (observer !== null) return;\n for (const delay of [150, 1000]) {\n setTimeout(pushTreeIfChanged, delay);\n }\n };\n window.addEventListener('popstate', onNavigation);\n window.addEventListener('hashchange', onNavigation);\n for (const method of ['pushState', 'replaceState'] as const) {\n const original = history[method].bind(history);\n history[method] = (...args: Parameters<History['pushState']>) => {\n original(...args);\n onNavigation();\n };\n }\n\n // -------------------------------------------------------------------------\n // Command dispatch\n // -------------------------------------------------------------------------\n\n pageChannel.on(INSPECT_CMD_CHANNEL, (data) => {\n const cmd = data as InspectorCommand;\n switch (cmd.type) {\n case 'tree': {\n const roots = buildTree();\n lastTreeJson = JSON.stringify(roots);\n send({type: 'tree', roots});\n break;\n }\n case 'details': {\n const el = elementById(cmd.id);\n if (el !== undefined) {\n send({type: 'details', details: collectDetails(el)});\n } else {\n send({type: 'gone', id: cmd.id});\n }\n break;\n }\n case 'watch':\n if (cmd.id === null) unwatch();\n else watch(cmd.id);\n break;\n case 'highlight':\n // Fallback path. A panel that handshaked over the in-page channel\n // emits there instead and never reaches this.\n highlightById(cmd.id);\n break;\n case 'observe':\n setObserving(cmd.enabled);\n break;\n }\n });\n\n // Announce readiness so a panel that loaded first re-requests the tree.\n send({type: 'ready'});\n // A carrier attached later (a standalone dev server) starts with no idea a\n // runtime exists.\n pageChannel.onAttach(() => send({type: 'ready'}));\n}\n"]}
@@ -3,6 +3,22 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: BSD-3-Clause
5
5
  */
6
+ /**
7
+ * In-place custom element class patching.
8
+ *
9
+ * Vite HMR re-executes an edited component module, which calls
10
+ * `customElements.define()` again with a freshly evaluated class. The
11
+ * platform registry can't re-define a tag, and live instances keep their
12
+ * original prototype chain, so instead of swapping classes we intercept the
13
+ * duplicate define and patch the originally-registered class in place:
14
+ * copy prototype + static descriptors from the new class onto the old one
15
+ * and nudge live instances to re-render.
16
+ *
17
+ * This module is dependency-free and duck-typed against ReactiveElement so
18
+ * it never imports lit (keeps it version-agnostic and safe for non-Lit
19
+ * custom elements, which get prototype/static patching only).
20
+ */
21
+ import { type ChildStateMode } from './child-state.js';
6
22
  import { type HmrIncompatibilityEvent, type HmrIncompatibilityReason } from '../../types/hmr-incompatibility.js';
7
23
  export interface PatchOptions {
8
24
  /**
@@ -15,6 +31,14 @@ export interface PatchOptions {
15
31
  * standard `accessor` decorators). Defaults to `'reload'`.
16
32
  */
17
33
  onIncompatible?: 'reload' | 'warn';
34
+ /**
35
+ * What happens to custom elements a hot patch re-creates (an edited
36
+ * template clones fresh DOM): `'reset'` leaves them at their defaults,
37
+ * `'transfer'` copies the old element's state onto the new one, `'reuse'`
38
+ * puts the old element back where the new one carries no bindings (and
39
+ * transfers otherwise). Defaults to `'transfer'`.
40
+ */
41
+ childState?: ChildStateMode;
18
42
  }
19
43
  /**
20
44
  * Syncs own members `source` → `target`: deletes own keys of `target` that