@dxos/log 0.8.4-main.c4373fc → 0.8.4-main.c85a9c8dae

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.
Files changed (66) hide show
  1. package/dist/lib/browser/chunk-IEP6GGEX.mjs +23 -0
  2. package/dist/lib/browser/chunk-IEP6GGEX.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-M2YHSBML.mjs +133 -0
  4. package/dist/lib/browser/chunk-M2YHSBML.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +221 -206
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/platform/browser/index.mjs +26 -0
  9. package/dist/lib/browser/platform/browser/index.mjs.map +7 -0
  10. package/dist/lib/browser/platform/node/index.mjs +21 -0
  11. package/dist/lib/browser/platform/node/index.mjs.map +7 -0
  12. package/dist/lib/browser/processors/console-processor.mjs +107 -0
  13. package/dist/lib/browser/processors/console-processor.mjs.map +7 -0
  14. package/dist/lib/browser/processors/console-stub.mjs +9 -0
  15. package/dist/lib/browser/processors/console-stub.mjs.map +7 -0
  16. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  17. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  18. package/dist/lib/node-esm/chunk-62VKC2WQ.mjs +135 -0
  19. package/dist/lib/node-esm/chunk-62VKC2WQ.mjs.map +7 -0
  20. package/dist/lib/node-esm/index.mjs +216 -288
  21. package/dist/lib/node-esm/index.mjs.map +4 -4
  22. package/dist/lib/node-esm/meta.json +1 -1
  23. package/dist/lib/node-esm/platform/browser/index.mjs +27 -0
  24. package/dist/lib/node-esm/platform/browser/index.mjs.map +7 -0
  25. package/dist/lib/node-esm/platform/node/index.mjs +22 -0
  26. package/dist/lib/node-esm/platform/node/index.mjs.map +7 -0
  27. package/dist/lib/node-esm/processors/console-processor.mjs +108 -0
  28. package/dist/lib/node-esm/processors/console-processor.mjs.map +7 -0
  29. package/dist/lib/node-esm/processors/console-stub.mjs +10 -0
  30. package/dist/lib/node-esm/processors/console-stub.mjs.map +7 -0
  31. package/dist/types/src/config.d.ts.map +1 -1
  32. package/dist/types/src/context.d.ts.map +1 -1
  33. package/dist/types/src/dbg.d.ts +23 -0
  34. package/dist/types/src/dbg.d.ts.map +1 -0
  35. package/dist/types/src/decorators.d.ts +1 -1
  36. package/dist/types/src/decorators.d.ts.map +1 -1
  37. package/dist/types/src/index.d.ts +3 -2
  38. package/dist/types/src/index.d.ts.map +1 -1
  39. package/dist/types/src/log-buffer.d.ts +36 -0
  40. package/dist/types/src/log-buffer.d.ts.map +1 -0
  41. package/dist/types/src/log-buffer.test.d.ts +2 -0
  42. package/dist/types/src/log-buffer.test.d.ts.map +1 -0
  43. package/dist/types/src/log.d.ts +14 -18
  44. package/dist/types/src/log.d.ts.map +1 -1
  45. package/dist/types/src/options.d.ts +1 -6
  46. package/dist/types/src/options.d.ts.map +1 -1
  47. package/dist/types/src/platform/index.d.ts +1 -1
  48. package/dist/types/src/platform/index.d.ts.map +1 -1
  49. package/dist/types/src/processors/file-processor.d.ts.map +1 -1
  50. package/dist/types/src/processors/index.d.ts +3 -3
  51. package/dist/types/src/processors/index.d.ts.map +1 -1
  52. package/dist/types/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +30 -12
  54. package/src/config.ts +1 -0
  55. package/src/context.ts +36 -5
  56. package/src/dbg.ts +34 -0
  57. package/src/decorators.ts +3 -3
  58. package/src/index.ts +3 -3
  59. package/src/log-buffer.test.ts +156 -0
  60. package/src/log-buffer.ts +108 -0
  61. package/src/log.test.ts +48 -18
  62. package/src/log.ts +103 -57
  63. package/src/options.ts +26 -10
  64. package/src/platform/index.ts +1 -1
  65. package/src/processors/file-processor.ts +2 -0
  66. package/src/processors/index.ts +3 -3
package/src/log.ts CHANGED
@@ -6,7 +6,16 @@ import { type LogConfig, LogLevel, type LogOptions } from './config';
6
6
  import { type LogContext, type LogProcessor } from './context';
7
7
  import { createFunctionLogDecorator, createMethodLogDecorator } from './decorators';
8
8
  import { type CallMetadata } from './meta';
