@monkey2582/thinconsole 1.3.5 → 1.3.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monkey2582/thinconsole",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "thinConsole是一个轻量级、功能丰富的浏览器端 JavaScript 控制台增强库。它提供了一个可浮动的按钮,点击后可以展开一个功能强大的控制台面板,用于捕获和查看日志、管理本地存储(LocalStorage)、记录系统事件,并支持通过插件系统进行扩展。",
5
5
  "keywords": [
6
6
  "console",
package/thinConsole.d.ts CHANGED
@@ -1,175 +1,110 @@
1
- // Type definitions for thinConsole v1.3.5
2
- // Project: thinConsole - A lightweight mobile web debugging console
3
- // UMD module: supports CommonJS, AMD, and global (browser window.thinConsole)
4
-
5
- // Class + namespace merge: class provides the value & constructor,
6
- // namespace provides additional types accessible as thinConsole.X
7
- declare class thinConsole {
8
- constructor(options?: thinConsole.Options);
9
-
10
- // ---- Instance properties ----
11
- version: string;
12
- options: Required<
13
- Omit<thinConsole.Options, "filters"> & { filters: thinConsole.Filter[] | null }
14
- >;
15
- currentTab: string;
16
- currentTheme: "light" | "dark";
17
- selectedElement: Node | null;
18
- logs: thinConsole.LogEntry[];
19
- networkRequests: thinConsole.NetworkRequest[];
20
- maxLog: number;
21
- /** Maximum number of network requests to retain (default: 1000) */
22
- maxNetwork: number;
23
-
24
- // ---- Instance methods ----
25
- show(tab?: string): thinConsole;
26
- hide(): thinConsole;
27
- destroy(): void;
28
- switchTab(tab: string): void;
29
- showNotification(message: string, type?: string): void;
30
- toggleSearch(visible?: boolean): void;
31
- toggleMute(): void;
32
- clearAllLogs(silent?: boolean): void;
33
- startElementPicker(): void;
34
- deleteElement(element: Node): void;
35
- copyElementHTML(element: Element): void;
36
- expandToElement(element: Node): void;
37
- getShadowRoot(element: Element): thinConsole.ShadowRootInfo | null;
38
- registerPlugin(id: string, pluginClass: any, config?: any): thinConsole;
39
- disablePlugin(id: string): thinConsole;
40
- enablePlugin(id: string): thinConsole;
41
- destroyPlugin(id: string): void;
42
- triggerGlobalHook(name: thinConsole.HookName, ...args: any[]): thinConsole;
43
- renderJSONTree(
44
- obj: any,
45
- key?: string,
46
- path?: string,
47
- chain?: any[],
48
- noProto?: boolean
49
- ): string;
50
- renderHTMLTree(
51
- element: Node,
52
- key?: string,
53
- path?: string,
54
- depth?: number
55
- ): string;
56
- renderElementTree(element: Node, depth: number): string;
57
- escapeHtml(str: string): string;
58
- captureConsole(type: string, ...args: any[]): void;
1
+ /**
2
+ * thinConsole - A lightweight web debugging console
3
+ * @version 1.3.7
4
+ */
59
5
 
60
- /**
61
- * Format a count number into compact display.
62
- * - <= 999: returns the number as-is
63
- * - 1000-99999: returns K format with 1 decimal (e.g. "1K", "1.1K")
64
- * - >= 100000: returns "XK+" (e.g. "100K+")
65
- * @param n The exact count
66
- * @param plusK If true, append "+" for K values (used by network/storage)
67
- * @returns Object with filterCount (display string/number) and exactCount (raw number)
68
- */
69
- _fmtCount(n: number, plusK?: boolean): thinConsole.FilterCountResult;
6
+ declare namespace thinConsole {
70
7
 
71
- /**
72
- * Unified filter count updater for both built-in (console) and plugin tabs.
73
- * @param container Filter button container (filterButtons or plugin view container)
74
- * @param counts Count lookup object (type -> number | FilterCountResult)
75
- * @param isPlugin If true, use plugin rendering (icon + orig); else console (cached HTML)
76
- */
77
- _updateFilterCounts(
78
- container: HTMLElement | NodeListOf<Element> | null,
79
- counts: Record<string, number | thinConsole.FilterCountResult> | null,
80
- isPlugin: boolean
81
- ): void;
82
-
83
- // ---- Static properties ----
84
- static readonly version: string;
85
- static tC: thinConsole | null;
86
- static plugins: Record<string, any>;
87
- static hooks: Record<thinConsole.HookName, thinConsole.HookCallback[]>;
88
-
89
- // ---- Static methods ----
90
- static show(tab?: string): typeof thinConsole;
91
- static hide(): typeof thinConsole;
92
- static destroy(): void;
93
- static log(...args: any[]): typeof thinConsole;
94
- static info(...args: any[]): typeof thinConsole;
95
- static warn(...args: any[]): typeof thinConsole;
96
- static error(...args: any[]): typeof thinConsole;
97
- static addPlugin(id: string, pluginClass: any, config?: any): typeof thinConsole;
98
- static addTabs(
99
- tabs: thinConsole.TabConfig | thinConsole.TabConfig[]
100
- ): typeof thinConsole;
101
- static addHook(
102
- name: thinConsole.HookName,
103
- callback: thinConsole.HookCallback
104
- ): typeof thinConsole;
105
- static removeHook(
106
- name: thinConsole.HookName,
107
- callback: thinConsole.HookCallback
108
- ): typeof thinConsole;
109
- static setFilterCounts(
110
- counts: Record<string, number | thinConsole.FilterCountResult>
111
- ): typeof thinConsole;
112
- }
8
+ /** Position configuration for the floating button */
9
+ interface Position {
10
+ x: number;
11
+ y: number;
12
+ }
113
13
 
114
- declare namespace thinConsole {
115
- // ============= Options & Config =============
14
+ /** Custom filter configuration */
15
+ interface FilterConfig {
16
+ id: string;
17
+ name: string;
18
+ }
116
19
 
20
+ /** Constructor options */
117
21
  interface Options {
118
- /** Button text (max 11 chars, no HTML special chars) */
22
+ /** Button text (max 11 chars, default "thinConsole") */
119
23
  text?: string;
120
- /** Button background color */
24
+ /** Button background color (default "#007aff") */
121
25
  color?: string;
122
- /** Button width (CSS value) */
26
+ /** Button width (default "auto") */
123
27
  width?: string;
124
- /** Button height (CSS value) */
28
+ /** Button height (default "auto") */
125
29
  height?: string;
126
- /** Theme mode */
127
- theme?: "light" | "dark" | "auto";
128
- /** Enable plugin system */
30
+ /** Theme: "light", "dark", "auto", or custom theme name (default "auto") */
31
+ theme?: string;
32
+ /** Enable plugins (default true) */
129
33
  plugins?: boolean;
130
- /** List of disabled plugin IDs */
34
+ /** List of disabled plugin names (default []) */
131
35
  disabledPlugins?: string[];
132
- /** Enable JS code execution via title click */
36
+ /** Enable JS execution (default true) */
133
37
  jsExecute?: boolean;
134
- /** Floating button position */
135
- pos?: { x: number; y: number };
136
- /** Maximum number of log entries to retain (default: 1000) */
38
+ /** Button position, null = saved/dragged (default null) */
39
+ pos?: Position | null;
40
+ /** Max number of log entries (default 100000) */
137
41
  maxLog?: number;
138
- /** Maximum number of network requests to retain (default: 1000) */
42
+ /** Max number of network requests (default 1000) */
139
43
  maxNetwork?: number;
140
- /** Custom console filter definitions */
141
- filters?: Filter[];
44
+ /** Per-plugin options keyed by plugin name (default {}) */
45
+ pluginOption?: Record<string, object>;
46
+ /** Custom log filters (default null = builtin) */
47
+ filters?: FilterConfig[] | null;
142
48
  }
143
49
 
144
- interface Filter {
145
- id: string;
146
- name: string;
147
- icon?: string;
50
+ /** Storage backend interface (local / session / cookie) */
51
+ interface StorageBackend {
52
+ get(key: string): string | null;
53
+ set(key: string, value: string, days?: number): void;
54
+ remove(key: string): void;
55
+ clear(): void;
56
+ length(): number;
57
+ key(index: number): string | null;
58
+ }
59
+
60
+ interface StorageAccessor {
61
+ local: StorageBackend;
62
+ session: StorageBackend;
63
+ cookie: StorageBackend;
64
+ }
65
+
66
+ /** Custom theme configuration */
67
+ interface ThemeConfig {
68
+ vars: Record<string, string>;
69
+ icons?: Record<string, string>;
70
+ }
71
+
72
+ /** Header button configuration */
73
+ interface HeaderButton {
74
+ icon: string;
75
+ fn?: () => void;
148
76
  }
149
77
 
78
+ /** Hook names and their handler arrays */
79
+ interface HookMap {
80
+ beforeRender: HookHandler[];
81
+ afterRender: HookHandler[];
82
+ beforeLog: HookHandler[];
83
+ afterLog: HookHandler[];
84
+ beforeOpen: HookHandler[];
85
+ afterOpen: HookHandler[];
86
+ beforeClose: HookHandler[];
87
+ afterClose: HookHandler[];
88
+ beforeClear: HookHandler[];
89
+ afterClear: HookHandler[];
90
+ pluginMount: HookHandler[];
91
+ pluginUnmount: HookHandler[];
92
+ }
93
+
94
+ type HookHandler = (...args: any[]) => void;
95
+
96
+ /** Custom tab configuration */
150
97
  interface TabConfig {
151
98
  id: string;
152
99
  name: string;
153
100
  icon?: string;
154
- /** Static HTML content for the tab */
101
+ render?(container: HTMLElement): void;
155
102
  html?: string;
156
- /** Dynamic render function for the tab content */
157
- render?: (container: HTMLElement) => void;
158
- /** Called when the tab is shown */
159
- onShow?: () => void;
103
+ onShow?(): void;
160
104
  }
161
105
 
162
- interface PluginTab {
163
- id: string;
164
- name: string;
165
- icon: string;
166
- plugin?: tCPlugin;
167
- onShow?: () => void;
168
- }
169
-
170
- // ============= Data Interfaces =============
171
-
172
- interface NetworkRequest {
106
+ /** Network request record */
107
+ interface NetRequest {
173
108
  id: number;
174
109
  url: string;
175
110
  method: string;
@@ -178,95 +113,253 @@ declare namespace thinConsole {
178
113
  reqHeaders: Record<string, string>;
179
114
  reqBody: any;
180
115
  resHeaders: Record<string, string>;
181
- resBody: any;
116
+ resBody: string | null;
182
117
  startTime: number;
183
118
  endTime: number;
184
119
  duration: number;
185
- error: any;
186
- }
187
-
188
- interface LogEntry {
189
- id: number;
190
- type: string;
191
- args: any[];
192
- time: number;
193
- stack?: string;
194
- subType?: string;
195
- extra?: any;
120
+ error: string | null;
196
121
  }
197
122
 
198
- interface ShadowRootInfo {
199
- root: ShadowRoot;
200
- mode: "open" | "closed";
123
+ /** Sandbox proxy that exposes instance API to plugins safely */
124
+ interface Sandbox {
125
+ tC: ThinConsole;
126
+ pluginOption: Record<string, object>;
127
+ readonly __isSandbox: boolean;
201
128
  }
202
129
 
203
- // ============= Filter Count =============
204
-
205
130
  /**
206
- * Result of count formatting. Used by filter buttons to display
207
- * a compact count in parentheses and the exact value on hover.
208
- *
209
- * - `filterCount`: displayed inside () on active filters
210
- * (string like "1K" / "1K+" / "100K+", or the raw number if <= 999)
211
- * - `exactCount`: shown in the title (tooltip) on hover
212
- *
213
- * For built-in tabs (console, network, storage) this is auto-generated
214
- * by `_fmtCount()`. For extension/plugin tabs, developers can pass
215
- * custom objects via `setFilterCounts()` to control both values.
131
+ * Base plugin class. Extend this to create a class-based plugin.
132
+ * ```ts
133
+ * class MyPlugin extends tCPlugin {
134
+ * init() { /* ... *\/ }
135
+ * addTab() { return { id: "my", name: "My Tab" }; }
136
+ * }
137
+ * thinConsole.addPlugin("my", MyPlugin);
138
+ * ```
216
139
  */
217
- interface FilterCountResult {
218
- filterCount: string | number;
219
- exactCount: number;
220
- }
221
-
222
- // ============= Hooks =============
223
-
224
- type HookName =
225
- | "beforeRender"
226
- | "afterRender"
227
- | "beforeLog"
228
- | "afterLog"
229
- | "beforeOpen"
230
- | "afterOpen"
231
- | "beforeClose"
232
- | "afterClose"
233
- | "beforeClear"
234
- | "afterClear"
235
- | "pluginMount"
236
- | "pluginUnmount";
237
-
238
- type HookCallback = (...args: any[]) => void;
239
-
240
- // ============= Plugin Base Class =============
241
-
242
- class tCPlugin {
243
- constructor(tC: thinConsole, config?: any);
244
- /** The thinConsole instance this plugin is bound to */
245
- tC: thinConsole;
246
- /** Plugin configuration object */
247
- config: any;
248
- /** Plugin ID (auto-derived from class name, lowercased) */
140
+ class Plugin {
141
+ protected tC: ThinConsole;
142
+ pluginOption: Record<string, object>;
249
143
  id: string;
250
- /** Initialize plugin — override in subclass */
144
+ constructor(tC: ThinConsole);
251
145
  init(): void;
252
- /** Whether the current language is Chinese */
253
146
  iszh(): boolean;
254
- /** Whether the current language is English */
255
147
  isen(): boolean;
256
- /** Whether running on a mobile device */
257
148
  isMobile(): boolean;
258
- /** Render plugin content into container — override in subclass */
259
149
  render(container: HTMLElement): void;
260
- /** Called when plugin tab becomes visible — override in subclass */
261
150
  onShow(): void;
262
- /** Called when plugin tab becomes hidden — override in subclass */
263
151
  onHide(): void;
264
- /** Cleanup when plugin is destroyed — override in subclass */
265
152
  destroy(): void;
266
- /** Define a tab for this plugin — override in subclass */
267
- addTab?(): PluginTab;
268
153
  }
154
+
155
+ /** ThinConsole instance */
156
+ class ThinConsole {
157
+ constructor(options?: Options);
158
+
159
+ /** Version string */
160
+ readonly version: string;
161
+
162
+ /** Current options (sanitized) */
163
+ readonly options: Options;
164
+
165
+ /** Current tab id */
166
+ currentTab: string;
167
+
168
+ /** Current theme id */
169
+ currentTheme: string;
170
+
171
+ /** Max log entries */
172
+ maxLog: number;
173
+
174
+ /** Max network request records */
175
+ maxNetwork: number;
176
+
177
+ /** Currently selected element */
178
+ selectedElement: Element | null;
179
+
180
+ /** Initialize the console (creates button + overlay) */
181
+ init(): void;
182
+
183
+ /** Show the console overlay, optionally switching to a tab */
184
+ show(tab?: string): this;
185
+
186
+ /** Hide the console overlay */
187
+ hide(): this;
188
+
189
+ /** Destroy the instance and remove all DOM elements */
190
+ destroy(): void;
191
+
192
+ /** Destroy and recreate with new options */
193
+ setOption(options: Options): this;
194
+
195
+ /** Switch to a tab by id */
196
+ switchTab(tab: string): void;
197
+
198
+ /** Show a toast notification */
199
+ showNotification(message: string, type?: string): void;
200
+
201
+ /** Toggle mute state for console logs */
202
+ toggleMute(): void;
203
+
204
+ /** Toggle search bar visibility */
205
+ toggleSearch(): void;
206
+
207
+ /** Run code from the title input */
208
+ runCode(): void;
209
+
210
+ /** Copy a log entry */
211
+ copyLog(id: string, plain?: boolean, raw?: boolean): void;
212
+
213
+ /** Clear all logs */
214
+ clearAllLogs(all?: boolean): void;
215
+
216
+ /** Add a localStorage item (opens editor) */
217
+ addLSItem(): void;
218
+
219
+ /** Edit a localStorage item by key */
220
+ editLSItem(key: string): void;
221
+
222
+ /** Save the current localStorage editor content */
223
+ saveLSItem(): void;
224
+
225
+ /** Remove a localStorage item by key */
226
+ removeLSItem(key: string): void;
227
+
228
+ /** Start the element picker mode */
229
+ startElementPicker(): void;
230
+
231
+ /** Expand the element tree to reveal a specific element */
232
+ expandToElement(el: Element): void;
233
+
234
+ /** Copy an element's HTML */
235
+ copyElementHTML(el: Element): void;
236
+
237
+ /** Delete an element from the DOM */
238
+ deleteElement(el: Element): void;
239
+
240
+ /** Start observing DOM mutations for element tree updates */
241
+ startElementObserver(): void;
242
+
243
+ /** Stop the element mutation observer */
244
+ stopElementObserver(): void;
245
+
246
+ /** Re-render current tab content */
247
+ renderContent(): void;
248
+
249
+ /** Capture XHR and fetch network requests */
250
+ captureNetworkRequests(): void;
251
+
252
+ /** Render the network request list */
253
+ renderNetworkList(): void;
254
+
255
+ /** Clear network requests (respects active filter) */
256
+ clearNetworkRequests(): void;
257
+
258
+ /** Send a new network request from the request editor */
259
+ sendNewRequest(): void;
260
+
261
+ /** Show network request detail panel */
262
+ showNetDetail(id: number): void;
263
+
264
+ /** Resend a previous network request */
265
+ resendRequest(req: NetRequest): void;
266
+
267
+ /** Apply custom icon overrides */
268
+ applyIcon(icons: Record<string, string>): void;
269
+
270
+ /** Set the icon for a specific filter button */
271
+ setFilterIcon(filterId: string, iconId: string): boolean;
272
+
273
+ /** Disable a plugin by name */
274
+ disablePlugin(name: string): this;
275
+
276
+ /** Enable a previously disabled plugin */
277
+ enablePlugin(name: string): this;
278
+
279
+ /** Trigger a global hook with arguments */
280
+ triggerGlobalHook(name: keyof HookMap, ...args: any[]): void;
281
+
282
+ /** Load a single plugin by name */
283
+ loadSinglePlugin(name: string): this;
284
+
285
+ /** Create a sandbox proxy for plugin isolation */
286
+ createSandbox(target: ThinConsole): Sandbox;
287
+
288
+ /** Escape HTML special characters */
289
+ escapeHtml(str: string): string;
290
+
291
+ /** Safe JSON stringify with circular reference handling */
292
+ safeStringify(value: any, indent?: number, json?: boolean): string;
293
+
294
+ /** Get the icon SVG string */
295
+ icon(name: string, className?: string): string;
296
+
297
+ /** Storage accessor (local, session, cookie) */
298
+ readonly storage: StorageAccessor;
299
+ }
300
+
301
+ // ---- Static API ----
302
+
303
+ /** Current singleton instance, or null */
304
+ const tC: ThinConsole | null;
305
+
306
+ /** Registered plugins (class-based) */
307
+ const plugins: Record<string, typeof Plugin>;
308
+
309
+ /** Registered themes */
310
+ const themes: Record<string, ThemeConfig>;
311
+
312
+ /** Registered header buttons (max 5) */
313
+ const headerButtons: HeaderButton[];
314
+
315
+ /** Global hook arrays */
316
+ const hooks: HookMap;
317
+
318
+ /** Register a custom theme */
319
+ function addTheme(
320
+ name: string,
321
+ styles: string,
322
+ icons?: Record<string, string>
323
+ ): typeof thinConsole;
324
+
325
+ /** Add a header button (max 5) */
326
+ function addHeader(icon: string, fn?: () => void): typeof thinConsole;
327
+
328
+ /** Set options (destroys and recreates the singleton) */
329
+ function setOption(options: Options): typeof thinConsole;
330
+
331
+ /** Show the console overlay (static convenience) */
332
+ function show(tab?: string): typeof thinConsole;
333
+
334
+ /** Hide the console overlay (static convenience) */
335
+ function hide(): typeof thinConsole;
336
+
337
+ /** Destroy the singleton (static convenience) */
338
+ function destroy(): typeof thinConsole;
339
+
340
+ /** console.log passthrough (static convenience) */
341
+ function log(...args: any[]): typeof thinConsole;
342
+
343
+ /** console.info passthrough (static convenience) */
344
+ function info(...args: any[]): typeof thinConsole;
345
+
346
+ /** console.warn passthrough (static convenience) */
347
+ function warn(...args: any[]): typeof thinConsole;
348
+
349
+ /** console.error passthrough (static convenience) */
350
+ function error(...args: any[]): typeof thinConsole;
351
+
352
+ /** Register a plugin (class or function) */
353
+ function addPlugin(name: string, plugin: typeof Plugin | ((tC: Sandbox) => void)): typeof thinConsole;
354
+
355
+ /** Add custom tabs */
356
+ function addTabs(tabs: TabConfig | TabConfig[]): typeof thinConsole;
269
357
  }
270
358
 
359
+ /** The Plugin base class, also available as window.tCPlugin */
360
+ declare const tCPlugin: typeof thinConsole.Plugin;
361
+
362
+ /** Main constructor: create or reuse the singleton */
363
+ declare function thinConsole(options?: thinConsole.Options): thinConsole.ThinConsole;
364
+
271
365
  export = thinConsole;
272
- export as namespace thinConsole;