@hkdigital/lib-core 0.4.53 → 0.4.55

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.
@@ -199,6 +199,56 @@ const health = await manager.checkHealth();
199
199
  await manager.stopAll();
200
200
  ```
201
201
 
202
+ ### Service Access Patterns
203
+
204
+ Services receive helpful utilities in their constructor options for accessing other services:
205
+
206
+ ```javascript
207
+ class AuthService extends ServiceBase {
208
+ constructor(serviceName, options) {
209
+ super(serviceName, options);
210
+
211
+ // Store service access utilities
212
+ this.getManager = options.getManager; // Function to get manager (lazy)
213
+ this.getService = options.getService; // Bound getService function
214
+ }
215
+
216
+ async authenticateUser(credentials) {
217
+ // Access other services with full type safety and error checking
218
+ const database = this.getService('database');
219
+ const user = await database.findUser(credentials.username);
220
+
221
+ // Access manager for advanced operations
222
+ const manager = this.getManager();
223
+ const health = await manager.checkHealth();
224
+
225
+ return user;
226
+ }
227
+ }
228
+ ```
229
+
230
+ **Service Access Methods:**
231
+
232
+ ```javascript
233
+ // ServiceManager provides two access patterns:
234
+
235
+ // 1. Permissive - returns undefined if not found/created
236
+ const service = manager.get('optional-service');
237
+ if (service) {
238
+ // Use service safely
239
+ }
240
+
241
+ // 2. Strict - throws error if not found/created
242
+ const service = manager.getService('required-service'); // Throws if missing
243
+ ```
244
+
245
+ **Benefits of constructor utilities:**
246
+
247
+ - **Lightweight** - Functions don't serialize, keeping services serialization-safe
248
+ - **Lazy access** - Manager is only accessed when needed
249
+ - **Type safety** - Full generic support with `getService<DatabaseService>('database')`
250
+ - **Error handling** - Clear errors when services are missing
251
+
202
252
  ### Service Registration
203
253
 
204
254
  ```javascript
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Create a getService function with a preset manager
3
+ *
4
+ * @param {import('./service-manager/ServiceManager.js').default} manager
5
+ * ServiceManager instance to use
6
+ *
7
+ * @returns {<T>(serviceName: string) => T} getService function with preset manager
8
+ */
9
+ export function createGetService(manager: import("./service-manager/ServiceManager.js").default): <T>(serviceName: string) => T;
1
10
  export { default as ServiceBase } from "./service-base/ServiceBase.js";
2
11
  export { default as ServiceManager } from "./service-manager/ServiceManager.js";
3
12
  export * from "./service-base/constants.js";
@@ -3,3 +3,33 @@ export { default as ServiceManager } from './service-manager/ServiceManager.js';
3
3
 
4
4
  export * from './service-base/constants.js';
5
5
  export * from './service-manager/constants.js';
6
+
7
+ /**
8
+ * Create a getService function with a preset manager
9
+ *
10
+ * @param {import('./service-manager/ServiceManager.js').default} manager
11
+ * ServiceManager instance to use
12
+ *
13
+ * @returns {<T>(serviceName: string) => T} getService function with preset manager
14
+ */
15
+ export function createGetService(manager) {
16
+ /**
17
+ * Get a typed service instance from the preset manager
18
+ *
19
+ * @template T
20
+ * @param {string} serviceName - Name of the service to retrieve
21
+ *
22
+ * @returns {T} The service instance cast to the specified type
23
+ *
24
+ * @throws {Error} If service is not found
25
+ */
26
+ return function getService(serviceName) {
27
+ const service = manager.get(serviceName);
28
+
29
+ if (!service) {
30
+ throw new Error(`Service [${serviceName}] not found`);
31
+ }
32
+
33
+ return /** @type {T} */ (service);
34
+ };
35
+ }
@@ -19,7 +19,14 @@ export type ServiceState = "not-created" | "created" | "configuring" | "configur
19
19
  * Options for creating a service instance
20
20
  */
21
21
  export type ServiceOptions = {
22
- manager: import("../service-manager/ServiceManager.js").default;
22
+ /**
23
+ * - Function to get manager instance
24
+ */
25
+ getManager: () => import("../service-manager/ServiceManager.js").default;
26
+ /**
27
+ * - Bound getService function
28
+ */
29
+ getService: <T>(serviceName: string) => T;
23
30
  /**
24
31
  * - Initial log level for the service
25
32
  */
@@ -53,7 +53,8 @@
53
53
  * Options for creating a service instance
54
54
  *
55
55
  * @typedef {Object} ServiceOptions
56
- * @property {import('../service-manager/ServiceManager.js').default} manager
56
+ * @property {() => import('../service-manager/ServiceManager.js').default} getManager - Function to get manager instance
57
+ * @property {<T>(serviceName: string) => T} getService - Bound getService function
57
58
  * @property {import('../../logging/typedef.js').LogLevel} [logLevel] - Initial log level for the service
58
59
  * @property {number} [shutdownTimeout=5000] - Timeout for graceful shutdown
59
60
  */
@@ -269,7 +269,10 @@ export class ServiceManager extends EventEmitter {
269
269
 
270
270
  if (!entry.instance) {
271
271
  try {
272
- const options = { manager: this };
272
+ const options = {
273
+ getManager: () => this,
274
+ getService: this.getService.bind(this)
275
+ };
273
276
 
274
277
  entry.instance = new entry.ServiceClass(name, options);
275
278
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-core",
3
- "version": "0.4.53",
3
+ "version": "0.4.55",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"