@hkdigital/lib-sveltekit 0.2.14 → 0.2.15

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.
@@ -8,28 +8,18 @@ export default class Logger extends EventEmitter {
8
8
  *
9
9
  * @param {string} name - Name of the service/component for this logger
10
10
  * @param {string} [defaultLevel=INFO] - Initial log level threshold
11
+ * @param {Object} [context={}] - Default context data for all logs
11
12
  */
12
- constructor(name: string, defaultLevel?: string);
13
+ constructor(name: string, defaultLevel?: string, context?: any);
13
14
  name: string;
14
15
  level: string;
15
16
  /**
16
17
  * Set the minimum log level threshold
17
18
  *
18
- * @param {string} level - New log level (DEBUG, INFO, WARN, ERROR, FATAL,
19
- * or NONE)
19
+ * @param {string} level - New log level (DEBUG, INFO, WARN, ERROR or NONE)
20
20
  * @returns {boolean} True if level was valid and set, false otherwise
21
21
  */
22
22
  setLevel(level: string): boolean;
23
- /**
24
- * Internal logging method
25
- *
26
- * @param {string} level - Log level
27
- * @param {string} message - Log message
28
- * @param {*} [details] - Additional details to include in the log
29
- * @returns {boolean} True if the log was emitted, false if filtered
30
- * @private
31
- */
32
- private _log;
33
23
  /**
34
24
  * Log a debug message
35
25
  *
@@ -63,12 +53,26 @@ export default class Logger extends EventEmitter {
63
53
  */
64
54
  error(message: string, details?: any): boolean;
65
55
  /**
66
- * Log a fatal error message
56
+ * Create a child logger with additional context
57
+ *
58
+ * @param {string} namespace
59
+ * Namespace of the context (needed for chaining contexts)
60
+ *
61
+ * @param {Object} additionalContext - Additional context data
67
62
  *
63
+ * @returns {Logger} New logger instance with merged context
64
+ */
65
+ context(namespace: string, additionalContext: any): Logger;
66
+ /**
67
+ * Internal logging method
68
+ *
69
+ * @param {string} level - Log level
68
70
  * @param {string} message - Log message
69
- * @param {*} [details] - Additional details
70
- * @returns {boolean} True if the log was emitted
71
+ * @param {*} [details] - Additional details to include in the log
72
+ * @returns {boolean} True if the log was emitted, false if filtered
73
+ * @private
71
74
  */
72
- fatal(message: string, details?: any): boolean;
75
+ private _log;
76
+ #private;
73
77
  }
74
78
  import { EventEmitter } from '../events';
@@ -34,30 +34,36 @@
34
34
 
35
35
  import { EventEmitter } from '../events';
36
36
 
37
- import { DEBUG, INFO, WARN, ERROR, FATAL, LEVELS } from './constants.js';
37
+ import { DEBUG, INFO, WARN, ERROR, LEVELS } from './constants.js';
38
38
 
39
39
  /**
40
40
  * Logger class for consistent logging across services
41
41
  * @extends EventEmitter
42
42
  */
