@three-flatland/devtools 0.1.0-alpha.3 → 1.0.0-alpha.6

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 (172) hide show
  1. package/README.md +1 -1
  2. package/dist/buffers-modal.d.ts +16 -52
  3. package/dist/buffers-modal.d.ts.map +1 -0
  4. package/dist/buffers-modal.js +459 -464
  5. package/dist/buffers-modal.js.map +1 -1
  6. package/dist/buffers-view.d.ts +22 -34
  7. package/dist/buffers-view.d.ts.map +1 -0
  8. package/dist/buffers-view.js +252 -240
  9. package/dist/buffers-view.js.map +1 -1
  10. package/dist/create-pane.d.ts +38 -37
  11. package/dist/create-pane.d.ts.map +1 -0
  12. package/dist/create-pane.js +197 -166
  13. package/dist/create-pane.js.map +1 -1
  14. package/dist/dashboard/app.tsx +2 -0
  15. package/dist/dashboard/export.ts +1 -3
  16. package/dist/dashboard/frame-cursor.ts +81 -0
  17. package/dist/dashboard/hooks.ts +10 -2
  18. package/dist/dashboard/index.html +61 -0
  19. package/dist/dashboard/panels/batches.tsx +5 -18
  20. package/dist/dashboard/panels/buffers.tsx +52 -26
  21. package/dist/dashboard/panels/env.tsx +5 -6
  22. package/dist/dashboard/panels/protocol-log.tsx +146 -58
  23. package/dist/dashboard/panels/registry.tsx +55 -69
  24. package/dist/dashboard/panels/scrubber.tsx +100 -0
  25. package/dist/dashboard/panels/stats.tsx +60 -32
  26. package/dist/dashboard/protocol-store.ts +25 -8
  27. package/dist/dashboard/vendor/hooks.module.d.ts +146 -0
  28. package/dist/dashboard/vendor/jsx-runtime.d.ts +55 -0
  29. package/dist/dashboard/vendor/jsx.d.ts +3123 -0
  30. package/dist/dashboard/vendor/preact.module.d.ts +397 -0
  31. package/dist/devtools-client.d.ts +312 -300
  32. package/dist/devtools-client.d.ts.map +1 -0
  33. package/dist/devtools-client.js +866 -838
  34. package/dist/devtools-client.js.map +1 -1
  35. package/dist/index.d.ts +6 -8
  36. package/dist/index.js +5 -12
  37. package/dist/perf-trace.d.ts +6 -4
  38. package/dist/perf-trace.d.ts.map +1 -0
  39. package/dist/perf-trace.js +80 -66
  40. package/dist/perf-trace.js.map +1 -1
  41. package/dist/plugins.d.ts +6 -6
  42. package/dist/plugins.d.ts.map +1 -0
  43. package/dist/plugins.js +5 -5
  44. package/dist/plugins.js.map +1 -1
  45. package/dist/provider-switcher.d.ts +8 -15
  46. package/dist/provider-switcher.d.ts.map +1 -0
  47. package/dist/provider-switcher.js +68 -68
  48. package/dist/provider-switcher.js.map +1 -1
  49. package/dist/react/devtools-provider.d.ts +11 -10
  50. package/dist/react/devtools-provider.d.ts.map +1 -0
  51. package/dist/react/devtools-provider.js +60 -32
  52. package/dist/react/devtools-provider.js.map +1 -1
  53. package/dist/react/use-fps-graph.d.ts +7 -7
  54. package/dist/react/use-fps-graph.d.ts.map +1 -0
  55. package/dist/react/use-fps-graph.js +27 -21
  56. package/dist/react/use-fps-graph.js.map +1 -1
  57. package/dist/react/use-pane-button.d.ts +4 -4
  58. package/dist/react/use-pane-button.d.ts.map +1 -0
  59. package/dist/react/use-pane-button.js +35 -30
  60. package/dist/react/use-pane-button.js.map +1 -1
  61. package/dist/react/use-pane-folder.d.ts +5 -4
  62. package/dist/react/use-pane-folder.d.ts.map +1 -0
  63. package/dist/react/use-pane-folder.js +33 -20
  64. package/dist/react/use-pane-folder.js.map +1 -1
  65. package/dist/react/use-pane-input.d.ts +31 -30
  66. package/dist/react/use-pane-input.d.ts.map +1 -0
  67. package/dist/react/use-pane-input.js +46 -42
  68. package/dist/react/use-pane-input.js.map +1 -1
  69. package/dist/react/use-pane-radio-grid.d.ts +20 -20
  70. package/dist/react/use-pane-radio-grid.d.ts.map +1 -0
  71. package/dist/react/use-pane-radio-grid.js +72 -50
  72. package/dist/react/use-pane-radio-grid.js.map +1 -1
  73. package/dist/react/use-pane.d.ts +4 -4
  74. package/dist/react/use-pane.d.ts.map +1 -0
  75. package/dist/react/use-pane.js +52 -17
  76. package/dist/react/use-pane.js.map +1 -1
  77. package/dist/react.d.ts +10 -12
  78. package/dist/react.js +2 -12
  79. package/dist/registry-view.d.ts +8 -21
  80. package/dist/registry-view.d.ts.map +1 -0
  81. package/dist/registry-view.js +357 -338
  82. package/dist/registry-view.js.map +1 -1
  83. package/dist/relay.d.ts +16 -0
  84. package/dist/relay.d.ts.map +1 -0
  85. package/dist/relay.js +189 -0
  86. package/dist/relay.js.map +1 -0
  87. package/dist/remote.d.ts +10 -0
  88. package/dist/remote.d.ts.map +1 -0
  89. package/dist/remote.js +28 -0
  90. package/dist/remote.js.map +1 -0
  91. package/dist/stats-graph.d.ts +23 -31
  92. package/dist/stats-graph.d.ts.map +1 -0
  93. package/dist/stats-graph.js +323 -264
  94. package/dist/stats-graph.js.map +1 -1
  95. package/dist/stats-row.d.ts +8 -21
  96. package/dist/stats-row.d.ts.map +1 -0
  97. package/dist/stats-row.js +99 -101
  98. package/dist/stats-row.js.map +1 -1
  99. package/dist/theme.d.ts +3 -1
  100. package/dist/theme.d.ts.map +1 -0
  101. package/dist/theme.js +43 -54
  102. package/dist/theme.js.map +1 -1
  103. package/dist/vite-plugin.d.ts +7 -6
  104. package/dist/vite-plugin.d.ts.map +1 -0
  105. package/dist/vite-plugin.js +87 -78
  106. package/dist/vite-plugin.js.map +1 -1
  107. package/package.json +33 -29
  108. package/dist/buffers-modal.cjs +0 -491
  109. package/dist/buffers-modal.cjs.map +0 -1
  110. package/dist/buffers-modal.d.cts +0 -62
  111. package/dist/buffers-view.cjs +0 -269
  112. package/dist/buffers-view.cjs.map +0 -1
  113. package/dist/buffers-view.d.cts +0 -39
  114. package/dist/create-pane.cjs +0 -203
  115. package/dist/create-pane.cjs.map +0 -1
  116. package/dist/create-pane.d.cts +0 -66
  117. package/dist/devtools-client.cjs +0 -870
  118. package/dist/devtools-client.cjs.map +0 -1
  119. package/dist/devtools-client.d.cts +0 -362
  120. package/dist/index.cjs +0 -42
  121. package/dist/index.cjs.map +0 -1
  122. package/dist/index.d.cts +0 -8
  123. package/dist/index.js.map +0 -1
  124. package/dist/perf-trace.cjs +0 -103
  125. package/dist/perf-trace.cjs.map +0 -1
  126. package/dist/perf-trace.d.cts +0 -27
  127. package/dist/plugins.cjs +0 -44
  128. package/dist/plugins.cjs.map +0 -1
  129. package/dist/plugins.d.cts +0 -7
  130. package/dist/provider-switcher.cjs +0 -95
  131. package/dist/provider-switcher.cjs.map +0 -1
  132. package/dist/provider-switcher.d.cts +0 -18
  133. package/dist/react/devtools-provider.cjs +0 -59
  134. package/dist/react/devtools-provider.cjs.map +0 -1
  135. package/dist/react/devtools-provider.d.cts +0 -39
  136. package/dist/react/use-fps-graph.cjs +0 -49
  137. package/dist/react/use-fps-graph.cjs.map +0 -1
  138. package/dist/react/use-fps-graph.d.cts +0 -15
  139. package/dist/react/use-pane-button.cjs +0 -58
  140. package/dist/react/use-pane-button.cjs.map +0 -1
  141. package/dist/react/use-pane-button.d.cts +0 -10
  142. package/dist/react/use-pane-folder.cjs +0 -48
  143. package/dist/react/use-pane-folder.cjs.map +0 -1
  144. package/dist/react/use-pane-folder.d.cts +0 -15
  145. package/dist/react/use-pane-input.cjs +0 -70
  146. package/dist/react/use-pane-input.cjs.map +0 -1
  147. package/dist/react/use-pane-input.d.cts +0 -44
  148. package/dist/react/use-pane-radio-grid.cjs +0 -78
  149. package/dist/react/use-pane-radio-grid.cjs.map +0 -1
  150. package/dist/react/use-pane-radio-grid.d.cts +0 -35
  151. package/dist/react/use-pane.cjs +0 -45
  152. package/dist/react/use-pane.cjs.map +0 -1
  153. package/dist/react/use-pane.d.cts +0 -40
  154. package/dist/react.cjs +0 -50
  155. package/dist/react.cjs.map +0 -1
  156. package/dist/react.d.cts +0 -12
  157. package/dist/react.js.map +0 -1
  158. package/dist/registry-view.cjs +0 -371
  159. package/dist/registry-view.cjs.map +0 -1
  160. package/dist/registry-view.d.cts +0 -24
  161. package/dist/stats-graph.cjs +0 -297
  162. package/dist/stats-graph.cjs.map +0 -1
  163. package/dist/stats-graph.d.cts +0 -40
  164. package/dist/stats-row.cjs +0 -153
  165. package/dist/stats-row.cjs.map +0 -1
  166. package/dist/stats-row.d.cts +0 -24
  167. package/dist/theme.cjs +0 -260
  168. package/dist/theme.cjs.map +0 -1
  169. package/dist/theme.d.cts +0 -10
  170. package/dist/vite-plugin.cjs +0 -113
  171. package/dist/vite-plugin.cjs.map +0 -1
  172. package/dist/vite-plugin.d.cts +0 -9
