@holz/console-backend 0.3.0 → 0.6.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 ADDED
@@ -0,0 +1,27 @@
1
+ # `@holz/console-backend`
2
+
3
+ Pretty-print logs to the browser console.
4
+
5
+ <img alt="Screenshot of logs printed to the browser console" src="https://user-images.githubusercontent.com/10053423/222927532-2925b0a3-9494-4de7-b328-917ceb8607b0.png" width="600" />
6
+
7
+ ## Usage
8
+
9
+ ```typescript
10
+ import { createConsoleBackend } from '@holz/console-backend';
11
+
12
+ const logger = createLogger(createConsoleBackend());
13
+ ```
14
+
15
+ > **Note**
16
+ > This is fine-tuned for an interactive browser console. If you want pretty-printed logs in Node or Deno, try [`@holz/ansi-terminal-backend`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-ansi-terminal-backend) instead.
17
+
18
+ ## Options
19
+
20
+ ```typescript
21
+ createConsoleBackend({
22
+ /**
23
+ * By default it prints to the global console, but you can override it.
24
+ */
25
+ console: typeof console,
26
+ });
27
+ ```
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const c=1e3,r=60*c,i=60*r,u=24*i,f=(a,t=a)=>{const e=a.getTime()-t.getTime(),o=Math.abs(e),s=e<0?"":"+";return o>=u?`${s}${Math.round(e/u)}d`:o>=i?`${s}${Math.round(e/i)}h`:o>=r?`${s}${Math.round(e/r)}m`:o>=c?`${s}${Math.round(e/c)}s`:`${s}${e}ms`};class l{constructor(t={}){this.console=t.console??console}processLog(t){const e=this.stamp,o=new Date;this.stamp=o;const s=[{include:!0,format:"%s",values:[t.message]},{include:Object.keys(t.context).length>0,format:"%o",values:[t.context]},{include:!0,format:"%c%s",values:["color: gray",f(o,e)]},{include:t.origin.length>0,format:"%c%s",values:["color: rgba(128, 128, 128, 0.6); font-style: italic",t.origin.join(":")]}].filter(n=>n.include),m=s.map(n=>n.format).join(" "),d=s.flatMap(n=>n.values);this.console[t.level](m,...d)}}exports.ConsoleBackend=l;exports.default=l;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=1e3,c=60*a,u=60*c,l=24*u,f=(s,r=s)=>{const e=s.getTime()-r.getTime(),t=Math.abs(e),n=e<0?"":"+";return t>=l?`${n}${Math.round(e/l)}d`:t>=u?`${n}${Math.round(e/u)}h`:t>=c?`${n}${Math.round(e/c)}m`:t>=a?`${n}${Math.round(e/a)}s`:`${n}${e}ms`};function $(s={}){const r=s.console??console;let e;return t=>{const n=new Date,i=[{include:!0,format:"%s",values:[t.message]},{include:Object.keys(t.context).length>0,format:"%o",values:[t.context]},{include:!0,format:"%c%s",values:["color: gray",f(n,e)]},{include:t.origin.length>0,format:"%c%s",values:["color: rgba(128, 128, 128, 0.6); font-style: italic",t.origin.join(":")]}].filter(o=>o.include),m=i.map(o=>o.format).join(" "),d=i.flatMap(o=>o.values);r[t.level](m,...d),e=n}}exports.createConsoleBackend=$;
@@ -1,15 +1,12 @@
1
- const i = (c, t = c) => {
2
- const e = c.getTime() - t.getTime(), n = Math.abs(e), s = e < 0 ? "" : "+";
3
- return n >= 864e5 ? `${s}${Math.round(e / 864e5)}d` : n >= 36e5 ? `${s}${Math.round(e / 36e5)}h` : n >= 6e4 ? `${s}${Math.round(e / 6e4)}m` : n >= 1e3 ? `${s}${Math.round(e / 1e3)}s` : `${s}${e}ms`;
1
+ const i = (s, r = s) => {
2
+ const e = s.getTime() - r.getTime(), t = Math.abs(e), n = e < 0 ? "" : "+";
3
+ return t >= 864e5 ? `${n}${Math.round(e / 864e5)}d` : t >= 36e5 ? `${n}${Math.round(e / 36e5)}h` : t >= 6e4 ? `${n}${Math.round(e / 6e4)}m` : t >= 1e3 ? `${n}${Math.round(e / 1e3)}s` : `${n}${e}ms`;
4
4
  };
5
- class u {
6
- constructor(t = {}) {
7
- this.console = t.console ?? console;
8
- }
9
- processLog(t) {
10
- const e = this.stamp, n = new Date();
11
- this.stamp = n;
12
- const s = [
5
+ function l(s = {}) {
6
+ const r = s.console ?? console;
7
+ let e;
8
+ return (t) => {
9
+ const n = new Date(), c = [
13
10
  {
14
11
  include: !0,
15
12
  format: "%s",
@@ -34,11 +31,10 @@ class u {
34
31
  t.origin.join(":")
35
32
  ]
36
33
  }
37
- ].filter((o) => o.include), a = s.map((o) => o.format).join(" "), r = s.flatMap((o) => o.values);
38
- this.console[t.level](a, ...r);
39
- }
34
+ ].filter((o) => o.include), a = c.map((o) => o.format).join(" "), u = c.flatMap((o) => o.values);
35
+ r[t.level](a, ...u), e = n;
36
+ };
40
37
  }
41
38
  export {
42
- u as ConsoleBackend,
43
- u as default
39
+ l as createConsoleBackend
44
40
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holz/console-backend",
3
- "version": "0.3.0",
3
+ "version": "0.6.0",
4
4
  "description": "A console backend for Holz",
5
5
  "type": "module",
6
6
  "main": "./dist/holz-console-backend.cjs",
@@ -39,10 +39,10 @@
39
39
  "test:types": "tsc"
40
40
  },
41
41
  "devDependencies": {
42
- "@holz/core": "0.2.0",
42
+ "@holz/core": "^0.6.0",
43
43
  "@types/node": "^18.14.0",
44
- "@vitest/coverage-c8": "0.28.5",
45
- "typescript": "4.9.5",
44
+ "@vitest/coverage-c8": "^0.28.5",
45
+ "typescript": "^4.9.5",
46
46
  "vite": "^4.0.0",
47
47
  "vitest": "^0.28.5"
48
48
  }
@@ -1,7 +1,7 @@
1
1
  import { format } from 'util';
2
2
  import { createLogger } from '@holz/core';
3
3
  import type { MinimalConsole } from '../console-backend';
4
- import ConsoleBackend from '../console-backend';
4
+ import { createConsoleBackend } from '../console-backend';
5
5
 
6
6
  class MockConsole implements MinimalConsole {
7
7
  private fmt = (level: string, ...strings: Array<unknown>) => {
@@ -30,7 +30,7 @@ describe('Console backend', () => {
30
30
 
31
31
  it('prints messages to the console', () => {
32
32
  const output = new MockConsole();
33
- const backend = new ConsoleBackend({ console: output });
33
+ const backend = createConsoleBackend({ console: output });
34
34
 
35
35
  const logger = createLogger(backend);
36
36
  logger.info('hello world');
@@ -42,7 +42,7 @@ describe('Console backend', () => {
42
42
 
43
43
  it('includes the log namespace', () => {
44
44
  const output = new MockConsole();
45
- const backend = new ConsoleBackend({ console: output });
45
+ const backend = createConsoleBackend({ console: output });
46
46
  const logger = createLogger(backend)
47
47
  .namespace('my-lib')
48
48
  .namespace('MyClass');
@@ -56,7 +56,7 @@ describe('Console backend', () => {
56
56
 
57
57
  it('includes the log context', () => {
58
58
  const output = new MockConsole();
59
- const backend = new ConsoleBackend({ console: output });
59
+ const backend = createConsoleBackend({ console: output });
60
60
  const logger = createLogger(backend);
61
61
 
62
62
  logger.info('creating session', { sessionId: 3109 });
@@ -71,7 +71,7 @@ describe('Console backend', () => {
71
71
 
72
72
  it('does not include the log context if it is empty', () => {
73
73
  const output = new MockConsole();
74
- const backend = new ConsoleBackend({ console: output });
74
+ const backend = createConsoleBackend({ console: output });
75
75
  const logger = createLogger(backend);
76
76
 
77
77
  logger.warn('activating death ray', {});
@@ -84,7 +84,7 @@ describe('Console backend', () => {
84
84
 
85
85
  it('prints the time since the last log', () => {
86
86
  const output = new MockConsole();
87
- const backend = new ConsoleBackend({ console: output });
87
+ const backend = createConsoleBackend({ console: output });
88
88
  const logger = createLogger(backend);
89
89
 
90
90
  logger.info('first message');
@@ -108,7 +108,7 @@ describe('Console backend', () => {
108
108
  ],
109
109
  ])('avoids changing %s messages', (method, message, namespace, pipe) => {
110
110
  const output = new MockConsole();
111
- const backend = new ConsoleBackend({ console: output });
111
+ const backend = createConsoleBackend({ console: output });
112
112
  const logger = namespace.reduce(
113
113
  (logger, ns) => logger.namespace(ns),
114
114
  createLogger(backend)
@@ -5,21 +5,13 @@ import { timeDelta } from './time-delta';
5
5
  * A backend that pretty-prints logs to a browser console, or any
6
6
  * remote-attached console.
7
7
  */
8
- export default class ConsoleBackend implements LogProcessor {
9
- private console: MinimalConsole;
10
- private stamp?: Date;
8
+ export function createConsoleBackend(options: Options = {}): LogProcessor {
9
+ const output = options.console ?? console;
10
+ let lastTimestamp: Date;
11
11
 
12
- constructor(options: Options = {}) {
13
- this.console = options.console ?? console;
14
- }
15
-
16
- processLog(log: Log) {
17
- const lastTimestamp = this.stamp;
12
+ return (log: Log) => {
18
13
  const now = new Date();
19
14
 
20
- // Track the time spent between logs.
21
- this.stamp = now;
22
-
23
15
  const segments = [
24
16
  {
25
17
  include: true,
@@ -50,8 +42,11 @@ export default class ConsoleBackend implements LogProcessor {
50
42
  const values = segments.flatMap<unknown>((segment) => segment.values);
51
43
 
52
44
  // Browsers have UIs for filtering by log level. Leverage that.
53
- this.console[log.level](format, ...values);
54
- }
45
+ output[log.level](format, ...values);
46
+
47
+ // Track the time spent between logs.
48
+ lastTimestamp = now;
49
+ };
55
50
  }
56
51
 
57
52
  interface Options {
package/src/index.ts CHANGED
@@ -1 +1 @@
1
- export { default, default as ConsoleBackend } from './console-backend';
1
+ export { createConsoleBackend } from './console-backend';