dev-inspector 1.0.5 → 1.1.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.
Files changed (36) hide show
  1. package/README.md +22 -1
  2. package/lib/init.d.ts +5 -2
  3. package/lib/init.js +5 -2
  4. package/lib/ui/panel/behavior/setupPanelBehavior.d.ts +4 -1
  5. package/lib/ui/panel/behavior/setupPanelBehavior.js +48 -1
  6. package/lib/ui/panel/bindings/bindStorageToPanelView.d.ts +2 -0
  7. package/lib/ui/panel/bindings/bindStorageToPanelView.js +50 -6
  8. package/lib/ui/panel/bindings/matchesQuery.d.ts +2 -0
  9. package/lib/ui/panel/bindings/matchesQuery.js +54 -0
  10. package/lib/ui/panel/bindings/types.d.ts +2 -0
  11. package/lib/ui/panel/dom/buildPanelDOM.js +65 -6
  12. package/lib/ui/panel/dom/constants.d.ts +5 -1
  13. package/lib/ui/panel/dom/constants.js +35 -20
  14. package/lib/ui/panel/dom/types.d.ts +6 -0
  15. package/lib/ui/panel/index.d.ts +4 -0
  16. package/lib/ui/panel/index.js +8 -3
  17. package/lib/ui/panel/state/createPanelState.d.ts +2 -1
  18. package/lib/ui/panel/state/createPanelState.js +5 -1
  19. package/lib/ui/panel/state/types.d.ts +5 -0
  20. package/lib/ui/panel/theme/applyTheme.d.ts +2 -0
  21. package/lib/ui/panel/theme/applyTheme.js +6 -0
  22. package/lib/ui/panel/theme/index.d.ts +3 -0
  23. package/lib/ui/panel/theme/index.js +9 -0
  24. package/lib/ui/panel/theme/storage.d.ts +4 -0
  25. package/lib/ui/panel/theme/storage.js +45 -0
  26. package/lib/ui/panel/theme/types.d.ts +6 -0
  27. package/lib/ui/panel/theme/types.js +2 -0
  28. package/lib/ui/panelStyles.d.ts +1 -1
  29. package/lib/ui/panelStyles.js +514 -125
  30. package/package.json +3 -2
  31. package/lib/ui/logList/networkDetails.d.ts +0 -2
  32. package/lib/ui/logList/networkDetails.js +0 -227
  33. package/lib/ui/logList.d.ts +0 -7
  34. package/lib/ui/logList.js +0 -117
  35. package/lib/ui/panel.d.ts +0 -15
  36. package/lib/ui/panel.js +0 -375
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-inspector",
3
- "version": "1.0.5",
3
+ "version": "1.1.1",
4
4
  "description": "In-page devtools-style logger panel for web apps (console + network).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,7 +16,8 @@
16
16
  "lint-staged": "lint-staged",
17
17
  "demo": "vite demo --open",
18
18
  "demo:build": "vite build demo",
19
- "build": "tsc -p tsconfig.json",
19
+ "clean": "rm -rf lib",
20
+ "build": "npm run clean && tsc -p tsconfig.json",
20
21
  "lint": "eslint \"src/**/*.{ts,tsx,js}\"",
21
22
  "prepublishOnly": "npm run build"
22
23
  },
