@fjell/registry 4.4.17 → 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 (60) 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 +1 -0
  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 +1 -0
  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 +40 -40
  35. package/package.json +21 -33
  36. package/tsconfig.docs.json +28 -0
  37. package/vitest.config.ts +17 -0
  38. package/MIGRATION_SUMMARY.md +0 -200
  39. package/dist/Coordinate.cjs +0 -32
  40. package/dist/Coordinate.js +0 -28
  41. package/dist/Instance.cjs +0 -24
  42. package/dist/Instance.js +0 -19
  43. package/dist/Registry.cjs +0 -182
  44. package/dist/Registry.js +0 -178
  45. package/dist/RegistryHub.cjs +0 -94
  46. package/dist/RegistryHub.js +0 -90
  47. package/dist/RegistryStats.cjs +0 -198
  48. package/dist/RegistryStats.js +0 -194
  49. package/dist/errors/CoordinateError.cjs +0 -70
  50. package/dist/errors/CoordinateError.js +0 -63
  51. package/dist/errors/InstanceError.cjs +0 -101
  52. package/dist/errors/InstanceError.js +0 -92
  53. package/dist/errors/RegistryError.cjs +0 -82
  54. package/dist/errors/RegistryError.js +0 -75
  55. package/dist/errors/RegistryHubError.cjs +0 -92
  56. package/dist/errors/RegistryHubError.js +0 -84
  57. package/dist/index.cjs +0 -821
  58. package/dist/index.cjs.map +0 -1
  59. package/dist/logger.cjs +0 -10
  60. package/dist/logger.js +0 -6
