@fjell/registry 4.4.16 → 4.4.20

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 (61) hide show
  1. package/build.js +4 -0
  2. package/dist/Coordinate.d.ts +2 -1
  3. package/dist/Coordinate.d.ts.map +1 -0
  4. package/dist/Instance.d.ts +3 -2
  5. package/dist/Instance.d.ts.map +1 -0
  6. package/dist/Registry.d.ts +1 -0
  7. package/dist/Registry.d.ts.map +1 -0
  8. package/dist/RegistryHub.d.ts +1 -0
  9. package/dist/RegistryHub.d.ts.map +1 -0
  10. package/dist/RegistryStats.d.ts +3 -1
  11. package/dist/RegistryStats.d.ts.map +1 -0
  12. package/dist/errors/CoordinateError.d.ts +1 -0
  13. package/dist/errors/CoordinateError.d.ts.map +1 -0
  14. package/dist/errors/InstanceError.d.ts +1 -0
  15. package/dist/errors/InstanceError.d.ts.map +1 -0
  16. package/dist/errors/RegistryError.d.ts +1 -0
  17. package/dist/errors/RegistryError.d.ts.map +1 -0
  18. package/dist/errors/RegistryHubError.d.ts +1 -0
  19. package/dist/errors/RegistryHubError.d.ts.map +1 -0
  20. package/dist/errors/index.d.ts +1 -0
  21. package/dist/errors/index.d.ts.map +1 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +685 -10
  25. package/dist/index.js.map +7 -0
  26. package/dist/logger.d.ts +2 -1
  27. package/dist/logger.d.ts.map +1 -0
  28. package/dist/types.d.ts +6 -4
  29. package/dist/types.d.ts.map +1 -0
  30. package/docs/docs.config.ts +1 -32
  31. package/docs/package-lock.json +5129 -0
  32. package/docs/package.json +2 -2
  33. package/docs/src/types.d.ts +13 -5
  34. package/docs/timing-range.svg +172 -0
  35. package/examples/multi-level-keys.ts +10 -2
  36. package/package.json +21 -33
  37. package/tsconfig.docs.json +28 -0
  38. package/vitest.config.ts +17 -0
  39. package/MIGRATION_SUMMARY.md +0 -200
  40. package/dist/Coordinate.cjs +0 -32
  41. package/dist/Coordinate.js +0 -28
  42. package/dist/Instance.cjs +0 -24
  43. package/dist/Instance.js +0 -19
  44. package/dist/Registry.cjs +0 -182
  45. package/dist/Registry.js +0 -178
  46. package/dist/RegistryHub.cjs +0 -94
  47. package/dist/RegistryHub.js +0 -90
  48. package/dist/RegistryStats.cjs +0 -200
  49. package/dist/RegistryStats.js +0 -196
  50. package/dist/errors/CoordinateError.cjs +0 -70
  51. package/dist/errors/CoordinateError.js +0 -63
  52. package/dist/errors/InstanceError.cjs +0 -101
  53. package/dist/errors/InstanceError.js +0 -92
  54. package/dist/errors/RegistryError.cjs +0 -82
  55. package/dist/errors/RegistryError.js +0 -75
  56. package/dist/errors/RegistryHubError.cjs +0 -92
  57. package/dist/errors/RegistryHubError.js +0 -84
  58. package/dist/index.cjs +0 -823
  59. package/dist/index.cjs.map +0 -1
  60. package/dist/logger.cjs +0 -10
  61. package/dist/logger.js +0 -6
