dev-inspector 1.0.3 → 1.0.5

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 (82) hide show
  1. package/README.md +15 -48
  2. package/lib/index.d.ts +1 -6
  3. package/lib/index.js +1 -10
  4. package/lib/init.d.ts +11 -22
  5. package/lib/init.js +33 -24
  6. package/lib/logger/networkLogger.js +41 -11
  7. package/lib/ui/logList/createLogList.d.ts +2 -0
  8. package/lib/ui/logList/createLogList.js +67 -0
  9. package/lib/ui/logList/index.d.ts +2 -0
  10. package/lib/ui/logList/index.js +5 -0
  11. package/lib/ui/logList/networkDetails/copy.d.ts +2 -0
  12. package/lib/ui/logList/networkDetails/copy.js +101 -0
  13. package/lib/ui/logList/networkDetails/createNetworkDetails.d.ts +2 -0
  14. package/lib/ui/logList/networkDetails/createNetworkDetails.js +61 -0
  15. package/lib/ui/logList/networkDetails/index.d.ts +1 -0
  16. package/lib/ui/logList/networkDetails/index.js +5 -0
  17. package/lib/ui/logList/networkDetails/renderValue.d.ts +2 -0
  18. package/lib/ui/logList/networkDetails/renderValue.js +75 -0
  19. package/lib/ui/logList/networkDetails.d.ts +2 -0
  20. package/lib/ui/logList/networkDetails.js +227 -0
  21. package/lib/ui/logList/shared/consoleInspect.d.ts +1 -0
  22. package/lib/ui/logList/shared/consoleInspect.js +17 -0
  23. package/lib/ui/logList/shared/index.d.ts +3 -0
  24. package/lib/ui/logList/shared/index.js +11 -0
  25. package/lib/ui/logList/shared/time.d.ts +1 -0
  26. package/lib/ui/logList/shared/time.js +10 -0
  27. package/lib/ui/logList/shared/tone.d.ts +6 -0
  28. package/lib/ui/logList/shared/tone.js +36 -0
  29. package/lib/ui/logList/types.d.ts +6 -0
  30. package/lib/ui/logList/types.js +2 -0
  31. package/lib/ui/logList.js +6 -0
  32. package/lib/ui/panel/behavior/index.d.ts +1 -0
  33. package/lib/ui/panel/behavior/index.js +5 -0
  34. package/lib/ui/panel/behavior/setupPanelBehavior.d.ts +5 -0
  35. package/lib/ui/panel/behavior/setupPanelBehavior.js +75 -0
  36. package/lib/ui/panel/bindings/bindStorageToPanelView.d.ts +16 -0
  37. package/lib/ui/panel/bindings/bindStorageToPanelView.js +76 -0
  38. package/lib/ui/panel/bindings/index.d.ts +2 -0
  39. package/lib/ui/panel/bindings/index.js +5 -0
  40. package/lib/ui/panel/bindings/types.d.ts +5 -0
  41. package/lib/ui/panel/bindings/types.js +2 -0
  42. package/lib/ui/panel/dom/buildPanelDOM.d.ts +3 -0
  43. package/lib/ui/panel/dom/buildPanelDOM.js +73 -0
  44. package/lib/ui/panel/dom/constants.d.ts +3 -0
  45. package/lib/ui/panel/dom/constants.js +28 -0
  46. package/lib/ui/panel/dom/index.d.ts +2 -0
  47. package/lib/ui/panel/dom/index.js +5 -0
  48. package/lib/ui/panel/dom/types.d.ts +25 -0
  49. package/lib/ui/panel/dom/types.js +2 -0
  50. package/lib/ui/panel/index.d.ts +15 -0
  51. package/lib/ui/panel/index.js +16 -0
  52. package/lib/ui/panel/resize/attachResizeHandling.d.ts +2 -0
  53. package/lib/ui/panel/resize/attachResizeHandling.js +94 -0
  54. package/lib/ui/panel/resize/index.d.ts +2 -0
  55. package/lib/ui/panel/resize/index.js +5 -0
  56. package/lib/ui/panel/resize/types.d.ts +3 -0
  57. package/lib/ui/panel/resize/types.js +2 -0
  58. package/lib/ui/panel/shared/dom.d.ts +1 -0
  59. package/lib/ui/panel/shared/dom.js +9 -0
  60. package/lib/ui/panel/shared/ensureDocument.d.ts +1 -0
  61. package/lib/ui/panel/shared/ensureDocument.js +9 -0
  62. package/lib/ui/panel/shared/ensureStyle.d.ts +1 -0
  63. package/lib/ui/panel/shared/ensureStyle.js +14 -0
  64. package/lib/ui/panel/shared/index.d.ts +6 -0
  65. package/lib/ui/panel/shared/index.js +13 -0
  66. package/lib/ui/panel/shared/math.d.ts +1 -0
  67. package/lib/ui/panel/shared/math.js +6 -0
  68. package/lib/ui/panel/shared/types.d.ts +11 -0
  69. package/lib/ui/panel/shared/types.js +2 -0
  70. package/lib/ui/panel/shared/window.d.ts +2 -0
  71. package/lib/ui/panel/shared/window.js +6 -0
  72. package/lib/ui/panel/state/createPanelState.d.ts +2 -0
  73. package/lib/ui/panel/state/createPanelState.js +11 -0
  74. package/lib/ui/panel/state/index.d.ts +2 -0
  75. package/lib/ui/panel/state/index.js +5 -0
  76. package/lib/ui/panel/state/types.d.ts +8 -0
  77. package/lib/ui/panel/state/types.js +2 -0
  78. package/lib/ui/panel.js +219 -186
  79. package/lib/ui/panelStyles.d.ts +1 -1
  80. package/lib/ui/panelStyles.js +74 -0
  81. package/lib/utils/types.d.ts +3 -0
  82. package/package.json +9 -2