package/dist/index.js CHANGED
@@ -1,10 +1,685 @@
1
- export { createCoordinate } from './Coordinate.js';
2
- export { createInstance, isInstance } from './Instance.js';
3
- export { createRegistry } from './Registry.js';
4
- export { createRegistryHub } from './RegistryHub.js';
5
- export { RegistryStats } from './RegistryStats.js';
6
- export { InvalidFactoryResultError, InvalidInstanceRegistrationError, RegistryCreationError, RegistryError } from './errors/RegistryError.js';
7
- export { InstanceError, InstanceNotFoundError, NoChildrenAvailableError, NoInstancesAvailableError, NoInstancesRegisteredError, ScopeNotFoundError } from './errors/InstanceError.js';
8
- export { CoordinateError, InvalidCoordinateError, InvalidKTAError, InvalidScopesError } from './errors/CoordinateError.js';
9
- export { DuplicateRegistryTypeError, InvalidRegistryFactoryResultError, RegistryFactoryError, RegistryHubError, RegistryTypeNotFoundError } from './errors/RegistryHubError.js';
10
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7OzsifQ==
1
+ // src/logger.ts
2
+ import Logging from "@fjell/logging";
3
+ var LibLogger = Logging.getLogger("@fjell/registry");
4
+ var logger_default = LibLogger;
5
+
6
+ // src/Coordinate.ts
7
+ var logger = logger_default.get("Coordinate");
8
+ var createCoordinate = (kta, scopes = []) => {
9
+ const ktArray = Array.isArray(kta) ? kta : [kta];
10
+ const toString = () => {
11
+ logger.debug("toString", { kta, scopes });
12
+ return `${ktArray.join(", ")} - ${scopes.join(", ")}`;
13
+ };
14
+ logger.debug("createCoordinate", { kta: ktArray, scopes, toString });
15
+ return { kta: ktArray, scopes, toString };
16
+ };
17
+
18
+ // src/Instance.ts
19
+ var logger2 = logger_default.get("Instance");
20
+ var createInstance = (registry, coordinate) => {
21
+ logger2.debug("createInstance", { coordinate, registry });
22
+ return { coordinate, registry };
23
+ };
24
+ var isInstance = (instance) => {
25
+ return instance !== null && instance !== void 0 && instance.coordinate !== void 0 && instance.registry !== void 0;
26
+ };
27
+
28
+ // src/RegistryStats.ts
29
+ var RegistryStats = class {
30
+ totalCalls = 0;
31
+ // Map structure: ktaKey -> scopeKey -> clientKey -> count
32
+ coordinateCalls = /* @__PURE__ */ new Map();
33
+ /**
34
+ * Records a get() call for the specified coordinate and client
35
+ */
36
+ recordGetCall(kta, scopes, client) {
37
+ this.totalCalls++;
38
+ const ktaKey = kta.join(".");
39
+ const scopeKey = this.createScopeKey(scopes || []);
40
+ const clientKey = this.createClientKey(client);
41
+ if (!this.coordinateCalls.has(ktaKey)) {
42
+ this.coordinateCalls.set(ktaKey, /* @__PURE__ */ new Map());
43
+ }
44
+ const scopeMap = this.coordinateCalls.get(ktaKey);
45
+ if (!scopeMap.has(scopeKey)) {
46
+ scopeMap.set(scopeKey, /* @__PURE__ */ new Map());
47
+ }
48
+ const clientMap = scopeMap.get(scopeKey);
49
+ const currentCount = clientMap.get(clientKey) || 0;
50
+ clientMap.set(clientKey, currentCount + 1);
51
+ }
52
+ /**
53
+ * Gets the current statistics snapshot
54
+ */
55
+ getStatistics() {
56
+ const coordinateCallRecords = [];
57
+ let serviceCalls = 0;
58
+ let applicationCalls = 0;
59
+ let unidentifiedCalls = 0;
60
+ for (const [ktaKey, scopeMap] of this.coordinateCalls) {
61
+ for (const [scopeKey, clientMap] of scopeMap) {
62
+ const clientCalls = [];
63
+ let totalCount = 0;
64
+ for (const [clientKey, count] of clientMap) {
65
+ const client = this.parseClientKey(clientKey);
66
+ if (client !== null) {
67
+ clientCalls.push({ client, count });
68
+ }
69
+ totalCount += count;
70
+ if (clientKey === "__no_client__") {
71
+ unidentifiedCalls += count;
72
+ } else if (typeof client === "string") {
73
+ applicationCalls += count;
74
+ } else if (client !== null) {
75
+ serviceCalls += count;
76
+ }
77
+ }
78
+ coordinateCallRecords.push({
79
+ kta: ktaKey.split("."),
80
+ scopes: this.parseScopeKey(scopeKey),
81
+ count: totalCount,
82
+ clientCalls: [...clientCalls]
83
+ // Return a copy
84
+ });
85
+ }
86
+ }
87
+ return {
88
+ totalGetCalls: this.totalCalls,
89
+ coordinateCallRecords: [...coordinateCallRecords],
90
+ // Return a copy
91
+ clientSummary: {
92
+ serviceCalls,
93
+ applicationCalls,
94
+ unidentifiedCalls
95
+ }
96
+ };
97
+ }
98
+ /**
99
+ * Gets call count for a specific coordinate combination
100
+ */
101
+ getCallCount(kta, scopes) {
102
+ const ktaKey = kta.join(".");
103
+ const scopeKey = this.createScopeKey(scopes || []);
104
+ const scopeMap = this.coordinateCalls.get(ktaKey);
105
+ if (!scopeMap) return 0;
106
+ const clientMap = scopeMap.get(scopeKey);
107
+ if (!clientMap) return 0;
108
+ let total = 0;
109
+ for (const count of clientMap.values()) {
110
+ total += count;
111
+ }
112
+ return total;
113
+ }
114
+ /**
115
+ * Gets call count for a specific coordinate combination from a specific client
116
+ */
117
+ getCallCountByClient(kta, scopes, client) {
118
+ const ktaKey = kta.join(".");
119
+ const scopeKey = this.createScopeKey(scopes || []);
120
+ const clientKey = this.createClientKey(client);
121
+ const scopeMap = this.coordinateCalls.get(ktaKey);
122
+ if (!scopeMap) return 0;
123
+ const clientMap = scopeMap.get(scopeKey);
124
+ if (!clientMap) return 0;
125
+ return clientMap.get(clientKey) || 0;
126
+ }
127
+ /**
128
+ * Gets total calls for a specific kta (across all scopes)
129
+ */
130
+ getTotalCallsForKta(kta) {
131
+ const ktaKey = kta.join(".");
132
+ const scopeMap = this.coordinateCalls.get(ktaKey);
133
+ if (!scopeMap) return 0;
134
+ let total = 0;
135
+ for (const clientMap of scopeMap.values()) {
136
+ for (const count of clientMap.values()) {
137
+ total += count;
138
+ }
139
+ }
140
+ return total;
141
+ }
142
+ /**
143
+ * Gets all unique kta paths that have been called
144
+ */
145
+ getCalledKtaPaths() {
146
+ const ktaPaths = [];
147
+ for (const ktaKey of this.coordinateCalls.keys()) {
148
+ ktaPaths.push(ktaKey.split("."));
149
+ }
150
+ return ktaPaths;
151
+ }
152
+ /**
153
+ * Creates a normalized scope key from scopes array
154
+ */
155
+ createScopeKey(scopes) {
156
+ if (scopes.length === 0) return "__no_scopes__";
157
+ return [...scopes].sort().join(",");
158
+ }
159
+ /**
160
+ * Parses a scope key back to scopes array
161
+ */
162
+ parseScopeKey(scopeKey) {
163
+ if (scopeKey === "__no_scopes__") return [];
164
+ return scopeKey.split(",");
165
+ }
166
+ /**
167
+ * Creates a normalized client key from client identifier
168
+ */
169
+ createClientKey(client) {
170
+ if (!client) return "__no_client__";
171
+ if (typeof client === "string") {
172
+ return `app:${client}`;
173
+ }
174
+ const coordKey = `${client.coordinate.kta.join(".")};${this.createScopeKey(client.coordinate.scopes)}`;
175
+ return `service:${client.registryType}:${coordKey}`;
176
+ }
177
+ /**
178
+ * Parses a client key back to client identifier
179
+ */
180
+ parseClientKey(clientKey) {
181
+ if (clientKey === "__no_client__") return null;
182
+ if (clientKey.startsWith("app:")) {
183
+ return clientKey.substring(4);
184
+ }
185
+ if (clientKey.startsWith("service:")) {
186
+ const parts = clientKey.substring(8).split(":");
187
+ if (parts.length !== 2) return null;
188
+ const registryType = parts[0];
189
+ const coordParts = parts[1].split(";");
190
+ if (coordParts.length !== 2) return null;
191
+ const kta = coordParts[0].split(".");
192
+ const scopes = this.parseScopeKey(coordParts[1]);
193
+ return {
194
+ registryType,
195
+ coordinate: { kta, scopes }
196
+ };
197
+ }
198
+ return null;
199
+ }
200
+ };
201
+
202
+ // src/Registry.ts
203
+ var logger3 = logger_default.get("Registry");
204
+ var findScopedInstance = (scopedInstances, requestedScopes) => {
205
+ if (!requestedScopes || requestedScopes.length === 0) {
206
+ const firstInstance = scopedInstances[0]?.instance;
207
+ if (!firstInstance) {
208
+ throw new Error("No instances available");
209
+ }
210
+ return firstInstance;
211
+ }
212
+ const matchingInstance = scopedInstances.find((scopedInstance) => {
213
+ if (!scopedInstance.scopes) return false;
214
+ return requestedScopes.every(
215
+ (scope) => scopedInstance.scopes && scopedInstance.scopes.includes(scope)
216
+ );
217
+ });
218
+ if (!matchingInstance) {
219
+ throw new Error(`No instance found matching scopes: ${requestedScopes.join(", ")}`);
220
+ }
221
+ return matchingInstance.instance;
222
+ };
223
+ var createRegistry = (type, registryHub) => {
224
+ const instanceTree = {};
225
+ const registryStats = new RegistryStats();
226
+ const createProxiedRegistry = (callingCoordinate) => {
227
+ const serviceClient = {
228
+ registryType: type,
229
+ coordinate: {
230
+ kta: callingCoordinate.kta,
231
+ scopes: callingCoordinate.scopes
232
+ }
233
+ };
234
+ return {
235
+ ...registry,
236
+ get: (kta, options) => {
237
+ const clientToUse = options?.client || serviceClient;
238
+ return registry.get(kta, { ...options, client: clientToUse });
239
+ }
240
+ };
241
+ };
242
+ const createInstance2 = (kta, scopes, factory) => {
243
+ logger3.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
244
+ const coordinate = createCoordinate(kta, scopes);
245
+ const proxiedRegistry = createProxiedRegistry(coordinate);
246
+ const instance = factory(coordinate, {
247
+ registry: proxiedRegistry,
248
+ registryHub
249
+ });
250
+ if (!isInstance(instance)) {
251
+ throw new Error(`Factory did not return a valid instance for: ${kta.join(".")}`);
252
+ }
253
+ registerInternal(kta, instance, { scopes });
254
+ return instance;
255
+ };
256
+ const registerInternal = (kta, instance, options) => {
257
+ const keyPath = [...kta].reverse();
258
+ let currentLevel = instanceTree;
259
+ logger3.debug(`Registering instance for key path and scopes`, keyPath, options?.scopes, `in registry type: ${type}`);
260
+ if (!isInstance(instance)) {
261
+ throw new Error(`Attempting to register a non-instance: ${kta.join(".")}`);
262
+ }
263
+ for (let i = 0; i < keyPath.length; i++) {
264
+ const keyType = keyPath[i];
265
+ const isLeaf = i === keyPath.length - 1;
266
+ if (!currentLevel[keyType]) {
267
+ currentLevel[keyType] = {
268
+ instances: [],
269
+ children: isLeaf ? null : {}
270
+ };
271
+ }
272
+ if (isLeaf) {
273
+ currentLevel[keyType].instances.push({
274
+ scopes: options?.scopes,
275
+ instance
276
+ });
277
+ } else {
278
+ if (!currentLevel[keyType].children) {
279
+ currentLevel[keyType].children = {};
280
+ }
281
+ currentLevel = currentLevel[keyType].children;
282
+ }
283
+ }
284
+ };
285
+ const register = (kta, instance, options) => {
286
+ logger3.debug("Using deprecated register method. Consider using createInstance instead.");
287
+ registerInternal(kta, instance, options);
288
+ };
289
+ const get = (kta, options) => {
290
+ registryStats.recordGetCall(kta, options?.scopes, options?.client);
291
+ const keyPath = [...kta].reverse();
292
+ let currentLevel = instanceTree;
293
+ for (let i = 0; i < keyPath.length; i++) {
294
+ const keyType = keyPath[i];
295
+ const isLeaf = i === keyPath.length - 1;
296
+ if (!currentLevel[keyType]) {
297
+ throw new Error(`Instance not found for key path: ${kta.join(".")}, Missing key: ${keyType}`);
298
+ }
299
+ if (isLeaf) {
300
+ const scopedInstances = currentLevel[keyType].instances;
301
+ if (scopedInstances.length === 0) {
302
+ throw new Error(`No instances registered for key path: ${kta.join(".")}`);
303
+ }
304
+ return findScopedInstance(scopedInstances, options?.scopes);
305
+ } else {
306
+ if (!currentLevel[keyType].children) {
307
+ throw new Error(`Instance not found for key path: ${kta.join(".")}, No children for: ${keyType}`);
308
+ }
309
+ currentLevel = currentLevel[keyType].children;
310
+ }
311
+ }
312
+ return null;
313
+ };
314
+ const getCoordinates = () => {
315
+ const coordinates = [];
316
+ const traverseTree = (node) => {
317
+ for (const keyType in node) {
318
+ const treeNode = node[keyType];
319
+ for (const scopedInstance of treeNode.instances) {
320
+ coordinates.push(scopedInstance.instance.coordinate);
321
+ }
322
+ if (treeNode.children) {
323
+ traverseTree(treeNode.children);
324
+ }
325
+ }
326
+ };
327
+ traverseTree(instanceTree);
328
+ return coordinates;
329
+ };
330
+ const getStatistics = () => {
331
+ return registryStats.getStatistics();
332
+ };
333
+ const registry = {
334
+ type,
335
+ registryHub,
336
+ createInstance: createInstance2,
337
+ register,
338
+ get,
339
+ getCoordinates,
340
+ getStatistics,
341
+ instanceTree
342
+ };
343
+ return registry;
344
+ };
345
+
346
+ // src/errors/RegistryError.ts
347
+ var RegistryError = class extends Error {
348
+ registryType;
349
+ context;
350
+ constructor(message, registryType, context) {
351
+ super(message);
352
+ this.name = this.constructor.name;
353
+ this.registryType = registryType;
354
+ this.context = context;
355
+ const ErrorConstructor = Error;
356
+ if (typeof ErrorConstructor.captureStackTrace === "function") {
357
+ ErrorConstructor.captureStackTrace(this, this.constructor);
358
+ }
359
+ }
360
+ getDetails() {
361
+ const details = [this.message];
362
+ if (this.registryType) {
363
+ details.push(`Registry Type: ${this.registryType}`);
364
+ }
365
+ if (this.context) {
366
+ details.push(`Context: ${JSON.stringify(this.context, null, 2)}`);
367
+ }
368
+ return details.join("\n");
369
+ }
370
+ };
371
+ var RegistryCreationError = class extends RegistryError {
372
+ constructor(type, reason, context) {
373
+ super(`Failed to create registry of type '${type}': ${reason}`, type, context);
374
+ }
375
+ };
376
+ var InvalidFactoryResultError = class extends RegistryError {
377
+ keyPath;
378
+ factoryResult;
379
+ constructor(keyPath, factoryResult, registryType) {
380
+ const keyPathStr = keyPath.join(".");
381
+ super(
382
+ `Factory did not return a valid instance for: ${keyPathStr}. Expected instance with 'coordinate' and 'registry' properties, got: ${typeof factoryResult}`,
383
+ registryType,
384
+ { keyPath, factoryResult: typeof factoryResult }
385
+ );
386
+ this.keyPath = keyPath;
387
+ this.factoryResult = factoryResult;
388
+ }
389
+ };
390
+ var InvalidInstanceRegistrationError = class extends RegistryError {
391
+ keyPath;
392
+ attemptedRegistration;
393
+ constructor(keyPath, attemptedRegistration, registryType) {
394
+ const keyPathStr = keyPath.join(".");
395
+ super(
396
+ `Attempting to register a non-instance: ${keyPathStr}. Expected instance with 'coordinate' and 'registry' properties, got: ${typeof attemptedRegistration}`,
397
+ registryType,
398
+ { keyPath, attemptedRegistration: typeof attemptedRegistration }
399
+ );
400
+ this.keyPath = keyPath;
401
+ this.attemptedRegistration = attemptedRegistration;
402
+ }
403
+ };
404
+
405
+ // src/errors/RegistryHubError.ts
406
+ var RegistryHubError = class extends RegistryError {
407
+ hubType;
408
+ constructor(message, hubType, context) {
409
+ const enrichedContext = hubType ? { ...context, hubType } : context;
410
+ super(message, "", enrichedContext);
411
+ this.hubType = hubType;
412
+ }
413
+ };
414
+ var DuplicateRegistryTypeError = class extends RegistryHubError {
415
+ duplicateType;
416
+ constructor(type, context) {
417
+ super(
418
+ `Registry already registered under type: ${type}. Each registry type must be unique within a registry hub.`,
419
+ "",
420
+ { ...context, duplicateType: type }
421
+ );
422
+ this.duplicateType = type;
423
+ }
424
+ };
425
+ var RegistryTypeNotFoundError = class extends RegistryHubError {
426
+ requestedType;
427
+ availableTypes;
428
+ constructor(requestedType, availableTypes = [], context) {
429
+ let message = `No registry registered under type: ${requestedType}`;
430
+ if (availableTypes.length > 0) {
431
+ message += `. Available types: [${availableTypes.join(", ")}]`;
432
+ }
433
+ super(message, "", { ...context, requestedType, availableTypes });
434
+ this.requestedType = requestedType;
435
+ this.availableTypes = availableTypes;
436
+ }
437
+ };
438
+ var RegistryFactoryError = class extends RegistryHubError {
439
+ factoryError;
440
+ attemptedType;
441
+ constructor(type, factoryError, context) {
442
+ super(
443
+ `Registry factory failed to create registry of type '${type}': ${factoryError.message}`,
444
+ "",
445
+ { ...context, attemptedType: type, originalError: factoryError.message }
446
+ );
447
+ this.factoryError = factoryError;
448
+ this.attemptedType = type;
449
+ }
450
+ };
451
+ var InvalidRegistryFactoryResultError = class extends RegistryHubError {
452
+ factoryResult;
453
+ attemptedType;
454
+ constructor(type, factoryResult, context) {
455
+ super(
456
+ `Registry factory returned invalid registry for type '${type}'. Expected registry with 'type', 'get', 'register', and 'createInstance' properties, got: ${typeof factoryResult}`,
457
+ "",
458
+ { ...context, attemptedType: type, factoryResult: typeof factoryResult }
459
+ );
460
+ this.factoryResult = factoryResult;
461
+ this.attemptedType = type;
462
+ }
463
+ };
464
+
465
+ // src/RegistryHub.ts
466
+ var logger4 = logger_default.get("RegistryHub");
467
+ var createRegistryHub = () => {
468
+ const registries = {};
469
+ const createRegistry2 = (type, factory) => {
470
+ logger4.debug(`Creating new registry with type: ${type}`);
471
+ if (registries[type]) {
472
+ throw new DuplicateRegistryTypeError(type);
473
+ }
474
+ const registry = factory(type, hub);
475
+ if (!("registryHub" in registry) || registry.registryHub !== hub) {
476
+ registry.registryHub = hub;
477
+ }
478
+ registries[type] = registry;
479
+ logger4.debug(`Successfully created and registered new registry with type: ${type}`);
480
+ return registry;
481
+ };
482
+ const registerRegistry = (registry) => {
483
+ const type = registry.type;
484
+ logger4.debug(`Registering registry with type: ${type}`);
485
+ if (registries[type]) {
486
+ throw new DuplicateRegistryTypeError(type);
487
+ }
488
+ registries[type] = registry;
489
+ if (!("registryHub" in registry) || registry.registryHub !== hub) {
490
+ registry.registryHub = hub;
491
+ }
492
+ logger4.debug(`Successfully registered registry with type: ${type}`);
493
+ };
494
+ const get = (type, kta, options) => {
495
+ logger4.debug(`Looking up instance for type: ${type}, kta: ${kta.join(".")}, scopes: ${options?.scopes?.join(",") || "none"}`);
496
+ const registry = registries[type];
497
+ if (!registry) {
498
+ const availableTypes = Object.keys(registries);
499
+ throw new RegistryTypeNotFoundError(type, availableTypes);
500
+ }
501
+ return registry.get(kta, options);
502
+ };
503
+ const getRegistry = (type) => {
504
+ return registries[type] || null;
505
+ };
506
+ const getRegisteredTypes = () => {
507
+ return Object.keys(registries);
508
+ };
509
+ const unregisterRegistry = (type) => {
510
+ if (registries[type]) {
511
+ delete registries[type];
512
+ logger4.debug(`Unregistered registry under type: ${type}`);
513
+ return true;
514
+ }
515
+ return false;
516
+ };
517
+ const getAllCoordinates = () => {
518
+ const allCoordinates = [];
519
+ for (const registryType in registries) {
520
+ const registry = registries[registryType];
521
+ const coordinates = registry.getCoordinates();
522
+ coordinates.forEach((coordinate) => {
523
+ allCoordinates.push({
524
+ coordinate,
525
+ registryType
526
+ });
527
+ });
528
+ }
529
+ logger4.debug(`Retrieved ${allCoordinates.length} total coordinates from ${Object.keys(registries).length} registries`);
530
+ return allCoordinates;
531
+ };
532
+ const hub = {
533
+ createRegistry: createRegistry2,
534
+ registerRegistry,
535
+ get,
536
+ getRegistry,
537
+ getRegisteredTypes,
538
+ getAllCoordinates,
539
+ unregisterRegistry
540
+ };
541
+ return hub;
542
+ };
543
+
544
+ // src/errors/InstanceError.ts
545
+ var InstanceError = class extends RegistryError {
546
+ keyPath;
547
+ constructor(message, keyPath, registryType, context) {
548
+ super(message, registryType, { ...context, keyPath });
549
+ this.keyPath = keyPath;
550
+ }
551
+ };
552
+ var InstanceNotFoundError = class extends InstanceError {
553
+ missingKey;
554
+ constructor(keyPath, missingKey, registryType, context) {
555
+ const keyPathStr = keyPath.join(".");
556
+ let message = `Instance not found for key path: ${keyPathStr}`;
557
+ if (missingKey) {
558
+ message += `, Missing key: ${missingKey}`;
559
+ }
560
+ super(message, keyPath, registryType, { ...context, missingKey });
561
+ this.missingKey = missingKey;
562
+ }
563
+ };
564
+ var NoInstancesRegisteredError = class extends InstanceError {
565
+ constructor(keyPath, registryType, context) {
566
+ const keyPathStr = keyPath.join(".");
567
+ super(
568
+ `No instances registered for key path: ${keyPathStr}. The key path exists in the registry tree but contains no instances.`,
569
+ keyPath,
570
+ registryType,
571
+ context
572
+ );
573
+ }
574
+ };
575
+ var NoInstancesAvailableError = class extends InstanceError {
576
+ constructor(keyPath, registryType, context) {
577
+ const keyPathStr = keyPath.join(".");
578
+ super(
579
+ `No instances available for key path: ${keyPathStr}. This typically indicates an internal registry state issue.`,
580
+ keyPath,
581
+ registryType,
582
+ context
583
+ );
584
+ }
585
+ };
586
+ var ScopeNotFoundError = class extends InstanceError {
587
+ requestedScopes;
588
+ availableScopes;
589
+ constructor(keyPath, requestedScopes, availableScopes = [], registryType) {
590
+ const keyPathStr = keyPath.join(".");
591
+ const scopesStr = requestedScopes.join(", ");
592
+ const availableScopesStr = availableScopes.map((scopes) => `[${scopes.join(", ")}]`).join(", ");
593
+ let message = `No instance found matching scopes: ${scopesStr} for key path: ${keyPathStr}`;
594
+ if (availableScopes.length > 0) {
595
+ message += `. Available scopes: ${availableScopesStr}`;
596
+ }
597
+ super(message, keyPath, registryType, { requestedScopes, availableScopes });
598
+ this.requestedScopes = requestedScopes;
599
+ this.availableScopes = availableScopes;
600
+ }
601
+ };
602
+ var NoChildrenAvailableError = class extends InstanceError {
603
+ parentKey;
604
+ constructor(keyPath, parentKey, registryType, context) {
605
+ const keyPathStr = keyPath.join(".");
606
+ super(
607
+ `Instance not found for key path: ${keyPathStr}, No children for: ${parentKey}. The path cannot be traversed further as '${parentKey}' has no child nodes.`,
608
+ keyPath,
609
+ registryType,
610
+ { ...context, parentKey }
611
+ );
612
+ this.parentKey = parentKey;
613
+ }
614
+ };
615
+
616
+ // src/errors/CoordinateError.ts
617
+ var CoordinateError = class extends RegistryError {
618
+ kta;
619
+ scopes;
620
+ constructor(message, kta, scopes, context) {
621
+ super(message, "", { ...context, kta, scopes });
622
+ this.kta = kta;
623
+ this.scopes = scopes;
624
+ }
625
+ };
626
+ var InvalidCoordinateError = class extends CoordinateError {
627
+ constructor(kta, scopes, reason, context) {
628
+ super(
629
+ `Invalid coordinate parameters: ${reason}. KTA: ${JSON.stringify(kta)}, Scopes: [${scopes.join(", ")}]`,
630
+ kta,
631
+ scopes,
632
+ { ...context, reason }
633
+ );
634
+ }
635
+ };
636
+ var InvalidKTAError = class extends CoordinateError {
637
+ constructor(kta, reason, context) {
638
+ super(
639
+ `Invalid KTA (Key Type Array): ${reason}. Expected string or array of strings, got: ${JSON.stringify(kta)}`,
640
+ kta,
641
+ [],
642
+ { ...context, reason }
643
+ );
644
+ }
645
+ };
646
+ var InvalidScopesError = class extends CoordinateError {
647
+ invalidScopes;
648
+ constructor(scopes, invalidScopes, reason, context) {
649
+ super(
650
+ `Invalid scopes: ${reason}. Invalid scope values: ${JSON.stringify(invalidScopes)}`,
651
+ null,
652
+ scopes.filter((s) => typeof s === "string"),
653
+ { ...context, reason, invalidScopes }
654
+ );
655
+ this.invalidScopes = invalidScopes;
656
+ }
657
+ };
658
+ export {
659
+ CoordinateError,
660
+ DuplicateRegistryTypeError,
661
+ InstanceError,
662
+ InstanceNotFoundError,
663
+ InvalidCoordinateError,
664
+ InvalidFactoryResultError,
665
+ InvalidInstanceRegistrationError,
666
+ InvalidKTAError,
667
+ InvalidRegistryFactoryResultError,
668
+ InvalidScopesError,
669
+ NoChildrenAvailableError,
670
+ NoInstancesAvailableError,
671
+ NoInstancesRegisteredError,
672
+ RegistryCreationError,
673
+ RegistryError,
674
+ RegistryFactoryError,
675
+ RegistryHubError,
676
+ RegistryStats,
677
+ RegistryTypeNotFoundError,
678
+ ScopeNotFoundError,
679
+ createCoordinate,
680
+ createInstance,
681
+ createRegistry,
682
+ createRegistryHub,
683
+ isInstance
684
+ };
685
+ //# sourceMappingURL=index.js.map