package/dist/index.cjs DELETED
@@ -1,823 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const Logging = require('@fjell/logging');
6
-
7
- const LibLogger = Logging.getLogger('@fjell/registry');
8
-
9
- const logger$3 = LibLogger.get("Coordinate");
10
- const createCoordinate = (kta, scopes = [])=>{
11
- const ktArray = Array.isArray(kta) ? kta : [
12
- kta
13
- ];
14
- const toString = ()=>{
15
- logger$3.debug("toString", {
16
- kta,
17
- scopes
18
- });
19
- return `${ktArray.join(', ')} - ${scopes.join(', ')}`;
20
- };
21
- logger$3.debug("createCoordinate", {
22
- kta: ktArray,
23
- scopes,
24
- toString
25
- });
26
- return {
27
- kta: ktArray,
28
- scopes,
29
- toString
30
- };
31
- };
32
-
33
- const logger$2 = LibLogger.get("Instance");
34
- const createInstance = (registry, coordinate)=>{
35
- logger$2.debug("createInstance", {
36
- coordinate,
37
- registry
38
- });
39
- return {
40
- coordinate,
41
- registry
42
- };
43
- };
44
- const isInstance = (instance)=>{
45
- return instance !== null && instance !== undefined && instance.coordinate !== undefined && instance.registry !== undefined;
46
- };
47
-
48
- /**
49
- * Represents a service client (another service making the request)
50
- */ function _define_property$4(obj, key, value) {
51
- if (key in obj) {
52
- Object.defineProperty(obj, key, {
53
- value: value,
54
- enumerable: true,
55
- configurable: true,
56
- writable: true
57
- });
58
- } else {
59
- obj[key] = value;
60
- }
61
- return obj;
62
- }
63
- /**
64
- * Internal class for tracking Registry statistics with complex coordinate combinations and client tracking
65
- */ class RegistryStats {
66
- /**
67
- * Records a get() call for the specified coordinate and client
68
- */ recordGetCall(kta, scopes, client) {
69
- this.totalCalls++;
70
- const ktaKey = kta.join('.');
71
- const scopeKey = this.createScopeKey(scopes || []);
72
- const clientKey = this.createClientKey(client);
73
- if (!this.coordinateCalls.has(ktaKey)) {
74
- this.coordinateCalls.set(ktaKey, new Map());
75
- }
76
- const scopeMap = this.coordinateCalls.get(ktaKey);
77
- if (!scopeMap.has(scopeKey)) {
78
- scopeMap.set(scopeKey, new Map());
79
- }
80
- const clientMap = scopeMap.get(scopeKey);
81
- const currentCount = clientMap.get(clientKey) || 0;
82
- clientMap.set(clientKey, currentCount + 1);
83
- }
84
- /**
85
- * Gets the current statistics snapshot
86
- */ getStatistics() {
87
- const coordinateCallRecords = [];
88
- let serviceCalls = 0;
89
- let applicationCalls = 0;
90
- let unidentifiedCalls = 0;
91
- for (const [ktaKey, scopeMap] of this.coordinateCalls){
92
- for (const [scopeKey, clientMap] of scopeMap){
93
- const clientCalls = [];
94
- let totalCount = 0;
95
- for (const [clientKey, count] of clientMap){
96
- const client = this.parseClientKey(clientKey);
97
- if (client !== null) {
98
- clientCalls.push({
99
- client,
100
- count
101
- });
102
- }
103
- totalCount += count;
104
- // Update client summary
105
- if (clientKey === '__no_client__') {
106
- unidentifiedCalls += count;
107
- } else if (typeof client === 'string') {
108
- applicationCalls += count;
109
- } else if (client !== null) {
110
- serviceCalls += count;
111
- }
112
- }
113
- coordinateCallRecords.push({
114
- kta: ktaKey.split('.'),
115
- scopes: this.parseScopeKey(scopeKey),
116
- count: totalCount,
117
- clientCalls: [
118
- ...clientCalls
119
- ] // Return a copy
120
- });
121
- }
122
- }
123
- return {
124
- totalGetCalls: this.totalCalls,
125
- coordinateCallRecords: [
126
- ...coordinateCallRecords
127
- ],
128
- clientSummary: {
129
- serviceCalls,
130
- applicationCalls,
131
- unidentifiedCalls
132
- }
133
- };
134
- }
135
- /**
136
- * Gets call count for a specific coordinate combination
137
- */ getCallCount(kta, scopes) {
138
- const ktaKey = kta.join('.');
139
- const scopeKey = this.createScopeKey(scopes || []);
140
- const scopeMap = this.coordinateCalls.get(ktaKey);
141
- if (!scopeMap) return 0;
142
- const clientMap = scopeMap.get(scopeKey);
143
- if (!clientMap) return 0;
144
- let total = 0;
145
- for (const count of clientMap.values()){
146
- total += count;
147
- }
148
- return total;
149
- }
150
- /**
151
- * Gets call count for a specific coordinate combination from a specific client
152
- */ getCallCountByClient(kta, scopes, client) {
153
- const ktaKey = kta.join('.');
154
- const scopeKey = this.createScopeKey(scopes || []);
155
- const clientKey = this.createClientKey(client);
156
- const scopeMap = this.coordinateCalls.get(ktaKey);
157
- if (!scopeMap) return 0;
158
- const clientMap = scopeMap.get(scopeKey);
159
- if (!clientMap) return 0;
160
- return clientMap.get(clientKey) || 0;
161
- }
162
- /**
163
- * Gets total calls for a specific kta (across all scopes)
164
- */ getTotalCallsForKta(kta) {
165
- const ktaKey = kta.join('.');
166
- const scopeMap = this.coordinateCalls.get(ktaKey);
167
- if (!scopeMap) return 0;
168
- let total = 0;
169
- for (const clientMap of scopeMap.values()){
170
- for (const count of clientMap.values()){
171
- total += count;
172
- }
173
- }
174
- return total;
175
- }
176
- /**
177
- * Gets all unique kta paths that have been called
178
- */ getCalledKtaPaths() {
179
- const ktaPaths = [];
180
- for (const ktaKey of this.coordinateCalls.keys()){
181
- ktaPaths.push(ktaKey.split('.'));
182
- }
183
- return ktaPaths;
184
- }
185
- /**
186
- * Creates a normalized scope key from scopes array
187
- */ createScopeKey(scopes) {
188
- if (scopes.length === 0) return '__no_scopes__';
189
- return [
190
- ...scopes
191
- ].sort().join(',');
192
- }
193
- /**
194
- * Parses a scope key back to scopes array
195
- */ parseScopeKey(scopeKey) {
196
- if (scopeKey === '__no_scopes__') return [];
197
- return scopeKey.split(',');
198
- }
199
- /**
200
- * Creates a normalized client key from client identifier
201
- */ createClientKey(client) {
202
- if (!client) return '__no_client__';
203
- if (typeof client === 'string') {
204
- return `app:${client}`;
205
- }
206
- // Service client
207
- const coordKey = `${client.coordinate.kta.join('.')};${this.createScopeKey(client.coordinate.scopes)}`;
208
- return `service:${client.registryType}:${coordKey}`;
209
- }
210
- /**
211
- * Parses a client key back to client identifier
212
- */ parseClientKey(clientKey) {
213
- if (clientKey === '__no_client__') return null;
214
- if (clientKey.startsWith('app:')) {
215
- return clientKey.substring(4);
216
- }
217
- if (clientKey.startsWith('service:')) {
218
- const parts = clientKey.substring(8).split(':');
219
- if (parts.length !== 2) return null;
220
- const registryType = parts[0];
221
- const coordParts = parts[1].split(';');
222
- if (coordParts.length !== 2) return null;
223
- const kta = coordParts[0].split('.');
224
- const scopes = this.parseScopeKey(coordParts[1]);
225
- return {
226
- registryType,
227
- coordinate: {
228
- kta,
229
- scopes
230
- }
231
- };
232
- }
233
- return null;
234
- }
235
- constructor(){
236
- _define_property$4(this, "totalCalls", 0);
237
- // Map structure: ktaKey -> scopeKey -> clientKey -> count
238
- _define_property$4(this, "coordinateCalls", new Map());
239
- }
240
- }
241
-
242
- const logger$1 = LibLogger.get("Registry");
243
- const findScopedInstance = (scopedInstances, requestedScopes)=>{
244
- if (!requestedScopes || requestedScopes.length === 0) {
245
- var _scopedInstances_;
246
- // Return first instance if no scopes specified
247
- const firstInstance = (_scopedInstances_ = scopedInstances[0]) === null || _scopedInstances_ === void 0 ? void 0 : _scopedInstances_.instance;
248
- if (!firstInstance) {
249
- throw new Error('No instances available');
250
- }
251
- return firstInstance;
252
- }
253
- // Find instance that matches all requested scopes
254
- const matchingInstance = scopedInstances.find((scopedInstance)=>{
255
- if (!scopedInstance.scopes) return false;
256
- return requestedScopes.every((scope)=>scopedInstance.scopes && scopedInstance.scopes.includes(scope));
257
- });
258
- if (!matchingInstance) {
259
- throw new Error(`No instance found matching scopes: ${requestedScopes.join(', ')}`);
260
- }
261
- return matchingInstance.instance;
262
- };
263
- const createRegistry = (type, registryHub)=>{
264
- const instanceTree = {};
265
- // Statistics tracking
266
- const registryStats = new RegistryStats();
267
- /**
268
- * Creates a proxied Registry that automatically injects client information for service-to-service calls
269
- */ const createProxiedRegistry = (callingCoordinate)=>{
270
- const serviceClient = {
271
- registryType: type,
272
- coordinate: {
273
- kta: callingCoordinate.kta,
274
- scopes: callingCoordinate.scopes
275
- }
276
- };
277
- return {
278
- ...registry,
279
- get: (kta, options)=>{
280
- // Automatically inject the calling service as the client if no client is specified
281
- const clientToUse = (options === null || options === void 0 ? void 0 : options.client) || serviceClient;
282
- return registry.get(kta, {
283
- ...options,
284
- client: clientToUse
285
- });
286
- }
287
- };
288
- };
289
- const createInstance = (kta, scopes, factory)=>{
290
- logger$1.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
291
- // Create coordinate for the instance
292
- const coordinate = createCoordinate(kta, scopes);
293
- // Create a proxied registry that automatically tracks this service as the client
294
- const proxiedRegistry = createProxiedRegistry(coordinate);
295
- // Use factory to create the instance with the proxied registry
296
- const instance = factory(coordinate, {
297
- registry: proxiedRegistry,
298
- registryHub
299
- });
300
- // Validate the created instance
301
- if (!isInstance(instance)) {
302
- throw new Error(`Factory did not return a valid instance for: ${kta.join('.')}`);
303
- }
304
- // Register the instance
305
- registerInternal(kta, instance, {
306
- scopes
307
- });
308
- return instance;
309
- };
310
- const registerInternal = (kta, instance, options)=>{
311
- const keyPath = [
312
- ...kta
313
- ].reverse(); // Work from most specific to least specific
314
- let currentLevel = instanceTree;
315
- logger$1.debug(`Registering instance for key path and scopes`, keyPath, options === null || options === void 0 ? void 0 : options.scopes, `in registry type: ${type}`);
316
- if (!isInstance(instance)) {
317
- throw new Error(`Attempting to register a non-instance: ${kta.join('.')}`);
318
- }
319
- // Navigate to the correct location in the tree
320
- for(let i = 0; i < keyPath.length; i++){
321
- const keyType = keyPath[i];
322
- const isLeaf = i === keyPath.length - 1;
323
- if (!currentLevel[keyType]) {
324
- currentLevel[keyType] = {
325
- instances: [],
326
- children: isLeaf ? null : {}
327
- };
328
- }
329
- if (isLeaf) {
330
- // Add instance to the leaf node
331
- currentLevel[keyType].instances.push({
332
- scopes: options === null || options === void 0 ? void 0 : options.scopes,
333
- instance
334
- });
335
- } else {
336
- // Navigate deeper into the tree
337
- if (!currentLevel[keyType].children) {
338
- currentLevel[keyType].children = {};
339
- }
340
- currentLevel = currentLevel[keyType].children;
341
- }
342
- }
343
- };
344
- const register = (kta, instance, options)=>{
345
- logger$1.debug('Using deprecated register method. Consider using createInstance instead.');
346
- registerInternal(kta, instance, options);
347
- };
348
- const get = (kta, options)=>{
349
- // Track statistics with kta, scopes, and client
350
- registryStats.recordGetCall(kta, options === null || options === void 0 ? void 0 : options.scopes, options === null || options === void 0 ? void 0 : options.client);
351
- const keyPath = [
352
- ...kta
353
- ].reverse();
354
- let currentLevel = instanceTree;
355
- // Navigate to the target node
356
- for(let i = 0; i < keyPath.length; i++){
357
- const keyType = keyPath[i];
358
- const isLeaf = i === keyPath.length - 1;
359
- if (!currentLevel[keyType]) {
360
- throw new Error(`Instance not found for key path: ${kta.join('.')}, Missing key: ${keyType}`);
361
- }
362
- if (isLeaf) {
363
- // Found the target node, extract instance
364
- const scopedInstances = currentLevel[keyType].instances;
365
- if (scopedInstances.length === 0) {
366
- throw new Error(`No instances registered for key path: ${kta.join('.')}`);
367
- }
368
- return findScopedInstance(scopedInstances, options === null || options === void 0 ? void 0 : options.scopes);
369
- } else {
370
- // Continue navigation
371
- if (!currentLevel[keyType].children) {
372
- throw new Error(`Instance not found for key path: ${kta.join('.')}, No children for: ${keyType}`);
373
- }
374
- currentLevel = currentLevel[keyType].children;
375
- }
376
- }
377
- return null;
378
- };
379
- const getCoordinates = ()=>{
380
- const coordinates = [];
381
- const traverseTree = (node)=>{
382
- for(const keyType in node){
383
- const treeNode = node[keyType];
384
- // Collect coordinates from instances at this level
385
- for (const scopedInstance of treeNode.instances){
386
- coordinates.push(scopedInstance.instance.coordinate);
387
- }
388
- // Recursively traverse children if they exist
389
- if (treeNode.children) {
390
- traverseTree(treeNode.children);
391
- }
392
- }
393
- };
394
- traverseTree(instanceTree);
395
- return coordinates;
396
- };
397
- const getStatistics = ()=>{
398
- return registryStats.getStatistics();
399
- };
400
- const registry = {
401
- type,
402
- registryHub,
403
- createInstance,
404
- register,
405
- get,
406
- getCoordinates,
407
- getStatistics,
408
- instanceTree
409
- };
410
- return registry;
411
- };
412
-
413
- /**
414
- * Base class for all registry-related errors
415
- */ function _define_property$3(obj, key, value) {
416
- if (key in obj) {
417
- Object.defineProperty(obj, key, {
418
- value: value,
419
- enumerable: true,
420
- configurable: true,
421
- writable: true
422
- });
423
- } else {
424
- obj[key] = value;
425
- }
426
- return obj;
427
- }
428
- class RegistryError extends Error {
429
- getDetails() {
430
- const details = [
431
- this.message
432
- ];
433
- if (this.registryType) {
434
- details.push(`Registry Type: ${this.registryType}`);
435
- }
436
- if (this.context) {
437
- details.push(`Context: ${JSON.stringify(this.context, null, 2)}`);
438
- }
439
- return details.join('\n');
440
- }
441
- constructor(message, registryType, context){
442
- super(message), _define_property$3(this, "registryType", void 0), _define_property$3(this, "context", void 0);
443
- this.name = this.constructor.name;
444
- this.registryType = registryType;
445
- this.context = context;
446
- // Maintains proper stack trace for where our error was thrown
447
- if (Error.captureStackTrace) {
448
- Error.captureStackTrace(this, this.constructor);
449
- }
450
- }
451
- }
452
- /**
453
- * Thrown when attempting to create a registry with invalid parameters
454
- */ class RegistryCreationError extends RegistryError {
455
- constructor(type, reason, context){
456
- super(`Failed to create registry of type '${type}': ${reason}`, type, context);
457
- }
458
- }
459
- /**
460
- * Thrown when a factory function returns an invalid instance
461
- */ class InvalidFactoryResultError extends RegistryError {
462
- constructor(keyPath, factoryResult, registryType){
463
- const keyPathStr = keyPath.join('.');
464
- super(`Factory did not return a valid instance for: ${keyPathStr}. ` + `Expected instance with 'coordinate' and 'registry' properties, got: ${typeof factoryResult}`, registryType, {
465
- keyPath,
466
- factoryResult: typeof factoryResult
467
- }), _define_property$3(this, "keyPath", void 0), _define_property$3(this, "factoryResult", void 0);
468
- this.keyPath = keyPath;
469
- this.factoryResult = factoryResult;
470
- }
471
- }
472
- /**
473
- * Thrown when attempting to register a non-instance object
474
- */ class InvalidInstanceRegistrationError extends RegistryError {
475
- constructor(keyPath, attemptedRegistration, registryType){
476
- const keyPathStr = keyPath.join('.');
477
- super(`Attempting to register a non-instance: ${keyPathStr}. ` + `Expected instance with 'coordinate' and 'registry' properties, got: ${typeof attemptedRegistration}`, registryType, {
478
- keyPath,
479
- attemptedRegistration: typeof attemptedRegistration
480
- }), _define_property$3(this, "keyPath", void 0), _define_property$3(this, "attemptedRegistration", void 0);
481
- this.keyPath = keyPath;
482
- this.attemptedRegistration = attemptedRegistration;
483
- }
484
- }
485
-
486
- function _define_property$2(obj, key, value) {
487
- if (key in obj) {
488
- Object.defineProperty(obj, key, {
489
- value: value,
490
- enumerable: true,
491
- configurable: true,
492
- writable: true
493
- });
494
- } else {
495
- obj[key] = value;
496
- }
497
- return obj;
498
- }
499
- /**
500
- * Base class for registry hub-related errors
501
- */ class RegistryHubError extends RegistryError {
502
- constructor(message, hubType, context){
503
- const enrichedContext = hubType ? {
504
- ...context,
505
- hubType
506
- } : context;
507
- super(message, '', enrichedContext), _define_property$2(this, "hubType", void 0);
508
- this.hubType = hubType;
509
- }
510
- }
511
- /**
512
- * Thrown when attempting to register a registry with a type that already exists
513
- */ class DuplicateRegistryTypeError extends RegistryHubError {
514
- constructor(type, context){
515
- super(`Registry already registered under type: ${type}. ` + `Each registry type must be unique within a registry hub.`, '', {
516
- ...context,
517
- duplicateType: type
518
- }), _define_property$2(this, "duplicateType", void 0);
519
- this.duplicateType = type;
520
- }
521
- }
522
- /**
523
- * Thrown when attempting to access a registry type that doesn't exist
524
- */ class RegistryTypeNotFoundError extends RegistryHubError {
525
- constructor(requestedType, availableTypes = [], context){
526
- let message = `No registry registered under type: ${requestedType}`;
527
- if (availableTypes.length > 0) {
528
- message += `. Available types: [${availableTypes.join(', ')}]`;
529
- }
530
- super(message, '', {
531
- ...context,
532
- requestedType,
533
- availableTypes
534
- }), _define_property$2(this, "requestedType", void 0), _define_property$2(this, "availableTypes", void 0);
535
- this.requestedType = requestedType;
536
- this.availableTypes = availableTypes;
537
- }
538
- }
539
- /**
540
- * Thrown when a registry factory function fails to create a valid registry
541
- */ class RegistryFactoryError extends RegistryHubError {
542
- constructor(type, factoryError, context){
543
- super(`Registry factory failed to create registry of type '${type}': ${factoryError.message}`, '', {
544
- ...context,
545
- attemptedType: type,
546
- originalError: factoryError.message
547
- }), _define_property$2(this, "factoryError", void 0), _define_property$2(this, "attemptedType", void 0);
548
- this.factoryError = factoryError;
549
- this.attemptedType = type;
550
- }
551
- }
552
- /**
553
- * Thrown when a factory returns an invalid registry object
554
- */ class InvalidRegistryFactoryResultError extends RegistryHubError {
555
- constructor(type, factoryResult, context){
556
- super(`Registry factory returned invalid registry for type '${type}'. ` + `Expected registry with 'type', 'get', 'register', and 'createInstance' properties, ` + `got: ${typeof factoryResult}`, '', {
557
- ...context,
558
- attemptedType: type,
559
- factoryResult: typeof factoryResult
560
- }), _define_property$2(this, "factoryResult", void 0), _define_property$2(this, "attemptedType", void 0);
561
- this.factoryResult = factoryResult;
562
- this.attemptedType = type;
563
- }
564
- }
565
-
566
- const logger = LibLogger.get("RegistryHub");
567
- const createRegistryHub = ()=>{
568
- const registries = {};
569
- const createRegistry = (type, factory)=>{
570
- logger.debug(`Creating new registry with type: ${type}`);
571
- if (registries[type]) {
572
- throw new DuplicateRegistryTypeError(type);
573
- }
574
- // Create the registry with a reference to this hub
575
- const registry = factory(type, hub);
576
- // Ensure the created registry has a reference to this hub if not already set
577
- if (!('registryHub' in registry) || registry.registryHub !== hub) {
578
- // @ts-expect-error: registryHub is optional and may be readonly, but we want to set it for hub awareness
579
- registry.registryHub = hub;
580
- }
581
- // Register the created registry
582
- registries[type] = registry;
583
- logger.debug(`Successfully created and registered new registry with type: ${type}`);
584
- return registry;
585
- };
586
- const registerRegistry = (registry)=>{
587
- const type = registry.type;
588
- logger.debug(`Registering registry with type: ${type}`);
589
- if (registries[type]) {
590
- throw new DuplicateRegistryTypeError(type);
591
- }
592
- registries[type] = registry;
593
- // Ensure the created registry has a reference to this hub if not already set
594
- if (!('registryHub' in registry) || registry.registryHub !== hub) {
595
- // @ts-expect-error: registryHub is optional and may be readonly, but we want to set it for hub awareness
596
- registry.registryHub = hub;
597
- }
598
- logger.debug(`Successfully registered registry with type: ${type}`);
599
- };
600
- const get = (type, kta, options)=>{
601
- var _options_scopes;
602
- logger.debug(`Looking up instance for type: ${type}, kta: ${kta.join('.')}, scopes: ${(options === null || options === void 0 ? void 0 : (_options_scopes = options.scopes) === null || _options_scopes === void 0 ? void 0 : _options_scopes.join(',')) || 'none'}`);
603
- const registry = registries[type];
604
- if (!registry) {
605
- const availableTypes = Object.keys(registries);
606
- throw new RegistryTypeNotFoundError(type, availableTypes);
607
- }
608
- return registry.get(kta, options);
609
- };
610
- const getRegistry = (type)=>{
611
- return registries[type] || null;
612
- };
613
- const getRegisteredTypes = ()=>{
614
- return Object.keys(registries);
615
- };
616
- const unregisterRegistry = (type)=>{
617
- if (registries[type]) {
618
- delete registries[type];
619
- logger.debug(`Unregistered registry under type: ${type}`);
620
- return true;
621
- }
622
- return false;
623
- };
624
- const getAllCoordinates = ()=>{
625
- const allCoordinates = [];
626
- for(const registryType in registries){
627
- const registry = registries[registryType];
628
- const coordinates = registry.getCoordinates();
629
- coordinates.forEach((coordinate)=>{
630
- allCoordinates.push({
631
- coordinate,
632
- registryType
633
- });
634
- });
635
- }
636
- logger.debug(`Retrieved ${allCoordinates.length} total coordinates from ${Object.keys(registries).length} registries`);
637
- return allCoordinates;
638
- };
639
- const hub = {
640
- createRegistry,
641
- registerRegistry,
642
- get,
643
- getRegistry,
644
- getRegisteredTypes,
645
- getAllCoordinates,
646
- unregisterRegistry
647
- };
648
- return hub;
649
- };
650
-
651
- function _define_property$1(obj, key, value) {
652
- if (key in obj) {
653
- Object.defineProperty(obj, key, {
654
- value: value,
655
- enumerable: true,
656
- configurable: true,
657
- writable: true
658
- });
659
- } else {
660
- obj[key] = value;
661
- }
662
- return obj;
663
- }
664
- /**
665
- * Base class for instance-related errors
666
- */ class InstanceError extends RegistryError {
667
- constructor(message, keyPath, registryType, context){
668
- super(message, registryType, {
669
- ...context,
670
- keyPath
671
- }), _define_property$1(this, "keyPath", void 0);
672
- this.keyPath = keyPath;
673
- }
674
- }
675
- /**
676
- * Thrown when an instance cannot be found for a given key path
677
- */ class InstanceNotFoundError extends InstanceError {
678
- constructor(keyPath, missingKey, registryType, context){
679
- const keyPathStr = keyPath.join('.');
680
- let message = `Instance not found for key path: ${keyPathStr}`;
681
- if (missingKey) {
682
- message += `, Missing key: ${missingKey}`;
683
- }
684
- super(message, keyPath, registryType, {
685
- ...context,
686
- missingKey
687
- }), _define_property$1(this, "missingKey", void 0);
688
- this.missingKey = missingKey;
689
- }
690
- }
691
- /**
692
- * Thrown when no instances are registered for a key path that exists in the tree
693
- */ class NoInstancesRegisteredError extends InstanceError {
694
- constructor(keyPath, registryType, context){
695
- const keyPathStr = keyPath.join('.');
696
- super(`No instances registered for key path: ${keyPathStr}. ` + `The key path exists in the registry tree but contains no instances.`, keyPath, registryType, context);
697
- }
698
- }
699
- /**
700
- * Thrown when no instances are available (empty instances array)
701
- */ class NoInstancesAvailableError extends InstanceError {
702
- constructor(keyPath, registryType, context){
703
- const keyPathStr = keyPath.join('.');
704
- super(`No instances available for key path: ${keyPathStr}. ` + `This typically indicates an internal registry state issue.`, keyPath, registryType, context);
705
- }
706
- }
707
- /**
708
- * Thrown when no instance matches the requested scopes
709
- */ class ScopeNotFoundError extends InstanceError {
710
- constructor(keyPath, requestedScopes, availableScopes = [], registryType){
711
- const keyPathStr = keyPath.join('.');
712
- const scopesStr = requestedScopes.join(', ');
713
- const availableScopesStr = availableScopes.map((scopes)=>`[${scopes.join(', ')}]`).join(', ');
714
- let message = `No instance found matching scopes: ${scopesStr} for key path: ${keyPathStr}`;
715
- if (availableScopes.length > 0) {
716
- message += `. Available scopes: ${availableScopesStr}`;
717
- }
718
- super(message, keyPath, registryType, {
719
- requestedScopes,
720
- availableScopes
721
- }), _define_property$1(this, "requestedScopes", void 0), _define_property$1(this, "availableScopes", void 0);
722
- this.requestedScopes = requestedScopes;
723
- this.availableScopes = availableScopes;
724
- }
725
- }
726
- /**
727
- * Thrown when a key path has no children but children are expected
728
- */ class NoChildrenAvailableError extends InstanceError {
729
- constructor(keyPath, parentKey, registryType, context){
730
- const keyPathStr = keyPath.join('.');
731
- super(`Instance not found for key path: ${keyPathStr}, No children for: ${parentKey}. ` + `The path cannot be traversed further as '${parentKey}' has no child nodes.`, keyPath, registryType, {
732
- ...context,
733
- parentKey
734
- }), _define_property$1(this, "parentKey", void 0);
735
- this.parentKey = parentKey;
736
- }
737
- }
738
-
739
- function _define_property(obj, key, value) {
740
- if (key in obj) {
741
- Object.defineProperty(obj, key, {
742
- value: value,
743
- enumerable: true,
744
- configurable: true,
745
- writable: true
746
- });
747
- } else {
748
- obj[key] = value;
749
- }
750
- return obj;
751
- }
752
- /**
753
- * Base class for coordinate-related errors
754
- */ class CoordinateError extends RegistryError {
755
- constructor(message, kta, scopes, context){
756
- super(message, '', {
757
- ...context,
758
- kta,
759
- scopes
760
- }), _define_property(this, "kta", void 0), _define_property(this, "scopes", void 0);
761
- this.kta = kta;
762
- this.scopes = scopes;
763
- }
764
- }
765
- /**
766
- * Thrown when coordinate creation fails due to invalid parameters
767
- */ class InvalidCoordinateError extends CoordinateError {
768
- constructor(kta, scopes, reason, context){
769
- super(`Invalid coordinate parameters: ${reason}. ` + `KTA: ${JSON.stringify(kta)}, Scopes: [${scopes.join(', ')}]`, kta, scopes, {
770
- ...context,
771
- reason
772
- });
773
- }
774
- }
775
- /**
776
- * Thrown when KTA (Key Type Array) is invalid
777
- */ class InvalidKTAError extends CoordinateError {
778
- constructor(kta, reason, context){
779
- super(`Invalid KTA (Key Type Array): ${reason}. ` + `Expected string or array of strings, got: ${JSON.stringify(kta)}`, kta, [], {
780
- ...context,
781
- reason
782
- });
783
- }
784
- }
785
- /**
786
- * Thrown when scopes array contains invalid values
787
- */ class InvalidScopesError extends CoordinateError {
788
- constructor(scopes, invalidScopes, reason, context){
789
- super(`Invalid scopes: ${reason}. ` + `Invalid scope values: ${JSON.stringify(invalidScopes)}`, null, scopes.filter((s)=>typeof s === 'string'), {
790
- ...context,
791
- reason,
792
- invalidScopes
793
- }), _define_property(this, "invalidScopes", void 0);
794
- this.invalidScopes = invalidScopes;
795
- }
796
- }
797
-
798
- exports.CoordinateError = CoordinateError;
799
- exports.DuplicateRegistryTypeError = DuplicateRegistryTypeError;
800
- exports.InstanceError = InstanceError;
801
- exports.InstanceNotFoundError = InstanceNotFoundError;
802
- exports.InvalidCoordinateError = InvalidCoordinateError;
803
- exports.InvalidFactoryResultError = InvalidFactoryResultError;
804
- exports.InvalidInstanceRegistrationError = InvalidInstanceRegistrationError;
805
- exports.InvalidKTAError = InvalidKTAError;
806
- exports.InvalidRegistryFactoryResultError = InvalidRegistryFactoryResultError;
807
- exports.InvalidScopesError = InvalidScopesError;
808
- exports.NoChildrenAvailableError = NoChildrenAvailableError;
809
- exports.NoInstancesAvailableError = NoInstancesAvailableError;
810
- exports.NoInstancesRegisteredError = NoInstancesRegisteredError;
811
- exports.RegistryCreationError = RegistryCreationError;
812
- exports.RegistryError = RegistryError;
813
- exports.RegistryFactoryError = RegistryFactoryError;
814
- exports.RegistryHubError = RegistryHubError;
815
- exports.RegistryStats = RegistryStats;
816
- exports.RegistryTypeNotFoundError = RegistryTypeNotFoundError;
817
- exports.ScopeNotFoundError = ScopeNotFoundError;
818
- exports.createCoordinate = createCoordinate;
819
- exports.createInstance = createInstance;
820
- exports.createRegistry = createRegistry;
821
- exports.createRegistryHub = createRegistryHub;
822
- exports.isInstance = isInstance;
823
- //# sourceMappingURL=index.cjs.map