@leftium/gg 0.0.33 → 0.0.34
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 +117 -36
- package/dist/GgConsole.svelte +12 -0
- package/dist/GgConsole.svelte.d.ts +4 -0
- package/dist/debug/browser.d.ts +10 -0
- package/dist/debug/browser.js +102 -0
- package/dist/debug/common.d.ts +41 -0
- package/dist/debug/common.js +191 -0
- package/dist/debug/index.d.ts +9 -0
- package/dist/debug/index.js +11 -0
- package/dist/debug/node.d.ts +10 -0
- package/dist/debug/node.js +137 -0
- package/dist/eruda/loader.js +0 -11
- package/dist/eruda/plugin.js +213 -25
- package/dist/eruda/types.d.ts +0 -5
- package/dist/gg-call-sites-plugin.d.ts +84 -0
- package/dist/gg-call-sites-plugin.js +496 -114
- package/dist/gg.d.ts +7 -0
- package/dist/gg.js +75 -51
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/vite.d.ts +37 -0
- package/dist/vite.js +46 -0
- package/package.json +20 -12
- package/dist/debug-bundled.d.ts +0 -2
- package/dist/debug-bundled.js +0 -3
- package/dist/debug.d.ts +0 -2
- package/dist/debug.js +0 -15
- package/patches/debug@4.4.3.patch +0 -35
package/README.md
CHANGED
|
@@ -18,24 +18,95 @@
|
|
|
18
18
|
npm add @leftium/gg
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## SvelteKit Quick Start
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### 1. Add Vite plugins
|
|
24
24
|
|
|
25
|
-
```
|
|
26
|
-
|
|
25
|
+
```ts
|
|
26
|
+
// vite.config.ts
|
|
27
|
+
import ggPlugins from '@leftium/gg/vite';
|
|
28
|
+
import { sveltekit } from '@sveltejs/kit/vite';
|
|
29
|
+
import { defineConfig } from 'vite';
|
|
30
|
+
|
|
31
|
+
export default defineConfig({
|
|
32
|
+
plugins: [sveltekit(), ...ggPlugins()]
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`ggPlugins()` includes:
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
- **Call-sites plugin** -- rewrites `gg()` calls with source file/line/col metadata
|
|
39
|
+
- **Open-in-editor plugin** -- adds dev server middleware for click-to-open
|
|
40
|
+
- **Automatic `es2022` target** -- required for top-level await
|
|
30
41
|
|
|
31
|
-
|
|
32
|
-
const result = gg(someFunction());
|
|
42
|
+
### 2. Add the debug console
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
```svelte
|
|
45
|
+
<!-- src/routes/+layout.svelte -->
|
|
46
|
+
<script>
|
|
47
|
+
import { GgConsole } from '@leftium/gg';
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<GgConsole />
|
|
51
|
+
{@render children()}
|
|
36
52
|
```
|
|
37
53
|
|
|
38
|
-
###
|
|
54
|
+
### 3. Use `gg()` anywhere
|
|
55
|
+
|
|
56
|
+
```svelte
|
|
57
|
+
<script>
|
|
58
|
+
import { gg } from '@leftium/gg';
|
|
59
|
+
|
|
60
|
+
gg('Hello world');
|
|
61
|
+
|
|
62
|
+
// Log expressions (returns first argument)
|
|
63
|
+
const result = gg(someFunction());
|
|
64
|
+
|
|
65
|
+
// Multiple arguments
|
|
66
|
+
gg('User:', user, 'Status:', status);
|
|
67
|
+
</script>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
That's it! In development, a debug console appears automatically.
|
|
71
|
+
In production, add `?gg` to the URL or use a 5-tap gesture to activate.
|
|
72
|
+
|
|
73
|
+
## GgConsole Options
|
|
74
|
+
|
|
75
|
+
```svelte
|
|
76
|
+
<GgConsole prod={['url-param', 'gesture']} maxEntries={5000} />
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
| Prop | Type | Default | Description |
|
|
80
|
+
| -------------- | -------------------------- | -------------------------- | ------------------------------ |
|
|
81
|
+
| `prod` | `Array \| string \| false` | `['url-param', 'gesture']` | Production activation triggers |
|
|
82
|
+
| `maxEntries` | `number` | `2000` | Max log entries in ring buffer |
|
|
83
|
+
| `erudaOptions` | `object` | `{}` | Pass-through options to Eruda |
|
|
84
|
+
|
|
85
|
+
**Production triggers:**
|
|
86
|
+
|
|
87
|
+
- `'url-param'` -- activate with `?gg` in the URL (persists to localStorage)
|
|
88
|
+
- `'gesture'` -- activate with 5 rapid taps anywhere on the page
|
|
89
|
+
- `'localStorage'` -- activate if `localStorage['gg-enabled']` is `'true'`
|
|
90
|
+
- `false` -- disable debug console in production entirely
|
|
91
|
+
|
|
92
|
+
## Vite Plugin Options
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import ggPlugins from '@leftium/gg/vite';
|
|
96
|
+
|
|
97
|
+
ggPlugins({
|
|
98
|
+
callSites: { srcRootPattern: '.*?(/src/)' },
|
|
99
|
+
openInEditor: false // disable open-in-editor middleware
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Individual plugins are also available for advanced setups:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { ggCallSitesPlugin, openInEditorPlugin } from '@leftium/gg/vite';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Color Support (ANSI)
|
|
39
110
|
|
|
40
111
|
Color your logs for better visual distinction using `fg()` (foreground/text) and `bg()` (background):
|
|
41
112
|
|
|
@@ -77,46 +148,56 @@ gg(fg('rgb(255,99,71)')`Tomato text`);
|
|
|
77
148
|
|
|
78
149
|
**Where colors work:**
|
|
79
150
|
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
151
|
+
- Native browser console (Chrome DevTools, Firefox, etc.)
|
|
152
|
+
- GgConsole debug panel (mobile debugging)
|
|
153
|
+
- Node.js terminal
|
|
154
|
+
- All environments that support ANSI escape codes
|
|
84
155
|
|
|
85
|
-
##
|
|
156
|
+
## Other Frameworks
|
|
86
157
|
|
|
87
|
-
|
|
158
|
+
`gg()` works in any JavaScript project. The Vite plugins work with any Vite-based framework (React, Vue, Solid, etc.).
|
|
88
159
|
|
|
89
|
-
|
|
160
|
+
### Vanilla / Non-Svelte Setup
|
|
90
161
|
|
|
91
|
-
|
|
162
|
+
```ts
|
|
163
|
+
// vite.config.ts
|
|
164
|
+
import ggPlugins from '@leftium/gg/vite';
|
|
92
165
|
|
|
93
|
-
|
|
94
|
-
|
|
166
|
+
export default defineConfig({
|
|
167
|
+
plugins: [...ggPlugins()]
|
|
168
|
+
});
|
|
95
169
|
```
|
|
96
170
|
|
|
97
|
-
|
|
171
|
+
```js
|
|
172
|
+
// app.js
|
|
173
|
+
import { gg } from '@leftium/gg';
|
|
174
|
+
import { initGgEruda } from '@leftium/gg/eruda';
|
|
98
175
|
|
|
176
|
+
initGgEruda();
|
|
177
|
+
gg('works in any framework');
|
|
99
178
|
```
|
|
100
|
-
+123ms gg:routes/+page.svelte
|
|
101
|
-
```
|
|
102
179
|
|
|
103
|
-
|
|
180
|
+
## Technical Details
|
|
181
|
+
|
|
182
|
+
### Internal Debug Implementation
|
|
104
183
|
|
|
105
|
-
|
|
184
|
+
This library includes an **internal TypeScript implementation** inspired by the [`debug`](https://www.npmjs.com/package/debug) package. The output format displays time diffs **before** the namespace for better readability:
|
|
106
185
|
|
|
107
|
-
|
|
186
|
+
**Output format:**
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
+123ms gg:routes/+page.svelte
|
|
190
|
+
```
|
|
108
191
|
|
|
109
|
-
|
|
110
|
-
2. Update patch: `pnpm patch debug@x.x.x` (apply changes, then `pnpm patch-commit`)
|
|
111
|
-
3. Run the update script: `./scripts/update-debug.sh`
|
|
112
|
-
4. Verify patches are present: `git diff src/lib/debug/src/`
|
|
113
|
-
5. Test dev mode: `pnpm dev`
|
|
114
|
-
6. Test production build: `pnpm prepack`
|
|
115
|
-
7. Commit changes: `git commit -am "Update bundled debug to x.x.x"`
|
|
192
|
+
Features implemented internally (~290 lines of TypeScript):
|
|
116
193
|
|
|
117
|
-
|
|
194
|
+
- Color hashing algorithm for consistent namespace colors
|
|
195
|
+
- Millisecond diff formatting (e.g., `+123ms`, `+2s`, `+5m`)
|
|
196
|
+
- Namespace wildcard matching (`gg:*`, `gg:routes/*`, `-gg:test`)
|
|
197
|
+
- localStorage.debug / process.env.DEBUG persistence
|
|
198
|
+
- Browser and Node.js environments
|
|
118
199
|
|
|
119
|
-
|
|
200
|
+
This approach eliminates the need for vendoring, patching, and bundling third-party code, resulting in better type safety and simpler maintenance.
|
|
120
201
|
|
|
121
202
|
## Inspirations
|
|
122
203
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
import type { GgErudaOptions } from './eruda/types.js';
|
|
4
|
+
|
|
5
|
+
let { prod, maxEntries, erudaOptions }: GgErudaOptions = $props();
|
|
6
|
+
|
|
7
|
+
onMount(() => {
|
|
8
|
+
import('./eruda/index.js').then(({ initGgEruda }) => {
|
|
9
|
+
initGgEruda({ prod, maxEntries, erudaOptions });
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
</script>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-specific debug implementation.
|
|
3
|
+
*
|
|
4
|
+
* Output: console.debug with %c CSS color formatting.
|
|
5
|
+
* Persistence: localStorage.debug
|
|
6
|
+
* Format (patched): +123ms namespace message
|
|
7
|
+
*/
|
|
8
|
+
import { type DebugFactory } from './common.js';
|
|
9
|
+
declare const debug: DebugFactory;
|
|
10
|
+
export default debug;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-specific debug implementation.
|
|
3
|
+
*
|
|
4
|
+
* Output: console.debug with %c CSS color formatting.
|
|
5
|
+
* Persistence: localStorage.debug
|
|
6
|
+
* Format (patched): +123ms namespace message
|
|
7
|
+
*/
|
|
8
|
+
import { setup, humanize } from './common.js';
|
|
9
|
+
/**
|
|
10
|
+
* 76 hex colors — identical to debug@4 browser.js for color-hash stability.
|
|
11
|
+
*/
|
|
12
|
+
const colors = [
|
|
13
|
+
'#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF',
|
|
14
|
+
'#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99',
|
|
15
|
+
'#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF',
|
|
16
|
+
'#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33',
|
|
17
|
+
'#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF',
|
|
18
|
+
'#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF',
|
|
19
|
+
'#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033',
|
|
20
|
+
'#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333',
|
|
21
|
+
'#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633',
|
|
22
|
+
'#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033',
|
|
23
|
+
'#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333',
|
|
24
|
+
'#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633',
|
|
25
|
+
'#FF9900', '#FF9933', '#FFCC00', '#FFCC33'
|
|
26
|
+
];
|
|
27
|
+
function useColors() {
|
|
28
|
+
// Modern browsers all support %c — simplified from debug's original checks
|
|
29
|
+
return typeof document !== 'undefined' || typeof navigator !== 'undefined';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Format args with color CSS and gg's patched prefix order:
|
|
33
|
+
* +123ms namespace message
|
|
34
|
+
*/
|
|
35
|
+
function formatArgs(args) {
|
|
36
|
+
const h = humanize(this.diff);
|
|
37
|
+
const prefix = ('+' + h).padStart(6);
|
|
38
|
+
args[0] = (this.useColors ? '%c' : '') +
|
|
39
|
+
`${prefix} ${this.namespace}` +
|
|
40
|
+
(this.useColors ? ' %c' : ' ') +
|
|
41
|
+
args[0] +
|
|
42
|
+
(this.useColors ? '%c ' : ' ');
|
|
43
|
+
if (!this.useColors)
|
|
44
|
+
return;
|
|
45
|
+
const c = 'color: ' + this.color;
|
|
46
|
+
args.splice(1, 0, c, 'color: inherit');
|
|
47
|
+
// Insert CSS for the final %c
|
|
48
|
+
let index = 0;
|
|
49
|
+
let lastC = 0;
|
|
50
|
+
args[0].replace(/%[a-zA-Z%]/g, (match) => {
|
|
51
|
+
if (match === '%%')
|
|
52
|
+
return match;
|
|
53
|
+
index++;
|
|
54
|
+
if (match === '%c')
|
|
55
|
+
lastC = index;
|
|
56
|
+
return match;
|
|
57
|
+
});
|
|
58
|
+
args.splice(lastC, 0, c);
|
|
59
|
+
}
|
|
60
|
+
function save(namespaces) {
|
|
61
|
+
try {
|
|
62
|
+
if (namespaces) {
|
|
63
|
+
localStorage.setItem('debug', namespaces);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
localStorage.removeItem('debug');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// localStorage may not be available
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function load() {
|
|
74
|
+
try {
|
|
75
|
+
return localStorage.getItem('debug') || localStorage.getItem('DEBUG') || '';
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return '';
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const log = console.debug || console.log || (() => { });
|
|
82
|
+
const env = {
|
|
83
|
+
formatArgs,
|
|
84
|
+
save,
|
|
85
|
+
load,
|
|
86
|
+
useColors,
|
|
87
|
+
colors,
|
|
88
|
+
log,
|
|
89
|
+
formatters: {
|
|
90
|
+
/** %j → JSON.stringify (preserved for compatibility) */
|
|
91
|
+
j(v) {
|
|
92
|
+
try {
|
|
93
|
+
return JSON.stringify(v);
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
return '[UnexpectedJSONParseError]: ' + e.message;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const debug = setup(env);
|
|
102
|
+
export default debug;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal debug implementation — replaces the `debug` npm package.
|
|
3
|
+
*
|
|
4
|
+
* Core logic: createDebug factory, enable/disable, namespace matching,
|
|
5
|
+
* color selection, and humanize (ms formatting).
|
|
6
|
+
*/
|
|
7
|
+
/** Format ms like debug's `ms` package: 0ms, 500ms, 5s, 2m, 1h, 3d */
|
|
8
|
+
export declare function humanize(ms: number): string;
|
|
9
|
+
export interface Debugger {
|
|
10
|
+
(...args: unknown[]): void;
|
|
11
|
+
namespace: string;
|
|
12
|
+
color: string;
|
|
13
|
+
diff: number;
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
useColors: boolean;
|
|
16
|
+
formatArgs: (args: unknown[]) => void;
|
|
17
|
+
log: ((...args: unknown[]) => void) | null;
|
|
18
|
+
}
|
|
19
|
+
export interface DebugFactory {
|
|
20
|
+
(namespace: string): Debugger;
|
|
21
|
+
enable: (namespaces: string) => void;
|
|
22
|
+
disable: () => string;
|
|
23
|
+
enabled: (namespace: string) => boolean;
|
|
24
|
+
humanize: typeof humanize;
|
|
25
|
+
names: string[];
|
|
26
|
+
skips: string[];
|
|
27
|
+
namespaces: string;
|
|
28
|
+
formatters: Record<string, (this: Debugger, val: unknown) => string>;
|
|
29
|
+
}
|
|
30
|
+
/** Platform-specific hooks provided by browser.ts or node.ts */
|
|
31
|
+
export interface DebugEnv {
|
|
32
|
+
formatArgs: (this: Debugger, args: unknown[]) => void;
|
|
33
|
+
save: (namespaces: string) => void;
|
|
34
|
+
load: () => string;
|
|
35
|
+
useColors: () => boolean;
|
|
36
|
+
colors: string[] | number[];
|
|
37
|
+
log: (...args: unknown[]) => void;
|
|
38
|
+
formatters?: Record<string, (this: Debugger, val: unknown) => string>;
|
|
39
|
+
init?: (instance: Debugger) => void;
|
|
40
|
+
}
|
|
41
|
+
export declare function setup(env: DebugEnv): DebugFactory;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal debug implementation — replaces the `debug` npm package.
|
|
3
|
+
*
|
|
4
|
+
* Core logic: createDebug factory, enable/disable, namespace matching,
|
|
5
|
+
* color selection, and humanize (ms formatting).
|
|
6
|
+
*/
|
|
7
|
+
/** Format ms like debug's `ms` package: 0ms, 500ms, 5s, 2m, 1h, 3d */
|
|
8
|
+
export function humanize(ms) {
|
|
9
|
+
const abs = Math.abs(ms);
|
|
10
|
+
if (abs >= 86_400_000)
|
|
11
|
+
return Math.round(ms / 86_400_000) + 'd';
|
|
12
|
+
if (abs >= 3_600_000)
|
|
13
|
+
return Math.round(ms / 3_600_000) + 'h';
|
|
14
|
+
if (abs >= 60_000)
|
|
15
|
+
return Math.round(ms / 60_000) + 'm';
|
|
16
|
+
if (abs >= 1_000)
|
|
17
|
+
return Math.round(ms / 1_000) + 's';
|
|
18
|
+
return ms + 'ms';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Wildcard pattern matching (same algorithm as debug's `matchesTemplate`).
|
|
22
|
+
* Supports `*` as a wildcard that matches any sequence of characters.
|
|
23
|
+
*/
|
|
24
|
+
function matchesTemplate(search, template) {
|
|
25
|
+
let si = 0;
|
|
26
|
+
let ti = 0;
|
|
27
|
+
let starIdx = -1;
|
|
28
|
+
let matchIdx = 0;
|
|
29
|
+
while (si < search.length) {
|
|
30
|
+
if (ti < template.length && (template[ti] === search[si] || template[ti] === '*')) {
|
|
31
|
+
if (template[ti] === '*') {
|
|
32
|
+
starIdx = ti;
|
|
33
|
+
matchIdx = si;
|
|
34
|
+
ti++;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
si++;
|
|
38
|
+
ti++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (starIdx !== -1) {
|
|
42
|
+
ti = starIdx + 1;
|
|
43
|
+
matchIdx++;
|
|
44
|
+
si = matchIdx;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
while (ti < template.length && template[ti] === '*') {
|
|
51
|
+
ti++;
|
|
52
|
+
}
|
|
53
|
+
return ti === template.length;
|
|
54
|
+
}
|
|
55
|
+
// ── Factory ────────────────────────────────────────────────────────────
|
|
56
|
+
export function setup(env) {
|
|
57
|
+
/** Deterministic color for a namespace (same hash as debug@4) */
|
|
58
|
+
function selectColor(namespace) {
|
|
59
|
+
let hash = 0;
|
|
60
|
+
for (let i = 0; i < namespace.length; i++) {
|
|
61
|
+
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
|
62
|
+
hash |= 0;
|
|
63
|
+
}
|
|
64
|
+
return env.colors[Math.abs(hash) % env.colors.length];
|
|
65
|
+
}
|
|
66
|
+
// Active include/exclude lists
|
|
67
|
+
let names = [];
|
|
68
|
+
let skips = [];
|
|
69
|
+
let currentNamespaces = '';
|
|
70
|
+
function enable(namespaces) {
|
|
71
|
+
env.save(namespaces);
|
|
72
|
+
currentNamespaces = namespaces;
|
|
73
|
+
names = [];
|
|
74
|
+
skips = [];
|
|
75
|
+
const parts = (typeof namespaces === 'string' ? namespaces : '')
|
|
76
|
+
.trim()
|
|
77
|
+
.replace(/\s+/g, ',')
|
|
78
|
+
.split(',')
|
|
79
|
+
.filter(Boolean);
|
|
80
|
+
for (const part of parts) {
|
|
81
|
+
if (part[0] === '-') {
|
|
82
|
+
skips.push(part.slice(1));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
names.push(part);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Update factory-level arrays for external inspection
|
|
89
|
+
factory.names = names;
|
|
90
|
+
factory.skips = skips;
|
|
91
|
+
factory.namespaces = currentNamespaces;
|
|
92
|
+
}
|
|
93
|
+
function disable() {
|
|
94
|
+
const prev = [
|
|
95
|
+
...names,
|
|
96
|
+
...skips.map((ns) => '-' + ns)
|
|
97
|
+
].join(',');
|
|
98
|
+
enable('');
|
|
99
|
+
return prev;
|
|
100
|
+
}
|
|
101
|
+
function enabled(name) {
|
|
102
|
+
for (const skip of skips) {
|
|
103
|
+
if (matchesTemplate(name, skip))
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
for (const ns of names) {
|
|
107
|
+
if (matchesTemplate(name, ns))
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
// ── createDebug ────────────────────────────────────────────────────
|
|
113
|
+
function createDebug(namespace) {
|
|
114
|
+
let prevTime;
|
|
115
|
+
let enableOverride = null;
|
|
116
|
+
let namespacesCache;
|
|
117
|
+
let enabledCache;
|
|
118
|
+
const debug = function (...args) {
|
|
119
|
+
if (!debug.enabled)
|
|
120
|
+
return;
|
|
121
|
+
const curr = Date.now();
|
|
122
|
+
const ms = curr - (prevTime || curr);
|
|
123
|
+
debug.diff = ms;
|
|
124
|
+
prevTime = curr;
|
|
125
|
+
// Coerce first arg
|
|
126
|
+
if (typeof args[0] !== 'string') {
|
|
127
|
+
args.unshift('%O');
|
|
128
|
+
}
|
|
129
|
+
// Apply %format replacements
|
|
130
|
+
let idx = 0;
|
|
131
|
+
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, fmt) => {
|
|
132
|
+
if (match === '%%')
|
|
133
|
+
return '%';
|
|
134
|
+
idx++;
|
|
135
|
+
const formatter = factory.formatters[fmt];
|
|
136
|
+
if (typeof formatter === 'function') {
|
|
137
|
+
const val = args[idx];
|
|
138
|
+
match = formatter.call(debug, val);
|
|
139
|
+
args.splice(idx, 1);
|
|
140
|
+
idx--;
|
|
141
|
+
}
|
|
142
|
+
return match;
|
|
143
|
+
});
|
|
144
|
+
// Platform-specific formatting (colors, prefix)
|
|
145
|
+
debug.formatArgs(args);
|
|
146
|
+
const logFn = debug.log || env.log;
|
|
147
|
+
logFn.apply(debug, args);
|
|
148
|
+
};
|
|
149
|
+
debug.namespace = namespace;
|
|
150
|
+
debug.useColors = env.useColors();
|
|
151
|
+
debug.color = String(selectColor(namespace));
|
|
152
|
+
debug.diff = 0;
|
|
153
|
+
debug.log = null;
|
|
154
|
+
debug.formatArgs = function (args) {
|
|
155
|
+
env.formatArgs.call(debug, args);
|
|
156
|
+
};
|
|
157
|
+
Object.defineProperty(debug, 'enabled', {
|
|
158
|
+
enumerable: true,
|
|
159
|
+
configurable: false,
|
|
160
|
+
get: () => {
|
|
161
|
+
if (enableOverride !== null)
|
|
162
|
+
return enableOverride;
|
|
163
|
+
if (namespacesCache !== currentNamespaces) {
|
|
164
|
+
namespacesCache = currentNamespaces;
|
|
165
|
+
enabledCache = enabled(namespace);
|
|
166
|
+
}
|
|
167
|
+
return enabledCache;
|
|
168
|
+
},
|
|
169
|
+
set: (v) => {
|
|
170
|
+
enableOverride = v;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
if (env.init) {
|
|
174
|
+
env.init(debug);
|
|
175
|
+
}
|
|
176
|
+
return debug;
|
|
177
|
+
}
|
|
178
|
+
// ── Assemble factory ───────────────────────────────────────────────
|
|
179
|
+
const factory = createDebug;
|
|
180
|
+
factory.enable = enable;
|
|
181
|
+
factory.disable = disable;
|
|
182
|
+
factory.enabled = enabled;
|
|
183
|
+
factory.humanize = humanize;
|
|
184
|
+
factory.names = names;
|
|
185
|
+
factory.skips = skips;
|
|
186
|
+
factory.namespaces = '';
|
|
187
|
+
factory.formatters = { ...env.formatters };
|
|
188
|
+
// Initialize from persisted namespaces
|
|
189
|
+
enable(env.load());
|
|
190
|
+
return factory;
|
|
191
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug entry point — selects browser or node implementation.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the DebugFactory and Debugger types for consumers.
|
|
5
|
+
*/
|
|
6
|
+
import type { DebugFactory } from './common.js';
|
|
7
|
+
export type { DebugFactory, Debugger } from './common.js';
|
|
8
|
+
declare const _default: DebugFactory;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug entry point — selects browser or node implementation.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the DebugFactory and Debugger types for consumers.
|
|
5
|
+
*/
|
|
6
|
+
import { BROWSER } from 'esm-env';
|
|
7
|
+
// Conditional import: browser.ts for browsers, node.ts for Node/Deno/Bun
|
|
8
|
+
const { default: debug } = BROWSER
|
|
9
|
+
? await import('./browser.js')
|
|
10
|
+
: await import('./node.js');
|
|
11
|
+
export default debug;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js-specific debug implementation.
|
|
3
|
+
*
|
|
4
|
+
* Output: process.stderr via util.formatWithOptions.
|
|
5
|
+
* Persistence: process.env.DEBUG
|
|
6
|
+
* Format (patched): +123ms namespace message (ANSI colored)
|
|
7
|
+
*/
|
|
8
|
+
import { type DebugFactory } from './common.js';
|
|
9
|
+
declare const debug: DebugFactory;
|
|
10
|
+
export default debug;
|