@loggerjs/codecs 0.0.2 → 0.3.0
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 +59 -7
- package/dist/fast-event-json.d.ts +1 -1
- package/dist/index.cjs +112 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +111 -4
- package/dist/index.js.map +1 -1
- package/dist/pino-compat.d.ts +13 -0
- package/dist/pino-compat.d.ts.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,19 +1,71 @@
|
|
|
1
1
|
# @loggerjs/codecs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> High-performance and binary serialization codecs for LoggerJS transports.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@loggerjs/codecs)
|
|
6
|
+
[](../../LICENSE)
|
|
7
|
+
|
|
8
|
+
Optional codecs for [LoggerJS](../../README.md) that go beyond the JSON/NDJSON codecs built into `@loggerjs/core`. **Codecs belong to transports** — the pipeline keeps values raw and each destination owns its serialization, so you can pick a different wire format per transport without touching middleware or processors.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @loggerjs/codecs
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
4
17
|
|
|
5
18
|
```ts
|
|
6
|
-
import { fastEventJsonCodec,
|
|
19
|
+
import { fastEventJsonCodec, pinoCompatCodec, projectorCodec } from "@loggerjs/codecs";
|
|
20
|
+
import { nodeHttpTransport } from "@loggerjs/node";
|
|
21
|
+
|
|
22
|
+
// The performance codec for JSON payload transports.
|
|
23
|
+
nodeHttpTransport({
|
|
24
|
+
url: "https://collector.example/logs",
|
|
25
|
+
codec: fastEventJsonCodec(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Drop envelope fields when downstream does not need them.
|
|
29
|
+
nodeHttpTransport({
|
|
30
|
+
url: "https://collector.example/logs",
|
|
31
|
+
codec: fastEventJsonCodec({ includeId: false, includeSeq: false, includeLevelName: false }),
|
|
32
|
+
});
|
|
7
33
|
|
|
8
|
-
|
|
9
|
-
|
|
34
|
+
// Pino-shaped NDJSON for migration paths.
|
|
35
|
+
nodeHttpTransport({
|
|
36
|
+
url: "https://collector.example/logs",
|
|
37
|
+
codec: pinoCompatCodec({ base: { pid: process.pid, hostname: "api-1" }, mergeData: true }),
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Codecs
|
|
42
|
+
|
|
43
|
+
| Codec | Format | Notes |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| `fastEventJsonCodec` | JSON | The performance codec — fragment-cached serialization, fast by default, falls back instead of throwing on circular references. Toggle envelope fields (`includeId`, `includeSeq`, `includeLevelName`) to trade detail for speed. |
|
|
46
|
+
| `pinoCompatCodec` / `pinoNdjsonProjector` | NDJSON | Encode-only Pino-shaped migration output with `level`, `time`, optional base fields, `msg`, `err`, and opt-in root data merging with reserved-key protection. |
|
|
47
|
+
| `msgpackrCodec` | MessagePack (binary) | Compact binary encoding via [`msgpackr`](https://github.com/kriszyp/msgpackr); ideal for worker, WebSocket, and HTTP transports that accept binary payloads. |
|
|
48
|
+
| `projectorCodec` | custom | Build a codec from a `project` step (shape the events) plus a `serialize` step (turn them into the wire payload). |
|
|
49
|
+
|
|
50
|
+
For line-delimited stdout/file output, use the Node transports' default `ndjsonCodec()` from `@loggerjs/core`; `fastEventJsonCodec()` emits JSON payloads and does not append newlines.
|
|
10
51
|
|
|
11
|
-
|
|
52
|
+
```ts
|
|
53
|
+
const idsOnly = projectorCodec({
|
|
12
54
|
name: "ids-only",
|
|
13
55
|
contentType: "application/json",
|
|
14
|
-
project: (events) => events,
|
|
56
|
+
project: (events) => events.map((e) => ({ id: e.id, level: e.level, time: e.time })),
|
|
15
57
|
serialize: JSON.stringify,
|
|
16
58
|
});
|
|
17
59
|
```
|
|
18
60
|
|
|
19
|
-
|
|
61
|
+
> Keep raw, structured values flowing through middleware and processors so redaction works on real data and batching can amortize serialization. Never pre-stringify in the pipeline.
|
|
62
|
+
|
|
63
|
+
## Documentation
|
|
64
|
+
|
|
65
|
+
- [Codecs](../../docs/CODECS.md) — the codec contract and fast-by-default safety semantics
|
|
66
|
+
- [Performance](../../docs/PERFORMANCE.md) — choosing a codec for the hot path
|
|
67
|
+
- [Benchmarks](../../docs/BENCHMARKS.md) · [LoggerJS root README](../../README.md)
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
[MIT](../../LICENSE) © JS Kits
|
|
@@ -7,7 +7,7 @@ import { type Codec, type SafeStringifyOptions } from "@loggerjs/core";
|
|
|
7
7
|
* everywhere, which also preserves `Error` name/message/stack inside data payloads.
|
|
8
8
|
*
|
|
9
9
|
* `includeId`, `includeSeq`, and `includeLevelName` trim the envelope for
|
|
10
|
-
*
|
|
10
|
+
* lean comparable JSON output; turning `includeId` off also skips id
|
|
11
11
|
* computation entirely on the record path.
|
|
12
12
|
*/
|
|
13
13
|
export interface FastEventJsonCodecOptions extends SafeStringifyOptions {
|
package/dist/index.cjs
CHANGED
|
@@ -2,17 +2,17 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
let _loggerjs_core = require("@loggerjs/core");
|
|
3
3
|
let msgpackr = require("msgpackr");
|
|
4
4
|
//#region src/fast-event-json.ts
|
|
5
|
-
function hasSafeOptions(options) {
|
|
5
|
+
function hasSafeOptions$1(options) {
|
|
6
6
|
return options.maxDepth !== void 0 || options.maxArrayLength !== void 0 || options.maxObjectKeys !== void 0 || options.includeStack !== void 0 || options.stable !== void 0 || options.space !== void 0;
|
|
7
7
|
}
|
|
8
8
|
function canUseNativeEventJson(options) {
|
|
9
|
-
return !hasSafeOptions(options) && options.includeContext !== false && options.includeData !== false && options.includeError !== false && options.includeTrace !== false && options.includeSource !== false && options.includeId !== false && options.includeSeq !== false && options.includeLevelName !== false;
|
|
9
|
+
return !hasSafeOptions$1(options) && options.includeContext !== false && options.includeData !== false && options.includeError !== false && options.includeTrace !== false && options.includeSource !== false && options.includeId !== false && options.includeSeq !== false && options.includeLevelName !== false;
|
|
10
10
|
}
|
|
11
11
|
function hasFullHeader(options) {
|
|
12
12
|
return (options.includeId ?? true) && (options.includeSeq ?? true) && (options.includeLevelName ?? true);
|
|
13
13
|
}
|
|
14
14
|
function createStringify(options) {
|
|
15
|
-
if (hasSafeOptions(options)) return (value) => (0, _loggerjs_core.safeJsonStringify)(value, options);
|
|
15
|
+
if (hasSafeOptions$1(options)) return (value) => (0, _loggerjs_core.safeJsonStringify)(value, options);
|
|
16
16
|
return JSON.stringify;
|
|
17
17
|
}
|
|
18
18
|
function appendField(output, name, value, stringify) {
|
|
@@ -226,6 +226,113 @@ function msgpackrCodec(options = {}) {
|
|
|
226
226
|
};
|
|
227
227
|
}
|
|
228
228
|
//#endregion
|
|
229
|
+
//#region src/pino-compat.ts
|
|
230
|
+
const baseReservedRootKeys = new Set([
|
|
231
|
+
"time",
|
|
232
|
+
"level",
|
|
233
|
+
"msg",
|
|
234
|
+
"err",
|
|
235
|
+
"logger",
|
|
236
|
+
"data"
|
|
237
|
+
]);
|
|
238
|
+
const dataReservedRootKeys = new Set([
|
|
239
|
+
"time",
|
|
240
|
+
"level",
|
|
241
|
+
"msg",
|
|
242
|
+
"pid",
|
|
243
|
+
"hostname",
|
|
244
|
+
"err",
|
|
245
|
+
"logger",
|
|
246
|
+
"data"
|
|
247
|
+
]);
|
|
248
|
+
function hasSafeOptions(options) {
|
|
249
|
+
return options.maxDepth !== void 0 || options.maxArrayLength !== void 0 || options.maxObjectKeys !== void 0 || options.includeStack !== void 0 || options.stable !== void 0 || options.space !== void 0;
|
|
250
|
+
}
|
|
251
|
+
function isRecord(value) {
|
|
252
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
253
|
+
}
|
|
254
|
+
function pinoError(error) {
|
|
255
|
+
return {
|
|
256
|
+
type: error.name ?? "Error",
|
|
257
|
+
message: error.message,
|
|
258
|
+
stack: error.stack,
|
|
259
|
+
code: error.code,
|
|
260
|
+
cause: error.cause
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function assignWithCollision(output, nested, key, value, policy, reservedKeys = dataReservedRootKeys) {
|
|
264
|
+
if (!reservedKeys.has(key) && !(key in output)) {
|
|
265
|
+
output[key] = value;
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (policy === "throw") throw new Error(`pinoCompatCodec cannot merge reserved key "${key}"`);
|
|
269
|
+
if (policy === "nest") nested[key] = value;
|
|
270
|
+
}
|
|
271
|
+
function mergeNestedData(existing, nested) {
|
|
272
|
+
if (isRecord(existing)) return {
|
|
273
|
+
...nested,
|
|
274
|
+
...existing
|
|
275
|
+
};
|
|
276
|
+
if (existing !== void 0) return {
|
|
277
|
+
...nested,
|
|
278
|
+
value: existing
|
|
279
|
+
};
|
|
280
|
+
return nested;
|
|
281
|
+
}
|
|
282
|
+
function projectEvent(event, options) {
|
|
283
|
+
const dataKey = options.dataKey ?? "data";
|
|
284
|
+
const errorKey = options.errorKey ?? "err";
|
|
285
|
+
const collision = options.collision ?? "nest";
|
|
286
|
+
const output = {
|
|
287
|
+
level: event.level,
|
|
288
|
+
time: event.time
|
|
289
|
+
};
|
|
290
|
+
const nested = {};
|
|
291
|
+
const baseReservedKeys = new Set(baseReservedRootKeys);
|
|
292
|
+
baseReservedKeys.add(dataKey);
|
|
293
|
+
baseReservedKeys.add(errorKey);
|
|
294
|
+
for (const [key, value] of Object.entries(options.base ?? {})) assignWithCollision(output, nested, key, value, collision, baseReservedKeys);
|
|
295
|
+
if (options.includeLogger) output.logger = event.logger;
|
|
296
|
+
if (event.error) output[errorKey] = pinoError(event.error);
|
|
297
|
+
if (event.data !== void 0) if (options.mergeData && isRecord(event.data)) {
|
|
298
|
+
const dataReservedKeys = new Set(dataReservedRootKeys);
|
|
299
|
+
dataReservedKeys.add(dataKey);
|
|
300
|
+
dataReservedKeys.add(errorKey);
|
|
301
|
+
for (const [key, value] of Object.entries(event.data)) assignWithCollision(output, nested, key, value, collision, dataReservedKeys);
|
|
302
|
+
} else output[dataKey] = event.data;
|
|
303
|
+
if (Object.keys(nested).length > 0) output[dataKey] = mergeNestedData(output[dataKey], nested);
|
|
304
|
+
output.msg = event.message;
|
|
305
|
+
return output;
|
|
306
|
+
}
|
|
307
|
+
function encodeLine(event, options, safeMode) {
|
|
308
|
+
const projected = projectEvent(event, options);
|
|
309
|
+
if (safeMode) return (0, _loggerjs_core.safeJsonStringify)(projected, options);
|
|
310
|
+
try {
|
|
311
|
+
return JSON.stringify(projected) ?? "{}";
|
|
312
|
+
} catch {
|
|
313
|
+
(0, _loggerjs_core.incrementLoggerMetaCounter)("codec.fallback");
|
|
314
|
+
(0, _loggerjs_core.incrementLoggerMetaCounter)("codec.fallback.pino-compat");
|
|
315
|
+
return (0, _loggerjs_core.safeJsonStringify)(projected, options);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function encodeEvents(input, options, safeMode) {
|
|
319
|
+
if (!Array.isArray(input)) return `${encodeLine(input, options, safeMode)}\n`;
|
|
320
|
+
let output = "";
|
|
321
|
+
for (const event of input) output += `${encodeLine(event, options, safeMode)}\n`;
|
|
322
|
+
return output;
|
|
323
|
+
}
|
|
324
|
+
function pinoCompatCodec(options = {}) {
|
|
325
|
+
const safeMode = hasSafeOptions(options);
|
|
326
|
+
return {
|
|
327
|
+
name: "pino-compat",
|
|
328
|
+
contentType: "application/x-ndjson",
|
|
329
|
+
encode(input) {
|
|
330
|
+
return encodeEvents((0, _loggerjs_core.normalizeCodecInput)(input), options, safeMode);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
const pinoNdjsonProjector = pinoCompatCodec;
|
|
335
|
+
//#endregion
|
|
229
336
|
//#region src/projector.ts
|
|
230
337
|
function projectorCodec(options) {
|
|
231
338
|
return {
|
|
@@ -240,6 +347,8 @@ function projectorCodec(options) {
|
|
|
240
347
|
//#endregion
|
|
241
348
|
exports.fastEventJsonCodec = fastEventJsonCodec;
|
|
242
349
|
exports.msgpackrCodec = msgpackrCodec;
|
|
350
|
+
exports.pinoCompatCodec = pinoCompatCodec;
|
|
351
|
+
exports.pinoNdjsonProjector = pinoNdjsonProjector;
|
|
243
352
|
exports.projectorCodec = projectorCodec;
|
|
244
353
|
Object.keys(_loggerjs_core).forEach(function(k) {
|
|
245
354
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["Packr"],"sources":["../src/fast-event-json.ts","../src/msgpackr.ts","../src/projector.ts"],"sourcesContent":["import {\n defaultRecordId,\n incrementLoggerMetaCounter,\n isLogRecord,\n normalizeError,\n resolveMessage,\n toLevelName,\n safeJsonStringify,\n type Codec,\n type CodecInput,\n type LogEvent,\n type LogRecord,\n type SafeStringifyOptions,\n} from \"@loggerjs/core\";\n\n/**\n * Without any option set, encode runs on a native `JSON.stringify` fast path: nested\n * `Error` values serialize as `{}` and circular or BigInt payloads trigger a safe\n * re-encode of the whole input (circular refs become \"[Circular]\", BigInt becomes a\n * string). Setting any {@link SafeStringifyOptions} field opts into the safe encoder\n * everywhere, which also preserves `Error` name/message/stack inside data payloads.\n *\n * `includeId`, `includeSeq`, and `includeLevelName` trim the envelope for\n * pino-shaped minimal NDJSON output; turning `includeId` off also skips id\n * computation entirely on the record path.\n */\nexport interface FastEventJsonCodecOptions extends SafeStringifyOptions {\n includeContext?: boolean;\n includeData?: boolean;\n includeError?: boolean;\n includeTrace?: boolean;\n includeSource?: boolean;\n includeId?: boolean;\n includeSeq?: boolean;\n includeLevelName?: boolean;\n}\n\ntype JsonStringify = (value: unknown) => string | undefined;\n\nfunction hasSafeOptions(options: SafeStringifyOptions): boolean {\n return (\n options.maxDepth !== undefined ||\n options.maxArrayLength !== undefined ||\n options.maxObjectKeys !== undefined ||\n options.includeStack !== undefined ||\n options.stable !== undefined ||\n options.space !== undefined\n );\n}\n\nfunction canUseNativeEventJson(options: FastEventJsonCodecOptions): boolean {\n return (\n !hasSafeOptions(options) &&\n options.includeContext !== false &&\n options.includeData !== false &&\n options.includeError !== false &&\n options.includeTrace !== false &&\n options.includeSource !== false &&\n options.includeId !== false &&\n options.includeSeq !== false &&\n options.includeLevelName !== false\n );\n}\n\nfunction hasFullHeader(options: FastEventJsonCodecOptions): boolean {\n return (\n (options.includeId ?? true) &&\n (options.includeSeq ?? true) &&\n (options.includeLevelName ?? true)\n );\n}\n\nfunction createStringify(options: SafeStringifyOptions): JsonStringify {\n if (hasSafeOptions(options)) return (value) => safeJsonStringify(value, options);\n return JSON.stringify;\n}\n\nfunction appendField(\n output: string,\n name: string,\n value: unknown,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const encoded = stringify(value);\n return encoded === undefined ? output : `${output},\"${name}\":${encoded}`;\n}\n\n// JSON.stringify costs ~35ns per short string mostly in call overhead. Short\n// strings without quotes, backslashes, or control characters can be quoted\n// directly after a linear scan.\nfunction asJsonString(value: string): string {\n if (value.length > 256) return JSON.stringify(value);\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code === 34 || code === 92 || code < 32) return JSON.stringify(value);\n }\n return `\"${value}\"`;\n}\n\n// Data payloads are usually small flat objects of primitives. Writing them\n// directly skips the native JSON.stringify call overhead; any nested or\n// exotic value bails out so the caller can use the configured stringifier.\nfunction tryFlatObjectJson(value: Record<string, unknown>): string | undefined {\n // Class instances may carry toJSON or accessors; only plain objects take\n // the fast path so behavior matches JSON.stringify.\n const proto = Object.getPrototypeOf(value) as unknown;\n if (proto !== Object.prototype && proto !== null) return undefined;\n let output = \"{\";\n let first = true;\n for (const key of Object.keys(value)) {\n const item = value[key];\n let encoded: string;\n switch (typeof item) {\n case \"string\":\n encoded = asJsonString(item);\n break;\n case \"number\":\n encoded = Number.isFinite(item) ? String(item) : \"null\";\n break;\n case \"boolean\":\n encoded = item ? \"true\" : \"false\";\n break;\n case \"object\":\n if (item !== null) return undefined;\n encoded = \"null\";\n break;\n case \"undefined\":\n continue;\n default:\n return undefined;\n }\n output += `${first ? \"\" : \",\"}${asJsonString(key)}:${encoded}`;\n first = false;\n }\n return `${output}}`;\n}\n\nfunction appendDataField(\n output: string,\n value: Record<string, unknown> | undefined,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const flat = tryFlatObjectJson(value);\n if (flat !== undefined) return `${output},\"data\":${flat}`;\n return appendField(output, \"data\", value, stringify);\n}\n\n// The timestamp changes once per millisecond while bursts of records share\n// it, so the rendered `\",\"time\":...,\"seq\":` fragment can be memoized the same\n// way the default id memoizes its time segment.\nlet lastFragmentTime = -1;\nlet lastTimeFragment = \"\";\n\nfunction timeFragment(time: number): string {\n if (time !== lastFragmentTime) {\n lastFragmentTime = time;\n lastTimeFragment = `\",\"time\":${time},\"seq\":`;\n }\n return lastTimeFragment;\n}\n\n// level -> ',\"level\":30,\"levelName\":\"info\",\"logger\":' — derived from the\n// numeric level alone, so a module-level cache is safe.\nconst levelFragments = new Map<number, string>();\n\nfunction levelFragment(level: number): string {\n let fragment = levelFragments.get(level);\n if (fragment === undefined) {\n fragment = `,\"level\":${level},\"levelName\":\"${toLevelName(level)}\",\"logger\":`;\n levelFragments.set(level, fragment);\n }\n return fragment;\n}\n\n// Loggers reuse one frozen category array for every record, so the joined and\n// escaped logger name can be cached per array identity.\nconst categoryFragments = new WeakMap<readonly string[], string>();\n\nfunction loggerFragment(category: readonly string[]): string {\n let fragment = categoryFragments.get(category);\n if (fragment === undefined) {\n fragment = asJsonString(category.join(\".\"));\n categoryFragments.set(category, fragment);\n }\n return fragment;\n}\n\nfunction errorForRecord(record: LogRecord): LogEvent[\"error\"] | undefined {\n if (record.err === null || record.err === undefined) return undefined;\n return normalizeError(record.err);\n}\n\nfunction encodeEvent(\n event: LogEvent,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogEvent[\"tags\"]>) => string,\n): string {\n let output: string;\n if (hasFullHeader(options)) {\n output = `{\"id\":${asJsonString(event.id)},\"time\":${event.time},\"seq\":${event.seq},\"level\":${event.level},\"levelName\":${asJsonString(event.levelName)},\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":${asJsonString(event.id)},`;\n output += `\"time\":${event.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${event.seq}`;\n output += `,\"level\":${event.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":${asJsonString(event.levelName)}`;\n output += `,\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n }\n if (event.type !== undefined) output += `,\"type\":${asJsonString(event.type)}`;\n if (event.tags !== undefined) output += tagsFragment(event.tags);\n if (options.includeData ?? true) output = appendField(output, \"data\", event.data, stringify);\n if (options.includeError ?? true) output = appendField(output, \"error\", event.error, stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", event.context, stringify);\n if (options.includeTrace ?? true) output = appendField(output, \"trace\", event.trace, stringify);\n if (options.includeSource ?? true)\n output = appendField(output, \"source\", event.source, stringify);\n return `${output}}`;\n}\n\nfunction encodeRecord(\n record: LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogRecord[\"tags\"]>) => string,\n): string {\n const levelName = toLevelName(record.level);\n let output: string;\n if (hasFullHeader(options)) {\n // The default id only contains [0-9a-z-] and the level name, so it never\n // needs escaping.\n output = `{\"id\":\"${defaultRecordId(record, levelName)}${timeFragment(record.time)}${record.seq}${levelFragment(record.level)}${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":\"${defaultRecordId(record, levelName)}\",`;\n output += `\"time\":${record.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${record.seq}`;\n output += `,\"level\":${record.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":\"${levelName}\"`;\n output += `,\"logger\":${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n }\n if (record.type !== null) output += `,\"type\":${asJsonString(record.type)}`;\n if (record.tags !== null) output += tagsFragment(record.tags);\n if (options.includeData ?? true)\n output = appendDataField(output, record.props ?? undefined, stringify);\n if (options.includeError ?? true)\n output = appendField(output, \"error\", errorForRecord(record), stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", record.ctx ?? undefined, stringify);\n if (options.includeTrace ?? true)\n output = appendField(output, \"trace\", record.trace ?? undefined, stringify);\n if ((options.includeSource ?? true) && record.source !== \"app\")\n output += `,\"source\":{\"integration\":${asJsonString(record.source)}}`;\n return `${output}}`;\n}\n\ntype TagsFragment = (tags: NonNullable<LogEvent[\"tags\"]>) => string;\n\nfunction encodeItem(\n item: LogEvent | LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n return isLogRecord(item)\n ? encodeRecord(item, options, stringify, tagsFragment)\n : encodeEvent(item, options, stringify, tagsFragment);\n}\n\nfunction encodeArray(\n items: readonly (LogEvent | LogRecord)[],\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n let output = \"[\";\n for (let index = 0; index < items.length; index += 1) {\n if (index > 0) output += \",\";\n output += encodeItem(items[index]!, options, stringify, tagsFragment);\n }\n return `${output}]`;\n}\n\nfunction isCodecArray(input: CodecInput): input is readonly (LogEvent | LogRecord)[] {\n return Array.isArray(input);\n}\n\nfunction hasLogRecord(items: readonly (LogEvent | LogRecord)[]): boolean {\n for (const item of items) {\n if (isLogRecord(item)) return true;\n }\n return false;\n}\n\n// Loggers share one frozen tags object across records, so the encoded\n// fragment can be cached per object identity. Mutable tags objects are\n// re-encoded every time. Callers create one fragment encoder per codec\n// because it bakes in that codec's stringify options.\nfunction createTagsFragment(encoder: JsonStringify, cached: boolean): TagsFragment {\n const fragments = cached ? new WeakMap<object, string>() : undefined;\n return (tags) => {\n if (fragments && Object.isFrozen(tags)) {\n let fragment = fragments.get(tags);\n if (fragment === undefined) {\n const encoded = encoder(tags);\n fragment = encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n fragments.set(tags, fragment);\n }\n return fragment;\n }\n const encoded = encoder(tags);\n return encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n };\n}\n\nexport function fastEventJsonCodec(options: FastEventJsonCodecOptions = {}): Codec<string> {\n const stringify = createStringify(options);\n const safeStringify: JsonStringify = (value) => safeJsonStringify(value, options);\n const useNativeEventJson = canUseNativeEventJson(options);\n const tagsFragment = createTagsFragment(stringify, true);\n // The fallback must not reuse the fast fragments: a cached entry or the\n // fast stringify could throw on the exact payload that triggered fallback.\n const safeTagsFragment = createTagsFragment(safeStringify, false);\n const fastEncode = (input: CodecInput): string => {\n if (isCodecArray(input)) {\n if (useNativeEventJson && !hasLogRecord(input)) return JSON.stringify(input);\n return encodeArray(input, options, stringify, tagsFragment);\n }\n if (useNativeEventJson && !isLogRecord(input)) return JSON.stringify(input);\n return encodeItem(input, options, stringify, tagsFragment);\n };\n return {\n name: \"fast-event-json\",\n contentType: \"application/json\",\n encode(input: CodecInput) {\n // Circular references and BigInt values throw on the native fast path. Logs\n // must never be lost to encoding, so re-encode the input with the safe\n // stringifier instead of surfacing the error as a transport failure.\n try {\n return fastEncode(input);\n } catch {\n incrementLoggerMetaCounter(\"codec.fallback\");\n incrementLoggerMetaCounter(\"codec.fallback.fast-event-json\");\n }\n if (isCodecArray(input)) return encodeArray(input, options, safeStringify, safeTagsFragment);\n return encodeItem(input, options, safeStringify, safeTagsFragment);\n },\n decode(payload) {\n return JSON.parse(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\nimport { Packr, type Options as MsgpackrOptions } from \"msgpackr\";\n\nexport interface MsgpackRuntime {\n pack: (input: unknown) => Uint8Array;\n unpack: (payload: Uint8Array) => unknown;\n}\n\nexport type MsgpackrCodecOptions = MsgpackrOptions;\n\nfunction isMsgpackRuntime(value: MsgpackRuntime | MsgpackrCodecOptions): value is MsgpackRuntime {\n return (\n typeof (value as MsgpackRuntime).pack === \"function\" &&\n typeof (value as MsgpackRuntime).unpack === \"function\"\n );\n}\n\nexport function msgpackrCodec(\n options: MsgpackRuntime | MsgpackrCodecOptions = {},\n): Codec<Uint8Array> {\n const runtime = isMsgpackRuntime(options) ? options : new Packr({ useRecords: true, ...options });\n return {\n name: \"msgpackr\",\n contentType: \"application/msgpack\",\n encode(input: CodecInput) {\n return runtime.pack(normalizeCodecInput(input));\n },\n decode(payload: Uint8Array) {\n return runtime.unpack(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\n\nexport interface ProjectorCodecOptions<TWire> {\n name: string;\n contentType: string;\n project: (input: LogEvent | LogEvent[]) => TWire;\n serialize: (wire: TWire) => string | Uint8Array;\n parse?: (payload: string | Uint8Array) => TWire;\n unproject?: (wire: TWire) => LogEvent | LogEvent[];\n}\n\nexport function projectorCodec<TWire>(\n options: ProjectorCodecOptions<TWire>,\n): Codec<string | Uint8Array> {\n return {\n name: options.name,\n contentType: options.contentType,\n encode(input: CodecInput) {\n return options.serialize(options.project(normalizeCodecInput(input)));\n },\n decode:\n options.parse && options.unproject\n ? (payload) => options.unproject!(options.parse!(payload))\n : undefined,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["hasSafeOptions","Packr"],"sources":["../src/fast-event-json.ts","../src/msgpackr.ts","../src/pino-compat.ts","../src/projector.ts"],"sourcesContent":["import {\n defaultRecordId,\n incrementLoggerMetaCounter,\n isLogRecord,\n normalizeError,\n resolveMessage,\n toLevelName,\n safeJsonStringify,\n type Codec,\n type CodecInput,\n type LogEvent,\n type LogRecord,\n type SafeStringifyOptions,\n} from \"@loggerjs/core\";\n\n/**\n * Without any option set, encode runs on a native `JSON.stringify` fast path: nested\n * `Error` values serialize as `{}` and circular or BigInt payloads trigger a safe\n * re-encode of the whole input (circular refs become \"[Circular]\", BigInt becomes a\n * string). Setting any {@link SafeStringifyOptions} field opts into the safe encoder\n * everywhere, which also preserves `Error` name/message/stack inside data payloads.\n *\n * `includeId`, `includeSeq`, and `includeLevelName` trim the envelope for\n * lean comparable JSON output; turning `includeId` off also skips id\n * computation entirely on the record path.\n */\nexport interface FastEventJsonCodecOptions extends SafeStringifyOptions {\n includeContext?: boolean;\n includeData?: boolean;\n includeError?: boolean;\n includeTrace?: boolean;\n includeSource?: boolean;\n includeId?: boolean;\n includeSeq?: boolean;\n includeLevelName?: boolean;\n}\n\ntype JsonStringify = (value: unknown) => string | undefined;\n\nfunction hasSafeOptions(options: SafeStringifyOptions): boolean {\n return (\n options.maxDepth !== undefined ||\n options.maxArrayLength !== undefined ||\n options.maxObjectKeys !== undefined ||\n options.includeStack !== undefined ||\n options.stable !== undefined ||\n options.space !== undefined\n );\n}\n\nfunction canUseNativeEventJson(options: FastEventJsonCodecOptions): boolean {\n return (\n !hasSafeOptions(options) &&\n options.includeContext !== false &&\n options.includeData !== false &&\n options.includeError !== false &&\n options.includeTrace !== false &&\n options.includeSource !== false &&\n options.includeId !== false &&\n options.includeSeq !== false &&\n options.includeLevelName !== false\n );\n}\n\nfunction hasFullHeader(options: FastEventJsonCodecOptions): boolean {\n return (\n (options.includeId ?? true) &&\n (options.includeSeq ?? true) &&\n (options.includeLevelName ?? true)\n );\n}\n\nfunction createStringify(options: SafeStringifyOptions): JsonStringify {\n if (hasSafeOptions(options)) return (value) => safeJsonStringify(value, options);\n return JSON.stringify;\n}\n\nfunction appendField(\n output: string,\n name: string,\n value: unknown,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const encoded = stringify(value);\n return encoded === undefined ? output : `${output},\"${name}\":${encoded}`;\n}\n\n// JSON.stringify costs ~35ns per short string mostly in call overhead. Short\n// strings without quotes, backslashes, or control characters can be quoted\n// directly after a linear scan.\nfunction asJsonString(value: string): string {\n if (value.length > 256) return JSON.stringify(value);\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code === 34 || code === 92 || code < 32) return JSON.stringify(value);\n }\n return `\"${value}\"`;\n}\n\n// Data payloads are usually small flat objects of primitives. Writing them\n// directly skips the native JSON.stringify call overhead; any nested or\n// exotic value bails out so the caller can use the configured stringifier.\nfunction tryFlatObjectJson(value: Record<string, unknown>): string | undefined {\n // Class instances may carry toJSON or accessors; only plain objects take\n // the fast path so behavior matches JSON.stringify.\n const proto = Object.getPrototypeOf(value) as unknown;\n if (proto !== Object.prototype && proto !== null) return undefined;\n let output = \"{\";\n let first = true;\n for (const key of Object.keys(value)) {\n const item = value[key];\n let encoded: string;\n switch (typeof item) {\n case \"string\":\n encoded = asJsonString(item);\n break;\n case \"number\":\n encoded = Number.isFinite(item) ? String(item) : \"null\";\n break;\n case \"boolean\":\n encoded = item ? \"true\" : \"false\";\n break;\n case \"object\":\n if (item !== null) return undefined;\n encoded = \"null\";\n break;\n case \"undefined\":\n continue;\n default:\n return undefined;\n }\n output += `${first ? \"\" : \",\"}${asJsonString(key)}:${encoded}`;\n first = false;\n }\n return `${output}}`;\n}\n\nfunction appendDataField(\n output: string,\n value: Record<string, unknown> | undefined,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const flat = tryFlatObjectJson(value);\n if (flat !== undefined) return `${output},\"data\":${flat}`;\n return appendField(output, \"data\", value, stringify);\n}\n\n// The timestamp changes once per millisecond while bursts of records share\n// it, so the rendered `\",\"time\":...,\"seq\":` fragment can be memoized the same\n// way the default id memoizes its time segment.\nlet lastFragmentTime = -1;\nlet lastTimeFragment = \"\";\n\nfunction timeFragment(time: number): string {\n if (time !== lastFragmentTime) {\n lastFragmentTime = time;\n lastTimeFragment = `\",\"time\":${time},\"seq\":`;\n }\n return lastTimeFragment;\n}\n\n// level -> ',\"level\":30,\"levelName\":\"info\",\"logger\":' — derived from the\n// numeric level alone, so a module-level cache is safe.\nconst levelFragments = new Map<number, string>();\n\nfunction levelFragment(level: number): string {\n let fragment = levelFragments.get(level);\n if (fragment === undefined) {\n fragment = `,\"level\":${level},\"levelName\":\"${toLevelName(level)}\",\"logger\":`;\n levelFragments.set(level, fragment);\n }\n return fragment;\n}\n\n// Loggers reuse one frozen category array for every record, so the joined and\n// escaped logger name can be cached per array identity.\nconst categoryFragments = new WeakMap<readonly string[], string>();\n\nfunction loggerFragment(category: readonly string[]): string {\n let fragment = categoryFragments.get(category);\n if (fragment === undefined) {\n fragment = asJsonString(category.join(\".\"));\n categoryFragments.set(category, fragment);\n }\n return fragment;\n}\n\nfunction errorForRecord(record: LogRecord): LogEvent[\"error\"] | undefined {\n if (record.err === null || record.err === undefined) return undefined;\n return normalizeError(record.err);\n}\n\nfunction encodeEvent(\n event: LogEvent,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogEvent[\"tags\"]>) => string,\n): string {\n let output: string;\n if (hasFullHeader(options)) {\n output = `{\"id\":${asJsonString(event.id)},\"time\":${event.time},\"seq\":${event.seq},\"level\":${event.level},\"levelName\":${asJsonString(event.levelName)},\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":${asJsonString(event.id)},`;\n output += `\"time\":${event.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${event.seq}`;\n output += `,\"level\":${event.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":${asJsonString(event.levelName)}`;\n output += `,\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n }\n if (event.type !== undefined) output += `,\"type\":${asJsonString(event.type)}`;\n if (event.tags !== undefined) output += tagsFragment(event.tags);\n if (options.includeData ?? true) output = appendField(output, \"data\", event.data, stringify);\n if (options.includeError ?? true) output = appendField(output, \"error\", event.error, stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", event.context, stringify);\n if (options.includeTrace ?? true) output = appendField(output, \"trace\", event.trace, stringify);\n if (options.includeSource ?? true)\n output = appendField(output, \"source\", event.source, stringify);\n return `${output}}`;\n}\n\nfunction encodeRecord(\n record: LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogRecord[\"tags\"]>) => string,\n): string {\n const levelName = toLevelName(record.level);\n let output: string;\n if (hasFullHeader(options)) {\n // The default id only contains [0-9a-z-] and the level name, so it never\n // needs escaping.\n output = `{\"id\":\"${defaultRecordId(record, levelName)}${timeFragment(record.time)}${record.seq}${levelFragment(record.level)}${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":\"${defaultRecordId(record, levelName)}\",`;\n output += `\"time\":${record.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${record.seq}`;\n output += `,\"level\":${record.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":\"${levelName}\"`;\n output += `,\"logger\":${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n }\n if (record.type !== null) output += `,\"type\":${asJsonString(record.type)}`;\n if (record.tags !== null) output += tagsFragment(record.tags);\n if (options.includeData ?? true)\n output = appendDataField(output, record.props ?? undefined, stringify);\n if (options.includeError ?? true)\n output = appendField(output, \"error\", errorForRecord(record), stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", record.ctx ?? undefined, stringify);\n if (options.includeTrace ?? true)\n output = appendField(output, \"trace\", record.trace ?? undefined, stringify);\n if ((options.includeSource ?? true) && record.source !== \"app\")\n output += `,\"source\":{\"integration\":${asJsonString(record.source)}}`;\n return `${output}}`;\n}\n\ntype TagsFragment = (tags: NonNullable<LogEvent[\"tags\"]>) => string;\n\nfunction encodeItem(\n item: LogEvent | LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n return isLogRecord(item)\n ? encodeRecord(item, options, stringify, tagsFragment)\n : encodeEvent(item, options, stringify, tagsFragment);\n}\n\nfunction encodeArray(\n items: readonly (LogEvent | LogRecord)[],\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n let output = \"[\";\n for (let index = 0; index < items.length; index += 1) {\n if (index > 0) output += \",\";\n output += encodeItem(items[index]!, options, stringify, tagsFragment);\n }\n return `${output}]`;\n}\n\nfunction isCodecArray(input: CodecInput): input is readonly (LogEvent | LogRecord)[] {\n return Array.isArray(input);\n}\n\nfunction hasLogRecord(items: readonly (LogEvent | LogRecord)[]): boolean {\n for (const item of items) {\n if (isLogRecord(item)) return true;\n }\n return false;\n}\n\n// Loggers share one frozen tags object across records, so the encoded\n// fragment can be cached per object identity. Mutable tags objects are\n// re-encoded every time. Callers create one fragment encoder per codec\n// because it bakes in that codec's stringify options.\nfunction createTagsFragment(encoder: JsonStringify, cached: boolean): TagsFragment {\n const fragments = cached ? new WeakMap<object, string>() : undefined;\n return (tags) => {\n if (fragments && Object.isFrozen(tags)) {\n let fragment = fragments.get(tags);\n if (fragment === undefined) {\n const encoded = encoder(tags);\n fragment = encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n fragments.set(tags, fragment);\n }\n return fragment;\n }\n const encoded = encoder(tags);\n return encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n };\n}\n\nexport function fastEventJsonCodec(options: FastEventJsonCodecOptions = {}): Codec<string> {\n const stringify = createStringify(options);\n const safeStringify: JsonStringify = (value) => safeJsonStringify(value, options);\n const useNativeEventJson = canUseNativeEventJson(options);\n const tagsFragment = createTagsFragment(stringify, true);\n // The fallback must not reuse the fast fragments: a cached entry or the\n // fast stringify could throw on the exact payload that triggered fallback.\n const safeTagsFragment = createTagsFragment(safeStringify, false);\n const fastEncode = (input: CodecInput): string => {\n if (isCodecArray(input)) {\n if (useNativeEventJson && !hasLogRecord(input)) return JSON.stringify(input);\n return encodeArray(input, options, stringify, tagsFragment);\n }\n if (useNativeEventJson && !isLogRecord(input)) return JSON.stringify(input);\n return encodeItem(input, options, stringify, tagsFragment);\n };\n return {\n name: \"fast-event-json\",\n contentType: \"application/json\",\n encode(input: CodecInput) {\n // Circular references and BigInt values throw on the native fast path. Logs\n // must never be lost to encoding, so re-encode the input with the safe\n // stringifier instead of surfacing the error as a transport failure.\n try {\n return fastEncode(input);\n } catch {\n incrementLoggerMetaCounter(\"codec.fallback\");\n incrementLoggerMetaCounter(\"codec.fallback.fast-event-json\");\n }\n if (isCodecArray(input)) return encodeArray(input, options, safeStringify, safeTagsFragment);\n return encodeItem(input, options, safeStringify, safeTagsFragment);\n },\n decode(payload) {\n return JSON.parse(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\nimport { Packr, type Options as MsgpackrOptions } from \"msgpackr\";\n\nexport interface MsgpackRuntime {\n pack: (input: unknown) => Uint8Array;\n unpack: (payload: Uint8Array) => unknown;\n}\n\nexport type MsgpackrCodecOptions = MsgpackrOptions;\n\nfunction isMsgpackRuntime(value: MsgpackRuntime | MsgpackrCodecOptions): value is MsgpackRuntime {\n return (\n typeof (value as MsgpackRuntime).pack === \"function\" &&\n typeof (value as MsgpackRuntime).unpack === \"function\"\n );\n}\n\nexport function msgpackrCodec(\n options: MsgpackRuntime | MsgpackrCodecOptions = {},\n): Codec<Uint8Array> {\n const runtime = isMsgpackRuntime(options) ? options : new Packr({ useRecords: true, ...options });\n return {\n name: \"msgpackr\",\n contentType: \"application/msgpack\",\n encode(input: CodecInput) {\n return runtime.pack(normalizeCodecInput(input));\n },\n decode(payload: Uint8Array) {\n return runtime.unpack(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import {\n incrementLoggerMetaCounter,\n normalizeCodecInput,\n safeJsonStringify,\n type Codec,\n type CodecInput,\n type LogEvent,\n type SafeStringifyOptions,\n type SerializedError,\n} from \"@loggerjs/core\";\n\nexport type PinoCompatCollisionPolicy = \"nest\" | \"drop\" | \"throw\";\n\nexport interface PinoCompatCodecOptions extends SafeStringifyOptions {\n base?: Record<string, unknown>;\n dataKey?: string;\n errorKey?: string;\n includeLogger?: boolean;\n mergeData?: boolean;\n collision?: PinoCompatCollisionPolicy;\n}\n\nconst baseReservedRootKeys = new Set([\"time\", \"level\", \"msg\", \"err\", \"logger\", \"data\"]);\nconst dataReservedRootKeys = new Set([\n \"time\",\n \"level\",\n \"msg\",\n \"pid\",\n \"hostname\",\n \"err\",\n \"logger\",\n \"data\",\n]);\n\nfunction hasSafeOptions(options: SafeStringifyOptions): boolean {\n return (\n options.maxDepth !== undefined ||\n options.maxArrayLength !== undefined ||\n options.maxObjectKeys !== undefined ||\n options.includeStack !== undefined ||\n options.stable !== undefined ||\n options.space !== undefined\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction pinoError(error: SerializedError): Record<string, unknown> {\n return {\n type: error.name ?? \"Error\",\n message: error.message,\n stack: error.stack,\n code: error.code,\n cause: error.cause,\n };\n}\n\nfunction assignWithCollision(\n output: Record<string, unknown>,\n nested: Record<string, unknown>,\n key: string,\n value: unknown,\n policy: PinoCompatCollisionPolicy,\n reservedKeys = dataReservedRootKeys,\n) {\n if (!reservedKeys.has(key) && !(key in output)) {\n output[key] = value;\n return;\n }\n\n if (policy === \"throw\") {\n throw new Error(`pinoCompatCodec cannot merge reserved key \"${key}\"`);\n }\n if (policy === \"nest\") nested[key] = value;\n}\n\nfunction mergeNestedData(\n existing: unknown,\n nested: Record<string, unknown>,\n): Record<string, unknown> {\n if (isRecord(existing)) return { ...nested, ...existing };\n if (existing !== undefined) return { ...nested, value: existing };\n return nested;\n}\n\nfunction projectEvent(event: LogEvent, options: PinoCompatCodecOptions): Record<string, unknown> {\n const dataKey = options.dataKey ?? \"data\";\n const errorKey = options.errorKey ?? \"err\";\n const collision = options.collision ?? \"nest\";\n const output: Record<string, unknown> = {\n level: event.level,\n time: event.time,\n };\n const nested: Record<string, unknown> = {};\n\n const baseReservedKeys = new Set(baseReservedRootKeys);\n baseReservedKeys.add(dataKey);\n baseReservedKeys.add(errorKey);\n for (const [key, value] of Object.entries(options.base ?? {})) {\n assignWithCollision(output, nested, key, value, collision, baseReservedKeys);\n }\n\n if (options.includeLogger) output.logger = event.logger;\n if (event.error) output[errorKey] = pinoError(event.error);\n\n if (event.data !== undefined) {\n if (options.mergeData && isRecord(event.data)) {\n const dataReservedKeys = new Set(dataReservedRootKeys);\n dataReservedKeys.add(dataKey);\n dataReservedKeys.add(errorKey);\n for (const [key, value] of Object.entries(event.data)) {\n assignWithCollision(output, nested, key, value, collision, dataReservedKeys);\n }\n } else {\n output[dataKey] = event.data;\n }\n }\n\n if (Object.keys(nested).length > 0) {\n output[dataKey] = mergeNestedData(output[dataKey], nested);\n }\n\n output.msg = event.message;\n\n return output;\n}\n\nfunction encodeLine(event: LogEvent, options: PinoCompatCodecOptions, safeMode: boolean): string {\n const projected = projectEvent(event, options);\n if (safeMode) return safeJsonStringify(projected, options);\n try {\n const encoded = JSON.stringify(projected);\n return encoded ?? \"{}\";\n } catch {\n incrementLoggerMetaCounter(\"codec.fallback\");\n incrementLoggerMetaCounter(\"codec.fallback.pino-compat\");\n return safeJsonStringify(projected, options);\n }\n}\n\nfunction encodeEvents(\n input: LogEvent | LogEvent[],\n options: PinoCompatCodecOptions,\n safeMode: boolean,\n): string {\n if (!Array.isArray(input)) return `${encodeLine(input, options, safeMode)}\\n`;\n let output = \"\";\n for (const event of input) output += `${encodeLine(event, options, safeMode)}\\n`;\n return output;\n}\n\nexport function pinoCompatCodec(options: PinoCompatCodecOptions = {}): Codec<string> {\n const safeMode = hasSafeOptions(options);\n return {\n name: \"pino-compat\",\n contentType: \"application/x-ndjson\",\n encode(input: CodecInput) {\n return encodeEvents(normalizeCodecInput(input), options, safeMode);\n },\n };\n}\n\nexport const pinoNdjsonProjector = pinoCompatCodec;\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\n\nexport interface ProjectorCodecOptions<TWire> {\n name: string;\n contentType: string;\n project: (input: LogEvent | LogEvent[]) => TWire;\n serialize: (wire: TWire) => string | Uint8Array;\n parse?: (payload: string | Uint8Array) => TWire;\n unproject?: (wire: TWire) => LogEvent | LogEvent[];\n}\n\nexport function projectorCodec<TWire>(\n options: ProjectorCodecOptions<TWire>,\n): Codec<string | Uint8Array> {\n return {\n name: options.name,\n contentType: options.contentType,\n encode(input: CodecInput) {\n return options.serialize(options.project(normalizeCodecInput(input)));\n },\n decode:\n options.parse && options.unproject\n ? (payload) => options.unproject!(options.parse!(payload))\n : undefined,\n };\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,17 +2,17 @@ import { defaultRecordId, incrementLoggerMetaCounter, isLogRecord, normalizeCode
|
|
|
2
2
|
import { Packr } from "msgpackr";
|
|
3
3
|
export * from "@loggerjs/core";
|
|
4
4
|
//#region src/fast-event-json.ts
|
|
5
|
-
function hasSafeOptions(options) {
|
|
5
|
+
function hasSafeOptions$1(options) {
|
|
6
6
|
return options.maxDepth !== void 0 || options.maxArrayLength !== void 0 || options.maxObjectKeys !== void 0 || options.includeStack !== void 0 || options.stable !== void 0 || options.space !== void 0;
|
|
7
7
|
}
|
|
8
8
|
function canUseNativeEventJson(options) {
|
|
9
|
-
return !hasSafeOptions(options) && options.includeContext !== false && options.includeData !== false && options.includeError !== false && options.includeTrace !== false && options.includeSource !== false && options.includeId !== false && options.includeSeq !== false && options.includeLevelName !== false;
|
|
9
|
+
return !hasSafeOptions$1(options) && options.includeContext !== false && options.includeData !== false && options.includeError !== false && options.includeTrace !== false && options.includeSource !== false && options.includeId !== false && options.includeSeq !== false && options.includeLevelName !== false;
|
|
10
10
|
}
|
|
11
11
|
function hasFullHeader(options) {
|
|
12
12
|
return (options.includeId ?? true) && (options.includeSeq ?? true) && (options.includeLevelName ?? true);
|
|
13
13
|
}
|
|
14
14
|
function createStringify(options) {
|
|
15
|
-
if (hasSafeOptions(options)) return (value) => safeJsonStringify(value, options);
|
|
15
|
+
if (hasSafeOptions$1(options)) return (value) => safeJsonStringify(value, options);
|
|
16
16
|
return JSON.stringify;
|
|
17
17
|
}
|
|
18
18
|
function appendField(output, name, value, stringify) {
|
|
@@ -226,6 +226,113 @@ function msgpackrCodec(options = {}) {
|
|
|
226
226
|
};
|
|
227
227
|
}
|
|
228
228
|
//#endregion
|
|
229
|
+
//#region src/pino-compat.ts
|
|
230
|
+
const baseReservedRootKeys = new Set([
|
|
231
|
+
"time",
|
|
232
|
+
"level",
|
|
233
|
+
"msg",
|
|
234
|
+
"err",
|
|
235
|
+
"logger",
|
|
236
|
+
"data"
|
|
237
|
+
]);
|
|
238
|
+
const dataReservedRootKeys = new Set([
|
|
239
|
+
"time",
|
|
240
|
+
"level",
|
|
241
|
+
"msg",
|
|
242
|
+
"pid",
|
|
243
|
+
"hostname",
|
|
244
|
+
"err",
|
|
245
|
+
"logger",
|
|
246
|
+
"data"
|
|
247
|
+
]);
|
|
248
|
+
function hasSafeOptions(options) {
|
|
249
|
+
return options.maxDepth !== void 0 || options.maxArrayLength !== void 0 || options.maxObjectKeys !== void 0 || options.includeStack !== void 0 || options.stable !== void 0 || options.space !== void 0;
|
|
250
|
+
}
|
|
251
|
+
function isRecord(value) {
|
|
252
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
253
|
+
}
|
|
254
|
+
function pinoError(error) {
|
|
255
|
+
return {
|
|
256
|
+
type: error.name ?? "Error",
|
|
257
|
+
message: error.message,
|
|
258
|
+
stack: error.stack,
|
|
259
|
+
code: error.code,
|
|
260
|
+
cause: error.cause
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function assignWithCollision(output, nested, key, value, policy, reservedKeys = dataReservedRootKeys) {
|
|
264
|
+
if (!reservedKeys.has(key) && !(key in output)) {
|
|
265
|
+
output[key] = value;
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (policy === "throw") throw new Error(`pinoCompatCodec cannot merge reserved key "${key}"`);
|
|
269
|
+
if (policy === "nest") nested[key] = value;
|
|
270
|
+
}
|
|
271
|
+
function mergeNestedData(existing, nested) {
|
|
272
|
+
if (isRecord(existing)) return {
|
|
273
|
+
...nested,
|
|
274
|
+
...existing
|
|
275
|
+
};
|
|
276
|
+
if (existing !== void 0) return {
|
|
277
|
+
...nested,
|
|
278
|
+
value: existing
|
|
279
|
+
};
|
|
280
|
+
return nested;
|
|
281
|
+
}
|
|
282
|
+
function projectEvent(event, options) {
|
|
283
|
+
const dataKey = options.dataKey ?? "data";
|
|
284
|
+
const errorKey = options.errorKey ?? "err";
|
|
285
|
+
const collision = options.collision ?? "nest";
|
|
286
|
+
const output = {
|
|
287
|
+
level: event.level,
|
|
288
|
+
time: event.time
|
|
289
|
+
};
|
|
290
|
+
const nested = {};
|
|
291
|
+
const baseReservedKeys = new Set(baseReservedRootKeys);
|
|
292
|
+
baseReservedKeys.add(dataKey);
|
|
293
|
+
baseReservedKeys.add(errorKey);
|
|
294
|
+
for (const [key, value] of Object.entries(options.base ?? {})) assignWithCollision(output, nested, key, value, collision, baseReservedKeys);
|
|
295
|
+
if (options.includeLogger) output.logger = event.logger;
|
|
296
|
+
if (event.error) output[errorKey] = pinoError(event.error);
|
|
297
|
+
if (event.data !== void 0) if (options.mergeData && isRecord(event.data)) {
|
|
298
|
+
const dataReservedKeys = new Set(dataReservedRootKeys);
|
|
299
|
+
dataReservedKeys.add(dataKey);
|
|
300
|
+
dataReservedKeys.add(errorKey);
|
|
301
|
+
for (const [key, value] of Object.entries(event.data)) assignWithCollision(output, nested, key, value, collision, dataReservedKeys);
|
|
302
|
+
} else output[dataKey] = event.data;
|
|
303
|
+
if (Object.keys(nested).length > 0) output[dataKey] = mergeNestedData(output[dataKey], nested);
|
|
304
|
+
output.msg = event.message;
|
|
305
|
+
return output;
|
|
306
|
+
}
|
|
307
|
+
function encodeLine(event, options, safeMode) {
|
|
308
|
+
const projected = projectEvent(event, options);
|
|
309
|
+
if (safeMode) return safeJsonStringify(projected, options);
|
|
310
|
+
try {
|
|
311
|
+
return JSON.stringify(projected) ?? "{}";
|
|
312
|
+
} catch {
|
|
313
|
+
incrementLoggerMetaCounter("codec.fallback");
|
|
314
|
+
incrementLoggerMetaCounter("codec.fallback.pino-compat");
|
|
315
|
+
return safeJsonStringify(projected, options);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function encodeEvents(input, options, safeMode) {
|
|
319
|
+
if (!Array.isArray(input)) return `${encodeLine(input, options, safeMode)}\n`;
|
|
320
|
+
let output = "";
|
|
321
|
+
for (const event of input) output += `${encodeLine(event, options, safeMode)}\n`;
|
|
322
|
+
return output;
|
|
323
|
+
}
|
|
324
|
+
function pinoCompatCodec(options = {}) {
|
|
325
|
+
const safeMode = hasSafeOptions(options);
|
|
326
|
+
return {
|
|
327
|
+
name: "pino-compat",
|
|
328
|
+
contentType: "application/x-ndjson",
|
|
329
|
+
encode(input) {
|
|
330
|
+
return encodeEvents(normalizeCodecInput(input), options, safeMode);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
const pinoNdjsonProjector = pinoCompatCodec;
|
|
335
|
+
//#endregion
|
|
229
336
|
//#region src/projector.ts
|
|
230
337
|
function projectorCodec(options) {
|
|
231
338
|
return {
|
|
@@ -238,6 +345,6 @@ function projectorCodec(options) {
|
|
|
238
345
|
};
|
|
239
346
|
}
|
|
240
347
|
//#endregion
|
|
241
|
-
export { fastEventJsonCodec, msgpackrCodec, projectorCodec };
|
|
348
|
+
export { fastEventJsonCodec, msgpackrCodec, pinoCompatCodec, pinoNdjsonProjector, projectorCodec };
|
|
242
349
|
|
|
243
350
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/fast-event-json.ts","../src/msgpackr.ts","../src/projector.ts"],"sourcesContent":["import {\n defaultRecordId,\n incrementLoggerMetaCounter,\n isLogRecord,\n normalizeError,\n resolveMessage,\n toLevelName,\n safeJsonStringify,\n type Codec,\n type CodecInput,\n type LogEvent,\n type LogRecord,\n type SafeStringifyOptions,\n} from \"@loggerjs/core\";\n\n/**\n * Without any option set, encode runs on a native `JSON.stringify` fast path: nested\n * `Error` values serialize as `{}` and circular or BigInt payloads trigger a safe\n * re-encode of the whole input (circular refs become \"[Circular]\", BigInt becomes a\n * string). Setting any {@link SafeStringifyOptions} field opts into the safe encoder\n * everywhere, which also preserves `Error` name/message/stack inside data payloads.\n *\n * `includeId`, `includeSeq`, and `includeLevelName` trim the envelope for\n * pino-shaped minimal NDJSON output; turning `includeId` off also skips id\n * computation entirely on the record path.\n */\nexport interface FastEventJsonCodecOptions extends SafeStringifyOptions {\n includeContext?: boolean;\n includeData?: boolean;\n includeError?: boolean;\n includeTrace?: boolean;\n includeSource?: boolean;\n includeId?: boolean;\n includeSeq?: boolean;\n includeLevelName?: boolean;\n}\n\ntype JsonStringify = (value: unknown) => string | undefined;\n\nfunction hasSafeOptions(options: SafeStringifyOptions): boolean {\n return (\n options.maxDepth !== undefined ||\n options.maxArrayLength !== undefined ||\n options.maxObjectKeys !== undefined ||\n options.includeStack !== undefined ||\n options.stable !== undefined ||\n options.space !== undefined\n );\n}\n\nfunction canUseNativeEventJson(options: FastEventJsonCodecOptions): boolean {\n return (\n !hasSafeOptions(options) &&\n options.includeContext !== false &&\n options.includeData !== false &&\n options.includeError !== false &&\n options.includeTrace !== false &&\n options.includeSource !== false &&\n options.includeId !== false &&\n options.includeSeq !== false &&\n options.includeLevelName !== false\n );\n}\n\nfunction hasFullHeader(options: FastEventJsonCodecOptions): boolean {\n return (\n (options.includeId ?? true) &&\n (options.includeSeq ?? true) &&\n (options.includeLevelName ?? true)\n );\n}\n\nfunction createStringify(options: SafeStringifyOptions): JsonStringify {\n if (hasSafeOptions(options)) return (value) => safeJsonStringify(value, options);\n return JSON.stringify;\n}\n\nfunction appendField(\n output: string,\n name: string,\n value: unknown,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const encoded = stringify(value);\n return encoded === undefined ? output : `${output},\"${name}\":${encoded}`;\n}\n\n// JSON.stringify costs ~35ns per short string mostly in call overhead. Short\n// strings without quotes, backslashes, or control characters can be quoted\n// directly after a linear scan.\nfunction asJsonString(value: string): string {\n if (value.length > 256) return JSON.stringify(value);\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code === 34 || code === 92 || code < 32) return JSON.stringify(value);\n }\n return `\"${value}\"`;\n}\n\n// Data payloads are usually small flat objects of primitives. Writing them\n// directly skips the native JSON.stringify call overhead; any nested or\n// exotic value bails out so the caller can use the configured stringifier.\nfunction tryFlatObjectJson(value: Record<string, unknown>): string | undefined {\n // Class instances may carry toJSON or accessors; only plain objects take\n // the fast path so behavior matches JSON.stringify.\n const proto = Object.getPrototypeOf(value) as unknown;\n if (proto !== Object.prototype && proto !== null) return undefined;\n let output = \"{\";\n let first = true;\n for (const key of Object.keys(value)) {\n const item = value[key];\n let encoded: string;\n switch (typeof item) {\n case \"string\":\n encoded = asJsonString(item);\n break;\n case \"number\":\n encoded = Number.isFinite(item) ? String(item) : \"null\";\n break;\n case \"boolean\":\n encoded = item ? \"true\" : \"false\";\n break;\n case \"object\":\n if (item !== null) return undefined;\n encoded = \"null\";\n break;\n case \"undefined\":\n continue;\n default:\n return undefined;\n }\n output += `${first ? \"\" : \",\"}${asJsonString(key)}:${encoded}`;\n first = false;\n }\n return `${output}}`;\n}\n\nfunction appendDataField(\n output: string,\n value: Record<string, unknown> | undefined,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const flat = tryFlatObjectJson(value);\n if (flat !== undefined) return `${output},\"data\":${flat}`;\n return appendField(output, \"data\", value, stringify);\n}\n\n// The timestamp changes once per millisecond while bursts of records share\n// it, so the rendered `\",\"time\":...,\"seq\":` fragment can be memoized the same\n// way the default id memoizes its time segment.\nlet lastFragmentTime = -1;\nlet lastTimeFragment = \"\";\n\nfunction timeFragment(time: number): string {\n if (time !== lastFragmentTime) {\n lastFragmentTime = time;\n lastTimeFragment = `\",\"time\":${time},\"seq\":`;\n }\n return lastTimeFragment;\n}\n\n// level -> ',\"level\":30,\"levelName\":\"info\",\"logger\":' — derived from the\n// numeric level alone, so a module-level cache is safe.\nconst levelFragments = new Map<number, string>();\n\nfunction levelFragment(level: number): string {\n let fragment = levelFragments.get(level);\n if (fragment === undefined) {\n fragment = `,\"level\":${level},\"levelName\":\"${toLevelName(level)}\",\"logger\":`;\n levelFragments.set(level, fragment);\n }\n return fragment;\n}\n\n// Loggers reuse one frozen category array for every record, so the joined and\n// escaped logger name can be cached per array identity.\nconst categoryFragments = new WeakMap<readonly string[], string>();\n\nfunction loggerFragment(category: readonly string[]): string {\n let fragment = categoryFragments.get(category);\n if (fragment === undefined) {\n fragment = asJsonString(category.join(\".\"));\n categoryFragments.set(category, fragment);\n }\n return fragment;\n}\n\nfunction errorForRecord(record: LogRecord): LogEvent[\"error\"] | undefined {\n if (record.err === null || record.err === undefined) return undefined;\n return normalizeError(record.err);\n}\n\nfunction encodeEvent(\n event: LogEvent,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogEvent[\"tags\"]>) => string,\n): string {\n let output: string;\n if (hasFullHeader(options)) {\n output = `{\"id\":${asJsonString(event.id)},\"time\":${event.time},\"seq\":${event.seq},\"level\":${event.level},\"levelName\":${asJsonString(event.levelName)},\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":${asJsonString(event.id)},`;\n output += `\"time\":${event.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${event.seq}`;\n output += `,\"level\":${event.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":${asJsonString(event.levelName)}`;\n output += `,\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n }\n if (event.type !== undefined) output += `,\"type\":${asJsonString(event.type)}`;\n if (event.tags !== undefined) output += tagsFragment(event.tags);\n if (options.includeData ?? true) output = appendField(output, \"data\", event.data, stringify);\n if (options.includeError ?? true) output = appendField(output, \"error\", event.error, stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", event.context, stringify);\n if (options.includeTrace ?? true) output = appendField(output, \"trace\", event.trace, stringify);\n if (options.includeSource ?? true)\n output = appendField(output, \"source\", event.source, stringify);\n return `${output}}`;\n}\n\nfunction encodeRecord(\n record: LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogRecord[\"tags\"]>) => string,\n): string {\n const levelName = toLevelName(record.level);\n let output: string;\n if (hasFullHeader(options)) {\n // The default id only contains [0-9a-z-] and the level name, so it never\n // needs escaping.\n output = `{\"id\":\"${defaultRecordId(record, levelName)}${timeFragment(record.time)}${record.seq}${levelFragment(record.level)}${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":\"${defaultRecordId(record, levelName)}\",`;\n output += `\"time\":${record.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${record.seq}`;\n output += `,\"level\":${record.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":\"${levelName}\"`;\n output += `,\"logger\":${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n }\n if (record.type !== null) output += `,\"type\":${asJsonString(record.type)}`;\n if (record.tags !== null) output += tagsFragment(record.tags);\n if (options.includeData ?? true)\n output = appendDataField(output, record.props ?? undefined, stringify);\n if (options.includeError ?? true)\n output = appendField(output, \"error\", errorForRecord(record), stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", record.ctx ?? undefined, stringify);\n if (options.includeTrace ?? true)\n output = appendField(output, \"trace\", record.trace ?? undefined, stringify);\n if ((options.includeSource ?? true) && record.source !== \"app\")\n output += `,\"source\":{\"integration\":${asJsonString(record.source)}}`;\n return `${output}}`;\n}\n\ntype TagsFragment = (tags: NonNullable<LogEvent[\"tags\"]>) => string;\n\nfunction encodeItem(\n item: LogEvent | LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n return isLogRecord(item)\n ? encodeRecord(item, options, stringify, tagsFragment)\n : encodeEvent(item, options, stringify, tagsFragment);\n}\n\nfunction encodeArray(\n items: readonly (LogEvent | LogRecord)[],\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n let output = \"[\";\n for (let index = 0; index < items.length; index += 1) {\n if (index > 0) output += \",\";\n output += encodeItem(items[index]!, options, stringify, tagsFragment);\n }\n return `${output}]`;\n}\n\nfunction isCodecArray(input: CodecInput): input is readonly (LogEvent | LogRecord)[] {\n return Array.isArray(input);\n}\n\nfunction hasLogRecord(items: readonly (LogEvent | LogRecord)[]): boolean {\n for (const item of items) {\n if (isLogRecord(item)) return true;\n }\n return false;\n}\n\n// Loggers share one frozen tags object across records, so the encoded\n// fragment can be cached per object identity. Mutable tags objects are\n// re-encoded every time. Callers create one fragment encoder per codec\n// because it bakes in that codec's stringify options.\nfunction createTagsFragment(encoder: JsonStringify, cached: boolean): TagsFragment {\n const fragments = cached ? new WeakMap<object, string>() : undefined;\n return (tags) => {\n if (fragments && Object.isFrozen(tags)) {\n let fragment = fragments.get(tags);\n if (fragment === undefined) {\n const encoded = encoder(tags);\n fragment = encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n fragments.set(tags, fragment);\n }\n return fragment;\n }\n const encoded = encoder(tags);\n return encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n };\n}\n\nexport function fastEventJsonCodec(options: FastEventJsonCodecOptions = {}): Codec<string> {\n const stringify = createStringify(options);\n const safeStringify: JsonStringify = (value) => safeJsonStringify(value, options);\n const useNativeEventJson = canUseNativeEventJson(options);\n const tagsFragment = createTagsFragment(stringify, true);\n // The fallback must not reuse the fast fragments: a cached entry or the\n // fast stringify could throw on the exact payload that triggered fallback.\n const safeTagsFragment = createTagsFragment(safeStringify, false);\n const fastEncode = (input: CodecInput): string => {\n if (isCodecArray(input)) {\n if (useNativeEventJson && !hasLogRecord(input)) return JSON.stringify(input);\n return encodeArray(input, options, stringify, tagsFragment);\n }\n if (useNativeEventJson && !isLogRecord(input)) return JSON.stringify(input);\n return encodeItem(input, options, stringify, tagsFragment);\n };\n return {\n name: \"fast-event-json\",\n contentType: \"application/json\",\n encode(input: CodecInput) {\n // Circular references and BigInt values throw on the native fast path. Logs\n // must never be lost to encoding, so re-encode the input with the safe\n // stringifier instead of surfacing the error as a transport failure.\n try {\n return fastEncode(input);\n } catch {\n incrementLoggerMetaCounter(\"codec.fallback\");\n incrementLoggerMetaCounter(\"codec.fallback.fast-event-json\");\n }\n if (isCodecArray(input)) return encodeArray(input, options, safeStringify, safeTagsFragment);\n return encodeItem(input, options, safeStringify, safeTagsFragment);\n },\n decode(payload) {\n return JSON.parse(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\nimport { Packr, type Options as MsgpackrOptions } from \"msgpackr\";\n\nexport interface MsgpackRuntime {\n pack: (input: unknown) => Uint8Array;\n unpack: (payload: Uint8Array) => unknown;\n}\n\nexport type MsgpackrCodecOptions = MsgpackrOptions;\n\nfunction isMsgpackRuntime(value: MsgpackRuntime | MsgpackrCodecOptions): value is MsgpackRuntime {\n return (\n typeof (value as MsgpackRuntime).pack === \"function\" &&\n typeof (value as MsgpackRuntime).unpack === \"function\"\n );\n}\n\nexport function msgpackrCodec(\n options: MsgpackRuntime | MsgpackrCodecOptions = {},\n): Codec<Uint8Array> {\n const runtime = isMsgpackRuntime(options) ? options : new Packr({ useRecords: true, ...options });\n return {\n name: \"msgpackr\",\n contentType: \"application/msgpack\",\n encode(input: CodecInput) {\n return runtime.pack(normalizeCodecInput(input));\n },\n decode(payload: Uint8Array) {\n return runtime.unpack(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\n\nexport interface ProjectorCodecOptions<TWire> {\n name: string;\n contentType: string;\n project: (input: LogEvent | LogEvent[]) => TWire;\n serialize: (wire: TWire) => string | Uint8Array;\n parse?: (payload: string | Uint8Array) => TWire;\n unproject?: (wire: TWire) => LogEvent | LogEvent[];\n}\n\nexport function projectorCodec<TWire>(\n options: ProjectorCodecOptions<TWire>,\n): Codec<string | Uint8Array> {\n return {\n name: options.name,\n contentType: options.contentType,\n encode(input: CodecInput) {\n return options.serialize(options.project(normalizeCodecInput(input)));\n },\n decode:\n options.parse && options.unproject\n ? (payload) => options.unproject!(options.parse!(payload))\n : undefined,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["hasSafeOptions"],"sources":["../src/fast-event-json.ts","../src/msgpackr.ts","../src/pino-compat.ts","../src/projector.ts"],"sourcesContent":["import {\n defaultRecordId,\n incrementLoggerMetaCounter,\n isLogRecord,\n normalizeError,\n resolveMessage,\n toLevelName,\n safeJsonStringify,\n type Codec,\n type CodecInput,\n type LogEvent,\n type LogRecord,\n type SafeStringifyOptions,\n} from \"@loggerjs/core\";\n\n/**\n * Without any option set, encode runs on a native `JSON.stringify` fast path: nested\n * `Error` values serialize as `{}` and circular or BigInt payloads trigger a safe\n * re-encode of the whole input (circular refs become \"[Circular]\", BigInt becomes a\n * string). Setting any {@link SafeStringifyOptions} field opts into the safe encoder\n * everywhere, which also preserves `Error` name/message/stack inside data payloads.\n *\n * `includeId`, `includeSeq`, and `includeLevelName` trim the envelope for\n * lean comparable JSON output; turning `includeId` off also skips id\n * computation entirely on the record path.\n */\nexport interface FastEventJsonCodecOptions extends SafeStringifyOptions {\n includeContext?: boolean;\n includeData?: boolean;\n includeError?: boolean;\n includeTrace?: boolean;\n includeSource?: boolean;\n includeId?: boolean;\n includeSeq?: boolean;\n includeLevelName?: boolean;\n}\n\ntype JsonStringify = (value: unknown) => string | undefined;\n\nfunction hasSafeOptions(options: SafeStringifyOptions): boolean {\n return (\n options.maxDepth !== undefined ||\n options.maxArrayLength !== undefined ||\n options.maxObjectKeys !== undefined ||\n options.includeStack !== undefined ||\n options.stable !== undefined ||\n options.space !== undefined\n );\n}\n\nfunction canUseNativeEventJson(options: FastEventJsonCodecOptions): boolean {\n return (\n !hasSafeOptions(options) &&\n options.includeContext !== false &&\n options.includeData !== false &&\n options.includeError !== false &&\n options.includeTrace !== false &&\n options.includeSource !== false &&\n options.includeId !== false &&\n options.includeSeq !== false &&\n options.includeLevelName !== false\n );\n}\n\nfunction hasFullHeader(options: FastEventJsonCodecOptions): boolean {\n return (\n (options.includeId ?? true) &&\n (options.includeSeq ?? true) &&\n (options.includeLevelName ?? true)\n );\n}\n\nfunction createStringify(options: SafeStringifyOptions): JsonStringify {\n if (hasSafeOptions(options)) return (value) => safeJsonStringify(value, options);\n return JSON.stringify;\n}\n\nfunction appendField(\n output: string,\n name: string,\n value: unknown,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const encoded = stringify(value);\n return encoded === undefined ? output : `${output},\"${name}\":${encoded}`;\n}\n\n// JSON.stringify costs ~35ns per short string mostly in call overhead. Short\n// strings without quotes, backslashes, or control characters can be quoted\n// directly after a linear scan.\nfunction asJsonString(value: string): string {\n if (value.length > 256) return JSON.stringify(value);\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code === 34 || code === 92 || code < 32) return JSON.stringify(value);\n }\n return `\"${value}\"`;\n}\n\n// Data payloads are usually small flat objects of primitives. Writing them\n// directly skips the native JSON.stringify call overhead; any nested or\n// exotic value bails out so the caller can use the configured stringifier.\nfunction tryFlatObjectJson(value: Record<string, unknown>): string | undefined {\n // Class instances may carry toJSON or accessors; only plain objects take\n // the fast path so behavior matches JSON.stringify.\n const proto = Object.getPrototypeOf(value) as unknown;\n if (proto !== Object.prototype && proto !== null) return undefined;\n let output = \"{\";\n let first = true;\n for (const key of Object.keys(value)) {\n const item = value[key];\n let encoded: string;\n switch (typeof item) {\n case \"string\":\n encoded = asJsonString(item);\n break;\n case \"number\":\n encoded = Number.isFinite(item) ? String(item) : \"null\";\n break;\n case \"boolean\":\n encoded = item ? \"true\" : \"false\";\n break;\n case \"object\":\n if (item !== null) return undefined;\n encoded = \"null\";\n break;\n case \"undefined\":\n continue;\n default:\n return undefined;\n }\n output += `${first ? \"\" : \",\"}${asJsonString(key)}:${encoded}`;\n first = false;\n }\n return `${output}}`;\n}\n\nfunction appendDataField(\n output: string,\n value: Record<string, unknown> | undefined,\n stringify: JsonStringify,\n): string {\n if (value === undefined) return output;\n const flat = tryFlatObjectJson(value);\n if (flat !== undefined) return `${output},\"data\":${flat}`;\n return appendField(output, \"data\", value, stringify);\n}\n\n// The timestamp changes once per millisecond while bursts of records share\n// it, so the rendered `\",\"time\":...,\"seq\":` fragment can be memoized the same\n// way the default id memoizes its time segment.\nlet lastFragmentTime = -1;\nlet lastTimeFragment = \"\";\n\nfunction timeFragment(time: number): string {\n if (time !== lastFragmentTime) {\n lastFragmentTime = time;\n lastTimeFragment = `\",\"time\":${time},\"seq\":`;\n }\n return lastTimeFragment;\n}\n\n// level -> ',\"level\":30,\"levelName\":\"info\",\"logger\":' — derived from the\n// numeric level alone, so a module-level cache is safe.\nconst levelFragments = new Map<number, string>();\n\nfunction levelFragment(level: number): string {\n let fragment = levelFragments.get(level);\n if (fragment === undefined) {\n fragment = `,\"level\":${level},\"levelName\":\"${toLevelName(level)}\",\"logger\":`;\n levelFragments.set(level, fragment);\n }\n return fragment;\n}\n\n// Loggers reuse one frozen category array for every record, so the joined and\n// escaped logger name can be cached per array identity.\nconst categoryFragments = new WeakMap<readonly string[], string>();\n\nfunction loggerFragment(category: readonly string[]): string {\n let fragment = categoryFragments.get(category);\n if (fragment === undefined) {\n fragment = asJsonString(category.join(\".\"));\n categoryFragments.set(category, fragment);\n }\n return fragment;\n}\n\nfunction errorForRecord(record: LogRecord): LogEvent[\"error\"] | undefined {\n if (record.err === null || record.err === undefined) return undefined;\n return normalizeError(record.err);\n}\n\nfunction encodeEvent(\n event: LogEvent,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogEvent[\"tags\"]>) => string,\n): string {\n let output: string;\n if (hasFullHeader(options)) {\n output = `{\"id\":${asJsonString(event.id)},\"time\":${event.time},\"seq\":${event.seq},\"level\":${event.level},\"levelName\":${asJsonString(event.levelName)},\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":${asJsonString(event.id)},`;\n output += `\"time\":${event.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${event.seq}`;\n output += `,\"level\":${event.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":${asJsonString(event.levelName)}`;\n output += `,\"logger\":${asJsonString(event.logger)},\"message\":${asJsonString(event.message)}`;\n }\n if (event.type !== undefined) output += `,\"type\":${asJsonString(event.type)}`;\n if (event.tags !== undefined) output += tagsFragment(event.tags);\n if (options.includeData ?? true) output = appendField(output, \"data\", event.data, stringify);\n if (options.includeError ?? true) output = appendField(output, \"error\", event.error, stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", event.context, stringify);\n if (options.includeTrace ?? true) output = appendField(output, \"trace\", event.trace, stringify);\n if (options.includeSource ?? true)\n output = appendField(output, \"source\", event.source, stringify);\n return `${output}}`;\n}\n\nfunction encodeRecord(\n record: LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: (tags: NonNullable<LogRecord[\"tags\"]>) => string,\n): string {\n const levelName = toLevelName(record.level);\n let output: string;\n if (hasFullHeader(options)) {\n // The default id only contains [0-9a-z-] and the level name, so it never\n // needs escaping.\n output = `{\"id\":\"${defaultRecordId(record, levelName)}${timeFragment(record.time)}${record.seq}${levelFragment(record.level)}${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n } else {\n output = \"{\";\n if (options.includeId ?? true) output += `\"id\":\"${defaultRecordId(record, levelName)}\",`;\n output += `\"time\":${record.time}`;\n if (options.includeSeq ?? true) output += `,\"seq\":${record.seq}`;\n output += `,\"level\":${record.level}`;\n if (options.includeLevelName ?? true) output += `,\"levelName\":\"${levelName}\"`;\n output += `,\"logger\":${loggerFragment(record.category)},\"message\":${asJsonString(resolveMessage(record))}`;\n }\n if (record.type !== null) output += `,\"type\":${asJsonString(record.type)}`;\n if (record.tags !== null) output += tagsFragment(record.tags);\n if (options.includeData ?? true)\n output = appendDataField(output, record.props ?? undefined, stringify);\n if (options.includeError ?? true)\n output = appendField(output, \"error\", errorForRecord(record), stringify);\n if (options.includeContext ?? true)\n output = appendField(output, \"context\", record.ctx ?? undefined, stringify);\n if (options.includeTrace ?? true)\n output = appendField(output, \"trace\", record.trace ?? undefined, stringify);\n if ((options.includeSource ?? true) && record.source !== \"app\")\n output += `,\"source\":{\"integration\":${asJsonString(record.source)}}`;\n return `${output}}`;\n}\n\ntype TagsFragment = (tags: NonNullable<LogEvent[\"tags\"]>) => string;\n\nfunction encodeItem(\n item: LogEvent | LogRecord,\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n return isLogRecord(item)\n ? encodeRecord(item, options, stringify, tagsFragment)\n : encodeEvent(item, options, stringify, tagsFragment);\n}\n\nfunction encodeArray(\n items: readonly (LogEvent | LogRecord)[],\n options: FastEventJsonCodecOptions,\n stringify: JsonStringify,\n tagsFragment: TagsFragment,\n): string {\n let output = \"[\";\n for (let index = 0; index < items.length; index += 1) {\n if (index > 0) output += \",\";\n output += encodeItem(items[index]!, options, stringify, tagsFragment);\n }\n return `${output}]`;\n}\n\nfunction isCodecArray(input: CodecInput): input is readonly (LogEvent | LogRecord)[] {\n return Array.isArray(input);\n}\n\nfunction hasLogRecord(items: readonly (LogEvent | LogRecord)[]): boolean {\n for (const item of items) {\n if (isLogRecord(item)) return true;\n }\n return false;\n}\n\n// Loggers share one frozen tags object across records, so the encoded\n// fragment can be cached per object identity. Mutable tags objects are\n// re-encoded every time. Callers create one fragment encoder per codec\n// because it bakes in that codec's stringify options.\nfunction createTagsFragment(encoder: JsonStringify, cached: boolean): TagsFragment {\n const fragments = cached ? new WeakMap<object, string>() : undefined;\n return (tags) => {\n if (fragments && Object.isFrozen(tags)) {\n let fragment = fragments.get(tags);\n if (fragment === undefined) {\n const encoded = encoder(tags);\n fragment = encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n fragments.set(tags, fragment);\n }\n return fragment;\n }\n const encoded = encoder(tags);\n return encoded === undefined ? \"\" : `,\"tags\":${encoded}`;\n };\n}\n\nexport function fastEventJsonCodec(options: FastEventJsonCodecOptions = {}): Codec<string> {\n const stringify = createStringify(options);\n const safeStringify: JsonStringify = (value) => safeJsonStringify(value, options);\n const useNativeEventJson = canUseNativeEventJson(options);\n const tagsFragment = createTagsFragment(stringify, true);\n // The fallback must not reuse the fast fragments: a cached entry or the\n // fast stringify could throw on the exact payload that triggered fallback.\n const safeTagsFragment = createTagsFragment(safeStringify, false);\n const fastEncode = (input: CodecInput): string => {\n if (isCodecArray(input)) {\n if (useNativeEventJson && !hasLogRecord(input)) return JSON.stringify(input);\n return encodeArray(input, options, stringify, tagsFragment);\n }\n if (useNativeEventJson && !isLogRecord(input)) return JSON.stringify(input);\n return encodeItem(input, options, stringify, tagsFragment);\n };\n return {\n name: \"fast-event-json\",\n contentType: \"application/json\",\n encode(input: CodecInput) {\n // Circular references and BigInt values throw on the native fast path. Logs\n // must never be lost to encoding, so re-encode the input with the safe\n // stringifier instead of surfacing the error as a transport failure.\n try {\n return fastEncode(input);\n } catch {\n incrementLoggerMetaCounter(\"codec.fallback\");\n incrementLoggerMetaCounter(\"codec.fallback.fast-event-json\");\n }\n if (isCodecArray(input)) return encodeArray(input, options, safeStringify, safeTagsFragment);\n return encodeItem(input, options, safeStringify, safeTagsFragment);\n },\n decode(payload) {\n return JSON.parse(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\nimport { Packr, type Options as MsgpackrOptions } from \"msgpackr\";\n\nexport interface MsgpackRuntime {\n pack: (input: unknown) => Uint8Array;\n unpack: (payload: Uint8Array) => unknown;\n}\n\nexport type MsgpackrCodecOptions = MsgpackrOptions;\n\nfunction isMsgpackRuntime(value: MsgpackRuntime | MsgpackrCodecOptions): value is MsgpackRuntime {\n return (\n typeof (value as MsgpackRuntime).pack === \"function\" &&\n typeof (value as MsgpackRuntime).unpack === \"function\"\n );\n}\n\nexport function msgpackrCodec(\n options: MsgpackRuntime | MsgpackrCodecOptions = {},\n): Codec<Uint8Array> {\n const runtime = isMsgpackRuntime(options) ? options : new Packr({ useRecords: true, ...options });\n return {\n name: \"msgpackr\",\n contentType: \"application/msgpack\",\n encode(input: CodecInput) {\n return runtime.pack(normalizeCodecInput(input));\n },\n decode(payload: Uint8Array) {\n return runtime.unpack(payload) as LogEvent | LogEvent[];\n },\n };\n}\n","import {\n incrementLoggerMetaCounter,\n normalizeCodecInput,\n safeJsonStringify,\n type Codec,\n type CodecInput,\n type LogEvent,\n type SafeStringifyOptions,\n type SerializedError,\n} from \"@loggerjs/core\";\n\nexport type PinoCompatCollisionPolicy = \"nest\" | \"drop\" | \"throw\";\n\nexport interface PinoCompatCodecOptions extends SafeStringifyOptions {\n base?: Record<string, unknown>;\n dataKey?: string;\n errorKey?: string;\n includeLogger?: boolean;\n mergeData?: boolean;\n collision?: PinoCompatCollisionPolicy;\n}\n\nconst baseReservedRootKeys = new Set([\"time\", \"level\", \"msg\", \"err\", \"logger\", \"data\"]);\nconst dataReservedRootKeys = new Set([\n \"time\",\n \"level\",\n \"msg\",\n \"pid\",\n \"hostname\",\n \"err\",\n \"logger\",\n \"data\",\n]);\n\nfunction hasSafeOptions(options: SafeStringifyOptions): boolean {\n return (\n options.maxDepth !== undefined ||\n options.maxArrayLength !== undefined ||\n options.maxObjectKeys !== undefined ||\n options.includeStack !== undefined ||\n options.stable !== undefined ||\n options.space !== undefined\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction pinoError(error: SerializedError): Record<string, unknown> {\n return {\n type: error.name ?? \"Error\",\n message: error.message,\n stack: error.stack,\n code: error.code,\n cause: error.cause,\n };\n}\n\nfunction assignWithCollision(\n output: Record<string, unknown>,\n nested: Record<string, unknown>,\n key: string,\n value: unknown,\n policy: PinoCompatCollisionPolicy,\n reservedKeys = dataReservedRootKeys,\n) {\n if (!reservedKeys.has(key) && !(key in output)) {\n output[key] = value;\n return;\n }\n\n if (policy === \"throw\") {\n throw new Error(`pinoCompatCodec cannot merge reserved key \"${key}\"`);\n }\n if (policy === \"nest\") nested[key] = value;\n}\n\nfunction mergeNestedData(\n existing: unknown,\n nested: Record<string, unknown>,\n): Record<string, unknown> {\n if (isRecord(existing)) return { ...nested, ...existing };\n if (existing !== undefined) return { ...nested, value: existing };\n return nested;\n}\n\nfunction projectEvent(event: LogEvent, options: PinoCompatCodecOptions): Record<string, unknown> {\n const dataKey = options.dataKey ?? \"data\";\n const errorKey = options.errorKey ?? \"err\";\n const collision = options.collision ?? \"nest\";\n const output: Record<string, unknown> = {\n level: event.level,\n time: event.time,\n };\n const nested: Record<string, unknown> = {};\n\n const baseReservedKeys = new Set(baseReservedRootKeys);\n baseReservedKeys.add(dataKey);\n baseReservedKeys.add(errorKey);\n for (const [key, value] of Object.entries(options.base ?? {})) {\n assignWithCollision(output, nested, key, value, collision, baseReservedKeys);\n }\n\n if (options.includeLogger) output.logger = event.logger;\n if (event.error) output[errorKey] = pinoError(event.error);\n\n if (event.data !== undefined) {\n if (options.mergeData && isRecord(event.data)) {\n const dataReservedKeys = new Set(dataReservedRootKeys);\n dataReservedKeys.add(dataKey);\n dataReservedKeys.add(errorKey);\n for (const [key, value] of Object.entries(event.data)) {\n assignWithCollision(output, nested, key, value, collision, dataReservedKeys);\n }\n } else {\n output[dataKey] = event.data;\n }\n }\n\n if (Object.keys(nested).length > 0) {\n output[dataKey] = mergeNestedData(output[dataKey], nested);\n }\n\n output.msg = event.message;\n\n return output;\n}\n\nfunction encodeLine(event: LogEvent, options: PinoCompatCodecOptions, safeMode: boolean): string {\n const projected = projectEvent(event, options);\n if (safeMode) return safeJsonStringify(projected, options);\n try {\n const encoded = JSON.stringify(projected);\n return encoded ?? \"{}\";\n } catch {\n incrementLoggerMetaCounter(\"codec.fallback\");\n incrementLoggerMetaCounter(\"codec.fallback.pino-compat\");\n return safeJsonStringify(projected, options);\n }\n}\n\nfunction encodeEvents(\n input: LogEvent | LogEvent[],\n options: PinoCompatCodecOptions,\n safeMode: boolean,\n): string {\n if (!Array.isArray(input)) return `${encodeLine(input, options, safeMode)}\\n`;\n let output = \"\";\n for (const event of input) output += `${encodeLine(event, options, safeMode)}\\n`;\n return output;\n}\n\nexport function pinoCompatCodec(options: PinoCompatCodecOptions = {}): Codec<string> {\n const safeMode = hasSafeOptions(options);\n return {\n name: \"pino-compat\",\n contentType: \"application/x-ndjson\",\n encode(input: CodecInput) {\n return encodeEvents(normalizeCodecInput(input), options, safeMode);\n },\n };\n}\n\nexport const pinoNdjsonProjector = pinoCompatCodec;\n","import { normalizeCodecInput, type Codec, type CodecInput, type LogEvent } from \"@loggerjs/core\";\n\nexport interface ProjectorCodecOptions<TWire> {\n name: string;\n contentType: string;\n project: (input: LogEvent | LogEvent[]) => TWire;\n serialize: (wire: TWire) => string | Uint8Array;\n parse?: (payload: string | Uint8Array) => TWire;\n unproject?: (wire: TWire) => LogEvent | LogEvent[];\n}\n\nexport function projectorCodec<TWire>(\n options: ProjectorCodecOptions<TWire>,\n): Codec<string | Uint8Array> {\n return {\n name: options.name,\n contentType: options.contentType,\n encode(input: CodecInput) {\n return options.serialize(options.project(normalizeCodecInput(input)));\n },\n decode:\n options.parse && options.unproject\n ? (payload) => options.unproject!(options.parse!(payload))\n : undefined,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Codec, type SafeStringifyOptions } from "@loggerjs/core";
|
|
2
|
+
export type PinoCompatCollisionPolicy = "nest" | "drop" | "throw";
|
|
3
|
+
export interface PinoCompatCodecOptions extends SafeStringifyOptions {
|
|
4
|
+
base?: Record<string, unknown>;
|
|
5
|
+
dataKey?: string;
|
|
6
|
+
errorKey?: string;
|
|
7
|
+
includeLogger?: boolean;
|
|
8
|
+
mergeData?: boolean;
|
|
9
|
+
collision?: PinoCompatCollisionPolicy;
|
|
10
|
+
}
|
|
11
|
+
export declare function pinoCompatCodec(options?: PinoCompatCodecOptions): Codec<string>;
|
|
12
|
+
export declare const pinoNdjsonProjector: typeof pinoCompatCodec;
|
|
13
|
+
//# sourceMappingURL=pino-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pino-compat.d.ts","sourceRoot":"","sources":["../src/pino-compat.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,KAAK,EAGV,KAAK,oBAAoB,EAE1B,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,yBAAyB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAElE,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAqID,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,KAAK,CAAC,MAAM,CAAC,CASnF;AAED,eAAO,MAAM,mBAAmB,wBAAkB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loggerjs/codecs",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Serialization codecs for loggerjs.",
|
|
5
5
|
"homepage": "https://github.com/jskits/loggerjs/tree/main/packages/codecs#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"msgpackr": "^2.0.4",
|
|
38
|
-
"@loggerjs/core": "0.0
|
|
38
|
+
"@loggerjs/core": "0.3.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "pnpm run clean && pnpm run build:js && pnpm run build:types",
|