@fjell/registry 4.4.5 → 4.4.6

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 (52) hide show
  1. package/README.md +546 -0
  2. package/dist/Coordinate.cjs +8 -5
  3. package/dist/Coordinate.d.ts +1 -1
  4. package/dist/Coordinate.js +8 -5
  5. package/dist/Instance.cjs +1 -1
  6. package/dist/Instance.d.ts +1 -1
  7. package/dist/Instance.js +1 -1
  8. package/dist/Registry.cjs +99 -90
  9. package/dist/Registry.d.ts +3 -42
  10. package/dist/Registry.js +99 -90
  11. package/dist/RegistryHub.cjs +78 -0
  12. package/dist/RegistryHub.d.ts +3 -0
  13. package/dist/RegistryHub.js +74 -0
  14. package/dist/errors/CoordinateError.cjs +70 -0
  15. package/dist/errors/CoordinateError.d.ts +28 -0
  16. package/dist/errors/CoordinateError.js +63 -0
  17. package/dist/errors/InstanceError.cjs +101 -0
  18. package/dist/errors/InstanceError.d.ts +42 -0
  19. package/dist/errors/InstanceError.js +92 -0
  20. package/dist/errors/RegistryError.cjs +82 -0
  21. package/dist/errors/RegistryError.d.ts +31 -0
  22. package/dist/errors/RegistryError.js +75 -0
  23. package/dist/errors/RegistryHubError.cjs +92 -0
  24. package/dist/errors/RegistryHubError.d.ts +39 -0
  25. package/dist/errors/RegistryHubError.js +84 -0
  26. package/dist/errors/index.d.ts +4 -0
  27. package/dist/index.cjs +501 -101
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.js +6 -1
  31. package/dist/types.d.ts +90 -0
  32. package/docs/TIMING_NODE_OPTIMIZATION.md +207 -0
  33. package/docs/TIMING_README.md +170 -0
  34. package/docs/memory-data/scaling-10-instances.json +526 -0
  35. package/docs/memory-data/scaling-100-instances.json +526 -0
  36. package/docs/memory-data/scaling-1000-instances.json +276 -0
  37. package/docs/memory-data/scaling-10000-instances.json +126 -0
  38. package/docs/memory-data/scaling-20-instances.json +526 -0
  39. package/docs/memory-data/scaling-200-instances.json +526 -0
  40. package/docs/memory-data/scaling-2000-instances.json +276 -0
  41. package/docs/memory-data/scaling-50-instances.json +526 -0
  42. package/docs/memory-data/scaling-500-instances.json +276 -0
  43. package/docs/memory-data/scaling-5000-instances.json +126 -0
  44. package/docs/memory-overhead.svg +120 -0
  45. package/docs/memory.md +430 -0
  46. package/docs/timing-range.svg +174 -0
  47. package/docs/timing.md +483 -0
  48. package/examples/README.md +187 -0
  49. package/examples/multi-level-keys.ts +374 -0
  50. package/examples/registry-hub-types.ts +437 -0
  51. package/examples/simple-example.ts +250 -0
  52. package/package.json +5 -3
package/dist/index.cjs CHANGED
@@ -6,30 +6,33 @@ const Logging = require('@fjell/logging');
6
6
 
7
7
  const LibLogger = Logging.getLogger('@fjell/registry');
8
8
 