9
- import { DEFAULT_PROCESSORS, getConfig } from './options';
9
+ import { createConfig } from './options';
10
+
11
+ /**
12
+ * Accessible from browser console.
13
+ * Example: `DX_LOG.config({ filter: 'ERROR' })`
14
+ * NOTE: File level filtering isn't supported in storybooks.
15
+ */
16
+ declare global {
17
+ const DX_LOG: Log;
18
+ }
10
19
 
11
20
  /**
12
21
  * Logging function.
@@ -17,6 +26,9 @@ type LogFunction = (message: string, context?: LogContext, meta?: CallMetadata)
17
26
  * Logging methods.
18
27
  */
19
28
  export interface LogMethods {
29
+ config: (options?: LogOptions) => Log;
30
+ addProcessor: (processor: LogProcessor, addDefault?: boolean) => () => void;
31
+
20
32
  trace: LogFunction;
21
33
  debug: LogFunction;
22
34
  verbose: LogFunction;
@@ -24,70 +36,56 @@ export interface LogMethods {
24
36
  warn: LogFunction;
25
37
  error: LogFunction;
26
38
  catch: (error: Error | any, context?: LogContext, meta?: CallMetadata) => void;
27
- break: () => void;
28
- stack: (message?: string, context?: never, meta?: CallMetadata) => void;
39
+
29
40
  method: (arg0?: never, arg1?: never, meta?: CallMetadata) => MethodDecorator;
30
- func: <F extends (...args: any[]) => any>(
41
+ function: <F extends (...args: any[]) => any>(
31
42
  name: string,
32
43
  fn: F,
33
- opts?: { transformOutput?: (result: ReturnType<F>) => Promise<any> | any },
44
+ opts?: {
45
+ transformOutput?: (result: ReturnType<F>) => Promise<any> | any;
46
+ },
34
47
  ) => F;
48
+
49
+ break: () => void;
50
+ stack: (message?: string, context?: never, meta?: CallMetadata) => void;
35
51
  }
36
52
 
37
53
  /**
38
54
  * Properties accessible on the logging function.
55
+ * @internal
39
56
  */
40
- interface Log extends LogMethods, LogFunction {
41
- config: (options: LogOptions) => void;
42
- addProcessor: (processor: LogProcessor) => void;
43
- runtimeConfig: LogConfig;
57
+ export interface Log extends LogFunction, LogMethods {
58
+ readonly runtimeConfig: LogConfig;
44
59
  }
45
60
 
61
+ /**
62
+ * @internal
63
+ */
46
64
  interface LogImp extends Log {
65
+ _id: string;
47
66
  _config: LogConfig;
48
67
  }
49
68
 
50
- const createLog = (): LogImp => {
51
- const log: LogImp = ((...params) => processLog(LogLevel.DEBUG, ...params)) as LogImp;
52
-
53
- log._config = getConfig();
54
- Object.defineProperty(log, 'runtimeConfig', { get: () => log._config });
55
-
56
- log.addProcessor = (processor: LogProcessor) => {
57
- if (DEFAULT_PROCESSORS.filter((p) => p === processor).length === 0) {
58
- DEFAULT_PROCESSORS.push(processor);
59
- }
60
- if (log._config.processors.filter((p) => p === processor).length === 0) {
61
- log._config.processors.push(processor);
62
- }
63
- };
64
-
65
- // Set config.
66
- log.config = (options: LogOptions) => {
67
- log._config = getConfig(options);
68
- };
69
-
70
- // TODO(burdon): API to set context and separate error object.
71
- // E.g., log.warn('failed', { key: 123 }, err);
72
-
73
- log.trace = (...params) => processLog(LogLevel.TRACE, ...params);
74
- log.debug = (...params) => processLog(LogLevel.DEBUG, ...params);
75
- log.verbose = (...params) => processLog(LogLevel.VERBOSE, ...params);
76
- log.info = (...params) => processLog(LogLevel.INFO, ...params);
77
- log.warn = (...params) => processLog(LogLevel.WARN, ...params);
78
- log.error = (...params) => processLog(LogLevel.ERROR, ...params);
69
+ let logCount = 0;
79
70
 
80
- // Catch only shows error message, not stacktrace.
81
- log.catch = (error: Error | any, context, meta) => processLog(LogLevel.ERROR, undefined, context, meta, error);
82
-
83
- // Show break.
84
- log.break = () => log.info('——————————————————————————————————————————————————');
71
+ /**
72
+ * Create a logging function with properties.
73
+ * @internal
74
+ */
75
+ export const createLog = (): LogImp => {
76
+ // Default function.
77
+ const log: LogImp = ((...params) => processLog(LogLevel.DEBUG, ...params)) as LogImp;
85
78
 
86
- log.stack = (message, context, meta) =>
87
- processLog(LogLevel.INFO, `${message ?? 'Stack Dump'}\n${getFormattedStackTrace()}`, context, meta);
79
+ // Add private properties.
80
+ Object.assign<LogImp, Partial<LogImp>>(log, {
81
+ _id: `log-${++logCount}`,
82
+ _config: createConfig(),
83
+ });
88
84
 
89
- log.method = createMethodLogDecorator(log);
90
- log.func = createFunctionLogDecorator(log);
85
+ // TODO(burdon): Document.
86
+ Object.defineProperty(log, 'runtimeConfig', {
87
+ get: () => log._config,
88
+ });
91
89
 
92
90
  /**
93
91
  * Process the current log call.
@@ -99,16 +97,72 @@ const createLog = (): LogImp => {
99
97
  meta?: CallMetadata,
100
98
  error?: Error,
101
99
  ) => {
102
- log._config.processors.forEach((processor) => processor(log._config, { level, message, context, meta, error }));
100
+ // TODO(burdon): Do the filter matching upstream (here) rather than in each processor?
101
+ log._config.processors.forEach((processor) =>
102
+ processor(log._config, {
103
+ level,
104
+ message,
105
+ context,
106
+ meta,
107
+ error,
108
+ }),
109
+ );
103
110
  };
104
111
 
112
+ /**
113
+ * API.
114
+ */
115
+ Object.assign<Log, LogMethods>(log, {
116
+ /**
117
+ * Update config.
118
+ * NOTE: Preserves any processors that were already added to this logger instance
119
+ * unless an explicit processor option is provided.
120
+ */
121
+ config: ({ processor, ...options } = {}) => {
122
+ const config = createConfig(options);
123
+ // TODO(burdon): This could be buggy since the behavior is not reentrant.
124
+ const processors = processor ? config.processors : log._config.processors;
125
+ log._config = { ...config, processors };
126
+ return log;
127
+ },
128
+
129
+ /**
130
+ * Adds a processor to the logger.
131
+ */
132
+ addProcessor: (processor) => {
133
+ if (log._config.processors.filter((p) => p === processor).length === 0) {
134
+ log._config.processors.push(processor);
135
+ }
136
+
137
+ return () => {
138
+ log._config.processors = log._config.processors.filter((p) => p !== processor);
139
+ };
140
+ },
141
+
142
+ trace: (...params) => processLog(LogLevel.TRACE, ...params),
143
+ debug: (...params) => processLog(LogLevel.DEBUG, ...params),
144
+ verbose: (...params) => processLog(LogLevel.VERBOSE, ...params),
145
+ info: (...params) => processLog(LogLevel.INFO, ...params),
146
+ warn: (...params) => processLog(LogLevel.WARN, ...params),
147
+ error: (...params) => processLog(LogLevel.ERROR, ...params),
148
+ catch: (error, context, meta) => processLog(LogLevel.ERROR, undefined, context, meta, error),
149
+
150
+ method: createMethodLogDecorator(log),
151
+ function: createFunctionLogDecorator(log),
152
+
153
+ break: () => log.info('-'.repeat(80)),
154
+ stack: (message, context, meta) => {
155
+ return processLog(LogLevel.INFO, `${message ?? 'Stack Dump'}\n${getFormattedStackTrace()}`, context, meta);
156
+ },
157
+ });
158
+
105
159
  return log;
106
160
  };
107
161
 
108
162
  /**
109
163
  * Global logging function.
110
164
  */
111
- export const log: Log = ((globalThis as any).dx_log ??= createLog());
165
+ export const log: Log = ((globalThis as any).DX_LOG ??= createLog());
112
166
 
113
167
  const start = Date.now();
114
168
  let last = start;
@@ -128,12 +182,4 @@ export const debug = (label?: any, args?: any) => {
128
182
  last = Date.now();
129
183
  };
130
184
 
131
- /**
132
- * Accessible from browser console.
133
- */
134
- declare global {
135
- // eslint-disable-next-line camelcase
136
- const dx_log: Log;
137
- }
138
-
139
185
  const getFormattedStackTrace = () => new Error().stack!.split('\n').slice(3).join('\n');
package/src/options.ts CHANGED
@@ -12,32 +12,48 @@ import { BROWSER_PROCESSOR, CONSOLE_PROCESSOR, DEBUG_PROCESSOR } from './process
12
12
  /**
13
13
  * Processor variants.
14
14
  */
15
- export const processors: { [index: string]: LogProcessor } = {
15
+ export const processors: Record<string, LogProcessor> = {
16
16
  [LogProcessorType.CONSOLE]: CONSOLE_PROCESSOR,
17
17
  [LogProcessorType.BROWSER]: BROWSER_PROCESSOR,
18
18
  [LogProcessorType.DEBUG]: DEBUG_PROCESSOR,
19
19
  };
20
20
 
21
- const IS_BROWSER = typeof window !== 'undefined' || typeof navigator !== 'undefined';
21
+ const browser =
22
+ (typeof window !== 'undefined' || typeof navigator !== 'undefined') &&
23
+ !(typeof process !== 'undefined' && process?.env?.VITEST);
22
24
 
23
- export const DEFAULT_PROCESSORS = [IS_BROWSER ? BROWSER_PROCESSOR : CONSOLE_PROCESSOR];
25
+ export const DEFAULT_PROCESSORS = [browser ? BROWSER_PROCESSOR : CONSOLE_PROCESSOR];
24
26
 
27
+ const parseLogLevel = (level: string, defValue = LogLevel.WARN) => levels[level.toLowerCase()] ?? defValue;
28
+
29
+ /**
30
+ * @internal
31
+ */
25
32
  export const parseFilter = (filter: string | string[] | LogLevel): LogFilter[] => {
26
33
  if (typeof filter === 'number') {
27
34
  return [{ level: filter }];
28
35
  }
29
36
 
30
- const parseLogLevel = (level: string, defValue = LogLevel.WARN) => levels[level.toLowerCase()] ?? defValue;
31
-
32
37
  const lines = typeof filter === 'string' ? filter.split(/,\s*/) : filter;
33
38
  return lines.map((filter) => {
34
39
  const [pattern, level] = filter.split(':');
35
- return level ? { level: parseLogLevel(level), pattern } : { level: parseLogLevel(pattern) };
40
+ return level
41
+ ? {
42
+ level: parseLogLevel(level),
43
+ pattern,
44
+ }
45
+ : {
46
+ level: parseLogLevel(pattern),
47
+ };
36
48
  });
37
49
  };
38
50
 
39
- export const getConfig = (options?: LogOptions): LogConfig => {
40
- const nodeOptions: LogOptions | undefined =
51
+ /**
52
+ * @internal
53
+ */
54
+ export const createConfig = (options?: LogOptions): LogConfig => {
55
+ // Node only.
56
+ const envOptions: LogOptions | undefined =
41
57
  'process' in globalThis
42
58
  ? {
43
59
  file: process!.env.LOG_CONFIG,
@@ -46,12 +62,12 @@ export const getConfig = (options?: LogOptions): LogConfig => {
46
62
  }
47
63
  : undefined;
48
64
 
49
- const mergedOptions: LogOptions = defaultsDeep({}, loadOptions(nodeOptions?.file), nodeOptions, options);
65
+ const mergedOptions: LogOptions = defaultsDeep({}, loadOptions(envOptions?.file), envOptions, options);
50
66
  return {
51
67
  options: mergedOptions,
52
68
  filters: parseFilter(mergedOptions.filter ?? LogLevel.INFO),
53
69
  captureFilters: parseFilter(mergedOptions.captureFilter ?? LogLevel.WARN),
54
- processors: mergedOptions.processor ? [processors[mergedOptions.processor]] : DEFAULT_PROCESSORS,
70
+ processors: mergedOptions.processor ? [processors[mergedOptions.processor]] : [...DEFAULT_PROCESSORS],
55
71
  prefix: mergedOptions.prefix,
56
72
  };
57
73
  };
@@ -2,4 +2,4 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- export * from './node';
5
+ export * from '#platform';
@@ -14,6 +14,7 @@ import { getRelativeFilename } from './common';
14
14
 
15
15
  // Amount of time to retry writing after encountering EAGAIN before giving up.
16
16
  const EAGAIN_MAX_DURATION = 1000;
17
+
17
18
  /**
18
19
  * Create a file processor.
19
20
  * @param path - Path to log file to create or append to, or existing open file descriptor e.g. stdout.
@@ -38,6 +39,7 @@ export const createFileProcessor = ({
38
39
  if (!shouldLog(entry, filters)) {
39
40
  return;
40
41
  }
42
+
41
43
  if (typeof pathOrFd === 'number') {
42
44
  fd = pathOrFd;
43
45
  } else {
@@ -2,8 +2,8 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- export * from './console-processor';
6
- export * from './debug-processor';
7
5
  export * from './browser-processor';
8
- export * from './file-processor';
9
6
  export * from './common';
7
+ export * from '#console-processor';
8
+ export * from './debug-processor';
9
+ export * from './file-processor';