what-devtools 0.6.0 → 0.6.2
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 +348 -0
- package/dist/index.js.map +7 -0
- package/dist/index.min.js +2 -0
- package/dist/index.min.js.map +7 -0
- package/dist/panel.js +476 -0
- package/dist/panel.js.map +7 -0
- package/dist/panel.min.js +2 -0
- package/dist/panel.min.js.map +7 -0
- package/index.d.ts +22 -0
- package/package.json +19 -7
- package/panel.d.ts +2 -0
- package/src/DevPanel.jsx +129 -356
- package/src/index.js +72 -9
package/dist/panel.js
ADDED
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
// packages/devtools/src/DevPanel.jsx
|
|
2
|
+
import { onCleanup } from "what-core";
|
|
3
|
+
|
|
4
|
+
// packages/devtools/src/index.js
|
|
5
|
+
var installed = false;
|
|
6
|
+
var signalId = 0;
|
|
7
|
+
var effectId = 0;
|
|
8
|
+
var componentId = 0;
|
|
9
|
+
var signals = /* @__PURE__ */ new Map();
|
|
10
|
+
var effects = /* @__PURE__ */ new Map();
|
|
11
|
+
var components = /* @__PURE__ */ new Map();
|
|
12
|
+
var subsToSignalId = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
var errors = [];
|
|
14
|
+
var MAX_ERRORS = 100;
|
|
15
|
+
var hydrationMismatches = [];
|
|
16
|
+
var MAX_HYDRATION_MISMATCHES = 50;
|
|
17
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
18
|
+
function emit(event, data) {
|
|
19
|
+
for (const fn of listeners) {
|
|
20
|
+
try {
|
|
21
|
+
fn(event, data);
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function safeSerialize(value, depth = 0, seen) {
|
|
27
|
+
if (depth > 6) return "[max depth]";
|
|
28
|
+
if (value === null || value === void 0) return value;
|
|
29
|
+
const type = typeof value;
|
|
30
|
+
if (type === "string" || type === "number" || type === "boolean") return value;
|
|
31
|
+
if (type === "function") return `[Function: ${value.name || "anonymous"}]`;
|
|
32
|
+
if (type === "symbol") return `[Symbol: ${value.description || ""}]`;
|
|
33
|
+
if (type === "bigint") return value.toString() + "n";
|
|
34
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
35
|
+
const tag = value.nodeName?.toLowerCase() || "node";
|
|
36
|
+
const id = value.id ? `#${value.id}` : "";
|
|
37
|
+
const cls = value.className ? `.${String(value.className).split(" ")[0]}` : "";
|
|
38
|
+
return `[DOM: <${tag}${id}${cls}>]`;
|
|
39
|
+
}
|
|
40
|
+
if (!seen) seen = /* @__PURE__ */ new Set();
|
|
41
|
+
if (seen.has(value)) return "[Circular]";
|
|
42
|
+
seen.add(value);
|
|
43
|
+
if (value instanceof Map) {
|
|
44
|
+
if (value.size > 50) return `[Map: ${value.size} entries]`;
|
|
45
|
+
const obj = {};
|
|
46
|
+
for (const [k, v] of value) {
|
|
47
|
+
obj[String(k)] = safeSerialize(v, depth + 1, seen);
|
|
48
|
+
}
|
|
49
|
+
return { __type: "Map", entries: obj };
|
|
50
|
+
}
|
|
51
|
+
if (value instanceof Set) {
|
|
52
|
+
if (value.size > 50) return `[Set: ${value.size} items]`;
|
|
53
|
+
return { __type: "Set", values: [...value].map((v) => safeSerialize(v, depth + 1, seen)) };
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(value)) {
|
|
56
|
+
if (value.length > 100) {
|
|
57
|
+
return [...value.slice(0, 100).map((v) => safeSerialize(v, depth + 1, seen)), `... (${value.length} total)`];
|
|
58
|
+
}
|
|
59
|
+
return value.map((v) => safeSerialize(v, depth + 1, seen));
|
|
60
|
+
}
|
|
61
|
+
if (value instanceof Error) {
|
|
62
|
+
return { __type: "Error", name: value.name, message: value.message, stack: value.stack };
|
|
63
|
+
}
|
|
64
|
+
if (value instanceof Date) return { __type: "Date", iso: value.toISOString() };
|
|
65
|
+
if (value instanceof RegExp) return value.toString();
|
|
66
|
+
if (type === "object") {
|
|
67
|
+
const keys = Object.keys(value);
|
|
68
|
+
if (keys.length > 100) {
|
|
69
|
+
const obj2 = {};
|
|
70
|
+
for (const k of keys.slice(0, 100)) {
|
|
71
|
+
obj2[k] = safeSerialize(value[k], depth + 1, seen);
|
|
72
|
+
}
|
|
73
|
+
obj2["..."] = `(${keys.length} total keys)`;
|
|
74
|
+
return obj2;
|
|
75
|
+
}
|
|
76
|
+
const obj = {};
|
|
77
|
+
for (const k of keys) {
|
|
78
|
+
obj[k] = safeSerialize(value[k], depth + 1, seen);
|
|
79
|
+
}
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
return String(value);
|
|
83
|
+
}
|
|
84
|
+
function registerSignal(sig, name) {
|
|
85
|
+
if (!installed) return;
|
|
86
|
+
const id = ++signalId;
|
|
87
|
+
const entry = {
|
|
88
|
+
id,
|
|
89
|
+
name: sig._debugName || name || `signal_${id}`,
|
|
90
|
+
ref: sig,
|
|
91
|
+
createdAt: Date.now(),
|
|
92
|
+
internal: false
|
|
93
|
+
};
|
|
94
|
+
signals.set(id, entry);
|
|
95
|
+
sig._devId = id;
|
|
96
|
+
if (sig._subs) subsToSignalId.set(sig._subs, id);
|
|
97
|
+
emit("signal:created", entry);
|
|
98
|
+
return id;
|
|
99
|
+
}
|
|
100
|
+
function notifySignalUpdate(sig) {
|
|
101
|
+
if (!installed) return;
|
|
102
|
+
const id = sig._devId;
|
|
103
|
+
if (id == null) return;
|
|
104
|
+
const entry = signals.get(id);
|
|
105
|
+
if (entry) {
|
|
106
|
+
emit("signal:updated", { id, name: entry.name, value: sig.peek() });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function unregisterSignal(sig) {
|
|
110
|
+
if (!installed) return;
|
|
111
|
+
const id = sig._devId;
|
|
112
|
+
if (id == null) return;
|
|
113
|
+
signals.delete(id);
|
|
114
|
+
emit("signal:disposed", { id });
|
|
115
|
+
}
|
|
116
|
+
function registerEffect(e, name) {
|
|
117
|
+
if (!installed) return;
|
|
118
|
+
const id = ++effectId;
|
|
119
|
+
const entry = {
|
|
120
|
+
id,
|
|
121
|
+
name: name || e.fn?.name || `effect_${id}`,
|
|
122
|
+
createdAt: Date.now(),
|
|
123
|
+
depSignalIds: [],
|
|
124
|
+
runCount: 0,
|
|
125
|
+
lastRunAt: null
|
|
126
|
+
};
|
|
127
|
+
effects.set(id, entry);
|
|
128
|
+
e._devId = id;
|
|
129
|
+
emit("effect:created", entry);
|
|
130
|
+
return id;
|
|
131
|
+
}
|
|
132
|
+
function trackEffectRun(e) {
|
|
133
|
+
const id = e._devId;
|
|
134
|
+
if (id == null) return;
|
|
135
|
+
const entry = effects.get(id);
|
|
136
|
+
if (!entry) return;
|
|
137
|
+
const depSignalIds = [];
|
|
138
|
+
if (e.deps) {
|
|
139
|
+
for (const subSet of e.deps) {
|
|
140
|
+
const sigId = subsToSignalId.get(subSet);
|
|
141
|
+
if (sigId != null) depSignalIds.push(sigId);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
entry.depSignalIds = depSignalIds;
|
|
145
|
+
entry.runCount = (entry.runCount || 0) + 1;
|
|
146
|
+
entry.lastRunAt = Date.now();
|
|
147
|
+
emit("effect:run", { id, depSignalIds: entry.depSignalIds, runCount: entry.runCount });
|
|
148
|
+
}
|
|
149
|
+
function unregisterEffect(e) {
|
|
150
|
+
if (!installed) return;
|
|
151
|
+
const id = e._devId;
|
|
152
|
+
if (id == null) return;
|
|
153
|
+
effects.delete(id);
|
|
154
|
+
emit("effect:disposed", { id });
|
|
155
|
+
}
|
|
156
|
+
function captureError(err, typeOrContext, context) {
|
|
157
|
+
const resolvedContext = typeof typeOrContext === "string" ? { ...context || {}, type: typeOrContext } : typeOrContext || context || {};
|
|
158
|
+
const entry = {
|
|
159
|
+
message: err?.message || String(err),
|
|
160
|
+
stack: err?.stack || null,
|
|
161
|
+
type: resolvedContext?.type || "unknown",
|
|
162
|
+
effectId: resolvedContext?.effect?._devId || null,
|
|
163
|
+
timestamp: Date.now()
|
|
164
|
+
};
|
|
165
|
+
errors.push(entry);
|
|
166
|
+
if (errors.length > MAX_ERRORS) errors.shift();
|
|
167
|
+
emit("error:captured", entry);
|
|
168
|
+
}
|
|
169
|
+
function registerComponent(name, element, parentDevId) {
|
|
170
|
+
if (!installed) return;
|
|
171
|
+
const id = ++componentId;
|
|
172
|
+
const entry = {
|
|
173
|
+
id,
|
|
174
|
+
name: name || "Anonymous",
|
|
175
|
+
element,
|
|
176
|
+
parentId: parentDevId || null,
|
|
177
|
+
mountedAt: Date.now()
|
|
178
|
+
};
|
|
179
|
+
components.set(id, entry);
|
|
180
|
+
emit("component:mounted", entry);
|
|
181
|
+
return id;
|
|
182
|
+
}
|
|
183
|
+
function unregisterComponent(id) {
|
|
184
|
+
if (!installed) return;
|
|
185
|
+
components.delete(id);
|
|
186
|
+
emit("component:unmounted", { id });
|
|
187
|
+
}
|
|
188
|
+
function subscribe(fn) {
|
|
189
|
+
listeners.add(fn);
|
|
190
|
+
return () => listeners.delete(fn);
|
|
191
|
+
}
|
|
192
|
+
function getSnapshot(opts = {}) {
|
|
193
|
+
const { includeInternal = false } = opts;
|
|
194
|
+
const signalList = [];
|
|
195
|
+
for (const [id, entry] of signals) {
|
|
196
|
+
if (!includeInternal && entry.internal) continue;
|
|
197
|
+
signalList.push({
|
|
198
|
+
id,
|
|
199
|
+
name: entry.name,
|
|
200
|
+
value: entry.ref.peek()
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
const effectList = [];
|
|
204
|
+
for (const [id, entry] of effects) {
|
|
205
|
+
effectList.push({
|
|
206
|
+
id,
|
|
207
|
+
name: entry.name,
|
|
208
|
+
depSignalIds: entry.depSignalIds || [],
|
|
209
|
+
runCount: entry.runCount || 0,
|
|
210
|
+
lastRunAt: entry.lastRunAt || null
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const componentList = [];
|
|
214
|
+
for (const [id, entry] of components) {
|
|
215
|
+
componentList.push({ id, name: entry.name, parentId: entry.parentId });
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
signals: signalList,
|
|
219
|
+
effects: effectList,
|
|
220
|
+
components: componentList,
|
|
221
|
+
errors: errors.slice(),
|
|
222
|
+
hydrationMismatches: hydrationMismatches.slice()
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function getErrors(opts = {}) {
|
|
226
|
+
const { since } = opts;
|
|
227
|
+
if (since) return errors.filter((e) => e.timestamp > since);
|
|
228
|
+
return errors.slice();
|
|
229
|
+
}
|
|
230
|
+
function getHydrationMismatches(opts = {}) {
|
|
231
|
+
const { since } = opts;
|
|
232
|
+
if (since) return hydrationMismatches.filter((m) => m.timestamp > since);
|
|
233
|
+
return hydrationMismatches.slice();
|
|
234
|
+
}
|
|
235
|
+
function resetDevTools() {
|
|
236
|
+
signals.clear();
|
|
237
|
+
effects.clear();
|
|
238
|
+
components.clear();
|
|
239
|
+
errors.length = 0;
|
|
240
|
+
hydrationMismatches.length = 0;
|
|
241
|
+
listeners.clear();
|
|
242
|
+
signalId = 0;
|
|
243
|
+
effectId = 0;
|
|
244
|
+
componentId = 0;
|
|
245
|
+
}
|
|
246
|
+
function installDevTools(core) {
|
|
247
|
+
if (installed) return;
|
|
248
|
+
installed = true;
|
|
249
|
+
const hooks = {
|
|
250
|
+
onSignalCreate: (sig) => registerSignal(sig),
|
|
251
|
+
onSignalUpdate: (sig) => notifySignalUpdate(sig),
|
|
252
|
+
onSignalDispose: (sig) => unregisterSignal(sig),
|
|
253
|
+
onEffectCreate: (e) => registerEffect(e),
|
|
254
|
+
onEffectDispose: (e) => unregisterEffect(e),
|
|
255
|
+
onEffectRun: (e) => trackEffectRun(e),
|
|
256
|
+
onError: (err, context) => captureError(err, context),
|
|
257
|
+
onHydrationMismatch: (info) => {
|
|
258
|
+
const entry = {
|
|
259
|
+
type: "hydration_mismatch",
|
|
260
|
+
component: info.component,
|
|
261
|
+
expected: info.expected,
|
|
262
|
+
actual: info.actual,
|
|
263
|
+
mismatchCount: info.mismatchCount,
|
|
264
|
+
timestamp: Date.now()
|
|
265
|
+
};
|
|
266
|
+
hydrationMismatches.push(entry);
|
|
267
|
+
if (hydrationMismatches.length > MAX_HYDRATION_MISMATCHES) hydrationMismatches.shift();
|
|
268
|
+
emit("hydration:mismatch", entry);
|
|
269
|
+
},
|
|
270
|
+
onComponentMount: (ctx) => {
|
|
271
|
+
const name = ctx.Component?.displayName || ctx.Component?.name || "Anonymous";
|
|
272
|
+
const parentDevId = ctx._parentCtx?._devId || null;
|
|
273
|
+
const id = registerComponent(name, ctx._wrapper, parentDevId);
|
|
274
|
+
ctx._devId = id;
|
|
275
|
+
},
|
|
276
|
+
onComponentUnmount: (ctx) => {
|
|
277
|
+
if (ctx._devId != null) unregisterComponent(ctx._devId);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
if (core && core.__setDevToolsHooks) {
|
|
281
|
+
core.__setDevToolsHooks(hooks);
|
|
282
|
+
if (typeof window !== "undefined") window.__WHAT_CORE__ = core;
|
|
283
|
+
} else {
|
|
284
|
+
try {
|
|
285
|
+
import("what-core/devtools").then((mod) => {
|
|
286
|
+
if (mod.__setDevToolsHooks) mod.__setDevToolsHooks(hooks);
|
|
287
|
+
if (typeof window !== "undefined") window.__WHAT_CORE_DEVTOOLS__ = mod;
|
|
288
|
+
}).catch((error) => warnDevToolsImportFailure(error));
|
|
289
|
+
} catch (error) {
|
|
290
|
+
warnDevToolsImportFailure(error);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (typeof window !== "undefined") {
|
|
294
|
+
window.__WHAT_DEVTOOLS__ = {
|
|
295
|
+
get signals() {
|
|
296
|
+
return getSnapshot().signals;
|
|
297
|
+
},
|
|
298
|
+
get effects() {
|
|
299
|
+
return getSnapshot().effects;
|
|
300
|
+
},
|
|
301
|
+
get components() {
|
|
302
|
+
return getSnapshot().components;
|
|
303
|
+
},
|
|
304
|
+
get errors() {
|
|
305
|
+
return getErrors();
|
|
306
|
+
},
|
|
307
|
+
get hydrationMismatches() {
|
|
308
|
+
return getHydrationMismatches();
|
|
309
|
+
},
|
|
310
|
+
getSnapshot,
|
|
311
|
+
getErrors,
|
|
312
|
+
getHydrationMismatches,
|
|
313
|
+
subscribe,
|
|
314
|
+
safeSerialize,
|
|
315
|
+
captureError,
|
|
316
|
+
resetDevTools,
|
|
317
|
+
_registries: { signals, effects, components, errors, hydrationMismatches }
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function warnDevToolsImportFailure(error) {
|
|
322
|
+
const isDev = typeof process === "undefined" || true;
|
|
323
|
+
if (!isDev || typeof console === "undefined") return;
|
|
324
|
+
console.warn(
|
|
325
|
+
"[what-devtools] Could not import what-core/devtools. Pass installDevTools({ __setDevToolsHooks }) or verify package subpath exports.",
|
|
326
|
+
error
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// packages/devtools/src/DevPanel.jsx
|
|
331
|
+
var MONO = "ui-monospace,SFMono-Regular,Menlo,monospace";
|
|
332
|
+
function DevPanel() {
|
|
333
|
+
installDevTools();
|
|
334
|
+
if (typeof document === "undefined") return null;
|
|
335
|
+
let activeTab = "signals";
|
|
336
|
+
let isOpen = false;
|
|
337
|
+
const root = document.createDocumentFragment();
|
|
338
|
+
const toggle = document.createElement("button");
|
|
339
|
+
toggle.type = "button";
|
|
340
|
+
toggle.textContent = "W";
|
|
341
|
+
toggle.title = "What Framework DevTools (Ctrl+Shift+D)";
|
|
342
|
+
toggle.setAttribute(
|
|
343
|
+
"style",
|
|
344
|
+
`position:fixed;bottom:12px;right:12px;z-index:99999;width:36px;height:36px;border-radius:8px;border:1px solid #2a2a4a;background:linear-gradient(135deg,#2563eb,#1d4ed8);color:#fff;font-weight:800;font-size:14px;cursor:pointer;font-family:${MONO};box-shadow:0 4px 12px rgba(37,99,235,0.3);`
|
|
345
|
+
);
|
|
346
|
+
const panel = document.createElement("div");
|
|
347
|
+
panel.setAttribute(
|
|
348
|
+
"style",
|
|
349
|
+
`position:fixed;bottom:0;right:0;width:380px;max-height:55vh;z-index:99998;font-family:${MONO};font-size:12px;background:#1a1a2e;color:#e0e0e0;border:1px solid #2a2a4a;border-radius:12px 0 0 0;box-shadow:0 -4px 24px rgba(0,0,0,0.3);display:none;flex-direction:column;overflow:hidden;`
|
|
350
|
+
);
|
|
351
|
+
root.append(toggle, panel);
|
|
352
|
+
function setOpen(next) {
|
|
353
|
+
isOpen = next;
|
|
354
|
+
panel.style.display = isOpen ? "flex" : "none";
|
|
355
|
+
if (isOpen) renderPanel();
|
|
356
|
+
}
|
|
357
|
+
toggle.addEventListener("click", () => setOpen(!isOpen));
|
|
358
|
+
const onKeyDown = (e) => {
|
|
359
|
+
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === "D") {
|
|
360
|
+
e.preventDefault();
|
|
361
|
+
setOpen(!isOpen);
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
document.addEventListener("keydown", onKeyDown);
|
|
365
|
+
const unsub = subscribe(() => {
|
|
366
|
+
if (isOpen) renderPanel();
|
|
367
|
+
});
|
|
368
|
+
const interval = setInterval(() => {
|
|
369
|
+
if (isOpen) renderPanel();
|
|
370
|
+
}, 500);
|
|
371
|
+
onCleanup(() => {
|
|
372
|
+
unsub();
|
|
373
|
+
clearInterval(interval);
|
|
374
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
375
|
+
});
|
|
376
|
+
function renderPanel() {
|
|
377
|
+
panel.replaceChildren(renderHeader(), renderTabs(), renderContent());
|
|
378
|
+
}
|
|
379
|
+
function renderHeader() {
|
|
380
|
+
const header = document.createElement("div");
|
|
381
|
+
header.setAttribute("style", "display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid #2a2a4a;background:#16163a;");
|
|
382
|
+
const title = document.createElement("span");
|
|
383
|
+
title.textContent = "What DevTools";
|
|
384
|
+
title.setAttribute("style", "font-weight:700;font-size:12px;color:#818cf8;");
|
|
385
|
+
const close = document.createElement("button");
|
|
386
|
+
close.type = "button";
|
|
387
|
+
close.textContent = "x";
|
|
388
|
+
close.setAttribute("style", "background:none;border:none;color:#6a6a8a;cursor:pointer;font-size:14px;");
|
|
389
|
+
close.addEventListener("click", () => setOpen(false));
|
|
390
|
+
header.append(title, close);
|
|
391
|
+
return header;
|
|
392
|
+
}
|
|
393
|
+
function renderTabs() {
|
|
394
|
+
const tabs = document.createElement("div");
|
|
395
|
+
tabs.setAttribute("style", "display:flex;gap:2px;padding:6px 8px;border-bottom:1px solid #2a2a4a;flex-wrap:wrap;");
|
|
396
|
+
for (const tab of ["signals", "effects", "components", "errors"]) {
|
|
397
|
+
const button = document.createElement("button");
|
|
398
|
+
button.type = "button";
|
|
399
|
+
button.textContent = tabLabel(tab);
|
|
400
|
+
button.setAttribute("style", tabStyle(tab));
|
|
401
|
+
button.addEventListener("click", () => {
|
|
402
|
+
activeTab = tab;
|
|
403
|
+
renderPanel();
|
|
404
|
+
});
|
|
405
|
+
tabs.append(button);
|
|
406
|
+
}
|
|
407
|
+
return tabs;
|
|
408
|
+
}
|
|
409
|
+
function tabLabel(tab) {
|
|
410
|
+
const snapshot = getSnapshot();
|
|
411
|
+
if (tab === "signals") return `Signals (${snapshot.signals.length})`;
|
|
412
|
+
if (tab === "effects") return `Effects (${snapshot.effects.length})`;
|
|
413
|
+
if (tab === "components") return `Components (${snapshot.components.length})`;
|
|
414
|
+
return `Errors (${getErrors().length})`;
|
|
415
|
+
}
|
|
416
|
+
function tabStyle(tab) {
|
|
417
|
+
const selected = activeTab === tab;
|
|
418
|
+
return "padding:6px 10px;border:none;background:" + (selected ? "#2a2a4a" : "transparent") + ";color:" + (selected ? "#fff" : "#6a6a8a") + `;cursor:pointer;font-family:${MONO};font-size:11px;font-weight:600;border-radius:4px;`;
|
|
419
|
+
}
|
|
420
|
+
function renderContent() {
|
|
421
|
+
const content = document.createElement("div");
|
|
422
|
+
content.setAttribute("style", "overflow-y:auto;flex:1;padding:8px;");
|
|
423
|
+
const snapshot = getSnapshot();
|
|
424
|
+
if (activeTab === "signals") {
|
|
425
|
+
renderRows(content, snapshot.signals, (signal) => [signal.name, formatValue(signal.value)], "#818cf8");
|
|
426
|
+
} else if (activeTab === "effects") {
|
|
427
|
+
renderRows(content, snapshot.effects, (effect) => [effect.name, `runs: ${effect.runCount || 0}`], "#fbbf24");
|
|
428
|
+
} else if (activeTab === "components") {
|
|
429
|
+
renderRows(content, snapshot.components, (component) => [`<${component.name} />`, ""], "#34d399");
|
|
430
|
+
} else {
|
|
431
|
+
renderRows(content, getErrors(), (error) => [`[${error.type}]`, error.message], "#f87171");
|
|
432
|
+
}
|
|
433
|
+
if (!content.childNodes.length) {
|
|
434
|
+
content.textContent = `No ${activeTab} tracked`;
|
|
435
|
+
content.style.color = "#4a4a6a";
|
|
436
|
+
content.style.padding = "12px";
|
|
437
|
+
}
|
|
438
|
+
return content;
|
|
439
|
+
}
|
|
440
|
+
function renderRows(parent, rows, mapRow, color) {
|
|
441
|
+
for (const row of rows) {
|
|
442
|
+
const [leftText, rightText] = mapRow(row);
|
|
443
|
+
const item = document.createElement("div");
|
|
444
|
+
item.setAttribute("style", "display:flex;justify-content:space-between;align-items:center;padding:4px 8px;border-bottom:1px solid #2a2a4a;gap:12px;");
|
|
445
|
+
const left = document.createElement("span");
|
|
446
|
+
left.textContent = leftText;
|
|
447
|
+
left.setAttribute("style", `color:${color};`);
|
|
448
|
+
const right = document.createElement("span");
|
|
449
|
+
right.textContent = rightText;
|
|
450
|
+
right.setAttribute("style", "color:#a0a0c0;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;");
|
|
451
|
+
item.append(left, right);
|
|
452
|
+
parent.append(item);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return root;
|
|
456
|
+
}
|
|
457
|
+
function formatValue(value) {
|
|
458
|
+
if (value === null) return "null";
|
|
459
|
+
if (value === void 0) return "undefined";
|
|
460
|
+
if (typeof value === "string") return `"${value.length > 30 ? value.slice(0, 30) + "..." : value}"`;
|
|
461
|
+
if (typeof value === "object") {
|
|
462
|
+
try {
|
|
463
|
+
const str = JSON.stringify(value);
|
|
464
|
+
return str.length > 40 ? str.slice(0, 40) + "..." : str;
|
|
465
|
+
} catch {
|
|
466
|
+
return "[Object]";
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return String(value);
|
|
470
|
+
}
|
|
471
|
+
var DevPanel_default = DevPanel;
|
|
472
|
+
export {
|
|
473
|
+
DevPanel,
|
|
474
|
+
DevPanel_default as default
|
|
475
|
+
};
|
|
476
|
+
//# sourceMappingURL=panel.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/DevPanel.jsx", "../src/index.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * What Framework DevPanel\n *\n * A small floating UI panel for browser-based devtools tests and local debugging.\n * It is intentionally implemented without JSX so the devtools package does not\n * depend on compiler fragment behavior to render its own diagnostics UI.\n */\n\nimport { onCleanup } from 'what-core';\nimport { subscribe, getSnapshot, getErrors, installDevTools } from './index.js';\n\nconst MONO = 'ui-monospace,SFMono-Regular,Menlo,monospace';\n\nexport function DevPanel() {\n installDevTools();\n\n if (typeof document === 'undefined') return null;\n\n let activeTab = 'signals';\n let isOpen = false;\n\n const root = document.createDocumentFragment();\n const toggle = document.createElement('button');\n toggle.type = 'button';\n toggle.textContent = 'W';\n toggle.title = 'What Framework DevTools (Ctrl+Shift+D)';\n toggle.setAttribute('style',\n 'position:fixed;bottom:12px;right:12px;z-index:99999;width:36px;height:36px;' +\n 'border-radius:8px;border:1px solid #2a2a4a;background:linear-gradient(135deg,#2563eb,#1d4ed8);' +\n `color:#fff;font-weight:800;font-size:14px;cursor:pointer;font-family:${MONO};` +\n 'box-shadow:0 4px 12px rgba(37,99,235,0.3);'\n );\n\n const panel = document.createElement('div');\n panel.setAttribute('style',\n 'position:fixed;bottom:0;right:0;width:380px;max-height:55vh;z-index:99998;' +\n `font-family:${MONO};font-size:12px;background:#1a1a2e;color:#e0e0e0;` +\n 'border:1px solid #2a2a4a;border-radius:12px 0 0 0;box-shadow:0 -4px 24px rgba(0,0,0,0.3);' +\n 'display:none;flex-direction:column;overflow:hidden;'\n );\n\n root.append(toggle, panel);\n\n function setOpen(next) {\n isOpen = next;\n panel.style.display = isOpen ? 'flex' : 'none';\n if (isOpen) renderPanel();\n }\n\n toggle.addEventListener('click', () => setOpen(!isOpen));\n\n const onKeyDown = (e) => {\n if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n setOpen(!isOpen);\n }\n };\n document.addEventListener('keydown', onKeyDown);\n\n const unsub = subscribe(() => {\n if (isOpen) renderPanel();\n });\n const interval = setInterval(() => {\n if (isOpen) renderPanel();\n }, 500);\n\n onCleanup(() => {\n unsub();\n clearInterval(interval);\n document.removeEventListener('keydown', onKeyDown);\n });\n\n function renderPanel() {\n panel.replaceChildren(renderHeader(), renderTabs(), renderContent());\n }\n\n function renderHeader() {\n const header = document.createElement('div');\n header.setAttribute('style', 'display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid #2a2a4a;background:#16163a;');\n\n const title = document.createElement('span');\n title.textContent = 'What DevTools';\n title.setAttribute('style', 'font-weight:700;font-size:12px;color:#818cf8;');\n\n const close = document.createElement('button');\n close.type = 'button';\n close.textContent = 'x';\n close.setAttribute('style', 'background:none;border:none;color:#6a6a8a;cursor:pointer;font-size:14px;');\n close.addEventListener('click', () => setOpen(false));\n\n header.append(title, close);\n return header;\n }\n\n function renderTabs() {\n const tabs = document.createElement('div');\n tabs.setAttribute('style', 'display:flex;gap:2px;padding:6px 8px;border-bottom:1px solid #2a2a4a;flex-wrap:wrap;');\n for (const tab of ['signals', 'effects', 'components', 'errors']) {\n const button = document.createElement('button');\n button.type = 'button';\n button.textContent = tabLabel(tab);\n button.setAttribute('style', tabStyle(tab));\n button.addEventListener('click', () => {\n activeTab = tab;\n renderPanel();\n });\n tabs.append(button);\n }\n return tabs;\n }\n\n function tabLabel(tab) {\n const snapshot = getSnapshot();\n if (tab === 'signals') return `Signals (${snapshot.signals.length})`;\n if (tab === 'effects') return `Effects (${snapshot.effects.length})`;\n if (tab === 'components') return `Components (${snapshot.components.length})`;\n return `Errors (${getErrors().length})`;\n }\n\n function tabStyle(tab) {\n const selected = activeTab === tab;\n return 'padding:6px 10px;border:none;background:' + (selected ? '#2a2a4a' : 'transparent') +\n ';color:' + (selected ? '#fff' : '#6a6a8a') +\n `;cursor:pointer;font-family:${MONO};font-size:11px;font-weight:600;border-radius:4px;`;\n }\n\n function renderContent() {\n const content = document.createElement('div');\n content.setAttribute('style', 'overflow-y:auto;flex:1;padding:8px;');\n const snapshot = getSnapshot();\n\n if (activeTab === 'signals') {\n renderRows(content, snapshot.signals, (signal) => [signal.name, formatValue(signal.value)], '#818cf8');\n } else if (activeTab === 'effects') {\n renderRows(content, snapshot.effects, (effect) => [effect.name, `runs: ${effect.runCount || 0}`], '#fbbf24');\n } else if (activeTab === 'components') {\n renderRows(content, snapshot.components, (component) => [`<${component.name} />`, ''], '#34d399');\n } else {\n renderRows(content, getErrors(), (error) => [`[${error.type}]`, error.message], '#f87171');\n }\n\n if (!content.childNodes.length) {\n content.textContent = `No ${activeTab} tracked`;\n content.style.color = '#4a4a6a';\n content.style.padding = '12px';\n }\n return content;\n }\n\n function renderRows(parent, rows, mapRow, color) {\n for (const row of rows) {\n const [leftText, rightText] = mapRow(row);\n const item = document.createElement('div');\n item.setAttribute('style', 'display:flex;justify-content:space-between;align-items:center;padding:4px 8px;border-bottom:1px solid #2a2a4a;gap:12px;');\n const left = document.createElement('span');\n left.textContent = leftText;\n left.setAttribute('style', `color:${color};`);\n const right = document.createElement('span');\n right.textContent = rightText;\n right.setAttribute('style', 'color:#a0a0c0;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;');\n item.append(left, right);\n parent.append(item);\n }\n }\n\n return root;\n}\n\nfunction formatValue(value) {\n if (value === null) return 'null';\n if (value === undefined) return 'undefined';\n if (typeof value === 'string') return `\"${value.length > 30 ? value.slice(0, 30) + '...' : value}\"`;\n if (typeof value === 'object') {\n try {\n const str = JSON.stringify(value);\n return str.length > 40 ? str.slice(0, 40) + '...' : str;\n } catch {\n return '[Object]';\n }\n }\n return String(value);\n}\n\nexport default DevPanel;\n", "/**\n * What Framework DevTools\n *\n * Runtime instrumentation for debugging signals, effects, and components.\n * In dev mode, exposes a `window.__WHAT_DEVTOOLS__` global for inspection.\n *\n * Usage:\n * import { installDevTools } from 'what-devtools';\n * installDevTools(); // Call once at app entry\n *\n * Then inspect in console:\n * __WHAT_DEVTOOLS__.signals // Map of all live signals\n * __WHAT_DEVTOOLS__.components // Map of mounted components\n * __WHAT_DEVTOOLS__.effects // Map of active effects\n */\n\nlet installed = false;\nlet signalId = 0;\nlet effectId = 0;\nlet componentId = 0;\n\n// Registries\nconst signals = new Map(); // id \u2192 { name, ref, createdAt, internal }\nconst effects = new Map(); // id \u2192 { name, createdAt, depSignalIds, runCount, lastRunAt }\nconst components = new Map(); // id \u2192 { name, element, mountedAt, parentId }\n\n// Reverse lookup: subscriber Set \u2192 signal ID (O(1) dep resolution)\nconst subsToSignalId = new WeakMap();\n\n// Error log (capped at 100)\nconst errors = [];\nconst MAX_ERRORS = 100;\n\n// Hydration mismatch log (capped at 50)\nconst hydrationMismatches = [];\nconst MAX_HYDRATION_MISMATCHES = 50;\n\n// Event listeners for the DevPanel\nconst listeners = new Set();\n\nfunction emit(event, data) {\n for (const fn of listeners) {\n try { fn(event, data); } catch {}\n }\n}\n\n/**\n * Safely serialize a value for transport (WS, JSON).\n * Handles DOM nodes, functions, circular refs, Maps, Sets, large collections.\n */\nexport function safeSerialize(value, depth = 0, seen) {\n if (depth > 6) return '[max depth]';\n if (value === null || value === undefined) return value;\n\n const type = typeof value;\n if (type === 'string' || type === 'number' || type === 'boolean') return value;\n if (type === 'function') return `[Function: ${value.name || 'anonymous'}]`;\n if (type === 'symbol') return `[Symbol: ${value.description || ''}]`;\n if (type === 'bigint') return value.toString() + 'n';\n\n // DOM nodes\n if (typeof Node !== 'undefined' && value instanceof Node) {\n const tag = value.nodeName?.toLowerCase() || 'node';\n const id = value.id ? `#${value.id}` : '';\n const cls = value.className ? `.${String(value.className).split(' ')[0]}` : '';\n return `[DOM: <${tag}${id}${cls}>]`;\n }\n\n if (!seen) seen = new Set();\n if (seen.has(value)) return '[Circular]';\n seen.add(value);\n\n // Map\n if (value instanceof Map) {\n if (value.size > 50) return `[Map: ${value.size} entries]`;\n const obj = {};\n for (const [k, v] of value) {\n obj[String(k)] = safeSerialize(v, depth + 1, seen);\n }\n return { __type: 'Map', entries: obj };\n }\n\n // Set\n if (value instanceof Set) {\n if (value.size > 50) return `[Set: ${value.size} items]`;\n return { __type: 'Set', values: [...value].map(v => safeSerialize(v, depth + 1, seen)) };\n }\n\n // Array\n if (Array.isArray(value)) {\n if (value.length > 100) {\n return [...value.slice(0, 100).map(v => safeSerialize(v, depth + 1, seen)), `... (${value.length} total)`];\n }\n return value.map(v => safeSerialize(v, depth + 1, seen));\n }\n\n // Error\n if (value instanceof Error) {\n return { __type: 'Error', name: value.name, message: value.message, stack: value.stack };\n }\n\n // Date\n if (value instanceof Date) return { __type: 'Date', iso: value.toISOString() };\n\n // RegExp\n if (value instanceof RegExp) return value.toString();\n\n // Plain object\n if (type === 'object') {\n const keys = Object.keys(value);\n if (keys.length > 100) {\n const obj = {};\n for (const k of keys.slice(0, 100)) {\n obj[k] = safeSerialize(value[k], depth + 1, seen);\n }\n obj['...'] = `(${keys.length} total keys)`;\n return obj;\n }\n const obj = {};\n for (const k of keys) {\n obj[k] = safeSerialize(value[k], depth + 1, seen);\n }\n return obj;\n }\n\n return String(value);\n}\n\n/**\n * Register a signal with the devtools.\n * Called from reactive.js __DEV__ hooks.\n */\nexport function registerSignal(sig, name) {\n if (!installed) return;\n const id = ++signalId;\n const entry = {\n id,\n name: sig._debugName || name || `signal_${id}`,\n ref: sig,\n createdAt: Date.now(),\n internal: false,\n };\n signals.set(id, entry);\n sig._devId = id;\n // Reverse lookup for O(1) effect dep resolution\n if (sig._subs) subsToSignalId.set(sig._subs, id);\n emit('signal:created', entry);\n return id;\n}\n\n/**\n * Notify devtools that a signal value changed.\n */\nexport function notifySignalUpdate(sig) {\n if (!installed) return;\n const id = sig._devId;\n if (id == null) return;\n const entry = signals.get(id);\n if (entry) {\n emit('signal:updated', { id, name: entry.name, value: sig.peek() });\n }\n}\n\n/**\n * Unregister a signal (when disposed via createRoot cleanup).\n */\nexport function unregisterSignal(sig) {\n if (!installed) return;\n const id = sig._devId;\n if (id == null) return;\n signals.delete(id);\n emit('signal:disposed', { id });\n}\n\n/**\n * Register an effect with the devtools.\n */\nexport function registerEffect(e, name) {\n if (!installed) return;\n const id = ++effectId;\n const entry = {\n id,\n name: name || e.fn?.name || `effect_${id}`,\n createdAt: Date.now(),\n depSignalIds: [],\n runCount: 0,\n lastRunAt: null,\n };\n effects.set(id, entry);\n e._devId = id;\n emit('effect:created', entry);\n return id;\n}\n\n/**\n * Track effect dependencies and run count after an effect runs.\n */\nfunction trackEffectRun(e) {\n const id = e._devId;\n if (id == null) return;\n const entry = effects.get(id);\n if (!entry) return;\n\n // Resolve deps via WeakMap reverse lookup \u2014 O(m) where m = number of deps\n const depSignalIds = [];\n if (e.deps) {\n for (const subSet of e.deps) {\n const sigId = subsToSignalId.get(subSet);\n if (sigId != null) depSignalIds.push(sigId);\n }\n }\n\n entry.depSignalIds = depSignalIds;\n entry.runCount = (entry.runCount || 0) + 1;\n entry.lastRunAt = Date.now();\n emit('effect:run', { id, depSignalIds: entry.depSignalIds, runCount: entry.runCount });\n}\n\n/**\n * Unregister an effect.\n */\nexport function unregisterEffect(e) {\n if (!installed) return;\n const id = e._devId;\n if (id == null) return;\n effects.delete(id);\n emit('effect:disposed', { id });\n}\n\n/**\n * Capture a runtime error.\n */\nexport function captureError(err, typeOrContext, context) {\n const resolvedContext = typeof typeOrContext === 'string'\n ? { ...(context || {}), type: typeOrContext }\n : (typeOrContext || context || {});\n const entry = {\n message: err?.message || String(err),\n stack: err?.stack || null,\n type: resolvedContext?.type || 'unknown',\n effectId: resolvedContext?.effect?._devId || null,\n timestamp: Date.now(),\n };\n errors.push(entry);\n if (errors.length > MAX_ERRORS) errors.shift();\n emit('error:captured', entry);\n}\n\n/**\n * Register a component mount.\n */\nexport function registerComponent(name, element, parentDevId) {\n if (!installed) return;\n const id = ++componentId;\n const entry = {\n id,\n name: name || 'Anonymous',\n element,\n parentId: parentDevId || null,\n mountedAt: Date.now(),\n };\n components.set(id, entry);\n emit('component:mounted', entry);\n return id;\n}\n\n/**\n * Unregister a component (unmount).\n */\nexport function unregisterComponent(id) {\n if (!installed) return;\n components.delete(id);\n emit('component:unmounted', { id });\n}\n\n/**\n * Subscribe to devtools events.\n * Returns an unsubscribe function.\n */\nexport function subscribe(fn) {\n listeners.add(fn);\n return () => listeners.delete(fn);\n}\n\n/**\n * Get a snapshot of all tracked state.\n * @param {object} [opts] - Options\n * @param {boolean} [opts.includeInternal=false] - Include framework-internal signals\n */\nexport function getSnapshot(opts = {}) {\n const { includeInternal = false } = opts;\n\n const signalList = [];\n for (const [id, entry] of signals) {\n if (!includeInternal && entry.internal) continue;\n signalList.push({\n id,\n name: entry.name,\n value: entry.ref.peek(),\n });\n }\n\n const effectList = [];\n for (const [id, entry] of effects) {\n effectList.push({\n id,\n name: entry.name,\n depSignalIds: entry.depSignalIds || [],\n runCount: entry.runCount || 0,\n lastRunAt: entry.lastRunAt || null,\n });\n }\n\n const componentList = [];\n for (const [id, entry] of components) {\n componentList.push({ id, name: entry.name, parentId: entry.parentId });\n }\n\n return {\n signals: signalList,\n effects: effectList,\n components: componentList,\n errors: errors.slice(),\n hydrationMismatches: hydrationMismatches.slice(),\n };\n}\n\n/**\n * Get captured errors.\n * @param {object} [opts]\n * @param {number} [opts.since] - Only errors after this timestamp\n */\nexport function getErrors(opts = {}) {\n const { since } = opts;\n if (since) return errors.filter(e => e.timestamp > since);\n return errors.slice();\n}\n\n/**\n * Get captured hydration mismatches.\n * @param {object} [opts]\n * @param {number} [opts.since] - Only mismatches after this timestamp\n */\nexport function getHydrationMismatches(opts = {}) {\n const { since } = opts;\n if (since) return hydrationMismatches.filter(m => m.timestamp > since);\n return hydrationMismatches.slice();\n}\n\n/**\n * Reset devtools registries and captured logs.\n */\nexport function resetDevTools() {\n signals.clear();\n effects.clear();\n components.clear();\n errors.length = 0;\n hydrationMismatches.length = 0;\n listeners.clear();\n signalId = 0;\n effectId = 0;\n componentId = 0;\n}\n\n/**\n * Install devtools. Call once at app startup.\n * Wires into what-core's __DEV__ hooks and exposes `window.__WHAT_DEVTOOLS__`.\n *\n * @param {object} [core] - Optional what-core module. If not provided, attempts dynamic import.\n */\nexport function installDevTools(core) {\n if (installed) return;\n installed = true;\n\n const hooks = {\n onSignalCreate: (sig) => registerSignal(sig),\n onSignalUpdate: (sig) => notifySignalUpdate(sig),\n onSignalDispose: (sig) => unregisterSignal(sig),\n onEffectCreate: (e) => registerEffect(e),\n onEffectDispose: (e) => unregisterEffect(e),\n onEffectRun: (e) => trackEffectRun(e),\n onError: (err, context) => captureError(err, context),\n onHydrationMismatch: (info) => {\n const entry = {\n type: 'hydration_mismatch',\n component: info.component,\n expected: info.expected,\n actual: info.actual,\n mismatchCount: info.mismatchCount,\n timestamp: Date.now(),\n };\n hydrationMismatches.push(entry);\n if (hydrationMismatches.length > MAX_HYDRATION_MISMATCHES) hydrationMismatches.shift();\n emit('hydration:mismatch', entry);\n },\n onComponentMount: (ctx) => {\n const name = ctx.Component?.displayName || ctx.Component?.name || 'Anonymous';\n const parentDevId = ctx._parentCtx?._devId || null;\n const id = registerComponent(name, ctx._wrapper, parentDevId);\n ctx._devId = id;\n },\n onComponentUnmount: (ctx) => {\n if (ctx._devId != null) unregisterComponent(ctx._devId);\n },\n };\n\n // Wire into what-core's reactive system\n if (core && core.__setDevToolsHooks) {\n core.__setDevToolsHooks(hooks);\n if (typeof window !== 'undefined') window.__WHAT_CORE__ = core;\n } else {\n try {\n import('what-core/devtools').then(mod => {\n if (mod.__setDevToolsHooks) mod.__setDevToolsHooks(hooks);\n if (typeof window !== 'undefined') window.__WHAT_CORE_DEVTOOLS__ = mod;\n }).catch((error) => warnDevToolsImportFailure(error));\n } catch (error) {\n warnDevToolsImportFailure(error);\n }\n }\n\n if (typeof window !== 'undefined') {\n window.__WHAT_DEVTOOLS__ = {\n get signals() { return getSnapshot().signals; },\n get effects() { return getSnapshot().effects; },\n get components() { return getSnapshot().components; },\n get errors() { return getErrors(); },\n get hydrationMismatches() { return getHydrationMismatches(); },\n getSnapshot,\n getErrors,\n getHydrationMismatches,\n subscribe,\n safeSerialize,\n captureError,\n resetDevTools,\n _registries: { signals, effects, components, errors, hydrationMismatches },\n };\n }\n}\n\nexport { signals, effects, components, errors, hydrationMismatches };\n\nfunction warnDevToolsImportFailure(error) {\n const isDev = typeof process === 'undefined' || process.env?.NODE_ENV !== 'production';\n if (!isDev || typeof console === 'undefined') return;\n console.warn(\n '[what-devtools] Could not import what-core/devtools. Pass installDevTools({ __setDevToolsHooks }) or verify package subpath exports.',\n error\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["obj"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{onCleanup as rt}from"what-core";var l=!1,O=0,R=0,N=0,y=new Map,x=new Map,h=new Map,H=new WeakMap,u=[],J=100,p=[],Y=50,E=new Set;function d(t,n){for(let e of E)try{e(t,n)}catch{}}function m(t,n=0,e){if(n>6)return"[max depth]";if(t==null)return t;let o=typeof t;if(o==="string"||o==="number"||o==="boolean")return t;if(o==="function")return`[Function: ${t.name||"anonymous"}]`;if(o==="symbol")return`[Symbol: ${t.description||""}]`;if(o==="bigint")return t.toString()+"n";if(typeof Node<"u"&&t instanceof Node){let s=t.nodeName?.toLowerCase()||"node",a=t.id?`#${t.id}`:"",i=t.className?`.${String(t.className).split(" ")[0]}`:"";return`[DOM: <${s}${a}${i}>]`}if(e||(e=new Set),e.has(t))return"[Circular]";if(e.add(t),t instanceof Map){if(t.size>50)return`[Map: ${t.size} entries]`;let s={};for(let[a,i]of t)s[String(a)]=m(i,n+1,e);return{__type:"Map",entries:s}}if(t instanceof Set)return t.size>50?`[Set: ${t.size} items]`:{__type:"Set",values:[...t].map(s=>m(s,n+1,e))};if(Array.isArray(t))return t.length>100?[...t.slice(0,100).map(s=>m(s,n+1,e)),`... (${t.length} total)`]:t.map(s=>m(s,n+1,e));if(t instanceof Error)return{__type:"Error",name:t.name,message:t.message,stack:t.stack};if(t instanceof Date)return{__type:"Date",iso:t.toISOString()};if(t instanceof RegExp)return t.toString();if(o==="object"){let s=Object.keys(t);if(s.length>100){let i={};for(let _ of s.slice(0,100))i[_]=m(t[_],n+1,e);return i["..."]=`(${s.length} total keys)`,i}let a={};for(let i of s)a[i]=m(t[i],n+1,e);return a}return String(t)}function q(t,n){if(!l)return;let e=++O,o={id:e,name:t._debugName||n||`signal_${e}`,ref:t,createdAt:Date.now(),internal:!1};return y.set(e,o),t._devId=e,t._subs&&H.set(t._subs,e),d("signal:created",o),e}function B(t){if(!l)return;let n=t._devId;if(n==null)return;let e=y.get(n);e&&d("signal:updated",{id:n,name:e.name,value:t.peek()})}function G(t){if(!l)return;let n=t._devId;n!=null&&(y.delete(n),d("signal:disposed",{id:n}))}function Q(t,n){if(!l)return;let e=++R,o={id:e,name:n||t.fn?.name||`effect_${e}`,createdAt:Date.now(),depSignalIds:[],runCount:0,lastRunAt:null};return x.set(e,o),t._devId=e,d("effect:created",o),e}function Z(t){let n=t._devId;if(n==null)return;let e=x.get(n);if(!e)return;let o=[];if(t.deps)for(let s of t.deps){let a=H.get(s);a!=null&&o.push(a)}e.depSignalIds=o,e.runCount=(e.runCount||0)+1,e.lastRunAt=Date.now(),d("effect:run",{id:n,depSignalIds:e.depSignalIds,runCount:e.runCount})}function tt(t){if(!l)return;let n=t._devId;n!=null&&(x.delete(n),d("effect:disposed",{id:n}))}function $(t,n,e){let o=typeof n=="string"?{...e||{},type:n}:n||e||{},s={message:t?.message||String(t),stack:t?.stack||null,type:o?.type||"unknown",effectId:o?.effect?._devId||null,timestamp:Date.now()};u.push(s),u.length>J&&u.shift(),d("error:captured",s)}function et(t,n,e){if(!l)return;let o=++N,s={id:o,name:t||"Anonymous",element:n,parentId:e||null,mountedAt:Date.now()};return h.set(o,s),d("component:mounted",s),o}function nt(t){l&&(h.delete(t),d("component:unmounted",{id:t}))}function I(t){return E.add(t),()=>E.delete(t)}function g(t={}){let{includeInternal:n=!1}=t,e=[];for(let[a,i]of y)!n&&i.internal||e.push({id:a,name:i.name,value:i.ref.peek()});let o=[];for(let[a,i]of x)o.push({id:a,name:i.name,depSignalIds:i.depSignalIds||[],runCount:i.runCount||0,lastRunAt:i.lastRunAt||null});let s=[];for(let[a,i]of h)s.push({id:a,name:i.name,parentId:i.parentId});return{signals:e,effects:o,components:s,errors:u.slice(),hydrationMismatches:p.slice()}}function b(t={}){let{since:n}=t;return n?u.filter(e=>e.timestamp>n):u.slice()}function T(t={}){let{since:n}=t;return n?p.filter(e=>e.timestamp>n):p.slice()}function ot(){y.clear(),x.clear(),h.clear(),u.length=0,p.length=0,E.clear(),O=0,R=0,N=0}function z(t){if(l)return;l=!0;let n={onSignalCreate:e=>q(e),onSignalUpdate:e=>B(e),onSignalDispose:e=>G(e),onEffectCreate:e=>Q(e),onEffectDispose:e=>tt(e),onEffectRun:e=>Z(e),onError:(e,o)=>$(e,o),onHydrationMismatch:e=>{let o={type:"hydration_mismatch",component:e.component,expected:e.expected,actual:e.actual,mismatchCount:e.mismatchCount,timestamp:Date.now()};p.push(o),p.length>Y&&p.shift(),d("hydration:mismatch",o)},onComponentMount:e=>{let o=e.Component?.displayName||e.Component?.name||"Anonymous",s=e._parentCtx?._devId||null,a=et(o,e._wrapper,s);e._devId=a},onComponentUnmount:e=>{e._devId!=null&&nt(e._devId)}};if(t&&t.__setDevToolsHooks)t.__setDevToolsHooks(n),typeof window<"u"&&(window.__WHAT_CORE__=t);else try{import("what-core/devtools").then(e=>{e.__setDevToolsHooks&&e.__setDevToolsHooks(n),typeof window<"u"&&(window.__WHAT_CORE_DEVTOOLS__=e)}).catch(e=>M(e))}catch(e){M(e)}typeof window<"u"&&(window.__WHAT_DEVTOOLS__={get signals(){return g().signals},get effects(){return g().effects},get components(){return g().components},get errors(){return b()},get hydrationMismatches(){return T()},getSnapshot:g,getErrors:b,getHydrationMismatches:T,subscribe:I,safeSerialize:m,captureError:$,resetDevTools:ot,_registries:{signals:y,effects:x,components:h,errors:u,hydrationMismatches:p}})}function M(t){!(typeof process>"u")||typeof console>"u"||console.warn("[what-devtools] Could not import what-core/devtools. Pass installDevTools({ __setDevToolsHooks }) or verify package subpath exports.",t)}var A="ui-monospace,SFMono-Regular,Menlo,monospace";function st(){if(z(),typeof document>"u")return null;let t="signals",n=!1,e=document.createDocumentFragment(),o=document.createElement("button");o.type="button",o.textContent="W",o.title="What Framework DevTools (Ctrl+Shift+D)",o.setAttribute("style",`position:fixed;bottom:12px;right:12px;z-index:99999;width:36px;height:36px;border-radius:8px;border:1px solid #2a2a4a;background:linear-gradient(135deg,#2563eb,#1d4ed8);color:#fff;font-weight:800;font-size:14px;cursor:pointer;font-family:${A};box-shadow:0 4px 12px rgba(37,99,235,0.3);`);let s=document.createElement("div");s.setAttribute("style",`position:fixed;bottom:0;right:0;width:380px;max-height:55vh;z-index:99998;font-family:${A};font-size:12px;background:#1a1a2e;color:#e0e0e0;border:1px solid #2a2a4a;border-radius:12px 0 0 0;box-shadow:0 -4px 24px rgba(0,0,0,0.3);display:none;flex-direction:column;overflow:hidden;`),e.append(o,s);function a(r){n=r,s.style.display=n?"flex":"none",n&&w()}o.addEventListener("click",()=>a(!n));let i=r=>{(r.ctrlKey||r.metaKey)&&r.shiftKey&&r.key==="D"&&(r.preventDefault(),a(!n))};document.addEventListener("keydown",i);let _=I(()=>{n&&w()}),L=setInterval(()=>{n&&w()},500);rt(()=>{_(),clearInterval(L),document.removeEventListener("keydown",i)});function w(){s.replaceChildren(v(),j(),K())}function v(){let r=document.createElement("div");r.setAttribute("style","display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid #2a2a4a;background:#16163a;");let f=document.createElement("span");f.textContent="What DevTools",f.setAttribute("style","font-weight:700;font-size:12px;color:#818cf8;");let c=document.createElement("button");return c.type="button",c.textContent="x",c.setAttribute("style","background:none;border:none;color:#6a6a8a;cursor:pointer;font-size:14px;"),c.addEventListener("click",()=>a(!1)),r.append(f,c),r}function j(){let r=document.createElement("div");r.setAttribute("style","display:flex;gap:2px;padding:6px 8px;border-bottom:1px solid #2a2a4a;flex-wrap:wrap;");for(let f of["signals","effects","components","errors"]){let c=document.createElement("button");c.type="button",c.textContent=W(f),c.setAttribute("style",F(f)),c.addEventListener("click",()=>{t=f,w()}),r.append(c)}return r}function W(r){let f=g();return r==="signals"?`Signals (${f.signals.length})`:r==="effects"?`Effects (${f.effects.length})`:r==="components"?`Components (${f.components.length})`:`Errors (${b().length})`}function F(r){let f=t===r;return"padding:6px 10px;border:none;background:"+(f?"#2a2a4a":"transparent")+";color:"+(f?"#fff":"#6a6a8a")+`;cursor:pointer;font-family:${A};font-size:11px;font-weight:600;border-radius:4px;`}function K(){let r=document.createElement("div");r.setAttribute("style","overflow-y:auto;flex:1;padding:8px;");let f=g();return t==="signals"?S(r,f.signals,c=>[c.name,it(c.value)],"#818cf8"):t==="effects"?S(r,f.effects,c=>[c.name,`runs: ${c.runCount||0}`],"#fbbf24"):t==="components"?S(r,f.components,c=>[`<${c.name} />`,""],"#34d399"):S(r,b(),c=>[`[${c.type}]`,c.message],"#f87171"),r.childNodes.length||(r.textContent=`No ${t} tracked`,r.style.color="#4a4a6a",r.style.padding="12px"),r}function S(r,f,c,V){for(let P of f){let[U,X]=c(P),C=document.createElement("div");C.setAttribute("style","display:flex;justify-content:space-between;align-items:center;padding:4px 8px;border-bottom:1px solid #2a2a4a;gap:12px;");let D=document.createElement("span");D.textContent=U,D.setAttribute("style",`color:${V};`);let k=document.createElement("span");k.textContent=X,k.setAttribute("style","color:#a0a0c0;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"),C.append(D,k),r.append(C)}}return e}function it(t){if(t===null)return"null";if(t===void 0)return"undefined";if(typeof t=="string")return`"${t.length>30?t.slice(0,30)+"...":t}"`;if(typeof t=="object")try{let n=JSON.stringify(t);return n.length>40?n.slice(0,40)+"...":n}catch{return"[Object]"}return String(t)}var dt=st;export{st as DevPanel,dt as default};
|
|
2
|
+
//# sourceMappingURL=panel.min.js.map
|