@@ -1,2 +0,0 @@
1
- import type { NetworkLogEntry } from "../../utils/types";
2
- export declare function createNetworkDetails(doc: Document, entry: NetworkLogEntry): HTMLElement | null;
@@ -1,227 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createNetworkDetails = createNetworkDetails;
4
- const jsonViewer_1 = require("../jsonViewer");
5
- function tryParseJson(text) {
6
- const t = text.trim();
7
- if (t.length < 2)
8
- return undefined;
9
- const looksLikeObject = t.startsWith("{") && t.endsWith("}");
10
- const looksLikeArray = t.startsWith("[") && t.endsWith("]");
11
- if (!looksLikeObject && !looksLikeArray)
12
- return undefined;
13
- try {
14
- return JSON.parse(t);
15
- }
16
- catch (_a) {
17
- return undefined;
18
- }
19
- }
20
- function safeStringify(value) {
21
- const seen = new WeakSet();
22
- const replacer = (_key, v) => {
23
- if (typeof v === "object" && v !== null) {
24
- const o = v;
25
- if (seen.has(o))
26
- return "[circular]";
27
- seen.add(o);
28
- }
29
- return v;
30
- };
31
- try {
32
- return JSON.stringify(value, replacer, 2);
33
- }
34
- catch (_a) {
35
- try {
36
- return String(value);
37
- }
38
- catch (_b) {
39
- return "[unserializable]";
40
- }
41
- }
42
- }
43
- async function copyText(text) {
44
- var _a, _b;
45
- try {
46
- const nav = globalThis;
47
- const fn = (_b = (_a = nav.navigator) === null || _a === void 0 ? void 0 : _a.clipboard) === null || _b === void 0 ? void 0 : _b.writeText;
48
- if (typeof fn === "function") {
49
- await fn(text);
50
- return true;
51
- }
52
- }
53
- catch (_c) {
54
- void 0;
55
- }
56
- try {
57
- if (typeof document === "undefined")
58
- return false;
59
- const ta = document.createElement("textarea");
60
- ta.value = text;
61
- ta.setAttribute("readonly", "true");
62
- ta.style.position = "fixed";
63
- ta.style.left = "-9999px";
64
- ta.style.top = "0";
65
- document.body.append(ta);
66
- ta.select();
67
- const ok = document.execCommand("copy");
68
- ta.remove();
69
- return ok;
70
- }
71
- catch (_d) {
72
- return false;
73
- }
74
- }
75
- function prefersReducedMotion() {
76
- var _a, _b;
77
- try {
78
- const mm = globalThis;
79
- return ((_b = (_a = mm.matchMedia) === null || _a === void 0 ? void 0 : _a.call(mm, "(prefers-reduced-motion: reduce)")) === null || _b === void 0 ? void 0 : _b.matches) === true;
80
- }
81
- catch (_c) {
82
- return false;
83
- }
84
- }
85
- function rand(min, max) {
86
- return min + Math.random() * (max - min);
87
- }
88
- function launchMiniConfetti(anchor) {
89
- if (prefersReducedMotion())
90
- return;
91
- if (typeof document === "undefined")
92
- return;
93
- const rect = anchor.getBoundingClientRect();
94
- const cx = rect.left + rect.width / 2;
95
- const cy = rect.top + rect.height / 2;
96
- const root = document.createElement("div");
97
- root.style.position = "fixed";
98
- root.style.left = "0";
99
- root.style.top = "0";
100
- root.style.width = "0";
101
- root.style.height = "0";
102
- root.style.pointerEvents = "none";
103
- root.style.zIndex = "2147483647";
104
- document.body.append(root);
105
- const colors = ["#a7ff00", "#7c5cff", "#00c4ff", "#ff9030", "#ef4444"];
106
- const n = 14;
107
- const duration = 520;
108
- for (let i = 0; i < n; i += 1) {
109
- const p = document.createElement("span");
110
- const size = Math.round(rand(3, 6));
111
- p.style.position = "fixed";
112
- p.style.left = `${cx}px`;
113
- p.style.top = `${cy}px`;
114
- p.style.width = `${size}px`;
115
- p.style.height = `${size}px`;
116
- p.style.borderRadius = Math.random() < 0.35 ? "999px" : "2px";
117
- p.style.background = colors[i % colors.length];
118
- p.style.opacity = "1";
119
- p.style.willChange = "transform, opacity";
120
- root.append(p);
121
- const angle = rand(0, Math.PI * 2);
122
- const dist = rand(18, 46);
123
- const dx = Math.cos(angle) * dist;
124
- const dy = Math.sin(angle) * dist + rand(8, 16);
125
- const rot = rand(-220, 220);
126
- const delay = Math.round(rand(0, 60));
127
- try {
128
- const anim = p.animate([
129
- { transform: `translate(-50%, -50%) translate(0px, 0px) rotate(0deg) scale(1)`, opacity: 1 },
130
- { transform: `translate(-50%, -50%) translate(${dx}px, ${dy}px) rotate(${rot}deg) scale(0.9)`, opacity: 0 },
131
- ], { duration, delay, easing: "cubic-bezier(0.2, 0.7, 0.2, 1)", fill: "forwards" });
132
- anim.addEventListener("finish", () => p.remove());
133
- }
134
- catch (_a) {
135
- globalThis.setTimeout(() => p.remove(), duration + delay + 50);
136
- }
137
- }
138
- globalThis.setTimeout(() => root.remove(), duration + 120);
139
- }
140
- function valueToElement(doc, value) {
141
- if (typeof value === "string") {
142
- const parsed = tryParseJson(value);
143
- if (parsed && typeof parsed === "object") {
144
- return (0, jsonViewer_1.createJsonViewer)(doc, parsed, { maxDepth: 6, maxKeys: 200, maxNodes: 2000 });
145
- }
146
- const el = doc.createElement("div");
147
- el.className = "di-netBodyText";
148
- el.textContent = value;
149
- return el;
150
- }
151
- if (value instanceof Error) {
152
- const el = doc.createElement("div");
153
- el.className = "di-netBodyText";
154
- el.textContent = `${value.name}: ${value.message}`;
155
- return el;
156
- }
157
- if (value === null || typeof value !== "object") {
158
- const el = doc.createElement("div");
159
- el.className = "di-netBodyText";
160
- el.textContent = String(value);
161
- return el;
162
- }
163
- return (0, jsonViewer_1.createJsonViewer)(doc, value, { maxDepth: 6, maxKeys: 200, maxNodes: 2000 });
164
- }
165
- function valueToCopyText(value) {
166
- if (typeof value === "string")
167
- return value;
168
- if (value instanceof Error)
169
- return `${value.name}: ${value.message}`;
170
- return safeStringify(value);
171
- }
172
- function createBodyDetails(doc, title, value, truncated, maxLen) {
173
- const details = doc.createElement("details");
174
- details.className = "di-details di-netBodyDetails";
175
- const summary = doc.createElement("summary");
176
- summary.className = "di-detailsSummary di-netDetailsSummary";
177
- const titleEl = doc.createElement("span");
178
- titleEl.className = "di-netDetailsTitle";
179
- titleEl.textContent = title;
180
- const copyBtn = doc.createElement("button");
181
- copyBtn.type = "button";
182
- copyBtn.className = "di-copyBtn";
183
- copyBtn.textContent = "Copy";
184
- copyBtn.setAttribute("aria-label", `Copy ${title.toLowerCase()}`);
185
- copyBtn.addEventListener("click", (ev) => {
186
- ev.preventDefault();
187
- ev.stopPropagation();
188
- const txt = valueToCopyText(value);
189
- void copyText(txt).then((ok) => {
190
- if (!ok)
191
- return;
192
- launchMiniConfetti(copyBtn);
193
- const prev = copyBtn.textContent;
194
- copyBtn.textContent = "Copied";
195
- globalThis.setTimeout(() => {
196
- copyBtn.textContent = prev !== null && prev !== void 0 ? prev : "Copy";
197
- }, 900);
198
- });
199
- });
200
- summary.append(titleEl, copyBtn);
201
- const body = doc.createElement("div");
202
- body.className = "di-detailsBody";
203
- if (truncated) {
204
- const warn = doc.createElement("div");
205
- warn.className = "di-netTrunc";
206
- warn.textContent = typeof maxLen === "number" ? `Truncated to first ${maxLen} characters.` : "Truncated.";
207
- body.append(warn);
208
- }
209
- body.append(valueToElement(doc, value));
210
- details.append(summary, body);
211
- return details;
212
- }
213
- function createNetworkDetails(doc, entry) {
214
- const hasReq = typeof entry.requestBody !== "undefined";
215
- const hasRes = typeof entry.responseBody !== "undefined";
216
- if (!hasReq && !hasRes)
217
- return null;
218
- const wrap = doc.createElement("div");
219
- wrap.className = "di-netDetailsWrap";
220
- if (hasReq) {
221
- wrap.append(createBodyDetails(doc, "Request", entry.requestBody, entry.requestBodyTruncated === true, entry.bodyMaxLength));
222
- }
223
- if (hasRes) {
224
- wrap.append(createBodyDetails(doc, "Response", entry.responseBody, entry.responseBodyTruncated === true, entry.bodyMaxLength));
225
- }
226
- return wrap;
227
- }
@@ -1,7 +0,0 @@
1
- import type { LogEntry } from "../utils/types";
2
- export type LogList = {
3
- el: HTMLUListElement;
4
- append: (entry: LogEntry) => void;
5
- clear: () => void;
6
- };
7
- export declare function createLogList(doc: Document): LogList;
package/lib/ui/logList.js DELETED
@@ -1,117 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createLogList = createLogList;
4
- const jsonViewer_1 = require("./jsonViewer");
5
- const networkDetails_1 = require("./logList/networkDetails");
6
- function fmtTime(ts) {
7
- const d = new Date(ts);
8
- const hh = String(d.getHours()).padStart(2, "0");
9
- const mm = String(d.getMinutes()).padStart(2, "0");
10
- const ss = String(d.getSeconds()).padStart(2, "0");
11
- return `${hh}:${mm}:${ss}`;
12
- }
13
- function toneForEntry(entry) {
14
- if (entry.source === "console") {
15
- if (entry.level === "error")
16
- return "error";
17
- if (entry.level === "warn")
18
- return "warning";
19
- return "neutral";
20
- }
21
- const s = entry.status;
22
- if (typeof s !== "number")
23
- return "error";
24
- if (s >= 400)
25
- return "error";
26
- if (s >= 300)
27
- return "warning";
28
- return "success";
29
- }
30
- function classForTone(tone) {
31
- if (tone === "error")
32
- return "di-itemToneError";
33
- if (tone === "warning")
34
- return "di-itemToneWarning";
35
- if (tone === "success")
36
- return "di-itemToneSuccess";
37
- return "di-itemToneNeutral";
38
- }
39
- function isNetworkFailure(entry) {
40
- if (entry.source !== "network")
41
- return false;
42
- return typeof entry.status !== "number" || entry.status >= 400;
43
- }
44
- function isInspectableValue(value) {
45
- if (typeof value !== "object" || value === null)
46
- return false;
47
- if (value instanceof Error)
48
- return false;
49
- if (value instanceof Date)
50
- return false;
51
- if (value instanceof RegExp)
52
- return false;
53
- return true;
54
- }
55
- function getInspectableArgs(args) {
56
- return args.filter(isInspectableValue);
57
- }
58
- function createLogList(doc) {
59
- const el = doc.createElement("ul");
60
- el.className = "di-list";
61
- const append = (entry) => {
62
- const li = doc.createElement("li");
63
- const tone = toneForEntry(entry);
64
- li.className = `di-item ${classForTone(tone)}`;
65
- const meta = doc.createElement("div");
66
- meta.className = "di-meta";
67
- const time = doc.createElement("span");
68
- time.textContent = fmtTime(entry.timestamp);
69
- const source = doc.createElement("span");
70
- source.textContent = entry.source;
71
- const detail = doc.createElement("span");
72
- if (entry.source === "console") {
73
- detail.textContent = entry.level;
74
- }
75
- else {
76
- detail.className = `di-statusChip ${isNetworkFailure(entry) ? "di-statusChipError" : "di-statusChipSuccess"}`;
77
- detail.textContent = typeof entry.status === "number" ? String(entry.status) : "ERR";
78
- }
79
- meta.append(time, source, detail);
80
- li.append(meta);
81
- if (entry.message && entry.message.trim().length > 0) {
82
- const msg = doc.createElement("div");
83
- msg.className = "di-msg";
84
- msg.textContent = entry.message;
85
- li.append(msg);
86
- }
87
- if (entry.source === "console") {
88
- const inspectable = getInspectableArgs(entry.args);
89
- if (inspectable.length > 0) {
90
- const details = doc.createElement("details");
91
- details.className = "di-details";
92
- const summary = doc.createElement("summary");
93
- summary.className = "di-detailsSummary";
94
- summary.textContent = "Inspect";
95
- const viewerWrap = doc.createElement("div");
96
- viewerWrap.className = "di-detailsBody";
97
- viewerWrap.append((0, jsonViewer_1.createJsonViewer)(doc, inspectable.length === 1 ? inspectable[0] : inspectable, {
98
- maxDepth: 6,
99
- maxKeys: 200,
100
- maxNodes: 2000,
101
- }));
102
- details.append(summary, viewerWrap);
103
- li.append(details);
104
- }
105
- }
106
- if (entry.source === "network") {
107
- const details = (0, networkDetails_1.createNetworkDetails)(doc, entry);
108
- if (details)
109
- li.append(details);
110
- }
111
- el.append(li);
112
- };
113
- const clear = () => {
114
- el.replaceChildren();
115
- };
116
- return { el, append, clear };
117
- }
package/lib/ui/panel.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import type { LogStorage } from "../storage/logStorage";
2
- export type PanelOptions = {
3
- storage: LogStorage;
4
- title?: string;
5
- initiallyOpen?: boolean;
6
- mount?: HTMLElement;
7
- };
8
- export type PanelHandle = {
9
- open: () => void;
10
- close: () => void;
11
- toggle: () => void;
12
- destroy: () => void;
13
- isOpen: () => boolean;
14
- };
15
- export declare function createPanel(options: PanelOptions): PanelHandle;