@oddsquad/vite-plugin-lit 0.2.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/LICENSE +28 -0
  3. package/README.md +157 -0
  4. package/bin.mjs +154 -0
  5. package/client.d.ts +61 -0
  6. package/dist/client/assets/browser-agent-rpc-BXhoSh1z-CdtPhBL-.js +69 -0
  7. package/dist/client/assets/browser-agent-rpc-BXhoSh1z-CdtPhBL-.js.map +1 -0
  8. package/dist/client/assets/flow-DK8vmxvN.js +745 -0
  9. package/dist/client/assets/flow-DK8vmxvN.js.map +1 -0
  10. package/dist/client/assets/index-DVe6M4HV.js +10614 -0
  11. package/dist/client/assets/index-DVe6M4HV.js.map +1 -0
  12. package/{panel → dist/client}/index.html +1 -0
  13. package/index.d.ts.map +1 -1
  14. package/index.js +2 -2
  15. package/index.js.map +1 -1
  16. package/lib/color-scheme.d.ts.map +1 -1
  17. package/lib/color-scheme.js +17 -21
  18. package/lib/color-scheme.js.map +1 -1
  19. package/lib/devframe/definition.d.ts +45 -0
  20. package/lib/devframe/definition.d.ts.map +1 -0
  21. package/lib/devframe/definition.js +547 -0
  22. package/lib/devframe/definition.js.map +1 -0
  23. package/lib/devframe/icon.d.ts +8 -0
  24. package/lib/devframe/icon.d.ts.map +1 -0
  25. package/lib/devframe/icon.js +21 -0
  26. package/lib/devframe/icon.js.map +1 -0
  27. package/lib/devframe/paths.d.ts +12 -0
  28. package/lib/devframe/paths.d.ts.map +1 -0
  29. package/lib/devframe/paths.js +38 -0
  30. package/lib/devframe/paths.js.map +1 -0
  31. package/lib/devframe/protocol.d.ts +218 -0
  32. package/lib/devframe/protocol.d.ts.map +1 -0
  33. package/lib/devframe/protocol.js +77 -0
  34. package/lib/devframe/protocol.js.map +1 -0
  35. package/lib/devframe/source.d.ts +49 -0
  36. package/lib/devframe/source.d.ts.map +1 -0
  37. package/lib/devframe/source.js +23 -0
  38. package/lib/devframe/source.js.map +1 -0
  39. package/lib/devframe/vite.d.ts +116 -0
  40. package/lib/devframe/vite.d.ts.map +1 -0
  41. package/lib/devframe/vite.js +292 -0
  42. package/lib/devframe/vite.js.map +1 -0
  43. package/lib/http.d.ts +29 -0
  44. package/lib/http.d.ts.map +1 -0
  45. package/lib/http.js +35 -0
  46. package/lib/http.js.map +1 -0
  47. package/lib/icons.d.ts +2 -0
  48. package/lib/icons.d.ts.map +1 -1
  49. package/lib/icons.js +10 -4
  50. package/lib/icons.js.map +1 -1
  51. package/lib/options.d.ts +131 -0
  52. package/lib/options.d.ts.map +1 -0
  53. package/lib/options.js +128 -0
  54. package/lib/options.js.map +1 -0
  55. package/lib/plugin.d.ts +6 -137
  56. package/lib/plugin.d.ts.map +1 -1
  57. package/lib/plugin.js +280 -677
  58. package/lib/plugin.js.map +1 -1
  59. package/lib/plugins/css-literals.d.ts +15 -0
  60. package/lib/plugins/css-literals.d.ts.map +1 -0
  61. package/lib/plugins/css-literals.js +154 -0
  62. package/lib/plugins/css-literals.js.map +1 -0
  63. package/lib/plugins/css-queries.d.ts +20 -0
  64. package/lib/plugins/css-queries.d.ts.map +1 -0
  65. package/lib/plugins/css-queries.js +139 -0
  66. package/lib/plugins/css-queries.js.map +1 -0
  67. package/lib/plugins/open-in-editor.d.ts +16 -0
  68. package/lib/plugins/open-in-editor.d.ts.map +1 -0
  69. package/lib/plugins/open-in-editor.js +91 -0
  70. package/lib/plugins/open-in-editor.js.map +1 -0
  71. package/lib/plugins/shared.d.ts +13 -0
  72. package/lib/plugins/shared.d.ts.map +1 -0
  73. package/lib/plugins/shared.js +23 -0
  74. package/lib/plugins/shared.js.map +1 -0
  75. package/lib/plugins/timeline-virtual.d.ts +19 -0
  76. package/lib/plugins/timeline-virtual.d.ts.map +1 -0
  77. package/lib/plugins/timeline-virtual.js +53 -0
  78. package/lib/plugins/timeline-virtual.js.map +1 -0
  79. package/lib/runtime/css.d.ts +2 -2
  80. package/lib/runtime/css.d.ts.map +1 -1
  81. package/lib/runtime/css.js +41 -34
  82. package/lib/runtime/css.js.map +1 -1
  83. package/lib/runtime/edge-panel.d.ts.map +1 -1
  84. package/lib/runtime/edge-panel.js +82 -91
  85. package/lib/runtime/edge-panel.js.map +1 -1
  86. package/lib/runtime/fonts.d.ts.map +1 -1
  87. package/lib/runtime/fonts.js +1 -1
  88. package/lib/runtime/fonts.js.map +1 -1
  89. package/lib/runtime/indicator.d.ts.map +1 -1
  90. package/lib/runtime/indicator.js +71 -74
  91. package/lib/runtime/indicator.js.map +1 -1
  92. package/lib/runtime/inspector/collect.d.ts.map +1 -1
  93. package/lib/runtime/inspector/collect.js +83 -90
  94. package/lib/runtime/inspector/collect.js.map +1 -1
  95. package/lib/runtime/inspector/highlight.d.ts +16 -0
  96. package/lib/runtime/inspector/highlight.d.ts.map +1 -0
  97. package/lib/runtime/inspector/highlight.js +66 -0
  98. package/lib/runtime/inspector/highlight.js.map +1 -0
  99. package/lib/runtime/inspector/install.d.ts.map +1 -1
  100. package/lib/runtime/inspector/install.js +230 -205
  101. package/lib/runtime/inspector/install.js.map +1 -1
  102. package/lib/runtime/inspector/serialize.d.ts.map +1 -1
  103. package/lib/runtime/inspector/serialize.js +86 -107
  104. package/lib/runtime/inspector/serialize.js.map +1 -1
  105. package/lib/runtime/intern.d.ts.map +1 -1
  106. package/lib/runtime/intern.js +31 -29
  107. package/lib/runtime/intern.js.map +1 -1
  108. package/lib/runtime/overrides.d.ts.map +1 -1
  109. package/lib/runtime/overrides.js +14 -13
  110. package/lib/runtime/overrides.js.map +1 -1
  111. package/lib/runtime/patch.d.ts +8 -0
  112. package/lib/runtime/patch.d.ts.map +1 -1
  113. package/lib/runtime/patch.js +321 -282
  114. package/lib/runtime/patch.js.map +1 -1
  115. package/lib/runtime/source-meta.d.ts.map +1 -1
  116. package/lib/runtime/source-meta.js +1 -1
  117. package/lib/runtime/source-meta.js.map +1 -1
  118. package/lib/runtime/source-overlay/editors.d.ts.map +1 -1
  119. package/lib/runtime/source-overlay/editors.js +27 -27
  120. package/lib/runtime/source-overlay/editors.js.map +1 -1
  121. package/lib/runtime/source-overlay/mask-path.d.ts.map +1 -1
  122. package/lib/runtime/source-overlay/mask-path.js +15 -15
  123. package/lib/runtime/source-overlay/mask-path.js.map +1 -1
  124. package/lib/runtime/source-overlay/overlay-element.d.ts.map +1 -1
  125. package/lib/runtime/source-overlay/overlay-element.js +359 -355
  126. package/lib/runtime/source-overlay/overlay-element.js.map +1 -1
  127. package/lib/runtime/source-overlay/source-host.d.ts.map +1 -1
  128. package/lib/runtime/source-overlay/source-host.js +64 -71
  129. package/lib/runtime/source-overlay/source-host.js.map +1 -1
  130. package/lib/runtime/source-overlay/template.d.ts.map +1 -1
  131. package/lib/runtime/source-overlay/template.js +3 -3
  132. package/lib/runtime/source-overlay/template.js.map +1 -1
  133. package/lib/runtime/source-overlay.d.ts.map +1 -1
  134. package/lib/runtime/source-overlay.js +5 -2
  135. package/lib/runtime/source-overlay.js.map +1 -1
  136. package/lib/runtime/timeline/clock.d.ts.map +1 -1
  137. package/lib/runtime/timeline/clock.js +2 -2
  138. package/lib/runtime/timeline/clock.js.map +1 -1
  139. package/lib/runtime/timeline/flash.d.ts +39 -0
  140. package/lib/runtime/timeline/flash.d.ts.map +1 -0
  141. package/lib/runtime/timeline/flash.js +169 -0
  142. package/lib/runtime/timeline/flash.js.map +1 -0
  143. package/lib/runtime/timeline/identity.d.ts.map +1 -1
  144. package/lib/runtime/timeline/identity.js +27 -27
  145. package/lib/runtime/timeline/identity.js.map +1 -1
  146. package/lib/runtime/timeline/input.d.ts.map +1 -1
  147. package/lib/runtime/timeline/input.js +54 -67
  148. package/lib/runtime/timeline/input.js.map +1 -1
  149. package/lib/runtime/timeline/install.d.ts.map +1 -1
  150. package/lib/runtime/timeline/install.js +47 -33
  151. package/lib/runtime/timeline/install.js.map +1 -1
  152. package/lib/runtime/timeline/lifecycle.d.ts +8 -0
  153. package/lib/runtime/timeline/lifecycle.d.ts.map +1 -1
  154. package/lib/runtime/timeline/lifecycle.js +149 -133
  155. package/lib/runtime/timeline/lifecycle.js.map +1 -1
  156. package/lib/runtime/timeline/public-api.d.ts +2 -2
  157. package/lib/runtime/timeline/public-api.d.ts.map +1 -1
  158. package/lib/runtime/timeline/public-api.js +11 -11
  159. package/lib/runtime/timeline/public-api.js.map +1 -1
  160. package/lib/runtime/timeline/render.d.ts +15 -6
  161. package/lib/runtime/timeline/render.d.ts.map +1 -1
  162. package/lib/runtime/timeline/render.js +212 -78
  163. package/lib/runtime/timeline/render.js.map +1 -1
  164. package/lib/runtime/timeline/transport.d.ts.map +1 -1
  165. package/lib/runtime/timeline/transport.js +39 -43
  166. package/lib/runtime/timeline/transport.js.map +1 -1
  167. package/lib/segmented-tabs.d.ts +3 -1
  168. package/lib/segmented-tabs.d.ts.map +1 -1
  169. package/lib/segmented-tabs.js +136 -107
  170. package/lib/segmented-tabs.js.map +1 -1
  171. package/lib/snapshot.d.ts +28 -0
  172. package/lib/snapshot.d.ts.map +1 -0
  173. package/lib/snapshot.js +57 -0
  174. package/lib/snapshot.js.map +1 -0
  175. package/lib/source-meta.d.ts.map +1 -1
  176. package/lib/source-meta.js +176 -162
  177. package/lib/source-meta.js.map +1 -1
  178. package/lib/timeline/derive.d.ts +152 -0
  179. package/lib/timeline/derive.d.ts.map +1 -0
  180. package/lib/timeline/derive.js +242 -0
  181. package/lib/timeline/derive.js.map +1 -0
  182. package/lib/tokens.d.ts.map +1 -1
  183. package/lib/tokens.js +17 -18
  184. package/lib/tokens.js.map +1 -1
  185. package/lib/transform.d.ts.map +1 -1
  186. package/lib/transform.js +62 -57
  187. package/lib/transform.js.map +1 -1
  188. package/lib/types.d.ts.map +1 -1
  189. package/lib/types.js +1 -1
  190. package/lib/types.js.map +1 -1
  191. package/lib/wrap-table.d.ts.map +1 -1
  192. package/lib/wrap-table.js +19 -17
  193. package/lib/wrap-table.js.map +1 -1
  194. package/package.json +80 -13
  195. package/types/hmr-incompatibility.d.ts +59 -0
  196. package/types/hmr-incompatibility.d.ts.map +1 -0
  197. package/types/hmr-incompatibility.js +30 -0
  198. package/types/hmr-incompatibility.js.map +1 -0
  199. package/types/in-page.d.ts +49 -0
  200. package/types/in-page.d.ts.map +1 -0
  201. package/types/in-page.js +33 -0
  202. package/types/in-page.js.map +1 -0
  203. package/types/inspector.d.ts.map +1 -1
  204. package/types/inspector.js.map +1 -1
  205. package/types/snapshot.d.ts +44 -0
  206. package/types/snapshot.d.ts.map +1 -0
  207. package/types/snapshot.js +7 -0
  208. package/types/snapshot.js.map +1 -0
  209. package/types/timeline.d.ts +23 -1
  210. package/types/timeline.d.ts.map +1 -1
  211. package/types/timeline.js +2 -0
  212. package/types/timeline.js.map +1 -1
  213. package/lib/timeline-plugin.d.ts +0 -72
  214. package/lib/timeline-plugin.d.ts.map +0 -1
  215. package/lib/timeline-plugin.js +0 -376
  216. package/lib/timeline-plugin.js.map +0 -1
  217. package/panel/components-view.d.ts +0 -60
  218. package/panel/components-view.d.ts.map +0 -1
  219. package/panel/components-view.js +0 -587
  220. package/panel/components-view.js.map +0 -1
  221. package/panel/devtools-settings.d.ts +0 -41
  222. package/panel/devtools-settings.d.ts.map +0 -1
  223. package/panel/devtools-settings.js +0 -463
  224. package/panel/devtools-settings.js.map +0 -1
  225. package/panel/lit-devtools-panel.d.ts +0 -37
  226. package/panel/lit-devtools-panel.d.ts.map +0 -1
  227. package/panel/lit-devtools-panel.js +0 -185
  228. package/panel/lit-devtools-panel.js.map +0 -1
  229. package/panel/timeline-event-list.d.ts +0 -43
  230. package/panel/timeline-event-list.d.ts.map +0 -1
  231. package/panel/timeline-event-list.js +0 -416
  232. package/panel/timeline-event-list.js.map +0 -1
  233. package/panel/timeline-layers.d.ts +0 -25
  234. package/panel/timeline-layers.d.ts.map +0 -1
  235. package/panel/timeline-layers.js +0 -96
  236. package/panel/timeline-layers.js.map +0 -1
  237. package/panel/timeline-view.d.ts +0 -38
  238. package/panel/timeline-view.d.ts.map +0 -1
  239. package/panel/timeline-view.js +0 -234
  240. package/panel/timeline-view.js.map +0 -1
