@decohere/scribe-console 0.0.1-dev.120

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.
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./json-console.adapter.js"), exports);
6
+ function _export_star(from, to) {
7
+ Object.keys(from).forEach(function(k) {
8
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
9
+ Object.defineProperty(to, k, {
10
+ enumerable: true,
11
+ get: function() {
12
+ return from[k];
13
+ }
14
+ });
15
+ }
16
+ });
17
+ return from;
18
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "JsonConsoleAdapter", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return JsonConsoleAdapter;
9
+ }
10
+ });
11
+ const _scribe = require("@decohere/scribe");
12
+ class JsonConsoleAdapter extends _scribe.LogEntryAdapter {
13
+ timestamp;
14
+ constructor(options = {}){
15
+ super();
16
+ this.timestamp = options.timestamp ?? false;
17
+ }
18
+ write(entry) {
19
+ const method = methodFor(this.levels[entry.level] ?? _scribe.LogLevels.info);
20
+ console[method](stringify(toLine(entry, this.timestamp)));
21
+ }
22
+ }
23
+ /**
24
+ * Custom levels pick the method of the default level at or below them:
25
+ * `fatal` and `error` → `console.error`, `warn` → `console.warn`, `info` →
26
+ * `console.info`, `debug` and `trace` → `console.debug` (`console.trace` would
27
+ * print a stack).
28
+ */ function methodFor(value) {
29
+ if (value >= _scribe.LogLevels.error) {
30
+ return "error";
31
+ }
32
+ if (value >= _scribe.LogLevels.warn) {
33
+ return "warn";
34
+ }
35
+ if (value >= _scribe.LogLevels.info) {
36
+ return "info";
37
+ }
38
+ return "debug";
39
+ }
40
+ /** `level`, `name`, `time` and `msg` are the entry's own; a field cannot replace them. */ function toLine(entry, timestamp) {
41
+ const line = {
42
+ level: entry.level,
43
+ name: entry.name
44
+ };
45
+ if (timestamp) {
46
+ line.time = new Date().toISOString();
47
+ }
48
+ if (entry.msg !== undefined) {
49
+ line.msg = entry.msg;
50
+ }
51
+ for (const [key, value] of Object.entries(entry.fields)){
52
+ if (!(key in line)) {
53
+ line[key] = value;
54
+ }
55
+ }
56
+ if (entry.err != null) {
57
+ line.err = entry.err;
58
+ }
59
+ return line;
60
+ }
61
+ /** `JSON.stringify` that survives cycles and bigints, and serializes nested errors. */ function stringify(line) {
62
+ const ancestors = [];
63
+ return JSON.stringify(line, function(_key, value) {
64
+ if (typeof value === "bigint") {
65
+ return value.toString();
66
+ }
67
+ if (value == null || typeof value !== "object") {
68
+ return value;
69
+ }
70
+ while(ancestors.length > 0 && ancestors.at(-1) !== this){
71
+ ancestors.pop();
72
+ }
73
+ if (ancestors.includes(value)) {
74
+ return "[Circular]";
75
+ }
76
+ if (value instanceof Error) {
77
+ // Track the error too: its serialized properties may point back at it.
78
+ const serialized = (0, _scribe.serializeError)(value);
79
+ ancestors.push(value, serialized);
80
+ return serialized;
81
+ }
82
+ ancestors.push(value);
83
+ return value;
84
+ });
85
+ }
@@ -0,0 +1 @@
1
+ export * from "./json-console.adapter.js";
@@ -0,0 +1,80 @@
1
+ import { LogEntryAdapter, LogLevels, serializeError } from "@decohere/scribe";
2
+ /**
3
+ * Writes one JSON object per entry, `{ level, name, msg, ...fields, err }`,
4
+ * through the console method of its level, so hosts that index JSON console
5
+ * lines (Workers Logs, browser devtools) see the level too. Uses nothing but
6
+ * `console` and `JSON`: it runs on Workers, in browsers, Deno, Bun and Node.
7
+ */ export class JsonConsoleAdapter extends LogEntryAdapter {
8
+ timestamp;
9
+ constructor(options = {}){
10
+ super();
11
+ this.timestamp = options.timestamp ?? false;
12
+ }
13
+ write(entry) {
14
+ const method = methodFor(this.levels[entry.level] ?? LogLevels.info);
15
+ console[method](stringify(toLine(entry, this.timestamp)));
16
+ }
17
+ }
18
+ /**
19
+ * Custom levels pick the method of the default level at or below them:
20
+ * `fatal` and `error` → `console.error`, `warn` → `console.warn`, `info` →
21
+ * `console.info`, `debug` and `trace` → `console.debug` (`console.trace` would
22
+ * print a stack).
23
+ */ function methodFor(value) {
24
+ if (value >= LogLevels.error) {
25
+ return "error";
26
+ }
27
+ if (value >= LogLevels.warn) {
28
+ return "warn";
29
+ }
30
+ if (value >= LogLevels.info) {
31
+ return "info";
32
+ }
33
+ return "debug";
34
+ }
35
+ /** `level`, `name`, `time` and `msg` are the entry's own; a field cannot replace them. */ function toLine(entry, timestamp) {
36
+ const line = {
37
+ level: entry.level,
38
+ name: entry.name
39
+ };
40
+ if (timestamp) {
41
+ line.time = new Date().toISOString();
42
+ }
43
+ if (entry.msg !== undefined) {
44
+ line.msg = entry.msg;
45
+ }
46
+ for (const [key, value] of Object.entries(entry.fields)){
47
+ if (!(key in line)) {
48
+ line[key] = value;
49
+ }
50
+ }
51
+ if (entry.err != null) {
52
+ line.err = entry.err;
53
+ }
54
+ return line;
55
+ }
56
+ /** `JSON.stringify` that survives cycles and bigints, and serializes nested errors. */ function stringify(line) {
57
+ const ancestors = [];
58
+ return JSON.stringify(line, function(_key, value) {
59
+ if (typeof value === "bigint") {
60
+ return value.toString();
61
+ }
62
+ if (value == null || typeof value !== "object") {
63
+ return value;
64
+ }
65
+ while(ancestors.length > 0 && ancestors.at(-1) !== this){
66
+ ancestors.pop();
67
+ }
68
+ if (ancestors.includes(value)) {
69
+ return "[Circular]";
70
+ }
71
+ if (value instanceof Error) {
72
+ // Track the error too: its serialized properties may point back at it.
73
+ const serialized = serializeError(value);
74
+ ancestors.push(value, serialized);
75
+ return serialized;
76
+ }
77
+ ancestors.push(value);
78
+ return value;
79
+ });
80
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@decohere/scribe-console",
3
+ "version": "0.0.1-dev.120",
4
+ "description": "JSON console adapter for @decohere/scribe: one JSON line per entry, for Workers, browsers, Deno, Bun and Node",
5
+ "keywords": [
6
+ "typescript",
7
+ "logging",
8
+ "structured-logging",
9
+ "json",
10
+ "cloudflare-workers",
11
+ "decohere"
12
+ ],
13
+ "license": "ISC",
14
+ "author": "Typesmiths",
15
+ "type": "module",
16
+ "main": "index.js",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./types/src/index.d.ts",
20
+ "import": "./es6/src/index.js",
21
+ "require": "./commonjs/src/index.js"
22
+ }
23
+ },
24
+ "scripts": {
25
+ "test": "echo \"Error: no test specified\" && exit 1"
26
+ },
27
+ "dependencies": {
28
+ "@decohere/scribe": "0.0.1-dev.120"
29
+ },
30
+ "devDependencies": {}
31
+ }
@@ -0,0 +1 @@
1
+ export * from "./json-console.adapter.js";
@@ -0,0 +1,19 @@
1
+ import { type LogEntry, LogEntryAdapter } from "@decohere/scribe";
2
+ export type JsonConsoleAdapterOptions = {
3
+ /**
4
+ * Add `time` (ISO 8601) to every line. Off by default: hosts such as Workers
5
+ * Logs and browser devtools stamp each line themselves.
6
+ */
7
+ timestamp?: boolean;
8
+ };
9
+ /**
10
+ * Writes one JSON object per entry, `{ level, name, msg, ...fields, err }`,
11
+ * through the console method of its level, so hosts that index JSON console
12
+ * lines (Workers Logs, browser devtools) see the level too. Uses nothing but
13
+ * `console` and `JSON`: it runs on Workers, in browsers, Deno, Bun and Node.
14
+ */
15
+ export declare class JsonConsoleAdapter extends LogEntryAdapter {
16
+ private readonly timestamp;
17
+ constructor(options?: JsonConsoleAdapterOptions);
18
+ protected write(entry: LogEntry): void;
19
+ }