package/README.md CHANGED
@@ -1,7 +1,18 @@
1
1
  # Dev Inspector
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/dev-inspector.svg)](https://www.npmjs.com/package/dev-inspector)
4
+ [![downloads](https://img.shields.io/npm/dm/dev-inspector.svg)](https://www.npmjs.com/package/dev-inspector)
5
+ [![license](https://img.shields.io/npm/l/dev-inspector.svg)](./LICENSE)
6
+
3
7
  In-page devtools-style logger panel for web apps. Capture **console** and **network** activity, store it in memory, and render it inside a lightweight UI panel.
4
8
 
9
+ ![Dev Inspector preview](./assets/dev-inspector.png)
10
+
11
+ ## Links
12
+
13
+ - **Website / Live demo**: `https://dev-inspector.alibugatekin.com/`
14
+ - **npm**: `https://www.npmjs.com/package/dev-inspector`
15
+
5
16
  ## Features
6
17
 
7
18
  - Console interception: `log/info/warn/error/debug`
@@ -48,22 +59,7 @@ async function initInBrowser() {
48
59
  initInBrowser();
49
60
  ```
50
61
 
51
- If you want manual control, you can keep the returned handles:
52
-
53
- ```ts
54
- import { initDevInspector } from "dev-inspector";
55
-
56
- const { storage, destroy } = initDevInspector({
57
- maxSize: 500,
58
- networkOptions: { includeBodies: false },
59
- panelOptions: { initiallyOpen: true, title: "Dev Inspector" },
60
- });
61
-
62
- storage.clear();
63
- destroy();
64
- ```
65
-
66
- ## Demo (Development)
62
+ ## Demo (Local development)
67
63
 
68
64
  ```bash
69
65
  npm install
@@ -72,40 +68,11 @@ npm run demo
72
68
 
73
69
  The demo page includes interactive generators for console logs and network requests so you can verify the panel quickly.
74
70
 
75
- ## API (Summary)
76
-
77
- ### `initDevInspector(options)`
78
-
79
- One-call integration that wires storage + loggers + UI.
80
-
81
- - `initDevInspector({ maxSize?, console?, network?, panel?, consoleLevels?, networkOptions?, panelOptions?, storage? })`
82
- - returns `{ storage, panel?, consoleLogger?, networkLogger?, destroy }`
83
-
84
- ### `LogStorage`
85
-
86
- - `new LogStorage({ maxSize?: number })`
87
- - `add(entry: LogEntry): void`
88
- - `getAll(): LogEntry[]`
89
- - `clear(): void` (emits `cleared`)
90
- - `onNewLog((entry) => void): () => void` (subscribe/unsubscribe)
91
-
92
- ### `installConsoleLogger(options)`
93
-
94
- Installs console interception and emits `LogEntry` objects.
95
-
96
- - `installConsoleLogger({ emit, levels? }) -> { uninstall, installed }`
97
-
98
- ### `installNetworkLogger(options)`
99
-
100
- Installs network interception for `fetch` and `XMLHttpRequest` and emits `LogEntry` objects.
101
-
102
- - `installNetworkLogger({ emit, includeBodies?, maxBodyLength? }) -> { uninstall, installed }`
103
-
104
- ### `createPanel(options)`
71
+ ## API
105
72
 
106
- Renders the UI panel and connects it to a `LogStorage`.
73
+ ### `initDevInspector()`
107
74
 
108
- - `createPanel({ storage, title?, initiallyOpen?, mount? }) -> { open, close, toggle, destroy, isOpen }`
75
+ One-call integration that installs console + network interception and renders the UI panel.
109
76
 
110
77
  ## Environment Notes
111
78
 
package/lib/index.d.ts CHANGED
@@ -1,6 +1 @@
1
- export { installConsoleLogger, type ConsoleLoggerHandle, type ConsoleLoggerOptions, } from "./logger/consoleLogger";
2
- export { installNetworkLogger, type NetworkLoggerHandle, type NetworkLoggerOptions } from "./logger/networkLogger";
3
- export { LogStorage, type LogStorageOptions } from "./storage/logStorage";
4
- export { createPanel, type PanelHandle, type PanelOptions } from "./ui/panel";
5
- export { init, initDevInspector, type DevInspectorHandle, type DevInspectorInitOptions } from "./init";
6
- export type { ConsoleLogLevel, LogEntry, LogSource } from "./utils/types";
1
+ export { initDevInspector } from "./init";
package/lib/index.js CHANGED
@@ -1,14 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initDevInspector = exports.init = exports.createPanel = exports.LogStorage = exports.installNetworkLogger = exports.installConsoleLogger = void 0;
4
- var consoleLogger_1 = require("./logger/consoleLogger");
5
- Object.defineProperty(exports, "installConsoleLogger", { enumerable: true, get: function () { return consoleLogger_1.installConsoleLogger; } });
6
- var networkLogger_1 = require("./logger/networkLogger");
7
- Object.defineProperty(exports, "installNetworkLogger", { enumerable: true, get: function () { return networkLogger_1.installNetworkLogger; } });
8
- var logStorage_1 = require("./storage/logStorage");
9
- Object.defineProperty(exports, "LogStorage", { enumerable: true, get: function () { return logStorage_1.LogStorage; } });
10
- var panel_1 = require("./ui/panel");
11
- Object.defineProperty(exports, "createPanel", { enumerable: true, get: function () { return panel_1.createPanel; } });
3
+ exports.initDevInspector = void 0;
12
4
  var init_1 = require("./init");
13
- Object.defineProperty(exports, "init", { enumerable: true, get: function () { return init_1.init; } });
14
5
  Object.defineProperty(exports, "initDevInspector", { enumerable: true, get: function () { return init_1.initDevInspector; } });
package/lib/init.d.ts CHANGED
@@ -1,24 +1,13 @@
1
- import { type ConsoleLoggerHandle } from "./logger/consoleLogger";
2
- import { type NetworkLoggerHandle, type NetworkLoggerOptions } from "./logger/networkLogger";
3
- import { LogStorage } from "./storage/logStorage";
4
- import { type PanelHandle, type PanelOptions } from "./ui/panel";
5
- import type { ConsoleLogLevel } from "./utils/types";
6
- export type DevInspectorInitOptions = {
1
+ type InitOptions = {
7
2
  maxSize?: number;
8
- storage?: LogStorage;
9
- panel?: boolean;
10
- panelOptions?: Omit<PanelOptions, "storage">;
11
- console?: boolean;
12
- consoleLevels?: ConsoleLogLevel[];
13
- network?: boolean;
14
- networkOptions?: Omit<NetworkLoggerOptions, "emit">;
3
+ panelOptions?: {
4
+ title?: string;
5
+ initiallyOpen?: boolean;
6
+ };
7
+ networkOptions?: {
8
+ includeBodies?: boolean;
9
+ maxBodyLength?: number;
10
+ };
15
11
  };
16
- export type DevInspectorHandle = {
17
- storage: LogStorage;
18
- panel?: PanelHandle;
19
- consoleLogger?: ConsoleLoggerHandle;
20
- networkLogger?: NetworkLoggerHandle;
21
- destroy: () => void;
22
- };
23
- export declare function initDevInspector(options?: DevInspectorInitOptions): DevInspectorHandle;
24
- export declare const init: typeof initDevInspector;
12
+ export declare function initDevInspector(options?: InitOptions): void;
13
+ export {};
package/lib/init.js CHANGED
@@ -1,51 +1,60 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.init = void 0;
4
3
  exports.initDevInspector = initDevInspector;
5
4
  const consoleLogger_1 = require("./logger/consoleLogger");
6
5
  const networkLogger_1 = require("./logger/networkLogger");
7
6
  const logStorage_1 = require("./storage/logStorage");
8
7
  const panel_1 = require("./ui/panel");
8
+ function getGlobalInstanceKey() {
9
+ return Symbol.for("dev-inspector.instance");
10
+ }
11
+ function getGlobalBag() {
12
+ return globalThis;
13
+ }
9
14
  function initDevInspector(options = {}) {
10
- var _a, _b, _c, _d, _e, _f;
11
- const storage = (_a = options.storage) !== null && _a !== void 0 ? _a : new logStorage_1.LogStorage({
12
- maxSize: options.maxSize,
15
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
16
+ const key = getGlobalInstanceKey();
17
+ const bag = getGlobalBag();
18
+ const prev = bag[key];
19
+ if (prev) {
20
+ try {
21
+ prev.destroy();
22
+ }
23
+ catch (_k) {
24
+ void 0;
25
+ }
26
+ }
27
+ const storage = new logStorage_1.LogStorage({ maxSize: (_a = options.maxSize) !== null && _a !== void 0 ? _a : 500 });
28
+ const consoleLogger = (0, consoleLogger_1.installConsoleLogger)({ emit: (e) => storage.add(e) });
29
+ const networkLogger = (0, networkLogger_1.installNetworkLogger)({
30
+ emit: (e) => storage.add(e),
31
+ includeBodies: (_c = (_b = options.networkOptions) === null || _b === void 0 ? void 0 : _b.includeBodies) !== null && _c !== void 0 ? _c : false,
32
+ maxBodyLength: (_e = (_d = options.networkOptions) === null || _d === void 0 ? void 0 : _d.maxBodyLength) !== null && _e !== void 0 ? _e : 20000,
33
+ });
34
+ const panel = (0, panel_1.createPanel)({
35
+ storage,
36
+ initiallyOpen: (_g = (_f = options.panelOptions) === null || _f === void 0 ? void 0 : _f.initiallyOpen) !== null && _g !== void 0 ? _g : true,
37
+ title: (_j = (_h = options.panelOptions) === null || _h === void 0 ? void 0 : _h.title) !== null && _j !== void 0 ? _j : "Dev Inspector",
13
38
  });
14
- const consoleEnabled = (_b = options.console) !== null && _b !== void 0 ? _b : true;
15
- const networkEnabled = (_c = options.network) !== null && _c !== void 0 ? _c : true;
16
- const panelEnabled = (_d = options.panel) !== null && _d !== void 0 ? _d : true;
17
- const consoleLogger = consoleEnabled
18
- ? (0, consoleLogger_1.installConsoleLogger)({
19
- emit: (e) => storage.add(e),
20
- levels: options.consoleLevels,
21
- })
22
- : undefined;
23
- const networkLogger = networkEnabled
24
- ? (0, networkLogger_1.installNetworkLogger)(Object.assign({ emit: (e) => storage.add(e) }, ((_e = options.networkOptions) !== null && _e !== void 0 ? _e : {})))
25
- : undefined;
26
- const panel = panelEnabled
27
- ? (0, panel_1.createPanel)(Object.assign({ storage }, ((_f = options.panelOptions) !== null && _f !== void 0 ? _f : {})))
28
- : undefined;
29
39
  const destroy = () => {
30
40
  try {
31
- panel === null || panel === void 0 ? void 0 : panel.destroy();
41
+ panel.destroy();
32
42
  }
33
43
  catch (_a) {
34
44
  void 0;
35
45
  }
36
46
  try {
37
- consoleLogger === null || consoleLogger === void 0 ? void 0 : consoleLogger.uninstall();
47
+ consoleLogger.uninstall();
38
48
  }
39
49
  catch (_b) {
40
50
  void 0;
41
51
  }
42
52
  try {
43
- networkLogger === null || networkLogger === void 0 ? void 0 : networkLogger.uninstall();
53
+ networkLogger.uninstall();
44
54
  }
45
55
  catch (_c) {
46
56
  void 0;
47
57
  }
48
58
  };
49
- return { storage, panel, consoleLogger, networkLogger, destroy };
59
+ bag[key] = { destroy };
50
60
  }
51
- exports.init = initDevInspector;
@@ -14,12 +14,12 @@ function safeToString(value) {
14
14
  return "[unstringifiable]";
15
15
  }
16
16
  }
17
- function truncateString(value, maxLen) {
17
+ function truncateStringMeta(value, maxLen) {
18
18
  if (maxLen <= 0)
19
- return "";
19
+ return { value: "", truncated: value.length > 0 };
20
20
  if (value.length <= maxLen)
21
- return value;
22
- return value.slice(0, maxLen);
21
+ return { value, truncated: false };
22
+ return { value: value.slice(0, maxLen), truncated: true };
23
23
  }
24
24
  function coerceUrl(input) {
25
25
  if (typeof input === "string")
@@ -52,7 +52,8 @@ function formatUrlForMessage(raw) {
52
52
  async function readResponseBody(response, maxLen) {
53
53
  try {
54
54
  const text = await response.text();
55
- return truncateString(text, maxLen);
55
+ const t = truncateStringMeta(text, maxLen);
56
+ return { body: t.value, truncated: t.truncated };
56
57
  }
57
58
  catch (_a) {
58
59
  return undefined;
@@ -79,30 +80,40 @@ function installNetworkLogger(options) {
79
80
  const originalXhrSend = canXhr ? g.XMLHttpRequest.prototype.send : undefined;
80
81
  if (canFetch) {
81
82
  g.fetch = (async (...args) => {
82
- var _a;
83
+ var _a, _b;
83
84
  const id = createId();
84
85
  let method;
85
86
  let url;
86
87
  let requestBody;
88
+ let requestBodyTruncated = false;
87
89
  try {
88
90
  const [input, init] = args;
89
91
  url = coerceUrl(input);
90
92
  const reqMethodFromInit = init === null || init === void 0 ? void 0 : init.method;
91
93
  const reqMethodFromInput = input && typeof input.method === "string" ? input.method : undefined;
92
94
  method = ((_a = reqMethodFromInit !== null && reqMethodFromInit !== void 0 ? reqMethodFromInit : reqMethodFromInput) !== null && _a !== void 0 ? _a : "GET").toUpperCase();
93
- if (includeBodies && init && "body" in init)
95
+ if (includeBodies && init && "body" in init) {
94
96
  requestBody = init.body;
97
+ if (typeof requestBody === "string") {
98
+ const t = truncateStringMeta(requestBody, maxBodyLength);
99
+ requestBody = t.value;
100
+ requestBodyTruncated = t.truncated;
101
+ }
102
+ }
95
103
  }
96
- catch (_b) {
104
+ catch (_c) {
97
105
  void 0;
98
106
  }
99
107
  try {
100
108
  const res = await Reflect.apply(originalFetch, globalThis, args);
101
109
  const status = res.status;
102
110
  let responseBody;
111
+ let responseBodyTruncated = false;
103
112
  if (includeBodies) {
104
113
  const cloned = res.clone();
105
- responseBody = await readResponseBody(cloned, maxBodyLength);
114
+ const r = await readResponseBody(cloned, maxBodyLength);
115
+ responseBody = r === null || r === void 0 ? void 0 : r.body;
116
+ responseBodyTruncated = (_b = r === null || r === void 0 ? void 0 : r.truncated) !== null && _b !== void 0 ? _b : false;
106
117
  }
107
118
  if (active) {
108
119
  const entry = {
@@ -113,7 +124,10 @@ function installNetworkLogger(options) {
113
124
  url,
114
125
  status,
115
126
  requestBody: includeBodies ? requestBody : undefined,
127
+ requestBodyTruncated: includeBodies ? requestBodyTruncated : undefined,
116
128
  responseBody: includeBodies ? responseBody : undefined,
129
+ responseBodyTruncated: includeBodies ? responseBodyTruncated : undefined,
130
+ bodyMaxLength: includeBodies ? maxBodyLength : undefined,
117
131
  message: makeMessage({ method, url, status }),
118
132
  };
119
133
  options.emit(entry);
@@ -130,7 +144,10 @@ function installNetworkLogger(options) {
130
144
  url,
131
145
  status: undefined,
132
146
  requestBody: includeBodies ? requestBody : undefined,
147
+ requestBodyTruncated: includeBodies ? requestBodyTruncated : undefined,
133
148
  responseBody: includeBodies ? safeToString(err) : undefined,
149
+ responseBodyTruncated: undefined,
150
+ bodyMaxLength: includeBodies ? maxBodyLength : undefined,
134
151
  message: makeMessage({ method, url, status: undefined }),
135
152
  };
136
153
  options.emit(entry);
@@ -156,9 +173,15 @@ function installNetworkLogger(options) {
156
173
  proto.send = function (...args) {
157
174
  var _a;
158
175
  const meta = (_a = xhrMeta.get(this)) !== null && _a !== void 0 ? _a : { id: createId() };
176
+ let requestBodyTruncated = false;
159
177
  if (includeBodies) {
160
178
  try {
161
179
  meta.requestBody = args[0];
180
+ if (typeof meta.requestBody === "string") {
181
+ const t = truncateStringMeta(meta.requestBody, maxBodyLength);
182
+ meta.requestBody = t.value;
183
+ requestBodyTruncated = t.truncated;
184
+ }
162
185
  }
163
186
  catch (_b) {
164
187
  void 0;
@@ -168,10 +191,14 @@ function installNetworkLogger(options) {
168
191
  const onLoadEnd = () => {
169
192
  const status = typeof this.status === "number" ? this.status : undefined;
170
193
  let responseBody;
194
+ let responseBodyTruncated = false;
171
195
  if (includeBodies) {
172
196
  try {
173
- if (typeof this.responseText === "string")
174
- responseBody = truncateString(this.responseText, maxBodyLength);
197
+ if (typeof this.responseText === "string") {
198
+ const t = truncateStringMeta(this.responseText, maxBodyLength);
199
+ responseBody = t.value;
200
+ responseBodyTruncated = t.truncated;
201
+ }
175
202
  else
176
203
  responseBody = undefined;
177
204
  }
@@ -188,7 +215,10 @@ function installNetworkLogger(options) {
188
215
  url: meta.url,
189
216
  status,
190
217
  requestBody: includeBodies ? meta.requestBody : undefined,
218
+ requestBodyTruncated: includeBodies ? requestBodyTruncated : undefined,
191
219
  responseBody: includeBodies ? responseBody : undefined,
220
+ responseBodyTruncated: includeBodies ? responseBodyTruncated : undefined,
221
+ bodyMaxLength: includeBodies ? maxBodyLength : undefined,
192
222
  message: makeMessage({ method: meta.method, url: meta.url, status }),
193
223
  };
194
224
  options.emit(entry);
@@ -0,0 +1,2 @@
1
+ import type { LogList } from "./types";
2
+ export declare function createLogList(doc: Document): LogList;
@@ -0,0 +1,67 @@
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("./networkDetails");
6
+ const shared_1 = require("./shared");
7
+ const shared_2 = require("./shared");
8
+ function createLogList(doc) {
9
+ const el = doc.createElement("ul");
10
+ el.className = "di-list";
11
+ const append = (entry) => {
12
+ const li = doc.createElement("li");
13
+ const tone = (0, shared_2.toneForEntry)(entry);
14
+ li.className = `di-item ${(0, shared_2.classForTone)(tone)}`;
15
+ const meta = doc.createElement("div");
16
+ meta.className = "di-meta";
17
+ const time = doc.createElement("span");
18
+ time.textContent = (0, shared_2.fmtTime)(entry.timestamp);
19
+ const source = doc.createElement("span");
20
+ source.textContent = entry.source;
21
+ const detail = doc.createElement("span");
22
+ if (entry.source === "console") {
23
+ detail.textContent = entry.level;
24
+ }
25
+ else {
26
+ detail.className = `di-statusChip ${(0, shared_2.isNetworkFailure)(entry) ? "di-statusChipError" : "di-statusChipSuccess"}`;
27
+ detail.textContent = typeof entry.status === "number" ? String(entry.status) : "ERR";
28
+ }
29
+ meta.append(time, source, detail);
30
+ li.append(meta);
31
+ if (entry.message && entry.message.trim().length > 0) {
32
+ const msg = doc.createElement("div");
33
+ msg.className = "di-msg";
34
+ msg.textContent = entry.message;
35
+ li.append(msg);
36
+ }
37
+ if (entry.source === "console") {
38
+ const inspectable = (0, shared_1.getInspectableArgs)(entry.args);
39
+ if (inspectable.length > 0) {
40
+ const details = doc.createElement("details");
41
+ details.className = "di-details";
42
+ const summary = doc.createElement("summary");
43
+ summary.className = "di-detailsSummary";
44
+ summary.textContent = "Inspect";
45
+ const viewerWrap = doc.createElement("div");
46
+ viewerWrap.className = "di-detailsBody";
47
+ viewerWrap.append((0, jsonViewer_1.createJsonViewer)(doc, inspectable.length === 1 ? inspectable[0] : inspectable, {
48
+ maxDepth: 6,
49
+ maxKeys: 200,
50
+ maxNodes: 2000,
51
+ }));
52
+ details.append(summary, viewerWrap);
53
+ li.append(details);
54
+ }
55
+ }
56
+ if (entry.source === "network") {
57
+ const details = (0, networkDetails_1.createNetworkDetails)(doc, entry);
58
+ if (details)
59
+ li.append(details);
60
+ }
61
+ el.append(li);
62
+ };
63
+ const clear = () => {
64
+ el.replaceChildren();
65
+ };
66
+ return { el, append, clear };
67
+ }
@@ -0,0 +1,2 @@
1
+ export { createLogList } from "./createLogList";
2
+ export type { LogList } from "./types";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLogList = void 0;
4
+ var createLogList_1 = require("./createLogList");
5
+ Object.defineProperty(exports, "createLogList", { enumerable: true, get: function () { return createLogList_1.createLogList; } });
@@ -0,0 +1,2 @@
1
+ export declare function launchMiniConfetti(anchor: HTMLElement): void;
2
+ export declare function copyText(text: string): Promise<boolean>;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.launchMiniConfetti = launchMiniConfetti;
4
+ exports.copyText = copyText;
5
+ function prefersReducedMotion() {
6
+ var _a, _b;
7
+ try {
8
+ const mm = globalThis;
9
+ 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;
10
+ }
11
+ catch (_c) {
12
+ return false;
13
+ }
14
+ }
15
+ function rand(min, max) {
16
+ return min + Math.random() * (max - min);
17
+ }
18
+ function launchMiniConfetti(anchor) {
19
+ if (prefersReducedMotion())
20
+ return;
21
+ if (typeof document === "undefined")
22
+ return;
23
+ const rect = anchor.getBoundingClientRect();
24
+ const cx = rect.left + rect.width / 2;
25
+ const cy = rect.top + rect.height / 2;
26
+ const root = document.createElement("div");
27
+ root.style.position = "fixed";
28
+ root.style.left = "0";
29
+ root.style.top = "0";
30
+ root.style.width = "0";
31
+ root.style.height = "0";
32
+ root.style.pointerEvents = "none";
33
+ root.style.zIndex = "2147483647";
34
+ document.body.append(root);
35
+ const colors = ["#a7ff00", "#7c5cff", "#00c4ff", "#ff9030", "#ef4444"];
36
+ const n = 14;
37
+ const duration = 520;
38
+ for (let i = 0; i < n; i += 1) {
39
+ const p = document.createElement("span");
40
+ const size = Math.round(rand(3, 6));
41
+ p.style.position = "fixed";
42
+ p.style.left = `${cx}px`;
43
+ p.style.top = `${cy}px`;
44
+ p.style.width = `${size}px`;
45
+ p.style.height = `${size}px`;
46
+ p.style.borderRadius = Math.random() < 0.35 ? "999px" : "2px";
47
+ p.style.background = colors[i % colors.length];
48
+ p.style.opacity = "1";
49
+ p.style.willChange = "transform, opacity";
50
+ root.append(p);
51
+ const angle = rand(0, Math.PI * 2);
52
+ const dist = rand(18, 46);
53
+ const dx = Math.cos(angle) * dist;
54
+ const dy = Math.sin(angle) * dist + rand(8, 16);
55
+ const rot = rand(-220, 220);
56
+ const delay = Math.round(rand(0, 60));
57
+ try {
58
+ const anim = p.animate([
59
+ { transform: `translate(-50%, -50%) translate(0px, 0px) rotate(0deg) scale(1)`, opacity: 1 },
60
+ { transform: `translate(-50%, -50%) translate(${dx}px, ${dy}px) rotate(${rot}deg) scale(0.9)`, opacity: 0 },
61
+ ], { duration, delay, easing: "cubic-bezier(0.2, 0.7, 0.2, 1)", fill: "forwards" });
62
+ anim.addEventListener("finish", () => p.remove());
63
+ }
64
+ catch (_a) {
65
+ globalThis.setTimeout(() => p.remove(), duration + delay + 50);
66
+ }
67
+ }
68
+ globalThis.setTimeout(() => root.remove(), duration + 120);
69
+ }
70
+ async function copyText(text) {
71
+ var _a, _b;
72
+ try {
73
+ const nav = globalThis;
74
+ const fn = (_b = (_a = nav.navigator) === null || _a === void 0 ? void 0 : _a.clipboard) === null || _b === void 0 ? void 0 : _b.writeText;
75
+ if (typeof fn === "function") {
76
+ await fn(text);
77
+ return true;
78
+ }
79
+ }
80
+ catch (_c) {
81
+ void 0;
82
+ }
83
+ try {
84
+ if (typeof document === "undefined")
85
+ return false;
86
+ const ta = document.createElement("textarea");
87
+ ta.value = text;
88
+ ta.setAttribute("readonly", "true");
89
+ ta.style.position = "fixed";
90
+ ta.style.left = "-9999px";
91
+ ta.style.top = "0";
92
+ document.body.append(ta);
93
+ ta.select();
94
+ const ok = document.execCommand("copy");
95
+ ta.remove();
96
+ return ok;
97
+ }
98
+ catch (_d) {
99
+ return false;
100
+ }
101
+ }
@@ -0,0 +1,2 @@
1
+ import type { NetworkLogEntry } from "../../../utils/types";
2
+ export declare function createNetworkDetails(doc: Document, entry: NetworkLogEntry): HTMLElement | null;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNetworkDetails = createNetworkDetails;
4
+ const copy_1 = require("./copy");
5
+ const renderValue_1 = require("./renderValue");
6
+ function createBodyDetails(doc, title, value, truncated, maxLen) {
7
+ const details = doc.createElement("details");
8
+ details.className = "di-details di-netBodyDetails";
9
+ const summary = doc.createElement("summary");
10
+ summary.className = "di-detailsSummary di-netDetailsSummary";
11
+ const titleEl = doc.createElement("span");
12
+ titleEl.className = "di-netDetailsTitle";
13
+ titleEl.textContent = title;
14
+ const copyBtn = doc.createElement("button");
15
+ copyBtn.type = "button";
16
+ copyBtn.className = "di-copyBtn";
17
+ copyBtn.textContent = "Copy";
18
+ copyBtn.setAttribute("aria-label", `Copy ${title.toLowerCase()}`);
19
+ copyBtn.addEventListener("click", (ev) => {
20
+ ev.preventDefault();
21
+ ev.stopPropagation();
22
+ const txt = (0, renderValue_1.valueToCopyText)(value);
23
+ void (0, copy_1.copyText)(txt).then((ok) => {
24
+ if (!ok)
25
+ return;
26
+ (0, copy_1.launchMiniConfetti)(copyBtn);
27
+ const prev = copyBtn.textContent;
28
+ copyBtn.textContent = "Copied";
29
+ globalThis.setTimeout(() => {
30
+ copyBtn.textContent = prev !== null && prev !== void 0 ? prev : "Copy";
31
+ }, 900);
32
+ });
33
+ });
34
+ summary.append(titleEl, copyBtn);
35
+ const body = doc.createElement("div");
36
+ body.className = "di-detailsBody";
37
+ if (truncated) {
38
+ const warn = doc.createElement("div");
39
+ warn.className = "di-netTrunc";
40
+ warn.textContent = typeof maxLen === "number" ? `Truncated to first ${maxLen} characters.` : "Truncated.";
41
+ body.append(warn);
42
+ }
43
+ body.append((0, renderValue_1.valueToElement)(doc, value));
44
+ details.append(summary, body);
45
+ return details;
46
+ }
47
+ function createNetworkDetails(doc, entry) {
48
+ const hasReq = typeof entry.requestBody !== "undefined";
49
+ const hasRes = typeof entry.responseBody !== "undefined";
50
+ if (!hasReq && !hasRes)
51
+ return null;
52
+ const wrap = doc.createElement("div");
53
+ wrap.className = "di-netDetailsWrap";
54
+ if (hasReq) {
55
+ wrap.append(createBodyDetails(doc, "Request", entry.requestBody, entry.requestBodyTruncated === true, entry.bodyMaxLength));
56
+ }
57
+ if (hasRes) {
58
+ wrap.append(createBodyDetails(doc, "Response", entry.responseBody, entry.responseBodyTruncated === true, entry.bodyMaxLength));
59
+ }
60
+ return wrap;
61
+ }
@@ -0,0 +1 @@
1
+ export { createNetworkDetails } from "./createNetworkDetails";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNetworkDetails = void 0;
4
+ var createNetworkDetails_1 = require("./createNetworkDetails");
5
+ Object.defineProperty(exports, "createNetworkDetails", { enumerable: true, get: function () { return createNetworkDetails_1.createNetworkDetails; } });
@@ -0,0 +1,2 @@
1
+ export declare function valueToElement(doc: Document, value: unknown): HTMLElement;
2
+ export declare function valueToCopyText(value: unknown): string;