package/dist/theme.js CHANGED
@@ -1,33 +1,25 @@
1
+ //#region src/theme.ts
2
+ /**
3
+ * Flatland theme — based on the Jehkoba32 retro palette.
4
+ *
5
+ * Uses project dark/neutral colors for backgrounds, retro-white/grey for text,
6
+ * and accent color only on control thumbs and slider grooves.
7
+ */
1
8
  const FLATLAND_THEME = {
2
- // Backgrounds — retro darks
3
- "--tp-base-background-color": "#00021c",
4
- // retro-midnight
5
- "--tp-container-background-color": "rgba(28, 40, 77, 0.4)",
6
- // retro-deep-purple @ 40%
7
- "--tp-input-background-color": "rgba(0, 2, 28, 0.6)",
8
- // retro-black @ 60%
9
- "--tp-monitor-background-color": "rgba(0, 2, 28, 0.4)",
10
- // retro-black @ 40%
11
- // Text — retro whites and greys
12
- "--tp-container-foreground-color": "#f0edd8",
13
- // retro-white
14
- "--tp-button-foreground-color": "#f0edd8",
15
- // retro-white
16
- "--tp-input-foreground-color": "#c8c5b4",
17
- // muted retro-white
18
- "--tp-label-foreground-color": "rgba(240, 237, 216, 0.55)",
19
- // retro-white @ 55%
20
- "--tp-monitor-foreground-color": "#c8c5b4",
21
- // muted retro-white
22
- // Buttons — retro-deep-purple
23
- "--tp-button-background-color": "#1c284d",
24
- // retro-deep-purple
25
- // Accent — slider grooves & separators
26
- "--tp-groove-foreground-color": "rgba(240, 237, 216, 0.12)",
27
- // muted separator/groove
28
- // Typography
29
- "--tp-base-font-family": "monospace"
9
+ "--tp-base-background-color": "#00021c",
10
+ "--tp-container-background-color": "rgba(28, 40, 77, 0.4)",
11
+ "--tp-input-background-color": "rgba(0, 2, 28, 0.6)",
12
+ "--tp-monitor-background-color": "rgba(0, 2, 28, 0.4)",
13
+ "--tp-container-foreground-color": "#f0edd8",
14
+ "--tp-button-foreground-color": "#f0edd8",
15
+ "--tp-input-foreground-color": "#c8c5b4",
16
+ "--tp-label-foreground-color": "rgba(240, 237, 216, 0.55)",
17
+ "--tp-monitor-foreground-color": "#c8c5b4",
18
+ "--tp-button-background-color": "#1c284d",
19
+ "--tp-groove-foreground-color": "rgba(240, 237, 216, 0.12)",
20
+ "--tp-base-font-family": "monospace"
30
21
  };
22
+ /** Accent CSS — colorizes slider thumb and number spinner drag handle */
31
23
  const ACCENT_CSS = `
32
24
  /* Slider thumb */
33
25
  .tp-sldv_k::after { background-color: #d94c87 !important; }
@@ -52,13 +44,13 @@ const ACCENT_CSS = `
52
44
  .tp-radv_i:hover + .tp-radv_b { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }
