@gjsify/console 0.0.4 → 0.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.
- package/README.md +27 -2
- package/lib/esm/index.js +244 -4
- package/lib/types/index.d.ts +90 -0
- package/package.json +13 -22
- package/src/index.spec.ts +542 -2
- package/src/index.ts +222 -3
- package/tsconfig.json +22 -10
- package/tsconfig.tsbuildinfo +1 -0
- package/lib/cjs/index.js +0 -6
- package/test.gjs.mjs +0 -35536
- package/test.gjs.mjs.meta.json +0 -1
- package/test.node.mjs +0 -308
- package/tsconfig.types.json +0 -8
package/README.md
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
# @gjsify/console
|
|
2
2
|
|
|
3
|
-
Node.js console module
|
|
3
|
+
GJS implementation of the Node.js `console` module with stream support.
|
|
4
|
+
|
|
5
|
+
Part of the [gjsify](https://github.com/gjsify/gjsify) project — Node.js and Web APIs for GJS (GNOME JavaScript).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @gjsify/console
|
|
11
|
+
# or
|
|
12
|
+
yarn add @gjsify/console
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Console } from '@gjsify/console';
|
|
19
|
+
|
|
20
|
+
const logger = new Console(process.stdout, process.stderr);
|
|
21
|
+
logger.log('hello');
|
|
22
|
+
logger.error('something went wrong');
|
|
23
|
+
```
|
|
4
24
|
|
|
5
25
|
## Inspirations and credits
|
|
6
|
-
|
|
26
|
+
|
|
27
|
+
- https://github.com/denoland/deno/tree/main/ext/console
|
|
28
|
+
|
|
29
|
+
## License
|
|
30
|
+
|
|
31
|
+
MIT
|
package/lib/esm/index.js
CHANGED
|
@@ -1,6 +1,246 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const _isGJS = typeof print === "function" && typeof printerr === "function";
|
|
2
|
+
function _formatArgs(...args) {
|
|
3
|
+
const fmt = args[0];
|
|
4
|
+
const rest = args.slice(1);
|
|
5
|
+
if (typeof fmt !== "string" || !/%(s|d|i|f|o|O|c)/.test(fmt)) {
|
|
6
|
+
return args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
7
|
+
}
|
|
8
|
+
let i = 0;
|
|
9
|
+
const result = fmt.replace(/%([sdifOoc])/g, (_match, spec) => {
|
|
10
|
+
if (i >= rest.length) return _match;
|
|
11
|
+
const val = rest[i++];
|
|
12
|
+
switch (spec) {
|
|
13
|
+
case "s":
|
|
14
|
+
return String(val);
|
|
15
|
+
case "d":
|
|
16
|
+
case "i":
|
|
17
|
+
return String(parseInt(String(val), 10));
|
|
18
|
+
case "f":
|
|
19
|
+
return String(parseFloat(String(val)));
|
|
20
|
+
case "o":
|
|
21
|
+
case "O":
|
|
22
|
+
return JSON.stringify(val);
|
|
23
|
+
case "c":
|
|
24
|
+
return "";
|
|
25
|
+
// CSS styles — ignore
|
|
26
|
+
default:
|
|
27
|
+
return _match;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const remaining = rest.slice(i);
|
|
31
|
+
if (remaining.length === 0) return result;
|
|
32
|
+
return result + " " + remaining.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
33
|
+
}
|
|
34
|
+
class Console {
|
|
35
|
+
_stdout;
|
|
36
|
+
_stderr;
|
|
37
|
+
_groupDepth = 0;
|
|
38
|
+
_groupIndentation;
|
|
39
|
+
_timers = /* @__PURE__ */ new Map();
|
|
40
|
+
_counters = /* @__PURE__ */ new Map();
|
|
41
|
+
constructor(stdoutOrOptions, stderr) {
|
|
42
|
+
if (stdoutOrOptions && typeof stdoutOrOptions.write === "function") {
|
|
43
|
+
this._stdout = stdoutOrOptions;
|
|
44
|
+
this._stderr = stderr || this._stdout;
|
|
45
|
+
} else if (stdoutOrOptions && typeof stdoutOrOptions === "object") {
|
|
46
|
+
const opts = stdoutOrOptions;
|
|
47
|
+
this._stdout = opts.stdout;
|
|
48
|
+
this._stderr = opts.stderr || opts.stdout;
|
|
49
|
+
}
|
|
50
|
+
this._groupIndentation = 2;
|
|
51
|
+
}
|
|
52
|
+
_write(stream, ...args) {
|
|
53
|
+
const target = stream === "stderr" ? this._stderr || this._stdout : this._stdout;
|
|
54
|
+
if (target) {
|
|
55
|
+
const indent = " ".repeat(this._groupDepth * this._groupIndentation);
|
|
56
|
+
const message = _formatArgs(...args);
|
|
57
|
+
target.write(indent + message + "\n");
|
|
58
|
+
} else if (_isGJS) {
|
|
59
|
+
const indent = " ".repeat(this._groupDepth * this._groupIndentation);
|
|
60
|
+
const message = indent + _formatArgs(...args);
|
|
61
|
+
if (stream === "stderr") {
|
|
62
|
+
printerr(message);
|
|
63
|
+
} else {
|
|
64
|
+
print(message);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
const gc = globalThis.console;
|
|
68
|
+
if (stream === "stderr") {
|
|
69
|
+
gc.error(...args);
|
|
70
|
+
} else {
|
|
71
|
+
gc.log(...args);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
log(...args) {
|
|
76
|
+
this._write("stdout", ...args);
|
|
77
|
+
}
|
|
78
|
+
info(...args) {
|
|
79
|
+
this._write("stdout", ...args);
|
|
80
|
+
}
|
|
81
|
+
debug(...args) {
|
|
82
|
+
this._write("stdout", ...args);
|
|
83
|
+
}
|
|
84
|
+
warn(...args) {
|
|
85
|
+
this._write("stderr", ...args);
|
|
86
|
+
}
|
|
87
|
+
error(...args) {
|
|
88
|
+
this._write("stderr", ...args);
|
|
89
|
+
}
|
|
90
|
+
dir(obj, _options) {
|
|
91
|
+
this._write("stdout", obj);
|
|
92
|
+
}
|
|
93
|
+
dirxml(...args) {
|
|
94
|
+
this.log(...args);
|
|
95
|
+
}
|
|
96
|
+
assert(value, ...args) {
|
|
97
|
+
if (!value) {
|
|
98
|
+
this.error("Assertion failed:", ...args);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
clear() {
|
|
102
|
+
if (this._stdout) {
|
|
103
|
+
this._stdout.write("\x1Bc");
|
|
104
|
+
} else if (_isGJS) {
|
|
105
|
+
print("\x1Bc");
|
|
106
|
+
} else {
|
|
107
|
+
globalThis.console.clear();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
count(label = "default") {
|
|
111
|
+
const count2 = (this._counters.get(label) || 0) + 1;
|
|
112
|
+
this._counters.set(label, count2);
|
|
113
|
+
this.log(`${label}: ${count2}`);
|
|
114
|
+
}
|
|
115
|
+
countReset(label = "default") {
|
|
116
|
+
this._counters.delete(label);
|
|
117
|
+
}
|
|
118
|
+
group(...args) {
|
|
119
|
+
if (args.length > 0) this.log(...args);
|
|
120
|
+
this._groupDepth++;
|
|
121
|
+
}
|
|
122
|
+
groupCollapsed(...args) {
|
|
123
|
+
this.group(...args);
|
|
124
|
+
}
|
|
125
|
+
groupEnd() {
|
|
126
|
+
if (this._groupDepth > 0) this._groupDepth--;
|
|
127
|
+
}
|
|
128
|
+
table(tabularData, _properties) {
|
|
129
|
+
if (this._stdout) {
|
|
130
|
+
this._write("stdout", tabularData);
|
|
131
|
+
} else if (_isGJS) {
|
|
132
|
+
print(JSON.stringify(tabularData, null, 2));
|
|
133
|
+
} else {
|
|
134
|
+
globalThis.console.table(tabularData, _properties);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
time(label = "default") {
|
|
138
|
+
this._timers.set(label, Date.now());
|
|
139
|
+
}
|
|
140
|
+
timeEnd(label = "default") {
|
|
141
|
+
const start = this._timers.get(label);
|
|
142
|
+
if (start !== void 0) {
|
|
143
|
+
this.log(`${label}: ${Date.now() - start}ms`);
|
|
144
|
+
this._timers.delete(label);
|
|
145
|
+
} else {
|
|
146
|
+
this.warn(`Warning: No such label '${label}' for console.timeEnd()`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
timeLog(label = "default", ...args) {
|
|
150
|
+
const start = this._timers.get(label);
|
|
151
|
+
if (start !== void 0) {
|
|
152
|
+
this.log(`${label}: ${Date.now() - start}ms`, ...args);
|
|
153
|
+
} else {
|
|
154
|
+
this.warn(`Warning: No such label '${label}' for console.timeLog()`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
trace(...args) {
|
|
158
|
+
const err = new Error();
|
|
159
|
+
const stack = err.stack?.split("\n").slice(1).join("\n") || "";
|
|
160
|
+
this._write("stderr", "Trace:", ...args, "\n" + stack);
|
|
161
|
+
}
|
|
162
|
+
profile(_label) {
|
|
163
|
+
}
|
|
164
|
+
profileEnd(_label) {
|
|
165
|
+
}
|
|
166
|
+
timeStamp(_label) {
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const _default = new Console();
|
|
170
|
+
const log = (...args) => _default.log(...args);
|
|
171
|
+
const info = (...args) => _default.info(...args);
|
|
172
|
+
const debug = (...args) => _default.debug(...args);
|
|
173
|
+
const warn = (...args) => _default.warn(...args);
|
|
174
|
+
const error = (...args) => _default.error(...args);
|
|
175
|
+
const dir = (obj, options) => _default.dir(obj, options);
|
|
176
|
+
const dirxml = (...args) => _default.dirxml(...args);
|
|
177
|
+
const table = (data, properties) => _default.table(data, properties);
|
|
178
|
+
const clear = () => _default.clear();
|
|
179
|
+
const assert = (value, ...args) => _default.assert(value, ...args);
|
|
180
|
+
const trace = (...args) => _default.trace(...args);
|
|
181
|
+
const time = (label) => _default.time(label);
|
|
182
|
+
const timeEnd = (label) => _default.timeEnd(label);
|
|
183
|
+
const timeLog = (label, ...args) => _default.timeLog(label, ...args);
|
|
184
|
+
const count = (label) => _default.count(label);
|
|
185
|
+
const countReset = (label) => _default.countReset(label);
|
|
186
|
+
const group = (...args) => _default.group(...args);
|
|
187
|
+
const groupCollapsed = (...args) => _default.groupCollapsed(...args);
|
|
188
|
+
const groupEnd = () => _default.groupEnd();
|
|
189
|
+
const profile = (_label) => {
|
|
190
|
+
};
|
|
191
|
+
const profileEnd = (_label) => {
|
|
192
|
+
};
|
|
193
|
+
const timeStamp = (_label) => {
|
|
194
|
+
};
|
|
195
|
+
const consoleModule = {
|
|
196
|
+
Console,
|
|
197
|
+
log,
|
|
198
|
+
info,
|
|
199
|
+
debug,
|
|
200
|
+
warn,
|
|
201
|
+
error,
|
|
202
|
+
dir,
|
|
203
|
+
dirxml,
|
|
204
|
+
table,
|
|
205
|
+
time,
|
|
206
|
+
timeEnd,
|
|
207
|
+
timeLog,
|
|
208
|
+
trace,
|
|
209
|
+
assert,
|
|
210
|
+
clear,
|
|
211
|
+
count,
|
|
212
|
+
countReset,
|
|
213
|
+
group,
|
|
214
|
+
groupCollapsed,
|
|
215
|
+
groupEnd,
|
|
216
|
+
profile,
|
|
217
|
+
profileEnd,
|
|
218
|
+
timeStamp
|
|
219
|
+
};
|
|
220
|
+
var index_default = consoleModule;
|
|
4
221
|
export {
|
|
5
|
-
|
|
222
|
+
Console,
|
|
223
|
+
assert,
|
|
224
|
+
clear,
|
|
225
|
+
count,
|
|
226
|
+
countReset,
|
|
227
|
+
debug,
|
|
228
|
+
index_default as default,
|
|
229
|
+
dir,
|
|
230
|
+
dirxml,
|
|
231
|
+
error,
|
|
232
|
+
group,
|
|
233
|
+
groupCollapsed,
|
|
234
|
+
groupEnd,
|
|
235
|
+
info,
|
|
236
|
+
log,
|
|
237
|
+
profile,
|
|
238
|
+
profileEnd,
|
|
239
|
+
table,
|
|
240
|
+
time,
|
|
241
|
+
timeEnd,
|
|
242
|
+
timeLog,
|
|
243
|
+
timeStamp,
|
|
244
|
+
trace,
|
|
245
|
+
warn
|
|
6
246
|
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ConsoleOptions } from 'node:console';
|
|
2
|
+
/**
|
|
3
|
+
* The Console class can be used to create a simple logger with configurable output streams.
|
|
4
|
+
* This implementation delegates to the global console for the basic case,
|
|
5
|
+
* and writes to custom streams when provided.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Console {
|
|
8
|
+
private _stdout;
|
|
9
|
+
private _stderr;
|
|
10
|
+
private _groupDepth;
|
|
11
|
+
private _groupIndentation;
|
|
12
|
+
private _timers;
|
|
13
|
+
private _counters;
|
|
14
|
+
constructor(stdoutOrOptions?: {
|
|
15
|
+
write: (data: string) => void;
|
|
16
|
+
} | ConsoleOptions, stderr?: {
|
|
17
|
+
write: (data: string) => void;
|
|
18
|
+
});
|
|
19
|
+
private _write;
|
|
20
|
+
log(...args: unknown[]): void;
|
|
21
|
+
info(...args: unknown[]): void;
|
|
22
|
+
debug(...args: unknown[]): void;
|
|
23
|
+
warn(...args: unknown[]): void;
|
|
24
|
+
error(...args: unknown[]): void;
|
|
25
|
+
dir(obj: unknown, _options?: object): void;
|
|
26
|
+
dirxml(...args: unknown[]): void;
|
|
27
|
+
assert(value: unknown, ...args: unknown[]): void;
|
|
28
|
+
clear(): void;
|
|
29
|
+
count(label?: string): void;
|
|
30
|
+
countReset(label?: string): void;
|
|
31
|
+
group(...args: unknown[]): void;
|
|
32
|
+
groupCollapsed(...args: unknown[]): void;
|
|
33
|
+
groupEnd(): void;
|
|
34
|
+
table(tabularData: unknown, _properties?: string[]): void;
|
|
35
|
+
time(label?: string): void;
|
|
36
|
+
timeEnd(label?: string): void;
|
|
37
|
+
timeLog(label?: string, ...args: unknown[]): void;
|
|
38
|
+
trace(...args: unknown[]): void;
|
|
39
|
+
profile(_label?: string): void;
|
|
40
|
+
profileEnd(_label?: string): void;
|
|
41
|
+
timeStamp(_label?: string): void;
|
|
42
|
+
}
|
|
43
|
+
export declare const log: (...args: unknown[]) => void;
|
|
44
|
+
export declare const info: (...args: unknown[]) => void;
|
|
45
|
+
export declare const debug: (...args: unknown[]) => void;
|
|
46
|
+
export declare const warn: (...args: unknown[]) => void;
|
|
47
|
+
export declare const error: (...args: unknown[]) => void;
|
|
48
|
+
export declare const dir: (obj: unknown, options?: object) => void;
|
|
49
|
+
export declare const dirxml: (...args: unknown[]) => void;
|
|
50
|
+
export declare const table: (data: unknown, properties?: string[]) => void;
|
|
51
|
+
export declare const clear: () => void;
|
|
52
|
+
export declare const assert: (value: unknown, ...args: unknown[]) => void;
|
|
53
|
+
export declare const trace: (...args: unknown[]) => void;
|
|
54
|
+
export declare const time: (label?: string) => void;
|
|
55
|
+
export declare const timeEnd: (label?: string) => void;
|
|
56
|
+
export declare const timeLog: (label?: string, ...args: unknown[]) => void;
|
|
57
|
+
export declare const count: (label?: string) => void;
|
|
58
|
+
export declare const countReset: (label?: string) => void;
|
|
59
|
+
export declare const group: (...args: unknown[]) => void;
|
|
60
|
+
export declare const groupCollapsed: (...args: unknown[]) => void;
|
|
61
|
+
export declare const groupEnd: () => void;
|
|
62
|
+
export declare const profile: (_label?: string) => void;
|
|
63
|
+
export declare const profileEnd: (_label?: string) => void;
|
|
64
|
+
export declare const timeStamp: (_label?: string) => void;
|
|
65
|
+
declare const consoleModule: {
|
|
66
|
+
Console: typeof Console;
|
|
67
|
+
log: (...args: unknown[]) => void;
|
|
68
|
+
info: (...args: unknown[]) => void;
|
|
69
|
+
debug: (...args: unknown[]) => void;
|
|
70
|
+
warn: (...args: unknown[]) => void;
|
|
71
|
+
error: (...args: unknown[]) => void;
|
|
72
|
+
dir: (obj: unknown, options?: object) => void;
|
|
73
|
+
dirxml: (...args: unknown[]) => void;
|
|
74
|
+
table: (data: unknown, properties?: string[]) => void;
|
|
75
|
+
time: (label?: string) => void;
|
|
76
|
+
timeEnd: (label?: string) => void;
|
|
77
|
+
timeLog: (label?: string, ...args: unknown[]) => void;
|
|
78
|
+
trace: (...args: unknown[]) => void;
|
|
79
|
+
assert: (value: unknown, ...args: unknown[]) => void;
|
|
80
|
+
clear: () => void;
|
|
81
|
+
count: (label?: string) => void;
|
|
82
|
+
countReset: (label?: string) => void;
|
|
83
|
+
group: (...args: unknown[]) => void;
|
|
84
|
+
groupCollapsed: (...args: unknown[]) => void;
|
|
85
|
+
groupEnd: () => void;
|
|
86
|
+
profile: (_label?: string) => void;
|
|
87
|
+
profileEnd: (_label?: string) => void;
|
|
88
|
+
timeStamp: (_label?: string) => void;
|
|
89
|
+
};
|
|
90
|
+
export default consoleModule;
|
package/package.json
CHANGED
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/console",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Node.js console module for Gjs",
|
|
5
|
-
"main": "lib/cjs/index.js",
|
|
6
5
|
"module": "lib/esm/index.js",
|
|
6
|
+
"types": "lib/types/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
"default": "./lib/esm/index.js"
|
|
13
|
-
},
|
|
14
|
-
"require": {
|
|
15
|
-
"types": "./lib/types/index.d.ts",
|
|
16
|
-
"default": "./lib/cjs/index.js"
|
|
17
|
-
}
|
|
10
|
+
"types": "./lib/types/index.d.ts",
|
|
11
|
+
"default": "./lib/esm/index.js"
|
|
18
12
|
}
|
|
19
13
|
},
|
|
20
14
|
"scripts": {
|
|
21
|
-
"clear": "rm -rf lib tsconfig.tsbuildinfo tsconfig.types.tsbuildinfo || exit 0",
|
|
22
|
-
"
|
|
23
|
-
"build": "yarn
|
|
15
|
+
"clear": "rm -rf lib tsconfig.tsbuildinfo tsconfig.types.tsbuildinfo test.gjs.mjs test.node.mjs || exit 0",
|
|
16
|
+
"check": "tsc --noEmit",
|
|
17
|
+
"build": "yarn build:gjsify && yarn build:types",
|
|
24
18
|
"build:gjsify": "gjsify build --library 'src/**/*.{ts,js}' --exclude 'src/**/*.spec.{mts,ts}' 'src/test.{mts,ts}'",
|
|
25
|
-
"build:types": "tsc
|
|
19
|
+
"build:types": "tsc",
|
|
26
20
|
"build:test": "yarn build:test:gjs && yarn build:test:node",
|
|
27
21
|
"build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs",
|
|
28
22
|
"build:test:node": "gjsify build src/test.mts --app node --outfile test.node.mjs",
|
|
29
|
-
"test": "yarn
|
|
23
|
+
"test": "yarn build:gjsify && yarn build:test && yarn test:node && yarn test:gjs",
|
|
30
24
|
"test:gjs": "gjs -m test.gjs.mjs",
|
|
31
25
|
"test:node": "node test.node.mjs"
|
|
32
26
|
},
|
|
@@ -36,12 +30,9 @@
|
|
|
36
30
|
"console"
|
|
37
31
|
],
|
|
38
32
|
"devDependencies": {
|
|
39
|
-
"@gjsify/cli": "^0.
|
|
40
|
-
"@gjsify/unit": "^0.
|
|
41
|
-
"@types/node": "^
|
|
42
|
-
"typescript": "^
|
|
43
|
-
},
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"@gjsify/deno_std": "^0.0.4"
|
|
33
|
+
"@gjsify/cli": "^0.1.1",
|
|
34
|
+
"@gjsify/unit": "^0.1.1",
|
|
35
|
+
"@types/node": "^25.5.0",
|
|
36
|
+
"typescript": "^6.0.2"
|
|
46
37
|
}
|
|
47
38
|
}
|