react-state-inspector-devtools 1.1.22 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +63 -18
- package/dist/index.d.ts +63 -18
- package/dist/index.js +467 -166
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +451 -151
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
StateInspectorProvider: () => StateInspectorProvider,
|
|
24
24
|
StateInspectorUI: () => StateInspectorUI,
|
|
25
25
|
createInspectorStore: () => createInspectorStore,
|
|
26
|
+
inferMeta: () => inferMeta,
|
|
26
27
|
useComponentLabel: () => useComponentLabel,
|
|
27
28
|
useInspectableState: () => useInspectableState,
|
|
28
29
|
useInspectorComponent: () => useInspectorComponent,
|
|
@@ -53,33 +54,37 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
// src/index.css
|
|
56
|
-
styleInject('@import "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";\n[data-rsi-root],\n[data-rsi-root] *,\n[data-rsi-root] *::before,\n[data-rsi-root] *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0;\n font-family:\n "Inter",\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n "Helvetica Neue",\n sans-serif;\n font-size: 14px;\n font-weight: 400;\n font-style: normal;\n font-variant: normal;\n line-height: 1.5;\n letter-spacing: normal;\n text-align: left;\n text-decoration: none;\n text-indent: 0;\n text-shadow: none;\n text-transform: none;\n word-spacing: normal;\n white-space: normal;\n background: transparent;\n color: inherit;\n outline: none;\n vertical-align: baseline;\n visibility: visible;\n opacity: 1;\n transform: none;\n transform-origin: 50% 50% 0;\n animation: none;\n transition: none;\n list-style: none;\n border-collapse: collapse;\n border-spacing: 0;\n float: none;\n clear: none;\n cursor: auto;\n}\n[data-rsi-root] {\n all: initial;\n font-family:\n "Inter",\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n "Helvetica Neue",\n sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #fff;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n}\n[data-rsi-floating-button] {\n all: initial;\n font-family:\n "Inter",\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n "Helvetica Neue",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n[data-rsi-root] button {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n cursor: pointer;\n background: transparent;\n border: none;\n padding: 0;\n margin: 0;\n}\n[data-rsi-root] input,\n[data-rsi-root] textarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n background: transparent;\n border: none;\n outline: none;\n padding: 0;\n margin: 0;\n resize: none;\n}\n[data-rsi-root] input::placeholder,\n[data-rsi-root] textarea::placeholder {\n color: inherit;\n opacity: 0.5;\n}\n[data-rsi-root] a {\n color: inherit;\n text-decoration: none;\n}\n[data-rsi-root] img,\n[data-rsi-root] svg {\n display: block;\n max-width: 100%;\n}\n[data-rsi-root] h1,\n[data-rsi-root] h2,\n[data-rsi-root] h3,\n[data-rsi-root] h4,\n[data-rsi-root] h5,\n[data-rsi-root] h6 {\n font-size: inherit;\n font-weight: inherit;\n}\n[data-rsi-root] ::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n}\n[data-rsi-root] ::-webkit-scrollbar-track {\n background: transparent;\n}\n[data-rsi-root] ::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.2);\n border-radius: 3px;\n}\n[data-rsi-root] ::-webkit-scrollbar-thumb:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n[data-rsi-root] ::selection {\n background: rgba(99, 102, 241, 0.4);\n color: #fff;\n}\n[data-rsi-root] :focus-visible {\n outline: 2px solid rgba(99, 102, 241, 0.6);\n outline-offset: 2px;\n}\n');
|
|
57
|
+
styleInject('@import "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";\n[data-rsi-root],\n[data-rsi-root] *,\n[data-rsi-root] *::before,\n[data-rsi-root] *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0;\n font-family:\n "Inter",\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n "Helvetica Neue",\n sans-serif;\n font-size: 14px;\n font-weight: 400;\n font-style: normal;\n font-variant: normal;\n line-height: 1.5;\n letter-spacing: normal;\n text-align: left;\n text-decoration: none;\n text-indent: 0;\n text-shadow: none;\n text-transform: none;\n word-spacing: normal;\n white-space: normal;\n background: transparent;\n color: inherit;\n outline: none;\n vertical-align: baseline;\n visibility: visible;\n opacity: 1;\n transform: none;\n transform-origin: 50% 50% 0;\n animation: none;\n transition: none;\n list-style: none;\n border-collapse: collapse;\n border-spacing: 0;\n float: none;\n clear: none;\n cursor: auto;\n}\n[data-rsi-root] {\n all: initial;\n font-family:\n "Inter",\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n "Helvetica Neue",\n sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #fff;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n}\n[data-rsi-floating-button] {\n all: initial;\n font-family:\n "Inter",\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n "Helvetica Neue",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n[data-rsi-root] button {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n cursor: pointer;\n background: transparent;\n border: none;\n padding: 0;\n margin: 0;\n border-radius: 8px;\n}\n[data-rsi-root] input,\n[data-rsi-root] textarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n background: transparent;\n border: none;\n outline: none;\n padding: 0;\n margin: 0;\n resize: none;\n}\n[data-rsi-root] input::placeholder,\n[data-rsi-root] textarea::placeholder {\n color: inherit;\n opacity: 0.5;\n}\n[data-rsi-root] a {\n color: inherit;\n text-decoration: none;\n}\n[data-rsi-root] img,\n[data-rsi-root] svg {\n display: block;\n max-width: 100%;\n}\n[data-rsi-root] h1,\n[data-rsi-root] h2,\n[data-rsi-root] h3,\n[data-rsi-root] h4,\n[data-rsi-root] h5,\n[data-rsi-root] h6 {\n font-size: inherit;\n font-weight: inherit;\n}\n[data-rsi-root] ::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n}\n[data-rsi-root] ::-webkit-scrollbar-track {\n background: transparent;\n}\n[data-rsi-root] ::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.2);\n border-radius: 3px;\n}\n[data-rsi-root] ::-webkit-scrollbar-thumb:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n[data-rsi-root] ::selection {\n background: rgba(99, 102, 241, 0.4);\n color: #fff;\n}\n[data-rsi-root] :focus-visible {\n outline: 2px solid rgba(99, 102, 241, 0.6);\n outline-offset: 2px;\n}\n');
|
|
57
58
|
|
|
58
59
|
// src/provider.tsx
|
|
59
|
-
var
|
|
60
|
+
var import_react2 = require("react");
|
|
60
61
|
|
|
61
62
|
// src/store.ts
|
|
62
63
|
function createInspectorStore() {
|
|
63
|
-
const
|
|
64
|
+
const dataSources = /* @__PURE__ */ new Map();
|
|
64
65
|
const listeners = /* @__PURE__ */ new Set();
|
|
65
66
|
function emit() {
|
|
66
67
|
for (const l of listeners) l();
|
|
67
68
|
}
|
|
68
|
-
function
|
|
69
|
-
const existing =
|
|
69
|
+
function getOrCreateDataSource(id, type, slices) {
|
|
70
|
+
const existing = dataSources.get(id);
|
|
70
71
|
if (existing) return existing;
|
|
71
72
|
const created = {
|
|
72
73
|
id,
|
|
73
74
|
label: "Unknown",
|
|
75
|
+
type,
|
|
74
76
|
mounted: true,
|
|
75
|
-
states: /* @__PURE__ */ new Map()
|
|
77
|
+
states: /* @__PURE__ */ new Map(),
|
|
78
|
+
slices: new Map(
|
|
79
|
+
slices?.map((sliceId) => [sliceId, { id: sliceId, label: sliceId, states: /* @__PURE__ */ new Map() }]) ?? []
|
|
80
|
+
)
|
|
76
81
|
};
|
|
77
|
-
|
|
82
|
+
dataSources.set(id, created);
|
|
78
83
|
return created;
|
|
79
84
|
}
|
|
80
85
|
const store = {
|
|
81
86
|
enabled: true,
|
|
82
|
-
|
|
87
|
+
dataSources,
|
|
83
88
|
subscribe(listener) {
|
|
84
89
|
listeners.add(listener);
|
|
85
90
|
return () => {
|
|
@@ -89,104 +94,120 @@ function createInspectorStore() {
|
|
|
89
94
|
getSnapshot() {
|
|
90
95
|
return {
|
|
91
96
|
enabled: store.enabled,
|
|
92
|
-
|
|
93
|
-
id:
|
|
94
|
-
label:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
dataSources: Array.from(dataSources.values()).map((ds) => ({
|
|
98
|
+
id: ds.id,
|
|
99
|
+
label: ds.label,
|
|
100
|
+
type: ds.type,
|
|
101
|
+
mounted: ds.mounted,
|
|
102
|
+
stateKeys: Array.from(ds.states.keys()),
|
|
103
|
+
slices: Array.from(ds.slices.values()).map((slice) => ({
|
|
104
|
+
id: slice.id,
|
|
105
|
+
label: slice.label,
|
|
106
|
+
stateKeys: Array.from(slice.states.keys())
|
|
107
|
+
}))
|
|
97
108
|
}))
|
|
98
109
|
};
|
|
99
110
|
},
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
// Data source lifecycle
|
|
112
|
+
registerDataSource(id, type, label, slices) {
|
|
113
|
+
const ds = getOrCreateDataSource(id, type, slices);
|
|
114
|
+
ds.mounted = true;
|
|
115
|
+
if (label?.trim()) ds.label = label.trim();
|
|
104
116
|
emit();
|
|
105
117
|
},
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
118
|
+
setDataSourceLabel(id, label) {
|
|
119
|
+
const ds = dataSources.get(id);
|
|
120
|
+
if (!ds) return;
|
|
121
|
+
ds.label = label.trim() || "Unknown";
|
|
109
122
|
emit();
|
|
110
123
|
},
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
if (!
|
|
114
|
-
|
|
124
|
+
unregisterDataSource(id) {
|
|
125
|
+
const ds = dataSources.get(id);
|
|
126
|
+
if (!ds) return;
|
|
127
|
+
ds.mounted = false;
|
|
128
|
+
emit();
|
|
129
|
+
},
|
|
130
|
+
// State lifecycle (for component type)
|
|
131
|
+
upsertState(dataSourceId, entry) {
|
|
132
|
+
const ds = getOrCreateDataSource(dataSourceId, "component");
|
|
133
|
+
ds.states.set(entry.key, entry);
|
|
115
134
|
emit();
|
|
116
135
|
},
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
136
|
+
updateStateValue(dataSourceId, key, value) {
|
|
137
|
+
const ds = dataSources.get(dataSourceId);
|
|
138
|
+
if (!ds) return;
|
|
139
|
+
const s = ds.states.get(key);
|
|
140
|
+
if (!s) return;
|
|
141
|
+
s.value = value;
|
|
142
|
+
emit();
|
|
143
|
+
},
|
|
144
|
+
removeState(dataSourceId, key) {
|
|
145
|
+
const ds = dataSources.get(dataSourceId);
|
|
146
|
+
if (!ds) return;
|
|
147
|
+
if (!ds.states.has(key)) return;
|
|
148
|
+
ds.states.delete(key);
|
|
120
149
|
emit();
|
|
121
150
|
},
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
151
|
+
// Slice state lifecycle (for context type)
|
|
152
|
+
upsertSliceState(dataSourceId, sliceId, entry) {
|
|
153
|
+
const ds = dataSources.get(dataSourceId);
|
|
154
|
+
if (!ds) return;
|
|
155
|
+
let slice = ds.slices.get(sliceId);
|
|
156
|
+
if (!slice) {
|
|
157
|
+
slice = { id: sliceId, label: sliceId, states: /* @__PURE__ */ new Map() };
|
|
158
|
+
ds.slices.set(sliceId, slice);
|
|
159
|
+
}
|
|
160
|
+
slice.states.set(entry.key, entry);
|
|
161
|
+
emit();
|
|
162
|
+
},
|
|
163
|
+
updateSliceStateValue(dataSourceId, sliceId, key, value) {
|
|
164
|
+
const ds = dataSources.get(dataSourceId);
|
|
165
|
+
if (!ds) return;
|
|
166
|
+
const slice = ds.slices.get(sliceId);
|
|
167
|
+
if (!slice) return;
|
|
168
|
+
const s = slice.states.get(key);
|
|
126
169
|
if (!s) return;
|
|
127
170
|
s.value = value;
|
|
128
171
|
emit();
|
|
129
172
|
},
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
if (!
|
|
133
|
-
|
|
134
|
-
|
|
173
|
+
removeSliceState(dataSourceId, sliceId, key) {
|
|
174
|
+
const ds = dataSources.get(dataSourceId);
|
|
175
|
+
if (!ds) return;
|
|
176
|
+
const slice = ds.slices.get(sliceId);
|
|
177
|
+
if (!slice) return;
|
|
178
|
+
slice.states.delete(key);
|
|
135
179
|
emit();
|
|
180
|
+
},
|
|
181
|
+
// Get state entries
|
|
182
|
+
getStateEntry(dataSourceId, key) {
|
|
183
|
+
const ds = dataSources.get(dataSourceId);
|
|
184
|
+
return ds?.states.get(key);
|
|
185
|
+
},
|
|
186
|
+
getSliceStateEntry(dataSourceId, sliceId, key) {
|
|
187
|
+
const ds = dataSources.get(dataSourceId);
|
|
188
|
+
if (!ds) return void 0;
|
|
189
|
+
const slice = ds.slices.get(sliceId);
|
|
190
|
+
return slice?.states.get(key);
|
|
191
|
+
},
|
|
192
|
+
// Legacy aliases
|
|
193
|
+
registerComponent(id, label) {
|
|
194
|
+
store.registerDataSource(id, "component", label);
|
|
195
|
+
},
|
|
196
|
+
setComponentLabel(id, label) {
|
|
197
|
+
store.setDataSourceLabel(id, label);
|
|
198
|
+
},
|
|
199
|
+
unregisterComponent(id) {
|
|
200
|
+
store.unregisterDataSource(id);
|
|
201
|
+
},
|
|
202
|
+
upsertDataSourceState(dataSourceId, sliceId, entry) {
|
|
203
|
+
store.upsertSliceState(dataSourceId, sliceId, entry);
|
|
136
204
|
}
|
|
137
205
|
};
|
|
138
206
|
return store;
|
|
139
207
|
}
|
|
140
208
|
|
|
141
|
-
// src/provider.tsx
|
|
142
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
143
|
-
var InspectorContext = (0, import_react.createContext)(null);
|
|
144
|
-
var storeRef = { current: null };
|
|
145
|
-
function getStore() {
|
|
146
|
-
if (!storeRef.current) {
|
|
147
|
-
storeRef.current = createInspectorStore();
|
|
148
|
-
}
|
|
149
|
-
return storeRef.current;
|
|
150
|
-
}
|
|
151
|
-
function StateInspectorProvider({
|
|
152
|
-
enabled = true,
|
|
153
|
-
children
|
|
154
|
-
}) {
|
|
155
|
-
const store = (0, import_react.useMemo)(() => getStore(), []);
|
|
156
|
-
(0, import_react.useEffect)(() => {
|
|
157
|
-
storeRef.current.enabled = enabled;
|
|
158
|
-
}, [enabled]);
|
|
159
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InspectorContext.Provider, { value: store, children });
|
|
160
|
-
}
|
|
161
|
-
function useInspectorStore() {
|
|
162
|
-
const ctx = (0, import_react.useContext)(InspectorContext);
|
|
163
|
-
if (!ctx) {
|
|
164
|
-
throw new Error("useInspectorStore must be used inside StateInspectorProvider");
|
|
165
|
-
}
|
|
166
|
-
return ctx;
|
|
167
|
-
}
|
|
168
|
-
function useInspectorComponent(label) {
|
|
169
|
-
const store = useInspectorStore();
|
|
170
|
-
const reactId = (0, import_react.useId)();
|
|
171
|
-
const componentId = (0, import_react.useMemo)(() => `c_${reactId}`, [reactId]);
|
|
172
|
-
(0, import_react.useEffect)(() => {
|
|
173
|
-
if (!store.enabled) return;
|
|
174
|
-
store.registerComponent(componentId, label?.trim());
|
|
175
|
-
return () => {
|
|
176
|
-
store.unregisterComponent(componentId);
|
|
177
|
-
};
|
|
178
|
-
}, [store, componentId, label]);
|
|
179
|
-
(0, import_react.useEffect)(() => {
|
|
180
|
-
if (!store.enabled) return;
|
|
181
|
-
const trimmed = label?.trim();
|
|
182
|
-
if (trimmed) store.setComponentLabel(componentId, trimmed);
|
|
183
|
-
}, [store, componentId, label]);
|
|
184
|
-
console.log({ id: componentId });
|
|
185
|
-
return (0, import_react.useMemo)(() => ({ id: componentId }), [componentId]);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
209
|
// src/hooks.ts
|
|
189
|
-
var
|
|
210
|
+
var import_react = require("react");
|
|
190
211
|
function stableKey(input) {
|
|
191
212
|
return input.trim();
|
|
192
213
|
}
|
|
@@ -201,14 +222,14 @@ function inferMeta(value) {
|
|
|
201
222
|
function useInspectableState(component, key, initial, meta) {
|
|
202
223
|
const store = useInspectorStore();
|
|
203
224
|
const componentId = component.id;
|
|
204
|
-
const stateKey = (0,
|
|
205
|
-
const [value, setValue] = (0,
|
|
206
|
-
const setValueRef = (0,
|
|
225
|
+
const stateKey = (0, import_react.useMemo)(() => stableKey(key), [key]);
|
|
226
|
+
const [value, setValue] = (0, import_react.useState)(initial);
|
|
227
|
+
const setValueRef = (0, import_react.useRef)(() => {
|
|
207
228
|
});
|
|
208
229
|
setValueRef.current = (next) => {
|
|
209
230
|
setValue(next);
|
|
210
231
|
};
|
|
211
|
-
(0,
|
|
232
|
+
(0, import_react.useEffect)(() => {
|
|
212
233
|
if (!store.enabled) return;
|
|
213
234
|
const resolvedMeta = meta ?? inferMeta(value);
|
|
214
235
|
store.upsertState(componentId, {
|
|
@@ -221,7 +242,7 @@ function useInspectableState(component, key, initial, meta) {
|
|
|
221
242
|
store.removeState(componentId, stateKey);
|
|
222
243
|
};
|
|
223
244
|
}, [store, componentId, stateKey]);
|
|
224
|
-
(0,
|
|
245
|
+
(0, import_react.useEffect)(() => {
|
|
225
246
|
if (!store.enabled) return;
|
|
226
247
|
const resolvedMeta = meta ?? inferMeta(value);
|
|
227
248
|
store.upsertState(componentId, {
|
|
@@ -235,9 +256,9 @@ function useInspectableState(component, key, initial, meta) {
|
|
|
235
256
|
}
|
|
236
257
|
function useComponentLabel(label) {
|
|
237
258
|
const store = useInspectorStore();
|
|
238
|
-
const reactId = (0,
|
|
239
|
-
const componentId = (0,
|
|
240
|
-
(0,
|
|
259
|
+
const reactId = (0, import_react.useId)();
|
|
260
|
+
const componentId = (0, import_react.useMemo)(() => `c_${reactId}`, [reactId]);
|
|
261
|
+
(0, import_react.useEffect)(() => {
|
|
241
262
|
if (!store.enabled) return;
|
|
242
263
|
const trimmed = label.trim();
|
|
243
264
|
if (!trimmed) return;
|
|
@@ -245,8 +266,108 @@ function useComponentLabel(label) {
|
|
|
245
266
|
}, [store, componentId, label]);
|
|
246
267
|
}
|
|
247
268
|
|
|
269
|
+
// src/provider.tsx
|
|
270
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
271
|
+
var InspectorContext = (0, import_react2.createContext)(null);
|
|
272
|
+
var storeRef = { current: null };
|
|
273
|
+
function getStore() {
|
|
274
|
+
if (!storeRef.current) {
|
|
275
|
+
storeRef.current = createInspectorStore();
|
|
276
|
+
}
|
|
277
|
+
return storeRef.current;
|
|
278
|
+
}
|
|
279
|
+
function StateInspectorProvider({
|
|
280
|
+
enabled = true,
|
|
281
|
+
store,
|
|
282
|
+
children
|
|
283
|
+
}) {
|
|
284
|
+
const mainStore = (0, import_react2.useMemo)(() => getStore(), []);
|
|
285
|
+
(0, import_react2.useEffect)(() => {
|
|
286
|
+
if (!store) return;
|
|
287
|
+
const initialState = store.getState();
|
|
288
|
+
const slices = Object.keys(initialState);
|
|
289
|
+
mainStore.registerDataSource("redux_context", "context", "ReduxContext", slices);
|
|
290
|
+
syncSliceStates(initialState);
|
|
291
|
+
function syncSliceStates(state) {
|
|
292
|
+
slices.forEach((sliceName) => {
|
|
293
|
+
const sliceState = state[sliceName];
|
|
294
|
+
if (sliceState && typeof sliceState === "object" && !Array.isArray(sliceState)) {
|
|
295
|
+
Object.entries(sliceState).forEach(
|
|
296
|
+
([stateKey, stateValue]) => {
|
|
297
|
+
const meta = inferMeta(stateValue);
|
|
298
|
+
mainStore.upsertSliceState("redux_context", sliceName, {
|
|
299
|
+
key: stateKey,
|
|
300
|
+
value: stateValue,
|
|
301
|
+
...meta !== void 0 && { meta },
|
|
302
|
+
setValue: (newValue) => {
|
|
303
|
+
store.dispatch({
|
|
304
|
+
type: `${sliceName}/updateField`,
|
|
305
|
+
payload: { field: stateKey, value: newValue }
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
} else {
|
|
312
|
+
const meta = inferMeta(sliceState);
|
|
313
|
+
mainStore.upsertSliceState("redux_context", sliceName, {
|
|
314
|
+
key: "value",
|
|
315
|
+
value: sliceState,
|
|
316
|
+
...meta !== void 0 && { meta },
|
|
317
|
+
setValue: (newValue) => {
|
|
318
|
+
store.dispatch({
|
|
319
|
+
type: `${sliceName}/setValue`,
|
|
320
|
+
payload: newValue
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
function handleChange() {
|
|
328
|
+
const nextState = store.getState();
|
|
329
|
+
syncSliceStates(nextState);
|
|
330
|
+
}
|
|
331
|
+
const unsubscribe = store.subscribe(handleChange);
|
|
332
|
+
return () => {
|
|
333
|
+
unsubscribe();
|
|
334
|
+
mainStore.unregisterDataSource("redux_context");
|
|
335
|
+
};
|
|
336
|
+
}, [store, mainStore]);
|
|
337
|
+
(0, import_react2.useEffect)(() => {
|
|
338
|
+
storeRef.current.enabled = enabled;
|
|
339
|
+
}, [enabled]);
|
|
340
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InspectorContext.Provider, { value: mainStore, children });
|
|
341
|
+
}
|
|
342
|
+
function useInspectorStore() {
|
|
343
|
+
const ctx = (0, import_react2.useContext)(InspectorContext);
|
|
344
|
+
if (!ctx) {
|
|
345
|
+
throw new Error("useInspectorStore must be used inside StateInspectorProvider");
|
|
346
|
+
}
|
|
347
|
+
return ctx;
|
|
348
|
+
}
|
|
349
|
+
function useInspectorComponent(label) {
|
|
350
|
+
const store = useInspectorStore();
|
|
351
|
+
const reactId = (0, import_react2.useId)();
|
|
352
|
+
const componentId = (0, import_react2.useMemo)(() => `c_${reactId}`, [reactId]);
|
|
353
|
+
(0, import_react2.useEffect)(() => {
|
|
354
|
+
if (!store.enabled) return;
|
|
355
|
+
store.registerComponent(componentId, label?.trim());
|
|
356
|
+
return () => {
|
|
357
|
+
store.unregisterComponent(componentId);
|
|
358
|
+
};
|
|
359
|
+
}, [store, componentId, label]);
|
|
360
|
+
(0, import_react2.useEffect)(() => {
|
|
361
|
+
if (!store.enabled) return;
|
|
362
|
+
const trimmed = label?.trim();
|
|
363
|
+
if (trimmed) store.setComponentLabel(componentId, trimmed);
|
|
364
|
+
}, [store, componentId, label]);
|
|
365
|
+
console.log({ id: componentId });
|
|
366
|
+
return (0, import_react2.useMemo)(() => ({ id: componentId }), [componentId]);
|
|
367
|
+
}
|
|
368
|
+
|
|
248
369
|
// src/StateInspectorUI.tsx
|
|
249
|
-
var
|
|
370
|
+
var import_react6 = require("react");
|
|
250
371
|
var import_react_dom = require("react-dom");
|
|
251
372
|
|
|
252
373
|
// src/ui/constants.ts
|
|
@@ -545,6 +666,9 @@ function DragHandle({ children, onDragStart, onDragEnd, style }) {
|
|
|
545
666
|
);
|
|
546
667
|
}
|
|
547
668
|
|
|
669
|
+
// src/ui/components/ComponentList.tsx
|
|
670
|
+
var import_react4 = require("react");
|
|
671
|
+
|
|
548
672
|
// src/ui/styles.ts
|
|
549
673
|
var inputStyle = {
|
|
550
674
|
padding: "8px 10px",
|
|
@@ -580,48 +704,128 @@ function SearchInput({ value, onChange, inputRef }) {
|
|
|
580
704
|
|
|
581
705
|
// src/ui/components/ComponentList.tsx
|
|
582
706
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
707
|
+
var ComponentListItem = ({ dataSource, active, onSelect }) => {
|
|
708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
709
|
+
"button",
|
|
710
|
+
{
|
|
711
|
+
id: `rsi-comp-${dataSource.id}`,
|
|
712
|
+
onClick: () => onSelect(dataSource.id),
|
|
713
|
+
style: {
|
|
714
|
+
display: "flex",
|
|
715
|
+
justifyContent: "space-between",
|
|
716
|
+
alignItems: "center",
|
|
717
|
+
padding: 8,
|
|
718
|
+
backgroundColor: active ? "#27272A" : "transparent",
|
|
719
|
+
border: "none",
|
|
720
|
+
cursor: "pointer"
|
|
721
|
+
},
|
|
722
|
+
children: [
|
|
723
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: 500, fontSize: 12, color: active ? "#fff" : "#9F9FA9" }, children: dataSource.label }),
|
|
724
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
725
|
+
"div",
|
|
726
|
+
{
|
|
727
|
+
style: {
|
|
728
|
+
fontSize: 9,
|
|
729
|
+
height: 16,
|
|
730
|
+
width: 16,
|
|
731
|
+
color: "#D4D4D8",
|
|
732
|
+
display: "flex",
|
|
733
|
+
alignItems: "center",
|
|
734
|
+
justifyContent: "center",
|
|
735
|
+
borderRadius: 8,
|
|
736
|
+
backgroundColor: "#3F3F47"
|
|
737
|
+
},
|
|
738
|
+
children: dataSource.stateKeys.length
|
|
739
|
+
}
|
|
740
|
+
)
|
|
741
|
+
]
|
|
742
|
+
},
|
|
743
|
+
dataSource.id
|
|
744
|
+
);
|
|
745
|
+
};
|
|
746
|
+
var ContextListItem = ({ dataSource, activeSliceId, onSelectSlice }) => {
|
|
747
|
+
const [expanded, setExpanded] = (0, import_react4.useState)(true);
|
|
748
|
+
const isActive = dataSource.slices.some(
|
|
749
|
+
(slice) => `${dataSource.id}:${slice.id}` === activeSliceId
|
|
750
|
+
);
|
|
751
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
|
|
752
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
753
|
+
"button",
|
|
596
754
|
{
|
|
755
|
+
onClick: () => setExpanded(!expanded),
|
|
597
756
|
style: {
|
|
598
757
|
display: "flex",
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
758
|
+
justifyContent: "space-between",
|
|
759
|
+
alignItems: "center",
|
|
760
|
+
padding: 8,
|
|
761
|
+
backgroundColor: isActive ? "#27272A" : "transparent",
|
|
762
|
+
border: "none",
|
|
763
|
+
cursor: "pointer"
|
|
604
764
|
},
|
|
605
|
-
children:
|
|
765
|
+
children: [
|
|
766
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: 500, fontSize: 12, color: isActive ? "#fff" : "#9F9FA9" }, children: dataSource.label }),
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
769
|
+
"div",
|
|
770
|
+
{
|
|
771
|
+
style: {
|
|
772
|
+
fontSize: 9,
|
|
773
|
+
height: 16,
|
|
774
|
+
width: 16,
|
|
775
|
+
color: "#D4D4D8",
|
|
776
|
+
display: "flex",
|
|
777
|
+
alignItems: "center",
|
|
778
|
+
justifyContent: "center",
|
|
779
|
+
borderRadius: 8,
|
|
780
|
+
backgroundColor: "#3F3F47"
|
|
781
|
+
},
|
|
782
|
+
children: dataSource.slices.length
|
|
783
|
+
}
|
|
784
|
+
),
|
|
785
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
786
|
+
"svg",
|
|
787
|
+
{
|
|
788
|
+
width: "10",
|
|
789
|
+
height: "10",
|
|
790
|
+
viewBox: "0 0 10 10",
|
|
791
|
+
fill: "none",
|
|
792
|
+
style: {
|
|
793
|
+
transform: expanded ? "rotate(180deg)" : "rotate(90deg)",
|
|
794
|
+
transition: "transform 0.15s ease"
|
|
795
|
+
},
|
|
796
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
797
|
+
"path",
|
|
798
|
+
{
|
|
799
|
+
d: "M3 2L7 5L3 8",
|
|
800
|
+
stroke: "#9F9FA9",
|
|
801
|
+
strokeWidth: "1.5",
|
|
802
|
+
strokeLinecap: "round",
|
|
803
|
+
strokeLinejoin: "round"
|
|
804
|
+
}
|
|
805
|
+
)
|
|
806
|
+
}
|
|
807
|
+
)
|
|
808
|
+
] })
|
|
809
|
+
]
|
|
606
810
|
}
|
|
607
811
|
),
|
|
608
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexDirection: "column",
|
|
609
|
-
const active =
|
|
812
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexDirection: "column", paddingLeft: 16 }, children: dataSource.slices.map((slice) => {
|
|
813
|
+
const active = activeSliceId === `${dataSource.id}:${slice.id}`;
|
|
610
814
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
611
815
|
"button",
|
|
612
816
|
{
|
|
613
|
-
|
|
614
|
-
onClick: () => onSelect(c.id),
|
|
817
|
+
onClick: () => onSelectSlice(dataSource.id, slice.id),
|
|
615
818
|
style: {
|
|
616
819
|
display: "flex",
|
|
617
820
|
justifyContent: "space-between",
|
|
618
821
|
alignItems: "center",
|
|
619
822
|
padding: 8,
|
|
620
823
|
backgroundColor: active ? "#27272A" : "transparent",
|
|
621
|
-
border: "none"
|
|
824
|
+
border: "none",
|
|
825
|
+
cursor: "pointer"
|
|
622
826
|
},
|
|
623
827
|
children: [
|
|
624
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: 500, fontSize: 12, color: active ? "#fff" : "#9F9FA9" }, children:
|
|
828
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: 500, fontSize: 12, color: active ? "#fff" : "#9F9FA9" }, children: slice.label }),
|
|
625
829
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
626
830
|
"div",
|
|
627
831
|
{
|
|
@@ -636,15 +840,59 @@ function ComponentList({
|
|
|
636
840
|
borderRadius: 8,
|
|
637
841
|
backgroundColor: "#3F3F47"
|
|
638
842
|
},
|
|
639
|
-
children:
|
|
843
|
+
children: slice.stateKeys.length
|
|
640
844
|
}
|
|
641
845
|
)
|
|
642
846
|
]
|
|
643
847
|
},
|
|
644
|
-
|
|
848
|
+
slice.id
|
|
645
849
|
);
|
|
646
850
|
}) })
|
|
647
851
|
] });
|
|
852
|
+
};
|
|
853
|
+
function DataSourceList({
|
|
854
|
+
dataSources,
|
|
855
|
+
selectedId,
|
|
856
|
+
onSelect,
|
|
857
|
+
onSelectSlice,
|
|
858
|
+
hidden,
|
|
859
|
+
query,
|
|
860
|
+
onQueryChange,
|
|
861
|
+
searchRef
|
|
862
|
+
}) {
|
|
863
|
+
if (hidden) return null;
|
|
864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { padding: 4, boxSizing: "border-box", backgroundColor: "#09090B" }, children: [
|
|
865
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
866
|
+
"div",
|
|
867
|
+
{
|
|
868
|
+
style: {
|
|
869
|
+
display: "flex",
|
|
870
|
+
flexDirection: "column",
|
|
871
|
+
paddingTop: 4,
|
|
872
|
+
paddingBottom: 8,
|
|
873
|
+
paddingLeft: 4,
|
|
874
|
+
paddingRight: 4
|
|
875
|
+
},
|
|
876
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SearchInput, { value: query, onChange: onQueryChange, inputRef: searchRef })
|
|
877
|
+
}
|
|
878
|
+
),
|
|
879
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 2, overflow: "auto", flex: 1 }, children: dataSources.map((ds) => {
|
|
880
|
+
if (ds.type === "context") {
|
|
881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
882
|
+
ContextListItem,
|
|
883
|
+
{
|
|
884
|
+
dataSource: ds,
|
|
885
|
+
activeSliceId: selectedId,
|
|
886
|
+
onSelectSlice: onSelectSlice ?? (() => {
|
|
887
|
+
})
|
|
888
|
+
},
|
|
889
|
+
ds.id
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
const active = ds.id === selectedId;
|
|
893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComponentListItem, { dataSource: ds, active, onSelect }, ds.id);
|
|
894
|
+
}) })
|
|
895
|
+
] });
|
|
648
896
|
}
|
|
649
897
|
|
|
650
898
|
// src/ui/components/StatePanelHeader.tsx
|
|
@@ -682,12 +930,12 @@ function StatePanelHeader({
|
|
|
682
930
|
}
|
|
683
931
|
|
|
684
932
|
// src/ui/components/JsonEditor.tsx
|
|
685
|
-
var
|
|
933
|
+
var import_react5 = require("react");
|
|
686
934
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
687
935
|
function JsonEditor({ initial, onValidJson }) {
|
|
688
|
-
const [raw, setRaw] = (0,
|
|
689
|
-
const [error, setError] = (0,
|
|
690
|
-
(0,
|
|
936
|
+
const [raw, setRaw] = (0, import_react5.useState)(initial);
|
|
937
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
938
|
+
(0, import_react5.useEffect)(() => {
|
|
691
939
|
setRaw(initial);
|
|
692
940
|
}, [initial]);
|
|
693
941
|
const handleChange = (e) => {
|
|
@@ -817,7 +1065,7 @@ function StateCard({ state }) {
|
|
|
817
1065
|
{
|
|
818
1066
|
value: state.value,
|
|
819
1067
|
meta: state.meta,
|
|
820
|
-
onChange: (next) => state.setValue(next)
|
|
1068
|
+
onChange: (next) => state.setValue?.(next)
|
|
821
1069
|
}
|
|
822
1070
|
)
|
|
823
1071
|
]
|
|
@@ -1068,16 +1316,18 @@ var DockHeader_default = DockHeader;
|
|
|
1068
1316
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1069
1317
|
function StateInspectorUI() {
|
|
1070
1318
|
const store = useInspectorStore();
|
|
1071
|
-
const [query, setQuery] = (0,
|
|
1072
|
-
const [leftCollapsed, setLeftCollapsed] = (0,
|
|
1073
|
-
const [layout, setLayout] = (0,
|
|
1074
|
-
const [preview, setPreview] = (0,
|
|
1075
|
-
const [isTransitioning, setIsTransitioning] = (0,
|
|
1076
|
-
const [open, setOpen] = (0,
|
|
1077
|
-
const [selectedId, setSelectedId] = (0,
|
|
1078
|
-
const [
|
|
1079
|
-
const
|
|
1080
|
-
|
|
1319
|
+
const [query, setQuery] = (0, import_react6.useState)("");
|
|
1320
|
+
const [leftCollapsed, setLeftCollapsed] = (0, import_react6.useState)(false);
|
|
1321
|
+
const [layout, setLayout] = (0, import_react6.useState)("floating");
|
|
1322
|
+
const [preview, setPreview] = (0, import_react6.useState)(null);
|
|
1323
|
+
const [isTransitioning, setIsTransitioning] = (0, import_react6.useState)(false);
|
|
1324
|
+
const [open, setOpen] = (0, import_react6.useState)(false);
|
|
1325
|
+
const [selectedId, setSelectedId] = (0, import_react6.useState)(null);
|
|
1326
|
+
const [selectedSlice, setSelectedSlice] = (0, import_react6.useState)(null);
|
|
1327
|
+
const [tick, force] = (0, import_react6.useState)(0);
|
|
1328
|
+
console.log(store);
|
|
1329
|
+
const searchRef = (0, import_react6.useRef)(null);
|
|
1330
|
+
const [pos, setPos] = (0, import_react6.useState)(() => {
|
|
1081
1331
|
try {
|
|
1082
1332
|
const raw = localStorage.getItem(LS_KEY);
|
|
1083
1333
|
return raw ? JSON.parse(raw) : { right: 16, bottom: 72 };
|
|
@@ -1085,7 +1335,7 @@ function StateInspectorUI() {
|
|
|
1085
1335
|
return { right: 16, bottom: 72 };
|
|
1086
1336
|
}
|
|
1087
1337
|
});
|
|
1088
|
-
const [leftWidth, setLeftWidth] = (0,
|
|
1338
|
+
const [leftWidth, setLeftWidth] = (0, import_react6.useState)(() => {
|
|
1089
1339
|
try {
|
|
1090
1340
|
const raw = localStorage.getItem(LS_LEFT_W);
|
|
1091
1341
|
return raw ? Number(raw) : 280;
|
|
@@ -1093,7 +1343,7 @@ function StateInspectorUI() {
|
|
|
1093
1343
|
return 280;
|
|
1094
1344
|
}
|
|
1095
1345
|
});
|
|
1096
|
-
const [size, setSize] = (0,
|
|
1346
|
+
const [size, setSize] = (0, import_react6.useState)(() => {
|
|
1097
1347
|
try {
|
|
1098
1348
|
const raw = localStorage.getItem(LS_SIZE);
|
|
1099
1349
|
return raw ? JSON.parse(raw) : { width: 720, height: 420 };
|
|
@@ -1101,64 +1351,83 @@ function StateInspectorUI() {
|
|
|
1101
1351
|
return { width: 720, height: 420 };
|
|
1102
1352
|
}
|
|
1103
1353
|
});
|
|
1104
|
-
(0,
|
|
1354
|
+
(0, import_react6.useEffect)(() => {
|
|
1105
1355
|
try {
|
|
1106
1356
|
localStorage.setItem(LS_LAYOUT, layout);
|
|
1107
1357
|
} catch (e) {
|
|
1108
1358
|
console.error(e);
|
|
1109
1359
|
}
|
|
1110
1360
|
}, [layout]);
|
|
1111
|
-
(0,
|
|
1361
|
+
(0, import_react6.useEffect)(() => {
|
|
1112
1362
|
try {
|
|
1113
1363
|
localStorage.setItem(LS_KEY, JSON.stringify(pos));
|
|
1114
1364
|
} catch (e) {
|
|
1115
1365
|
console.error(e);
|
|
1116
1366
|
}
|
|
1117
1367
|
}, [pos]);
|
|
1118
|
-
(0,
|
|
1368
|
+
(0, import_react6.useEffect)(() => {
|
|
1119
1369
|
try {
|
|
1120
1370
|
localStorage.setItem(LS_LEFT_W, String(leftWidth));
|
|
1121
1371
|
} catch (e) {
|
|
1122
1372
|
console.error(e);
|
|
1123
1373
|
}
|
|
1124
1374
|
}, [leftWidth]);
|
|
1125
|
-
(0,
|
|
1375
|
+
(0, import_react6.useEffect)(() => {
|
|
1126
1376
|
try {
|
|
1127
1377
|
localStorage.setItem(LS_SIZE, JSON.stringify(size));
|
|
1128
1378
|
} catch (e) {
|
|
1129
1379
|
console.error(e);
|
|
1130
1380
|
}
|
|
1131
1381
|
}, [size]);
|
|
1132
|
-
(0,
|
|
1382
|
+
(0, import_react6.useEffect)(() => {
|
|
1133
1383
|
const shouldCollapse = leftWidth <= 200 || (size.width ?? 720) - leftWidth < 320;
|
|
1134
1384
|
setLeftCollapsed(shouldCollapse);
|
|
1135
1385
|
}, [leftWidth, size.width]);
|
|
1136
|
-
(0,
|
|
1137
|
-
const snapshot = (0,
|
|
1138
|
-
const
|
|
1139
|
-
() => snapshot.
|
|
1140
|
-
[snapshot.
|
|
1386
|
+
(0, import_react6.useEffect)(() => store.subscribe(() => force((x) => x + 1)), [store]);
|
|
1387
|
+
const snapshot = (0, import_react6.useMemo)(() => store.getSnapshot(), [store, tick]);
|
|
1388
|
+
const dataSources = (0, import_react6.useMemo)(
|
|
1389
|
+
() => snapshot.dataSources.filter((ds) => ds.mounted),
|
|
1390
|
+
[snapshot.dataSources]
|
|
1141
1391
|
);
|
|
1142
1392
|
const q = query.trim().toLowerCase();
|
|
1143
|
-
const filtered = (0,
|
|
1144
|
-
() => q ?
|
|
1145
|
-
const labelHit =
|
|
1146
|
-
const
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1393
|
+
const filtered = (0, import_react6.useMemo)(
|
|
1394
|
+
() => q ? dataSources.filter((ds) => {
|
|
1395
|
+
const labelHit = ds.label.toLowerCase().includes(q);
|
|
1396
|
+
const stateKeyHit = ds.stateKeys.some((k) => k.toLowerCase().includes(q));
|
|
1397
|
+
const sliceKeyHit = ds.slices.some(
|
|
1398
|
+
(slice) => slice.stateKeys.some((k) => k.toLowerCase().includes(q))
|
|
1399
|
+
);
|
|
1400
|
+
return labelHit || stateKeyHit || sliceKeyHit;
|
|
1401
|
+
}) : dataSources,
|
|
1402
|
+
[q, dataSources]
|
|
1150
1403
|
);
|
|
1151
|
-
(0,
|
|
1404
|
+
(0, import_react6.useEffect)(() => {
|
|
1152
1405
|
if (!open) return;
|
|
1153
|
-
if (
|
|
1406
|
+
if (dataSources.length === 0) {
|
|
1154
1407
|
setSelectedId(null);
|
|
1155
1408
|
return;
|
|
1156
1409
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1410
|
+
const isValidSelection = selectedId && dataSources.some((ds) => {
|
|
1411
|
+
if (ds.id === selectedId) return true;
|
|
1412
|
+
if (selectedId.includes(":")) {
|
|
1413
|
+
const [dsId, sliceId] = selectedId.split(":");
|
|
1414
|
+
return ds.id === dsId && ds.slices.some((s) => s.id === sliceId);
|
|
1415
|
+
}
|
|
1416
|
+
return false;
|
|
1417
|
+
});
|
|
1418
|
+
if (!isValidSelection) {
|
|
1419
|
+
const firstDs = dataSources[0];
|
|
1420
|
+
if (firstDs?.type === "context" && firstDs.slices.length > 0) {
|
|
1421
|
+
const firstSlice = firstDs.slices[0];
|
|
1422
|
+
setSelectedId(`${firstDs.id}:${firstSlice.id}`);
|
|
1423
|
+
setSelectedSlice({ dataSourceId: firstDs.id, sliceId: firstSlice.id });
|
|
1424
|
+
} else if (firstDs) {
|
|
1425
|
+
setSelectedId(firstDs.id);
|
|
1426
|
+
setSelectedSlice(null);
|
|
1427
|
+
}
|
|
1159
1428
|
}
|
|
1160
|
-
}, [open,
|
|
1161
|
-
(0,
|
|
1429
|
+
}, [open, dataSources.length]);
|
|
1430
|
+
(0, import_react6.useEffect)(() => {
|
|
1162
1431
|
function onKey(e) {
|
|
1163
1432
|
const mod = isMac ? e.metaKey : e.ctrlKey;
|
|
1164
1433
|
if (mod && e.shiftKey && e.key.toLowerCase() === "i") {
|
|
@@ -1191,10 +1460,40 @@ function StateInspectorUI() {
|
|
|
1191
1460
|
window.addEventListener("keydown", onKey);
|
|
1192
1461
|
return () => window.removeEventListener("keydown", onKey);
|
|
1193
1462
|
}, [open, filtered, selectedId]);
|
|
1194
|
-
const selected = (0,
|
|
1463
|
+
const selected = (0, import_react6.useMemo)(() => {
|
|
1464
|
+
if (selectedSlice) {
|
|
1465
|
+
const ds2 = store.dataSources.get(selectedSlice.dataSourceId);
|
|
1466
|
+
if (ds2 && ds2.type === "context") {
|
|
1467
|
+
const slice = ds2.slices.get(selectedSlice.sliceId);
|
|
1468
|
+
if (slice) {
|
|
1469
|
+
return {
|
|
1470
|
+
id: `${selectedSlice.dataSourceId}:${selectedSlice.sliceId}`,
|
|
1471
|
+
label: slice.label,
|
|
1472
|
+
mounted: ds2.mounted,
|
|
1473
|
+
states: slice.states
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
return null;
|
|
1478
|
+
}
|
|
1195
1479
|
if (!selectedId) return null;
|
|
1196
|
-
|
|
1197
|
-
|
|
1480
|
+
const ds = store.dataSources.get(selectedId);
|
|
1481
|
+
if (!ds) return null;
|
|
1482
|
+
return {
|
|
1483
|
+
id: ds.id,
|
|
1484
|
+
label: ds.label,
|
|
1485
|
+
mounted: ds.mounted,
|
|
1486
|
+
states: ds.states
|
|
1487
|
+
};
|
|
1488
|
+
}, [store, selectedId, selectedSlice, tick]);
|
|
1489
|
+
const handleSelectSlice = (dataSourceId, sliceId) => {
|
|
1490
|
+
setSelectedId(`${dataSourceId}:${sliceId}`);
|
|
1491
|
+
setSelectedSlice({ dataSourceId, sliceId });
|
|
1492
|
+
};
|
|
1493
|
+
const handleSelectComponent = (id) => {
|
|
1494
|
+
setSelectedId(id);
|
|
1495
|
+
setSelectedSlice(null);
|
|
1496
|
+
};
|
|
1198
1497
|
const handleDragEnd = () => {
|
|
1199
1498
|
if (preview) {
|
|
1200
1499
|
setLayout(preview);
|
|
@@ -1337,14 +1636,15 @@ function StateInspectorUI() {
|
|
|
1337
1636
|
children: [
|
|
1338
1637
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ResizeHandle, { onResize: handlePanelResize(size, pos) }),
|
|
1339
1638
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1340
|
-
|
|
1639
|
+
DataSourceList,
|
|
1341
1640
|
{
|
|
1342
1641
|
query,
|
|
1343
1642
|
onQueryChange: setQuery,
|
|
1344
1643
|
searchRef,
|
|
1345
|
-
|
|
1644
|
+
dataSources: filtered,
|
|
1346
1645
|
selectedId,
|
|
1347
|
-
onSelect:
|
|
1646
|
+
onSelect: handleSelectComponent,
|
|
1647
|
+
onSelectSlice: handleSelectSlice,
|
|
1348
1648
|
hidden: leftCollapsed
|
|
1349
1649
|
}
|
|
1350
1650
|
),
|
|
@@ -1379,6 +1679,7 @@ function StateInspectorUI() {
|
|
|
1379
1679
|
StateInspectorProvider,
|
|
1380
1680
|
StateInspectorUI,
|
|
1381
1681
|
createInspectorStore,
|
|
1682
|
+
inferMeta,
|
|
1382
1683
|
useComponentLabel,
|
|
1383
1684
|
useInspectableState,
|
|
1384
1685
|
useInspectorComponent,
|