react-state-inspector-devtools 0.1.2 → 0.1.8
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/dist/index.js +198 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +202 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -116,16 +116,22 @@ function createInspectorStore() {
|
|
|
116
116
|
// src/provider.tsx
|
|
117
117
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
118
118
|
var InspectorContext = (0, import_react.createContext)(null);
|
|
119
|
+
var storeRef = { current: null };
|
|
120
|
+
function getStore() {
|
|
121
|
+
if (!storeRef.current) {
|
|
122
|
+
storeRef.current = createInspectorStore();
|
|
123
|
+
}
|
|
124
|
+
return storeRef.current;
|
|
125
|
+
}
|
|
119
126
|
function StateInspectorProvider({
|
|
120
127
|
enabled = true,
|
|
121
128
|
children
|
|
122
129
|
}) {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
storeRef.current =
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InspectorContext.Provider, { value: storeRef.current, children });
|
|
130
|
+
const store = (0, import_react.useMemo)(() => getStore(), []);
|
|
131
|
+
(0, import_react.useEffect)(() => {
|
|
132
|
+
storeRef.current.enabled = enabled;
|
|
133
|
+
}, [enabled]);
|
|
134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InspectorContext.Provider, { value: store, children });
|
|
129
135
|
}
|
|
130
136
|
function useInspectorStore() {
|
|
131
137
|
const ctx = (0, import_react.useContext)(InspectorContext);
|
|
@@ -217,20 +223,68 @@ function useComponentLabel(label) {
|
|
|
217
223
|
var import_react3 = require("react");
|
|
218
224
|
var import_react_dom = require("react-dom");
|
|
219
225
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
226
|
+
var isMac = navigator.platform.toUpperCase().includes("MAC");
|
|
220
227
|
function isOptionObject(opt) {
|
|
221
228
|
return typeof opt === "object" && opt !== null && "value" in opt;
|
|
222
229
|
}
|
|
223
230
|
function StateInspectorUI() {
|
|
224
231
|
const store = useInspectorStore();
|
|
232
|
+
const [query, setQuery] = (0, import_react3.useState)("");
|
|
225
233
|
const [open, setOpen] = (0, import_react3.useState)(false);
|
|
226
234
|
const [selectedId, setSelectedId] = (0, import_react3.useState)(null);
|
|
227
235
|
const [, force] = (0, import_react3.useState)(0);
|
|
236
|
+
const searchRef = (0, import_react3.useRef)(null);
|
|
237
|
+
const LS_KEY = "rsi:panel-pos";
|
|
238
|
+
const [pos, setPos] = (0, import_react3.useState)(() => {
|
|
239
|
+
try {
|
|
240
|
+
const raw = localStorage.getItem(LS_KEY);
|
|
241
|
+
return raw ? JSON.parse(raw) : { right: 16, bottom: 72 };
|
|
242
|
+
} catch {
|
|
243
|
+
return { right: 16, bottom: 72 };
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
(0, import_react3.useEffect)(() => {
|
|
247
|
+
try {
|
|
248
|
+
localStorage.setItem(LS_KEY, JSON.stringify(pos));
|
|
249
|
+
} catch {
|
|
250
|
+
}
|
|
251
|
+
}, [pos]);
|
|
252
|
+
const SIZE_KEY = "rsi:panel-size";
|
|
253
|
+
const [size, setSize] = (0, import_react3.useState)(() => {
|
|
254
|
+
try {
|
|
255
|
+
const raw = localStorage.getItem(SIZE_KEY);
|
|
256
|
+
return raw ? JSON.parse(raw) : { width: 720, height: 420 };
|
|
257
|
+
} catch {
|
|
258
|
+
return { width: 720, height: 420 };
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
(0, import_react3.useEffect)(() => {
|
|
262
|
+
try {
|
|
263
|
+
localStorage.setItem(SIZE_KEY, JSON.stringify(size));
|
|
264
|
+
} catch {
|
|
265
|
+
}
|
|
266
|
+
}, [size]);
|
|
228
267
|
(0, import_react3.useEffect)(() => store.subscribe(() => force((x) => x + 1)), [store]);
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
268
|
+
const snapshot = (0, import_react3.useMemo)(() => store.getSnapshot(), [store]);
|
|
269
|
+
const components = (0, import_react3.useMemo)(
|
|
270
|
+
() => snapshot.components.filter((c) => c.mounted),
|
|
271
|
+
[snapshot.components]
|
|
272
|
+
);
|
|
273
|
+
const q = query.trim().toLowerCase();
|
|
274
|
+
const filtered = (0, import_react3.useMemo)(
|
|
275
|
+
() => q ? components.filter((c) => {
|
|
276
|
+
const labelHit = c.label.toLowerCase().includes(q);
|
|
277
|
+
const keyHit = c.stateKeys.some(
|
|
278
|
+
(k) => k.toLowerCase().includes(q)
|
|
279
|
+
);
|
|
280
|
+
return labelHit || keyHit;
|
|
281
|
+
}) : components,
|
|
282
|
+
[q, components]
|
|
283
|
+
);
|
|
232
284
|
(0, import_react3.useEffect)(() => {
|
|
233
|
-
if (!open)
|
|
285
|
+
if (!open) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
234
288
|
if (components.length === 0) {
|
|
235
289
|
setSelectedId(null);
|
|
236
290
|
return;
|
|
@@ -240,22 +294,56 @@ function StateInspectorUI() {
|
|
|
240
294
|
}
|
|
241
295
|
}, [open, components.length]);
|
|
242
296
|
(0, import_react3.useEffect)(() => {
|
|
243
|
-
if (!open)
|
|
297
|
+
if (!open) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
244
300
|
function onKey(e) {
|
|
245
301
|
if (e.key === "Escape") setOpen(false);
|
|
246
302
|
}
|
|
247
303
|
window.addEventListener("keydown", onKey);
|
|
248
304
|
return () => window.removeEventListener("keydown", onKey);
|
|
249
305
|
}, [open]);
|
|
306
|
+
(0, import_react3.useEffect)(() => {
|
|
307
|
+
function onKey(e) {
|
|
308
|
+
const mod = isMac ? e.metaKey : e.ctrlKey;
|
|
309
|
+
if (mod && e.shiftKey && e.key.toLowerCase() === "i") {
|
|
310
|
+
e.preventDefault();
|
|
311
|
+
setOpen((o) => !o);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (!open) return;
|
|
315
|
+
if (e.key === "Escape") {
|
|
316
|
+
setOpen(false);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (e.key === "/") {
|
|
320
|
+
e.preventDefault();
|
|
321
|
+
searchRef.current?.focus();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
325
|
+
e.preventDefault();
|
|
326
|
+
const list = filtered;
|
|
327
|
+
if (!list.length) return;
|
|
328
|
+
const idx = list.findIndex((c) => c.id === selectedId);
|
|
329
|
+
const next = e.key === "ArrowDown" ? list[(Math.max(-1, idx) + 1) % list.length].id : list[idx <= 0 ? list.length - 1 : idx - 1].id;
|
|
330
|
+
setSelectedId(next);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
window.addEventListener("keydown", onKey);
|
|
334
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
335
|
+
}, [open, filtered, selectedId]);
|
|
250
336
|
const selected = (0, import_react3.useMemo)(() => {
|
|
251
337
|
if (!selectedId) return null;
|
|
252
338
|
return store.components.get(selectedId) ?? null;
|
|
253
|
-
}, [store, selectedId
|
|
339
|
+
}, [store, selectedId]);
|
|
340
|
+
if (!store.enabled) return null;
|
|
254
341
|
return (0, import_react_dom.createPortal)(
|
|
255
342
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
256
343
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
257
344
|
"button",
|
|
258
345
|
{
|
|
346
|
+
title: "State Inspector (\u2318\u21E7I / Ctrl\u21E7I)",
|
|
259
347
|
onClick: () => setOpen((o) => !o),
|
|
260
348
|
style: {
|
|
261
349
|
position: "fixed",
|
|
@@ -271,7 +359,6 @@ function StateInspectorUI() {
|
|
|
271
359
|
zIndex: 999999
|
|
272
360
|
},
|
|
273
361
|
"aria-label": "Toggle State Inspector",
|
|
274
|
-
title: "State Inspector",
|
|
275
362
|
children: "\u25CE"
|
|
276
363
|
}
|
|
277
364
|
),
|
|
@@ -280,11 +367,11 @@ function StateInspectorUI() {
|
|
|
280
367
|
{
|
|
281
368
|
style: {
|
|
282
369
|
position: "fixed",
|
|
283
|
-
right:
|
|
284
|
-
bottom:
|
|
285
|
-
width:
|
|
370
|
+
right: pos.right,
|
|
371
|
+
bottom: pos.bottom,
|
|
372
|
+
width: size.width,
|
|
286
373
|
maxWidth: "calc(100vw - 32px)",
|
|
287
|
-
height:
|
|
374
|
+
height: size.height,
|
|
288
375
|
maxHeight: "calc(100vh - 120px)",
|
|
289
376
|
background: "#1c1c1c",
|
|
290
377
|
color: "#fff",
|
|
@@ -296,12 +383,74 @@ function StateInspectorUI() {
|
|
|
296
383
|
overflow: "hidden"
|
|
297
384
|
},
|
|
298
385
|
children: [
|
|
299
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
386
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
387
|
+
"div",
|
|
388
|
+
{
|
|
389
|
+
onPointerDown: (e) => {
|
|
390
|
+
const startX = e.clientX;
|
|
391
|
+
const startY = e.clientY;
|
|
392
|
+
const start = size;
|
|
393
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
394
|
+
const onMove = (ev) => {
|
|
395
|
+
const dx = ev.clientX - startX;
|
|
396
|
+
const dy = ev.clientY - startY;
|
|
397
|
+
setSize({
|
|
398
|
+
width: Math.min(window.innerWidth - 16, Math.max(480, start.width + dx)),
|
|
399
|
+
height: Math.min(window.innerHeight - 120, Math.max(280, start.height + dy))
|
|
400
|
+
});
|
|
401
|
+
};
|
|
402
|
+
const onUp = () => {
|
|
403
|
+
window.removeEventListener("pointermove", onMove);
|
|
404
|
+
window.removeEventListener("pointerup", onUp);
|
|
405
|
+
};
|
|
406
|
+
window.addEventListener("pointermove", onMove);
|
|
407
|
+
window.addEventListener("pointerup", onUp);
|
|
408
|
+
},
|
|
409
|
+
style: {
|
|
410
|
+
position: "absolute",
|
|
411
|
+
right: 6,
|
|
412
|
+
bottom: 6,
|
|
413
|
+
width: 14,
|
|
414
|
+
height: 14,
|
|
415
|
+
borderRadius: 6,
|
|
416
|
+
border: "1px solid #333",
|
|
417
|
+
background: "#838383",
|
|
418
|
+
cursor: "nwse-resize"
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
),
|
|
422
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { borderRight: "1px solid #333", padding: 12, height: size.height, display: "flex", flexDirection: "column", boxSizing: "border-box" }, children: [
|
|
423
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
style: { display: "flex", alignItems: "center", justifyContent: "space-between", cursor: "grab", userSelect: "none" },
|
|
427
|
+
onPointerDown: (e) => {
|
|
428
|
+
const startX = e.clientX;
|
|
429
|
+
const startY = e.clientY;
|
|
430
|
+
const start = pos;
|
|
431
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
432
|
+
const onMove = (ev) => {
|
|
433
|
+
const dx = ev.clientX - startX;
|
|
434
|
+
const dy = ev.clientY - startY;
|
|
435
|
+
setPos({
|
|
436
|
+
right: Math.max(8, start.right - dx),
|
|
437
|
+
bottom: Math.max(8, start.bottom - dy)
|
|
438
|
+
});
|
|
439
|
+
};
|
|
440
|
+
const onUp = () => {
|
|
441
|
+
window.removeEventListener("pointermove", onMove);
|
|
442
|
+
window.removeEventListener("pointerup", onUp);
|
|
443
|
+
};
|
|
444
|
+
window.addEventListener("pointermove", onMove);
|
|
445
|
+
window.addEventListener("pointerup", onUp);
|
|
446
|
+
},
|
|
447
|
+
children: [
|
|
448
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { style: { margin: 0 }, children: "Components" }),
|
|
449
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 12, opacity: 0.7 }, children: filtered.length })
|
|
450
|
+
]
|
|
451
|
+
}
|
|
452
|
+
),
|
|
453
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 10, display: "grid", gap: 8, overflow: "auto", flex: 1 }, children: filtered.map((c) => {
|
|
305
454
|
const active = c.id === selectedId;
|
|
306
455
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
307
456
|
"button",
|
|
@@ -328,7 +477,7 @@ function StateInspectorUI() {
|
|
|
328
477
|
);
|
|
329
478
|
}) })
|
|
330
479
|
] }),
|
|
331
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { padding: 12, overflow: "auto" }, children: [
|
|
480
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { padding: 12, overflow: "auto", display: "flex", flexDirection: "column", boxSizing: "border-box" }, children: [
|
|
332
481
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
333
482
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
334
483
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { style: { margin: 0 }, children: "State" }),
|
|
@@ -344,12 +493,31 @@ function StateInspectorUI() {
|
|
|
344
493
|
border: "1px solid #333",
|
|
345
494
|
borderRadius: 10,
|
|
346
495
|
padding: "6px 10px",
|
|
347
|
-
cursor: "pointer"
|
|
496
|
+
cursor: "pointer",
|
|
497
|
+
fontSize: 12
|
|
348
498
|
},
|
|
349
499
|
children: "Close"
|
|
350
500
|
}
|
|
351
501
|
)
|
|
352
502
|
] }),
|
|
503
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
504
|
+
"input",
|
|
505
|
+
{
|
|
506
|
+
value: query,
|
|
507
|
+
onChange: (e) => setQuery(e.target.value),
|
|
508
|
+
placeholder: "Search components / state keys\u2026",
|
|
509
|
+
ref: searchRef,
|
|
510
|
+
style: {
|
|
511
|
+
marginTop: 10,
|
|
512
|
+
padding: "8px 10px",
|
|
513
|
+
borderRadius: 10,
|
|
514
|
+
border: "1px solid #333",
|
|
515
|
+
background: "#111",
|
|
516
|
+
color: "#fff",
|
|
517
|
+
outline: "none"
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
),
|
|
353
521
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: 12, display: "grid", gap: 10 }, children: [
|
|
354
522
|
selected && selected.states.size === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: 13, opacity: 0.7 }, children: "This component has no inspectable state." }),
|
|
355
523
|
!selected && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { opacity: 0.7, fontSize: 13 }, children: "No component selected." }),
|
|
@@ -360,7 +528,8 @@ function StateInspectorUI() {
|
|
|
360
528
|
border: "1px solid #333",
|
|
361
529
|
borderRadius: 12,
|
|
362
530
|
padding: 10,
|
|
363
|
-
display: "
|
|
531
|
+
display: "flex",
|
|
532
|
+
flexDirection: "column",
|
|
364
533
|
gap: 8
|
|
365
534
|
},
|
|
366
535
|
children: [
|
|
@@ -415,7 +584,6 @@ function StateEditor({
|
|
|
415
584
|
value: current,
|
|
416
585
|
onChange: (e) => onChange(e.target.value),
|
|
417
586
|
style: {
|
|
418
|
-
width: "100%",
|
|
419
587
|
padding: "8px 10px",
|
|
420
588
|
borderRadius: 10,
|
|
421
589
|
border: "1px solid #333",
|
|
@@ -429,7 +597,7 @@ function StateEditor({
|
|
|
429
597
|
}
|
|
430
598
|
);
|
|
431
599
|
}
|
|
432
|
-
if (meta?.type === "number"
|
|
600
|
+
if (meta?.type === "number") {
|
|
433
601
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
434
602
|
"input",
|
|
435
603
|
{
|
|
@@ -440,7 +608,6 @@ function StateEditor({
|
|
|
440
608
|
step: meta?.step,
|
|
441
609
|
onChange: (e) => onChange(e.target.value === "" ? 0 : Number(e.target.value)),
|
|
442
610
|
style: {
|
|
443
|
-
width: "100%",
|
|
444
611
|
padding: "8px 10px",
|
|
445
612
|
borderRadius: 10,
|
|
446
613
|
border: "1px solid #333",
|
|
@@ -459,10 +626,9 @@ function StateEditor({
|
|
|
459
626
|
{
|
|
460
627
|
type: "text",
|
|
461
628
|
value: typeof value === "string" ? value : String(value ?? ""),
|
|
462
|
-
placeholder: meta?.placeholder,
|
|
629
|
+
placeholder: meta?.type === "text" ? meta.placeholder : void 0,
|
|
463
630
|
onChange: (e) => onChange(e.target.value),
|
|
464
631
|
style: {
|
|
465
|
-
width: "100%",
|
|
466
632
|
padding: "8px 10px",
|
|
467
633
|
borderRadius: 10,
|
|
468
634
|
border: "1px solid #333",
|
|
@@ -500,13 +666,12 @@ function JsonEditor({
|
|
|
500
666
|
const parsed = JSON.parse(next);
|
|
501
667
|
setError(null);
|
|
502
668
|
onValidJson(parsed);
|
|
503
|
-
} catch
|
|
669
|
+
} catch {
|
|
504
670
|
setError("Invalid JSON");
|
|
505
671
|
}
|
|
506
672
|
},
|
|
507
673
|
rows: 6,
|
|
508
674
|
style: {
|
|
509
|
-
width: "100%",
|
|
510
675
|
padding: "8px 10px",
|
|
511
676
|
borderRadius: 10,
|
|
512
677
|
border: "1px solid #333",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/store.ts","../src/hooks.ts","../src/StateInspectorUI.tsx"],"sourcesContent":["export * from \"./provider\";\nexport * from \"./store\";\nexport * from \"./hooks\";\nexport * from \"./StateInspectorUI\";\n","import React, { createContext, useContext, useEffect, useId, useMemo, useRef } from \"react\";\nimport { createInspectorStore, InspectorComponentRef, InspectorStore } from \"./store\";\n\nconst InspectorContext = createContext<InspectorStore | null>(null);\n\nexport function StateInspectorProvider({\n enabled = true,\n children,\n}: {\n enabled?: boolean;\n children: React.ReactNode;\n}) {\n const storeRef = useRef<InspectorStore>(null);\n\n if (!storeRef.current) {\n storeRef.current = createInspectorStore();\n }\n\n storeRef.current.enabled = enabled;\n\n return (\n <InspectorContext.Provider value={storeRef.current}>\n {children}\n </InspectorContext.Provider>\n );\n}\n\nexport function useInspectorStore(): InspectorStore {\n const ctx = useContext(InspectorContext);\n if (!ctx) {\n throw new Error(\"useInspectorStore must be used inside StateInspectorProvider\");\n }\n return ctx;\n}\n\nexport function useInspectorComponent(label?: string): InspectorComponentRef {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n\n store.registerComponent(componentId, label?.trim());\n return () => {\n store.unregisterComponent(componentId);\n };\n }, [store, componentId, label]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label?.trim();\n if (trimmed) store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n\n return useMemo(() => ({ id: componentId }), [componentId]);\n}\n","export type ComponentId = string;\n\nexport type InspectableMeta =\n | { type: \"boolean\" }\n | { type: \"text\"; placeholder?: string }\n | { type: \"number\"; min?: number; max?: number; step?: number }\n | { type: \"select\"; options: Array<string | { label: string; value: string }> }\n | { type: \"json\" }\n | { type: \"custom\"; renderId: string };\n\nexport interface InspectableStateEntry {\n key: string;\n value: unknown;\n setValue: (next: unknown) => void;\n meta?: InspectableMeta;\n}\n\nexport interface ComponentEntry {\n id: ComponentId;\n label: string;\n mounted: boolean;\n states: Map<string, InspectableStateEntry>;\n}\n\nexport interface InspectorSnapshot {\n enabled: boolean;\n components: Array<{\n id: ComponentId;\n label: string;\n mounted: boolean;\n stateKeys: string[];\n }>;\n}\n\ntype Listener = () => void;\n\nexport interface InspectorComponentRef {\n id: string;\n}\n\nexport interface InspectorStore {\n enabled: boolean;\n\n // internal registry\n components: Map<ComponentId, ComponentEntry>;\n\n // subscriptions\n subscribe: (listener: Listener) => () => void;\n getSnapshot: () => InspectorSnapshot;\n\n // component lifecycle\n registerComponent: (id: ComponentId, label?: string) => void;\n setComponentLabel: (id: ComponentId, label: string) => void;\n unregisterComponent: (id: ComponentId) => void;\n\n // state lifecycle\n upsertState: (\n componentId: ComponentId,\n entry: InspectableStateEntry,\n ) => void;\n\n updateStateValue: (componentId: ComponentId, key: string, value: unknown) => void;\n removeState: (componentId: ComponentId, key: string) => void;\n}\n\nexport function createInspectorStore(): InspectorStore {\n const components = new Map<ComponentId, ComponentEntry>();\n const listeners = new Set<Listener>();\n\n function emit() {\n for (const l of listeners) l();\n }\n\n function getOrCreateComponent(id: ComponentId): ComponentEntry {\n const existing = components.get(id);\n if (existing) return existing;\n\n const created: ComponentEntry = {\n id,\n label: \"Unknown\",\n mounted: true,\n states: new Map(),\n };\n components.set(id, created);\n return created;\n }\n\n const store: InspectorStore = {\n enabled: true,\n components,\n\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n\n getSnapshot() {\n return {\n enabled: store.enabled,\n components: Array.from(components.values()).map((c) => ({\n id: c.id,\n label: c.label,\n mounted: c.mounted,\n stateKeys: Array.from(c.states.keys()),\n })),\n };\n },\n\n registerComponent(id, label) {\n const c = getOrCreateComponent(id);\n c.mounted = true;\n if (label && label.trim()) c.label = label.trim();\n emit();\n },\n\n setComponentLabel(id, label) {\n const c = getOrCreateComponent(id);\n c.label = label.trim() || \"Unknown\";\n emit();\n },\n\n unregisterComponent(id) {\n const c = components.get(id);\n if (!c) return;\n\n // StrictMode double-unmount safe:\n // we mark as unmounted; UI can choose to hide unmounted entries.\n c.mounted = false;\n\n // Optional: immediate cleanup if you prefer:\n // components.delete(id);\n\n emit();\n },\n\n upsertState(componentId, entry) {\n const c = getOrCreateComponent(componentId);\n c.states.set(entry.key, entry);\n emit();\n },\n\n updateStateValue(componentId, key, value) {\n const c = components.get(componentId);\n if (!c) return;\n const s = c.states.get(key);\n if (!s) return;\n s.value = value;\n emit();\n },\n\n removeState(componentId, key) {\n const c = components.get(componentId);\n if (!c) return;\n if (!c.states.has(key)) return;\n c.states.delete(key);\n emit();\n },\n };\n\n return store;\n}\n","import React, { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { useInspectorStore } from \"./provider\";\nimport type { InspectableMeta, InspectorComponentRef } from \"./store\";\n\nfunction stableKey(input: string): string {\n return input.trim();\n}\n\nfunction inferMeta(value: unknown): InspectableMeta | undefined {\n const t = typeof value;\n if (t === \"boolean\") return { type: \"boolean\" };\n if (t === \"number\") return { type: \"number\" };\n if (t === \"string\") return { type: \"text\" };\n if (value && t === \"object\") return { type: \"json\" };\n return undefined;\n}\n\n/**\n * Registers a piece of state to the inspector registry.\n * Opt-in by replacing useState with useInspectableState.\n */\nexport function useInspectableState<T>(\n component: InspectorComponentRef,\n key: string,\n initial: T | (() => T),\n meta?: InspectableMeta,\n): [T, React.Dispatch<React.SetStateAction<T>>] {\n const store = useInspectorStore();\n const componentId = component.id;\n\n const stateKey = useMemo(() => stableKey(key), [key]);\n\n const [value, setValue] = useState<T>(initial);\n\n // Keep latest setter stable for registry consumers\n const setValueRef = useRef<(next: unknown) => void>(() => {});\n setValueRef.current = (next: unknown) => {\n setValue(next as T);\n };\n\n // Register component + state entry\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n\n return () => {\n store.removeState(componentId, stateKey);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, componentId, stateKey]);\n\n // Sync updates on each render when value/meta changes\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n }, [store, componentId, stateKey, value, meta]);\n\n return [value, setValue];\n}\n\n/**\n * Optional helper to give the current component instance a human label.\n */\nexport function useComponentLabel(label: string) {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label.trim();\n if (!trimmed) return;\n store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useInspectorStore } from \"./provider\";\nuseInspectorStore\n\nfunction isOptionObject(\n opt: string | { label: string; value: string },\n): opt is { label: string; value: string } {\n return typeof opt === \"object\" && opt !== null && \"value\" in opt;\n}\n\nexport function StateInspectorUI() {\n const store = useInspectorStore();\n\n const [open, setOpen] = useState(false);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [, force] = useState(0);\n\n useEffect(() => store.subscribe(() => force((x) => x + 1)), [store]);\n\n if (!store.enabled) return null;\n\n const snapshot = store.getSnapshot();\n const components = snapshot.components.filter((c) => c.mounted);\n\n // Keep a valid selection\n useEffect(() => {\n if (!open) return;\n\n if (components.length === 0) {\n setSelectedId(null);\n return;\n }\n\n if (!selectedId || !components.some((c) => c.id === selectedId)) {\n setSelectedId(components[0]!.id);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, components.length]);\n\n useEffect(() => {\n if (!open) return;\n\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") setOpen(false);\n }\n\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open]);\n\n const selected = useMemo(() => {\n if (!selectedId) return null;\n return store.components.get(selectedId) ?? null;\n }, [store, selectedId, snapshot.components.length]);\n\n return createPortal(\n <>\n {/* Floating Button */}\n <button\n onClick={() => setOpen((o) => !o)}\n style={{\n position: \"fixed\",\n right: 16,\n bottom: 16,\n width: 44,\n height: 44,\n borderRadius: 22,\n border: \"none\",\n background: \"#111\",\n color: \"#fff\",\n cursor: \"pointer\",\n zIndex: 999999,\n }}\n aria-label=\"Toggle State Inspector\"\n title=\"State Inspector\"\n >\n ◎\n </button>\n\n {/* Floating Card */}\n {open && (\n <div\n style={{\n position: \"fixed\",\n right: 16,\n bottom: 72,\n width: 720,\n maxWidth: \"calc(100vw - 32px)\",\n height: 420,\n maxHeight: \"calc(100vh - 120px)\",\n background: \"#1c1c1c\",\n color: \"#fff\",\n borderRadius: 12,\n border: \"1px solid #333\",\n zIndex: 999999,\n display: \"grid\",\n gridTemplateColumns: \"280px 1fr\",\n overflow: \"hidden\",\n }}\n >\n {/* Left: component list */}\n <div style={{ borderRight: \"1px solid #333\", padding: 12, height: \"420px\", display: \"flex\", flexDirection: \"column\", boxSizing: \"border-box\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <h4 style={{ margin: 0 }}>Components</h4>\n <span style={{ fontSize: 12, opacity: 0.7 }}>{components.length}</span>\n </div>\n\n <div style={{ marginTop: 10, display: \"grid\", gap: 8, overflow: \"auto\", flex: 1 }}>\n {components.map((c) => {\n const active = c.id === selectedId;\n return (\n <button\n key={c.id}\n onClick={() => setSelectedId(c.id)}\n style={{\n textAlign: \"left\",\n background: active ? \"#2a2a2a\" : \"transparent\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: 10,\n color: \"#fff\",\n cursor: \"pointer\",\n }}\n >\n <div style={{ fontWeight: 700 }}>{c.label}</div>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n states: {c.stateKeys.length ? c.stateKeys.length : 0}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Right: state editors */}\n <div style={{ padding: 12, overflow: \"auto\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <div>\n <h4 style={{ margin: 0 }}>State</h4>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n {selected ? selected.label : \"No selection\"}\n </div>\n </div>\n\n <button\n onClick={() => setOpen(false)}\n style={{\n background: \"transparent\",\n color: \"#fff\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: \"6px 10px\",\n cursor: \"pointer\",\n }}\n >\n Close\n </button>\n </div>\n\n <div style={{ marginTop: 12, display: \"grid\", gap: 10 }}>\n {selected && selected.states.size === 0 && (\n <div style={{ fontSize: 13, opacity: 0.7 }}>\n This component has no inspectable state.\n </div>\n )}\n\n {!selected && (\n <div style={{ opacity: 0.7, fontSize: 13 }}>\n No component selected.\n </div>\n )}\n\n {selected &&\n Array.from(selected.states.values()).map((s) => (\n <div\n key={s.key}\n style={{\n border: \"1px solid #333\",\n borderRadius: 12,\n padding: 10,\n display: \"grid\",\n gap: 8,\n }}\n >\n <div style={{ display: \"flex\", justifyContent: \"space-between\", gap: 12 }}>\n <div style={{ fontWeight: 700 }}>{s.key}</div>\n <div style={{ fontSize: 12, opacity: 0.6 }}>{s.meta?.type ?? \"auto\"}</div>\n </div>\n\n <StateEditor\n value={s.value}\n meta={s.meta}\n onChange={(next) => s.setValue(next)}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n </>,\n document.body,\n );\n}\n\nfunction StateEditor({\n value,\n meta,\n onChange,\n}: {\n value: unknown;\n meta: any;\n onChange: (next: unknown) => void;\n}) {\n // boolean\n if (meta?.type === \"boolean\" || typeof value === \"boolean\") {\n return (\n <label style={{ display: \"flex\", gap: 10, alignItems: \"center\" }}>\n <input\n type=\"checkbox\"\n checked={Boolean(value)}\n onChange={(e) => onChange(e.target.checked)}\n />\n <span style={{ fontSize: 13, opacity: 0.8 }}>{String(Boolean(value))}</span>\n </label>\n );\n }\n\n // select\n if (meta?.type === \"select\" && Array.isArray(meta.options)) {\n const current = typeof value === \"string\" ? value : String(value ?? \"\");\n return (\n <select\n value={current}\n onChange={(e) => onChange(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n >\n {meta.options.map((opt: any) => {\n const o = isOptionObject(opt) ? opt : { label: String(opt), value: String(opt) };\n return (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n );\n })}\n </select>\n );\n }\n\n // number\n if (meta?.type === \"number\" || typeof value === \"number\") {\n return (\n <input\n type=\"number\"\n value={typeof value === \"number\" ? value : Number(value ?? 0)}\n min={meta?.min}\n max={meta?.max}\n step={meta?.step}\n onChange={(e) => onChange(e.target.value === \"\" ? 0 : Number(e.target.value))}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n }\n\n // json\n if (meta?.type === \"json\" || (value && typeof value === \"object\")) {\n const text = safeStringify(value);\n return (\n <JsonEditor initial={text} onValidJson={(obj) => onChange(obj)} />\n );\n }\n\n // text (default)\n return (\n <input\n type=\"text\"\n value={typeof value === \"string\" ? value : String(value ?? \"\")}\n placeholder={meta?.placeholder}\n onChange={(e) => onChange(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n}\n\nfunction safeStringify(v: unknown) {\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n\nfunction JsonEditor({\n initial,\n onValidJson,\n}: {\n initial: string;\n onValidJson: (obj: unknown) => void;\n}) {\n const [raw, setRaw] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n setRaw(initial);\n }, [initial]);\n\n return (\n <div style={{ display: \"grid\", gap: 6 }}>\n <textarea\n value={raw}\n onChange={(e) => {\n const next = e.target.value;\n setRaw(next);\n\n try {\n const parsed = JSON.parse(next);\n setError(null);\n onValidJson(parsed);\n } catch (err: any) {\n setError(\"Invalid JSON\");\n }\n }}\n rows={6}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace\",\n fontSize: 12,\n }}\n />\n {error && <div style={{ fontSize: 12, color: \"#ff6b6b\" }}>{error}</div>}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/store.ts","../src/hooks.ts","../src/StateInspectorUI.tsx"],"sourcesContent":["export * from \"./provider\";\nexport * from \"./store\";\nexport * from \"./hooks\";\nexport * from \"./StateInspectorUI\";\n","import React, { createContext, useContext, useEffect, useId, useMemo } from \"react\";\nimport { createInspectorStore, InspectorComponentRef, InspectorStore } from \"./store\";\n\nconst InspectorContext = createContext<InspectorStore | null>(null);\n\nconst storeRef = { current: null as InspectorStore | null };\n\nfunction getStore(): InspectorStore {\n if (!storeRef.current) {\n storeRef.current = createInspectorStore();\n }\n return storeRef.current;\n}\n\nexport function StateInspectorProvider({\n enabled = true,\n children,\n}: {\n enabled?: boolean;\n children: React.ReactNode;\n}) {\n const store = useMemo(() => getStore(), []);\n\n useEffect(() => {\n storeRef.current!.enabled = enabled;\n }, [enabled]);\n\n return (\n <InspectorContext.Provider value={store}>\n {children}\n </InspectorContext.Provider>\n );\n}\n\nexport function useInspectorStore(): InspectorStore {\n const ctx = useContext(InspectorContext);\n if (!ctx) {\n throw new Error(\"useInspectorStore must be used inside StateInspectorProvider\");\n }\n return ctx;\n}\n\nexport function useInspectorComponent(label?: string): InspectorComponentRef {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n\n store.registerComponent(componentId, label?.trim());\n return () => {\n store.unregisterComponent(componentId);\n };\n }, [store, componentId, label]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label?.trim();\n if (trimmed) store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n\n return useMemo(() => ({ id: componentId }), [componentId]);\n}\n","export type ComponentId = string;\n\nexport type InspectableMeta =\n | { type: \"boolean\" }\n | { type: \"text\"; placeholder?: string }\n | { type: \"number\"; min?: number; max?: number; step?: number }\n | { type: \"select\"; options: Array<string | { label: string; value: string }> }\n | { type: \"json\" }\n | { type: \"custom\"; renderId: string };\n\nexport interface InspectableStateEntry {\n key: string;\n value: unknown;\n setValue: (next: unknown) => void;\n meta?: InspectableMeta;\n}\n\nexport interface ComponentEntry {\n id: ComponentId;\n label: string;\n mounted: boolean;\n states: Map<string, InspectableStateEntry>;\n}\n\nexport interface InspectorSnapshot {\n enabled: boolean;\n components: Array<{\n id: ComponentId;\n label: string;\n mounted: boolean;\n stateKeys: string[];\n }>;\n}\n\ntype Listener = () => void;\n\nexport interface InspectorComponentRef {\n id: string;\n}\n\nexport interface InspectorStore {\n enabled: boolean;\n\n // internal registry\n components: Map<ComponentId, ComponentEntry>;\n\n // subscriptions\n subscribe: (listener: Listener) => () => void;\n getSnapshot: () => InspectorSnapshot;\n\n // component lifecycle\n registerComponent: (id: ComponentId, label?: string) => void;\n setComponentLabel: (id: ComponentId, label: string) => void;\n unregisterComponent: (id: ComponentId) => void;\n\n // state lifecycle\n upsertState: (\n componentId: ComponentId,\n entry: InspectableStateEntry,\n ) => void;\n\n updateStateValue: (componentId: ComponentId, key: string, value: unknown) => void;\n removeState: (componentId: ComponentId, key: string) => void;\n}\n\nexport function createInspectorStore(): InspectorStore {\n const components = new Map<ComponentId, ComponentEntry>();\n const listeners = new Set<Listener>();\n\n function emit() {\n for (const l of listeners) l();\n }\n\n function getOrCreateComponent(id: ComponentId): ComponentEntry {\n const existing = components.get(id);\n if (existing) return existing;\n\n const created: ComponentEntry = {\n id,\n label: \"Unknown\",\n mounted: true,\n states: new Map(),\n };\n components.set(id, created);\n return created;\n }\n\n const store: InspectorStore = {\n enabled: true,\n components,\n\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n\n getSnapshot() {\n return {\n enabled: store.enabled,\n components: Array.from(components.values()).map((c) => ({\n id: c.id,\n label: c.label,\n mounted: c.mounted,\n stateKeys: Array.from(c.states.keys()),\n })),\n };\n },\n\n registerComponent(id, label) {\n const c = getOrCreateComponent(id);\n c.mounted = true;\n if (label && label.trim()) c.label = label.trim();\n emit();\n },\n\n setComponentLabel(id, label) {\n const c = getOrCreateComponent(id);\n c.label = label.trim() || \"Unknown\";\n emit();\n },\n\n unregisterComponent(id) {\n const c = components.get(id);\n if (!c) return;\n\n // StrictMode double-unmount safe:\n // we mark as unmounted; UI can choose to hide unmounted entries.\n c.mounted = false;\n\n // Optional: immediate cleanup if you prefer:\n // components.delete(id);\n\n emit();\n },\n\n upsertState(componentId, entry) {\n const c = getOrCreateComponent(componentId);\n c.states.set(entry.key, entry);\n emit();\n },\n\n updateStateValue(componentId, key, value) {\n const c = components.get(componentId);\n if (!c) return;\n const s = c.states.get(key);\n if (!s) return;\n s.value = value;\n emit();\n },\n\n removeState(componentId, key) {\n const c = components.get(componentId);\n if (!c) return;\n if (!c.states.has(key)) return;\n c.states.delete(key);\n emit();\n },\n };\n\n return store;\n}\n","import React, { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { useInspectorStore } from \"./provider\";\nimport type { InspectableMeta, InspectorComponentRef } from \"./store\";\n\nfunction stableKey(input: string): string {\n return input.trim();\n}\n\nfunction inferMeta(value: unknown): InspectableMeta | undefined {\n const t = typeof value;\n if (t === \"boolean\") return { type: \"boolean\" };\n if (t === \"number\") return { type: \"number\" };\n if (t === \"string\") return { type: \"text\" };\n if (value && t === \"object\") return { type: \"json\" };\n return undefined;\n}\n\n/**\n * Registers a piece of state to the inspector registry.\n * Opt-in by replacing useState with useInspectableState.\n */\nexport function useInspectableState<T>(\n component: InspectorComponentRef,\n key: string,\n initial: T | (() => T),\n meta?: InspectableMeta,\n): [T, React.Dispatch<React.SetStateAction<T>>] {\n const store = useInspectorStore();\n const componentId = component.id;\n\n const stateKey = useMemo(() => stableKey(key), [key]);\n\n const [value, setValue] = useState<T>(initial);\n\n // Keep latest setter stable for registry consumers\n const setValueRef = useRef<(next: unknown) => void>(() => {});\n setValueRef.current = (next: unknown) => {\n setValue(next as T);\n };\n\n // Register component + state entry\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n\n return () => {\n store.removeState(componentId, stateKey);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, componentId, stateKey]);\n\n // Sync updates on each render when value/meta changes\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n }, [store, componentId, stateKey, value, meta]);\n\n return [value, setValue];\n}\n\n/**\n * Optional helper to give the current component instance a human label.\n */\nexport function useComponentLabel(label: string) {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label.trim();\n if (!trimmed) return;\n store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useInspectorStore } from \"./provider\";\nimport { InspectableMeta } from \"./store\";\nconst isMac = navigator.platform.toUpperCase().includes(\"MAC\");\n\nfunction isOptionObject(\n opt: string | { label: string; value: string },\n): opt is { label: string; value: string } {\n return typeof opt === \"object\" && opt !== null && \"value\" in opt;\n}\n\nexport function StateInspectorUI() {\n const store = useInspectorStore();\n const [query, setQuery] = useState<string>(\"\");\n\n const [open, setOpen] = useState(false);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [, force] = useState(0);\n\n const searchRef = useRef<HTMLInputElement | null>(null);\n\n const LS_KEY = \"rsi:panel-pos\";\n const [pos, setPos] = useState<{ right: number; bottom: number }>(() => {\n try {\n const raw = localStorage.getItem(LS_KEY);\n return raw ? JSON.parse(raw) : { right: 16, bottom: 72 };\n } catch {\n // Fallback to default position if localStorage is unavailable\n return { right: 16, bottom: 72 };\n }\n });\n\n useEffect(() => {\n try {\n localStorage.setItem(LS_KEY, JSON.stringify(pos));\n } catch {\n // Silently fail if localStorage is unavailable\n }\n }, [pos]);\n\n const SIZE_KEY = \"rsi:panel-size\";\n const [size, setSize] = useState<{ width: number; height: number }>(() => {\n try {\n const raw = localStorage.getItem(SIZE_KEY);\n return raw ? JSON.parse(raw) : { width: 720, height: 420 };\n } catch {\n // Fallback to default size if localStorage is unavailable\n return { width: 720, height: 420 };\n }\n });\n\n useEffect(() => {\n try {\n localStorage.setItem(SIZE_KEY, JSON.stringify(size));\n } catch {\n // Silently fail if localStorage is unavailable\n }\n }, [size]);\n\n useEffect(() => store.subscribe(() => force((x) => x + 1)), [store]);\n\n const snapshot = useMemo(() => store.getSnapshot(), [store]);\n const components = useMemo(\n () => snapshot.components.filter((c) => c.mounted),\n [snapshot.components]\n );\n\n const q = query.trim().toLowerCase();\n\n const filtered = useMemo(\n () =>\n q\n ? components.filter((c) => {\n const labelHit = c.label.toLowerCase().includes(q);\n const keyHit = c.stateKeys.some((k) =>\n k.toLowerCase().includes(q)\n );\n return labelHit || keyHit;\n })\n : components,\n [q, components]\n );\n\n // Keep a valid selection\n useEffect(() => {\n if (!open) {\n return;\n }\n\n if (components.length === 0) {\n setSelectedId(null);\n return;\n }\n\n if (!selectedId || !components.some((c) => c.id === selectedId)) {\n setSelectedId(components[0]!.id);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, components.length]);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") setOpen(false);\n }\n\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open]);\n\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n const mod = isMac ? e.metaKey : e.ctrlKey;\n\n // Cmd/Ctrl + Shift + I → toggle inspector\n if (mod && e.shiftKey && e.key.toLowerCase() === \"i\") {\n e.preventDefault();\n setOpen((o) => !o);\n return;\n }\n\n if (!open) return;\n\n // Esc → close\n if (e.key === \"Escape\") {\n setOpen(false);\n return;\n }\n\n // \"/\" → focus search\n if (e.key === \"/\") {\n e.preventDefault();\n searchRef.current?.focus();\n return;\n }\n\n // Arrow navigation\n if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n const list = filtered;\n if (!list.length) return;\n\n const idx = list.findIndex((c) => c.id === selectedId);\n const next =\n e.key === \"ArrowDown\"\n ? list[(Math.max(-1, idx) + 1) % list.length]!.id\n : list[(idx <= 0 ? list.length - 1 : idx - 1)]!.id;\n\n setSelectedId(next);\n }\n }\n\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open, filtered, selectedId]);\n\n const selected = useMemo(() => {\n if (!selectedId) return null;\n return store.components.get(selectedId) ?? null;\n }, [store, selectedId]);\n\n if (!store.enabled) return null;\n\n return createPortal(\n <>\n {/* Floating Button */}\n <button\n title=\"State Inspector (⌘⇧I / Ctrl⇧I)\"\n onClick={() => setOpen((o) => !o)}\n style={{\n position: \"fixed\",\n right: 16,\n bottom: 16,\n width: 44,\n height: 44,\n borderRadius: 22,\n border: \"none\",\n background: \"#111\",\n color: \"#fff\",\n cursor: \"pointer\",\n zIndex: 999999,\n }}\n aria-label=\"Toggle State Inspector\"\n >\n ◎\n </button>\n\n {/* Floating Card */}\n {open && (\n <div\n style={{\n position: \"fixed\",\n right: pos.right,\n bottom: pos.bottom,\n width: size.width,\n maxWidth: \"calc(100vw - 32px)\",\n height: size.height,\n maxHeight: \"calc(100vh - 120px)\",\n background: \"#1c1c1c\",\n color: \"#fff\",\n borderRadius: 12,\n border: \"1px solid #333\",\n zIndex: 999999,\n display: \"grid\",\n gridTemplateColumns: \"280px 1fr\",\n overflow: \"hidden\",\n }}\n >\n {/* Resize Handle */}\n <div\n onPointerDown={(e) => {\n const startX = e.clientX;\n const startY = e.clientY;\n const start = size;\n\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const dx = ev.clientX - startX;\n const dy = ev.clientY - startY;\n setSize({\n width: Math.min(window.innerWidth - 16, Math.max(480, start.width + dx)),\n height: Math.min(window.innerHeight - 120, Math.max(280, start.height + dy)),\n });\n };\n\n const onUp = () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n };\n\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }}\n style={{\n position: \"absolute\",\n right: 6,\n bottom: 6,\n width: 14,\n height: 14,\n borderRadius: 6,\n border: \"1px solid #333\",\n background: \"#838383\",\n cursor: \"nwse-resize\",\n }}\n />\n\n {/* Left: component list */}\n <div style={{ borderRight: \"1px solid #333\", padding: 12, height: size.height, display: \"flex\", flexDirection: \"column\", boxSizing: \"border-box\" }}>\n <div \n style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", cursor: \"grab\", userSelect: \"none\" }}\n onPointerDown={(e) => {\n const startX = e.clientX;\n const startY = e.clientY;\n const start = pos;\n\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const dx = ev.clientX - startX;\n const dy = ev.clientY - startY;\n setPos({\n right: Math.max(8, start.right - dx),\n bottom: Math.max(8, start.bottom - dy),\n });\n };\n\n const onUp = () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n };\n\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }}\n >\n <h4 style={{ margin: 0 }}>Components</h4>\n <span style={{ fontSize: 12, opacity: 0.7 }}>{filtered.length}</span>\n </div>\n\n <div style={{ marginTop: 10, display: \"grid\", gap: 8, overflow: \"auto\", flex: 1 }}>\n {filtered.map((c) => {\n const active = c.id === selectedId;\n return (\n <button\n key={c.id}\n onClick={() => setSelectedId(c.id)}\n style={{\n textAlign: \"left\",\n background: active ? \"#2a2a2a\" : \"transparent\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: 10,\n color: \"#fff\",\n cursor: \"pointer\",\n }}\n >\n <div style={{ fontWeight: 700 }}>{c.label}</div>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n states: {c.stateKeys.length ? c.stateKeys.length : 0}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Right: state editors */}\n <div style={{ padding: 12, overflow: \"auto\", display: \"flex\", flexDirection: \"column\", boxSizing: \"border-box\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <div>\n <h4 style={{ margin: 0 }}>State</h4>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n {selected ? selected.label : \"No selection\"}\n </div>\n </div>\n\n <button\n onClick={() => setOpen(false)}\n style={{\n background: \"transparent\",\n color: \"#fff\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: \"6px 10px\",\n cursor: \"pointer\",\n fontSize: 12,\n }}\n >\n Close\n </button>\n </div>\n\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search components / state keys…\"\n ref={searchRef}\n style={{\n marginTop: 10,\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n outline: \"none\",\n }}\n />\n\n <div style={{ marginTop: 12, display: \"grid\", gap: 10 }}>\n {selected && selected.states.size === 0 && (\n <div style={{ fontSize: 13, opacity: 0.7 }}>\n This component has no inspectable state.\n </div>\n )}\n\n {!selected && (\n <div style={{ opacity: 0.7, fontSize: 13 }}>\n No component selected.\n </div>\n )}\n\n {selected &&\n Array.from(selected.states.values()).map((s) => (\n <div\n key={s.key}\n style={{\n border: \"1px solid #333\",\n borderRadius: 12,\n padding: 10,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8\n }}\n >\n <div style={{ display: \"flex\", justifyContent: \"space-between\", gap: 12 }}>\n <div style={{ fontWeight: 700 }}>{s.key}</div>\n <div style={{ fontSize: 12, opacity: 0.6 }}>{s.meta?.type ?? \"auto\"}</div>\n </div>\n\n <StateEditor\n value={s.value}\n meta={s.meta}\n onChange={(next) => s.setValue(next)}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n </>,\n document.body,\n );\n}\n\nfunction StateEditor({\n value,\n meta,\n onChange,\n}: {\n value: unknown;\n meta: InspectableMeta | undefined;\n onChange: (next: unknown) => void;\n}) {\n // boolean\n if (meta?.type === \"boolean\" || typeof value === \"boolean\") {\n return (\n <label style={{ display: \"flex\", gap: 10, alignItems: \"center\" }}>\n <input\n type=\"checkbox\"\n checked={Boolean(value)}\n onChange={(e) => onChange(e.target.checked)}\n />\n <span style={{ fontSize: 13, opacity: 0.8 }}>{String(Boolean(value))}</span>\n </label>\n );\n }\n\n // select\n if (meta?.type === \"select\" && Array.isArray(meta.options)) {\n const current = typeof value === \"string\" ? value : String(value ?? \"\");\n return (\n <select\n value={current}\n onChange={(e) => onChange(e.target.value)}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n >\n {meta.options.map((opt: string | { label: string; value: string }) => {\n const o = isOptionObject(opt) ? opt : { label: String(opt), value: String(opt) };\n return (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n );\n })}\n </select>\n );\n }\n\n // number\n if (meta?.type === \"number\") {\n return (\n <input\n type=\"number\"\n value={typeof value === \"number\" ? value : Number(value ?? 0)}\n min={meta?.min}\n max={meta?.max}\n step={meta?.step}\n onChange={(e) => onChange(e.target.value === \"\" ? 0 : Number(e.target.value))}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n }\n\n // json\n if (meta?.type === \"json\" || (value && typeof value === \"object\")) {\n const text = safeStringify(value);\n return (\n <JsonEditor initial={text} onValidJson={(obj) => onChange(obj)} />\n );\n }\n\n // text (default)\n return (\n <input\n type=\"text\"\n value={typeof value === \"string\" ? value : String(value ?? \"\")}\n placeholder={meta?.type === \"text\" ? meta.placeholder : undefined}\n onChange={(e) => onChange(e.target.value)}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n}\n\nfunction safeStringify(v: unknown) {\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n\nfunction JsonEditor({\n initial,\n onValidJson,\n}: {\n initial: string;\n onValidJson: (obj: unknown) => void;\n}) {\n const [raw, setRaw] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n setRaw(initial);\n }, [initial]);\n\n return (\n <div style={{ display: \"grid\", gap: 6 }}>\n <textarea\n value={raw}\n onChange={(e) => {\n const next = e.target.value;\n setRaw(next);\n\n try {\n const parsed = JSON.parse(next);\n setError(null);\n onValidJson(parsed);\n } catch {\n setError(\"Invalid JSON\");\n }\n }}\n rows={6}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace\",\n fontSize: 12,\n }}\n />\n {error && <div style={{ fontSize: 12, color: \"#ff6b6b\" }}>{error}</div>}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/provider.tsx
|
|
2
|
-
import { createContext, useContext, useEffect, useId, useMemo
|
|
2
|
+
import { createContext, useContext, useEffect, useId, useMemo } from "react";
|
|
3
3
|
|
|
4
4
|
// src/store.ts
|
|
5
5
|
function createInspectorStore() {
|
|
@@ -84,16 +84,22 @@ function createInspectorStore() {
|
|
|
84
84
|
// src/provider.tsx
|
|
85
85
|
import { jsx } from "react/jsx-runtime";
|
|
86
86
|
var InspectorContext = createContext(null);
|
|
87
|
+
var storeRef = { current: null };
|
|
88
|
+
function getStore() {
|
|
89
|
+
if (!storeRef.current) {
|
|
90
|
+
storeRef.current = createInspectorStore();
|
|
91
|
+
}
|
|
92
|
+
return storeRef.current;
|
|
93
|
+
}
|
|
87
94
|
function StateInspectorProvider({
|
|
88
95
|
enabled = true,
|
|
89
96
|
children
|
|
90
97
|
}) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
storeRef.current =
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return /* @__PURE__ */ jsx(InspectorContext.Provider, { value: storeRef.current, children });
|
|
98
|
+
const store = useMemo(() => getStore(), []);
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
storeRef.current.enabled = enabled;
|
|
101
|
+
}, [enabled]);
|
|
102
|
+
return /* @__PURE__ */ jsx(InspectorContext.Provider, { value: store, children });
|
|
97
103
|
}
|
|
98
104
|
function useInspectorStore() {
|
|
99
105
|
const ctx = useContext(InspectorContext);
|
|
@@ -122,7 +128,7 @@ function useInspectorComponent(label) {
|
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
// src/hooks.ts
|
|
125
|
-
import { useEffect as useEffect2, useId as useId2, useMemo as useMemo2, useRef
|
|
131
|
+
import { useEffect as useEffect2, useId as useId2, useMemo as useMemo2, useRef, useState } from "react";
|
|
126
132
|
function stableKey(input) {
|
|
127
133
|
return input.trim();
|
|
128
134
|
}
|
|
@@ -139,7 +145,7 @@ function useInspectableState(component, key, initial, meta) {
|
|
|
139
145
|
const componentId = component.id;
|
|
140
146
|
const stateKey = useMemo2(() => stableKey(key), [key]);
|
|
141
147
|
const [value, setValue] = useState(initial);
|
|
142
|
-
const setValueRef =
|
|
148
|
+
const setValueRef = useRef(() => {
|
|
143
149
|
});
|
|
144
150
|
setValueRef.current = (next) => {
|
|
145
151
|
setValue(next);
|
|
@@ -182,23 +188,71 @@ function useComponentLabel(label) {
|
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
// src/StateInspectorUI.tsx
|
|
185
|
-
import { useEffect as useEffect3, useMemo as useMemo3, useState as useState2 } from "react";
|
|
191
|
+
import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState2 } from "react";
|
|
186
192
|
import { createPortal } from "react-dom";
|
|
187
193
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
194
|
+
var isMac = navigator.platform.toUpperCase().includes("MAC");
|
|
188
195
|
function isOptionObject(opt) {
|
|
189
196
|
return typeof opt === "object" && opt !== null && "value" in opt;
|
|
190
197
|
}
|
|
191
198
|
function StateInspectorUI() {
|
|
192
199
|
const store = useInspectorStore();
|
|
200
|
+
const [query, setQuery] = useState2("");
|
|
193
201
|
const [open, setOpen] = useState2(false);
|
|
194
202
|
const [selectedId, setSelectedId] = useState2(null);
|
|
195
203
|
const [, force] = useState2(0);
|
|
204
|
+
const searchRef = useRef2(null);
|
|
205
|
+
const LS_KEY = "rsi:panel-pos";
|
|
206
|
+
const [pos, setPos] = useState2(() => {
|
|
207
|
+
try {
|
|
208
|
+
const raw = localStorage.getItem(LS_KEY);
|
|
209
|
+
return raw ? JSON.parse(raw) : { right: 16, bottom: 72 };
|
|
210
|
+
} catch {
|
|
211
|
+
return { right: 16, bottom: 72 };
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
useEffect3(() => {
|
|
215
|
+
try {
|
|
216
|
+
localStorage.setItem(LS_KEY, JSON.stringify(pos));
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
}, [pos]);
|
|
220
|
+
const SIZE_KEY = "rsi:panel-size";
|
|
221
|
+
const [size, setSize] = useState2(() => {
|
|
222
|
+
try {
|
|
223
|
+
const raw = localStorage.getItem(SIZE_KEY);
|
|
224
|
+
return raw ? JSON.parse(raw) : { width: 720, height: 420 };
|
|
225
|
+
} catch {
|
|
226
|
+
return { width: 720, height: 420 };
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
useEffect3(() => {
|
|
230
|
+
try {
|
|
231
|
+
localStorage.setItem(SIZE_KEY, JSON.stringify(size));
|
|
232
|
+
} catch {
|
|
233
|
+
}
|
|
234
|
+
}, [size]);
|
|
196
235
|
useEffect3(() => store.subscribe(() => force((x) => x + 1)), [store]);
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
236
|
+
const snapshot = useMemo3(() => store.getSnapshot(), [store]);
|
|
237
|
+
const components = useMemo3(
|
|
238
|
+
() => snapshot.components.filter((c) => c.mounted),
|
|
239
|
+
[snapshot.components]
|
|
240
|
+
);
|
|
241
|
+
const q = query.trim().toLowerCase();
|
|
242
|
+
const filtered = useMemo3(
|
|
243
|
+
() => q ? components.filter((c) => {
|
|
244
|
+
const labelHit = c.label.toLowerCase().includes(q);
|
|
245
|
+
const keyHit = c.stateKeys.some(
|
|
246
|
+
(k) => k.toLowerCase().includes(q)
|
|
247
|
+
);
|
|
248
|
+
return labelHit || keyHit;
|
|
249
|
+
}) : components,
|
|
250
|
+
[q, components]
|
|
251
|
+
);
|
|
200
252
|
useEffect3(() => {
|
|
201
|
-
if (!open)
|
|
253
|
+
if (!open) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
202
256
|
if (components.length === 0) {
|
|
203
257
|
setSelectedId(null);
|
|
204
258
|
return;
|
|
@@ -208,22 +262,56 @@ function StateInspectorUI() {
|
|
|
208
262
|
}
|
|
209
263
|
}, [open, components.length]);
|
|
210
264
|
useEffect3(() => {
|
|
211
|
-
if (!open)
|
|
265
|
+
if (!open) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
212
268
|
function onKey(e) {
|
|
213
269
|
if (e.key === "Escape") setOpen(false);
|
|
214
270
|
}
|
|
215
271
|
window.addEventListener("keydown", onKey);
|
|
216
272
|
return () => window.removeEventListener("keydown", onKey);
|
|
217
273
|
}, [open]);
|
|
274
|
+
useEffect3(() => {
|
|
275
|
+
function onKey(e) {
|
|
276
|
+
const mod = isMac ? e.metaKey : e.ctrlKey;
|
|
277
|
+
if (mod && e.shiftKey && e.key.toLowerCase() === "i") {
|
|
278
|
+
e.preventDefault();
|
|
279
|
+
setOpen((o) => !o);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (!open) return;
|
|
283
|
+
if (e.key === "Escape") {
|
|
284
|
+
setOpen(false);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (e.key === "/") {
|
|
288
|
+
e.preventDefault();
|
|
289
|
+
searchRef.current?.focus();
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
293
|
+
e.preventDefault();
|
|
294
|
+
const list = filtered;
|
|
295
|
+
if (!list.length) return;
|
|
296
|
+
const idx = list.findIndex((c) => c.id === selectedId);
|
|
297
|
+
const next = e.key === "ArrowDown" ? list[(Math.max(-1, idx) + 1) % list.length].id : list[idx <= 0 ? list.length - 1 : idx - 1].id;
|
|
298
|
+
setSelectedId(next);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
window.addEventListener("keydown", onKey);
|
|
302
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
303
|
+
}, [open, filtered, selectedId]);
|
|
218
304
|
const selected = useMemo3(() => {
|
|
219
305
|
if (!selectedId) return null;
|
|
220
306
|
return store.components.get(selectedId) ?? null;
|
|
221
|
-
}, [store, selectedId
|
|
307
|
+
}, [store, selectedId]);
|
|
308
|
+
if (!store.enabled) return null;
|
|
222
309
|
return createPortal(
|
|
223
310
|
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
224
311
|
/* @__PURE__ */ jsx2(
|
|
225
312
|
"button",
|
|
226
313
|
{
|
|
314
|
+
title: "State Inspector (\u2318\u21E7I / Ctrl\u21E7I)",
|
|
227
315
|
onClick: () => setOpen((o) => !o),
|
|
228
316
|
style: {
|
|
229
317
|
position: "fixed",
|
|
@@ -239,7 +327,6 @@ function StateInspectorUI() {
|
|
|
239
327
|
zIndex: 999999
|
|
240
328
|
},
|
|
241
329
|
"aria-label": "Toggle State Inspector",
|
|
242
|
-
title: "State Inspector",
|
|
243
330
|
children: "\u25CE"
|
|
244
331
|
}
|
|
245
332
|
),
|
|
@@ -248,11 +335,11 @@ function StateInspectorUI() {
|
|
|
248
335
|
{
|
|
249
336
|
style: {
|
|
250
337
|
position: "fixed",
|
|
251
|
-
right:
|
|
252
|
-
bottom:
|
|
253
|
-
width:
|
|
338
|
+
right: pos.right,
|
|
339
|
+
bottom: pos.bottom,
|
|
340
|
+
width: size.width,
|
|
254
341
|
maxWidth: "calc(100vw - 32px)",
|
|
255
|
-
height:
|
|
342
|
+
height: size.height,
|
|
256
343
|
maxHeight: "calc(100vh - 120px)",
|
|
257
344
|
background: "#1c1c1c",
|
|
258
345
|
color: "#fff",
|
|
@@ -264,12 +351,74 @@ function StateInspectorUI() {
|
|
|
264
351
|
overflow: "hidden"
|
|
265
352
|
},
|
|
266
353
|
children: [
|
|
267
|
-
/* @__PURE__ */
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
354
|
+
/* @__PURE__ */ jsx2(
|
|
355
|
+
"div",
|
|
356
|
+
{
|
|
357
|
+
onPointerDown: (e) => {
|
|
358
|
+
const startX = e.clientX;
|
|
359
|
+
const startY = e.clientY;
|
|
360
|
+
const start = size;
|
|
361
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
362
|
+
const onMove = (ev) => {
|
|
363
|
+
const dx = ev.clientX - startX;
|
|
364
|
+
const dy = ev.clientY - startY;
|
|
365
|
+
setSize({
|
|
366
|
+
width: Math.min(window.innerWidth - 16, Math.max(480, start.width + dx)),
|
|
367
|
+
height: Math.min(window.innerHeight - 120, Math.max(280, start.height + dy))
|
|
368
|
+
});
|
|
369
|
+
};
|
|
370
|
+
const onUp = () => {
|
|
371
|
+
window.removeEventListener("pointermove", onMove);
|
|
372
|
+
window.removeEventListener("pointerup", onUp);
|
|
373
|
+
};
|
|
374
|
+
window.addEventListener("pointermove", onMove);
|
|
375
|
+
window.addEventListener("pointerup", onUp);
|
|
376
|
+
},
|
|
377
|
+
style: {
|
|
378
|
+
position: "absolute",
|
|
379
|
+
right: 6,
|
|
380
|
+
bottom: 6,
|
|
381
|
+
width: 14,
|
|
382
|
+
height: 14,
|
|
383
|
+
borderRadius: 6,
|
|
384
|
+
border: "1px solid #333",
|
|
385
|
+
background: "#838383",
|
|
386
|
+
cursor: "nwse-resize"
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
),
|
|
390
|
+
/* @__PURE__ */ jsxs("div", { style: { borderRight: "1px solid #333", padding: 12, height: size.height, display: "flex", flexDirection: "column", boxSizing: "border-box" }, children: [
|
|
391
|
+
/* @__PURE__ */ jsxs(
|
|
392
|
+
"div",
|
|
393
|
+
{
|
|
394
|
+
style: { display: "flex", alignItems: "center", justifyContent: "space-between", cursor: "grab", userSelect: "none" },
|
|
395
|
+
onPointerDown: (e) => {
|
|
396
|
+
const startX = e.clientX;
|
|
397
|
+
const startY = e.clientY;
|
|
398
|
+
const start = pos;
|
|
399
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
400
|
+
const onMove = (ev) => {
|
|
401
|
+
const dx = ev.clientX - startX;
|
|
402
|
+
const dy = ev.clientY - startY;
|
|
403
|
+
setPos({
|
|
404
|
+
right: Math.max(8, start.right - dx),
|
|
405
|
+
bottom: Math.max(8, start.bottom - dy)
|
|
406
|
+
});
|
|
407
|
+
};
|
|
408
|
+
const onUp = () => {
|
|
409
|
+
window.removeEventListener("pointermove", onMove);
|
|
410
|
+
window.removeEventListener("pointerup", onUp);
|
|
411
|
+
};
|
|
412
|
+
window.addEventListener("pointermove", onMove);
|
|
413
|
+
window.addEventListener("pointerup", onUp);
|
|
414
|
+
},
|
|
415
|
+
children: [
|
|
416
|
+
/* @__PURE__ */ jsx2("h4", { style: { margin: 0 }, children: "Components" }),
|
|
417
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 12, opacity: 0.7 }, children: filtered.length })
|
|
418
|
+
]
|
|
419
|
+
}
|
|
420
|
+
),
|
|
421
|
+
/* @__PURE__ */ jsx2("div", { style: { marginTop: 10, display: "grid", gap: 8, overflow: "auto", flex: 1 }, children: filtered.map((c) => {
|
|
273
422
|
const active = c.id === selectedId;
|
|
274
423
|
return /* @__PURE__ */ jsxs(
|
|
275
424
|
"button",
|
|
@@ -296,7 +445,7 @@ function StateInspectorUI() {
|
|
|
296
445
|
);
|
|
297
446
|
}) })
|
|
298
447
|
] }),
|
|
299
|
-
/* @__PURE__ */ jsxs("div", { style: { padding: 12, overflow: "auto" }, children: [
|
|
448
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: 12, overflow: "auto", display: "flex", flexDirection: "column", boxSizing: "border-box" }, children: [
|
|
300
449
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
301
450
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
302
451
|
/* @__PURE__ */ jsx2("h4", { style: { margin: 0 }, children: "State" }),
|
|
@@ -312,12 +461,31 @@ function StateInspectorUI() {
|
|
|
312
461
|
border: "1px solid #333",
|
|
313
462
|
borderRadius: 10,
|
|
314
463
|
padding: "6px 10px",
|
|
315
|
-
cursor: "pointer"
|
|
464
|
+
cursor: "pointer",
|
|
465
|
+
fontSize: 12
|
|
316
466
|
},
|
|
317
467
|
children: "Close"
|
|
318
468
|
}
|
|
319
469
|
)
|
|
320
470
|
] }),
|
|
471
|
+
/* @__PURE__ */ jsx2(
|
|
472
|
+
"input",
|
|
473
|
+
{
|
|
474
|
+
value: query,
|
|
475
|
+
onChange: (e) => setQuery(e.target.value),
|
|
476
|
+
placeholder: "Search components / state keys\u2026",
|
|
477
|
+
ref: searchRef,
|
|
478
|
+
style: {
|
|
479
|
+
marginTop: 10,
|
|
480
|
+
padding: "8px 10px",
|
|
481
|
+
borderRadius: 10,
|
|
482
|
+
border: "1px solid #333",
|
|
483
|
+
background: "#111",
|
|
484
|
+
color: "#fff",
|
|
485
|
+
outline: "none"
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
),
|
|
321
489
|
/* @__PURE__ */ jsxs("div", { style: { marginTop: 12, display: "grid", gap: 10 }, children: [
|
|
322
490
|
selected && selected.states.size === 0 && /* @__PURE__ */ jsx2("div", { style: { fontSize: 13, opacity: 0.7 }, children: "This component has no inspectable state." }),
|
|
323
491
|
!selected && /* @__PURE__ */ jsx2("div", { style: { opacity: 0.7, fontSize: 13 }, children: "No component selected." }),
|
|
@@ -328,7 +496,8 @@ function StateInspectorUI() {
|
|
|
328
496
|
border: "1px solid #333",
|
|
329
497
|
borderRadius: 12,
|
|
330
498
|
padding: 10,
|
|
331
|
-
display: "
|
|
499
|
+
display: "flex",
|
|
500
|
+
flexDirection: "column",
|
|
332
501
|
gap: 8
|
|
333
502
|
},
|
|
334
503
|
children: [
|
|
@@ -383,7 +552,6 @@ function StateEditor({
|
|
|
383
552
|
value: current,
|
|
384
553
|
onChange: (e) => onChange(e.target.value),
|
|
385
554
|
style: {
|
|
386
|
-
width: "100%",
|
|
387
555
|
padding: "8px 10px",
|
|
388
556
|
borderRadius: 10,
|
|
389
557
|
border: "1px solid #333",
|
|
@@ -397,7 +565,7 @@ function StateEditor({
|
|
|
397
565
|
}
|
|
398
566
|
);
|
|
399
567
|
}
|
|
400
|
-
if (meta?.type === "number"
|
|
568
|
+
if (meta?.type === "number") {
|
|
401
569
|
return /* @__PURE__ */ jsx2(
|
|
402
570
|
"input",
|
|
403
571
|
{
|
|
@@ -408,7 +576,6 @@ function StateEditor({
|
|
|
408
576
|
step: meta?.step,
|
|
409
577
|
onChange: (e) => onChange(e.target.value === "" ? 0 : Number(e.target.value)),
|
|
410
578
|
style: {
|
|
411
|
-
width: "100%",
|
|
412
579
|
padding: "8px 10px",
|
|
413
580
|
borderRadius: 10,
|
|
414
581
|
border: "1px solid #333",
|
|
@@ -427,10 +594,9 @@ function StateEditor({
|
|
|
427
594
|
{
|
|
428
595
|
type: "text",
|
|
429
596
|
value: typeof value === "string" ? value : String(value ?? ""),
|
|
430
|
-
placeholder: meta?.placeholder,
|
|
597
|
+
placeholder: meta?.type === "text" ? meta.placeholder : void 0,
|
|
431
598
|
onChange: (e) => onChange(e.target.value),
|
|
432
599
|
style: {
|
|
433
|
-
width: "100%",
|
|
434
600
|
padding: "8px 10px",
|
|
435
601
|
borderRadius: 10,
|
|
436
602
|
border: "1px solid #333",
|
|
@@ -468,13 +634,12 @@ function JsonEditor({
|
|
|
468
634
|
const parsed = JSON.parse(next);
|
|
469
635
|
setError(null);
|
|
470
636
|
onValidJson(parsed);
|
|
471
|
-
} catch
|
|
637
|
+
} catch {
|
|
472
638
|
setError("Invalid JSON");
|
|
473
639
|
}
|
|
474
640
|
},
|
|
475
641
|
rows: 6,
|
|
476
642
|
style: {
|
|
477
|
-
width: "100%",
|
|
478
643
|
padding: "8px 10px",
|
|
479
644
|
borderRadius: 10,
|
|
480
645
|
border: "1px solid #333",
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.tsx","../src/store.ts","../src/hooks.ts","../src/StateInspectorUI.tsx"],"sourcesContent":["import React, { createContext, useContext, useEffect, useId, useMemo, useRef } from \"react\";\nimport { createInspectorStore, InspectorComponentRef, InspectorStore } from \"./store\";\n\nconst InspectorContext = createContext<InspectorStore | null>(null);\n\nexport function StateInspectorProvider({\n enabled = true,\n children,\n}: {\n enabled?: boolean;\n children: React.ReactNode;\n}) {\n const storeRef = useRef<InspectorStore>(null);\n\n if (!storeRef.current) {\n storeRef.current = createInspectorStore();\n }\n\n storeRef.current.enabled = enabled;\n\n return (\n <InspectorContext.Provider value={storeRef.current}>\n {children}\n </InspectorContext.Provider>\n );\n}\n\nexport function useInspectorStore(): InspectorStore {\n const ctx = useContext(InspectorContext);\n if (!ctx) {\n throw new Error(\"useInspectorStore must be used inside StateInspectorProvider\");\n }\n return ctx;\n}\n\nexport function useInspectorComponent(label?: string): InspectorComponentRef {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n\n store.registerComponent(componentId, label?.trim());\n return () => {\n store.unregisterComponent(componentId);\n };\n }, [store, componentId, label]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label?.trim();\n if (trimmed) store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n\n return useMemo(() => ({ id: componentId }), [componentId]);\n}\n","export type ComponentId = string;\n\nexport type InspectableMeta =\n | { type: \"boolean\" }\n | { type: \"text\"; placeholder?: string }\n | { type: \"number\"; min?: number; max?: number; step?: number }\n | { type: \"select\"; options: Array<string | { label: string; value: string }> }\n | { type: \"json\" }\n | { type: \"custom\"; renderId: string };\n\nexport interface InspectableStateEntry {\n key: string;\n value: unknown;\n setValue: (next: unknown) => void;\n meta?: InspectableMeta;\n}\n\nexport interface ComponentEntry {\n id: ComponentId;\n label: string;\n mounted: boolean;\n states: Map<string, InspectableStateEntry>;\n}\n\nexport interface InspectorSnapshot {\n enabled: boolean;\n components: Array<{\n id: ComponentId;\n label: string;\n mounted: boolean;\n stateKeys: string[];\n }>;\n}\n\ntype Listener = () => void;\n\nexport interface InspectorComponentRef {\n id: string;\n}\n\nexport interface InspectorStore {\n enabled: boolean;\n\n // internal registry\n components: Map<ComponentId, ComponentEntry>;\n\n // subscriptions\n subscribe: (listener: Listener) => () => void;\n getSnapshot: () => InspectorSnapshot;\n\n // component lifecycle\n registerComponent: (id: ComponentId, label?: string) => void;\n setComponentLabel: (id: ComponentId, label: string) => void;\n unregisterComponent: (id: ComponentId) => void;\n\n // state lifecycle\n upsertState: (\n componentId: ComponentId,\n entry: InspectableStateEntry,\n ) => void;\n\n updateStateValue: (componentId: ComponentId, key: string, value: unknown) => void;\n removeState: (componentId: ComponentId, key: string) => void;\n}\n\nexport function createInspectorStore(): InspectorStore {\n const components = new Map<ComponentId, ComponentEntry>();\n const listeners = new Set<Listener>();\n\n function emit() {\n for (const l of listeners) l();\n }\n\n function getOrCreateComponent(id: ComponentId): ComponentEntry {\n const existing = components.get(id);\n if (existing) return existing;\n\n const created: ComponentEntry = {\n id,\n label: \"Unknown\",\n mounted: true,\n states: new Map(),\n };\n components.set(id, created);\n return created;\n }\n\n const store: InspectorStore = {\n enabled: true,\n components,\n\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n\n getSnapshot() {\n return {\n enabled: store.enabled,\n components: Array.from(components.values()).map((c) => ({\n id: c.id,\n label: c.label,\n mounted: c.mounted,\n stateKeys: Array.from(c.states.keys()),\n })),\n };\n },\n\n registerComponent(id, label) {\n const c = getOrCreateComponent(id);\n c.mounted = true;\n if (label && label.trim()) c.label = label.trim();\n emit();\n },\n\n setComponentLabel(id, label) {\n const c = getOrCreateComponent(id);\n c.label = label.trim() || \"Unknown\";\n emit();\n },\n\n unregisterComponent(id) {\n const c = components.get(id);\n if (!c) return;\n\n // StrictMode double-unmount safe:\n // we mark as unmounted; UI can choose to hide unmounted entries.\n c.mounted = false;\n\n // Optional: immediate cleanup if you prefer:\n // components.delete(id);\n\n emit();\n },\n\n upsertState(componentId, entry) {\n const c = getOrCreateComponent(componentId);\n c.states.set(entry.key, entry);\n emit();\n },\n\n updateStateValue(componentId, key, value) {\n const c = components.get(componentId);\n if (!c) return;\n const s = c.states.get(key);\n if (!s) return;\n s.value = value;\n emit();\n },\n\n removeState(componentId, key) {\n const c = components.get(componentId);\n if (!c) return;\n if (!c.states.has(key)) return;\n c.states.delete(key);\n emit();\n },\n };\n\n return store;\n}\n","import React, { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { useInspectorStore } from \"./provider\";\nimport type { InspectableMeta, InspectorComponentRef } from \"./store\";\n\nfunction stableKey(input: string): string {\n return input.trim();\n}\n\nfunction inferMeta(value: unknown): InspectableMeta | undefined {\n const t = typeof value;\n if (t === \"boolean\") return { type: \"boolean\" };\n if (t === \"number\") return { type: \"number\" };\n if (t === \"string\") return { type: \"text\" };\n if (value && t === \"object\") return { type: \"json\" };\n return undefined;\n}\n\n/**\n * Registers a piece of state to the inspector registry.\n * Opt-in by replacing useState with useInspectableState.\n */\nexport function useInspectableState<T>(\n component: InspectorComponentRef,\n key: string,\n initial: T | (() => T),\n meta?: InspectableMeta,\n): [T, React.Dispatch<React.SetStateAction<T>>] {\n const store = useInspectorStore();\n const componentId = component.id;\n\n const stateKey = useMemo(() => stableKey(key), [key]);\n\n const [value, setValue] = useState<T>(initial);\n\n // Keep latest setter stable for registry consumers\n const setValueRef = useRef<(next: unknown) => void>(() => {});\n setValueRef.current = (next: unknown) => {\n setValue(next as T);\n };\n\n // Register component + state entry\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n\n return () => {\n store.removeState(componentId, stateKey);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, componentId, stateKey]);\n\n // Sync updates on each render when value/meta changes\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n }, [store, componentId, stateKey, value, meta]);\n\n return [value, setValue];\n}\n\n/**\n * Optional helper to give the current component instance a human label.\n */\nexport function useComponentLabel(label: string) {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label.trim();\n if (!trimmed) return;\n store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useInspectorStore } from \"./provider\";\nuseInspectorStore\n\nfunction isOptionObject(\n opt: string | { label: string; value: string },\n): opt is { label: string; value: string } {\n return typeof opt === \"object\" && opt !== null && \"value\" in opt;\n}\n\nexport function StateInspectorUI() {\n const store = useInspectorStore();\n\n const [open, setOpen] = useState(false);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [, force] = useState(0);\n\n useEffect(() => store.subscribe(() => force((x) => x + 1)), [store]);\n\n if (!store.enabled) return null;\n\n const snapshot = store.getSnapshot();\n const components = snapshot.components.filter((c) => c.mounted);\n\n // Keep a valid selection\n useEffect(() => {\n if (!open) return;\n\n if (components.length === 0) {\n setSelectedId(null);\n return;\n }\n\n if (!selectedId || !components.some((c) => c.id === selectedId)) {\n setSelectedId(components[0]!.id);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, components.length]);\n\n useEffect(() => {\n if (!open) return;\n\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") setOpen(false);\n }\n\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open]);\n\n const selected = useMemo(() => {\n if (!selectedId) return null;\n return store.components.get(selectedId) ?? null;\n }, [store, selectedId, snapshot.components.length]);\n\n return createPortal(\n <>\n {/* Floating Button */}\n <button\n onClick={() => setOpen((o) => !o)}\n style={{\n position: \"fixed\",\n right: 16,\n bottom: 16,\n width: 44,\n height: 44,\n borderRadius: 22,\n border: \"none\",\n background: \"#111\",\n color: \"#fff\",\n cursor: \"pointer\",\n zIndex: 999999,\n }}\n aria-label=\"Toggle State Inspector\"\n title=\"State Inspector\"\n >\n ◎\n </button>\n\n {/* Floating Card */}\n {open && (\n <div\n style={{\n position: \"fixed\",\n right: 16,\n bottom: 72,\n width: 720,\n maxWidth: \"calc(100vw - 32px)\",\n height: 420,\n maxHeight: \"calc(100vh - 120px)\",\n background: \"#1c1c1c\",\n color: \"#fff\",\n borderRadius: 12,\n border: \"1px solid #333\",\n zIndex: 999999,\n display: \"grid\",\n gridTemplateColumns: \"280px 1fr\",\n overflow: \"hidden\",\n }}\n >\n {/* Left: component list */}\n <div style={{ borderRight: \"1px solid #333\", padding: 12, height: \"420px\", display: \"flex\", flexDirection: \"column\", boxSizing: \"border-box\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <h4 style={{ margin: 0 }}>Components</h4>\n <span style={{ fontSize: 12, opacity: 0.7 }}>{components.length}</span>\n </div>\n\n <div style={{ marginTop: 10, display: \"grid\", gap: 8, overflow: \"auto\", flex: 1 }}>\n {components.map((c) => {\n const active = c.id === selectedId;\n return (\n <button\n key={c.id}\n onClick={() => setSelectedId(c.id)}\n style={{\n textAlign: \"left\",\n background: active ? \"#2a2a2a\" : \"transparent\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: 10,\n color: \"#fff\",\n cursor: \"pointer\",\n }}\n >\n <div style={{ fontWeight: 700 }}>{c.label}</div>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n states: {c.stateKeys.length ? c.stateKeys.length : 0}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Right: state editors */}\n <div style={{ padding: 12, overflow: \"auto\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <div>\n <h4 style={{ margin: 0 }}>State</h4>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n {selected ? selected.label : \"No selection\"}\n </div>\n </div>\n\n <button\n onClick={() => setOpen(false)}\n style={{\n background: \"transparent\",\n color: \"#fff\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: \"6px 10px\",\n cursor: \"pointer\",\n }}\n >\n Close\n </button>\n </div>\n\n <div style={{ marginTop: 12, display: \"grid\", gap: 10 }}>\n {selected && selected.states.size === 0 && (\n <div style={{ fontSize: 13, opacity: 0.7 }}>\n This component has no inspectable state.\n </div>\n )}\n\n {!selected && (\n <div style={{ opacity: 0.7, fontSize: 13 }}>\n No component selected.\n </div>\n )}\n\n {selected &&\n Array.from(selected.states.values()).map((s) => (\n <div\n key={s.key}\n style={{\n border: \"1px solid #333\",\n borderRadius: 12,\n padding: 10,\n display: \"grid\",\n gap: 8,\n }}\n >\n <div style={{ display: \"flex\", justifyContent: \"space-between\", gap: 12 }}>\n <div style={{ fontWeight: 700 }}>{s.key}</div>\n <div style={{ fontSize: 12, opacity: 0.6 }}>{s.meta?.type ?? \"auto\"}</div>\n </div>\n\n <StateEditor\n value={s.value}\n meta={s.meta}\n onChange={(next) => s.setValue(next)}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n </>,\n document.body,\n );\n}\n\nfunction StateEditor({\n value,\n meta,\n onChange,\n}: {\n value: unknown;\n meta: any;\n onChange: (next: unknown) => void;\n}) {\n // boolean\n if (meta?.type === \"boolean\" || typeof value === \"boolean\") {\n return (\n <label style={{ display: \"flex\", gap: 10, alignItems: \"center\" }}>\n <input\n type=\"checkbox\"\n checked={Boolean(value)}\n onChange={(e) => onChange(e.target.checked)}\n />\n <span style={{ fontSize: 13, opacity: 0.8 }}>{String(Boolean(value))}</span>\n </label>\n );\n }\n\n // select\n if (meta?.type === \"select\" && Array.isArray(meta.options)) {\n const current = typeof value === \"string\" ? value : String(value ?? \"\");\n return (\n <select\n value={current}\n onChange={(e) => onChange(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n >\n {meta.options.map((opt: any) => {\n const o = isOptionObject(opt) ? opt : { label: String(opt), value: String(opt) };\n return (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n );\n })}\n </select>\n );\n }\n\n // number\n if (meta?.type === \"number\" || typeof value === \"number\") {\n return (\n <input\n type=\"number\"\n value={typeof value === \"number\" ? value : Number(value ?? 0)}\n min={meta?.min}\n max={meta?.max}\n step={meta?.step}\n onChange={(e) => onChange(e.target.value === \"\" ? 0 : Number(e.target.value))}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n }\n\n // json\n if (meta?.type === \"json\" || (value && typeof value === \"object\")) {\n const text = safeStringify(value);\n return (\n <JsonEditor initial={text} onValidJson={(obj) => onChange(obj)} />\n );\n }\n\n // text (default)\n return (\n <input\n type=\"text\"\n value={typeof value === \"string\" ? value : String(value ?? \"\")}\n placeholder={meta?.placeholder}\n onChange={(e) => onChange(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n}\n\nfunction safeStringify(v: unknown) {\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n\nfunction JsonEditor({\n initial,\n onValidJson,\n}: {\n initial: string;\n onValidJson: (obj: unknown) => void;\n}) {\n const [raw, setRaw] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n setRaw(initial);\n }, [initial]);\n\n return (\n <div style={{ display: \"grid\", gap: 6 }}>\n <textarea\n value={raw}\n onChange={(e) => {\n const next = e.target.value;\n setRaw(next);\n\n try {\n const parsed = JSON.parse(next);\n setError(null);\n onValidJson(parsed);\n } catch (err: any) {\n setError(\"Invalid JSON\");\n }\n }}\n rows={6}\n style={{\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace\",\n fontSize: 12,\n }}\n />\n {error && <div style={{ fontSize: 12, color: \"#ff6b6b\" }}>{error}</div>}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useId","useMemo","useRef","useMemo","useRef","useEffect","useId","useEffect","useMemo","useState","jsx","useState","useEffect","useMemo","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider.tsx","../src/store.ts","../src/hooks.ts","../src/StateInspectorUI.tsx"],"sourcesContent":["import React, { createContext, useContext, useEffect, useId, useMemo } from \"react\";\nimport { createInspectorStore, InspectorComponentRef, InspectorStore } from \"./store\";\n\nconst InspectorContext = createContext<InspectorStore | null>(null);\n\nconst storeRef = { current: null as InspectorStore | null };\n\nfunction getStore(): InspectorStore {\n if (!storeRef.current) {\n storeRef.current = createInspectorStore();\n }\n return storeRef.current;\n}\n\nexport function StateInspectorProvider({\n enabled = true,\n children,\n}: {\n enabled?: boolean;\n children: React.ReactNode;\n}) {\n const store = useMemo(() => getStore(), []);\n\n useEffect(() => {\n storeRef.current!.enabled = enabled;\n }, [enabled]);\n\n return (\n <InspectorContext.Provider value={store}>\n {children}\n </InspectorContext.Provider>\n );\n}\n\nexport function useInspectorStore(): InspectorStore {\n const ctx = useContext(InspectorContext);\n if (!ctx) {\n throw new Error(\"useInspectorStore must be used inside StateInspectorProvider\");\n }\n return ctx;\n}\n\nexport function useInspectorComponent(label?: string): InspectorComponentRef {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n\n store.registerComponent(componentId, label?.trim());\n return () => {\n store.unregisterComponent(componentId);\n };\n }, [store, componentId, label]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label?.trim();\n if (trimmed) store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n\n return useMemo(() => ({ id: componentId }), [componentId]);\n}\n","export type ComponentId = string;\n\nexport type InspectableMeta =\n | { type: \"boolean\" }\n | { type: \"text\"; placeholder?: string }\n | { type: \"number\"; min?: number; max?: number; step?: number }\n | { type: \"select\"; options: Array<string | { label: string; value: string }> }\n | { type: \"json\" }\n | { type: \"custom\"; renderId: string };\n\nexport interface InspectableStateEntry {\n key: string;\n value: unknown;\n setValue: (next: unknown) => void;\n meta?: InspectableMeta;\n}\n\nexport interface ComponentEntry {\n id: ComponentId;\n label: string;\n mounted: boolean;\n states: Map<string, InspectableStateEntry>;\n}\n\nexport interface InspectorSnapshot {\n enabled: boolean;\n components: Array<{\n id: ComponentId;\n label: string;\n mounted: boolean;\n stateKeys: string[];\n }>;\n}\n\ntype Listener = () => void;\n\nexport interface InspectorComponentRef {\n id: string;\n}\n\nexport interface InspectorStore {\n enabled: boolean;\n\n // internal registry\n components: Map<ComponentId, ComponentEntry>;\n\n // subscriptions\n subscribe: (listener: Listener) => () => void;\n getSnapshot: () => InspectorSnapshot;\n\n // component lifecycle\n registerComponent: (id: ComponentId, label?: string) => void;\n setComponentLabel: (id: ComponentId, label: string) => void;\n unregisterComponent: (id: ComponentId) => void;\n\n // state lifecycle\n upsertState: (\n componentId: ComponentId,\n entry: InspectableStateEntry,\n ) => void;\n\n updateStateValue: (componentId: ComponentId, key: string, value: unknown) => void;\n removeState: (componentId: ComponentId, key: string) => void;\n}\n\nexport function createInspectorStore(): InspectorStore {\n const components = new Map<ComponentId, ComponentEntry>();\n const listeners = new Set<Listener>();\n\n function emit() {\n for (const l of listeners) l();\n }\n\n function getOrCreateComponent(id: ComponentId): ComponentEntry {\n const existing = components.get(id);\n if (existing) return existing;\n\n const created: ComponentEntry = {\n id,\n label: \"Unknown\",\n mounted: true,\n states: new Map(),\n };\n components.set(id, created);\n return created;\n }\n\n const store: InspectorStore = {\n enabled: true,\n components,\n\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n\n getSnapshot() {\n return {\n enabled: store.enabled,\n components: Array.from(components.values()).map((c) => ({\n id: c.id,\n label: c.label,\n mounted: c.mounted,\n stateKeys: Array.from(c.states.keys()),\n })),\n };\n },\n\n registerComponent(id, label) {\n const c = getOrCreateComponent(id);\n c.mounted = true;\n if (label && label.trim()) c.label = label.trim();\n emit();\n },\n\n setComponentLabel(id, label) {\n const c = getOrCreateComponent(id);\n c.label = label.trim() || \"Unknown\";\n emit();\n },\n\n unregisterComponent(id) {\n const c = components.get(id);\n if (!c) return;\n\n // StrictMode double-unmount safe:\n // we mark as unmounted; UI can choose to hide unmounted entries.\n c.mounted = false;\n\n // Optional: immediate cleanup if you prefer:\n // components.delete(id);\n\n emit();\n },\n\n upsertState(componentId, entry) {\n const c = getOrCreateComponent(componentId);\n c.states.set(entry.key, entry);\n emit();\n },\n\n updateStateValue(componentId, key, value) {\n const c = components.get(componentId);\n if (!c) return;\n const s = c.states.get(key);\n if (!s) return;\n s.value = value;\n emit();\n },\n\n removeState(componentId, key) {\n const c = components.get(componentId);\n if (!c) return;\n if (!c.states.has(key)) return;\n c.states.delete(key);\n emit();\n },\n };\n\n return store;\n}\n","import React, { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { useInspectorStore } from \"./provider\";\nimport type { InspectableMeta, InspectorComponentRef } from \"./store\";\n\nfunction stableKey(input: string): string {\n return input.trim();\n}\n\nfunction inferMeta(value: unknown): InspectableMeta | undefined {\n const t = typeof value;\n if (t === \"boolean\") return { type: \"boolean\" };\n if (t === \"number\") return { type: \"number\" };\n if (t === \"string\") return { type: \"text\" };\n if (value && t === \"object\") return { type: \"json\" };\n return undefined;\n}\n\n/**\n * Registers a piece of state to the inspector registry.\n * Opt-in by replacing useState with useInspectableState.\n */\nexport function useInspectableState<T>(\n component: InspectorComponentRef,\n key: string,\n initial: T | (() => T),\n meta?: InspectableMeta,\n): [T, React.Dispatch<React.SetStateAction<T>>] {\n const store = useInspectorStore();\n const componentId = component.id;\n\n const stateKey = useMemo(() => stableKey(key), [key]);\n\n const [value, setValue] = useState<T>(initial);\n\n // Keep latest setter stable for registry consumers\n const setValueRef = useRef<(next: unknown) => void>(() => {});\n setValueRef.current = (next: unknown) => {\n setValue(next as T);\n };\n\n // Register component + state entry\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n\n return () => {\n store.removeState(componentId, stateKey);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, componentId, stateKey]);\n\n // Sync updates on each render when value/meta changes\n useEffect(() => {\n if (!store.enabled) return;\n\n const resolvedMeta = meta ?? inferMeta(value);\n store.upsertState(componentId, {\n key: stateKey,\n value,\n setValue: (next) => setValueRef.current(next),\n ...(resolvedMeta !== undefined && { meta: resolvedMeta }),\n });\n }, [store, componentId, stateKey, value, meta]);\n\n return [value, setValue];\n}\n\n/**\n * Optional helper to give the current component instance a human label.\n */\nexport function useComponentLabel(label: string) {\n const store = useInspectorStore();\n const reactId = useId();\n const componentId = useMemo(() => `c_${reactId}`, [reactId]);\n\n useEffect(() => {\n if (!store.enabled) return;\n const trimmed = label.trim();\n if (!trimmed) return;\n store.setComponentLabel(componentId, trimmed);\n }, [store, componentId, label]);\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useInspectorStore } from \"./provider\";\nimport { InspectableMeta } from \"./store\";\nconst isMac = navigator.platform.toUpperCase().includes(\"MAC\");\n\nfunction isOptionObject(\n opt: string | { label: string; value: string },\n): opt is { label: string; value: string } {\n return typeof opt === \"object\" && opt !== null && \"value\" in opt;\n}\n\nexport function StateInspectorUI() {\n const store = useInspectorStore();\n const [query, setQuery] = useState<string>(\"\");\n\n const [open, setOpen] = useState(false);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [, force] = useState(0);\n\n const searchRef = useRef<HTMLInputElement | null>(null);\n\n const LS_KEY = \"rsi:panel-pos\";\n const [pos, setPos] = useState<{ right: number; bottom: number }>(() => {\n try {\n const raw = localStorage.getItem(LS_KEY);\n return raw ? JSON.parse(raw) : { right: 16, bottom: 72 };\n } catch {\n // Fallback to default position if localStorage is unavailable\n return { right: 16, bottom: 72 };\n }\n });\n\n useEffect(() => {\n try {\n localStorage.setItem(LS_KEY, JSON.stringify(pos));\n } catch {\n // Silently fail if localStorage is unavailable\n }\n }, [pos]);\n\n const SIZE_KEY = \"rsi:panel-size\";\n const [size, setSize] = useState<{ width: number; height: number }>(() => {\n try {\n const raw = localStorage.getItem(SIZE_KEY);\n return raw ? JSON.parse(raw) : { width: 720, height: 420 };\n } catch {\n // Fallback to default size if localStorage is unavailable\n return { width: 720, height: 420 };\n }\n });\n\n useEffect(() => {\n try {\n localStorage.setItem(SIZE_KEY, JSON.stringify(size));\n } catch {\n // Silently fail if localStorage is unavailable\n }\n }, [size]);\n\n useEffect(() => store.subscribe(() => force((x) => x + 1)), [store]);\n\n const snapshot = useMemo(() => store.getSnapshot(), [store]);\n const components = useMemo(\n () => snapshot.components.filter((c) => c.mounted),\n [snapshot.components]\n );\n\n const q = query.trim().toLowerCase();\n\n const filtered = useMemo(\n () =>\n q\n ? components.filter((c) => {\n const labelHit = c.label.toLowerCase().includes(q);\n const keyHit = c.stateKeys.some((k) =>\n k.toLowerCase().includes(q)\n );\n return labelHit || keyHit;\n })\n : components,\n [q, components]\n );\n\n // Keep a valid selection\n useEffect(() => {\n if (!open) {\n return;\n }\n\n if (components.length === 0) {\n setSelectedId(null);\n return;\n }\n\n if (!selectedId || !components.some((c) => c.id === selectedId)) {\n setSelectedId(components[0]!.id);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, components.length]);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") setOpen(false);\n }\n\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open]);\n\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n const mod = isMac ? e.metaKey : e.ctrlKey;\n\n // Cmd/Ctrl + Shift + I → toggle inspector\n if (mod && e.shiftKey && e.key.toLowerCase() === \"i\") {\n e.preventDefault();\n setOpen((o) => !o);\n return;\n }\n\n if (!open) return;\n\n // Esc → close\n if (e.key === \"Escape\") {\n setOpen(false);\n return;\n }\n\n // \"/\" → focus search\n if (e.key === \"/\") {\n e.preventDefault();\n searchRef.current?.focus();\n return;\n }\n\n // Arrow navigation\n if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n const list = filtered;\n if (!list.length) return;\n\n const idx = list.findIndex((c) => c.id === selectedId);\n const next =\n e.key === \"ArrowDown\"\n ? list[(Math.max(-1, idx) + 1) % list.length]!.id\n : list[(idx <= 0 ? list.length - 1 : idx - 1)]!.id;\n\n setSelectedId(next);\n }\n }\n\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open, filtered, selectedId]);\n\n const selected = useMemo(() => {\n if (!selectedId) return null;\n return store.components.get(selectedId) ?? null;\n }, [store, selectedId]);\n\n if (!store.enabled) return null;\n\n return createPortal(\n <>\n {/* Floating Button */}\n <button\n title=\"State Inspector (⌘⇧I / Ctrl⇧I)\"\n onClick={() => setOpen((o) => !o)}\n style={{\n position: \"fixed\",\n right: 16,\n bottom: 16,\n width: 44,\n height: 44,\n borderRadius: 22,\n border: \"none\",\n background: \"#111\",\n color: \"#fff\",\n cursor: \"pointer\",\n zIndex: 999999,\n }}\n aria-label=\"Toggle State Inspector\"\n >\n ◎\n </button>\n\n {/* Floating Card */}\n {open && (\n <div\n style={{\n position: \"fixed\",\n right: pos.right,\n bottom: pos.bottom,\n width: size.width,\n maxWidth: \"calc(100vw - 32px)\",\n height: size.height,\n maxHeight: \"calc(100vh - 120px)\",\n background: \"#1c1c1c\",\n color: \"#fff\",\n borderRadius: 12,\n border: \"1px solid #333\",\n zIndex: 999999,\n display: \"grid\",\n gridTemplateColumns: \"280px 1fr\",\n overflow: \"hidden\",\n }}\n >\n {/* Resize Handle */}\n <div\n onPointerDown={(e) => {\n const startX = e.clientX;\n const startY = e.clientY;\n const start = size;\n\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const dx = ev.clientX - startX;\n const dy = ev.clientY - startY;\n setSize({\n width: Math.min(window.innerWidth - 16, Math.max(480, start.width + dx)),\n height: Math.min(window.innerHeight - 120, Math.max(280, start.height + dy)),\n });\n };\n\n const onUp = () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n };\n\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }}\n style={{\n position: \"absolute\",\n right: 6,\n bottom: 6,\n width: 14,\n height: 14,\n borderRadius: 6,\n border: \"1px solid #333\",\n background: \"#838383\",\n cursor: \"nwse-resize\",\n }}\n />\n\n {/* Left: component list */}\n <div style={{ borderRight: \"1px solid #333\", padding: 12, height: size.height, display: \"flex\", flexDirection: \"column\", boxSizing: \"border-box\" }}>\n <div \n style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", cursor: \"grab\", userSelect: \"none\" }}\n onPointerDown={(e) => {\n const startX = e.clientX;\n const startY = e.clientY;\n const start = pos;\n\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const dx = ev.clientX - startX;\n const dy = ev.clientY - startY;\n setPos({\n right: Math.max(8, start.right - dx),\n bottom: Math.max(8, start.bottom - dy),\n });\n };\n\n const onUp = () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n };\n\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }}\n >\n <h4 style={{ margin: 0 }}>Components</h4>\n <span style={{ fontSize: 12, opacity: 0.7 }}>{filtered.length}</span>\n </div>\n\n <div style={{ marginTop: 10, display: \"grid\", gap: 8, overflow: \"auto\", flex: 1 }}>\n {filtered.map((c) => {\n const active = c.id === selectedId;\n return (\n <button\n key={c.id}\n onClick={() => setSelectedId(c.id)}\n style={{\n textAlign: \"left\",\n background: active ? \"#2a2a2a\" : \"transparent\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: 10,\n color: \"#fff\",\n cursor: \"pointer\",\n }}\n >\n <div style={{ fontWeight: 700 }}>{c.label}</div>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n states: {c.stateKeys.length ? c.stateKeys.length : 0}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Right: state editors */}\n <div style={{ padding: 12, overflow: \"auto\", display: \"flex\", flexDirection: \"column\", boxSizing: \"border-box\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <div>\n <h4 style={{ margin: 0 }}>State</h4>\n <div style={{ fontSize: 12, opacity: 0.7 }}>\n {selected ? selected.label : \"No selection\"}\n </div>\n </div>\n\n <button\n onClick={() => setOpen(false)}\n style={{\n background: \"transparent\",\n color: \"#fff\",\n border: \"1px solid #333\",\n borderRadius: 10,\n padding: \"6px 10px\",\n cursor: \"pointer\",\n fontSize: 12,\n }}\n >\n Close\n </button>\n </div>\n\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search components / state keys…\"\n ref={searchRef}\n style={{\n marginTop: 10,\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n outline: \"none\",\n }}\n />\n\n <div style={{ marginTop: 12, display: \"grid\", gap: 10 }}>\n {selected && selected.states.size === 0 && (\n <div style={{ fontSize: 13, opacity: 0.7 }}>\n This component has no inspectable state.\n </div>\n )}\n\n {!selected && (\n <div style={{ opacity: 0.7, fontSize: 13 }}>\n No component selected.\n </div>\n )}\n\n {selected &&\n Array.from(selected.states.values()).map((s) => (\n <div\n key={s.key}\n style={{\n border: \"1px solid #333\",\n borderRadius: 12,\n padding: 10,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8\n }}\n >\n <div style={{ display: \"flex\", justifyContent: \"space-between\", gap: 12 }}>\n <div style={{ fontWeight: 700 }}>{s.key}</div>\n <div style={{ fontSize: 12, opacity: 0.6 }}>{s.meta?.type ?? \"auto\"}</div>\n </div>\n\n <StateEditor\n value={s.value}\n meta={s.meta}\n onChange={(next) => s.setValue(next)}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n </>,\n document.body,\n );\n}\n\nfunction StateEditor({\n value,\n meta,\n onChange,\n}: {\n value: unknown;\n meta: InspectableMeta | undefined;\n onChange: (next: unknown) => void;\n}) {\n // boolean\n if (meta?.type === \"boolean\" || typeof value === \"boolean\") {\n return (\n <label style={{ display: \"flex\", gap: 10, alignItems: \"center\" }}>\n <input\n type=\"checkbox\"\n checked={Boolean(value)}\n onChange={(e) => onChange(e.target.checked)}\n />\n <span style={{ fontSize: 13, opacity: 0.8 }}>{String(Boolean(value))}</span>\n </label>\n );\n }\n\n // select\n if (meta?.type === \"select\" && Array.isArray(meta.options)) {\n const current = typeof value === \"string\" ? value : String(value ?? \"\");\n return (\n <select\n value={current}\n onChange={(e) => onChange(e.target.value)}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n >\n {meta.options.map((opt: string | { label: string; value: string }) => {\n const o = isOptionObject(opt) ? opt : { label: String(opt), value: String(opt) };\n return (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n );\n })}\n </select>\n );\n }\n\n // number\n if (meta?.type === \"number\") {\n return (\n <input\n type=\"number\"\n value={typeof value === \"number\" ? value : Number(value ?? 0)}\n min={meta?.min}\n max={meta?.max}\n step={meta?.step}\n onChange={(e) => onChange(e.target.value === \"\" ? 0 : Number(e.target.value))}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n }\n\n // json\n if (meta?.type === \"json\" || (value && typeof value === \"object\")) {\n const text = safeStringify(value);\n return (\n <JsonEditor initial={text} onValidJson={(obj) => onChange(obj)} />\n );\n }\n\n // text (default)\n return (\n <input\n type=\"text\"\n value={typeof value === \"string\" ? value : String(value ?? \"\")}\n placeholder={meta?.type === \"text\" ? meta.placeholder : undefined}\n onChange={(e) => onChange(e.target.value)}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n }}\n />\n );\n}\n\nfunction safeStringify(v: unknown) {\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n\nfunction JsonEditor({\n initial,\n onValidJson,\n}: {\n initial: string;\n onValidJson: (obj: unknown) => void;\n}) {\n const [raw, setRaw] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n setRaw(initial);\n }, [initial]);\n\n return (\n <div style={{ display: \"grid\", gap: 6 }}>\n <textarea\n value={raw}\n onChange={(e) => {\n const next = e.target.value;\n setRaw(next);\n\n try {\n const parsed = JSON.parse(next);\n setError(null);\n onValidJson(parsed);\n } catch {\n setError(\"Invalid JSON\");\n }\n }}\n rows={6}\n style={{\n padding: \"8px 10px\",\n borderRadius: 10,\n border: \"1px solid #333\",\n background: \"#111\",\n color: \"#fff\",\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace\",\n fontSize: 12,\n }}\n />\n {error && <div style={{ fontSize: 12, color: \"#ff6b6b\" }}>{error}</div>}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useId","useMemo","useMemo","useEffect","useId","useEffect","useMemo","useRef","useState","jsx","useState","useRef","useEffect","useMemo"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-state-inspector-devtools",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsup",
|
|
29
|
-
"typecheck": "
|
|
29
|
+
"typecheck": "pnpm -r typecheck",
|
|
30
30
|
"lint": "eslint .",
|
|
31
|
-
"format": "prettier . --check"
|
|
31
|
+
"format": "prettier . --check",
|
|
32
|
+
"format:write": "prettier . --write"
|
|
32
33
|
}
|
|
33
34
|
}
|