@holz/json-backend 0.8.3-rc.168 → 0.8.3-rc.170
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 +8 -47
- package/dist/holz-json-backend.cjs +1 -1
- package/dist/holz-json-backend.d.ts +5 -16
- package/dist/holz-json-backend.js +12 -16
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,66 +1,27 @@
|
|
|
1
1
|
# `@holz/json-backend`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Prints structured logs to a writable stream in NDJSON form.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
|
-
This backend serializes logs into a [`WritableStream<Uint8Array>`](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream). Each chunk is UTF-8 encoded. Ideal for append-only log files.
|
|
8
|
-
|
|
9
|
-
Target environments are servers, host endpoints, and browsers (via [OPFS](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createWritable)).
|
|
10
|
-
|
|
11
7
|
```typescript
|
|
12
8
|
import { createJsonBackend } from '@holz/json-backend';
|
|
13
9
|
import { createLogger } from '@holz/core';
|
|
10
|
+
import { createWriteStream } from 'node:fs';
|
|
14
11
|
|
|
15
12
|
const logger = createLogger(
|
|
16
13
|
createJsonBackend({
|
|
17
|
-
stream:
|
|
18
|
-
{
|
|
19
|
-
// ...
|
|
20
|
-
},
|
|
21
|
-
new CountQueuingStrategy({
|
|
22
|
-
highWaterMark: 1024,
|
|
23
|
-
}),
|
|
24
|
-
),
|
|
14
|
+
stream: createWriteStream('my-logs.ndjson', { flags: 'a' }),
|
|
25
15
|
}),
|
|
26
16
|
);
|
|
27
17
|
```
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Node's streams shipped long before the web standard and need to be wrapped with [Writable.toWeb](https://nodejs.org/api/stream.html#streamwritabletowebstreamwritable):
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
import { createWriteStream } from 'node:fs';
|
|
35
|
-
import { Writable } from 'node:stream';
|
|
36
|
-
|
|
37
|
-
createJsonBackend({
|
|
38
|
-
stream: Writable.toWeb(createWriteStream('logs.ndjson', { flags: 'a' })),
|
|
39
|
-
}),
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
The same adapter works for any Node writable, including `process.stderr`.
|
|
43
|
-
|
|
44
|
-
### Closing the Stream
|
|
45
|
-
|
|
46
|
-
By default, the stream remains open forever. Pass an [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) to control the shutdown.
|
|
19
|
+
Logs are output in [NDJSON](https://github.com/ndjson/ndjson-spec) format. The output is optimized for log files, following the order of typical log statements. The output includes the log level, timestamp, message, and context, if provided.
|
|
47
20
|
|
|
48
|
-
|
|
49
|
-
const controller = new AbortController();
|
|
50
|
-
|
|
51
|
-
createJsonBackend({
|
|
52
|
-
stream: writableStream,
|
|
53
|
-
signal: controller.signal,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Permanently close the writable stream.
|
|
57
|
-
controller.abort();
|
|
58
|
-
```
|
|
21
|
+
The `stream` option specifies where the logs will be written to. You can use any writable stream, such as a file or `process.stdout`.
|
|
59
22
|
|
|
60
|
-
|
|
23
|
+
## Log Rotation
|
|
61
24
|
|
|
62
|
-
|
|
25
|
+
Long-lived processes or noisy services can fill up the disk, given enough time.
|
|
63
26
|
|
|
64
|
-
|
|
65
|
-
- Long-running processes and noisy services create giant files. Lean on your environment's tools (`journalctl`) or use a package like [rotating-file-stream](https://github.com/iccicci/rotating-file-stream).
|
|
66
|
-
- OPFS streams in browser environments have poor durability. You may need synchronous access to periodically flush writes, an API only available in workers.
|
|
27
|
+
Lean on your environment's tools (`journalctl`) or use a package like [rotating-file-stream](https://github.com/iccicci/rotating-file-stream) to prevent files from growing unbounded.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={fatal:60,error:50,warn:40,info:30,debug:20,trace:10},t=(n,r)=>{let i=(e,t,i={})=>{n({timestamp:Date.now(),message:t,level:e,origin:r,context:i})},a={owner:r,trace:i.bind(null,e.trace),debug:i.bind(null,e.debug),info:i.bind(null,e.info),warn:i.bind(null,e.warn),error:i.bind(null,e.error),fatal:i.bind(null,e.fatal),namespace:e=>t(n,r.concat(e)),withMiddleware:e=>t(e(n),r)},o={configurable:!1,enumerable:!1};return Object.defineProperties(a,{withMiddleware:o,namespace:o,trace:o,debug:o,info:o,warn:o,error:o,fatal:o})},n=
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={fatal:60,error:50,warn:40,info:30,debug:20,trace:10},t=(n,r)=>{let i=(e,t,i={})=>{n({timestamp:Date.now(),message:t,level:e,origin:r,context:i})},a={owner:r,trace:i.bind(null,e.trace),debug:i.bind(null,e.debug),info:i.bind(null,e.info),warn:i.bind(null,e.warn),error:i.bind(null,e.error),fatal:i.bind(null,e.fatal),namespace:e=>t(n,r.concat(e)),withMiddleware:e=>t(e(n),r)},o={configurable:!1,enumerable:!1};return Object.defineProperties(a,{withMiddleware:o,namespace:o,trace:o,debug:o,info:o,warn:o,error:o,fatal:o})},n=({stream:e})=>t=>{let n=JSON.stringify({level:i[t.level],time:new Date(t.timestamp).toISOString(),msg:t.message,origin:t.origin,ctx:Object.keys(t.context).length>0?t.context:void 0},r);e.write(`${n}\n`)},r=(e,t)=>t instanceof Error?{...t,name:t.name,message:t.message,cause:t.cause,...t instanceof AggregateError&&{errors:t.errors}}:t,i=Object.fromEntries(Object.entries(e).map(([e,t])=>[t,e]));exports.createJsonBackend=n;
|
|
@@ -1,33 +1,22 @@
|
|
|
1
1
|
import { LogProcessor } from '@holz/core';
|
|
2
|
+
import { Writable } from 'node:stream';
|
|
2
3
|
|
|
3
4
|
declare interface Config {
|
|
4
|
-
/** Where to print logs.
|
|
5
|
-
stream:
|
|
6
|
-
/**
|
|
7
|
-
* Closes the stream on abort, flushing queued writes and committing
|
|
8
|
-
* OPFS-style sinks. Fire-and-forget: to await the flush, observe your own
|
|
9
|
-
* sink or resource completion. Logs are dropped once shutdown begins.
|
|
10
|
-
*/
|
|
11
|
-
signal?: AbortSignal;
|
|
5
|
+
/** Where to print logs. */
|
|
6
|
+
stream: Writable;
|
|
12
7
|
}
|
|
13
8
|
|
|
14
9
|
/**
|
|
15
10
|
* Prints structured logs to a writable stream in NDJSON form. Optimized for
|
|
16
11
|
* log files.
|
|
17
12
|
*
|
|
18
|
-
* Writes to a Web Streams `WritableStream<Uint8Array>` so the same backend
|
|
19
|
-
* runs across Node, Deno, Bun, and the browser (e.g. OPFS). See the readme
|
|
20
|
-
* for a Node file-stream example.
|
|
21
|
-
*
|
|
22
13
|
* @example
|
|
23
14
|
* createJsonBackend({
|
|
24
|
-
* stream:
|
|
25
|
-
* write: (chunk) => void process.stdout.write(chunk),
|
|
26
|
-
* }),
|
|
15
|
+
* stream: fs.createWriteStream('my-app.log', { flags: 'a' }),
|
|
27
16
|
* })
|
|
28
17
|
*
|
|
29
18
|
* @see https://github.com/ndjson/ndjson-spec
|
|
30
19
|
*/
|
|
31
|
-
export declare const createJsonBackend: ({ stream
|
|
20
|
+
export declare const createJsonBackend: ({ stream }: Config) => LogProcessor;
|
|
32
21
|
|
|
33
22
|
export { }
|
|
@@ -39,25 +39,21 @@ var e = {
|
|
|
39
39
|
error: o,
|
|
40
40
|
fatal: o
|
|
41
41
|
});
|
|
42
|
-
}, n =
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}, a);
|
|
53
|
-
r.write(n.encode(`${t}\n`)).catch(i);
|
|
54
|
-
};
|
|
55
|
-
}, i = () => {}, a = (e, t) => t instanceof Error ? {
|
|
42
|
+
}, n = ({ stream: e }) => (t) => {
|
|
43
|
+
let n = JSON.stringify({
|
|
44
|
+
level: i[t.level],
|
|
45
|
+
time: new Date(t.timestamp).toISOString(),
|
|
46
|
+
msg: t.message,
|
|
47
|
+
origin: t.origin,
|
|
48
|
+
ctx: Object.keys(t.context).length > 0 ? t.context : void 0
|
|
49
|
+
}, r);
|
|
50
|
+
e.write(`${n}\n`);
|
|
51
|
+
}, r = (e, t) => t instanceof Error ? {
|
|
56
52
|
...t,
|
|
57
53
|
name: t.name,
|
|
58
54
|
message: t.message,
|
|
59
55
|
cause: t.cause,
|
|
60
56
|
...t instanceof AggregateError && { errors: t.errors }
|
|
61
|
-
} : t,
|
|
57
|
+
} : t, i = Object.fromEntries(Object.entries(e).map(([e, t]) => [t, e]));
|
|
62
58
|
//#endregion
|
|
63
|
-
export {
|
|
59
|
+
export { n as createJsonBackend };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holz/json-backend",
|
|
3
|
-
"version": "0.8.3-rc.
|
|
3
|
+
"version": "0.8.3-rc.170+39397cc",
|
|
4
4
|
"description": "Print logs as newline-delimited JSON.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"test:types": "tsc"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@holz/core": "^0.8.3-rc.
|
|
40
|
+
"@holz/core": "^0.8.3-rc.170+39397cc",
|
|
41
41
|
"@microsoft/api-extractor": "^7.58.8",
|
|
42
42
|
"@types/node": "^24.0.0",
|
|
43
43
|
"@vitest/coverage-v8": "^4.0.0",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"vite-tsconfig-paths": "^6.0.0",
|
|
48
48
|
"vitest": "^4.0.0"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "39397cc9e7120e987e0843fb686dba0916d4c2cd"
|
|
51
51
|
}
|