@holz/core 0.6.0 → 0.7.0-rc.1

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.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var s=(e=>(e.Error="error",e.Warn="warn",e.Info="info",e.Debug="debug",e))(s||{});function c(e){return r=>e.forEach(o=>o(r))}function f(e,r){return o=>{e(o)&&r(o)}}class a{constructor(r,o){this.processor=r,this.owner=o,this.debug=(n,i)=>{this.forwardLog(s.Debug,n,i)},this.info=(n,i)=>{this.forwardLog(s.Info,n,i)},this.warn=(n,i)=>{this.forwardLog(s.Warn,n,i)},this.error=(n,i)=>{this.forwardLog(s.Error,n,i)};const t={configurable:!1,enumerable:!1};Object.defineProperties(this,{processor:t,debug:t,info:t,warn:t,error:t})}static create(r){return new a(r,[])}namespace(r){return new a(this.processor,this.owner.concat(r))}forwardLog(r,o,t={}){this.processor({message:o,level:r,origin:this.owner,context:t})}}const u=a.create;exports.LogLevel=s;exports.combine=c;exports.createLogger=u;exports.filter=f;
1
+ "use strict";var a=Object.defineProperty;var c=(o,r,e)=>r in o?a(o,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[r]=e;var i=(o,r,e)=>c(o,typeof r!="symbol"?r+"":r,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var t=(o=>(o.Error="error",o.Warn="warn",o.Info="info",o.Debug="debug",o))(t||{});function f(o){return r=>o.forEach(e=>e(r))}function u(o,r){return e=>{o(e)&&r(e)}}class s{constructor(r,e){i(this,"debug",(r,e)=>{this.forwardLog(t.Debug,r,e)});i(this,"info",(r,e)=>{this.forwardLog(t.Info,r,e)});i(this,"warn",(r,e)=>{this.forwardLog(t.Warn,r,e)});i(this,"error",(r,e)=>{this.forwardLog(t.Error,r,e)});this.processor=r,this.owner=e;const n={configurable:!1,enumerable:!1};Object.defineProperties(this,{processor:n,debug:n,info:n,warn:n,error:n})}namespace(r){return new s(this.processor,this.owner.concat(r))}forwardLog(r,e,n={}){this.processor({message:e,level:r,origin:this.owner,context:n})}}const g=o=>new s(o,[]);exports.LogLevel=t;exports.combine=f;exports.createLogger=g;exports.filter=u;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Combine several log processors into a single log processor. Each one is
3
+ * called in sequence. Useful for sending a single log to multiple log
4
+ * destinations.
5
+ */
6
+ export declare function combine(processors: Array<LogProcessor>): LogProcessor;
7
+
8
+ /**
9
+ * Create a new logger. The processor is up to you. There are plugins for
10
+ * filtering, formatting, combining multiple processors together, and more.
11
+ *
12
+ * If you wish to use more than one processor, `combine(...)` them first.
13
+ */
14
+ export declare const createLogger: (processor: LogProcessor) => Logger;
15
+
16
+ /**
17
+ * Filter logs based on a filter function. If the function returns true, the
18
+ * log is kept and forwarded onto the next processor, otherwise it is
19
+ * discarded.
20
+ */
21
+ export declare function filter(
22
+ /** Returns `true` to forward the log. */
23
+ predicate: (log: Log) => boolean,
24
+ /** Where to send the log if it passes the filter. */
25
+ processor: LogProcessor): LogProcessor;
26
+
27
+ declare type JsonPrimitive = string | number | boolean | null | undefined;
28
+
29
+ /** A log message where variables are carried as structured data. */
30
+ export declare interface Log {
31
+ /** The verbatim log message. Should not contain interpolated data. */
32
+ readonly message: string;
33
+ /** Log severity. */
34
+ readonly level: LogLevel;
35
+ /**
36
+ * Where the log message originated. Usually starts with a library or app name,
37
+ * followed by something more specific.
38
+ *
39
+ * @example ['logger-library', 'ConsoleBackend']
40
+ */
41
+ readonly origin: ReadonlyArray<string>;
42
+ /**
43
+ * Key-value pairs that provide additional context for the log message. If
44
+ * you're tempted to interpolate data into the message, consider using log
45
+ * context instead.
46
+ *
47
+ * These values must be JSON serializable.
48
+ *
49
+ * Because it's easy to accidentally include unsuitable log context (e.g.
50
+ * redux state, PII) nested objects are not allowed. The restriction doesn't
51
+ * make it impossible, but it makes it harder to miss during code review.
52
+ *
53
+ * @example { userId: 123, reason: 'disconnect' }
54
+ */
55
+ readonly context: LogContext;
56
+ }
57
+
58
+ export declare type LogContext = Record<string, JsonPrimitive | ReadonlyArray<JsonPrimitive>>;
59
+
60
+ export declare class Logger {
61
+ private processor;
62
+ readonly owner: ReadonlyArray<string>;
63
+ constructor(processor: LogProcessor, owner: ReadonlyArray<string>);
64
+ /** Extend the logger to attach a class or module name to logs. */
65
+ namespace(owner: string): Logger;
66
+ /** Log a frequent and verbose progress update. */
67
+ debug: (message: string, context?: LogContext) => void;
68
+ /** Log a high-level progress update. */
69
+ info: (message: string, context?: LogContext) => void;
70
+ /** Log something concerning. */
71
+ warn: (message: string, context?: LogContext) => void;
72
+ /** Log a critical failure. */
73
+ error: (message: string, context?: LogContext) => void;
74
+ private forwardLog;
75
+ }
76
+
77
+ export declare enum LogLevel {
78
+ /** Something critical failed and we can't continue. */
79
+ Error = "error",
80
+ /** Something is concerning, but we can keep going. */
81
+ Warn = "warn",
82
+ /** High-level progress updates. */
83
+ Info = "info",
84
+ /** Extremely verbose progress updates (usually hidden). */
85
+ Debug = "debug"
86
+ }
87
+
88
+ /**
89
+ * A logger is made up of log processors. These processors take structured
90
+ * logs and do something with them. Examples are logging backends (console,
91
+ * file, uploads) and operators (filtering, transforming, aggregating).
92
+ */
93
+ export declare interface LogProcessor {
94
+ /** Do something with a log message. */
95
+ (log: Log): void;
96
+ }
97
+
98
+ export { }
package/dist/holz-core.js CHANGED
@@ -1,58 +1,60 @@
1
- var i = /* @__PURE__ */ ((o) => (o.Error = "error", o.Warn = "warn", o.Info = "info", o.Debug = "debug", o))(i || {});
2
- function c(o) {
3
- return (r) => o.forEach((e) => e(r));
1
+ var a = Object.defineProperty;
2
+ var c = (e, r, o) => r in e ? a(e, r, { enumerable: !0, configurable: !0, writable: !0, value: o }) : e[r] = o;
3
+ var s = (e, r, o) => c(e, typeof r != "symbol" ? r + "" : r, o);
4
+ var t = /* @__PURE__ */ ((e) => (e.Error = "error", e.Warn = "warn", e.Info = "info", e.Debug = "debug", e))(t || {});
5
+ function u(e) {
6
+ return (r) => e.forEach((o) => o(r));
4
7
  }
5
- function f(o, r) {
6
- return (e) => {
7
- o(e) && r(e);
8
+ function h(e, r) {
9
+ return (o) => {
10
+ e(o) && r(o);
8
11
  };
9
12
  }
10
- class a {
11
- constructor(r, e) {
12
- this.processor = r, this.owner = e, this.debug = (n, s) => {
13
- this.forwardLog(i.Debug, n, s);
14
- }, this.info = (n, s) => {
15
- this.forwardLog(i.Info, n, s);
16
- }, this.warn = (n, s) => {
17
- this.forwardLog(i.Warn, n, s);
18
- }, this.error = (n, s) => {
19
- this.forwardLog(i.Error, n, s);
20
- };
21
- const t = { configurable: !1, enumerable: !1 };
13
+ class i {
14
+ constructor(r, o) {
15
+ /** Log a frequent and verbose progress update. */
16
+ s(this, "debug", (r, o) => {
17
+ this.forwardLog(t.Debug, r, o);
18
+ });
19
+ /** Log a high-level progress update. */
20
+ s(this, "info", (r, o) => {
21
+ this.forwardLog(t.Info, r, o);
22
+ });
23
+ /** Log something concerning. */
24
+ s(this, "warn", (r, o) => {
25
+ this.forwardLog(t.Warn, r, o);
26
+ });
27
+ /** Log a critical failure. */
28
+ s(this, "error", (r, o) => {
29
+ this.forwardLog(t.Error, r, o);
30
+ });
31
+ this.processor = r, this.owner = o;
32
+ const n = { configurable: !1, enumerable: !1 };
22
33
  Object.defineProperties(this, {
23
- processor: t,
24
- debug: t,
25
- info: t,
26
- warn: t,
27
- error: t
34
+ processor: n,
35
+ debug: n,
36
+ info: n,
37
+ warn: n,
38
+ error: n
28
39
  });
29
40
  }
30
- /**
31
- * Create a new logger. The processor is up to you. There are plugins for
32
- * filtering, formatting, combining multiple processors together, and more.
33
- *
34
- * If you wish to use more than one processor, `combine(...)` them first.
35
- */
36
- static create(r) {
37
- return new a(r, []);
38
- }
39
41
  /** Extend the logger to attach a class or module name to logs. */
40
42
  namespace(r) {
41
- return new a(this.processor, this.owner.concat(r));
43
+ return new i(this.processor, this.owner.concat(r));
42
44
  }
43
- forwardLog(r, e, t = {}) {
45
+ forwardLog(r, o, n = {}) {
44
46
  this.processor({
45
- message: e,
47
+ message: o,
46
48
  level: r,
47
49
  origin: this.owner,
48
- context: t
50
+ context: n
49
51
  });
50
52
  }
51
53
  }
52
- const h = a.create;
54
+ const w = (e) => new i(e, []);
53
55
  export {
54
- i as LogLevel,
55
- c as combine,
56
- h as createLogger,
57
- f as filter
56
+ t as LogLevel,
57
+ u as combine,
58
+ w as createLogger,
59
+ h as filter
58
60
  };
package/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "@holz/core",
3
- "version": "0.6.0",
3
+ "version": "0.7.0-rc.1",
4
4
  "description": "A structured and composable logger",
5
5
  "type": "module",
6
- "main": "./dist/holz-core.cjs",
7
- "module": "./dist/holz-core.js",
8
- "types": "./src/index.ts",
9
6
  "repository": {
10
7
  "type": "git",
11
8
  "url": "https://github.com/PsychoLlama/holz",
@@ -13,6 +10,7 @@
13
10
  },
14
11
  "exports": {
15
12
  ".": {
13
+ "types": "./dist/holz-core.d.ts",
16
14
  "require": "./dist/holz-core.cjs",
17
15
  "import": "./dist/holz-core.js"
18
16
  }
@@ -38,9 +36,12 @@
38
36
  "test:types": "tsc"
39
37
  },
40
38
  "devDependencies": {
41
- "@vitest/coverage-c8": "^0.28.5",
42
- "typescript": "^4.9.5",
43
- "vite": "^4.0.0",
44
- "vitest": "^0.28.5"
45
- }
39
+ "@vitest/coverage-v8": "^3.0.8",
40
+ "typescript": "^5.0.0",
41
+ "vite": "^6.0.0",
42
+ "vite-plugin-dts": "^4.5.3",
43
+ "vite-tsconfig-paths": "^5.1.4",
44
+ "vitest": "^3.0.8"
45
+ },
46
+ "stableVersion": "0.6.0"
46
47
  }
@@ -13,11 +13,11 @@ describe('operators', () => {
13
13
  logger.info('tee message');
14
14
 
15
15
  expect(b1).toHaveBeenCalledWith(
16
- expect.objectContaining({ message: 'tee message' })
16
+ expect.objectContaining({ message: 'tee message' }),
17
17
  );
18
18
 
19
19
  expect(b2).toHaveBeenCalledWith(
20
- expect.objectContaining({ message: 'tee message' })
20
+ expect.objectContaining({ message: 'tee message' }),
21
21
  );
22
22
  });
23
23
 
@@ -33,7 +33,7 @@ describe('operators', () => {
33
33
  it('filters out logs that do not match the predicate', () => {
34
34
  const backend = vi.fn();
35
35
  const logger = createLogger(
36
- filter((log) => log.level !== LogLevel.Debug, backend)
36
+ filter((log) => log.level !== LogLevel.Debug, backend),
37
37
  );
38
38
 
39
39
  logger.info('keep me');
@@ -41,7 +41,7 @@ describe('operators', () => {
41
41
 
42
42
  expect(backend).toHaveBeenCalledOnce();
43
43
  expect(backend).toHaveBeenCalledWith(
44
- expect.objectContaining({ message: 'keep me' })
44
+ expect.objectContaining({ message: 'keep me' }),
45
45
  );
46
46
  });
47
47
  });
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export type { LogProcessor, LogContext, Log } from './types';
2
2
  export { LogLevel } from './types';
3
3
  export { combine, filter } from './operators';
4
- export { createLogger } from './logger';
4
+ export { createLogger, type Logger } from './logger';
package/src/logger.ts CHANGED
@@ -2,19 +2,9 @@ import type { LogProcessor, LogContext } from './types';
2
2
  import { LogLevel } from './types';
3
3
 
4
4
  class Logger {
5
- /**
6
- * Create a new logger. The processor is up to you. There are plugins for
7
- * filtering, formatting, combining multiple processors together, and more.
8
- *
9
- * If you wish to use more than one processor, `combine(...)` them first.
10
- */
11
- static create(processor: LogProcessor): Logger {
12
- return new Logger(processor, []);
13
- }
14
-
15
- private constructor(
5
+ constructor(
16
6
  private processor: LogProcessor,
17
- readonly owner: ReadonlyArray<string>
7
+ readonly owner: ReadonlyArray<string>,
18
8
  ) {
19
9
  // Non-enumerable to keep the repl clean.
20
10
  const hidden = { configurable: false, enumerable: false };
@@ -55,7 +45,7 @@ class Logger {
55
45
  private forwardLog(
56
46
  level: LogLevel,
57
47
  message: string,
58
- context: LogContext = {}
48
+ context: LogContext = {},
59
49
  ) {
60
50
  this.processor({
61
51
  message,
@@ -66,4 +56,13 @@ class Logger {
66
56
  }
67
57
  }
68
58
 
69
- export const createLogger = Logger.create;
59
+ /**
60
+ * Create a new logger. The processor is up to you. There are plugins for
61
+ * filtering, formatting, combining multiple processors together, and more.
62
+ *
63
+ * If you wish to use more than one processor, `combine(...)` them first.
64
+ */
65
+ export const createLogger = (processor: LogProcessor): Logger =>
66
+ new Logger(processor, []);
67
+
68
+ export type { Logger };
package/src/operators.ts CHANGED
@@ -18,7 +18,7 @@ export function filter(
18
18
  /** Returns `true` to forward the log. */
19
19
  predicate: (log: Log) => boolean,
20
20
  /** Where to send the log if it passes the filter. */
21
- processor: LogProcessor
21
+ processor: LogProcessor,
22
22
  ): LogProcessor {
23
23
  return (log: Log) => {
24
24
  if (predicate(log)) {