53
45
  .tp-radv_i:checked + .tp-radv_b { background-color: #1c284d !important; color: #d94c87 !important; }
54
46
  .tp-radv_i:active + .tp-radv_b { background-color: #343473 !important; color: #f0edd8 !important; }
55
- /* Checkbox \u2014 default background blends with the container, so bump to
47
+ /* Checkbox default background blends with the container, so bump to
56
48
  the same surface as the select/button controls for a visible hit
57
49
  target, and accent the check stroke on :checked. Markup:
58
50
  <input.tp-ckbv_i> + <div.tp-ckbv_w><svg><path/></svg></div>
59
51
 
60
- Tweakpane's hidden input ships at browser-default size (~13\xD713) at
61
- top-left of the label, relying on <label>\u2192<input> click forwarding
52
+ Tweakpane's hidden input ships at browser-default size (~13×13) at
53
+ top-left of the label, relying on <label>→<input> click forwarding
62
54
  to toggle from clicks on the visible box. That forwarding is flaky
63
55
  under some pointer-events + z-index combinations (reports: clicks
64
56
  sometimes register, sometimes don't). Stretching the input to cover
@@ -79,7 +71,7 @@ const ACCENT_CSS = `
79
71
  .tp-ckbv_i:active + .tp-ckbv_w { background-color: #343473 !important; }
80
72
  .tp-ckbv_i:checked + .tp-ckbv_w svg path { stroke: #d94c87 !important; }
81
73
 
82
- /* Dimmable pane \u2014 slightly translucent when idle, opaque on hover or when pinned.
74
+ /* Dimmable pane slightly translucent when idle, opaque on hover or when pinned.
83
75
  Hover-promotion is gated on devices that actually have a pointer (desktop),
84
76
  so on touch devices the pin toggle is the only way to flip opacity. */
85
77
  .tp-flatland-dimmable { opacity: 0.8; transition: opacity 750ms ease; }
@@ -129,7 +121,7 @@ const ACCENT_CSS = `
129
121
  display: flex;
130
122
  align-items: center;
131
123
  justify-content: center;
132
- /* Match the original tweakpane fold caret and folder-header glyphs \u2014
124
+ /* Match the original tweakpane fold caret and folder-header glyphs
133
125
  * the muted foreground token pane headers use throughout. */
134
126
  color: var(--tp-label-foreground-color);
135
127
  cursor: pointer;
@@ -138,12 +130,12 @@ const ACCENT_CSS = `
138
130
  user-select: none;
139
131
  }
140
132
  /*
141
- * Glyph exactly replicates tweakpane's native fold marker \u2014 a 6\xD76
133
+ * Glyph exactly replicates tweakpane's native fold marker a 6×6
142
134
  * square with a horizontal linear-gradient that draws two vertical
143
135
  * stripes (screw-head look). Rotating gives the three states:
144
- * full \u2192 0\xB0 (vertical stripes, ||) \u2014 matches tweakpane's expanded
145
- * minimal \u2192 45\xB0 (diagonal, like a flat-head screw)
146
- * collapsed \u2192 90\xB0 (horizontal stripes, =) \u2014 matches tweakpane's collapsed
136
+ * full 0° (vertical stripes, ||) matches tweakpane's expanded
137
+ * minimal 45° (diagonal, like a flat-head screw)
138
+ * collapsed 90° (horizontal stripes, =) matches tweakpane's collapsed
147
139
  */
148
140
  .tp-flatland-mode-glyph {
149
141
  display: block;
@@ -159,7 +151,7 @@ const ACCENT_CSS = `
159
151
  var(--cnt-fg, currentColor) 4px
160
152
  );
161
153
  opacity: 0.5;
162
- /* 0.2s ease-in-out \u2014 the exact transition tweakpane applies to its
154
+ /* 0.2s ease-in-out the exact transition tweakpane applies to its
163
155
  * own fold marker. */
164
156
  transition: transform 0.2s ease-in-out;
165
157
  }
@@ -171,7 +163,7 @@ const ACCENT_CSS = `
171
163
  * Minimal mode: keep only blades tagged with .tp-flatland-minimal-keep
172
164
  * (stats graph + stats row). Non-keep blades animate max-height to 0
173
165
  * and fade out so the whole pane visibly shrinks, matching tweakpane
174
- * native fold feel. Values and bindings stay intact \u2014 DOM is just
166
+ * native fold feel. Values and bindings stay intact DOM is just
175
167
  * clipped.
176
168
  *
177
169
  * max-height uses a generous ceiling instead of a measured value so we
@@ -183,7 +175,7 @@ const ACCENT_CSS = `
183
175
  * .tp-rotv_c / .tp-fldv_c use
184
176
  * height .2s ease-in-out, opacity .2s linear, padding .2s ease-in-out
185
177
  * and on expand, opacity has a 0.2s delay so height finishes first
186
- * then opacity fades in. The collapse direction has no delay \u2014 both
178
+ * then opacity fades in. The collapse direction has no delay both
187
179
  * animate together.
188
180
  *
189
181
  * We use max-height in place of height because content height isn't
@@ -208,7 +200,7 @@ const ACCENT_CSS = `
208
200
  padding-top: 0 !important;
209
201
  padding-bottom: 0 !important;
210
202
  pointer-events: none;
211
- /* On collapse: no delay on opacity \u2014 both animate together,
203
+ /* On collapse: no delay on opacity both animate together,
212
204
  * matching tweakpane's non-expanded transition shape. */
213
205
  transition:
214
206
  max-height 0.2s ease-in-out,
@@ -218,18 +210,15 @@ const ACCENT_CSS = `
218
210
  }
219
211
  `;
220
212
  function applyTheme(element, theme = FLATLAND_THEME) {
221
- for (const [key, value] of Object.entries(theme)) {
222
- element.style.setProperty(key, value);
223
- }
224
- if (!element.querySelector("style[data-flatland]")) {
225
- const style = document.createElement("style");
226
- style.setAttribute("data-flatland", "");
227
- style.textContent = ACCENT_CSS;
228
- element.appendChild(style);
229
- }
213
+ for (const [key, value] of Object.entries(theme)) element.style.setProperty(key, value);
214
+ if (!element.querySelector("style[data-flatland]")) {
215
+ const style = document.createElement("style");
216
+ style.setAttribute("data-flatland", "");
217
+ style.textContent = ACCENT_CSS;
218
+ element.appendChild(style);
219
+ }
230
220
  }
231
- export {
232
- FLATLAND_THEME,
233
- applyTheme
234
- };
221
+ //#endregion
222
+ export { FLATLAND_THEME, applyTheme };
223
+
235
224
  //# sourceMappingURL=theme.js.map
package/dist/theme.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/theme.ts"],"sourcesContent":["/**\n * Flatland theme — based on the Jehkoba32 retro palette.\n *\n * Uses project dark/neutral colors for backgrounds, retro-white/grey for text,\n * and accent color only on control thumbs and slider grooves.\n */\nexport const FLATLAND_THEME: Record<string, string> = {\n // Backgrounds — retro darks\n '--tp-base-background-color': '#00021c', // retro-midnight\n '--tp-container-background-color': 'rgba(28, 40, 77, 0.4)', // retro-deep-purple @ 40%\n '--tp-input-background-color': 'rgba(0, 2, 28, 0.6)', // retro-black @ 60%\n '--tp-monitor-background-color': 'rgba(0, 2, 28, 0.4)', // retro-black @ 40%\n\n // Text — retro whites and greys\n '--tp-container-foreground-color': '#f0edd8', // retro-white\n '--tp-button-foreground-color': '#f0edd8', // retro-white\n '--tp-input-foreground-color': '#c8c5b4', // muted retro-white\n '--tp-label-foreground-color': 'rgba(240, 237, 216, 0.55)', // retro-white @ 55%\n '--tp-monitor-foreground-color': '#c8c5b4', // muted retro-white\n\n // Buttons — retro-deep-purple\n '--tp-button-background-color': '#1c284d', // retro-deep-purple\n\n // Accent — slider grooves & separators\n '--tp-groove-foreground-color': 'rgba(240, 237, 216, 0.12)', // muted separator/groove\n\n // Typography\n '--tp-base-font-family': 'monospace',\n}\n\n/** Accent CSS — colorizes slider thumb and number spinner drag handle */\nconst ACCENT_CSS = `\n/* Slider thumb */\n.tp-sldv_k::after { background-color: #d94c87 !important; }\n.tp-sldv_t:hover .tp-sldv_k::after { background-color: #e0609a !important; }\n.tp-sldv_t:active .tp-sldv_k::after { background-color: #a6216e !important; }\n/* Slider track (filled portion) */\n.tp-sldv_k::before { background-color: rgba(240, 237, 216, 0.25) !important; }\n/* Number spinner drag handle */\n.tp-txtv_k::before { background-color: #d94c87 !important; }\n/* Select/dropdown */\n.tp-lstv_s { background-color: rgba(28, 40, 77, 0.6) !important; color: rgba(240, 237, 216, 0.5) !important; }\n.tp-lstv_s:hover { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-lstv_s:focus { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-lstv_s:active { background-color: #343473 !important; color: #d94c87 !important; }\n.tp-lstv_m { color: rgba(240, 237, 216, 0.5) !important; }\n/* Buttons */\n.tp-btnv_b { background-color: rgba(28, 40, 77, 0.6) !important; color: rgba(240, 237, 216, 0.5) !important; }\n.tp-btnv_b:hover { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-btnv_b:active { background-color: #343473 !important; color: #d94c87 !important; }\n/* Radio grid buttons */\n.tp-radv_b { background-color: rgba(28, 40, 77, 0.6) !important; color: rgba(240, 237, 216, 0.5) !important; }\n.tp-radv_i:hover + .tp-radv_b { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-radv_i:checked + .tp-radv_b { background-color: #1c284d !important; color: #d94c87 !important; }\n.tp-radv_i:active + .tp-radv_b { background-color: #343473 !important; color: #f0edd8 !important; }\n/* Checkbox — default background blends with the container, so bump to\n the same surface as the select/button controls for a visible hit\n target, and accent the check stroke on :checked. Markup:\n <input.tp-ckbv_i> + <div.tp-ckbv_w><svg><path/></svg></div>\n\n Tweakpane's hidden input ships at browser-default size (~13×13) at\n top-left of the label, relying on <label>→<input> click forwarding\n to toggle from clicks on the visible box. That forwarding is flaky\n under some pointer-events + z-index combinations (reports: clicks\n sometimes register, sometimes don't). Stretching the input to cover\n the entire visible box puts the hit target directly on the pointer,\n no label forwarding required. */\n.tp-ckbv_i {\n /* Absolute positioning + zero opacity is Tweakpane's default; we\n just add explicit size + cursor so the click area matches the\n visible affordance exactly. */\n width: var(--cnt-usz) !important;\n height: var(--cnt-usz) !important;\n margin: 0 !important;\n cursor: pointer !important;\n}\n.tp-ckbv_w { background-color: rgba(28, 40, 77, 0.6) !important; }\n.tp-ckbv_i:hover + .tp-ckbv_w { background-color: rgba(28, 40, 77, 0.9) !important; }\n.tp-ckbv_i:focus + .tp-ckbv_w { background-color: rgba(28, 40, 77, 0.9) !important; }\n.tp-ckbv_i:active + .tp-ckbv_w { background-color: #343473 !important; }\n.tp-ckbv_i:checked + .tp-ckbv_w svg path { stroke: #d94c87 !important; }\n\n/* Dimmable pane — slightly translucent when idle, opaque on hover or when pinned.\n Hover-promotion is gated on devices that actually have a pointer (desktop),\n so on touch devices the pin toggle is the only way to flip opacity. */\n.tp-flatland-dimmable { opacity: 0.8; transition: opacity 750ms ease; }\n.tp-flatland-dimmable.tp-flatland-pinned { opacity: 1; }\n@media (hover: hover) {\n .tp-flatland-dimmable:hover { opacity: 1; }\n}\n\n/* Pin in the pane header (left side, mirrors the collapse caret on the right) */\n.tp-flatland-pin {\n position: absolute;\n left: var(--cnt-hp, 4px);\n top: 0;\n bottom: 0;\n margin: auto;\n width: var(--cnt-usz, 20px);\n height: var(--cnt-usz, 20px);\n display: flex;\n align-items: center;\n justify-content: center;\n color: rgba(240, 237, 216, 0.45);\n cursor: pointer;\n border-radius: 2px;\n transition: color 150ms, background-color 150ms;\n}\n.tp-flatland-pin:hover { color: #d94c87; background: transparent; }\n.tp-flatland-pin svg { display: block; }\n.tp-flatland-pin svg circle { fill: none; stroke: currentColor; stroke-width: 1.6; }\n.tp-flatland-pinned .tp-flatland-pin svg circle { fill: currentColor; }\n\n/*\n * Three-mode cycle toggle in the header (replaces Tweakpane's built-in\n * fold caret). We hide the native caret via the .tp-rotv_m marker\n * class and render our own button that cycles full - minimal -\n * collapsed - full. The data-mode attribute drives icon styling.\n */\n.tp-rotv_m { display: none !important; }\n.tp-flatland-mode {\n position: absolute;\n right: var(--cnt-hp, 4px);\n top: 0;\n bottom: 0;\n margin: auto;\n min-width: var(--cnt-usz, 20px);\n height: var(--cnt-usz, 20px);\n padding: 0 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n /* Match the original tweakpane fold caret and folder-header glyphs —\n * the muted foreground token pane headers use throughout. */\n color: var(--tp-label-foreground-color);\n cursor: pointer;\n font-size: 11px;\n line-height: 1;\n user-select: none;\n}\n/*\n * Glyph exactly replicates tweakpane's native fold marker — a 6×6\n * square with a horizontal linear-gradient that draws two vertical\n * stripes (screw-head look). Rotating gives the three states:\n * full → 0° (vertical stripes, ||) — matches tweakpane's expanded\n * minimal → 45° (diagonal, like a flat-head screw)\n * collapsed → 90° (horizontal stripes, =) — matches tweakpane's collapsed\n */\n.tp-flatland-mode-glyph {\n display: block;\n width: 6px;\n height: 6px;\n border-radius: 2px;\n background: linear-gradient(\n to left,\n var(--cnt-fg, currentColor),\n var(--cnt-fg, currentColor) 2px,\n transparent 2px,\n transparent 4px,\n var(--cnt-fg, currentColor) 4px\n );\n opacity: 0.5;\n /* 0.2s ease-in-out — the exact transition tweakpane applies to its\n * own fold marker. */\n transition: transform 0.2s ease-in-out;\n}\n.tp-flatland-mode[data-mode=\"full\"] .tp-flatland-mode-glyph { transform: rotate(0deg); }\n.tp-flatland-mode[data-mode=\"minimal\"] .tp-flatland-mode-glyph { transform: rotate(45deg); }\n.tp-flatland-mode[data-mode=\"collapsed\"] .tp-flatland-mode-glyph { transform: rotate(90deg); }\n\n/*\n * Minimal mode: keep only blades tagged with .tp-flatland-minimal-keep\n * (stats graph + stats row). Non-keep blades animate max-height to 0\n * and fade out so the whole pane visibly shrinks, matching tweakpane\n * native fold feel. Values and bindings stay intact — DOM is just\n * clipped.\n *\n * max-height uses a generous ceiling instead of a measured value so we\n * can stay declarative; the transition duration matches the native\n * pane fold for continuity.\n */\n/*\n * Animation timings + easings mirror tweakpane's own fold exactly:\n * .tp-rotv_c / .tp-fldv_c use\n * height .2s ease-in-out, opacity .2s linear, padding .2s ease-in-out\n * and on expand, opacity has a 0.2s delay so height finishes first\n * then opacity fades in. The collapse direction has no delay — both\n * animate together.\n *\n * We use max-height in place of height because content height isn't\n * known at author time; with a generous ceiling the visual is\n * indistinguishable from native height tweens.\n */\n.tp-rotv_c > *:not(.tp-flatland-minimal-keep) {\n max-height: 1200px;\n opacity: 1;\n overflow: hidden;\n transition:\n max-height 0.2s ease-in-out,\n opacity 0.2s linear 0.2s,\n margin 0.2s ease-in-out,\n padding 0.2s ease-in-out;\n}\n.tp-flatland-minimal .tp-rotv_c > *:not(.tp-flatland-minimal-keep) {\n max-height: 0;\n opacity: 0;\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n pointer-events: none;\n /* On collapse: no delay on opacity — both animate together,\n * matching tweakpane's non-expanded transition shape. */\n transition:\n max-height 0.2s ease-in-out,\n opacity 0.2s linear,\n margin 0.2s ease-in-out,\n padding 0.2s ease-in-out;\n}\n`\n\nexport function applyTheme(\n element: HTMLElement,\n theme: Record<string, string> = FLATLAND_THEME,\n): void {\n for (const [key, value] of Object.entries(theme)) {\n element.style.setProperty(key, value)\n }\n\n // Inject accent styles once\n if (!element.querySelector('style[data-flatland]')) {\n const style = document.createElement('style')\n style.setAttribute('data-flatland', '')\n style.textContent = ACCENT_CSS\n element.appendChild(style)\n }\n}\n"],"mappings":"AAMO,MAAM,iBAAyC;AAAA;AAAA,EAEpD,8BAA8B;AAAA;AAAA,EAC9B,mCAAmC;AAAA;AAAA,EACnC,+BAA+B;AAAA;AAAA,EAC/B,iCAAiC;AAAA;AAAA;AAAA,EAGjC,mCAAmC;AAAA;AAAA,EACnC,gCAAgC;AAAA;AAAA,EAChC,+BAA+B;AAAA;AAAA,EAC/B,+BAA+B;AAAA;AAAA,EAC/B,iCAAiC;AAAA;AAAA;AAAA,EAGjC,gCAAgC;AAAA;AAAA;AAAA,EAGhC,gCAAgC;AAAA;AAAA;AAAA,EAGhC,yBAAyB;AAC3B;AAGA,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8LZ,SAAS,WACd,SACA,QAAgC,gBAC1B;AACN,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,YAAQ,MAAM,YAAY,KAAK,KAAK;AAAA,EACtC;AAGA,MAAI,CAAC,QAAQ,cAAc,sBAAsB,GAAG;AAClD,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,aAAa,iBAAiB,EAAE;AACtC,UAAM,cAAc;AACpB,YAAQ,YAAY,KAAK;AAAA,EAC3B;AACF;","names":[]}
1
+ {"version":3,"file":"theme.js","names":[],"sources":["../src/theme.ts"],"sourcesContent":["/**\n * Flatland theme — based on the Jehkoba32 retro palette.\n *\n * Uses project dark/neutral colors for backgrounds, retro-white/grey for text,\n * and accent color only on control thumbs and slider grooves.\n */\nexport const FLATLAND_THEME: Record<string, string> = {\n // Backgrounds — retro darks\n '--tp-base-background-color': '#00021c', // retro-midnight\n '--tp-container-background-color': 'rgba(28, 40, 77, 0.4)', // retro-deep-purple @ 40%\n '--tp-input-background-color': 'rgba(0, 2, 28, 0.6)', // retro-black @ 60%\n '--tp-monitor-background-color': 'rgba(0, 2, 28, 0.4)', // retro-black @ 40%\n\n // Text — retro whites and greys\n '--tp-container-foreground-color': '#f0edd8', // retro-white\n '--tp-button-foreground-color': '#f0edd8', // retro-white\n '--tp-input-foreground-color': '#c8c5b4', // muted retro-white\n '--tp-label-foreground-color': 'rgba(240, 237, 216, 0.55)', // retro-white @ 55%\n '--tp-monitor-foreground-color': '#c8c5b4', // muted retro-white\n\n // Buttons — retro-deep-purple\n '--tp-button-background-color': '#1c284d', // retro-deep-purple\n\n // Accent — slider grooves & separators\n '--tp-groove-foreground-color': 'rgba(240, 237, 216, 0.12)', // muted separator/groove\n\n // Typography\n '--tp-base-font-family': 'monospace',\n}\n\n/** Accent CSS — colorizes slider thumb and number spinner drag handle */\nconst ACCENT_CSS = `\n/* Slider thumb */\n.tp-sldv_k::after { background-color: #d94c87 !important; }\n.tp-sldv_t:hover .tp-sldv_k::after { background-color: #e0609a !important; }\n.tp-sldv_t:active .tp-sldv_k::after { background-color: #a6216e !important; }\n/* Slider track (filled portion) */\n.tp-sldv_k::before { background-color: rgba(240, 237, 216, 0.25) !important; }\n/* Number spinner drag handle */\n.tp-txtv_k::before { background-color: #d94c87 !important; }\n/* Select/dropdown */\n.tp-lstv_s { background-color: rgba(28, 40, 77, 0.6) !important; color: rgba(240, 237, 216, 0.5) !important; }\n.tp-lstv_s:hover { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-lstv_s:focus { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-lstv_s:active { background-color: #343473 !important; color: #d94c87 !important; }\n.tp-lstv_m { color: rgba(240, 237, 216, 0.5) !important; }\n/* Buttons */\n.tp-btnv_b { background-color: rgba(28, 40, 77, 0.6) !important; color: rgba(240, 237, 216, 0.5) !important; }\n.tp-btnv_b:hover { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-btnv_b:active { background-color: #343473 !important; color: #d94c87 !important; }\n/* Radio grid buttons */\n.tp-radv_b { background-color: rgba(28, 40, 77, 0.6) !important; color: rgba(240, 237, 216, 0.5) !important; }\n.tp-radv_i:hover + .tp-radv_b { background-color: rgba(28, 40, 77, 0.9) !important; color: #f0edd8 !important; }\n.tp-radv_i:checked + .tp-radv_b { background-color: #1c284d !important; color: #d94c87 !important; }\n.tp-radv_i:active + .tp-radv_b { background-color: #343473 !important; color: #f0edd8 !important; }\n/* Checkbox — default background blends with the container, so bump to\n the same surface as the select/button controls for a visible hit\n target, and accent the check stroke on :checked. Markup:\n <input.tp-ckbv_i> + <div.tp-ckbv_w><svg><path/></svg></div>\n\n Tweakpane's hidden input ships at browser-default size (~13×13) at\n top-left of the label, relying on <label>→<input> click forwarding\n to toggle from clicks on the visible box. That forwarding is flaky\n under some pointer-events + z-index combinations (reports: clicks\n sometimes register, sometimes don't). Stretching the input to cover\n the entire visible box puts the hit target directly on the pointer,\n no label forwarding required. */\n.tp-ckbv_i {\n /* Absolute positioning + zero opacity is Tweakpane's default; we\n just add explicit size + cursor so the click area matches the\n visible affordance exactly. */\n width: var(--cnt-usz) !important;\n height: var(--cnt-usz) !important;\n margin: 0 !important;\n cursor: pointer !important;\n}\n.tp-ckbv_w { background-color: rgba(28, 40, 77, 0.6) !important; }\n.tp-ckbv_i:hover + .tp-ckbv_w { background-color: rgba(28, 40, 77, 0.9) !important; }\n.tp-ckbv_i:focus + .tp-ckbv_w { background-color: rgba(28, 40, 77, 0.9) !important; }\n.tp-ckbv_i:active + .tp-ckbv_w { background-color: #343473 !important; }\n.tp-ckbv_i:checked + .tp-ckbv_w svg path { stroke: #d94c87 !important; }\n\n/* Dimmable pane — slightly translucent when idle, opaque on hover or when pinned.\n Hover-promotion is gated on devices that actually have a pointer (desktop),\n so on touch devices the pin toggle is the only way to flip opacity. */\n.tp-flatland-dimmable { opacity: 0.8; transition: opacity 750ms ease; }\n.tp-flatland-dimmable.tp-flatland-pinned { opacity: 1; }\n@media (hover: hover) {\n .tp-flatland-dimmable:hover { opacity: 1; }\n}\n\n/* Pin in the pane header (left side, mirrors the collapse caret on the right) */\n.tp-flatland-pin {\n position: absolute;\n left: var(--cnt-hp, 4px);\n top: 0;\n bottom: 0;\n margin: auto;\n width: var(--cnt-usz, 20px);\n height: var(--cnt-usz, 20px);\n display: flex;\n align-items: center;\n justify-content: center;\n color: rgba(240, 237, 216, 0.45);\n cursor: pointer;\n border-radius: 2px;\n transition: color 150ms, background-color 150ms;\n}\n.tp-flatland-pin:hover { color: #d94c87; background: transparent; }\n.tp-flatland-pin svg { display: block; }\n.tp-flatland-pin svg circle { fill: none; stroke: currentColor; stroke-width: 1.6; }\n.tp-flatland-pinned .tp-flatland-pin svg circle { fill: currentColor; }\n\n/*\n * Three-mode cycle toggle in the header (replaces Tweakpane's built-in\n * fold caret). We hide the native caret via the .tp-rotv_m marker\n * class and render our own button that cycles full - minimal -\n * collapsed - full. The data-mode attribute drives icon styling.\n */\n.tp-rotv_m { display: none !important; }\n.tp-flatland-mode {\n position: absolute;\n right: var(--cnt-hp, 4px);\n top: 0;\n bottom: 0;\n margin: auto;\n min-width: var(--cnt-usz, 20px);\n height: var(--cnt-usz, 20px);\n padding: 0 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n /* Match the original tweakpane fold caret and folder-header glyphs —\n * the muted foreground token pane headers use throughout. */\n color: var(--tp-label-foreground-color);\n cursor: pointer;\n font-size: 11px;\n line-height: 1;\n user-select: none;\n}\n/*\n * Glyph exactly replicates tweakpane's native fold marker — a 6×6\n * square with a horizontal linear-gradient that draws two vertical\n * stripes (screw-head look). Rotating gives the three states:\n * full → 0° (vertical stripes, ||) — matches tweakpane's expanded\n * minimal → 45° (diagonal, like a flat-head screw)\n * collapsed → 90° (horizontal stripes, =) — matches tweakpane's collapsed\n */\n.tp-flatland-mode-glyph {\n display: block;\n width: 6px;\n height: 6px;\n border-radius: 2px;\n background: linear-gradient(\n to left,\n var(--cnt-fg, currentColor),\n var(--cnt-fg, currentColor) 2px,\n transparent 2px,\n transparent 4px,\n var(--cnt-fg, currentColor) 4px\n );\n opacity: 0.5;\n /* 0.2s ease-in-out — the exact transition tweakpane applies to its\n * own fold marker. */\n transition: transform 0.2s ease-in-out;\n}\n.tp-flatland-mode[data-mode=\"full\"] .tp-flatland-mode-glyph { transform: rotate(0deg); }\n.tp-flatland-mode[data-mode=\"minimal\"] .tp-flatland-mode-glyph { transform: rotate(45deg); }\n.tp-flatland-mode[data-mode=\"collapsed\"] .tp-flatland-mode-glyph { transform: rotate(90deg); }\n\n/*\n * Minimal mode: keep only blades tagged with .tp-flatland-minimal-keep\n * (stats graph + stats row). Non-keep blades animate max-height to 0\n * and fade out so the whole pane visibly shrinks, matching tweakpane\n * native fold feel. Values and bindings stay intact — DOM is just\n * clipped.\n *\n * max-height uses a generous ceiling instead of a measured value so we\n * can stay declarative; the transition duration matches the native\n * pane fold for continuity.\n */\n/*\n * Animation timings + easings mirror tweakpane's own fold exactly:\n * .tp-rotv_c / .tp-fldv_c use\n * height .2s ease-in-out, opacity .2s linear, padding .2s ease-in-out\n * and on expand, opacity has a 0.2s delay so height finishes first\n * then opacity fades in. The collapse direction has no delay — both\n * animate together.\n *\n * We use max-height in place of height because content height isn't\n * known at author time; with a generous ceiling the visual is\n * indistinguishable from native height tweens.\n */\n.tp-rotv_c > *:not(.tp-flatland-minimal-keep) {\n max-height: 1200px;\n opacity: 1;\n overflow: hidden;\n transition:\n max-height 0.2s ease-in-out,\n opacity 0.2s linear 0.2s,\n margin 0.2s ease-in-out,\n padding 0.2s ease-in-out;\n}\n.tp-flatland-minimal .tp-rotv_c > *:not(.tp-flatland-minimal-keep) {\n max-height: 0;\n opacity: 0;\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n pointer-events: none;\n /* On collapse: no delay on opacity — both animate together,\n * matching tweakpane's non-expanded transition shape. */\n transition:\n max-height 0.2s ease-in-out,\n opacity 0.2s linear,\n margin 0.2s ease-in-out,\n padding 0.2s ease-in-out;\n}\n`\n\nexport function applyTheme(element: HTMLElement, theme: Record<string, string> = FLATLAND_THEME): void {\n for (const [key, value] of Object.entries(theme)) {\n element.style.setProperty(key, value)\n }\n\n // Inject accent styles once\n if (!element.querySelector('style[data-flatland]')) {\n const style = document.createElement('style')\n style.setAttribute('data-flatland', '')\n style.textContent = ACCENT_CSS\n element.appendChild(style)\n }\n}\n"],"mappings":";;;;;;;AAMA,MAAa,iBAAyC;CAEpD,8BAA8B;CAC9B,mCAAmC;CACnC,+BAA+B;CAC/B,iCAAiC;CAGjC,mCAAmC;CACnC,gCAAgC;CAChC,+BAA+B;CAC/B,+BAA+B;CAC/B,iCAAiC;CAGjC,gCAAgC;CAGhC,gCAAgC;CAGhC,yBAAyB;AAC3B;;AAGA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8LnB,SAAgB,WAAW,SAAsB,QAAgC,gBAAsB;CACrG,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,QAAQ,MAAM,YAAY,KAAK,KAAK;CAItC,IAAI,CAAC,QAAQ,cAAc,sBAAsB,GAAG;EAClD,MAAM,QAAQ,SAAS,cAAc,OAAO;EAC5C,MAAM,aAAa,iBAAiB,EAAE;EACtC,MAAM,cAAc;EACpB,QAAQ,YAAY,KAAK;CAC3B;AACF"}
@@ -1,9 +1,10 @@
1
- import { Plugin } from 'vite';
2
-
1
+ import { Plugin } from "vite";
2
+ //#region src/vite-plugin.d.ts
3
3
  interface ThreeFlatlandDevtoolsOptions {
4
- /** URL path the dashboard is served under. Default: `/.devtools`. */
5
- path?: string;
4
+ /** URL path the dashboard is served under. Default: `/.devtools`. */
5
+ path?: string;
6
6
  }
7
7
  declare function threeFlatlandDevtools(options?: ThreeFlatlandDevtoolsOptions): Plugin;
8
-
9
- export { type ThreeFlatlandDevtoolsOptions, threeFlatlandDevtools as default, threeFlatlandDevtools };
8
+ //#endregion
9
+ export { ThreeFlatlandDevtoolsOptions, threeFlatlandDevtools as default, threeFlatlandDevtools };
10
+ //# sourceMappingURL=vite-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.d.ts","names":[],"sources":["../src/vite-plugin.ts"],"mappings":";;UAiCiB;;EAEf;;iBAoBc,sBAAsB,UAAS,+BAAoC"}
@@ -2,87 +2,96 @@ import { existsSync } from "node:fs";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { dirname, resolve } from "node:path";
5
+ //#region src/vite-plugin.ts
6
+ /**
7
+ * Vite plugin that serves the standalone devtools dashboard alongside the
8
+ * user's app. Mounts a dev-only middleware at a configurable path (default
9
+ * `/.devtools`).
10
+ *
11
+ * The dashboard source lives inside this package
12
+ * (`packages/devtools/src/dashboard/`), not inside the consumer's project.
13
+ * The plugin:
14
+ * 1. Whitelists the dashboard directory via `server.fs.allow` so Vite
15
+ * is willing to read its files across the workspace boundary.
16
+ * 2. Serves `index.html` at the mount path, rewritten so the entry
17
+ * script loads via `/@fs/<abs>` — Vite then transforms it with full
18
+ * HMR.
19
+ * 3. Aliases the vendored Preact files so `import from 'preact'`
20
+ * resolves locally — no runtime dep on Preact leaks into the
21
+ * consumer's `node_modules`.
22
+ *
23
+ * Access the dashboard at the Vite dev server's origin directly, e.g.
24
+ * `http://localhost:5174/.devtools`. If the host project sits behind a
25
+ * microfrontend proxy, point the browser at the Vite port — the
26
+ * dashboard's transitive requests (`/@fs/`, `/@vite/client`, pre-bundled
27
+ * `node_modules/.vite/`) are not namespaced and expect to land on the
28
+ * same origin that served the HTML.
29
+ *
30
+ * Dev-only; the plugin is inert in production builds.
31
+ */
5
32
  const DEFAULT_PATH = "/.devtools";
6
33
  function resolveDashboardRoot() {
7
- const here = dirname(fileURLToPath(import.meta.url));
8
- const siblingSrc = resolve(here, "../src/dashboard");
9
- if (existsSync(siblingSrc)) return siblingSrc;
10
- return resolve(here, "dashboard");
34
+ const here = dirname(fileURLToPath(import.meta.url));
35
+ const siblingSrc = resolve(here, "../src/dashboard");
36
+ if (existsSync(siblingSrc)) return siblingSrc;
37
+ return resolve(here, "dashboard");
11
38
  }
12
39
  function threeFlatlandDevtools(options = {}) {
13
- const mountPath = options.path ?? DEFAULT_PATH;
14
- const dashboardRoot = resolveDashboardRoot();
15
- const vendorRoot = resolve(dashboardRoot, "vendor");
16
- return {
17
- name: "three-flatland-devtools",
18
- apply: "serve",
19
- config() {
20
- return {
21
- resolve: {
22
- // Order matters — Vite/rollup-plugin-alias matches left-to-right
23
- // by string prefix, so the broad `preact` entry must come last
24
- // or it swallows `preact/jsx-*` and `preact/hooks`.
25
- alias: [
26
- {
27
- find: "preact/jsx-runtime",
28
- replacement: resolve(vendorRoot, "jsx-runtime.js")
29
- },
30
- {
31
- // esbuild dev mode emits `import { jsxDEV } from 'preact/jsx-dev-runtime'`;
32
- // the same shim exports `jsxDEV`.
33
- find: "preact/jsx-dev-runtime",
34
- replacement: resolve(vendorRoot, "jsx-runtime.js")
35
- },
36
- {
37
- find: "preact/hooks",
38
- replacement: resolve(vendorRoot, "hooks.module.js")
39
- },
40
- {
41
- find: /^preact$/,
42
- replacement: resolve(vendorRoot, "preact.module.js")
43
- }
44
- ]
45
- }
46
- };
47
- },
48
- configResolved(config) {
49
- if (!config.server.fs.allow.includes(dashboardRoot)) {
50
- config.server.fs.allow.push(dashboardRoot);
51
- }
52
- },
53
- configureServer(server) {
54
- server.middlewares.use((req, res, next) => {
55
- void (async () => {
56
- if (req.url === void 0) return next();
57
- const url = req.url.split("?")[0] ?? "";
58
- if (url !== mountPath && url !== `${mountPath}/`) return next();
59
- try {
60
- const indexPath = resolve(dashboardRoot, "index.html");
61
- let html = await readFile(indexPath, "utf-8");
62
- const entryAbs = resolve(dashboardRoot, "index.tsx");
63
- html = html.replace("./index.tsx", `/@fs${entryAbs}`);
64
- html = await server.transformIndexHtml(req.url, html, req.originalUrl);
65
- res.statusCode = 200;
66
- res.setHeader("Content-Type", "text/html; charset=utf-8");
67
- res.end(html);
68
- } catch (err) {
69
- next(err);
70
- }
71
- })();
72
- });
73
- const logger = server.config.logger;
74
- const port = server.config.server.port ?? 5173;
75
- logger.info(
76
- `
77
- \x1B[32m\u279C\x1B[0m three-flatland devtools: \x1B[36mhttp://localhost:${port}${mountPath}\x1B[0m
78
- `
79
- );
80
- }
81
- };
40
+ const mountPath = options.path ?? DEFAULT_PATH;
41
+ const dashboardRoot = resolveDashboardRoot();
42
+ const vendorRoot = resolve(dashboardRoot, "vendor");
43
+ return {
44
+ name: "three-flatland-devtools",
45
+ apply: "serve",
46
+ config() {
47
+ return { resolve: { alias: [
48
+ {
49
+ find: "preact/jsx-runtime",
50
+ replacement: resolve(vendorRoot, "jsx-runtime.js")
51
+ },
52
+ {
53
+ find: "preact/jsx-dev-runtime",
54
+ replacement: resolve(vendorRoot, "jsx-runtime.js")
55
+ },
56
+ {
57
+ find: "preact/hooks",
58
+ replacement: resolve(vendorRoot, "hooks.module.js")
59
+ },
60
+ {
61
+ find: /^preact$/,
62
+ replacement: resolve(vendorRoot, "preact.module.js")
63
+ }
64
+ ] } };
65
+ },
66
+ configResolved(config) {
67
+ if (!config.server.fs.allow.includes(dashboardRoot)) config.server.fs.allow.push(dashboardRoot);
68
+ },
69
+ configureServer(server) {
70
+ server.middlewares.use((req, res, next) => {
71
+ (async () => {
72
+ if (req.url === void 0) return next();
73
+ const url = req.url.split("?")[0] ?? "";
74
+ if (url !== mountPath && url !== `${mountPath}/`) return next();
75
+ try {
76
+ let html = await readFile(resolve(dashboardRoot, "index.html"), "utf-8");
77
+ const entryAbs = resolve(dashboardRoot, "index.tsx");
78
+ html = html.replace("./index.tsx", `/@fs${entryAbs}`);
79
+ html = await server.transformIndexHtml(req.url, html, req.originalUrl);
80
+ res.statusCode = 200;
81
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
82
+ res.end(html);
83
+ } catch (err) {
84
+ next(err);
85
+ }
86
+ })();
87
+ });
88
+ const logger = server.config.logger;
89
+ const port = server.config.server.port ?? 5173;
90
+ logger.info(`\n \u001b[32m\u279c\u001b[0m three-flatland devtools: \u001b[36mhttp://localhost:${port}${mountPath}\u001b[0m\n`);
91
+ }
92
+ };
82
93
  }
83
- var vite_plugin_default = threeFlatlandDevtools;
84
- export {
85
- vite_plugin_default as default,
86
- threeFlatlandDevtools
87
- };
94
+ //#endregion
95
+ export { threeFlatlandDevtools as default, threeFlatlandDevtools };
96
+
88
97
  //# sourceMappingURL=vite-plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/vite-plugin.ts"],"sourcesContent":["/**\n * Vite plugin that serves the standalone devtools dashboard alongside the\n * user's app. Mounts a dev-only middleware at a configurable path (default\n * `/.devtools`).\n *\n * The dashboard source lives inside this package\n * (`packages/devtools/src/dashboard/`), not inside the consumer's project.\n * The plugin:\n * 1. Whitelists the dashboard directory via `server.fs.allow` so Vite\n * is willing to read its files across the workspace boundary.\n * 2. Serves `index.html` at the mount path, rewritten so the entry\n * script loads via `/@fs/<abs>` — Vite then transforms it with full\n * HMR.\n * 3. Aliases the vendored Preact files so `import from 'preact'`\n * resolves locally — no runtime dep on Preact leaks into the\n * consumer's `node_modules`.\n *\n * Access the dashboard at the Vite dev server's origin directly, e.g.\n * `http://localhost:5174/.devtools`. If the host project sits behind a\n * microfrontend proxy, point the browser at the Vite port — the\n * dashboard's transitive requests (`/@fs/`, `/@vite/client`, pre-bundled\n * `node_modules/.vite/`) are not namespaced and expect to land on the\n * same origin that served the HTML.\n *\n * Dev-only; the plugin is inert in production builds.\n */\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\n\nimport type { Plugin, ViteDevServer } from 'vite'\n\nexport interface ThreeFlatlandDevtoolsOptions {\n /** URL path the dashboard is served under. Default: `/.devtools`. */\n path?: string\n}\n\nconst DEFAULT_PATH = '/.devtools'\n\nfunction resolveDashboardRoot(): string {\n // Three possible layouts for this file at runtime:\n // 1. `packages/devtools/src/vite-plugin.ts` (source condition)\n // 2. `packages/devtools/dist/vite-plugin.js` (workspace, Node import condition)\n // 3. `node_modules/@three-flatland/devtools/dist/vite-plugin.js` (published)\n //\n // For (2) — the dev workflow where Node loads the built plugin but we\n // want HMR over the unbuilt sources — prefer the sibling `../src/dashboard/`\n // if it exists. Otherwise resolve `./dashboard` relative to this file.\n const here = dirname(fileURLToPath(import.meta.url))\n const siblingSrc = resolve(here, '../src/dashboard')\n if (existsSync(siblingSrc)) return siblingSrc\n return resolve(here, 'dashboard')\n}\n\nexport function threeFlatlandDevtools(\n options: ThreeFlatlandDevtoolsOptions = {},\n): Plugin {\n const mountPath = options.path ?? DEFAULT_PATH\n const dashboardRoot = resolveDashboardRoot()\n const vendorRoot = resolve(dashboardRoot, 'vendor')\n\n return {\n name: 'three-flatland-devtools',\n apply: 'serve',\n\n config() {\n return {\n resolve: {\n // Order matters — Vite/rollup-plugin-alias matches left-to-right\n // by string prefix, so the broad `preact` entry must come last\n // or it swallows `preact/jsx-*` and `preact/hooks`.\n alias: [\n {\n find: 'preact/jsx-runtime',\n replacement: resolve(vendorRoot, 'jsx-runtime.js'),\n },\n {\n // esbuild dev mode emits `import { jsxDEV } from 'preact/jsx-dev-runtime'`;\n // the same shim exports `jsxDEV`.\n find: 'preact/jsx-dev-runtime',\n replacement: resolve(vendorRoot, 'jsx-runtime.js'),\n },\n {\n find: 'preact/hooks',\n replacement: resolve(vendorRoot, 'hooks.module.js'),\n },\n {\n find: /^preact$/,\n replacement: resolve(vendorRoot, 'preact.module.js'),\n },\n ],\n },\n }\n },\n\n configResolved(config) {\n // Append, don't replace. Returning an array from `config` would\n // overwrite Vite's default allow-list (project + workspace root),\n // locking the host app out of its own files.\n if (!config.server.fs.allow.includes(dashboardRoot)) {\n config.server.fs.allow.push(dashboardRoot)\n }\n },\n\n configureServer(server: ViteDevServer) {\n server.middlewares.use((req, res, next) => {\n void (async () => {\n if (req.url === undefined) return next()\n const url = req.url.split('?')[0] ?? ''\n if (url !== mountPath && url !== `${mountPath}/`) return next()\n\n try {\n const indexPath = resolve(dashboardRoot, 'index.html')\n let html = await readFile(indexPath, 'utf-8')\n const entryAbs = resolve(dashboardRoot, 'index.tsx')\n html = html.replace('./index.tsx', `/@fs${entryAbs}`)\n html = await server.transformIndexHtml(req.url, html, req.originalUrl)\n res.statusCode = 200\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end(html)\n } catch (err) {\n next(err)\n }\n })()\n })\n\n const logger = server.config.logger\n const port = server.config.server.port ?? 5173\n logger.info(\n `\\n \\u001b[32m\\u279c\\u001b[0m three-flatland devtools: \\u001b[36mhttp://localhost:${port}${mountPath}\\u001b[0m\\n`,\n )\n },\n }\n}\n\nexport default threeFlatlandDevtools\n"],"mappings":"AA0BA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,SAAS,eAAe;AASjC,MAAM,eAAe;AAErB,SAAS,uBAA+B;AAStC,QAAM,OAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AACnD,QAAM,aAAa,QAAQ,MAAM,kBAAkB;AACnD,MAAI,WAAW,UAAU,EAAG,QAAO;AACnC,SAAO,QAAQ,MAAM,WAAW;AAClC;AAEO,SAAS,sBACd,UAAwC,CAAC,GACjC;AACR,QAAM,YAAY,QAAQ,QAAQ;AAClC,QAAM,gBAAgB,qBAAqB;AAC3C,QAAM,aAAa,QAAQ,eAAe,QAAQ;AAElD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IAEP,SAAS;AACP,aAAO;AAAA,QACL,SAAS;AAAA;AAAA;AAAA;AAAA,UAIP,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,aAAa,QAAQ,YAAY,gBAAgB;AAAA,YACnD;AAAA,YACA;AAAA;AAAA;AAAA,cAGE,MAAM;AAAA,cACN,aAAa,QAAQ,YAAY,gBAAgB;AAAA,YACnD;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,aAAa,QAAQ,YAAY,iBAAiB;AAAA,YACpD;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,aAAa,QAAQ,YAAY,kBAAkB;AAAA,YACrD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,eAAe,QAAQ;AAIrB,UAAI,CAAC,OAAO,OAAO,GAAG,MAAM,SAAS,aAAa,GAAG;AACnD,eAAO,OAAO,GAAG,MAAM,KAAK,aAAa;AAAA,MAC3C;AAAA,IACF;AAAA,IAEA,gBAAgB,QAAuB;AACrC,aAAO,YAAY,IAAI,CAAC,KAAK,KAAK,SAAS;AACzC,cAAM,YAAY;AAChB,cAAI,IAAI,QAAQ,OAAW,QAAO,KAAK;AACvC,gBAAM,MAAM,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC,KAAK;AACrC,cAAI,QAAQ,aAAa,QAAQ,GAAG,SAAS,IAAK,QAAO,KAAK;AAE9D,cAAI;AACF,kBAAM,YAAY,QAAQ,eAAe,YAAY;AACrD,gBAAI,OAAO,MAAM,SAAS,WAAW,OAAO;AAC5C,kBAAM,WAAW,QAAQ,eAAe,WAAW;AACnD,mBAAO,KAAK,QAAQ,eAAe,OAAO,QAAQ,EAAE;AACpD,mBAAO,MAAM,OAAO,mBAAmB,IAAI,KAAK,MAAM,IAAI,WAAW;AACrE,gBAAI,aAAa;AACjB,gBAAI,UAAU,gBAAgB,0BAA0B;AACxD,gBAAI,IAAI,IAAI;AAAA,UACd,SAAS,KAAK;AACZ,iBAAK,GAAG;AAAA,UACV;AAAA,QACF,GAAG;AAAA,MACL,CAAC;AAED,YAAM,SAAS,OAAO,OAAO;AAC7B,YAAM,OAAO,OAAO,OAAO,OAAO,QAAQ;AAC1C,aAAO;AAAA,QACL;AAAA,6EAAsF,IAAI,GAAG,SAAS;AAAA;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,sBAAQ;","names":[]}
1
+ {"version":3,"file":"vite-plugin.js","names":[],"sources":["../src/vite-plugin.ts"],"sourcesContent":["/**\n * Vite plugin that serves the standalone devtools dashboard alongside the\n * user's app. Mounts a dev-only middleware at a configurable path (default\n * `/.devtools`).\n *\n * The dashboard source lives inside this package\n * (`packages/devtools/src/dashboard/`), not inside the consumer's project.\n * The plugin:\n * 1. Whitelists the dashboard directory via `server.fs.allow` so Vite\n * is willing to read its files across the workspace boundary.\n * 2. Serves `index.html` at the mount path, rewritten so the entry\n * script loads via `/@fs/<abs>` — Vite then transforms it with full\n * HMR.\n * 3. Aliases the vendored Preact files so `import from 'preact'`\n * resolves locally — no runtime dep on Preact leaks into the\n * consumer's `node_modules`.\n *\n * Access the dashboard at the Vite dev server's origin directly, e.g.\n * `http://localhost:5174/.devtools`. If the host project sits behind a\n * microfrontend proxy, point the browser at the Vite port — the\n * dashboard's transitive requests (`/@fs/`, `/@vite/client`, pre-bundled\n * `node_modules/.vite/`) are not namespaced and expect to land on the\n * same origin that served the HTML.\n *\n * Dev-only; the plugin is inert in production builds.\n */\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\n\nimport type { Plugin, ViteDevServer } from 'vite'\n\nexport interface ThreeFlatlandDevtoolsOptions {\n /** URL path the dashboard is served under. Default: `/.devtools`. */\n path?: string\n}\n\nconst DEFAULT_PATH = '/.devtools'\n\nfunction resolveDashboardRoot(): string {\n // Three possible layouts for this file at runtime:\n // 1. `packages/devtools/src/vite-plugin.ts` (source condition)\n // 2. `packages/devtools/dist/vite-plugin.js` (workspace, Node import condition)\n // 3. `node_modules/@three-flatland/devtools/dist/vite-plugin.js` (published)\n //\n // For (2) — the dev workflow where Node loads the built plugin but we\n // want HMR over the unbuilt sources — prefer the sibling `../src/dashboard/`\n // if it exists. Otherwise resolve `./dashboard` relative to this file.\n const here = dirname(fileURLToPath(import.meta.url))\n const siblingSrc = resolve(here, '../src/dashboard')\n if (existsSync(siblingSrc)) return siblingSrc\n return resolve(here, 'dashboard')\n}\n\nexport function threeFlatlandDevtools(options: ThreeFlatlandDevtoolsOptions = {}): Plugin {\n const mountPath = options.path ?? DEFAULT_PATH\n const dashboardRoot = resolveDashboardRoot()\n const vendorRoot = resolve(dashboardRoot, 'vendor')\n\n return {\n name: 'three-flatland-devtools',\n apply: 'serve',\n\n config() {\n return {\n resolve: {\n // Order matters — Vite/rollup-plugin-alias matches left-to-right\n // by string prefix, so the broad `preact` entry must come last\n // or it swallows `preact/jsx-*` and `preact/hooks`.\n alias: [\n {\n find: 'preact/jsx-runtime',\n replacement: resolve(vendorRoot, 'jsx-runtime.js'),\n },\n {\n // esbuild dev mode emits `import { jsxDEV } from 'preact/jsx-dev-runtime'`;\n // the same shim exports `jsxDEV`.\n find: 'preact/jsx-dev-runtime',\n replacement: resolve(vendorRoot, 'jsx-runtime.js'),\n },\n {\n find: 'preact/hooks',\n replacement: resolve(vendorRoot, 'hooks.module.js'),\n },\n {\n find: /^preact$/,\n replacement: resolve(vendorRoot, 'preact.module.js'),\n },\n ],\n },\n }\n },\n\n configResolved(config) {\n // Append, don't replace. Returning an array from `config` would\n // overwrite Vite's default allow-list (project + workspace root),\n // locking the host app out of its own files.\n if (!config.server.fs.allow.includes(dashboardRoot)) {\n config.server.fs.allow.push(dashboardRoot)\n }\n },\n\n configureServer(server: ViteDevServer) {\n server.middlewares.use((req, res, next) => {\n void (async () => {\n if (req.url === undefined) return next()\n const url = req.url.split('?')[0] ?? ''\n if (url !== mountPath && url !== `${mountPath}/`) return next()\n\n try {\n const indexPath = resolve(dashboardRoot, 'index.html')\n let html = await readFile(indexPath, 'utf-8')\n const entryAbs = resolve(dashboardRoot, 'index.tsx')\n html = html.replace('./index.tsx', `/@fs${entryAbs}`)\n html = await server.transformIndexHtml(req.url, html, req.originalUrl)\n res.statusCode = 200\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end(html)\n } catch (err) {\n next(err)\n }\n })()\n })\n\n const logger = server.config.logger\n const port = server.config.server.port ?? 5173\n logger.info(\n `\\n \\u001b[32m\\u279c\\u001b[0m three-flatland devtools: \\u001b[36mhttp://localhost:${port}${mountPath}\\u001b[0m\\n`\n )\n },\n }\n}\n\nexport default threeFlatlandDevtools\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,MAAM,eAAe;AAErB,SAAS,uBAA+B;CAStC,MAAM,OAAO,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;CACnD,MAAM,aAAa,QAAQ,MAAM,kBAAkB;CACnD,IAAI,WAAW,UAAU,GAAG,OAAO;CACnC,OAAO,QAAQ,MAAM,WAAW;AAClC;AAEA,SAAgB,sBAAsB,UAAwC,CAAC,GAAW;CACxF,MAAM,YAAY,QAAQ,QAAQ;CAClC,MAAM,gBAAgB,qBAAqB;CAC3C,MAAM,aAAa,QAAQ,eAAe,QAAQ;CAElD,OAAO;EACL,MAAM;EACN,OAAO;EAEP,SAAS;GACP,OAAO,EACL,SAAS,EAIP,OAAO;IACL;KACE,MAAM;KACN,aAAa,QAAQ,YAAY,gBAAgB;IACnD;IACA;KAGE,MAAM;KACN,aAAa,QAAQ,YAAY,gBAAgB;IACnD;IACA;KACE,MAAM;KACN,aAAa,QAAQ,YAAY,iBAAiB;IACpD;IACA;KACE,MAAM;KACN,aAAa,QAAQ,YAAY,kBAAkB;IACrD;GACF,EACF,EACF;EACF;EAEA,eAAe,QAAQ;GAIrB,IAAI,CAAC,OAAO,OAAO,GAAG,MAAM,SAAS,aAAa,GAChD,OAAO,OAAO,GAAG,MAAM,KAAK,aAAa;EAE7C;EAEA,gBAAgB,QAAuB;GACrC,OAAO,YAAY,KAAK,KAAK,KAAK,SAAS;IACzC,CAAM,YAAY;KAChB,IAAI,IAAI,QAAQ,KAAA,GAAW,OAAO,KAAK;KACvC,MAAM,MAAM,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM;KACrC,IAAI,QAAQ,aAAa,QAAQ,GAAG,UAAU,IAAI,OAAO,KAAK;KAE9D,IAAI;MAEF,IAAI,OAAO,MAAM,SADC,QAAQ,eAAe,YACP,GAAG,OAAO;MAC5C,MAAM,WAAW,QAAQ,eAAe,WAAW;MACnD,OAAO,KAAK,QAAQ,eAAe,OAAO,UAAU;MACpD,OAAO,MAAM,OAAO,mBAAmB,IAAI,KAAK,MAAM,IAAI,WAAW;MACrE,IAAI,aAAa;MACjB,IAAI,UAAU,gBAAgB,0BAA0B;MACxD,IAAI,IAAI,IAAI;KACd,SAAS,KAAK;MACZ,KAAK,GAAG;KACV;IACF,EAAA,CAAG;GACL,CAAC;GAED,MAAM,SAAS,OAAO,OAAO;GAC7B,MAAM,OAAO,OAAO,OAAO,OAAO,QAAQ;GAC1C,OAAO,KACL,sFAAsF,OAAO,UAAU,YACzG;EACF;CACF;AACF"}
package/package.json CHANGED
@@ -1,69 +1,70 @@
1
1
  {
2
2
  "name": "@three-flatland/devtools",
3
- "version": "0.1.0-alpha.3",
3
+ "version": "1.0.0-alpha.6",
4
4
  "description": "Dev-time introspection toolkit for three-flatland — Tweakpane v4 UI plugin, stats monitor, and buffer inspection",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {
8
- "source": "./src/index.ts",
9
8
  "import": {
10
9
  "types": "./dist/index.d.ts",
11
10
  "default": "./dist/index.js"
12
- },
13
- "require": {
14
- "types": "./dist/index.d.cts",
15
- "default": "./dist/index.cjs"
16
11
  }
17
12
  },
18
13
  "./react": {
19
- "source": "./src/react.ts",
20
14
  "import": {
21
15
  "types": "./dist/react.d.ts",
22
16
  "default": "./dist/react.js"
23
- },
24
- "require": {
25
- "types": "./dist/react.d.cts",
26
- "default": "./dist/react.cjs"
27
17
  }
28
18
  },
29
19
  "./react/*": {
30
- "source": "./src/react/*.ts",
31
20
  "import": {
32
21
  "types": "./dist/react/*.d.ts",
33
22
  "default": "./dist/react/*.js"
34
- },
35
- "require": {
36
- "types": "./dist/react/*.d.cts",
37
- "default": "./dist/react/*.cjs"
38
23
  }
39
24
  },
40
25
  "./vite": {
41
- "source": "./src/vite-plugin.ts",
42
26
  "import": {
43
27
  "types": "./dist/vite-plugin.d.ts",
44
28
  "default": "./dist/vite-plugin.js"
45
- },
46
- "require": {
47
- "types": "./dist/vite-plugin.d.cts",
48
- "default": "./dist/vite-plugin.cjs"
49
29
  }
50
30
  }
51
31
  },
52
- "main": "./dist/index.cjs",
32
+ "main": "./dist/index.js",
53
33
  "module": "./dist/index.js",
54
34
  "types": "./dist/index.d.ts",
55
35
  "files": [
56
36
  "dist"
57
37
  ],
58
38
  "sideEffects": false,
39
+ "nx": {
40
+ "tags": [
41
+ "scope:consumer"
42
+ ],
43
+ "targets": {
44
+ "test": {
45
+ "executor": "nx:run-commands",
46
+ "options": {
47
+ "command": "vitest run",
48
+ "cwd": "{projectRoot}"
49
+ }
50
+ },
51
+ "lint": {
52
+ "executor": "nx:run-commands",
53
+ "options": {
54
+ "command": "oxlint --type-aware .",
55
+ "cwd": "{projectRoot}"
56
+ }
57
+ }
58
+ }
59
+ },
59
60
  "peerDependencies": {
60
61
  "@react-three/fiber": "^10.0.0-alpha.2",
61
62
  "@tweakpane/plugin-essentials": "^0.2.1",
62
63
  "react": "^19.2.0",
63
64
  "three": "^0.183.0",
64
- "three-flatland": "^0.1.0-alpha.4",
65
+ "three-flatland": "^0.1.0-alpha.9",
65
66
  "tweakpane": "^4.0.5",
66
- "vite": "^5.0.0 || ^6.0.0"
67
+ "vite": "^7.0.0"
67
68
  },
68
69
  "peerDependenciesMeta": {
69
70
  "react": {
@@ -90,14 +91,14 @@
90
91
  "@types/react": "^19.0.2",
91
92
  "@types/react-dom": "^19.0.2",
92
93
  "@types/three": "^0.183.1",
93
- "happy-dom": "^15.11.7",
94
+ "happy-dom": "^20.8.9",
94
95
  "react": "^19.2.0",
95
96
  "react-dom": "^19.2.0",
96
97
  "three": "^0.183.1",
97
98
  "tweakpane": "^4.0.5",
98
99
  "typescript": "^5.7.3",
99
- "vite": "^6.4.1",
100
- "three-flatland": "0.1.0-alpha.6"
100
+ "vite": "^7.3.6",
101
+ "three-flatland": "0.1.0-alpha.9"
101
102
  },
102
103
  "keywords": [
103
104
  "three.js",
@@ -112,10 +113,13 @@
112
113
  "url": "https://github.com/thejustinwalsh/three-flatland.git",
113
114
  "directory": "packages/devtools"
114
115
  },
116
+ "bin": {
117
+ "flatland-devtools-relay": "./dist/relay.js"
118
+ },
115
119
  "scripts": {
116
- "build": "tsup",
120
+ "build": "tsdown",
117
121
  "build:bundle": "vite build --config vite.config.bundle.ts",
118
- "dev": "tsup --watch",
122
+ "dev": "tsdown --watch",
119
123
  "test": "vitest run",
120
124
  "test:watch": "vitest",
121
125
  "typecheck": "tsc --noEmit && tsc --noEmit -p src/dashboard/tsconfig.json",