@versini/ui-debug-overlay 1.1.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -25
- package/dist/components/DebugOverlay/DebugOverlay.js +90 -92
- package/dist/index.d.ts +48 -15
- package/dist/index.js +11 -11
- package/package.json +3 -7
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
- Automatically snapshot an `appState` object on referential changes
|
|
11
11
|
- Push manual, labeled, color‑coded snapshots from anywhere (via a hook)
|
|
12
12
|
- Target snapshots to specific overlay instances
|
|
13
|
-
- Copy a merged chronological timeline (
|
|
13
|
+
- Copy a merged chronological timeline (always includes manual snapshots)
|
|
14
14
|
- Clear everything in a click
|
|
15
15
|
- Position the panel with shorthands or explicit edges
|
|
16
16
|
- Keep bundle weight minimal (inline styles only, no CSS frameworks)
|
|
@@ -57,14 +57,10 @@ export function App() {
|
|
|
57
57
|
Use the hook to push ad‑hoc snapshots (successful responses, errors, timings, etc.).
|
|
58
58
|
|
|
59
59
|
```tsx
|
|
60
|
-
import {
|
|
61
|
-
useDebugSnapshot,
|
|
62
|
-
LOG_GREEN,
|
|
63
|
-
LOG_RED
|
|
64
|
-
} from "@versini/ui-debug-overlay";
|
|
60
|
+
import { useDebugOverlay, LOG_GREEN, LOG_RED } from "@versini/ui-debug-overlay";
|
|
65
61
|
|
|
66
62
|
function SomeLogic() {
|
|
67
|
-
const debug =
|
|
63
|
+
const debug = useDebugOverlay();
|
|
68
64
|
|
|
69
65
|
async function run() {
|
|
70
66
|
debug("start", { ts: Date.now() });
|
|
@@ -83,7 +79,7 @@ function SomeLogic() {
|
|
|
83
79
|
## Multiple / Targeted Overlays
|
|
84
80
|
|
|
85
81
|
```tsx
|
|
86
|
-
const debug =
|
|
82
|
+
const debug = useDebugOverlay();
|
|
87
83
|
|
|
88
84
|
debug("metrics", { fps: 60 }, { targetOverlays: ["perf"] });
|
|
89
85
|
|
|
@@ -120,11 +116,7 @@ Supported shorthands: `left`, `right`, `top`, `bottom`, `top-left`, `top-right`,
|
|
|
120
116
|
|
|
121
117
|
## Copy Behavior
|
|
122
118
|
|
|
123
|
-
Pressing "Copy" produces a plain text timeline. Chronological numbering always starts at `#1` (oldest), even if UI order shows newest first.
|
|
124
|
-
|
|
125
|
-
```tsx
|
|
126
|
-
<DebugOverlay appState={state} includeManualInCopy={false} />
|
|
127
|
-
```
|
|
119
|
+
Pressing "Copy" produces a plain text timeline. Chronological numbering always starts at `#1` (oldest), even if UI order shows newest first. Manual snapshots are always included.
|
|
128
120
|
|
|
129
121
|
## Collapsing
|
|
130
122
|
|
|
@@ -144,15 +136,14 @@ Pressing "Copy" produces a plain text timeline. Chronological numbering always s
|
|
|
144
136
|
| `maxBodyHeight` | `number | string` | `320` | Scroll region max height. |
|
|
145
137
|
| `indent` | `number` | `2` | JSON indent spaces. |
|
|
146
138
|
| `maxSnapshots` | `number` | `50` | Retained automatic state snapshot cap (FIFO). |
|
|
147
|
-
| `maxVisibleSnapshots` | `number` | `
|
|
139
|
+
| `maxVisibleSnapshots` | `number` | `10` | Visible snapshot limit; remainder summarized. |
|
|
148
140
|
| `snapshotOrder` | `"asc" | "desc"` | `"desc"` | Visual ordering only. Numbering stays chronological. |
|
|
149
141
|
| `appendSnapshotCountInTitle` | `boolean` | `false` | Append live count to title. |
|
|
150
|
-
| `includeManualInCopy` | `boolean` | `true` | Include manual snapshots in copy output. |
|
|
151
142
|
|
|
152
|
-
## Hook: `
|
|
143
|
+
## Hook: `useDebugOverlay()`
|
|
153
144
|
|
|
154
145
|
```ts
|
|
155
|
-
const debug =
|
|
146
|
+
const debug = useDebugOverlay();
|
|
156
147
|
|
|
157
148
|
debug(
|
|
158
149
|
label: string,
|
|
@@ -170,14 +161,6 @@ Color constants: `LOG_YELLOW`, `LOG_GREEN`, `LOG_BLUE`, `LOG_MAGENTA`, `LOG_RED`
|
|
|
170
161
|
- Multiple overlays can focus on separate domains (state vs. performance vs. network)
|
|
171
162
|
- Use colors to visually cluster snapshot categories (success, error, timing)
|
|
172
163
|
|
|
173
|
-
## Accessibility
|
|
174
|
-
|
|
175
|
-
Buttons include accessible labels; simple semantic markup keeps the overlay screen‑reader friendly while remaining visually unobtrusive. Inline styles avoid CSS collisions.
|
|
176
|
-
|
|
177
164
|
## License
|
|
178
165
|
|
|
179
166
|
MIT © Arno Versini
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
Open an issue for enhancements (redaction hooks, diff mode, retention strategies, pause/resume, etc.).
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { jsxs as L, jsx as g } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback as _, useState as x, useRef as
|
|
3
|
-
const
|
|
4
|
-
let
|
|
2
|
+
import { useCallback as _, useState as x, useRef as V, useMemo as h, useEffect as S } from "react";
|
|
3
|
+
const re = "LOG_YELLOW", ne = "LOG_GREEN", se = "LOG_BLUE", ae = "LOG_MAGENTA", le = "LOG_RED", ee = 200;
|
|
4
|
+
let W = 0;
|
|
5
5
|
const p = [], $ = /* @__PURE__ */ new Set();
|
|
6
|
-
function
|
|
7
|
-
p.length = 0,
|
|
6
|
+
function ie() {
|
|
7
|
+
p.length = 0, W = 0;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
return
|
|
9
|
+
function F() {
|
|
10
|
+
return W++;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function z(s) {
|
|
13
13
|
const a = {
|
|
14
14
|
kind: "manual",
|
|
15
15
|
ts: Date.now(),
|
|
16
|
-
seq:
|
|
16
|
+
seq: F(),
|
|
17
17
|
label: s.label,
|
|
18
18
|
data: s.data,
|
|
19
19
|
color: s.color,
|
|
20
20
|
targetOverlays: s.targetOverlays && s.targetOverlays.length ? [...s.targetOverlays] : void 0
|
|
21
21
|
};
|
|
22
|
-
p.push(a), p.length >
|
|
22
|
+
p.push(a), p.length > ee && p.shift(), $.forEach((l) => l(a));
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function ce() {
|
|
25
25
|
return _(
|
|
26
26
|
(s, a, l) => {
|
|
27
|
-
|
|
27
|
+
z(typeof l == "string" ? { label: s, data: a, color: l } : {
|
|
28
28
|
label: s,
|
|
29
29
|
data: a,
|
|
30
30
|
color: l?.color,
|
|
@@ -34,7 +34,7 @@ function dt() {
|
|
|
34
34
|
[]
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function N(s, a = 2) {
|
|
38
38
|
const l = /* @__PURE__ */ new WeakSet(), c = (o) => {
|
|
39
39
|
if (!o || typeof o != "object" || o instanceof Date || o instanceof RegExp)
|
|
40
40
|
return o;
|
|
@@ -53,82 +53,80 @@ function W(s, a = 2) {
|
|
|
53
53
|
return `<<unserializable: ${o.message}>>`;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
const
|
|
56
|
+
const de = ({
|
|
57
57
|
appState: s,
|
|
58
58
|
title: a = "AppState",
|
|
59
59
|
initialCollapsed: l = !1,
|
|
60
60
|
overlayId: c = "default",
|
|
61
61
|
position: o,
|
|
62
|
-
maxBodyHeight: y =
|
|
62
|
+
maxBodyHeight: y = "50svh",
|
|
63
63
|
indent: d = 2,
|
|
64
64
|
maxSnapshots: C = 50,
|
|
65
|
-
maxVisibleSnapshots: v =
|
|
65
|
+
maxVisibleSnapshots: v = 10,
|
|
66
66
|
snapshotOrder: A = "desc",
|
|
67
|
-
appendSnapshotCountInTitle:
|
|
68
|
-
includeManualInCopy: R = !0
|
|
67
|
+
appendSnapshotCountInTitle: U = !1
|
|
69
68
|
}) => {
|
|
70
|
-
const [b, I] = x(l), [
|
|
69
|
+
const [b, I] = x(l), [R, T] = x(!1), m = V(null), [D, j] = x([]), [q, B] = x(
|
|
71
70
|
() => (
|
|
72
71
|
// Apply same targeting filter to initial buffered snapshots as we do for
|
|
73
|
-
// live subscription events so targeted snapshots don't leak to unrelated
|
|
72
|
+
// live subscription events so targeted snapshots don't leak to unrelated
|
|
73
|
+
// overlays.
|
|
74
74
|
p.filter(
|
|
75
|
-
(
|
|
75
|
+
(e) => !e.targetOverlays || e.targetOverlays.length === 0 || e.targetOverlays.includes(c)
|
|
76
76
|
)
|
|
77
77
|
)
|
|
78
78
|
), E = h(
|
|
79
|
-
() => s !== void 0 ?
|
|
79
|
+
() => s !== void 0 ? N(s, d) : null,
|
|
80
80
|
[s, d]
|
|
81
81
|
);
|
|
82
|
-
|
|
83
|
-
E != null &&
|
|
84
|
-
(
|
|
82
|
+
S(() => {
|
|
83
|
+
E != null && j(
|
|
84
|
+
(e) => [{ ts: Date.now(), json: E }, ...e].slice(0, C)
|
|
85
85
|
);
|
|
86
|
-
}, [E, C]),
|
|
87
|
-
const
|
|
88
|
-
(!
|
|
86
|
+
}, [E, C]), S(() => {
|
|
87
|
+
const e = (t) => {
|
|
88
|
+
(!t.targetOverlays || t.targetOverlays.length === 0 || t.targetOverlays.includes(c)) && B((r) => [...r, t]);
|
|
89
89
|
};
|
|
90
|
-
return $.add(
|
|
91
|
-
$.delete(
|
|
90
|
+
return $.add(e), () => {
|
|
91
|
+
$.delete(e);
|
|
92
92
|
};
|
|
93
93
|
}, [c]);
|
|
94
94
|
const i = h(() => {
|
|
95
|
-
const
|
|
95
|
+
const e = [...D].reverse().map((n) => ({
|
|
96
96
|
kind: "state",
|
|
97
97
|
ts: n.ts,
|
|
98
98
|
json: n.json,
|
|
99
|
-
seq:
|
|
100
|
-
})),
|
|
99
|
+
seq: F()
|
|
100
|
+
})), t = q.map((n) => ({
|
|
101
101
|
kind: "manual",
|
|
102
102
|
ts: n.ts,
|
|
103
103
|
seq: n.seq,
|
|
104
104
|
label: n.label,
|
|
105
105
|
color: n.color,
|
|
106
|
-
json:
|
|
107
|
-
})), r = [...
|
|
106
|
+
json: N(n.data, d)
|
|
107
|
+
})), r = [...e, ...t];
|
|
108
108
|
return r.sort((n, f) => n.ts === f.ts ? n.seq - f.seq : n.ts - f.ts), r;
|
|
109
|
-
}, [
|
|
109
|
+
}, [D, q, d]), k = h(
|
|
110
110
|
() => A === "asc" ? i : [...i].reverse(),
|
|
111
111
|
[A, i]
|
|
112
|
-
),
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return;
|
|
117
|
-
const S = new Date(r.ts).toLocaleTimeString(void 0, {
|
|
112
|
+
), Y = _(() => {
|
|
113
|
+
const e = [];
|
|
114
|
+
e.push(`${a} (total snapshots: ${i.length})`), i.forEach((r, n) => {
|
|
115
|
+
const G = new Date(r.ts).toLocaleTimeString(void 0, {
|
|
118
116
|
hour: "2-digit",
|
|
119
117
|
minute: "2-digit",
|
|
120
118
|
second: "2-digit",
|
|
121
119
|
hour12: !1
|
|
122
|
-
}),
|
|
123
|
-
|
|
120
|
+
}), Z = r.kind === "manual" && r.label ? ` [${r.label}]` : "";
|
|
121
|
+
e.push(`--- ${G} (#${n + 1})${Z} ---`), e.push(r.json);
|
|
124
122
|
});
|
|
125
|
-
const
|
|
123
|
+
const t = e.join(`
|
|
126
124
|
`);
|
|
127
|
-
navigator?.clipboard?.writeText && navigator.clipboard.writeText(
|
|
128
|
-
|
|
125
|
+
navigator?.clipboard?.writeText && navigator.clipboard.writeText(t).then(() => {
|
|
126
|
+
T(!0), setTimeout(() => T(!1), 1300);
|
|
129
127
|
});
|
|
130
|
-
}, [a, i
|
|
131
|
-
|
|
128
|
+
}, [a, i]), P = _(() => {
|
|
129
|
+
j([]), B([]), p.length = 0;
|
|
132
130
|
}, []), M = h(() => {
|
|
133
131
|
if (!o)
|
|
134
132
|
return {};
|
|
@@ -150,34 +148,34 @@ const ut = ({
|
|
|
150
148
|
default:
|
|
151
149
|
return { top: "0", right: "0" };
|
|
152
150
|
}
|
|
153
|
-
const
|
|
154
|
-
for (const
|
|
155
|
-
const r = o[
|
|
156
|
-
r !== void 0 && (t
|
|
151
|
+
const e = {};
|
|
152
|
+
for (const t of ["top", "right", "bottom", "left"]) {
|
|
153
|
+
const r = o[t];
|
|
154
|
+
r !== void 0 && (e[t] = String(r));
|
|
157
155
|
}
|
|
158
|
-
return
|
|
156
|
+
return e;
|
|
159
157
|
}, [o]), u = h(() => {
|
|
160
|
-
const
|
|
161
|
-
return !("top" in
|
|
158
|
+
const e = { ...M };
|
|
159
|
+
return !("top" in e) && !("bottom" in e) && (e.top = "0"), !("left" in e) && !("right" in e) && (e.right = "0"), e;
|
|
162
160
|
}, [M]);
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
if (!
|
|
161
|
+
S(() => {
|
|
162
|
+
const e = typeof window < "u" ? window.visualViewport : null;
|
|
163
|
+
if (!e)
|
|
166
164
|
return;
|
|
167
|
-
const
|
|
168
|
-
if (m.current && (!("top" in u) && !("bottom" in u) && (m.current.style.top = `${
|
|
165
|
+
const t = () => {
|
|
166
|
+
if (m.current && (!("top" in u) && !("bottom" in u) && (m.current.style.top = `${e.offsetTop}px`), !("right" in u) && !("left" in u))) {
|
|
169
167
|
const r = Math.max(
|
|
170
168
|
0,
|
|
171
|
-
Math.round(window.innerWidth - (
|
|
169
|
+
Math.round(window.innerWidth - (e.offsetLeft + e.width))
|
|
172
170
|
);
|
|
173
171
|
m.current.style.right = `${r}px`;
|
|
174
172
|
}
|
|
175
173
|
};
|
|
176
|
-
return
|
|
177
|
-
|
|
174
|
+
return e.addEventListener("resize", t), e.addEventListener("scroll", t), t(), () => {
|
|
175
|
+
e.removeEventListener("resize", t), e.removeEventListener("scroll", t);
|
|
178
176
|
};
|
|
179
177
|
}, [u]);
|
|
180
|
-
const
|
|
178
|
+
const H = i.length, J = U ? `${a} (${H})` : a, K = { margin: 0, padding: 0 }, Q = {
|
|
181
179
|
margin: 0,
|
|
182
180
|
padding: 0,
|
|
183
181
|
paddingLeft: 4
|
|
@@ -208,13 +206,13 @@ const ut = ({
|
|
|
208
206
|
border: "2px solid #cc0000"
|
|
209
207
|
}
|
|
210
208
|
};
|
|
211
|
-
function
|
|
212
|
-
const
|
|
209
|
+
function X(e) {
|
|
210
|
+
const t = e && w[e] ? w[e] : w.LOG_YELLOW;
|
|
213
211
|
return {
|
|
214
|
-
...
|
|
215
|
-
color:
|
|
216
|
-
background:
|
|
217
|
-
borderLeft:
|
|
212
|
+
...Q,
|
|
213
|
+
color: t.color,
|
|
214
|
+
background: t.background,
|
|
215
|
+
borderLeft: t.border
|
|
218
216
|
};
|
|
219
217
|
}
|
|
220
218
|
return /* @__PURE__ */ L(
|
|
@@ -252,13 +250,13 @@ const ut = ({
|
|
|
252
250
|
userSelect: "none"
|
|
253
251
|
},
|
|
254
252
|
children: [
|
|
255
|
-
/* @__PURE__ */ g("strong", { style: { fontWeight: 600, fontSize: 11 }, children:
|
|
253
|
+
/* @__PURE__ */ g("strong", { style: { fontWeight: 600, fontSize: 11 }, children: J }),
|
|
256
254
|
/* @__PURE__ */ L("div", { style: { marginLeft: "auto", display: "flex", gap: 4 }, children: [
|
|
257
255
|
/* @__PURE__ */ g(
|
|
258
256
|
"button",
|
|
259
257
|
{
|
|
260
258
|
type: "button",
|
|
261
|
-
onClick: () => I((
|
|
259
|
+
onClick: () => I((e) => !e),
|
|
262
260
|
"aria-label": b ? "Expand debug overlay" : "Collapse debug overlay",
|
|
263
261
|
style: O,
|
|
264
262
|
children: b ? "+" : "−"
|
|
@@ -268,20 +266,20 @@ const ut = ({
|
|
|
268
266
|
"button",
|
|
269
267
|
{
|
|
270
268
|
type: "button",
|
|
271
|
-
onClick:
|
|
269
|
+
onClick: Y,
|
|
272
270
|
"aria-label": "Copy debug JSON",
|
|
273
271
|
style: {
|
|
274
272
|
...O,
|
|
275
|
-
color:
|
|
273
|
+
color: R ? "#0f0" : O.color
|
|
276
274
|
},
|
|
277
|
-
children:
|
|
275
|
+
children: R ? "Copied" : "Copy"
|
|
278
276
|
}
|
|
279
277
|
),
|
|
280
278
|
i.length > 1 && /* @__PURE__ */ g(
|
|
281
279
|
"button",
|
|
282
280
|
{
|
|
283
281
|
type: "button",
|
|
284
|
-
onClick:
|
|
282
|
+
onClick: P,
|
|
285
283
|
"aria-label": "Clear stored snapshots",
|
|
286
284
|
style: O,
|
|
287
285
|
children: "Clear"
|
|
@@ -306,21 +304,21 @@ const ut = ({
|
|
|
306
304
|
wordBreak: "break-word"
|
|
307
305
|
},
|
|
308
306
|
children: [
|
|
309
|
-
k.slice(0, v).map((
|
|
310
|
-
const
|
|
307
|
+
k.slice(0, v).map((e) => {
|
|
308
|
+
const t = i.findIndex((G) => G.seq === e.seq), n = new Date(e.ts).toLocaleTimeString(void 0, {
|
|
311
309
|
hour: "2-digit",
|
|
312
310
|
minute: "2-digit",
|
|
313
311
|
second: "2-digit",
|
|
314
312
|
hour12: !1
|
|
315
|
-
}), f =
|
|
313
|
+
}), f = e.kind === "manual" && e.label ? ` [${e.label}]` : "";
|
|
316
314
|
return /* @__PURE__ */ g(
|
|
317
315
|
"pre",
|
|
318
316
|
{
|
|
319
|
-
style:
|
|
320
|
-
children: `--- ${n} (#${
|
|
321
|
-
${
|
|
317
|
+
style: e.kind === "manual" ? X(e.color) : K,
|
|
318
|
+
children: `--- ${n} (#${t + 1})${f} ---
|
|
319
|
+
${e.json}`
|
|
322
320
|
},
|
|
323
|
-
`${
|
|
321
|
+
`${e.kind}-${e.seq}`
|
|
324
322
|
);
|
|
325
323
|
}),
|
|
326
324
|
k.length > v && /* @__PURE__ */ g("div", { style: { opacity: 0.7, marginTop: 4 }, children: `(+${k.length - v} snapshots not shown)` })
|
|
@@ -341,12 +339,12 @@ ${t.json}`
|
|
|
341
339
|
fontFamily: "inherit"
|
|
342
340
|
};
|
|
343
341
|
export {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
342
|
+
de as DebugOverlay,
|
|
343
|
+
se as LOG_BLUE,
|
|
344
|
+
ne as LOG_GREEN,
|
|
345
|
+
ae as LOG_MAGENTA,
|
|
346
|
+
le as LOG_RED,
|
|
347
|
+
re as LOG_YELLOW,
|
|
348
|
+
ie as __resetDebugOverlayTestState,
|
|
349
|
+
ce as useDebugOverlay
|
|
352
350
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
|
|
3
3
|
type DebugOverlayProps = {
|
|
4
4
|
/**
|
|
@@ -7,15 +7,18 @@ type DebugOverlayProps = {
|
|
|
7
7
|
*/
|
|
8
8
|
appState?: unknown;
|
|
9
9
|
/**
|
|
10
|
-
* Short label shown in the header.
|
|
10
|
+
* Short label shown in the header.
|
|
11
|
+
* @default "AppState"
|
|
11
12
|
*/
|
|
12
13
|
title?: string;
|
|
13
14
|
/**
|
|
14
15
|
* Start collapsed (header only).
|
|
16
|
+
* @default false
|
|
15
17
|
*/
|
|
16
18
|
initialCollapsed?: boolean;
|
|
17
19
|
/**
|
|
18
|
-
* Identifier for manual snapshot targeting
|
|
20
|
+
* Identifier for manual snapshot targeting..
|
|
21
|
+
* @default "default"
|
|
19
22
|
*/
|
|
20
23
|
overlayId?: string;
|
|
21
24
|
/**
|
|
@@ -44,38 +47,40 @@ type DebugOverlayProps = {
|
|
|
44
47
|
| "bottom-left"
|
|
45
48
|
| "bottom-right";
|
|
46
49
|
/**
|
|
47
|
-
* Maximum body height before scrolling (px number or CSS length e.g. "
|
|
50
|
+
* Maximum body height before scrolling (px number or CSS length e.g. "100vh").
|
|
51
|
+
* @default "50svh"
|
|
48
52
|
*/
|
|
49
53
|
maxBodyHeight?: number | string;
|
|
50
54
|
/**
|
|
51
|
-
* Pretty print spacing for JSON output
|
|
55
|
+
* Pretty print spacing for JSON output.
|
|
56
|
+
* @default 2
|
|
52
57
|
*/
|
|
53
58
|
indent?: number;
|
|
54
59
|
/**
|
|
55
|
-
* Maximum snapshots retained in memory
|
|
60
|
+
* Maximum snapshots retained in memory (FIFO)..
|
|
61
|
+
* @default 50
|
|
56
62
|
*/
|
|
57
63
|
maxSnapshots?: number;
|
|
58
64
|
/**
|
|
59
|
-
* Maximum snapshots shown without
|
|
65
|
+
* Maximum snapshots shown without scrolling.
|
|
66
|
+
* @default 10
|
|
60
67
|
*/
|
|
61
68
|
maxVisibleSnapshots?: number;
|
|
62
69
|
/**
|
|
63
70
|
* Visual ordering of snapshots in the panel.
|
|
64
|
-
* - "desc"
|
|
71
|
+
* - "desc": newest snapshot at the top.
|
|
65
72
|
* - "asc": oldest snapshot at the top.
|
|
66
73
|
* Numbering ALWAYS reflects chronological order with #1 being the oldest
|
|
67
74
|
* snapshot regardless of display order.
|
|
75
|
+
* @default "desc"
|
|
68
76
|
*/
|
|
69
77
|
snapshotOrder?: "asc" | "desc";
|
|
70
78
|
/**
|
|
71
79
|
* When true, appends the current snapshot count to the title (e.g. "AppState
|
|
72
80
|
* (5)").
|
|
81
|
+
* @default false
|
|
73
82
|
*/
|
|
74
83
|
appendSnapshotCountInTitle?: boolean;
|
|
75
|
-
/**
|
|
76
|
-
* Include manual snapshots when copying all snapshots.
|
|
77
|
-
*/
|
|
78
|
-
includeManualInCopy?: boolean;
|
|
79
84
|
};
|
|
80
85
|
|
|
81
86
|
/**
|
|
@@ -89,12 +94,40 @@ declare const LOG_BLUE: "LOG_BLUE";
|
|
|
89
94
|
declare const LOG_MAGENTA: "LOG_MAGENTA";
|
|
90
95
|
declare const LOG_RED: "LOG_RED";
|
|
91
96
|
type LogColor = typeof LOG_YELLOW | typeof LOG_GREEN | typeof LOG_BLUE | typeof LOG_MAGENTA | typeof LOG_RED;
|
|
97
|
+
/**
|
|
98
|
+
* Test-only helper (not part of public API). Enables isolation across tests.
|
|
99
|
+
* Exported unconditionally; consumer code should not rely on it.
|
|
100
|
+
*/
|
|
92
101
|
declare function __resetDebugOverlayTestState(): void;
|
|
93
102
|
interface DebugFnOptions {
|
|
94
103
|
color?: LogColor;
|
|
95
104
|
targetOverlays?: string[];
|
|
96
105
|
}
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
/**
|
|
107
|
+
* React hook returning a function to push a manual snapshot into all (or
|
|
108
|
+
* targeted) mounted `DebugOverlay` instances.
|
|
109
|
+
*
|
|
110
|
+
* Usage:
|
|
111
|
+
* ```js
|
|
112
|
+
* const debug = useDebugOverlay();
|
|
113
|
+
* debug("loaded", { user, meta }, LOG_GREEN);
|
|
114
|
+
* debug("error", errorObj, { color: LOG_RED, targetOverlays: ["errors"] });
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* Parameters when invoking the returned function:
|
|
118
|
+
* - label: short string identifying the snapshot category.
|
|
119
|
+
* - data: any serializable (or even cyclic) value; cyclic structures are
|
|
120
|
+
* replaced with "[Circular]" markers.
|
|
121
|
+
* - options: either a LogColor constant OR an object with `color` and
|
|
122
|
+
* optional `targetOverlays` (array of overlayId strings). When
|
|
123
|
+
* `targetOverlays` is omitted or empty, the snapshot broadcasts to
|
|
124
|
+
* every mounted overlay.
|
|
125
|
+
*
|
|
126
|
+
* The hook itself has no dependencies and returns a stable callback identity
|
|
127
|
+
* for the component lifetime, keeping re-renders minimal.
|
|
128
|
+
*
|
|
129
|
+
*/
|
|
130
|
+
declare function useDebugOverlay(): (label: string, data: unknown, options?: LogColor | DebugFnOptions) => void;
|
|
131
|
+
declare const DebugOverlay: ({ appState, title, initialCollapsed, overlayId, position, maxBodyHeight, indent, maxSnapshots, maxVisibleSnapshots, snapshotOrder, appendSnapshotCountInTitle, }: DebugOverlayProps) => react_jsx_runtime.JSX.Element;
|
|
99
132
|
|
|
100
|
-
export { type DebugFnOptions, DebugOverlay, type DebugOverlayProps, LOG_BLUE, LOG_GREEN, LOG_MAGENTA, LOG_RED, LOG_YELLOW, type LogColor, __resetDebugOverlayTestState,
|
|
133
|
+
export { type DebugFnOptions, DebugOverlay, type DebugOverlayProps, LOG_BLUE, LOG_GREEN, LOG_MAGENTA, LOG_RED, LOG_YELLOW, type LogColor, __resetDebugOverlayTestState, useDebugOverlay };
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { DebugOverlay as
|
|
1
|
+
import { DebugOverlay as r, LOG_BLUE as i, LOG_GREEN as t, LOG_MAGENTA as O, LOG_RED as o, LOG_YELLOW as L, __resetDebugOverlayTestState as G, useDebugOverlay as s } from "./components/DebugOverlay/DebugOverlay.js";
|
|
2
2
|
/*!
|
|
3
|
-
@versini/ui-debug-overlay
|
|
3
|
+
@versini/ui-debug-overlay v2.0.1
|
|
4
4
|
© 2025 gizmette.com
|
|
5
5
|
*/
|
|
6
6
|
try {
|
|
7
7
|
window.__VERSINI_UI_DEBUG_OVERLAY__ || (window.__VERSINI_UI_DEBUG_OVERLAY__ = {
|
|
8
|
-
version: "
|
|
9
|
-
buildTime: "
|
|
8
|
+
version: "2.0.1",
|
|
9
|
+
buildTime: "10/17/2025 12:55 PM EDT",
|
|
10
10
|
homepage: "https://github.com/aversini/ui-components",
|
|
11
11
|
license: "MIT"
|
|
12
12
|
});
|
|
13
13
|
} catch {
|
|
14
14
|
}
|
|
15
15
|
export {
|
|
16
|
-
|
|
16
|
+
r as DebugOverlay,
|
|
17
17
|
i as LOG_BLUE,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
t as LOG_GREEN,
|
|
19
|
+
O as LOG_MAGENTA,
|
|
20
|
+
o as LOG_RED,
|
|
21
|
+
L as LOG_YELLOW,
|
|
22
|
+
G as __resetDebugOverlayTestState,
|
|
23
|
+
s as useDebugOverlay
|
|
24
24
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@versini/ui-debug-overlay",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Arno Versini",
|
|
6
6
|
"publishConfig": {
|
|
@@ -36,12 +36,8 @@
|
|
|
36
36
|
"test:watch": "vitest",
|
|
37
37
|
"test": "vitest run"
|
|
38
38
|
},
|
|
39
|
-
"peerDependencies": {
|
|
40
|
-
"react": "^19.1.0",
|
|
41
|
-
"react-dom": "^19.1.0"
|
|
42
|
-
},
|
|
43
39
|
"devDependencies": {
|
|
44
|
-
"@testing-library/jest-dom": "6.
|
|
40
|
+
"@testing-library/jest-dom": "6.9.1"
|
|
45
41
|
},
|
|
46
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "67e049c9b2e46e8f52509bf6198ca0cdaf5d970a"
|
|
47
43
|
}
|