@@ -3,8 +3,8 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: BSD-3-Clause
5
5
  */
6
- import { idOf, sourceOf } from './identity.js';
7
- import { now } from './clock.js';
6
+ import {idOf, sourceOf} from './identity.js';
7
+ import {now} from './clock.js';
8
8
  /**
9
9
  * Builds the element-identity `meta` for a render event from the render
10
10
  * `host` (the LitElement whose `render()` produced these debug events).
@@ -13,83 +13,218 @@ import { now } from './clock.js';
13
13
  * (e.g. a bare lit-html `render()` call not driven by a LitElement).
14
14
  */
15
15
  const hostMeta = (host) => {
16
- if (host === null || typeof host !== 'object')
17
- return undefined;
18
- return {
19
- elementId: idOf(host),
20
- tagName: host.localName ?? 'unknown',
21
- source: sourceOf(host),
22
- };
16
+ if (host === null || typeof host !== 'object') return undefined;
17
+ return {
18
+ elementId: idOf(host),
19
+ tagName: host.localName ?? 'unknown',
20
+ source: sourceOf(host),
21
+ };
23
22
  };
23
+ /** Reads the render `host` off a `Part` for the one kind (`set part`) whose
24
+ * detail carries the part instead of the render `options` directly. */
25
+ const partHost = (part) => part?.options?.host;
24
26
  let removeListener = null;
