@hkdigital/lib-sveltekit 0.2.14 → 0.2.16
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/dist/classes/logging/Logger.d.ts +20 -18
- package/dist/classes/logging/Logger.js +94 -44
- package/dist/classes/logging/constants.d.ts +0 -2
- package/dist/classes/logging/constants.js +0 -2
- package/dist/classes/logging/typedef.d.ts +28 -0
- package/dist/classes/logging/typedef.js +12 -0
- package/dist/classes/services/ServiceManager.d.ts +3 -3
- package/dist/classes/services/ServiceManager.js +8 -3
- package/dist/classes/services/service-states.d.ts +5 -0
- package/dist/classes/services/service-states.js +6 -0
- package/dist/classes/services/typedef.d.ts +5 -5
- package/dist/classes/services/typedef.js +17 -4
- package/dist/classes/svelte/network-loader/NetworkLoader.svelte.js +1 -1
- package/dist/logging/adapters/console.d.ts +47 -0
- package/dist/logging/adapters/console.js +113 -0
- package/dist/logging/adapters/pino.d.ts +25 -0
- package/dist/logging/adapters/pino.js +60 -0
- package/dist/logging/constants.d.ts +1 -0
- package/dist/logging/constants.js +1 -0
- package/dist/logging/factories/client.d.ts +10 -0
- package/dist/logging/factories/client.js +21 -0
- package/dist/logging/factories/server.d.ts +10 -0
- package/dist/logging/factories/server.js +22 -0
- package/dist/logging/factories/universal.d.ts +9 -0
- package/dist/logging/factories/universal.js +23 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.js +8 -0
- package/dist/util/http/http-request.js +6 -6
- package/package.json +1 -1
@@ -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
|
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,24 @@ export default class Logger extends EventEmitter {
|
|
63
53
|
*/
|
64
54
|
error(message: string, details?: any): boolean;
|
65
55
|
/**
|
66
|
-
*
|
56
|
+
* Create a child logger with additional context
|
67
57
|
*
|
68
|
-
* @param {string}
|
69
|
-
*
|
70
|
-
*
|
58
|
+
* @param {string} namespace
|
59
|
+
* Namespace of the context (needed for chaining contexts)
|
60
|
+
*
|
61
|
+
* @param {Object} additionalContext - Additional context data
|
62
|
+
*
|
63
|
+
* @returns {Logger} New logger instance with merged context
|
64
|
+
*/
|
65
|
+
context(namespace: string, additionalContext: any): Logger;
|
66
|
+
/**
|
67
|
+
* Log an event of type LogEvent,
|
68
|
+
* e.g. an event that was created by another Logger instance and should be
|
69
|
+
* forwarded to this logger.
|
70
|
+
*
|
71
|
+
* @param {import('./typedef.js').LogEvent} logEvent
|
71
72
|
*/
|
72
|
-
|
73
|
+
logEvent(logEvent: import("./typedef.js").LogEvent): boolean;
|
74
|
+
#private;
|
73
75
|
}
|
74
76
|
import { EventEmitter } from '../events';
|
@@ -34,30 +34,36 @@
|
|
34
34
|
|
35
35
|
import { EventEmitter } from '../events';
|
36
36
|
|
37
|
-
import { DEBUG, INFO, WARN, ERROR,
|
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
|
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
|
*
|
@@ -109,7 +84,7 @@ export default class Logger extends EventEmitter {
|
|
109
84
|
* @returns {boolean} True if the log was emitted
|
110
85
|
*/
|
111
86
|
debug(message, details) {
|
112
|
-
return this
|
87
|
+
return this.#log(DEBUG, message, details);
|
113
88
|
}
|
114
89
|
|
115
90
|
/**
|
@@ -120,7 +95,7 @@ export default class Logger extends EventEmitter {
|
|
120
95
|
* @returns {boolean} True if the log was emitted
|
121
96
|
*/
|
122
97
|
info(message, details) {
|
123
|
-
return this
|
98
|
+
return this.#log(INFO, message, details);
|
124
99
|
}
|
125
100
|
|
126
101
|
/**
|
@@ -131,7 +106,7 @@ export default class Logger extends EventEmitter {
|
|
131
106
|
* @returns {boolean} True if the log was emitted
|
132
107
|
*/
|
133
108
|
warn(message, details) {
|
134
|
-
return this
|
109
|
+
return this.#log(WARN, message, details);
|
135
110
|
}
|
136
111
|
|
137
112
|
/**
|
@@ -142,17 +117,92 @@ export default class Logger extends EventEmitter {
|
|
142
117
|
* @returns {boolean} True if the log was emitted
|
143
118
|
*/
|
144
119
|
error(message, details) {
|
145
|
-
return this
|
120
|
+
return this.#log(ERROR, message, details);
|
121
|
+
}
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Create a child logger with additional context
|
125
|
+
*
|
126
|
+
* @param {string} namespace
|
127
|
+
* Namespace of the context (needed for chaining contexts)
|
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
|
+
* Log an event of type LogEvent,
|
148
|
+
* e.g. an event that was created by another Logger instance and should be
|
149
|
+
* forwarded to this logger.
|
150
|
+
*
|
151
|
+
* @param {import('./typedef.js').LogEvent} logEvent
|
152
|
+
*/
|
153
|
+
logEvent( logEvent ) {
|
154
|
+
const level = logEvent.level;
|
155
|
+
|
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
|
+
this.#logEvent( logEvent );
|
146
162
|
}
|
147
163
|
|
148
164
|
/**
|
149
|
-
*
|
165
|
+
* Internal logging method
|
150
166
|
*
|
167
|
+
* @param {string} level - Log level
|
151
168
|
* @param {string} message - Log message
|
152
|
-
* @param {*} [details] - Additional details
|
153
|
-
* @returns {boolean} True if the log was emitted
|
169
|
+
* @param {*} [details] - Additional details to include in the log
|
170
|
+
* @returns {boolean} True if the log was emitted, false if filtered
|
171
|
+
*/
|
172
|
+
#log(level, message, details) {
|
173
|
+
// Check if this log level should be filtered
|
174
|
+
if (LEVELS[level] < LEVELS[this.level]) {
|
175
|
+
return false; // Below threshold, don't emit
|
176
|
+
}
|
177
|
+
|
178
|
+
const timestamp = new Date();
|
179
|
+
|
180
|
+
const logEvent = {
|
181
|
+
timestamp,
|
182
|
+
service: this.name,
|
183
|
+
level,
|
184
|
+
message,
|
185
|
+
context: this.#hasContext ? this.#defaultContext : null,
|
186
|
+
details
|
187
|
+
};
|
188
|
+
|
189
|
+
// Emit as both specific level event and generic 'log' event
|
190
|
+
this.emit(level, logEvent);
|
191
|
+
this.emit('log', logEvent);
|
192
|
+
|
193
|
+
return true;
|
194
|
+
}
|
195
|
+
|
196
|
+
/**
|
197
|
+
* Internal event loggin method
|
198
|
+
*
|
199
|
+
* @param {import('./typedef.js').LogEvent} logEvent
|
154
200
|
*/
|
155
|
-
|
156
|
-
|
201
|
+
#logEvent(logEvent) {
|
202
|
+
// Emit as both specific level event and generic 'log' event
|
203
|
+
this.emit(logEvent.level, logEvent);
|
204
|
+
this.emit('log', logEvent);
|
205
|
+
|
206
|
+
return true;
|
157
207
|
}
|
158
208
|
}
|
@@ -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
|
};
|
@@ -0,0 +1,28 @@
|
|
1
|
+
declare const _default: {};
|
2
|
+
export default _default;
|
3
|
+
export type LogEvent = {
|
4
|
+
/**
|
5
|
+
* - When the log event was created
|
6
|
+
*/
|
7
|
+
timestamp: Date;
|
8
|
+
/**
|
9
|
+
* - Name of the service/component that logged this event
|
10
|
+
*/
|
11
|
+
service: string;
|
12
|
+
/**
|
13
|
+
* - Log level (DEBUG, INFO, WARN, ERROR)
|
14
|
+
*/
|
15
|
+
level: string;
|
16
|
+
/**
|
17
|
+
* - The log message
|
18
|
+
*/
|
19
|
+
message: string;
|
20
|
+
/**
|
21
|
+
* - Default context data from the logger (null if no context)
|
22
|
+
*/
|
23
|
+
context: any | null;
|
24
|
+
/**
|
25
|
+
* - Additional details provided with the log (optional)
|
26
|
+
*/
|
27
|
+
details?: any;
|
28
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
/**
|
3
|
+
* @typedef {Object} LogEvent
|
4
|
+
* @property {Date} timestamp - When the log event was created
|
5
|
+
* @property {string} service - Name of the service/component that logged this event
|
6
|
+
* @property {string} level - Log level (DEBUG, INFO, WARN, ERROR)
|
7
|
+
* @property {string} message - The log message
|
8
|
+
* @property {Object|null} context - Default context data from the logger (null if no context)
|
9
|
+
* @property {*} [details] - Additional details provided with the log (optional)
|
10
|
+
*/
|
11
|
+
|
12
|
+
export default {};
|
@@ -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').
|
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").
|
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').
|
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').
|
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:
|
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').
|
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}
|
@@ -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) =>
|
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
|
-
* -
|
138
|
+
* - Debug mode switch
|
139
139
|
*/
|
140
|
-
|
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:
|
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
|
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
|
-
*
|
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 {
|
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 {
|
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
|
-
*
|
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} name
|
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(name: 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} name
|
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(name, level = INFO, consoleOptions = {}) {
|
14
|
+
const logger = new Logger(name, 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} name
|
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(name: 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} name
|
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(name, level = INFO, pinoOptions = {}) {
|
15
|
+
const logger = new Logger(name, 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,8 @@
|
|
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
|
+
|
8
|
+
export * from '../classes/logger/typedef.js';
|
@@ -356,12 +356,12 @@ export async function httpRequest(options) {
|
|
356
356
|
}
|
357
357
|
|
358
358
|
// Create stale info
|
359
|
-
const staleInfo = {
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
};
|
359
|
+
// const staleInfo = {
|
360
|
+
// isStale: false,
|
361
|
+
// fresh: null,
|
362
|
+
// timestamp: Date.now(),
|
363
|
+
// expires
|
364
|
+
// };
|
365
365
|
|
366
366
|
// Store response in cache
|
367
367
|
const cacheKeyParams = { url, ...headers };
|