43
43
  export default class Logger extends EventEmitter {
44
+ #defaultContext;
45
+ #hasContext;
46
+
44
47
  /**
45
48
  * Create a new Logger instance
46
49
  *
47
50
  * @param {string} name - Name of the service/component for this logger
48
51
  * @param {string} [defaultLevel=INFO] - Initial log level threshold
52
+ * @param {Object} [context={}] - Default context data for all logs
49
53
  */
50
- constructor(name, defaultLevel = INFO) {
54
+ constructor(name, defaultLevel = INFO, context = {}) {
51
55
  super();
52
56
  this.name = name;
53
57
  this.level = defaultLevel;
58
+
59
+ this.#defaultContext = structuredClone(context);
60
+ this.#hasContext = Object.keys(this.#defaultContext).length > 0;
54
61
  }
55
62
 
56
63
  /**
57
64
  * Set the minimum log level threshold
58
65
  *
59
- * @param {string} level - New log level (DEBUG, INFO, WARN, ERROR, FATAL,
60
- * or NONE)
66
+ * @param {string} level - New log level (DEBUG, INFO, WARN, ERROR or NONE)
61
67
  * @returns {boolean} True if level was valid and set, false otherwise
62
68
  */
63
69
  setLevel(level) {
@@ -70,37 +76,6 @@ export default class Logger extends EventEmitter {
70
76
  return false;
71
77
  }
72
78
 
73
- /**
74
- * Internal logging method
75
- *
76
- * @param {string} level - Log level
77
- * @param {string} message - Log message
78
- * @param {*} [details] - Additional details to include in the log
79
- * @returns {boolean} True if the log was emitted, false if filtered
80
- * @private
81
- */
82
- _log(level, message, details) {
83
- // Check if this log level should be filtered
84
- if (LEVELS[level] < LEVELS[this.level]) {
85
- return false; // Below threshold, don't emit
86
- }
87
-
88
- const timestamp = new Date();
89
- const logEvent = {
90
- timestamp,
91
- service: this.name,
92
- level,
93
- message,
94
- details
95
- };
96
-
97
- // Emit as both specific level event and generic 'log' event
98
- this.emit(level, logEvent);
99
- this.emit('log', logEvent);
100
-
101
- return true;
102
- }
103
-
104
79
  /**
105
80
  * Log a debug message
106
81
  *
@@ -146,13 +121,57 @@ export default class Logger extends EventEmitter {
146
121
  }
147
122
 
148
123
  /**
149
- * Log a fatal error message
124
+ * Create a child logger with additional context
125
+ *
126
+ * @param {string} namespace
127
+ * Namespace of the context (needed for chaining contexts)
150
128
  *
129
+ * @param {Object} additionalContext - Additional context data
130
+ *
131
+ * @returns {Logger} New logger instance with merged context
132
+ */
133
+ context(namespace, additionalContext) {
134
+ if( typeof namespace !== "string" ) {
135
+ throw new Error('Invalid namespace');
136
+ }
137
+
138
+ const mergedContext = {
139
+ ...this.#defaultContext,
140
+ [namespace]: additionalContext
141
+ };
142
+
143
+ return new Logger(this.name, this.level, mergedContext);
144
+ }
145
+
146
+ /**
147
+ * Internal logging method
148
+ *
149
+ * @param {string} level - Log level
151
150
  * @param {string} message - Log message
152
- * @param {*} [details] - Additional details
153
- * @returns {boolean} True if the log was emitted
151
+ * @param {*} [details] - Additional details to include in the log
152
+ * @returns {boolean} True if the log was emitted, false if filtered
153
+ * @private
154
154
  */
155
- fatal(message, details) {
156
- return this._log(FATAL, message, details);
155
+ _log(level, message, details) {
156
+ // Check if this log level should be filtered
157
+ if (LEVELS[level] < LEVELS[this.level]) {
158
+ return false; // Below threshold, don't emit
159
+ }
160
+
161
+ const timestamp = new Date();
162
+ const logEvent = {
163
+ timestamp,
164
+ service: this.name,
165
+ level,
166
+ message,
167
+ context: this.#hasContext ? this.#defaultContext : null,
168
+ details
169
+ };
170
+
171
+ // Emit as both specific level event and generic 'log' event
172
+ this.emit(level, logEvent);
173
+ this.emit('log', logEvent);
174
+
175
+ return true;
157
176
  }
158
177
  }
@@ -2,13 +2,11 @@ export const DEBUG: "debug";
2
2
  export const INFO: "info";
3
3
  export const WARN: "warn";
4
4
  export const ERROR: "error";
5
- export const FATAL: "fatal";
6
5
  export const NONE: "none";
7
6
  export namespace LEVELS {
8
7
  let debug: number;
9
8
  let info: number;
10
9
  let warn: number;
11
10
  let error: number;
12
- let fatal: number;
13
11
  let none: number;
14
12
  }
@@ -4,7 +4,6 @@ export const DEBUG = 'debug';
4
4
  export const INFO = 'info';
5
5
  export const WARN = 'warn';
6
6
  export const ERROR = 'error';
7
- export const FATAL = 'fatal';
8
7
  export const NONE = 'none';
9
8
 
10
9
  // Level values for filtering (higher = more important)
@@ -13,6 +12,5 @@ export const LEVELS = {
13
12
  [INFO]: 2,
14
13
  [WARN]: 3,
15
14
  [ERROR]: 4,
16
- [FATAL]: 5,
17
15
  [NONE]: 6
18
16
  };
@@ -40,10 +40,10 @@ export class ServiceManager extends EventEmitter {
40
40
  *
41
41
  * @param {string} name - Service name
42
42
  *
43
- * @returns {import('./typedef.js').ServiceBase|null}
43
+ * @returns {import('./typedef.js').ServiceInstance|null}
44
44
  * Service instance or null if not found
45
45
  */
46
- get(name: string): import("./typedef.js").ServiceBase | null;
46
+ get(name: string): import("./typedef.js").ServiceInstance | null;
47
47
  /**
48
48
  * Initialize a service
49
49
  *
@@ -153,7 +153,7 @@ export class ServiceManager extends EventEmitter {
153
153
  *
154
154
  * @private
155
155
  * @param {string} name - Service name
156
- * @param {import('./typedef.js').ServiceBase} instance
156
+ * @param {import('./typedef.js').ServiceInstance} instance
157
157
  * Service instance
158
158
  */
159
159
  private _attachServiceEvents;
@@ -67,6 +67,7 @@ import { EventEmitter } from '../events';
67
67
  import { Logger, DEBUG, INFO, WARN } from '../logging';
68
68
 
69
69
  import {
70
+ NOT_CREATED,
70
71
  CREATED,
71
72
  RUNNING,
72
73
  DESTROYED
@@ -147,6 +148,7 @@ export class ServiceManager extends EventEmitter {
147
148
  });
148
149
 
149
150
  this.services.set(name, entry);
151
+
150
152
  this.logger.debug(`Registered service '${name}'`, {
151
153
  dependencies: entry.dependencies,
152
154
  tags: entry.tags
@@ -158,7 +160,7 @@ export class ServiceManager extends EventEmitter {
158
160
  *
159
161
  * @param {string} name - Service name
160
162
  *
161
- * @returns {import('./typedef.js').ServiceBase|null}
163
+ * @returns {import('./typedef.js').ServiceInstance|null}
162
164
  * Service instance or null if not found
163
165
  */
164
166
  get(name) {
@@ -223,7 +225,9 @@ export class ServiceManager extends EventEmitter {
223
225
  // Start dependencies first
224
226
  for (const dep of entry.dependencies) {
225
227
  if (!await this.isRunning(dep)) {
228
+
226
229
  this.logger.debug(`Starting dependency '${dep}' for '${name}'`);
230
+
227
231
  const started = await this.startService(dep);
228
232
  if (!started) {
229
233
  this.logger.error(
@@ -408,6 +412,7 @@ export class ServiceManager extends EventEmitter {
408
412
  * @returns {Promise<HealthCheckResult>} Health status for all services
409
413
  */
410
414
  async checkHealth() {
415
+ /** @type {HealthCheckResult} */
411
416
  const health = {};
412
417
 
413
418
  for (const [name, entry] of this.services) {
@@ -416,7 +421,7 @@ export class ServiceManager extends EventEmitter {
416
421
  } else {
417
422
  health[name] = {
418
423
  name,
419
- state: 'NOT_CREATED',
424
+ state: NOT_CREATED,
420
425
  healthy: false
421
426
  };
422
427
  }
@@ -540,7 +545,7 @@ export class ServiceManager extends EventEmitter {
540
545
  *
541
546
  * @private
542
547
  * @param {string} name - Service name
543
- * @param {import('./typedef.js').ServiceBase} instance
548
+ * @param {import('./typedef.js').ServiceInstance} instance
544
549
  * Service instance
545
550
  */
546
551
  _attachServiceEvents(name, instance) {
@@ -69,6 +69,11 @@ export function isInactive(state: string): boolean;
69
69
  * break;
70
70
  * }
71
71
  */
72
+ /**
73
+ * Service has not been created yet
74
+ * @const {string}
75
+ */
76
+ export const NOT_CREATED: "not-created";
72
77
  /**
73
78
  * Service has been created but not initialized
74
79
  * @const {string}
@@ -37,6 +37,12 @@
37
37
  * }
38
38
  */
39
39
 
40
+ /**
41
+ * Service has not been created yet
42
+ * @const {string}
43
+ */
44
+ export const NOT_CREATED = 'not-created';
45
+
40
46
  /**
41
47
  * Service has been created but not initialized
42
48
  * @const {string}
@@ -112,7 +112,7 @@ export type ServiceErrorEvent = {
112
112
  /**
113
113
  * Service class constructor type
114
114
  */
115
- export type ServiceConstructor = new (name: string, options?: ServiceOptions) => ServiceBase;
115
+ export type ServiceConstructor = new (name: string, options?: ServiceOptions) => ServiceInstance;
116
116
  /**
117
117
  * Options for registering a service
118
118
  */
@@ -135,9 +135,9 @@ export type ServiceRegistrationOptions = {
135
135
  */
136
136
  export type ServiceManagerConfig = {
137
137
  /**
138
- * - Runtime environment
138
+ * - Debug mode switch
139
139
  */
140
- environment?: string;
140
+ debug?: boolean;
141
141
  /**
142
142
  * - Auto-start services on registration
143
143
  */
@@ -185,7 +185,7 @@ export type ServiceEntry = {
185
185
  /**
186
186
  * - Service instance (lazy-created)
187
187
  */
188
- instance: ServiceBase | null;
188
+ instance: ServiceInstance | null;
189
189
  /**
190
190
  * - Service configuration
191
191
  */
@@ -216,7 +216,7 @@ export type HealthCheckResult = {
216
216
  /**
217
217
  * Base class interface that services must implement
218
218
  */
219
- export type ServiceBase = {
219
+ export type ServiceInstance = {
220
220
  /**
221
221
  * - Service name
222
222
  */
@@ -47,12 +47,14 @@
47
47
 
48
48
  /**
49
49
  * Service configuration object passed to service initialization
50
+ *
50
51
  * @typedef {Object} ServiceConfig
51
52
  * @property {*} [key] - Service-specific configuration properties
52
53
  */
53
54
 
54
55
  /**
55
56
  * Options for creating a service instance
57
+ *
56
58
  * @typedef {Object} ServiceOptions
57
59
  * @property {string} [logLevel] - Initial log level for the service
58
60
  * @property {number} [shutdownTimeout=5000] - Timeout for graceful shutdown
@@ -60,6 +62,7 @@
60
62
 
61
63
  /**
62
64
  * Options for stopping a service
65
+ *
63
66
  * @typedef {Object} StopOptions
64
67
  * @property {number} [timeout] - Override shutdown timeout
65
68
  * @property {boolean} [force=false] - Force stop even if timeout exceeded
@@ -67,6 +70,7 @@
67
70
 
68
71
  /**
69
72
  * Health status returned by service health checks
73
+ *
70
74
  * @typedef {Object} HealthStatus
71
75
  * @property {string} name - Service name
72
76
  * @property {string} state - Current service state
@@ -78,6 +82,7 @@
78
82
 
79
83
  /**
80
84
  * Event emitted when service state changes
85
+ *
81
86
  * @typedef {Object} StateChangeEvent
82
87
  * @property {string} service - Service name
83
88
  * @property {string} oldState - Previous state
@@ -86,6 +91,7 @@
86
91
 
87
92
  /**
88
93
  * Event emitted when service health changes
94
+ *
89
95
  * @typedef {Object} HealthChangeEvent
90
96
  * @property {string} service - Service name
91
97
  * @property {boolean} healthy - New health status
@@ -93,6 +99,7 @@
93
99
 
94
100
  /**
95
101
  * Event emitted when service encounters an error
102
+ *
96
103
  * @typedef {Object} ServiceErrorEvent
97
104
  * @property {string} service - Service name
98
105
  * @property {string} operation - Operation that failed
@@ -101,11 +108,13 @@
101
108
 
102
109
  /**
103
110
  * Service class constructor type
104
- * @typedef {new (name: string, options?: ServiceOptions) => ServiceBase} ServiceConstructor
111
+ *
112
+ * @typedef {new (name: string, options?: ServiceOptions) => ServiceInstance} ServiceConstructor
105
113
  */
106
114
 
107
115
  /**
108
116
  * Options for registering a service
117
+ *
109
118
  * @typedef {Object} ServiceRegistrationOptions
110
119
  * @property {string[]} [dependencies=[]] - Services this service depends on
111
120
  * @property {string[]} [tags=[]] - Tags for grouping services
@@ -114,8 +123,9 @@
114
123
 
115
124
  /**
116
125
  * Configuration for ServiceManager
126
+ *
117
127
  * @typedef {Object} ServiceManagerConfig
118
- * @property {string} [environment='production'] - Runtime environment
128
+ * @property {boolean} [debug=false] - Debug mode switch
119
129
  * @property {boolean} [autoStart=false] - Auto-start services on registration
120
130
  * @property {number} [stopTimeout=10000] - Default timeout for stopping services
121
131
  * @property {string} [logLevel] - Initial log level for ServiceManager
@@ -124,6 +134,7 @@
124
134
 
125
135
  /**
126
136
  * Logging configuration
137
+ *
127
138
  * @typedef {Object} LogConfig
128
139
  * @property {string} [defaultLevel] - Default log level for services
129
140
  * @property {string} [globalLevel] - Override level for all services
@@ -132,9 +143,10 @@
132
143
 
133
144
  /**
134
145
  * Internal service registry entry
146
+ *
135
147
  * @typedef {Object} ServiceEntry
136
148
  * @property {ServiceConstructor} ServiceClass - Service class constructor
137
- * @property {ServiceBase|null} instance - Service instance (lazy-created)
149
+ * @property {ServiceInstance|null} instance - Service instance (lazy-created)
138
150
  * @property {ServiceConfig} config - Service configuration
139
151
  * @property {string[]} dependencies - Service dependencies
140
152
  * @property {Set<string>} dependents - Services that depend on this one
@@ -149,7 +161,8 @@
149
161
 
150
162
  /**
151
163
  * Base class interface that services must implement
152
- * @typedef {Object} ServiceBase
164
+ *
165
+ * @typedef {Object} ServiceInstance
153
166
  * @property {string} name - Service name
154
167
  * @property {string} state - Current state
155
168
  * @property {boolean} healthy - Health status
@@ -0,0 +1,47 @@
1
+ /**
2
+ * (Browser) console adapter that uses native DevTools styling
3
+ */
4
+ export class ConsoleAdapter {
5
+ /**
6
+ * Create a new ConsoleAdapter
7
+ *
8
+ * @param {Object} [options] - Browser configuration options
9
+ * @param {string} [options.level] - Minimum log level
10
+ * @param {Object} [options.context] - Additional context data to include with all logs
11
+ */
12
+ constructor(options?: {
13
+ level?: string;
14
+ context?: any;
15
+ });
16
+ level: string;
17
+ context: any;
18
+ /**
19
+ * Handle log events from Logger
20
+ *
21
+ * @param {Object} logEvent - Log event from Logger
22
+ */
23
+ handleLog(logEvent: any): void;
24
+ /**
25
+ * Get CSS styles for browser console
26
+ *
27
+ * @param {string} level - Log level
28
+ * @returns {string} CSS styles
29
+ * @private
30
+ */
31
+ private _getStyles;
32
+ /**
33
+ * Get appropriate console method for log level
34
+ *
35
+ * @param {string} level - Log level
36
+ * @returns {string} Console method name
37
+ * @private
38
+ */
39
+ private _getConsoleMethod;
40
+ /**
41
+ * Create a child logger with additional context
42
+ *
43
+ * @param {Object} context - Additional context data
44
+ * @returns {ConsoleAdapter} New adapter instance with context
45
+ */
46
+ child(context: any): ConsoleAdapter;
47
+ }
@@ -0,0 +1,113 @@
1
+ import { LEVELS } from '../constants.js';
2
+
3
+ /**
4
+ * (Browser) console adapter that uses native DevTools styling
5
+ */
6
+ export class ConsoleAdapter {
7
+ /**
8
+ * Create a new ConsoleAdapter
9
+ *
10
+ * @param {Object} [options] - Browser configuration options
11
+ * @param {string} [options.level] - Minimum log level
12
+ * @param {Object} [options.context] - Additional context data to include with all logs
13
+ */
14
+ constructor(options = {}) {
15
+ this.level = options.level || 'info';
16
+ this.context = options.context || {};
17
+ }
18
+
19
+ /**
20
+ * Handle log events from Logger
21
+ *
22
+ * @param {Object} logEvent - Log event from Logger
23
+ */
24
+ handleLog(logEvent) {
25
+ // eslint-disable-next-line no-unused-vars
26
+ const { level, message, details, service, timestamp } = logEvent;
27
+
28
+ // Filter by level
29
+ if (LEVELS[level] < LEVELS[this.level]) {
30
+ return;
31
+ }
32
+
33
+ // Use browser console styling
34
+ const styles = this._getStyles(level);
35
+ const prefix = `%c[${service}]`;
36
+
37
+ // Merge context with details
38
+ const logData = details
39
+ ? { ...this.context, ...details }
40
+ : Object.keys(this.context).length > 0
41
+ ? this.context
42
+ : undefined;
43
+
44
+ if (logData) {
45
+ console[this._getConsoleMethod(level)](prefix, styles, message, logData);
46
+ } else {
47
+ console[this._getConsoleMethod(level)](prefix, styles, message);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Get CSS styles for browser console
53
+ *
54
+ * @param {string} level - Log level
55
+ * @returns {string} CSS styles
56
+ * @private
57
+ */
58
+ _getStyles(level) {
59
+ const baseStyle =
60
+ 'padding: 2px 4px; border-radius: 2px; font-weight: bold;';
61
+
62
+ switch (level) {
63
+ case 'debug':
64
+ return `${baseStyle} background: #e3f2fd; color: #1976d2;`;
65
+ case 'info':
66
+ return `${baseStyle} background: #e8f5e8; color: #2e7d32;`;
67
+ case 'warn':
68
+ return `${baseStyle} background: #fff3e0; color: #f57c00;`;
69
+ case 'error':
70
+ return `${baseStyle} background: #ffebee; color: #d32f2f;`;
71
+ case 'fatal':
72
+ return `${baseStyle} background: #d32f2f; color: white;`;
73
+ default:
74
+ return baseStyle;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Get appropriate console method for log level
80
+ *
81
+ * @param {string} level - Log level
82
+ * @returns {string} Console method name
83
+ * @private
84
+ */
85
+ _getConsoleMethod(level) {
86
+ switch (level) {
87
+ case 'debug':
88
+ return 'debug';
89
+ case 'info':
90
+ return 'info';
91
+ case 'warn':
92
+ return 'warn';
93
+ case 'error':
94
+ case 'fatal':
95
+ return 'error';
96
+ default:
97
+ return 'log';
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Create a child logger with additional context
103
+ *
104
+ * @param {Object} context - Additional context data
105
+ * @returns {ConsoleAdapter} New adapter instance with context
106
+ */
107
+ child(context) {
108
+ return new ConsoleAdapter({
109
+ level: this.level,
110
+ context: { ...this.context, ...context }
111
+ });
112
+ }
113
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Pino adapter that bridges Logger events to pino
3
+ */
4
+ export class PinoAdapter {
5
+ /**
6
+ * Create a new PinoAdapter
7
+ *
8
+ * @param {Object} [options] - Pino configuration options
9
+ */
10
+ constructor(options?: any);
11
+ pino: import("pino").Logger<never, boolean>;
12
+ /**
13
+ * Handle log events from Logger
14
+ *
15
+ * @param {Object} logEvent - Log event from Logger
16
+ */
17
+ handleLog(logEvent: any): void;
18
+ /**
19
+ * Create a child logger with additional context
20
+ *
21
+ * @param {Object} context - Additional context data
22
+ * @returns {PinoAdapter} New adapter instance with context
23
+ */
24
+ child(context: any): PinoAdapter;
25
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Pino adapter for server-side logging
3
+ */
4
+
5
+ import pino from 'pino';
6
+ import { dev } from '$app/environment';
7
+
8
+ /**
9
+ * Pino adapter that bridges Logger events to pino
10
+ */
11
+ export class PinoAdapter {
12
+ /**
13
+ * Create a new PinoAdapter
14
+ *
15
+ * @param {Object} [options] - Pino configuration options
16
+ */
17
+ constructor(options = {}) {
18
+ const defaultOptions = dev ? {
19
+ level: 'debug',
20
+ transport: {
21
+ target: 'pino-pretty',
22
+ options: {
23
+ colorize: true
24
+ }
25
+ }
26
+ } : {};
27
+
28
+ this.pino = pino({ ...defaultOptions, ...options });
29
+ }
30
+
31
+ /**
32
+ * Handle log events from Logger
33
+ *
34
+ * @param {Object} logEvent - Log event from Logger
35
+ */
36
+ handleLog(logEvent) {
37
+ const { level, message, details, service, timestamp } = logEvent;
38
+
39
+ const logData = {
40
+ service,
41
+ timestamp,
42
+ ...(details && { details })
43
+ };
44
+
45
+ this.pino[level](logData, message);
46
+ }
47
+
48
+ /**
49
+ * Create a child logger with additional context
50
+ *
51
+ * @param {Object} context - Additional context data
52
+ * @returns {PinoAdapter} New adapter instance with context
53
+ */
54
+ child(context) {
55
+ const childPino = this.pino.child(context);
56
+ const adapter = new PinoAdapter();
57
+ adapter.pino = childPino;
58
+ return adapter;
59
+ }
60
+ }
@@ -0,0 +1 @@
1
+ export * from "../classes/logging/constants.js";
@@ -0,0 +1 @@
1
+ export * from '../classes/logging/constants.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Create a client-side logger with console adapter
3
+ *
4
+ * @param {string} serviceName - Name of the service
5
+ * @param {string} [level=INFO] - Initial log level
6
+ * @param {Object} [consoleOptions] - Additional console options
7
+ * @returns {Logger} Configured logger instance
8
+ */
9
+ export function createClientLogger(serviceName: string, level?: string, consoleOptions?: any): Logger;
10
+ import { Logger } from '../../classes/logging';
@@ -0,0 +1,21 @@
1
+ import { Logger } from '../../classes/logging';
2
+ import { ConsoleAdapter } from '../adapters/console.js';
3
+ import { INFO } from '../constants.js';
4
+
5
+ /**
6
+ * Create a client-side logger with console adapter
7
+ *
8
+ * @param {string} serviceName - Name of the service
9
+ * @param {string} [level=INFO] - Initial log level
10
+ * @param {Object} [consoleOptions] - Additional console options
11
+ * @returns {Logger} Configured logger instance
12
+ */
13
+ export function createClientLogger(serviceName, level = INFO, consoleOptions = {}) {
14
+ const logger = new Logger(serviceName, level);
15
+ const adapter = new ConsoleAdapter({ ...consoleOptions, level });
16
+
17
+ // Connect adapter to logger events
18
+ logger.on('log', (logEvent) => adapter.handleLog(logEvent));
19
+
20
+ return logger;
21
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Create a server-side logger with pino adapter
3
+ *
4
+ * @param {string} serviceName - Name of the service
5
+ * @param {string} [level=INFO] - Initial log level
6
+ * @param {Object} [pinoOptions] - Additional pino options
7
+ * @returns {Logger} Configured logger instance
8
+ */
9
+ export function createServerLogger(serviceName: string, level?: string, pinoOptions?: any): Logger;
10
+ import { Logger } from '../../classes/logging';
@@ -0,0 +1,22 @@
1
+ import { Logger } from '../../classes/logging';
2
+
3
+ import { PinoAdapter } from '../adapters/pino.js';
4
+ import { INFO } from '../constants.js';
5
+
6
+ /**
7
+ * Create a server-side logger with pino adapter
8
+ *
9
+ * @param {string} serviceName - Name of the service
10
+ * @param {string} [level=INFO] - Initial log level
11
+ * @param {Object} [pinoOptions] - Additional pino options
12
+ * @returns {Logger} Configured logger instance
13
+ */
14
+ export function createServerLogger(serviceName, level = INFO, pinoOptions = {}) {
15
+ const logger = new Logger(serviceName, level);
16
+ const adapter = new PinoAdapter(pinoOptions);
17
+
18
+ // Connect adapter to logger events
19
+ logger.on('log', (logEvent) => adapter.handleLog(logEvent));
20
+
21
+ return logger;
22
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Create a logger that works in both server and client environments
3
+ *
4
+ * @param {string} serviceName - Name of the service
5
+ * @param {string} [level] - Initial log level
6
+ * @param {Object} [options] - Additional options
7
+ * @returns {Logger} Configured logger instance
8
+ */
9
+ export function createLogger(serviceName: string, level?: string, options?: any): Logger;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Universal logger factory that auto-detects environment
3
+ */
4
+
5
+ import { browser } from '$app/environment';
6
+ import { createServerLogger } from './server.js';
7
+ import { createClientLogger } from './client.js';
8
+
9
+ /**
10
+ * Create a logger that works in both server and client environments
11
+ *
12
+ * @param {string} serviceName - Name of the service
13
+ * @param {string} [level] - Initial log level
14
+ * @param {Object} [options] - Additional options
15
+ * @returns {Logger} Configured logger instance
16
+ */
17
+ export function createLogger(serviceName, level, options = {}) {
18
+ if (browser) {
19
+ return createClientLogger(serviceName, level, options);
20
+ } else {
21
+ return createServerLogger(serviceName, level, options);
22
+ }
23
+ }
@@ -0,0 +1,4 @@
1
+ export { createServerLogger } from "./factories/server.js";
2
+ export { createClientLogger } from "./factories/client.js";
3
+ export { createLogger } from "./factories/universal.js";
4
+ export { DEBUG, INFO, WARN, ERROR, NONE, LEVELS } from "./constants.js";
@@ -0,0 +1,7 @@
1
+ export { DEBUG, INFO, WARN, ERROR, NONE, LEVELS } from './constants.js';
2
+
3
+ // Factories
4
+ export { createServerLogger } from './factories/server.js';
5
+ export { createClientLogger } from './factories/client.js';
6
+ export { createLogger } from './factories/universal.js';
7
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-sveltekit",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"