@logtape/logtape 0.1.0-dev.15 → 0.1.0-dev.17
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 +71 -61
- package/esm/config.js +35 -1
- package/esm/filesink.node.js +32 -0
- package/esm/filesink.web.js +12 -0
- package/esm/mod.js +4 -2
- package/esm/sink.js +7 -3
- package/package.json +1 -1
- package/script/config.js +60 -2
- package/script/filesink.node.js +62 -0
- package/script/filesink.web.js +15 -0
- package/script/mod.js +5 -2
- package/script/sink.js +7 -3
- package/types/config.d.ts +7 -0
- package/types/config.d.ts.map +1 -1
- package/types/filesink.node.d.ts +18 -0
- package/types/filesink.node.d.ts.map +1 -0
- package/types/filesink.test.d.ts.map +1 -0
- package/types/filesink.web.d.ts +6 -0
- package/types/filesink.web.d.ts.map +1 -0
- package/types/mod.d.ts +3 -2
- package/types/mod.d.ts.map +1 -1
- package/types/sink.d.ts +6 -5
- package/types/sink.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -241,103 +241,113 @@ in the API reference for more details.
|
|
|
241
241
|
|
|
242
242
|
### File sink
|
|
243
243
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
a file sink that writes log messages to a file:
|
|
244
|
+
> [!NOTE]
|
|
245
|
+
> File sink is unavailable in the browser environment.
|
|
247
246
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
import { type FileSinkDriver, getFileSink } from "@logtape/logtape";
|
|
247
|
+
LogTape provides a file sink as well. Here's an example of a file sink that
|
|
248
|
+
writes log messages to a file:
|
|
251
249
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return Deno.openSync(path, { create: true, append: true });
|
|
255
|
-
},
|
|
256
|
-
writeSync(fd, chunk) {
|
|
257
|
-
fd.writeSync(chunk);
|
|
258
|
-
},
|
|
259
|
-
flushSync(fd) {
|
|
260
|
-
fd.syncSync();
|
|
261
|
-
},
|
|
262
|
-
closeSync(fd) {
|
|
263
|
-
fd.close();
|
|
264
|
-
},
|
|
265
|
-
};
|
|
250
|
+
~~~~ typescript
|
|
251
|
+
import { getFileSink } from "@logtape/logtape";
|
|
266
252
|
|
|
267
253
|
configure({
|
|
268
254
|
sinks: {
|
|
269
|
-
file: getFileSink("my-app.log"
|
|
255
|
+
file: getFileSink("my-app.log"),
|
|
270
256
|
},
|
|
271
257
|
// Omitted for brevity
|
|
272
258
|
});
|
|
273
259
|
~~~~
|
|
274
260
|
|
|
261
|
+
See also [`getFileSink()`] function and [`FileSinkOptions`] interface
|
|
262
|
+
in the API reference for more details.
|
|
263
|
+
|
|
264
|
+
[`getFileSink()`]: https://jsr.io/@logtape/logtape/doc/~/getFileSink
|
|
265
|
+
[`FileSinkOptions`]: https://jsr.io/@logtape/logtape/doc/~/FileSinkOptions
|
|
266
|
+
|
|
267
|
+
### Text formatter
|
|
268
|
+
|
|
269
|
+
A stream sink and a file sink write log messages in a plain text format.
|
|
270
|
+
You can customize the format by providing a text formatter. The type of a
|
|
271
|
+
text formatter is:
|
|
272
|
+
|
|
275
273
|
~~~~ typescript
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
import { type FileSinkDriver, getFileSink } from "@logtape/logtape";
|
|
274
|
+
export type TextFormatter = (record: LogRecord) => string;
|
|
275
|
+
~~~~
|
|
279
276
|
|
|
280
|
-
|
|
281
|
-
openSync(path: string) {
|
|
282
|
-
return fs.openSync(path, "a");
|
|
283
|
-
},
|
|
284
|
-
writeSync: fs.writeSync,
|
|
285
|
-
flushSync: fs.fsyncSync,
|
|
286
|
-
closeSync: fs.closeSync,
|
|
287
|
-
};
|
|
277
|
+
Here's an example of a text formatter that writes log messages in a JSON format:
|
|
288
278
|
|
|
279
|
+
~~~~ typescript
|
|
289
280
|
configure({
|
|
290
281
|
sinks: {
|
|
291
|
-
|
|
282
|
+
stream: getStreamSink(Deno.stderr.writable, {
|
|
283
|
+
formatter: JSON.stringify,
|
|
284
|
+
}),
|
|
292
285
|
},
|
|
293
286
|
// Omitted for brevity
|
|
294
|
-
})
|
|
287
|
+
})
|
|
295
288
|
~~~~
|
|
296
289
|
|
|
297
|
-
|
|
298
|
-
[`FileSinkDriver`] interface in the API reference for more details.
|
|
290
|
+
### Disposable sink
|
|
299
291
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
292
|
+
A disposable sink is a sink that can be disposed of. They are automatically
|
|
293
|
+
disposed of when the configuration is reset or the program exits. The type
|
|
294
|
+
of a disposable sink is: `Sink & Disposable`. You can create a disposable
|
|
295
|
+
sink by defining a `[Symbol.dispose]` method:
|
|
303
296
|
|
|
304
|
-
|
|
297
|
+
~~~~ typescript
|
|
298
|
+
const disposableSink: Sink & Disposable = (record: LogRecord) => {
|
|
299
|
+
console.log(record.message);
|
|
300
|
+
};
|
|
301
|
+
disposableSink[Symbol.dispose] = () => {
|
|
302
|
+
console.log("Disposed!");
|
|
303
|
+
};
|
|
304
|
+
~~~~
|
|
305
305
|
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
|
|
307
|
+
Testing
|
|
308
|
+
-------
|
|
309
|
+
|
|
310
|
+
Here are some tips for testing your application or library with LogTape.
|
|
311
|
+
|
|
312
|
+
### Reset configuration
|
|
313
|
+
|
|
314
|
+
You can reset the configuration of LogTape to its initial state. This is
|
|
315
|
+
useful when you want to reset the configuration between tests. For example,
|
|
316
|
+
the following code shows how to reset the configuration after a test
|
|
317
|
+
(regardless of whether the test passes or fails) in Deno:
|
|
308
318
|
|
|
309
319
|
~~~~ typescript
|
|
310
|
-
import {
|
|
320
|
+
import { configure, reset } from "@logtape/logtape";
|
|
311
321
|
|
|
312
|
-
|
|
322
|
+
Deno.test("my test", async (t) => {
|
|
323
|
+
await t.step("set up", () => {
|
|
324
|
+
configure({ /* ... */ });
|
|
325
|
+
});
|
|
313
326
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
327
|
+
await t.step("run test", () => {
|
|
328
|
+
// Run the test
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
await t.step("tear down", () => {
|
|
332
|
+
reset();
|
|
333
|
+
});
|
|
319
334
|
});
|
|
320
335
|
~~~~
|
|
321
336
|
|
|
322
|
-
###
|
|
337
|
+
### Buffer sink
|
|
323
338
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
text formatter is:
|
|
339
|
+
For testing purposes, you may want to collect log messages in memory. Although
|
|
340
|
+
LogTape does not provide a built-in buffer sink, you can easily implement it:
|
|
327
341
|
|
|
328
342
|
~~~~ typescript
|
|
329
|
-
|
|
330
|
-
~~~~
|
|
343
|
+
import { type LogRecord, configure } from "@logtape/logtape";
|
|
331
344
|
|
|
332
|
-
|
|
345
|
+
const buffer: LogRecord[] = [];
|
|
333
346
|
|
|
334
|
-
~~~~ typescript
|
|
335
347
|
configure({
|
|
336
348
|
sinks: {
|
|
337
|
-
|
|
338
|
-
formatter: JSON.stringify,
|
|
339
|
-
}),
|
|
349
|
+
buffer: buffer.push.bind(buffer),
|
|
340
350
|
},
|
|
341
351
|
// Omitted for brevity
|
|
342
|
-
})
|
|
352
|
+
});
|
|
343
353
|
~~~~
|
package/esm/config.js
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
import * as dntShim from "./_dnt.shims.js";
|
|
1
2
|
import { toFilter } from "./filter.js";
|
|
2
3
|
import { LoggerImpl } from "./logger.js";
|
|
3
4
|
import { getConsoleSink } from "./sink.js";
|
|
5
|
+
/**
|
|
6
|
+
* Whether the loggers are configured.
|
|
7
|
+
*/
|
|
4
8
|
let configured = false;
|
|
9
|
+
/**
|
|
10
|
+
* Disposables to dispose when resetting the configuration.
|
|
11
|
+
*/
|
|
12
|
+
const disposables = new Set();
|
|
5
13
|
/**
|
|
6
14
|
* Configure the loggers with the specified configuration.
|
|
7
15
|
*
|
|
16
|
+
* Note that if the given sinks or filters are disposable, they will be
|
|
17
|
+
* disposed when the configuration is reset, or when the process exits.
|
|
18
|
+
*
|
|
8
19
|
* @example
|
|
9
20
|
* ```typescript
|
|
10
21
|
* configure({
|
|
@@ -42,8 +53,8 @@ export function configure(config) {
|
|
|
42
53
|
if (configured && !config.reset) {
|
|
43
54
|
throw new ConfigError("Already configured; if you want to reset, turn on the reset flag.");
|
|
44
55
|
}
|
|
56
|
+
reset();
|
|
45
57
|
configured = true;
|
|
46
|
-
LoggerImpl.getLogger([]).resetDescendants();
|
|
47
58
|
let metaConfigured = false;
|
|
48
59
|
for (const cfg of config.loggers) {
|
|
49
60
|
if (cfg.category.length === 0 ||
|
|
@@ -73,6 +84,20 @@ export function configure(config) {
|
|
|
73
84
|
logger.filters.push(toFilter(filter));
|
|
74
85
|
}
|
|
75
86
|
}
|
|
87
|
+
for (const sink of Object.values(config.sinks)) {
|
|
88
|
+
if (Symbol.dispose in sink)
|
|
89
|
+
disposables.add(sink);
|
|
90
|
+
}
|
|
91
|
+
for (const filter of Object.values(config.filters)) {
|
|
92
|
+
if (filter != null && typeof filter !== "string" && Symbol.dispose in filter)
|
|
93
|
+
disposables.add(filter);
|
|
94
|
+
}
|
|
95
|
+
if ("process" in dntShim.dntGlobalThis) { // @ts-ignore: It's fine to use process in Node
|
|
96
|
+
process.on("exit", dispose);
|
|
97
|
+
}
|
|
98
|
+
else { // @ts-ignore: It's fine to addEventListener() on the browser/Deno
|
|
99
|
+
addEventListener("unload", dispose);
|
|
100
|
+
}
|
|
76
101
|
const meta = LoggerImpl.getLogger(["logtape", "meta"]);
|
|
77
102
|
if (!metaConfigured) {
|
|
78
103
|
meta.sinks.push(getConsoleSink());
|
|
@@ -90,9 +115,18 @@ export function configure(config) {
|
|
|
90
115
|
* Reset the configuration. Mostly for testing purposes.
|
|
91
116
|
*/
|
|
92
117
|
export function reset() {
|
|
118
|
+
dispose();
|
|
93
119
|
LoggerImpl.getLogger([]).resetDescendants();
|
|
94
120
|
configured = false;
|
|
95
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Dispose of the disposables.
|
|
124
|
+
*/
|
|
125
|
+
export function dispose() {
|
|
126
|
+
for (const disposable of disposables)
|
|
127
|
+
disposable[Symbol.dispose]();
|
|
128
|
+
disposables.clear();
|
|
129
|
+
}
|
|
96
130
|
/**
|
|
97
131
|
* A configuration error.
|
|
98
132
|
*/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as dntShim from "./_dnt.shims.js";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { webDriver } from "./filesink.web.js";
|
|
4
|
+
import { getFileSink as getBaseFileSink, } from "./sink.js";
|
|
5
|
+
/**
|
|
6
|
+
* A Node.js-specific file sink driver.
|
|
7
|
+
*/
|
|
8
|
+
export const nodeDriver = {
|
|
9
|
+
openSync(path) {
|
|
10
|
+
return fs.openSync(path, "a");
|
|
11
|
+
},
|
|
12
|
+
writeSync: fs.writeSync,
|
|
13
|
+
flushSync: fs.fsyncSync,
|
|
14
|
+
closeSync: fs.closeSync,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Get a file sink.
|
|
18
|
+
*
|
|
19
|
+
* Note that this function is unavailable in the browser.
|
|
20
|
+
*
|
|
21
|
+
* @param path A path to the file to write to.
|
|
22
|
+
* @param options The options for the sink.
|
|
23
|
+
* @returns A sink that writes to the file. The sink is also a disposable
|
|
24
|
+
* object that closes the file when disposed.
|
|
25
|
+
*/
|
|
26
|
+
export function getFileSink(path, options = {}) {
|
|
27
|
+
if ("document" in dntShim.dntGlobalThis) {
|
|
28
|
+
return getBaseFileSink(path, { ...options, ...webDriver });
|
|
29
|
+
}
|
|
30
|
+
return getBaseFileSink(path, { ...options, ...nodeDriver });
|
|
31
|
+
}
|
|
32
|
+
// cSpell: ignore filesink
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function notImplemented() {
|
|
2
|
+
throw new Error("File sink is not available in the browser.");
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* A browser-specific file sink driver. All methods throw an error.
|
|
6
|
+
*/
|
|
7
|
+
export const webDriver = {
|
|
8
|
+
openSync: notImplemented,
|
|
9
|
+
writeSync: notImplemented,
|
|
10
|
+
flushSync: notImplemented,
|
|
11
|
+
closeSync: notImplemented,
|
|
12
|
+
};
|
package/esm/mod.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { ConfigError, configure, } from "./config.js";
|
|
1
|
+
export { ConfigError, configure, reset, } from "./config.js";
|
|
2
|
+
export { getFileSink } from "./filesink.node.js";
|
|
2
3
|
export { getLevelFilter, toFilter, } from "./filter.js";
|
|
3
4
|
export { defaultConsoleFormatter, defaultTextFormatter, } from "./formatter.js";
|
|
4
5
|
export { getLogger } from "./logger.js";
|
|
5
|
-
export { getConsoleSink,
|
|
6
|
+
export { getConsoleSink, getStreamSink, } from "./sink.js";
|
|
7
|
+
// cSpell: ignore filesink
|
package/esm/sink.js
CHANGED
|
@@ -27,10 +27,12 @@ export function getStreamSink(stream, options = {}) {
|
|
|
27
27
|
const formatter = options.formatter ?? defaultTextFormatter;
|
|
28
28
|
const encoder = options.encoder ?? new TextEncoder();
|
|
29
29
|
const writer = stream.getWriter();
|
|
30
|
-
|
|
30
|
+
const sink = (record) => {
|
|
31
31
|
const bytes = encoder.encode(formatter(record));
|
|
32
32
|
writer.ready.then(() => writer.write(bytes));
|
|
33
33
|
};
|
|
34
|
+
sink[Symbol.dispose] = () => writer.close();
|
|
35
|
+
return sink;
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
38
|
* A console sink factory that returns a sink that logs to the console.
|
|
@@ -58,10 +60,12 @@ export function getConsoleSink(options = {}) {
|
|
|
58
60
|
}
|
|
59
61
|
/**
|
|
60
62
|
* Get a platform-independent file sink.
|
|
63
|
+
*
|
|
61
64
|
* @typeParam TFile The type of the file descriptor.
|
|
62
65
|
* @param path A path to the file to write to.
|
|
63
66
|
* @param options The options for the sink and the file driver.
|
|
64
|
-
* @returns A sink that writes to the file.
|
|
67
|
+
* @returns A sink that writes to the file. The sink is also a disposable
|
|
68
|
+
* object that closes the file when disposed.
|
|
65
69
|
*/
|
|
66
70
|
export function getFileSink(path, options) {
|
|
67
71
|
const formatter = options.formatter ?? defaultTextFormatter;
|
|
@@ -71,6 +75,6 @@ export function getFileSink(path, options) {
|
|
|
71
75
|
options.writeSync(fd, encoder.encode(formatter(record)));
|
|
72
76
|
options.flushSync(fd);
|
|
73
77
|
};
|
|
74
|
-
sink.
|
|
78
|
+
sink[Symbol.dispose] = () => options.closeSync(fd);
|
|
75
79
|
return sink;
|
|
76
80
|
}
|
package/package.json
CHANGED
package/script/config.js
CHANGED
|
@@ -1,13 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ConfigError = exports.reset = exports.configure = void 0;
|
|
26
|
+
exports.ConfigError = exports.dispose = exports.reset = exports.configure = void 0;
|
|
27
|
+
const dntShim = __importStar(require("./_dnt.shims.js"));
|
|
4
28
|
const filter_js_1 = require("./filter.js");
|
|
5
29
|
const logger_js_1 = require("./logger.js");
|
|
6
30
|
const sink_js_1 = require("./sink.js");
|
|
31
|
+
/**
|
|
32
|
+
* Whether the loggers are configured.
|
|
33
|
+
*/
|
|
7
34
|
let configured = false;
|
|
35
|
+
/**
|
|
36
|
+
* Disposables to dispose when resetting the configuration.
|
|
37
|
+
*/
|
|
38
|
+
const disposables = new Set();
|
|
8
39
|
/**
|
|
9
40
|
* Configure the loggers with the specified configuration.
|
|
10
41
|
*
|
|
42
|
+
* Note that if the given sinks or filters are disposable, they will be
|
|
43
|
+
* disposed when the configuration is reset, or when the process exits.
|
|
44
|
+
*
|
|
11
45
|
* @example
|
|
12
46
|
* ```typescript
|
|
13
47
|
* configure({
|
|
@@ -45,8 +79,8 @@ function configure(config) {
|
|
|
45
79
|
if (configured && !config.reset) {
|
|
46
80
|
throw new ConfigError("Already configured; if you want to reset, turn on the reset flag.");
|
|
47
81
|
}
|
|
82
|
+
reset();
|
|
48
83
|
configured = true;
|
|
49
|
-
logger_js_1.LoggerImpl.getLogger([]).resetDescendants();
|
|
50
84
|
let metaConfigured = false;
|
|
51
85
|
for (const cfg of config.loggers) {
|
|
52
86
|
if (cfg.category.length === 0 ||
|
|
@@ -76,6 +110,20 @@ function configure(config) {
|
|
|
76
110
|
logger.filters.push((0, filter_js_1.toFilter)(filter));
|
|
77
111
|
}
|
|
78
112
|
}
|
|
113
|
+
for (const sink of Object.values(config.sinks)) {
|
|
114
|
+
if (Symbol.dispose in sink)
|
|
115
|
+
disposables.add(sink);
|
|
116
|
+
}
|
|
117
|
+
for (const filter of Object.values(config.filters)) {
|
|
118
|
+
if (filter != null && typeof filter !== "string" && Symbol.dispose in filter)
|
|
119
|
+
disposables.add(filter);
|
|
120
|
+
}
|
|
121
|
+
if ("process" in dntShim.dntGlobalThis) { // @ts-ignore: It's fine to use process in Node
|
|
122
|
+
process.on("exit", dispose);
|
|
123
|
+
}
|
|
124
|
+
else { // @ts-ignore: It's fine to addEventListener() on the browser/Deno
|
|
125
|
+
addEventListener("unload", dispose);
|
|
126
|
+
}
|
|
79
127
|
const meta = logger_js_1.LoggerImpl.getLogger(["logtape", "meta"]);
|
|
80
128
|
if (!metaConfigured) {
|
|
81
129
|
meta.sinks.push((0, sink_js_1.getConsoleSink)());
|
|
@@ -94,10 +142,20 @@ exports.configure = configure;
|
|
|
94
142
|
* Reset the configuration. Mostly for testing purposes.
|
|
95
143
|
*/
|
|
96
144
|
function reset() {
|
|
145
|
+
dispose();
|
|
97
146
|
logger_js_1.LoggerImpl.getLogger([]).resetDescendants();
|
|
98
147
|
configured = false;
|
|
99
148
|
}
|
|
100
149
|
exports.reset = reset;
|
|
150
|
+
/**
|
|
151
|
+
* Dispose of the disposables.
|
|
152
|
+
*/
|
|
153
|
+
function dispose() {
|
|
154
|
+
for (const disposable of disposables)
|
|
155
|
+
disposable[Symbol.dispose]();
|
|
156
|
+
disposables.clear();
|
|
157
|
+
}
|
|
158
|
+
exports.dispose = dispose;
|
|
101
159
|
/**
|
|
102
160
|
* A configuration error.
|
|
103
161
|
*/
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.getFileSink = exports.nodeDriver = void 0;
|
|
30
|
+
const dntShim = __importStar(require("./_dnt.shims.js"));
|
|
31
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
32
|
+
const filesink_web_js_1 = require("./filesink.web.js");
|
|
33
|
+
const sink_js_1 = require("./sink.js");
|
|
34
|
+
/**
|
|
35
|
+
* A Node.js-specific file sink driver.
|
|
36
|
+
*/
|
|
37
|
+
exports.nodeDriver = {
|
|
38
|
+
openSync(path) {
|
|
39
|
+
return node_fs_1.default.openSync(path, "a");
|
|
40
|
+
},
|
|
41
|
+
writeSync: node_fs_1.default.writeSync,
|
|
42
|
+
flushSync: node_fs_1.default.fsyncSync,
|
|
43
|
+
closeSync: node_fs_1.default.closeSync,
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Get a file sink.
|
|
47
|
+
*
|
|
48
|
+
* Note that this function is unavailable in the browser.
|
|
49
|
+
*
|
|
50
|
+
* @param path A path to the file to write to.
|
|
51
|
+
* @param options The options for the sink.
|
|
52
|
+
* @returns A sink that writes to the file. The sink is also a disposable
|
|
53
|
+
* object that closes the file when disposed.
|
|
54
|
+
*/
|
|
55
|
+
function getFileSink(path, options = {}) {
|
|
56
|
+
if ("document" in dntShim.dntGlobalThis) {
|
|
57
|
+
return (0, sink_js_1.getFileSink)(path, { ...options, ...filesink_web_js_1.webDriver });
|
|
58
|
+
}
|
|
59
|
+
return (0, sink_js_1.getFileSink)(path, { ...options, ...exports.nodeDriver });
|
|
60
|
+
}
|
|
61
|
+
exports.getFileSink = getFileSink;
|
|
62
|
+
// cSpell: ignore filesink
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.webDriver = void 0;
|
|
4
|
+
function notImplemented() {
|
|
5
|
+
throw new Error("File sink is not available in the browser.");
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A browser-specific file sink driver. All methods throw an error.
|
|
9
|
+
*/
|
|
10
|
+
exports.webDriver = {
|
|
11
|
+
openSync: notImplemented,
|
|
12
|
+
writeSync: notImplemented,
|
|
13
|
+
flushSync: notImplemented,
|
|
14
|
+
closeSync: notImplemented,
|
|
15
|
+
};
|
package/script/mod.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getStreamSink = exports.
|
|
3
|
+
exports.getStreamSink = exports.getConsoleSink = exports.getLogger = exports.defaultTextFormatter = exports.defaultConsoleFormatter = exports.toFilter = exports.getLevelFilter = exports.getFileSink = exports.reset = exports.configure = exports.ConfigError = void 0;
|
|
4
4
|
var config_js_1 = require("./config.js");
|
|
5
5
|
Object.defineProperty(exports, "ConfigError", { enumerable: true, get: function () { return config_js_1.ConfigError; } });
|
|
6
6
|
Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return config_js_1.configure; } });
|
|
7
|
+
Object.defineProperty(exports, "reset", { enumerable: true, get: function () { return config_js_1.reset; } });
|
|
8
|
+
var filesink_node_js_1 = require("./filesink.node.js");
|
|
9
|
+
Object.defineProperty(exports, "getFileSink", { enumerable: true, get: function () { return filesink_node_js_1.getFileSink; } });
|
|
7
10
|
var filter_js_1 = require("./filter.js");
|
|
8
11
|
Object.defineProperty(exports, "getLevelFilter", { enumerable: true, get: function () { return filter_js_1.getLevelFilter; } });
|
|
9
12
|
Object.defineProperty(exports, "toFilter", { enumerable: true, get: function () { return filter_js_1.toFilter; } });
|
|
@@ -14,5 +17,5 @@ var logger_js_1 = require("./logger.js");
|
|
|
14
17
|
Object.defineProperty(exports, "getLogger", { enumerable: true, get: function () { return logger_js_1.getLogger; } });
|
|
15
18
|
var sink_js_1 = require("./sink.js");
|
|
16
19
|
Object.defineProperty(exports, "getConsoleSink", { enumerable: true, get: function () { return sink_js_1.getConsoleSink; } });
|
|
17
|
-
Object.defineProperty(exports, "getFileSink", { enumerable: true, get: function () { return sink_js_1.getFileSink; } });
|
|
18
20
|
Object.defineProperty(exports, "getStreamSink", { enumerable: true, get: function () { return sink_js_1.getStreamSink; } });
|
|
21
|
+
// cSpell: ignore filesink
|
package/script/sink.js
CHANGED
|
@@ -30,10 +30,12 @@ function getStreamSink(stream, options = {}) {
|
|
|
30
30
|
const formatter = options.formatter ?? formatter_js_1.defaultTextFormatter;
|
|
31
31
|
const encoder = options.encoder ?? new TextEncoder();
|
|
32
32
|
const writer = stream.getWriter();
|
|
33
|
-
|
|
33
|
+
const sink = (record) => {
|
|
34
34
|
const bytes = encoder.encode(formatter(record));
|
|
35
35
|
writer.ready.then(() => writer.write(bytes));
|
|
36
36
|
};
|
|
37
|
+
sink[Symbol.dispose] = () => writer.close();
|
|
38
|
+
return sink;
|
|
37
39
|
}
|
|
38
40
|
exports.getStreamSink = getStreamSink;
|
|
39
41
|
/**
|
|
@@ -63,10 +65,12 @@ function getConsoleSink(options = {}) {
|
|
|
63
65
|
exports.getConsoleSink = getConsoleSink;
|
|
64
66
|
/**
|
|
65
67
|
* Get a platform-independent file sink.
|
|
68
|
+
*
|
|
66
69
|
* @typeParam TFile The type of the file descriptor.
|
|
67
70
|
* @param path A path to the file to write to.
|
|
68
71
|
* @param options The options for the sink and the file driver.
|
|
69
|
-
* @returns A sink that writes to the file.
|
|
72
|
+
* @returns A sink that writes to the file. The sink is also a disposable
|
|
73
|
+
* object that closes the file when disposed.
|
|
70
74
|
*/
|
|
71
75
|
function getFileSink(path, options) {
|
|
72
76
|
const formatter = options.formatter ?? formatter_js_1.defaultTextFormatter;
|
|
@@ -76,7 +80,7 @@ function getFileSink(path, options) {
|
|
|
76
80
|
options.writeSync(fd, encoder.encode(formatter(record)));
|
|
77
81
|
options.flushSync(fd);
|
|
78
82
|
};
|
|
79
|
-
sink.
|
|
83
|
+
sink[Symbol.dispose] = () => options.closeSync(fd);
|
|
80
84
|
return sink;
|
|
81
85
|
}
|
|
82
86
|
exports.getFileSink = getFileSink;
|
package/types/config.d.ts
CHANGED
|
@@ -50,6 +50,9 @@ export interface LoggerConfig<TSinkId extends string, TFilterId extends string>
|
|
|
50
50
|
/**
|
|
51
51
|
* Configure the loggers with the specified configuration.
|
|
52
52
|
*
|
|
53
|
+
* Note that if the given sinks or filters are disposable, they will be
|
|
54
|
+
* disposed when the configuration is reset, or when the process exits.
|
|
55
|
+
*
|
|
53
56
|
* @example
|
|
54
57
|
* ```typescript
|
|
55
58
|
* configure({
|
|
@@ -88,6 +91,10 @@ export declare function configure<TSinkId extends string, TFilterId extends stri
|
|
|
88
91
|
* Reset the configuration. Mostly for testing purposes.
|
|
89
92
|
*/
|
|
90
93
|
export declare function reset(): void;
|
|
94
|
+
/**
|
|
95
|
+
* Dispose of the disposables.
|
|
96
|
+
*/
|
|
97
|
+
export declare function dispose(): void;
|
|
91
98
|
/**
|
|
92
99
|
* A configuration error.
|
|
93
100
|
*/
|
package/types/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAY,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAkB,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,OAAO,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM;IACtE;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC7B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEvC;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;IAE5C;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAC3B,OAAO,SAAS,MAAM,EACtB,SAAS,SAAS,MAAM;IAExB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE5B;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IAEtB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;CACzB;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,SAAS,CAAC,OAAO,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EACxE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,QA0EnC;AAED;;GAEG;AACH,wBAAgB,KAAK,SAIpB;AAED;;GAEG;AACH,wBAAgB,OAAO,SAGtB;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC;;;OAGG;gBACS,OAAO,EAAE,MAAM;CAI5B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type FileSinkDriver, type FileSinkOptions, type Sink } from "./sink.js";
|
|
3
|
+
/**
|
|
4
|
+
* A Node.js-specific file sink driver.
|
|
5
|
+
*/
|
|
6
|
+
export declare const nodeDriver: FileSinkDriver<number>;
|
|
7
|
+
/**
|
|
8
|
+
* Get a file sink.
|
|
9
|
+
*
|
|
10
|
+
* Note that this function is unavailable in the browser.
|
|
11
|
+
*
|
|
12
|
+
* @param path A path to the file to write to.
|
|
13
|
+
* @param options The options for the sink.
|
|
14
|
+
* @returns A sink that writes to the file. The sink is also a disposable
|
|
15
|
+
* object that closes the file when disposed.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFileSink(path: string, options?: FileSinkOptions): Sink & Disposable;
|
|
18
|
+
//# sourceMappingURL=filesink.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesink.node.d.ts","sourceRoot":"","sources":["../src/filesink.node.ts"],"names":[],"mappings":";AAGA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,KAAK,IAAI,EACV,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,cAAc,CAAC,MAAM,CAO7C,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAoB,GAC5B,IAAI,GAAG,UAAU,CAKnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesink.test.d.ts","sourceRoot":"","sources":["../src/filesink.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesink.web.d.ts","sourceRoot":"","sources":["../src/filesink.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAMhD;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,cAAc,CAAC,IAAI,CAK1C,CAAC"}
|
package/types/mod.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { type Config, ConfigError, configure, type LoggerConfig, } from "./config.js";
|
|
1
|
+
export { type Config, ConfigError, configure, type LoggerConfig, reset, } from "./config.js";
|
|
2
|
+
export { getFileSink } from "./filesink.node.js";
|
|
2
3
|
export { type Filter, type FilterLike, getLevelFilter, toFilter, } from "./filter.js";
|
|
3
4
|
export { type ConsoleFormatter, defaultConsoleFormatter, defaultTextFormatter, type TextFormatter, } from "./formatter.js";
|
|
4
5
|
export { getLogger, type Logger } from "./logger.js";
|
|
5
6
|
export type { LogLevel, LogRecord } from "./record.js";
|
|
6
|
-
export { type ConsoleSinkOptions, type FileSinkDriver, type FileSinkOptions, getConsoleSink,
|
|
7
|
+
export { type ConsoleSinkOptions, type FileSinkDriver, type FileSinkOptions, getConsoleSink, getStreamSink, type Sink, type StreamSinkOptions, } from "./sink.js";
|
|
7
8
|
//# sourceMappingURL=mod.d.ts.map
|
package/types/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,WAAW,EACX,SAAS,EACT,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,WAAW,EACX,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,GACN,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACL,KAAK,MAAM,EACX,KAAK,UAAU,EACf,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,gBAAgB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACrD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,cAAc,EACd,aAAa,EACb,KAAK,IAAI,EACT,KAAK,iBAAiB,GACvB,MAAM,WAAW,CAAC"}
|
package/types/sink.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import * as dntShim from "./_dnt.shims.js";
|
|
4
5
|
import { type ConsoleFormatter, type TextFormatter } from "./formatter.js";
|
|
5
6
|
import type { LogRecord } from "./record.js";
|
|
@@ -52,7 +53,7 @@ export interface StreamSinkOptions {
|
|
|
52
53
|
* @param options The options for the sink.
|
|
53
54
|
* @returns A sink that writes to the stream.
|
|
54
55
|
*/
|
|
55
|
-
export declare function getStreamSink(stream: dntShim.WritableStream, options?: StreamSinkOptions): Sink;
|
|
56
|
+
export declare function getStreamSink(stream: dntShim.WritableStream, options?: StreamSinkOptions): Sink & Disposable;
|
|
56
57
|
/**
|
|
57
58
|
* Options for the {@link getConsoleSink} function.
|
|
58
59
|
*/
|
|
@@ -106,12 +107,12 @@ export interface FileSinkDriver<TFile> {
|
|
|
106
107
|
}
|
|
107
108
|
/**
|
|
108
109
|
* Get a platform-independent file sink.
|
|
110
|
+
*
|
|
109
111
|
* @typeParam TFile The type of the file descriptor.
|
|
110
112
|
* @param path A path to the file to write to.
|
|
111
113
|
* @param options The options for the sink and the file driver.
|
|
112
|
-
* @returns A sink that writes to the file.
|
|
114
|
+
* @returns A sink that writes to the file. The sink is also a disposable
|
|
115
|
+
* object that closes the file when disposed.
|
|
113
116
|
*/
|
|
114
|
-
export declare function getFileSink<TFile>(path: string, options: FileSinkOptions & FileSinkDriver<TFile>): Sink &
|
|
115
|
-
close: () => void;
|
|
116
|
-
};
|
|
117
|
+
export declare function getFileSink<TFile>(path: string, options: FileSinkOptions & FileSinkDriver<TFile>): Sink & Disposable;
|
|
117
118
|
//# sourceMappingURL=sink.d.ts.map
|
package/types/sink.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../src/sink.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../src/sink.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EACL,KAAK,gBAAgB,EAGrB,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B;;OAEG;IACH,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,OAAO,CAAC,cAAc,EAC9B,OAAO,GAAE,iBAAsB,GAC9B,IAAI,GAAG,UAAU,CAUnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAE7B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,kBAAuB,GAAG,IAAI,CAYrE;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,KAAK;IACnC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAE9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAE9C;;;OAGG;IACH,SAAS,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,GAC/C,IAAI,GAAG,UAAU,CAUnB"}
|