@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.
- package/README.md +1 -1
- package/dist/buffers-modal.d.ts +16 -52
- package/dist/buffers-modal.d.ts.map +1 -0
- package/dist/buffers-modal.js +459 -464
- package/dist/buffers-modal.js.map +1 -1
- package/dist/buffers-view.d.ts +22 -34
- package/dist/buffers-view.d.ts.map +1 -0
- package/dist/buffers-view.js +252 -240
- package/dist/buffers-view.js.map +1 -1
- package/dist/create-pane.d.ts +38 -37
- package/dist/create-pane.d.ts.map +1 -0
- package/dist/create-pane.js +197 -166
- package/dist/create-pane.js.map +1 -1
- package/dist/dashboard/app.tsx +2 -0
- package/dist/dashboard/export.ts +1 -3
- package/dist/dashboard/frame-cursor.ts +81 -0
- package/dist/dashboard/hooks.ts +10 -2
- package/dist/dashboard/index.html +61 -0
- package/dist/dashboard/panels/batches.tsx +5 -18
- package/dist/dashboard/panels/buffers.tsx +52 -26
- package/dist/dashboard/panels/env.tsx +5 -6
- package/dist/dashboard/panels/protocol-log.tsx +146 -58
- package/dist/dashboard/panels/registry.tsx +55 -69
- package/dist/dashboard/panels/scrubber.tsx +100 -0
- package/dist/dashboard/panels/stats.tsx +60 -32
- package/dist/dashboard/protocol-store.ts +25 -8
- package/dist/dashboard/vendor/hooks.module.d.ts +146 -0
- package/dist/dashboard/vendor/jsx-runtime.d.ts +55 -0
- package/dist/dashboard/vendor/jsx.d.ts +3123 -0
- package/dist/dashboard/vendor/preact.module.d.ts +397 -0
- package/dist/devtools-client.d.ts +312 -300
- package/dist/devtools-client.d.ts.map +1 -0
- package/dist/devtools-client.js +866 -838
- package/dist/devtools-client.js.map +1 -1
- package/dist/index.d.ts +6 -8
- package/dist/index.js +5 -12
- package/dist/perf-trace.d.ts +6 -4
- package/dist/perf-trace.d.ts.map +1 -0
- package/dist/perf-trace.js +80 -66
- package/dist/perf-trace.js.map +1 -1
- package/dist/plugins.d.ts +6 -6
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +5 -5
- package/dist/plugins.js.map +1 -1
- package/dist/provider-switcher.d.ts +8 -15
- package/dist/provider-switcher.d.ts.map +1 -0
- package/dist/provider-switcher.js +68 -68
- package/dist/provider-switcher.js.map +1 -1
- package/dist/react/devtools-provider.d.ts +11 -10
- package/dist/react/devtools-provider.d.ts.map +1 -0
- package/dist/react/devtools-provider.js +60 -32
- package/dist/react/devtools-provider.js.map +1 -1
- package/dist/react/use-fps-graph.d.ts +7 -7
- package/dist/react/use-fps-graph.d.ts.map +1 -0
- package/dist/react/use-fps-graph.js +27 -21
- package/dist/react/use-fps-graph.js.map +1 -1
- package/dist/react/use-pane-button.d.ts +4 -4
- package/dist/react/use-pane-button.d.ts.map +1 -0
- package/dist/react/use-pane-button.js +35 -30
- package/dist/react/use-pane-button.js.map +1 -1
- package/dist/react/use-pane-folder.d.ts +5 -4
- package/dist/react/use-pane-folder.d.ts.map +1 -0
- package/dist/react/use-pane-folder.js +33 -20
- package/dist/react/use-pane-folder.js.map +1 -1
- package/dist/react/use-pane-input.d.ts +31 -30
- package/dist/react/use-pane-input.d.ts.map +1 -0
- package/dist/react/use-pane-input.js +46 -42
- package/dist/react/use-pane-input.js.map +1 -1
- package/dist/react/use-pane-radio-grid.d.ts +20 -20
- package/dist/react/use-pane-radio-grid.d.ts.map +1 -0
- package/dist/react/use-pane-radio-grid.js +72 -50
- package/dist/react/use-pane-radio-grid.js.map +1 -1
- package/dist/react/use-pane.d.ts +4 -4
- package/dist/react/use-pane.d.ts.map +1 -0
- package/dist/react/use-pane.js +52 -17
- package/dist/react/use-pane.js.map +1 -1
- package/dist/react.d.ts +10 -12
- package/dist/react.js +2 -12
- package/dist/registry-view.d.ts +8 -21
- package/dist/registry-view.d.ts.map +1 -0
- package/dist/registry-view.js +357 -338
- package/dist/registry-view.js.map +1 -1
- package/dist/relay.d.ts +16 -0
- package/dist/relay.d.ts.map +1 -0
- package/dist/relay.js +189 -0
- package/dist/relay.js.map +1 -0
- package/dist/remote.d.ts +10 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +28 -0
- package/dist/remote.js.map +1 -0
- package/dist/stats-graph.d.ts +23 -31
- package/dist/stats-graph.d.ts.map +1 -0
- package/dist/stats-graph.js +323 -264
- package/dist/stats-graph.js.map +1 -1
- package/dist/stats-row.d.ts +8 -21
- package/dist/stats-row.d.ts.map +1 -0
- package/dist/stats-row.js +99 -101
- package/dist/stats-row.js.map +1 -1
- package/dist/theme.d.ts +3 -1
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +43 -54
- package/dist/theme.js.map +1 -1
- package/dist/vite-plugin.d.ts +7 -6
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +87 -78
- package/dist/vite-plugin.js.map +1 -1
- package/package.json +33 -29
- package/dist/buffers-modal.cjs +0 -491
- package/dist/buffers-modal.cjs.map +0 -1
- package/dist/buffers-modal.d.cts +0 -62
- package/dist/buffers-view.cjs +0 -269
- package/dist/buffers-view.cjs.map +0 -1
- package/dist/buffers-view.d.cts +0 -39
- package/dist/create-pane.cjs +0 -203
- package/dist/create-pane.cjs.map +0 -1
- package/dist/create-pane.d.cts +0 -66
- package/dist/devtools-client.cjs +0 -870
- package/dist/devtools-client.cjs.map +0 -1
- package/dist/devtools-client.d.cts +0 -362
- package/dist/index.cjs +0 -42
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -8
- package/dist/index.js.map +0 -1
- package/dist/perf-trace.cjs +0 -103
- package/dist/perf-trace.cjs.map +0 -1
- package/dist/perf-trace.d.cts +0 -27
- package/dist/plugins.cjs +0 -44
- package/dist/plugins.cjs.map +0 -1
- package/dist/plugins.d.cts +0 -7
- package/dist/provider-switcher.cjs +0 -95
- package/dist/provider-switcher.cjs.map +0 -1
- package/dist/provider-switcher.d.cts +0 -18
- package/dist/react/devtools-provider.cjs +0 -59
- package/dist/react/devtools-provider.cjs.map +0 -1
- package/dist/react/devtools-provider.d.cts +0 -39
- package/dist/react/use-fps-graph.cjs +0 -49
- package/dist/react/use-fps-graph.cjs.map +0 -1
- package/dist/react/use-fps-graph.d.cts +0 -15
- package/dist/react/use-pane-button.cjs +0 -58
- package/dist/react/use-pane-button.cjs.map +0 -1
- package/dist/react/use-pane-button.d.cts +0 -10
- package/dist/react/use-pane-folder.cjs +0 -48
- package/dist/react/use-pane-folder.cjs.map +0 -1
- package/dist/react/use-pane-folder.d.cts +0 -15
- package/dist/react/use-pane-input.cjs +0 -70
- package/dist/react/use-pane-input.cjs.map +0 -1
- package/dist/react/use-pane-input.d.cts +0 -44
- package/dist/react/use-pane-radio-grid.cjs +0 -78
- package/dist/react/use-pane-radio-grid.cjs.map +0 -1
- package/dist/react/use-pane-radio-grid.d.cts +0 -35
- package/dist/react/use-pane.cjs +0 -45
- package/dist/react/use-pane.cjs.map +0 -1
- package/dist/react/use-pane.d.cts +0 -40
- package/dist/react.cjs +0 -50
- package/dist/react.cjs.map +0 -1
- package/dist/react.d.cts +0 -12
- package/dist/react.js.map +0 -1
- package/dist/registry-view.cjs +0 -371
- package/dist/registry-view.cjs.map +0 -1
- package/dist/registry-view.d.cts +0 -24
- package/dist/stats-graph.cjs +0 -297
- package/dist/stats-graph.cjs.map +0 -1
- package/dist/stats-graph.d.cts +0 -40
- package/dist/stats-row.cjs +0 -153
- package/dist/stats-row.cjs.map +0 -1
- package/dist/stats-row.d.cts +0 -24
- package/dist/theme.cjs +0 -260
- package/dist/theme.cjs.map +0 -1
- package/dist/theme.d.cts +0 -10
- package/dist/vite-plugin.cjs +0 -113
- package/dist/vite-plugin.cjs.map +0 -1
- 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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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
|
|
61
|
-
top-left of the label, relying on <label
|
|
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
|
|
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
|
|
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
|
|
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
|
|
145
|
-
* minimal
|
|
146
|
-
* 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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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"}
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Plugin } from
|
|
2
|
-
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
//#region src/vite-plugin.d.ts
|
|
3
3
|
interface ThreeFlatlandDevtoolsOptions {
|
|
4
|
-
|
|
5
|
-
|
|
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 {
|
|
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"}
|
package/dist/vite-plugin.js
CHANGED
|
@@ -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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
84
|
-
export {
|
|
85
|
-
|
|
86
|
-
threeFlatlandDevtools
|
|
87
|
-
};
|
|
94
|
+
//#endregion
|
|
95
|
+
export { threeFlatlandDevtools as default, threeFlatlandDevtools };
|
|
96
|
+
|
|
88
97
|
//# sourceMappingURL=vite-plugin.js.map
|
package/dist/vite-plugin.js.map
CHANGED
|
@@ -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(
|
|
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": "
|
|
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.
|
|
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.
|
|
65
|
+
"three-flatland": "^0.1.0-alpha.9",
|
|
65
66
|
"tweakpane": "^4.0.5",
|
|
66
|
-
"vite": "^
|
|
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": "^
|
|
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": "^
|
|
100
|
-
"three-flatland": "0.1.0-alpha.
|
|
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": "
|
|
120
|
+
"build": "tsdown",
|
|
117
121
|
"build:bundle": "vite build --config vite.config.bundle.ts",
|
|
118
|
-
"dev": "
|
|
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",
|