@hkdigital/lib-core 0.4.42 → 0.4.44

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.
@@ -34,6 +34,8 @@
34
34
 
35
35
  /** @typedef {import('../../../generic/typedef.js').ErrorDetails} ErrorDetails */
36
36
 
37
+ import * as expect from '../../../util/expect.js';
38
+
37
39
  import { EventEmitter } from '../../../generic/events.js';
38
40
 
39
41
  import {
@@ -248,6 +250,8 @@ export default class Logger extends EventEmitter {
248
250
  * @param {import('../../typedef.js').LogEventData} eventData
249
251
  */
250
252
  logFromEvent(eventData) {
253
+ expect.object(eventData);
254
+
251
255
  const level = eventData.level;
252
256
 
253
257
  // Check if this log level should be filtered
@@ -89,20 +89,20 @@ export default class SceneBase {
89
89
  const state = this.#state;
90
90
 
91
91
  $effect(() => {
92
- if (state.current === STATE_LOADING) {
92
+ if (this.#state.current === STATE_LOADING) {
93
93
  const { sourcesLoaded, numberOfSources } = this.#progress;
94
94
 
95
- if (sourcesLoaded === numberOfSources) {
95
+ if (sourcesLoaded === numberOfSources && numberOfSources > 0) {
96
96
  this.#state.send(LOADED);
97
97
  }
98
98
  }
99
99
  });
100
100
 
101
101
  $effect(() => {
102
- if (state.current === STATE_ABORTING) {
102
+ if (this.#state.current === STATE_ABORTING) {
103
103
  const { sourcesAborted, numberOfSources } = this.#abortProgress;
104
104
 
105
- if (sourcesAborted === numberOfSources) {
105
+ if (sourcesAborted === numberOfSources && numberOfSources > 0) {
106
106
  this.#state.send(ABORTED);
107
107
  }
108
108
  }
@@ -1,3 +1,4 @@
1
+ /** @typedef {import('../../logging/typedef.js').LogLevel} LogLevel */
1
2
  /**
2
3
  * @typedef {import('./typedef.js').ServiceConstructor} ServiceConstructor
3
4
  * @typedef {import('./typedef.js').ServiceRegistrationOptions} ServiceRegistrationOptions
@@ -27,8 +28,24 @@ export class ServiceManager extends EventEmitter {
27
28
  services: Map<string, ServiceEntry>;
28
29
  /** @type {Logger} */
29
30
  logger: Logger;
30
- /** @type {ServiceManagerConfig} */
31
- config: ServiceManagerConfig;
31
+ /**
32
+ * @type {{
33
+ * debug: boolean,
34
+ * autoStart: boolean,
35
+ * stopTimeout: number,
36
+ * defaultLogLevel: LogLevel,
37
+ * managerLogLevel: LogLevel,
38
+ * serviceLogLevels?: Record<string,LogLevel>
39
+ * }}
40
+ **/
41
+ config: {
42
+ debug: boolean;
43
+ autoStart: boolean;
44
+ stopTimeout: number;
45
+ defaultLogLevel: LogLevel;
46
+ managerLogLevel: LogLevel;
47
+ serviceLogLevels?: Record<string, LogLevel>;
48
+ };
32
49
  /**
33
50
  * Attach a plugin to the ServiceManager
34
51
  *
@@ -163,22 +180,20 @@ export class ServiceManager extends EventEmitter {
163
180
  /**
164
181
  * Set log level for the ServiceManager itself
165
182
  *
166
- * @param {string} level - Log level to set for the ServiceManager
183
+ * @param {LogLevel} level - Log level to set for the ServiceManager
167
184
  */
168
- setManagerLogLevel(level: string): void;
185
+ setManagerLogLevel(level: LogLevel): void;
169
186
  /**
170
187
  * Set log level for individual services
171
188
  *
172
- * @param {string|Object<string,string>} nameOrConfig
189
+ * @param {string|Record<string,LogLevel>} nameOrConfig
173
190
  * Service configuration:
174
191
  * - String with service name: 'auth' (requires level parameter)
175
192
  * - String with config: 'auth:debug,database:info'
176
193
  * - Object: { auth: 'debug', database: 'info' }
177
- * @param {string} [level] - Log level (required when nameOrConfig is service name)
194
+ * @param {LogLevel} [level] - Log level (required when nameOrConfig is service name)
178
195
  */
179
- setServiceLogLevel(nameOrConfig: string | {
180
- [x: string]: string;
181
- }, level?: string): void;
196
+ setServiceLogLevel(nameOrConfig: string | Record<string, LogLevel>, level?: LogLevel): void;
182
197
  /**
183
198
  * Get all services with a specific tag
184
199
  *
@@ -198,6 +213,7 @@ export class ServiceManager extends EventEmitter {
198
213
  #private;
199
214
  }
200
215
  export default ServiceManager;
216
+ export type LogLevel = import("../../logging/typedef.js").LogLevel;
201
217
  export type ServiceConstructor = import("./typedef.js").ServiceConstructor;
202
218
  export type ServiceRegistrationOptions = import("./typedef.js").ServiceRegistrationOptions;
203
219
  export type ServiceManagerConfig = import("./typedef.js").ServiceManagerConfig;
@@ -86,6 +86,8 @@ import {
86
86
  STATE_DESTROYED
87
87
  } from '../service-base/constants.js';
88
88
 
89
+ /** @typedef {import('../../logging/typedef.js').LogLevel} LogLevel */
90
+
89
91
  /**
90
92
  * @typedef {import('./typedef.js').ServiceConstructor} ServiceConstructor
91
93
  * @typedef {import('./typedef.js').ServiceRegistrationOptions} ServiceRegistrationOptions
@@ -128,20 +130,50 @@ export class ServiceManager extends EventEmitter {
128
130
  /** @type {Logger} */
129
131
  this.logger = new Logger('ServiceManager', managerLogLevel);
130
132
 
131
- /** @type {ServiceManagerConfig} */
133
+ /**
134
+ * @type {{
135
+ * debug: boolean,
136
+ * autoStart: boolean,
137
+ * stopTimeout: number,
138
+ * defaultLogLevel: LogLevel,
139
+ * managerLogLevel: LogLevel,
140
+ * serviceLogLevels?: Record<string,LogLevel>
141
+ * }}
142
+ **/
143
+ // @ts-ignore (managerLogLevel set later)
132
144
  this.config = {
133
145
  debug: config.debug ?? false,
134
146
  autoStart: config.autoStart ?? false,
135
147
  stopTimeout: config.stopTimeout || 10000,
136
148
  defaultLogLevel
137
149
  // managerLogLevel will be set bysetManagerLogLevel()
138
- // serviceLogLevels will be set by setServiceLogLevel()
150
+ // serviceLogLevels will be optionally set by setServiceLogLevel()
139
151
  };
140
152
 
141
153
  this.setManagerLogLevel(managerLogLevel);
142
154
 
143
155
  if (serviceLogLevels) {
144
- this.setServiceLogLevel(serviceLogLevels);
156
+ // Parse and store service log levels, but don't apply them yet
157
+ // They will be applied when services are created in get()
158
+
159
+ /** @type {Record<string,LogLevel>} */
160
+ let parsedServiceLevels = {};
161
+
162
+ if (typeof serviceLogLevels === 'string') {
163
+ if (serviceLogLevels.includes(':')) {
164
+ // Parse string config: 'auth:debug,database:info'
165
+ parsedServiceLevels = parseServiceLogLevels(serviceLogLevels);
166
+ } else {
167
+ throw new Error(
168
+ 'Service log levels string must include service:level pairs'
169
+ );
170
+ }
171
+ } else {
172
+ // Object config: { auth: 'debug', database: 'info' }
173
+ parsedServiceLevels = serviceLogLevels;
174
+ }
175
+
176
+ this.config.serviceLogLevels = parsedServiceLevels;
145
177
  }
146
178
  }
147
179
 
@@ -570,7 +602,7 @@ export class ServiceManager extends EventEmitter {
570
602
  /**
571
603
  * Set log level for the ServiceManager itself
572
604
  *
573
- * @param {string} level - Log level to set for the ServiceManager
605
+ * @param {LogLevel} level - Log level to set for the ServiceManager
574
606
  */
575
607
  setManagerLogLevel(level) {
576
608
  this.config.managerLogLevel = level;
@@ -580,15 +612,15 @@ export class ServiceManager extends EventEmitter {
580
612
  /**
581
613
  * Set log level for individual services
582
614
  *
583
- * @param {string|Object<string,string>} nameOrConfig
615
+ * @param {string|Record<string,LogLevel>} nameOrConfig
584
616
  * Service configuration:
585
617
  * - String with service name: 'auth' (requires level parameter)
586
618
  * - String with config: 'auth:debug,database:info'
587
619
  * - Object: { auth: 'debug', database: 'info' }
588
- * @param {string} [level] - Log level (required when nameOrConfig is service name)
620
+ * @param {LogLevel} [level] - Log level (required when nameOrConfig is service name)
589
621
  */
590
622
  setServiceLogLevel(nameOrConfig, level) {
591
- /** @type {{[name:string]: string}} */
623
+ /** @type {Record<string,LogLevel>} */
592
624
  let serviceLevels = {};
593
625
 
594
626
  if (typeof nameOrConfig === 'string') {
@@ -609,7 +641,9 @@ export class ServiceManager extends EventEmitter {
609
641
  serviceLevels = nameOrConfig;
610
642
  }
611
643
 
644
+ // Ensure serviceLogLevels is initialized as an object
612
645
  if (!this.config.serviceLogLevels) {
646
+ /** @type {Record<string,LogLevel>} */
613
647
  this.config.serviceLogLevels = {};
614
648
  }
615
649
 
@@ -617,10 +651,10 @@ export class ServiceManager extends EventEmitter {
617
651
  for (const [name, logLevel] of Object.entries(serviceLevels)) {
618
652
  this.config.serviceLogLevels[name] = logLevel;
619
653
 
620
- // Apply to existing instance
621
- const instance = this.get(name);
622
- if (instance) {
623
- instance.setLogLevel(logLevel);
654
+ // Apply to existing instance if it exists and is registered
655
+ const entry = this.services.get(name);
656
+ if (entry?.instance) {
657
+ entry.instance.setLogLevel(logLevel);
624
658
  }
625
659
  }
626
660
  }
@@ -51,9 +51,7 @@ export type ServiceManagerConfig = {
51
51
  * - String: "auth:debug,database:info"
52
52
  * - Object: { auth: "debug", database: "info" }
53
53
  */
54
- serviceLogLevels?: string | {
55
- [x: string]: import("../../logging/typedef.js").LogLevel;
56
- } | undefined;
54
+ serviceLogLevels?: string | Record<string, import("../../logging/typedef.js").LogLevel> | undefined;
57
55
  };
58
56
  /**
59
57
  * Result of health check for all services
@@ -56,7 +56,7 @@
56
56
  * @property {number} [stopTimeout=10000] - Default timeout for stopping services
57
57
  * @property {LogLevel} [defaultLogLevel] - Default log level for new services
58
58
  * @property {LogLevel} [managerLogLevel] - Initial log level for ServiceManager
59
- * @property {string|Object<string,LogLevel>} [serviceLogLevels]
59
+ * @property {string|Record<string,LogLevel>} [serviceLogLevels]
60
60
  * Per-service log levels:
61
61
  * - String: "auth:debug,database:info"
62
62
  * - Object: { auth: "debug", database: "info" }
@@ -1,18 +1,17 @@
1
+ /** @typedef {import('../../logging/typedef.js').LogLevel} LogLevel */
1
2
  /**
2
3
  * Parse comma-separated service:level configuration string
3
4
  *
4
5
  * @param {string} configString
5
6
  * Comma-separated string like "auth:debug,database:info,cache:warn"
6
7
  *
7
- * @returns {Object<string, string>} Service name to log level mapping
8
+ * @returns {Record<string, LogLevel>} Service name to log level mapping
8
9
  *
9
10
  * @example
10
11
  * const config = parseServiceLogLevels("auth:debug,database:info");
11
12
  * // Returns: { auth: "debug", database: "info" }
12
13
  */
13
- export function parseServiceLogLevels(configString: string): {
14
- [x: string]: string;
15
- };
14
+ export function parseServiceLogLevels(configString: string): Record<string, LogLevel>;
16
15
  /**
17
16
  * Expand log levels to include higher severity levels
18
17
  *
@@ -33,3 +32,4 @@ export function expandLogLevels(serviceLevels: {
33
32
  }): {
34
33
  [x: string]: string[];
35
34
  };
35
+ export type LogLevel = import("../../logging/typedef.js").LogLevel;
@@ -7,13 +7,15 @@
7
7
 
8
8
  import { DEBUG, INFO, WARN, ERROR } from '../../logging/index.js';
9
9
 
10
+ /** @typedef {import('../../logging/typedef.js').LogLevel} LogLevel */
11
+
10
12
  /**
11
13
  * Parse comma-separated service:level configuration string
12
14
  *
13
15
  * @param {string} configString
14
16
  * Comma-separated string like "auth:debug,database:info,cache:warn"
15
17
  *
16
- * @returns {Object<string, string>} Service name to log level mapping
18
+ * @returns {Record<string, LogLevel>} Service name to log level mapping
17
19
  *
18
20
  * @example
19
21
  * const config = parseServiceLogLevels("auth:debug,database:info");
@@ -21,11 +23,11 @@ import { DEBUG, INFO, WARN, ERROR } from '../../logging/index.js';
21
23
  */
22
24
  export function parseServiceLogLevels(configString) {
23
25
  if (!configString || typeof configString !== 'string') {
24
- /** @type {Object<string, string>} */
26
+ /** @type {Record<string, LogLevel>} */
25
27
  return {};
26
28
  }
27
29
 
28
- /** @type {Object<string, string>} */
30
+ /** @type {Record<string, LogLevel>} */
29
31
  const result = {};
30
32
 
31
33
  const services = configString.split(',');
@@ -37,7 +39,7 @@ export function parseServiceLogLevels(configString) {
37
39
  const parts = trimmed.split(':');
38
40
  if (parts.length === 2) {
39
41
  const [serviceName, logLevel] = parts;
40
- result[serviceName.trim()] = logLevel.trim();
42
+ result[serviceName.trim()] = /** @type {LogLevel} */ (logLevel.trim());
41
43
  }
42
44
  }
43
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-core",
3
- "version": "0.4.42",
3
+ "version": "0.4.44",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"