9
- const logger$2 = LibLogger.get("Coordinate");
10
- const createCoordinate = (kta, scopes)=>{
9
+ const logger$3 = LibLogger.get("Coordinate");
10
+ const createCoordinate = (kta, scopes = [])=>{
11
+ const ktArray = Array.isArray(kta) ? kta : [
12
+ kta
13
+ ];
11
14
  const toString = ()=>{
12
- logger$2.debug("toString", {
15
+ logger$3.debug("toString", {
13
16
  kta,
14
17
  scopes
15
18
  });
16
- return `${kta.join(', ')} - ${scopes.join(', ')}`;
19
+ return `${ktArray.join(', ')} - ${scopes.join(', ')}`;
17
20
  };
18
- logger$2.debug("createCoordinate", {
19
- kta,
21
+ logger$3.debug("createCoordinate", {
22
+ kta: ktArray,
20
23
  scopes,
21
24
  toString
22
25
  });
23
26
  return {
24
- kta,
27
+ kta: ktArray,
25
28
  scopes,
26
29
  toString
27
30
  };
28
31
  };
29
32
 
30
- const logger$1 = LibLogger.get("Instance");
31
- const createInstance = (coordinate, registry)=>{
32
- logger$1.debug("createInstance", {
33
+ const logger$2 = LibLogger.get("Instance");
34
+ const createInstance = (registry, coordinate)=>{
35
+ logger$2.debug("createInstance", {
33
36
  coordinate,
34
37
  registry
35
38
  });
@@ -42,120 +45,517 @@ const isInstance = (instance)=>{
42
45
  return instance !== null && instance !== undefined && instance.coordinate !== undefined && instance.registry !== undefined;
43
46
  };
44
47
 
45
- const logger = LibLogger.get("Registry");
46
- const isScopedInstance = (instance)=>{
47
- // eslint-disable-next-line no-undefined
48
- return instance.instance !== undefined;
49
- };
50
- const retrieveScopedInstance = (scopedInstanceArray, scopes)=>{
51
- let instance;
52
- if (scopes) {
53
- var _scopedInstanceArray_find;
54
- instance = (_scopedInstanceArray_find = scopedInstanceArray.find((sl)=>{
55
- return sl.scopes && scopes && scopes.every((scope)=>sl.scopes && sl.scopes.includes(scope));
56
- })) === null || _scopedInstanceArray_find === void 0 ? void 0 : _scopedInstanceArray_find.instance;
57
- } else {
58
- var _scopedInstanceArray_;
59
- instance = (_scopedInstanceArray_ = scopedInstanceArray[0]) === null || _scopedInstanceArray_ === void 0 ? void 0 : _scopedInstanceArray_.instance;
48
+ const logger$1 = LibLogger.get("Registry");
49
+ const findScopedInstance = (scopedInstances, requestedScopes)=>{
50
+ if (!requestedScopes || requestedScopes.length === 0) {
51
+ var _scopedInstances_;
52
+ // Return first instance if no scopes specified
53
+ const firstInstance = (_scopedInstances_ = scopedInstances[0]) === null || _scopedInstances_ === void 0 ? void 0 : _scopedInstances_.instance;
54
+ if (!firstInstance) {
55
+ throw new Error('No instances available');
56
+ }
57
+ return firstInstance;
60
58
  }
61
- if (!instance) {
62
- throw new Error(`No Scoped Instance for ${scopes === null || scopes === void 0 ? void 0 : scopes.join(', ')}`);
59
+ // Find instance that matches all requested scopes
60
+ const matchingInstance = scopedInstances.find((scopedInstance)=>{
61
+ if (!scopedInstance.scopes) return false;
62
+ return requestedScopes.every((scope)=>scopedInstance.scopes && scopedInstance.scopes.includes(scope));
63
+ });
64
+ if (!matchingInstance) {
65
+ throw new Error(`No instance found matching scopes: ${requestedScopes.join(', ')}`);
63
66
  }
64
- return instance;
67
+ return matchingInstance.instance;
65
68
  };
66
- const createRegistry = ()=>{
67
- // TODO: My use of Generics has Boxes be into a corner where I can't reference AbstractLib without the types
68
- const libTree = {};
69
- const register = (kta, instance, options)=>{
70
- const ktaArray = [
69
+ const createRegistry = (type, registryHub)=>{
70
+ const instanceTree = {};
71
+ const createInstance = (kta, scopes, factory)=>{
72
+ logger$1.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
73
+ // Create coordinate for the instance
74
+ const coordinate = createCoordinate(kta, scopes);
75
+ // Use factory to create the instance with the new context parameter
76
+ const instance = factory(coordinate, {
77
+ registry,
78
+ registryHub
79
+ });
80
+ // Validate the created instance
81
+ if (!isInstance(instance)) {
82
+ throw new Error(`Factory did not return a valid instance for: ${kta.join('.')}`);
83
+ }
84
+ // Register the instance
85
+ registerInternal(kta, instance, {
86
+ scopes
87
+ });
88
+ return instance;
89
+ };
90
+ const registerInternal = (kta, instance, options)=>{
91
+ const keyPath = [
71
92
  ...kta
72
- ];
73
- let currentTree = libTree;
74
- logger.debug(`Registering lib for KTA and scopes`, ktaArray, options === null || options === void 0 ? void 0 : options.scopes);
93
+ ].reverse(); // Work from most specific to least specific
94
+ let currentLevel = instanceTree;
95
+ logger$1.debug(`Registering instance for key path and scopes`, keyPath, options === null || options === void 0 ? void 0 : options.scopes, `in registry type: ${type}`);
75
96
  if (!isInstance(instance)) {
76
- throw new Error(`Attempting to register a non-instance as an instance: ${ktaArray.join('.')}`);
77
- }
78
- while(ktaArray.length > 0){
79
- const kt = ktaArray.pop();
80
- if (kt) {
81
- if (ktaArray.length === 0) {
82
- if (!currentTree[kt]) {
83
- currentTree[kt] = [
84
- [],
85
- null
86
- ];
87
- }
88
- currentTree[kt][0].push({
89
- scopes: options === null || options === void 0 ? void 0 : options.scopes,
90
- instance
91
- });
92
- } else {
93
- if (!currentTree[kt]) {
94
- const newTree = {};
95
- currentTree[kt] = [
96
- [],
97
- newTree
98
- ];
99
- currentTree = newTree;
100
- } else if (!currentTree[kt][1]) {
101
- const newTree = {};
102
- currentTree[kt][1] = newTree;
103
- currentTree = newTree;
104
- } else {
105
- currentTree = currentTree[kt][1];
106
- }
107
- }
97
+ throw new Error(`Attempting to register a non-instance: ${kta.join('.')}`);
98
+ }
99
+ // Navigate to the correct location in the tree
100
+ for(let i = 0; i < keyPath.length; i++){
101
+ const keyType = keyPath[i];
102
+ const isLeaf = i === keyPath.length - 1;
103
+ if (!currentLevel[keyType]) {
104
+ currentLevel[keyType] = {
105
+ instances: [],
106
+ children: isLeaf ? null : {}
107
+ };
108
+ }
109
+ if (isLeaf) {
110
+ // Add instance to the leaf node
111
+ currentLevel[keyType].instances.push({
112
+ scopes: options === null || options === void 0 ? void 0 : options.scopes,
113
+ instance
114
+ });
108
115
  } else {
109
- throw new Error(`Invalid KTA containing an empty false or undefined kt: ${ktaArray.join('.')}`);
116
+ // Navigate deeper into the tree
117
+ if (!currentLevel[keyType].children) {
118
+ currentLevel[keyType].children = {};
119
+ }
120
+ currentLevel = currentLevel[keyType].children;
110
121
  }
111
122
  }
112
123
  };
124
+ const register = (kta, instance, options)=>{
125
+ logger$1.debug('Using deprecated register method. Consider using createInstance instead.');
126
+ registerInternal(kta, instance, options);
127
+ };
113
128
  const get = (kta, options)=>{
114
- const ktaArray = [
129
+ const keyPath = [
115
130
  ...kta
116
- ];
117
- let currentTree = libTree;
118
- let instance = null;
119
- // logger.debug(`Getting lib for KTA and scopes`, ktaArray, options?.scopes);
120
- while(ktaArray.length > 0){
121
- const kt = ktaArray.pop();
122
- if (kt) {
123
- if (ktaArray.length === 0 && currentTree[kt]) {
124
- const element = currentTree[kt];
125
- const scopedInstanceArray = element[0];
126
- if (scopedInstanceArray.length > 0 && isScopedInstance(scopedInstanceArray[0])) {
127
- instance = retrieveScopedInstance(scopedInstanceArray, options === null || options === void 0 ? void 0 : options.scopes);
128
- // eslint-disable-next-line max-depth
129
- if (!instance) {
130
- var _options_scopes;
131
- throw new Error(`No Instance not found for kta: ${JSON.stringify(ktaArray)}, Scopes: ${options === null || options === void 0 ? void 0 : (_options_scopes = options.scopes) === null || _options_scopes === void 0 ? void 0 : _options_scopes.join(', ')}`);
132
- }
133
- } else {
134
- throw new Error(`No Instance not found for kta: ${JSON.stringify(ktaArray)}, Last Key not a instance: ${kt}`);
135
- }
136
- } else {
137
- if (!currentTree[kt]) {
138
- throw new Error(`Lib not found for kta: ${JSON.stringify(ktaArray)}, Subtree Not Found: ${kt}`);
139
- } else {
140
- currentTree = currentTree[kt][1];
141
- }
131
+ ].reverse();
132
+ let currentLevel = instanceTree;
133
+ // Navigate to the target node
134
+ for(let i = 0; i < keyPath.length; i++){
135
+ const keyType = keyPath[i];
136
+ const isLeaf = i === keyPath.length - 1;
137
+ if (!currentLevel[keyType]) {
138
+ throw new Error(`Instance not found for key path: ${kta.join('.')}, Missing key: ${keyType}`);
139
+ }
140
+ if (isLeaf) {
141
+ // Found the target node, extract instance
142
+ const scopedInstances = currentLevel[keyType].instances;
143
+ if (scopedInstances.length === 0) {
144
+ throw new Error(`No instances registered for key path: ${kta.join('.')}`);
142
145
  }
146
+ return findScopedInstance(scopedInstances, options === null || options === void 0 ? void 0 : options.scopes);
143
147
  } else {
144
- throw new Error(`Invalid KTA containing an empty false or undefined kt: ${JSON.stringify(ktaArray)}`);
148
+ // Continue navigation
149
+ if (!currentLevel[keyType].children) {
150
+ throw new Error(`Instance not found for key path: ${kta.join('.')}, No children for: ${keyType}`);
151
+ }
152
+ currentLevel = currentLevel[keyType].children;
145
153
  }
146
154
  }
147
- return instance;
155
+ return null;
148
156
  };
149
- return {
157
+ const registry = {
158
+ type,
159
+ registryHub,
160
+ createInstance,
150
161
  register,
151
162
  get,
152
- // TODO: Remove this once we have a better way to test
153
- libTree
163
+ instanceTree
154
164
  };
165
+ return registry;
155
166
  };
156
167
 
168
+ /**
169
+ * Base class for all registry-related errors
170
+ */ function _define_property$3(obj, key, value) {
171
+ if (key in obj) {
172
+ Object.defineProperty(obj, key, {
173
+ value: value,
174
+ enumerable: true,
175
+ configurable: true,
176
+ writable: true
177
+ });
178
+ } else {
179
+ obj[key] = value;
180
+ }
181
+ return obj;
182
+ }
183
+ class RegistryError extends Error {
184
+ getDetails() {
185
+ const details = [
186
+ this.message
187
+ ];
188
+ if (this.registryType) {
189
+ details.push(`Registry Type: ${this.registryType}`);
190
+ }
191
+ if (this.context) {
192
+ details.push(`Context: ${JSON.stringify(this.context, null, 2)}`);
193
+ }
194
+ return details.join('\n');
195
+ }
196
+ constructor(message, registryType, context){
197
+ super(message), _define_property$3(this, "registryType", void 0), _define_property$3(this, "context", void 0);
198
+ this.name = this.constructor.name;
199
+ this.registryType = registryType;
200
+ this.context = context;
201
+ // Maintains proper stack trace for where our error was thrown
202
+ if (Error.captureStackTrace) {
203
+ Error.captureStackTrace(this, this.constructor);
204
+ }
205
+ }
206
+ }
207
+ /**
208
+ * Thrown when attempting to create a registry with invalid parameters
209
+ */ class RegistryCreationError extends RegistryError {
210
+ constructor(type, reason, context){
211
+ super(`Failed to create registry of type '${type}': ${reason}`, type, context);
212
+ }
213
+ }
214
+ /**
215
+ * Thrown when a factory function returns an invalid instance
216
+ */ class InvalidFactoryResultError extends RegistryError {
217
+ constructor(keyPath, factoryResult, registryType){
218
+ const keyPathStr = keyPath.join('.');
219
+ super(`Factory did not return a valid instance for: ${keyPathStr}. ` + `Expected instance with 'coordinate' and 'registry' properties, got: ${typeof factoryResult}`, registryType, {
220
+ keyPath,
221
+ factoryResult: typeof factoryResult
222
+ }), _define_property$3(this, "keyPath", void 0), _define_property$3(this, "factoryResult", void 0);
223
+ this.keyPath = keyPath;
224
+ this.factoryResult = factoryResult;
225
+ }
226
+ }
227
+ /**
228
+ * Thrown when attempting to register a non-instance object
229
+ */ class InvalidInstanceRegistrationError extends RegistryError {
230
+ constructor(keyPath, attemptedRegistration, registryType){
231
+ const keyPathStr = keyPath.join('.');
232
+ super(`Attempting to register a non-instance: ${keyPathStr}. ` + `Expected instance with 'coordinate' and 'registry' properties, got: ${typeof attemptedRegistration}`, registryType, {
233
+ keyPath,
234
+ attemptedRegistration: typeof attemptedRegistration
235
+ }), _define_property$3(this, "keyPath", void 0), _define_property$3(this, "attemptedRegistration", void 0);
236
+ this.keyPath = keyPath;
237
+ this.attemptedRegistration = attemptedRegistration;
238
+ }
239
+ }
240
+
241
+ function _define_property$2(obj, key, value) {
242
+ if (key in obj) {
243
+ Object.defineProperty(obj, key, {
244
+ value: value,
245
+ enumerable: true,
246
+ configurable: true,
247
+ writable: true
248
+ });
249
+ } else {
250
+ obj[key] = value;
251
+ }
252
+ return obj;
253
+ }
254
+ /**
255
+ * Base class for registry hub-related errors
256
+ */ class RegistryHubError extends RegistryError {
257
+ constructor(message, hubType, context){
258
+ const enrichedContext = hubType ? {
259
+ ...context,
260
+ hubType
261
+ } : context;
262
+ super(message, '', enrichedContext), _define_property$2(this, "hubType", void 0);
263
+ this.hubType = hubType;
264
+ }
265
+ }
266
+ /**
267
+ * Thrown when attempting to register a registry with a type that already exists
268
+ */ class DuplicateRegistryTypeError extends RegistryHubError {
269
+ constructor(type, context){
270
+ super(`Registry already registered under type: ${type}. ` + `Each registry type must be unique within a registry hub.`, '', {
271
+ ...context,
272
+ duplicateType: type
273
+ }), _define_property$2(this, "duplicateType", void 0);
274
+ this.duplicateType = type;
275
+ }
276
+ }
277
+ /**
278
+ * Thrown when attempting to access a registry type that doesn't exist
279
+ */ class RegistryTypeNotFoundError extends RegistryHubError {
280
+ constructor(requestedType, availableTypes = [], context){
281
+ let message = `No registry registered under type: ${requestedType}`;
282
+ if (availableTypes.length > 0) {
283
+ message += `. Available types: [${availableTypes.join(', ')}]`;
284
+ }
285
+ super(message, '', {
286
+ ...context,
287
+ requestedType,
288
+ availableTypes
289
+ }), _define_property$2(this, "requestedType", void 0), _define_property$2(this, "availableTypes", void 0);
290
+ this.requestedType = requestedType;
291
+ this.availableTypes = availableTypes;
292
+ }
293
+ }
294
+ /**
295
+ * Thrown when a registry factory function fails to create a valid registry
296
+ */ class RegistryFactoryError extends RegistryHubError {
297
+ constructor(type, factoryError, context){
298
+ super(`Registry factory failed to create registry of type '${type}': ${factoryError.message}`, '', {
299
+ ...context,
300
+ attemptedType: type,
301
+ originalError: factoryError.message
302
+ }), _define_property$2(this, "factoryError", void 0), _define_property$2(this, "attemptedType", void 0);
303
+ this.factoryError = factoryError;
304
+ this.attemptedType = type;
305
+ }
306
+ }
307
+ /**
308
+ * Thrown when a factory returns an invalid registry object
309
+ */ class InvalidRegistryFactoryResultError extends RegistryHubError {
310
+ constructor(type, factoryResult, context){
311
+ super(`Registry factory returned invalid registry for type '${type}'. ` + `Expected registry with 'type', 'get', 'register', and 'createInstance' properties, ` + `got: ${typeof factoryResult}`, '', {
312
+ ...context,
313
+ attemptedType: type,
314
+ factoryResult: typeof factoryResult
315
+ }), _define_property$2(this, "factoryResult", void 0), _define_property$2(this, "attemptedType", void 0);
316
+ this.factoryResult = factoryResult;
317
+ this.attemptedType = type;
318
+ }
319
+ }
320
+
321
+ const logger = LibLogger.get("RegistryHub");
322
+ const createRegistryHub = ()=>{
323
+ const registries = {};
324
+ const createRegistry = (type, factory)=>{
325
+ logger.debug(`Creating new registry with type: ${type}`);
326
+ if (registries[type]) {
327
+ throw new DuplicateRegistryTypeError(type);
328
+ }
329
+ // Create the registry with a reference to this hub
330
+ const registry = factory(type, hub);
331
+ // Ensure the created registry has a reference to this hub if not already set
332
+ if (!('registryHub' in registry) || registry.registryHub !== hub) {
333
+ // @ts-expect-error: registryHub is optional and may be readonly, but we want to set it for hub awareness
334
+ registry.registryHub = hub;
335
+ }
336
+ // Register the created registry
337
+ registries[type] = registry;
338
+ logger.debug(`Successfully created and registered new registry with type: ${type}`);
339
+ return registry;
340
+ };
341
+ const registerRegistry = (registry)=>{
342
+ const type = registry.type;
343
+ logger.debug(`Registering registry with type: ${type}`);
344
+ if (registries[type]) {
345
+ throw new DuplicateRegistryTypeError(type);
346
+ }
347
+ registries[type] = registry;
348
+ // Ensure the created registry has a reference to this hub if not already set
349
+ if (!('registryHub' in registry) || registry.registryHub !== hub) {
350
+ // @ts-expect-error: registryHub is optional and may be readonly, but we want to set it for hub awareness
351
+ registry.registryHub = hub;
352
+ }
353
+ logger.debug(`Successfully registered registry with type: ${type}`);
354
+ };
355
+ const get = (type, kta, options)=>{
356
+ var _options_scopes;
357
+ 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'}`);
358
+ const registry = registries[type];
359
+ if (!registry) {
360
+ const availableTypes = Object.keys(registries);
361
+ throw new RegistryTypeNotFoundError(type, availableTypes);
362
+ }
363
+ return registry.get(kta, options);
364
+ };
365
+ const getRegistry = (type)=>{
366
+ return registries[type] || null;
367
+ };
368
+ const getRegisteredTypes = ()=>{
369
+ return Object.keys(registries);
370
+ };
371
+ const unregisterRegistry = (type)=>{
372
+ if (registries[type]) {
373
+ delete registries[type];
374
+ logger.debug(`Unregistered registry under type: ${type}`);
375
+ return true;
376
+ }
377
+ return false;
378
+ };
379
+ const hub = {
380
+ createRegistry,
381
+ registerRegistry,
382
+ get,
383
+ getRegistry,
384
+ getRegisteredTypes,
385
+ unregisterRegistry
386
+ };
387
+ return hub;
388
+ };
389
+
390
+ function _define_property$1(obj, key, value) {
391
+ if (key in obj) {
392
+ Object.defineProperty(obj, key, {
393
+ value: value,
394
+ enumerable: true,
395
+ configurable: true,
396
+ writable: true
397
+ });
398
+ } else {
399
+ obj[key] = value;
400
+ }
401
+ return obj;
402
+ }
403
+ /**
404
+ * Base class for instance-related errors
405
+ */ class InstanceError extends RegistryError {
406
+ constructor(message, keyPath, registryType, context){
407
+ super(message, registryType, {
408
+ ...context,
409
+ keyPath
410
+ }), _define_property$1(this, "keyPath", void 0);
411
+ this.keyPath = keyPath;
412
+ }
413
+ }
414
+ /**
415
+ * Thrown when an instance cannot be found for a given key path
416
+ */ class InstanceNotFoundError extends InstanceError {
417
+ constructor(keyPath, missingKey, registryType, context){
418
+ const keyPathStr = keyPath.join('.');
419
+ let message = `Instance not found for key path: ${keyPathStr}`;
420
+ if (missingKey) {
421
+ message += `, Missing key: ${missingKey}`;
422
+ }
423
+ super(message, keyPath, registryType, {
424
+ ...context,
425
+ missingKey
426
+ }), _define_property$1(this, "missingKey", void 0);
427
+ this.missingKey = missingKey;
428
+ }
429
+ }
430
+ /**
431
+ * Thrown when no instances are registered for a key path that exists in the tree
432
+ */ class NoInstancesRegisteredError extends InstanceError {
433
+ constructor(keyPath, registryType, context){
434
+ const keyPathStr = keyPath.join('.');
435
+ super(`No instances registered for key path: ${keyPathStr}. ` + `The key path exists in the registry tree but contains no instances.`, keyPath, registryType, context);
436
+ }
437
+ }
438
+ /**
439
+ * Thrown when no instances are available (empty instances array)
440
+ */ class NoInstancesAvailableError extends InstanceError {
441
+ constructor(keyPath, registryType, context){
442
+ const keyPathStr = keyPath.join('.');
443
+ super(`No instances available for key path: ${keyPathStr}. ` + `This typically indicates an internal registry state issue.`, keyPath, registryType, context);
444
+ }
445
+ }
446
+ /**
447
+ * Thrown when no instance matches the requested scopes
448
+ */ class ScopeNotFoundError extends InstanceError {
449
+ constructor(keyPath, requestedScopes, availableScopes = [], registryType){
450
+ const keyPathStr = keyPath.join('.');
451
+ const scopesStr = requestedScopes.join(', ');
452
+ const availableScopesStr = availableScopes.map((scopes)=>`[${scopes.join(', ')}]`).join(', ');
453
+ let message = `No instance found matching scopes: ${scopesStr} for key path: ${keyPathStr}`;
454
+ if (availableScopes.length > 0) {
455
+ message += `. Available scopes: ${availableScopesStr}`;
456
+ }
457
+ super(message, keyPath, registryType, {
458
+ requestedScopes,
459
+ availableScopes
460
+ }), _define_property$1(this, "requestedScopes", void 0), _define_property$1(this, "availableScopes", void 0);
461
+ this.requestedScopes = requestedScopes;
462
+ this.availableScopes = availableScopes;
463
+ }
464
+ }
465
+ /**
466
+ * Thrown when a key path has no children but children are expected
467
+ */ class NoChildrenAvailableError extends InstanceError {
468
+ constructor(keyPath, parentKey, registryType, context){
469
+ const keyPathStr = keyPath.join('.');
470
+ 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, {
471
+ ...context,
472
+ parentKey
473
+ }), _define_property$1(this, "parentKey", void 0);
474
+ this.parentKey = parentKey;
475
+ }
476
+ }
477
+
478
+ function _define_property(obj, key, value) {
479
+ if (key in obj) {
480
+ Object.defineProperty(obj, key, {
481
+ value: value,
482
+ enumerable: true,
483
+ configurable: true,
484
+ writable: true
485
+ });
486
+ } else {
487
+ obj[key] = value;
488
+ }
489
+ return obj;
490
+ }
491
+ /**
492
+ * Base class for coordinate-related errors
493
+ */ class CoordinateError extends RegistryError {
494
+ constructor(message, kta, scopes, context){
495
+ super(message, '', {
496
+ ...context,
497
+ kta,
498
+ scopes
499
+ }), _define_property(this, "kta", void 0), _define_property(this, "scopes", void 0);
500
+ this.kta = kta;
501
+ this.scopes = scopes;
502
+ }
503
+ }
504
+ /**
505
+ * Thrown when coordinate creation fails due to invalid parameters
506
+ */ class InvalidCoordinateError extends CoordinateError {
507
+ constructor(kta, scopes, reason, context){
508
+ super(`Invalid coordinate parameters: ${reason}. ` + `KTA: ${JSON.stringify(kta)}, Scopes: [${scopes.join(', ')}]`, kta, scopes, {
509
+ ...context,
510
+ reason
511
+ });
512
+ }
513
+ }
514
+ /**
515
+ * Thrown when KTA (Key Type Array) is invalid
516
+ */ class InvalidKTAError extends CoordinateError {
517
+ constructor(kta, reason, context){
518
+ super(`Invalid KTA (Key Type Array): ${reason}. ` + `Expected string or array of strings, got: ${JSON.stringify(kta)}`, kta, [], {
519
+ ...context,
520
+ reason
521
+ });
522
+ }
523
+ }
524
+ /**
525
+ * Thrown when scopes array contains invalid values
526
+ */ class InvalidScopesError extends CoordinateError {
527
+ constructor(scopes, invalidScopes, reason, context){
528
+ super(`Invalid scopes: ${reason}. ` + `Invalid scope values: ${JSON.stringify(invalidScopes)}`, null, scopes.filter((s)=>typeof s === 'string'), {
529
+ ...context,
530
+ reason,
531
+ invalidScopes
532
+ }), _define_property(this, "invalidScopes", void 0);
533
+ this.invalidScopes = invalidScopes;
534
+ }
535
+ }
536
+
537
+ exports.CoordinateError = CoordinateError;
538
+ exports.DuplicateRegistryTypeError = DuplicateRegistryTypeError;
539
+ exports.InstanceError = InstanceError;
540
+ exports.InstanceNotFoundError = InstanceNotFoundError;
541
+ exports.InvalidCoordinateError = InvalidCoordinateError;
542
+ exports.InvalidFactoryResultError = InvalidFactoryResultError;
543
+ exports.InvalidInstanceRegistrationError = InvalidInstanceRegistrationError;
544
+ exports.InvalidKTAError = InvalidKTAError;
545
+ exports.InvalidRegistryFactoryResultError = InvalidRegistryFactoryResultError;
546
+ exports.InvalidScopesError = InvalidScopesError;
547
+ exports.NoChildrenAvailableError = NoChildrenAvailableError;
548
+ exports.NoInstancesAvailableError = NoInstancesAvailableError;
549
+ exports.NoInstancesRegisteredError = NoInstancesRegisteredError;
550
+ exports.RegistryCreationError = RegistryCreationError;
551
+ exports.RegistryError = RegistryError;
552
+ exports.RegistryFactoryError = RegistryFactoryError;
553
+ exports.RegistryHubError = RegistryHubError;
554
+ exports.RegistryTypeNotFoundError = RegistryTypeNotFoundError;
555
+ exports.ScopeNotFoundError = ScopeNotFoundError;
157
556
  exports.createCoordinate = createCoordinate;
158
557
  exports.createInstance = createInstance;
159
558
  exports.createRegistry = createRegistry;
559
+ exports.createRegistryHub = createRegistryHub;
160
560
  exports.isInstance = isInstance;
161
561
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
1
  export * from './Coordinate';
2
2
  export * from './Instance';
3
3
  export * from './Registry';
4
+ export * from './RegistryHub';
5
+ export * from './types';
6
+ export * from './errors';
package/dist/index.js CHANGED
@@ -1,4 +1,9 @@
1
1
  export { createCoordinate } from './Coordinate.js';
2
2
  export { createInstance, isInstance } from './Instance.js';
3
3
  export { createRegistry } from './Registry.js';
4
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzsifQ==
4
+ export { createRegistryHub } from './RegistryHub.js';
5
+ export { InvalidFactoryResultError, InvalidInstanceRegistrationError, RegistryCreationError, RegistryError } from './errors/RegistryError.js';
6
+ export { InstanceError, InstanceNotFoundError, NoChildrenAvailableError, NoInstancesAvailableError, NoInstancesRegisteredError, ScopeNotFoundError } from './errors/InstanceError.js';
7
+ export { CoordinateError, InvalidCoordinateError, InvalidKTAError, InvalidScopesError } from './errors/CoordinateError.js';
8
+ export { DuplicateRegistryTypeError, InvalidRegistryFactoryResultError, RegistryFactoryError, RegistryHubError, RegistryTypeNotFoundError } from './errors/RegistryHubError.js';
9
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7OyJ9