25
- const onLitDebug = (e, emit, recording, layerEnabled) => {
26
- if (!recording() || !layerEnabled())
27
- return;
28
- const detail = e.detail;
29
- if (!detail?.kind)
30
- return;
31
- const time = now();
32
- const { kind, id } = detail;
33
- switch (kind) {
34
- case 'begin render': {
35
- const meta = hostMeta(detail.options?.host);
36
- emit({
37
- layerId: 'lit-render',
38
- time,
39
- groupId: id,
40
- title: 'render:start',
41
- subtitle: meta?.tagName,
42
- data: { kind, id },
43
- meta,
44
- });
45
- break;
46
- }
47
- case 'end render': {
48
- const meta = hostMeta(detail.options?.host);
49
- emit({
50
- layerId: 'lit-render',
51
- time,
52
- groupId: id,
53
- title: 'render:end',
54
- subtitle: meta?.tagName,
55
- data: { kind, id },
56
- meta,
57
- });
58
- break;
59
- }
60
- // `template prep` fires once per *unique* template, the first time it's
61
- // compiled — low volume, useful as a "new template" marker.
62
- case 'template prep':
63
- emit({
64
- layerId: 'lit-render',
65
- time,
66
- title: kind,
67
- data: { kind, id },
68
- });
69
- break;
70
- // `template updating` / `template instantiated` / `…and updated` fire once
71
- // per template-bound ChildPart on *every* render — extremely high volume
72
- // (a ticking clock or animation floods the layer). The begin/end render
73
- // pair above already captures each render as a grouped duration, so these
74
- // add noise without signal. Skip them; re-expose behind a "verbose" toggle
75
- // if per-part detail is ever needed. Same rationale for commit * / set part.
76
- default:
77
- break;
27
+ /**
28
+ * Reduces an arbitrary lit-html binding value to a small JSON-serializable
29
+ * summary for the verbose layer's `data` field. Never puts the value itself
30
+ * in `data` — it may be a DOM Node, a TemplateResult, a function, or hold a
31
+ * reference back to the host element, none of which survive (or belong in) a
32
+ * structured-clone over the HMR channel.
33
+ */
34
+ const describeValue = (value) => {
35
+ if (value === null) return 'null';
36
+ if (value === undefined) return 'undefined';
37
+ if (typeof value === 'string') {
38
+ return value.length > 40
39
+ ? `string:"${value.slice(0, 40)}…"`
40
+ : `string:"${value}"`;
41
+ }
42
+ if (typeof value === 'number') return `number:${value}`;
43
+ if (typeof value === 'boolean') return `boolean:${value}`;
44
+ if (typeof value === 'function') {
45
+ return `function:${value.name || 'anonymous'}`;
46
+ }
47
+ // lit's sentinels (`nothing`, `noChange`) are symbols.
48
+ if (typeof value === 'symbol') return `symbol:${value.description ?? ''}`;
49
+ if (Array.isArray(value)) return `array(${value.length})`;
50
+ if (typeof value === 'object' && '_$litType$' in value) return 'template';
51
+ if (typeof Node !== 'undefined' && value instanceof Node) {
52
+ const tag = value.tagName?.toLowerCase();
53
+ return tag ? `node:<${tag}>` : `node:#${value.nodeType}`;
54
+ }
55
+ const ctor = value?.constructor?.name;
56
+ return `object:${ctor ?? 'Object'}`;
57
+ };
58
+ /** Summarizes each entry of a template-instance's `values` array. */
59
+ const describeValues = (values) => values?.map(describeValue);
60
+ const onLitDebug = (e, emit, recording, renderEnabled, verboseEnabled) => {
61
+ if (!recording() || (!renderEnabled() && !verboseEnabled())) return;
62
+ const detail = e.detail;
63
+ if (!detail?.kind) return;
64
+ const time = now();
65
+ const {kind, id} = detail;
66
+ switch (kind) {
67
+ case 'begin render': {
68
+ if (!renderEnabled()) break;
69
+ const meta = hostMeta(detail.options?.host);
70
+ emit({
71
+ layerId: 'lit-render',
72
+ time,
73
+ groupId: id,
74
+ title: 'render:start',
75
+ subtitle: meta?.tagName,
76
+ data: {kind, id},
77
+ meta,
78
+ });
79
+ break;
80
+ }
81
+ case 'end render': {
82
+ if (!renderEnabled()) break;
83
+ const meta = hostMeta(detail.options?.host);
84
+ emit({
85
+ layerId: 'lit-render',
86
+ time,
87
+ groupId: id,
88
+ title: 'render:end',
89
+ subtitle: meta?.tagName,
90
+ data: {kind, id},
91
+ meta,
92
+ });
93
+ break;
94
+ }
95
+ // `template prep` fires once per *unique* template, the first time it's
96
+ // compiled — low volume, useful as a "new template" marker.
97
+ case 'template prep':
98
+ if (!renderEnabled()) break;
99
+ emit({
100
+ layerId: 'lit-render',
101
+ time,
102
+ title: kind,
103
+ data: {kind, id},
104
+ });
105
+ break;
106
+ // The events below fire once per template-bound part on *every* render —
107
+ // extremely high volume (a ticking clock or animation floods the layer).
108
+ // The begin/end render pair above already captures each render as a
109
+ // grouped duration, so these live on the separate opt-in
110
+ // `lit-render-verbose` layer instead of adding noise to `lit-render`.
111
+ case 'template updating':
112
+ case 'template instantiated':
113
+ case 'template instantiated and updated': {
114
+ if (!verboseEnabled()) break;
115
+ const meta = hostMeta(detail.options?.host);
116
+ emit({
117
+ layerId: 'lit-render-verbose',
118
+ time,
119
+ title: kind,
120
+ subtitle: meta?.tagName,
121
+ data: {kind, values: describeValues(detail.values)},
122
+ meta,
123
+ });
124
+ break;
125
+ }
126
+ case 'set part': {
127
+ if (!verboseEnabled()) break;
128
+ const meta = hostMeta(partHost(detail.part));
129
+ emit({
130
+ layerId: 'lit-render-verbose',
131
+ time,
132
+ title: kind,
133
+ subtitle: meta?.tagName,
134
+ data: {
135
+ kind,
136
+ valueIndex: detail.valueIndex,
137
+ value: describeValue(detail.value),
138
+ },
139
+ meta,
140
+ });
141
+ break;
142
+ }
143
+ case 'commit nothing to child': {
144
+ if (!verboseEnabled()) break;
145
+ const meta = hostMeta(detail.options?.host);
146
+ emit({
147
+ layerId: 'lit-render-verbose',
148
+ time,
149
+ title: kind,
150
+ subtitle: meta?.tagName,
151
+ data: {kind},
152
+ meta,
153
+ });
154
+ break;
155
+ }
156
+ case 'commit text':
157
+ case 'commit node':
158
+ case 'commit to element binding': {
159
+ if (!verboseEnabled()) break;
160
+ const meta = hostMeta(detail.options?.host);
161
+ emit({
162
+ layerId: 'lit-render-verbose',
163
+ time,
164
+ title: kind,
165
+ subtitle: meta?.tagName,
166
+ data: {kind, value: describeValue(detail.value)},
167
+ meta,
168
+ });
169
+ break;
170
+ }
171
+ case 'commit attribute':
172
+ case 'commit property':
173
+ case 'commit boolean attribute': {
174
+ if (!verboseEnabled()) break;
175
+ const meta = hostMeta(detail.options?.host);
176
+ emit({
177
+ layerId: 'lit-render-verbose',
178
+ time,
179
+ title: kind,
180
+ subtitle: meta?.tagName,
181
+ data: {kind, name: detail.name, value: describeValue(detail.value)},
182
+ meta,
183
+ });
184
+ break;
185
+ }
186
+ case 'commit event listener': {
187
+ if (!verboseEnabled()) break;
188
+ const meta = hostMeta(detail.options?.host);
189
+ emit({
190
+ layerId: 'lit-render-verbose',
191
+ time,
192
+ title: kind,
193
+ subtitle: meta?.tagName,
194
+ data: {
195
+ kind,
196
+ name: detail.name,
197
+ addListener: detail.addListener,
198
+ removeListener: detail.removeListener,
199
+ },
200
+ meta,
201
+ });
202
+ break;
78
203
  }
204
+ // Unknown or future `*Unstable` kind — ignore rather than guess a shape.
205
+ default:
206
+ break;
207
+ }
79
208
  };
80
209
  /**
81
- * Install the lit-debug render layer.
210
+ * Install the lit-debug render layers (`lit-render` and the opt-in
211
+ * `lit-render-verbose`).
82
212
  * Idempotent — calling again when already installed is a no-op.
83
213
  */
84
- export const installRenderLayer = (emit, recording, layerEnabled) => {
85
- if (removeListener !== null)
86
- return;
87
- // The listener is cheap and always attached; the per-render cost lives in the
88
- // `emitLitDebugLogEvents` flag, which the caller toggles via
89
- // `setRenderDebugEnabled` only while actively capturing.
90
- const handler = (e) => onLitDebug(e, emit, recording, layerEnabled);
91
- window.addEventListener('lit-debug', handler);
92
- removeListener = () => window.removeEventListener('lit-debug', handler);
214
+ export const installRenderLayer = (
215
+ emit,
216
+ recording,
217
+ renderEnabled,
218
+ verboseEnabled
219
+ ) => {
220
+ if (removeListener !== null) return;
221
+ // The listener is cheap and always attached; the per-render cost lives in the
222
+ // `emitLitDebugLogEvents` flag, which the caller toggles via
223
+ // `setRenderDebugEnabled` only while actively capturing.
224
+ const handler = (e) =>
225
+ onLitDebug(e, emit, recording, renderEnabled, verboseEnabled);
226
+ window.addEventListener('lit-debug', handler);
227
+ removeListener = () => window.removeEventListener('lit-debug', handler);
93
228
  };
94
229
  /**
95
230
  * Toggle Lit's debug event system. Enabling makes lit-html dispatch a
@@ -97,13 +232,12 @@ export const installRenderLayer = (emit, recording, layerEnabled) => {
97
232
  * keeps it off unless the render layer is actively recording.
98
233
  */
99
234
  export const setRenderDebugEnabled = (enabled) => {
100
- globalThis.emitLitDebugLogEvents =
101
- enabled;
235
+ globalThis.emitLitDebugLogEvents = enabled;
102
236
  };
103
237
  /** Remove the listener and clear the Lit debug flag. */
104
238
  export const uninstallRenderLayer = () => {
105
- removeListener?.();
106
- removeListener = null;
107
- setRenderDebugEnabled(false);
239
+ removeListener?.();
240
+ removeListener = null;
241
+ setRenderDebugEnabled(false);
108
242
  };
109
- //# sourceMappingURL=render.js.map
243
+ //# sourceMappingURL=render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../../packages/labs/vite-plugin-lit/src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAC,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAC,GAAG,EAAC,MAAM,YAAY,CAAC;AAgB/B;;;;;;GAMG;AACH,MAAM,QAAQ,GAAG,CACf,IAAa,EACmC,EAAE;IAClD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC;QACrB,OAAO,EAAG,IAAgB,CAAC,SAAS,IAAI,SAAS;QACjD,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC;KACvB,CAAC;AACJ,CAAC,CAAC;AAIF,IAAI,cAAc,GAAwB,IAAI,CAAC;AAE/C,MAAM,UAAU,GAAG,CACjB,CAAQ,EACR,IAAY,EACZ,SAAsB,EACtB,YAA4B,EACtB,EAAE;IACR,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE;QAAE,OAAO;IAE5C,MAAM,MAAM,GAAI,CAAmB,CAAC,MAAM,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,IAAI;QAAE,OAAO;IAE1B,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC;IACnB,MAAM,EAAC,IAAI,EAAE,EAAE,EAAC,GAAG,MAAM,CAAC;IAE1B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC5C,IAAI,CAAC;gBACH,OAAO,EAAE,YAAY;gBACrB,IAAI;gBACJ,OAAO,EAAE,EAAE;gBACX,KAAK,EAAE,cAAc;gBACrB,QAAQ,EAAE,IAAI,EAAE,OAAO;gBACvB,IAAI,EAAE,EAAC,IAAI,EAAE,EAAE,EAAC;gBAChB,IAAI;aACL,CAAC,CAAC;YACH,MAAM;QACR,CAAC;QAED,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC5C,IAAI,CAAC;gBACH,OAAO,EAAE,YAAY;gBACrB,IAAI;gBACJ,OAAO,EAAE,EAAE;gBACX,KAAK,EAAE,YAAY;gBACnB,QAAQ,EAAE,IAAI,EAAE,OAAO;gBACvB,IAAI,EAAE,EAAC,IAAI,EAAE,EAAE,EAAC;gBAChB,IAAI;aACL,CAAC,CAAC;YACH,MAAM;QACR,CAAC;QAED,wEAAwE;QACxE,4DAA4D;QAC5D,KAAK,eAAe;YAClB,IAAI,CAAC;gBACH,OAAO,EAAE,YAAY;gBACrB,IAAI;gBACJ,KAAK,EAAE,IAAI;gBACX,IAAI,EAAE,EAAC,IAAI,EAAE,EAAE,EAAC;aACjB,CAAC,CAAC;YACH,MAAM;QAER,2EAA2E;QAC3E,yEAAyE;QACzE,wEAAwE;QACxE,0EAA0E;QAC1E,2EAA2E;QAC3E,6EAA6E;QAC7E;YACE,MAAM;IACV,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,IAAY,EACZ,SAAsB,EACtB,YAA4B,EACtB,EAAE;IACR,IAAI,cAAc,KAAK,IAAI;QAAE,OAAO;IAEpC,8EAA8E;IAC9E,6DAA6D;IAC7D,yDAAyD;IACzD,MAAM,OAAO,GAAG,CAAC,CAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC3E,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9C,cAAc,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAgB,EAAQ,EAAE;IAC7D,UAAgD,CAAC,qBAAqB;QACrE,OAAO,CAAC;AACZ,CAAC,CAAC;AAEF,wDAAwD;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAS,EAAE;IAC7C,cAAc,EAAE,EAAE,CAAC;IACnB,cAAc,GAAG,IAAI,CAAC;IACtB,qBAAqB,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * lit-render timeline layer — listens to the built-in lit-debug CustomEvents\n * instead of patching prototypes, so it's zero-cost when the Lit debug flag\n * is off and perfectly accurate for the render layer.\n *\n * `globalThis.emitLitDebugLogEvents = true` gates the events, and lit-html\n * dispatches a CustomEvent per render whenever it's set — a real per-render\n * cost. So the caller drives the flag via {@link setRenderDebugEnabled} from\n * `recording × layer-enabled` rather than leaving it on for the whole session.\n * The events are tagged `*Unstable` in the Lit source; we tolerate missing\n * `kind` values gracefully.\n *\n * begin render / end render share a numeric `id` → we use it as groupId so\n * the panel can show a duration bar for each render call.\n */\n\nimport type {TimelineEvent} from '../../../types/timeline.js';\nimport {idOf, sourceOf} from './identity.js';\nimport {now} from './clock.js';\n\ntype EmitFn = (event: TimelineEvent) => void;\ntype RecordingFn = () => boolean;\ntype LayerEnabledFn = () => boolean;\n\n/** Minimal shape of the lit-debug event detail we care about. */\ninterface LitDebugDetail {\n kind: string;\n id?: number;\n template?: unknown;\n instance?: unknown;\n /** Render options passed to lit-html's `render()`; `host` is the element. */\n options?: {host?: unknown};\n}\n\n/**\n * Builds the element-identity `meta` for a render event from the render\n * `host` (the LitElement whose `render()` produced these debug events).\n * Uses the same id/source maps as the lifecycle layer so an element keeps one\n * stable id across both layers. Returns undefined for host-less renders\n * (e.g. a bare lit-html `render()` call not driven by a LitElement).\n */\nconst hostMeta = (\n host: unknown\n): NonNullable<TimelineEvent['meta']> | undefined => {\n if (host === null || typeof host !== 'object') return undefined;\n return {\n elementId: idOf(host),\n tagName: (host as Element).localName ?? 'unknown',\n source: sourceOf(host),\n };\n};\n\ntype LitDebugEvent = CustomEvent<LitDebugDetail>;\n\nlet removeListener: (() => void) | null = null;\n\nconst onLitDebug = (\n e: Event,\n emit: EmitFn,\n recording: RecordingFn,\n layerEnabled: LayerEnabledFn\n): void => {\n if (!recording() || !layerEnabled()) return;\n\n const detail = (e as LitDebugEvent).detail;\n if (!detail?.kind) return;\n\n const time = now();\n const {kind, id} = detail;\n\n switch (kind) {\n case 'begin render': {\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:start',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n case 'end render': {\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:end',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n // `template prep` fires once per *unique* template, the first time it's\n // compiled — low volume, useful as a \"new template\" marker.\n case 'template prep':\n emit({\n layerId: 'lit-render',\n time,\n title: kind,\n data: {kind, id},\n });\n break;\n\n // `template updating` / `template instantiated` / `…and updated` fire once\n // per template-bound ChildPart on *every* render — extremely high volume\n // (a ticking clock or animation floods the layer). The begin/end render\n // pair above already captures each render as a grouped duration, so these\n // add noise without signal. Skip them; re-expose behind a \"verbose\" toggle\n // if per-part detail is ever needed. Same rationale for commit * / set part.\n default:\n break;\n }\n};\n\n/**\n * Install the lit-debug render layer.\n * Idempotent — calling again when already installed is a no-op.\n */\nexport const installRenderLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n layerEnabled: LayerEnabledFn\n): void => {\n if (removeListener !== null) return;\n\n // The listener is cheap and always attached; the per-render cost lives in the\n // `emitLitDebugLogEvents` flag, which the caller toggles via\n // `setRenderDebugEnabled` only while actively capturing.\n const handler = (e: Event) => onLitDebug(e, emit, recording, layerEnabled);\n window.addEventListener('lit-debug', handler);\n removeListener = () => window.removeEventListener('lit-debug', handler);\n};\n\n/**\n * Toggle Lit's debug event system. Enabling makes lit-html dispatch a\n * CustomEvent on every render (dev-only; no-op in prod builds), so the caller\n * keeps it off unless the render layer is actively recording.\n */\nexport const setRenderDebugEnabled = (enabled: boolean): void => {\n (globalThis as {emitLitDebugLogEvents?: boolean}).emitLitDebugLogEvents =\n enabled;\n};\n\n/** Remove the listener and clear the Lit debug flag. */\nexport const uninstallRenderLayer = (): void => {\n removeListener?.();\n removeListener = null;\n setRenderDebugEnabled(false);\n};\n"]}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/render.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * lit-render timeline layers — listen to the built-in lit-debug CustomEvents\n * instead of patching prototypes, so they're zero-cost when the Lit debug\n * flag is off and perfectly accurate for the render layers.\n *\n * `globalThis.emitLitDebugLogEvents = true` gates the events, and lit-html\n * dispatches a CustomEvent per render whenever it's set — a real per-render\n * cost. So the caller drives the flag via {@link setRenderDebugEnabled} from\n * `recording × (lit-render OR lit-render-verbose enabled)` rather than\n * leaving it on for the whole session.\n * The events are tagged `*Unstable` in the Lit source; we tolerate missing\n * `kind` values gracefully.\n *\n * begin render / end render share a numeric `id` → we use it as groupId so\n * the panel can show a duration bar for each render call.\n *\n * `template updating` / `template instantiated[ and updated]` / `set part` /\n * `commit *` fire once per template-bound part on *every* render — extremely\n * high volume (a ticking clock or animation floods the layer). They're\n * emitted on the separate opt-in `lit-render-verbose` layer rather than\n * `lit-render`, so the common case (the begin/end render duration bar) stays\n * quiet by default.\n */\n\nimport type {TimelineEvent} from '../../../types/timeline.js';\nimport {idOf, sourceOf} from './identity.js';\nimport {now} from './clock.js';\n\ntype EmitFn = (event: TimelineEvent) => void;\ntype RecordingFn = () => boolean;\ntype LayerEnabledFn = () => boolean;\n\n/**\n * Minimal shape of the lit-debug event detail we care about. Broader than any\n * single `kind` needs — see lit-html's `LitUnstable.DebugLog.Entry` union in\n * `packages/lit-html/src/lit-html.ts` for the exact per-kind shapes; fields\n * below are the ones this layer reads across all of them.\n */\ninterface LitDebugDetail {\n kind: string;\n id?: number;\n template?: unknown;\n instance?: unknown;\n /** Render options passed to lit-html's `render()`; `host` is the element. */\n options?: {host?: unknown};\n /** `template updating` / `template instantiated[ and updated]`. */\n values?: unknown[];\n /** `set part` / most `commit *` kinds. */\n value?: unknown;\n /**\n * `set part` only. Unlike every other kind, `set part` carries no\n * top-level `options` — the host lives on the `Part` instance itself\n * (`ChildPart` / `AttributePart` / `EventPart` / `ElementPart` all expose a\n * public `options: RenderOptions | undefined`), so the host is derived via\n * {@link partHost} instead of `options?.host` directly.\n */\n part?: {options?: {host?: unknown}};\n /** `set part`. */\n valueIndex?: number;\n /** `commit attribute` / `commit property` / `commit boolean attribute` /\n * `commit event listener`. */\n name?: string;\n /** `commit event listener`. */\n addListener?: boolean;\n removeListener?: boolean;\n}\n\n/**\n * Builds the element-identity `meta` for a render event from the render\n * `host` (the LitElement whose `render()` produced these debug events).\n * Uses the same id/source maps as the lifecycle layer so an element keeps one\n * stable id across both layers. Returns undefined for host-less renders\n * (e.g. a bare lit-html `render()` call not driven by a LitElement).\n */\nconst hostMeta = (\n host: unknown\n): NonNullable<TimelineEvent['meta']> | undefined => {\n if (host === null || typeof host !== 'object') return undefined;\n return {\n elementId: idOf(host),\n tagName: (host as Element).localName ?? 'unknown',\n source: sourceOf(host),\n };\n};\n\n/** Reads the render `host` off a `Part` for the one kind (`set part`) whose\n * detail carries the part instead of the render `options` directly. */\nconst partHost = (part: LitDebugDetail['part']): unknown => part?.options?.host;\n\ntype LitDebugEvent = CustomEvent<LitDebugDetail>;\n\nlet removeListener: (() => void) | null = null;\n\n/**\n * Reduces an arbitrary lit-html binding value to a small JSON-serializable\n * summary for the verbose layer's `data` field. Never puts the value itself\n * in `data` — it may be a DOM Node, a TemplateResult, a function, or hold a\n * reference back to the host element, none of which survive (or belong in) a\n * structured-clone over the HMR channel.\n */\nconst describeValue = (value: unknown): string => {\n if (value === null) return 'null';\n if (value === undefined) return 'undefined';\n if (typeof value === 'string') {\n return value.length > 40\n ? `string:\"${value.slice(0, 40)}…\"`\n : `string:\"${value}\"`;\n }\n if (typeof value === 'number') return `number:${value}`;\n if (typeof value === 'boolean') return `boolean:${value}`;\n if (typeof value === 'function') {\n return `function:${value.name || 'anonymous'}`;\n }\n // lit's sentinels (`nothing`, `noChange`) are symbols.\n if (typeof value === 'symbol') return `symbol:${value.description ?? ''}`;\n if (Array.isArray(value)) return `array(${value.length})`;\n if (typeof value === 'object' && '_$litType$' in value) return 'template';\n if (typeof Node !== 'undefined' && value instanceof Node) {\n const tag = (value as Partial<Element>).tagName?.toLowerCase();\n return tag ? `node:<${tag}>` : `node:#${value.nodeType}`;\n }\n const ctor = (value as {constructor?: {name?: string}})?.constructor?.name;\n return `object:${ctor ?? 'Object'}`;\n};\n\n/** Summarizes each entry of a template-instance's `values` array. */\nconst describeValues = (values: unknown[] | undefined): string[] | undefined =>\n values?.map(describeValue);\n\nconst onLitDebug = (\n e: Event,\n emit: EmitFn,\n recording: RecordingFn,\n renderEnabled: LayerEnabledFn,\n verboseEnabled: LayerEnabledFn\n): void => {\n if (!recording() || (!renderEnabled() && !verboseEnabled())) return;\n\n const detail = (e as LitDebugEvent).detail;\n if (!detail?.kind) return;\n\n const time = now();\n const {kind, id} = detail;\n\n switch (kind) {\n case 'begin render': {\n if (!renderEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:start',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n case 'end render': {\n if (!renderEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render',\n time,\n groupId: id,\n title: 'render:end',\n subtitle: meta?.tagName,\n data: {kind, id},\n meta,\n });\n break;\n }\n\n // `template prep` fires once per *unique* template, the first time it's\n // compiled — low volume, useful as a \"new template\" marker.\n case 'template prep':\n if (!renderEnabled()) break;\n emit({\n layerId: 'lit-render',\n time,\n title: kind,\n data: {kind, id},\n });\n break;\n\n // The events below fire once per template-bound part on *every* render —\n // extremely high volume (a ticking clock or animation floods the layer).\n // The begin/end render pair above already captures each render as a\n // grouped duration, so these live on the separate opt-in\n // `lit-render-verbose` layer instead of adding noise to `lit-render`.\n case 'template updating':\n case 'template instantiated':\n case 'template instantiated and updated': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind, values: describeValues(detail.values)},\n meta,\n });\n break;\n }\n\n case 'set part': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(partHost(detail.part));\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {\n kind,\n valueIndex: detail.valueIndex,\n value: describeValue(detail.value),\n },\n meta,\n });\n break;\n }\n\n case 'commit nothing to child': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind},\n meta,\n });\n break;\n }\n\n case 'commit text':\n case 'commit node':\n case 'commit to element binding': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind, value: describeValue(detail.value)},\n meta,\n });\n break;\n }\n\n case 'commit attribute':\n case 'commit property':\n case 'commit boolean attribute': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {kind, name: detail.name, value: describeValue(detail.value)},\n meta,\n });\n break;\n }\n\n case 'commit event listener': {\n if (!verboseEnabled()) break;\n const meta = hostMeta(detail.options?.host);\n emit({\n layerId: 'lit-render-verbose',\n time,\n title: kind,\n subtitle: meta?.tagName,\n data: {\n kind,\n name: detail.name,\n addListener: detail.addListener,\n removeListener: detail.removeListener,\n },\n meta,\n });\n break;\n }\n\n // Unknown or future `*Unstable` kind — ignore rather than guess a shape.\n default:\n break;\n }\n};\n\n/**\n * Install the lit-debug render layers (`lit-render` and the opt-in\n * `lit-render-verbose`).\n * Idempotent — calling again when already installed is a no-op.\n */\nexport const installRenderLayer = (\n emit: EmitFn,\n recording: RecordingFn,\n renderEnabled: LayerEnabledFn,\n verboseEnabled: LayerEnabledFn\n): void => {\n if (removeListener !== null) return;\n\n // The listener is cheap and always attached; the per-render cost lives in the\n // `emitLitDebugLogEvents` flag, which the caller toggles via\n // `setRenderDebugEnabled` only while actively capturing.\n const handler = (e: Event) =>\n onLitDebug(e, emit, recording, renderEnabled, verboseEnabled);\n window.addEventListener('lit-debug', handler);\n removeListener = () => window.removeEventListener('lit-debug', handler);\n};\n\n/**\n * Toggle Lit's debug event system. Enabling makes lit-html dispatch a\n * CustomEvent on every render (dev-only; no-op in prod builds), so the caller\n * keeps it off unless the render layer is actively recording.\n */\nexport const setRenderDebugEnabled = (enabled: boolean): void => {\n (globalThis as {emitLitDebugLogEvents?: boolean}).emitLitDebugLogEvents =\n enabled;\n};\n\n/** Remove the listener and clear the Lit debug flag. */\nexport const uninstallRenderLayer = (): void => {\n removeListener?.();\n removeListener = null;\n setRenderDebugEnabled(false);\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../../../packages/labs/vite-plugin-lit/src/lib/runtime/timeline/transport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAE9D,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9C,CAAC;AAmBF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,SAAS,KAAG,IAe7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,IAAI,MAAM,IAAI,KAAG,IAMrD,CAAC;AAaF;;;;GAIG;AACH,eAAO,MAAM,IAAI,GAAI,OAAO,aAAa,KAAG,IAc3C,CAAC"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/transport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAE9D,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9C,CAAC;AAmBF;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAS,SAAS,KAAG,IAe7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,OAAQ,MAAM,IAAI,KAAG,IAMrD,CAAC;AAaF;;;;GAIG;AACH,eAAO,MAAM,IAAI,UAAW,aAAa,KAAG,IAc3C,CAAC"}
@@ -23,45 +23,41 @@ const pendingCallbacks = [];
23
23
  * Flushes any queued events and fires pending one-shot callbacks.
24
24
  */
25
25
  export const setHotClient = (hot) => {
26
- hotClient = hot;
27
- // Drain any events that arrived before the client was wired.
28
- if (queue.length > 0 && !flushScheduled) {
29
- flushScheduled = true;
30
- queueMicrotask(flush);
31
- }
32
- // Fire one-shot callbacks (e.g. addTimelineLayer announcements).
33
- for (const cb of pendingCallbacks.splice(0)) {
34
- try {
35
- cb();
36
- }
37
- catch {
38
- // ignore
39
- }
26
+ hotClient = hot;
27
+ // Drain any events that arrived before the client was wired.
28
+ if (queue.length > 0 && !flushScheduled) {
29
+ flushScheduled = true;
30
+ queueMicrotask(flush);
31
+ }
32
+ // Fire one-shot callbacks (e.g. addTimelineLayer announcements).
33
+ for (const cb of pendingCallbacks.splice(0)) {
34
+ try {
35
+ cb();
36
+ } catch {
37
+ // ignore
40
38
  }
39
+ }
41
40
  };
42
41
  /**
43
42
  * Register a callback to be invoked once the HMR client is available.
44
43
  * If the client is already set the callback is fired on the next microtask.
45
44
  */
46
45
  export const setHotClientCallback = (cb) => {
47
- if (hotClient !== null) {
48
- queueMicrotask(cb);
49
- }
50
- else {
51
- pendingCallbacks.push(cb);
52
- }
46
+ if (hotClient !== null) {
47
+ queueMicrotask(cb);
48
+ } else {
49
+ pendingCallbacks.push(cb);
50
+ }
53
51
  };
54
52
  const flush = () => {
55
- flushScheduled = false;
56
- if (queue.length === 0 || hotClient === null)
57
- return;
58
- const batch = queue.splice(0);
59
- try {
60
- hotClient.send('lit:timeline:push-event', { events: batch });
61
- }
62
- catch {
63
- // HMR channel may be temporarily unavailable; events are dropped.
64
- }
53
+ flushScheduled = false;
54
+ if (queue.length === 0 || hotClient === null) return;
55
+ const batch = queue.splice(0);
56
+ try {
57
+ hotClient.send('lit:timeline:push-event', {events: batch});
58
+ } catch {
59
+ // HMR channel may be temporarily unavailable; events are dropped.
60
+ }
65
61
  };
66
62
  /**
67
63
  * Enqueue a timeline event for forwarding to the Vite server.
@@ -69,18 +65,18 @@ const flush = () => {
69
65
  * doesn't send dozens of individual messages.
70
66
  */
71
67
  export const emit = (event) => {
72
- queue.push(event);
73
- if (hotClient === null) {
74
- // No consumer yet: bound the buffer instead of scheduling a flush that
75
- // would only no-op. `setHotClient` drains the retained tail on connect.
76
- if (queue.length > MAX_PENDING) {
77
- queue.splice(0, queue.length - MAX_PENDING);
78
- }
79
- return;
80
- }
81
- if (!flushScheduled) {
82
- flushScheduled = true;
83
- queueMicrotask(flush);
68
+ queue.push(event);
69
+ if (hotClient === null) {
70
+ // No consumer yet: bound the buffer instead of scheduling a flush that
71
+ // would only no-op. `setHotClient` drains the retained tail on connect.
72
+ if (queue.length > MAX_PENDING) {
73
+ queue.splice(0, queue.length - MAX_PENDING);
84
74
  }
75
+ return;
76
+ }
77
+ if (!flushScheduled) {
78
+ flushScheduled = true;
79
+ queueMicrotask(flush);
80
+ }
85
81
  };
86
- //# sourceMappingURL=transport.js.map
82
+ //# sourceMappingURL=transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../../../packages/labs/vite-plugin-lit/src/lib/runtime/timeline/transport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuBH,MAAM,KAAK,GAAoB,EAAE,CAAC;AAClC,IAAI,cAAc,GAAG,KAAK,CAAC;AAC3B,IAAI,SAAS,GAAqB,IAAI,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB,kFAAkF;AAClF,oEAAoE;AACpE,MAAM,gBAAgB,GAAsB,EAAE,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAc,EAAQ,EAAE;IACnD,SAAS,GAAG,GAAG,CAAC;IAChB,6DAA6D;IAC7D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QACxC,cAAc,GAAG,IAAI,CAAC;QACtB,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,iEAAiE;IACjE,KAAK,MAAM,EAAE,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,EAAE,EAAE,CAAC;QACP,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAc,EAAQ,EAAE;IAC3D,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,GAAS,EAAE;IACvB,cAAc,GAAG,KAAK,CAAC;IACvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO;IACrD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;AACH,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAoB,EAAQ,EAAE;IACjD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,uEAAuE;QACvE,wEAAwE;QACxE,IAAI,KAAK,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;YAC/B,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,CAAC;QACtB,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;AACH,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Buffered transport for timeline events.\n *\n * Phase 0/1: forwards events over Vite's HMR WebSocket channel\n * (`import.meta.hot.send`). This avoids the need for a separate devframe\n * RPC connection in early phases and works with any Vite dev server.\n *\n * Phase 2 migration: replace `sendViaHmr` with `sendViaRpc` when the\n * devframe RPC client is available (injected by the panel's clientScript).\n *\n * Batching: we coalesce events with `queueMicrotask` so a burst of\n * commit/set-part events from a single render doesn't hammer the channel\n * with one message per event.\n */\n\nimport type {TimelineEvent} from '../../../types/timeline.js';\n\ntype HotClient = {\n send: (event: string, data: unknown) => void;\n};\n\nconst queue: TimelineEvent[] = [];\nlet flushScheduled = false;\nlet hotClient: HotClient | null = null;\n\n/**\n * Cap on events retained while no hot client is connected. Without a client\n * `flush()` cannot drain the queue, so an uncapped buffer would grow for the\n * whole session (in production, or before `install.ts` wires the client).\n * We keep only the most recent events; the retained tail flushes if a client\n * later connects.\n */\nconst MAX_PENDING = 1000;\n\n// Callbacks registered before the hot client was available (e.g. addTimelineLayer\n// called at module init time before install.ts has set the client).\nconst pendingCallbacks: Array<() => void> = [];\n\n/**\n * Register the HMR hot client.\n * Called by install.ts after import.meta.hot check.\n * Flushes any queued events and fires pending one-shot callbacks.\n */\nexport const setHotClient = (hot: HotClient): void => {\n hotClient = hot;\n // Drain any events that arrived before the client was wired.\n if (queue.length > 0 && !flushScheduled) {\n flushScheduled = true;\n queueMicrotask(flush);\n }\n // Fire one-shot callbacks (e.g. addTimelineLayer announcements).\n for (const cb of pendingCallbacks.splice(0)) {\n try {\n cb();\n } catch {\n // ignore\n }\n }\n};\n\n/**\n * Register a callback to be invoked once the HMR client is available.\n * If the client is already set the callback is fired on the next microtask.\n */\nexport const setHotClientCallback = (cb: () => void): void => {\n if (hotClient !== null) {\n queueMicrotask(cb);\n } else {\n pendingCallbacks.push(cb);\n }\n};\n\nconst flush = (): void => {\n flushScheduled = false;\n if (queue.length === 0 || hotClient === null) return;\n const batch = queue.splice(0);\n try {\n hotClient.send('lit:timeline:push-event', {events: batch});\n } catch {\n // HMR channel may be temporarily unavailable; events are dropped.\n }\n};\n\n/**\n * Enqueue a timeline event for forwarding to the Vite server.\n * Batches via microtask so a single synchronous render burst\n * doesn't send dozens of individual messages.\n */\nexport const emit = (event: TimelineEvent): void => {\n queue.push(event);\n if (hotClient === null) {\n // No consumer yet: bound the buffer instead of scheduling a flush that\n // would only no-op. `setHotClient` drains the retained tail on connect.\n if (queue.length > MAX_PENDING) {\n queue.splice(0, queue.length - MAX_PENDING);\n }\n return;\n }\n if (!flushScheduled) {\n flushScheduled = true;\n queueMicrotask(flush);\n }\n};\n"]}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/lib/runtime/timeline/transport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuBH,MAAM,KAAK,GAAoB,EAAE,CAAC;AAClC,IAAI,cAAc,GAAG,KAAK,CAAC;AAC3B,IAAI,SAAS,GAAqB,IAAI,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB,kFAAkF;AAClF,oEAAoE;AACpE,MAAM,gBAAgB,GAAsB,EAAE,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAc,EAAQ,EAAE;IACnD,SAAS,GAAG,GAAG,CAAC;IAChB,6DAA6D;IAC7D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QACxC,cAAc,GAAG,IAAI,CAAC;QACtB,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,iEAAiE;IACjE,KAAK,MAAM,EAAE,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,EAAE,EAAE,CAAC;QACP,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAc,EAAQ,EAAE;IAC3D,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,GAAS,EAAE;IACvB,cAAc,GAAG,KAAK,CAAC;IACvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO;IACrD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;AACH,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAoB,EAAQ,EAAE;IACjD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,uEAAuE;QACvE,wEAAwE;QACxE,IAAI,KAAK,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;YAC/B,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,CAAC;QACtB,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;AACH,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Buffered transport for timeline events.\n *\n * Phase 0/1: forwards events over Vite's HMR WebSocket channel\n * (`import.meta.hot.send`). This avoids the need for a separate devframe\n * RPC connection in early phases and works with any Vite dev server.\n *\n * Phase 2 migration: replace `sendViaHmr` with `sendViaRpc` when the\n * devframe RPC client is available (injected by the panel's clientScript).\n *\n * Batching: we coalesce events with `queueMicrotask` so a burst of\n * commit/set-part events from a single render doesn't hammer the channel\n * with one message per event.\n */\n\nimport type {TimelineEvent} from '../../../types/timeline.js';\n\ntype HotClient = {\n send: (event: string, data: unknown) => void;\n};\n\nconst queue: TimelineEvent[] = [];\nlet flushScheduled = false;\nlet hotClient: HotClient | null = null;\n\n/**\n * Cap on events retained while no hot client is connected. Without a client\n * `flush()` cannot drain the queue, so an uncapped buffer would grow for the\n * whole session (in production, or before `install.ts` wires the client).\n * We keep only the most recent events; the retained tail flushes if a client\n * later connects.\n */\nconst MAX_PENDING = 1000;\n\n// Callbacks registered before the hot client was available (e.g. addTimelineLayer\n// called at module init time before install.ts has set the client).\nconst pendingCallbacks: Array<() => void> = [];\n\n/**\n * Register the HMR hot client.\n * Called by install.ts after import.meta.hot check.\n * Flushes any queued events and fires pending one-shot callbacks.\n */\nexport const setHotClient = (hot: HotClient): void => {\n hotClient = hot;\n // Drain any events that arrived before the client was wired.\n if (queue.length > 0 && !flushScheduled) {\n flushScheduled = true;\n queueMicrotask(flush);\n }\n // Fire one-shot callbacks (e.g. addTimelineLayer announcements).\n for (const cb of pendingCallbacks.splice(0)) {\n try {\n cb();\n } catch {\n // ignore\n }\n }\n};\n\n/**\n * Register a callback to be invoked once the HMR client is available.\n * If the client is already set the callback is fired on the next microtask.\n */\nexport const setHotClientCallback = (cb: () => void): void => {\n if (hotClient !== null) {\n queueMicrotask(cb);\n } else {\n pendingCallbacks.push(cb);\n }\n};\n\nconst flush = (): void => {\n flushScheduled = false;\n if (queue.length === 0 || hotClient === null) return;\n const batch = queue.splice(0);\n try {\n hotClient.send('lit:timeline:push-event', {events: batch});\n } catch {\n // HMR channel may be temporarily unavailable; events are dropped.\n }\n};\n\n/**\n * Enqueue a timeline event for forwarding to the Vite server.\n * Batches via microtask so a single synchronous render burst\n * doesn't send dozens of individual messages.\n */\nexport const emit = (event: TimelineEvent): void => {\n queue.push(event);\n if (hotClient === null) {\n // No consumer yet: bound the buffer instead of scheduling a flush that\n // would only no-op. `setHotClient` drains the retained tail on connect.\n if (queue.length > MAX_PENDING) {\n queue.splice(0, queue.length - MAX_PENDING);\n }\n return;\n }\n if (!flushScheduled) {\n flushScheduled = true;\n queueMicrotask(flush);\n }\n};\n"]}
@@ -8,6 +8,8 @@ export interface TabItem {
8
8
  id: string;
9
9
  label: string;
10
10
  icon?: string;
11
+ /** Optional count pill trailing the label. Hidden when absent or zero. */
12
+ badge?: number;
11
13
  }
12
14
  export type SegTabSize = 'sm' | 'md';
13
15
  /**
@@ -23,7 +25,7 @@ export declare class SegmentedTabs extends LitElement {
23
25
  size: SegTabSize;
24
26
  constructor();
25
27
  private _select;
26
- render(): import("lit-html").TemplateResult<1>;
28
+ render(): import("lit").TemplateResult<1>;
27
29
  }
28
30
  declare global {
29
31
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-tabs.d.ts","sourceRoot":"","sources":["../../../packages/labs/vite-plugin-lit/src/lib/segmented-tabs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,UAAU,EAAqB,MAAM,KAAK,CAAC;AAInD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;AAErC;;;;;GAKG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C,OAAgB,MAAM,4BAuDpB;IAE+B,KAAK,EAAE,OAAO,EAAE,CAAC;IAE9B,KAAK,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,UAAU,CAAC;;IASrC,OAAO,CAAC,OAAO;IAWN,MAAM;CAyBhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,aAAa,CAAC;KACjC;CACF"}
1
+ {"version":3,"file":"segmented-tabs.d.ts","sourceRoot":"","sources":["../src/lib/segmented-tabs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,UAAU,EAAqB,MAAM,KAAK,CAAC;AAInD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;AAErC;;;;;GAKG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C,OAAgB,MAAM,4BAkEpB;IAE+B,KAAK,EAAE,OAAO,EAAE,CAAC;IAE9B,KAAK,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,UAAU,CAAC;IAErC,cAKC;IAED,OAAO,CAAC,OAAO;IAWN,MAAM,oCA+Bd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,aAAa,CAAC;KACjC;CACF"}