@fjell/registry 4.4.4 → 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 (55) 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 +4 -4
  6. package/dist/Instance.d.ts +3 -4
  7. package/dist/Instance.js +4 -4
  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 -112
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.ts +3 -1
  30. package/dist/index.js +6 -2
  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
  53. package/dist/Definition.cjs +0 -18
  54. package/dist/Definition.d.ts +0 -5
  55. package/dist/Definition.js +0 -14
package/dist/Instance.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import LibLogger from './logger.js';
2
2
 
3
3
  const logger = LibLogger.get("Instance");
4
- const createInstance = (definition, registry)=>{
4
+ const createInstance = (registry, coordinate)=>{
5
5
  logger.debug("createInstance", {
6
- definition,
6
+ coordinate,
7
7
  registry
8
8
  });
9
9
  return {
10
- definition,
10
+ coordinate,
11
11
  registry
12
12
  };
13
13
  };
14
14
  const isInstance = (instance)=>{
15
- return instance !== null && instance !== undefined && instance.definition !== undefined && instance.registry !== undefined;
15
+ return instance !== null && instance !== undefined && instance.coordinate !== undefined && instance.registry !== undefined;
16
16
  };
17
17
 
18
18
  export { createInstance, isInstance };
package/dist/Registry.cjs CHANGED
@@ -4,118 +4,127 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
 
5
5
  const logger$1 = require('./logger.cjs');
6
6
  const Instance = require('./Instance.cjs');
7
+ const Coordinate = require('./Coordinate.cjs');
7
8
 
8
9
  const logger = logger$1.default.get("Registry");
9
- const isScopedInstance = (instance)=>{
10
- // eslint-disable-next-line no-undefined
11
- return instance.instance !== undefined;
12
- };
13
- const retrieveScopedInstance = (scopedInstanceArray, scopes)=>{
14
- let instance;
15
- if (scopes) {
16
- var _scopedInstanceArray_find;
17
- instance = (_scopedInstanceArray_find = scopedInstanceArray.find((sl)=>{
18
- return sl.scopes && scopes && scopes.every((scope)=>sl.scopes && sl.scopes.includes(scope));
19
- })) === null || _scopedInstanceArray_find === void 0 ? void 0 : _scopedInstanceArray_find.instance;
20
- } else {
21
- var _scopedInstanceArray_;
22
- instance = (_scopedInstanceArray_ = scopedInstanceArray[0]) === null || _scopedInstanceArray_ === void 0 ? void 0 : _scopedInstanceArray_.instance;
10
+ const findScopedInstance = (scopedInstances, requestedScopes)=>{
11
+ if (!requestedScopes || requestedScopes.length === 0) {
12
+ var _scopedInstances_;
13
+ // Return first instance if no scopes specified
14
+ const firstInstance = (_scopedInstances_ = scopedInstances[0]) === null || _scopedInstances_ === void 0 ? void 0 : _scopedInstances_.instance;
15
+ if (!firstInstance) {
16
+ throw new Error('No instances available');
17
+ }
18
+ return firstInstance;
23
19
  }
24
- if (!instance) {
25
- throw new Error(`No Scoped Instance for ${scopes === null || scopes === void 0 ? void 0 : scopes.join(', ')}`);
20
+ // Find instance that matches all requested scopes
21
+ const matchingInstance = scopedInstances.find((scopedInstance)=>{
22
+ if (!scopedInstance.scopes) return false;
23
+ return requestedScopes.every((scope)=>scopedInstance.scopes && scopedInstance.scopes.includes(scope));
24
+ });
25
+ if (!matchingInstance) {
26
+ throw new Error(`No instance found matching scopes: ${requestedScopes.join(', ')}`);
26
27
  }
27
- return instance;
28
+ return matchingInstance.instance;
28
29
  };
29
- const createRegistry = ()=>{
30
- // TODO: My use of Generics has Boxes be into a corner where I can't reference AbstractLib without the types
31
- const libTree = {};
32
- const register = (kta, instance, options)=>{
33
- const ktaArray = [
30
+ const createRegistry = (type, registryHub)=>{
31
+ const instanceTree = {};
32
+ const createInstance = (kta, scopes, factory)=>{
33
+ logger.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
34
+ // Create coordinate for the instance
35
+ const coordinate = Coordinate.createCoordinate(kta, scopes);
36
+ // Use factory to create the instance with the new context parameter
37
+ const instance = factory(coordinate, {
38
+ registry,
39
+ registryHub
40
+ });
41
+ // Validate the created instance
42
+ if (!Instance.isInstance(instance)) {
43
+ throw new Error(`Factory did not return a valid instance for: ${kta.join('.')}`);
44
+ }
45
+ // Register the instance
46
+ registerInternal(kta, instance, {
47
+ scopes
48
+ });
49
+ return instance;
50
+ };
51
+ const registerInternal = (kta, instance, options)=>{
52
+ const keyPath = [
34
53
  ...kta
35
- ];
36
- let currentTree = libTree;
37
- logger.debug(`Registering lib for KTA and scopes`, ktaArray, options === null || options === void 0 ? void 0 : options.scopes);
54
+ ].reverse(); // Work from most specific to least specific
55
+ let currentLevel = instanceTree;
56
+ logger.debug(`Registering instance for key path and scopes`, keyPath, options === null || options === void 0 ? void 0 : options.scopes, `in registry type: ${type}`);
38
57
  if (!Instance.isInstance(instance)) {
39
- throw new Error(`Attempting to register a non-instance as an instance: ${ktaArray.join('.')}`);
58
+ throw new Error(`Attempting to register a non-instance: ${kta.join('.')}`);
40
59
  }
41
- while(ktaArray.length > 0){
42
- const kt = ktaArray.pop();
43
- if (kt) {
44
- if (ktaArray.length === 0) {
45
- if (!currentTree[kt]) {
46
- currentTree[kt] = [
47
- [],
48
- null
49
- ];
50
- }
51
- currentTree[kt][0].push({
52
- scopes: options === null || options === void 0 ? void 0 : options.scopes,
53
- instance
54
- });
55
- } else {
56
- if (!currentTree[kt]) {
57
- const newTree = {};
58
- currentTree[kt] = [
59
- [],
60
- newTree
61
- ];
62
- currentTree = newTree;
63
- } else if (!currentTree[kt][1]) {
64
- const newTree = {};
65
- currentTree[kt][1] = newTree;
66
- currentTree = newTree;
67
- } else {
68
- currentTree = currentTree[kt][1];
69
- }
70
- }
60
+ // Navigate to the correct location in the tree
61
+ for(let i = 0; i < keyPath.length; i++){
62
+ const keyType = keyPath[i];
63
+ const isLeaf = i === keyPath.length - 1;
64
+ if (!currentLevel[keyType]) {
65
+ currentLevel[keyType] = {
66
+ instances: [],
67
+ children: isLeaf ? null : {}
68
+ };
69
+ }
70
+ if (isLeaf) {
71
+ // Add instance to the leaf node
72
+ currentLevel[keyType].instances.push({
73
+ scopes: options === null || options === void 0 ? void 0 : options.scopes,
74
+ instance
75
+ });
71
76
  } else {
72
- throw new Error(`Invalid KTA containing an empty false or undefined kt: ${ktaArray.join('.')}`);
77
+ // Navigate deeper into the tree
78
+ if (!currentLevel[keyType].children) {
79
+ currentLevel[keyType].children = {};
80
+ }
81
+ currentLevel = currentLevel[keyType].children;
73
82
  }
74
83
  }
75
84
  };
85
+ const register = (kta, instance, options)=>{
86
+ logger.debug('Using deprecated register method. Consider using createInstance instead.');
87
+ registerInternal(kta, instance, options);
88
+ };
76
89
  const get = (kta, options)=>{
77
- const ktaArray = [
90
+ const keyPath = [
78
91
  ...kta
79
- ];
80
- let currentTree = libTree;
81
- let instance = null;
82
- // logger.debug(`Getting lib for KTA and scopes`, ktaArray, options?.scopes);
83
- while(ktaArray.length > 0){
84
- const kt = ktaArray.pop();
85
- if (kt) {
86
- if (ktaArray.length === 0 && currentTree[kt]) {
87
- const element = currentTree[kt];
88
- const scopedInstanceArray = element[0];
89
- if (scopedInstanceArray.length > 0 && isScopedInstance(scopedInstanceArray[0])) {
90
- instance = retrieveScopedInstance(scopedInstanceArray, options === null || options === void 0 ? void 0 : options.scopes);
91
- // eslint-disable-next-line max-depth
92
- if (!instance) {
93
- var _options_scopes;
94
- 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(', ')}`);
95
- }
96
- } else {
97
- throw new Error(`No Instance not found for kta: ${JSON.stringify(ktaArray)}, Last Key not a instance: ${kt}`);
98
- }
99
- } else {
100
- if (!currentTree[kt]) {
101
- throw new Error(`Lib not found for kta: ${JSON.stringify(ktaArray)}, Subtree Not Found: ${kt}`);
102
- } else {
103
- currentTree = currentTree[kt][1];
104
- }
92
+ ].reverse();
93
+ let currentLevel = instanceTree;
94
+ // Navigate to the target node
95
+ for(let i = 0; i < keyPath.length; i++){
96
+ const keyType = keyPath[i];
97
+ const isLeaf = i === keyPath.length - 1;
98
+ if (!currentLevel[keyType]) {
99
+ throw new Error(`Instance not found for key path: ${kta.join('.')}, Missing key: ${keyType}`);
100
+ }
101
+ if (isLeaf) {
102
+ // Found the target node, extract instance
103
+ const scopedInstances = currentLevel[keyType].instances;
104
+ if (scopedInstances.length === 0) {
105
+ throw new Error(`No instances registered for key path: ${kta.join('.')}`);
105
106
  }
107
+ return findScopedInstance(scopedInstances, options === null || options === void 0 ? void 0 : options.scopes);
106
108
  } else {
107
- throw new Error(`Invalid KTA containing an empty false or undefined kt: ${JSON.stringify(ktaArray)}`);
109
+ // Continue navigation
110
+ if (!currentLevel[keyType].children) {
111
+ throw new Error(`Instance not found for key path: ${kta.join('.')}, No children for: ${keyType}`);
112
+ }
113
+ currentLevel = currentLevel[keyType].children;
108
114
  }
109
115
  }
110
- return instance;
116
+ return null;
111
117
  };
112
- return {
118
+ const registry = {
119
+ type,
120
+ registryHub,
121
+ createInstance,
113
122
  register,
114
123
  get,
115
- // TODO: Remove this once we have a better way to test
116
- libTree
124
+ instanceTree
117
125
  };
126
+ return registry;
118
127
  };
119
128
 
120
129
  exports.createRegistry = createRegistry;
121
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==
130
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==
@@ -1,42 +1,3 @@
1
- import { Instance } from './Instance';
2
- /**
3
- * The Registry interface provides a central registry for managing and accessing instances of services.
4
- * It serves as a dependency injection container that allows libraries to reference and access
5
- * other library instances they depend on.
6
- *
7
- * The registry maintains a tree structure of library instances and provides methods to:
8
- * 1. Register new library instances with their key types and optional scopes
9
- * 2. Retrieve library instances by their key types and optional scopes
10
- * 3. Access the library tree structure for dependency resolution
11
- */
12
- export interface Registry {
13
- /**
14
- * Registers a new library instance in the registry.
15
- * @param kta - Array of key types that identify this library instance
16
- * @param instance - The library instance to register
17
- * @param options - Optional configuration including scopes for the instance
18
- */
19
- register: (kta: string[], instance: Instance<any, any | never, any | never, any | never, any | never, any | never>, options?: {
20
- scopes?: string[];
21
- }) => void;
22
- /**
23
- * Retrieves a library instance from the registry.
24
- * @param kta - Array of key types to identify the library instance
25
- * @param options - Optional configuration including scopes to search in
26
- * @returns The found library instance or null if not found
27
- */
28
- get: (kta: string[], options?: {
29
- scopes?: string[];
30
- }) => Instance<any, any | never, any | never, any | never, any | never, any | never> | null;
31
- /** The tree structure representing the hierarchy of library instances */
32
- libTree: LibTree;
33
- }
34
- interface ScopedInstance {
35
- scopes?: string[];
36
- instance: Instance<any, any | never, any | never, any | never, any | never, any | never>;
37
- }
38
- interface LibTree {
39
- [kt: string]: [ScopedInstance[], LibTree | null];
40
- }
41
- export declare const createRegistry: () => Registry;
42
- export {};
1
+ import { Registry, RegistryHub } from './types';
2
+ export type { Registry, RegistryHub, InstanceFactory, RegistryFactory } from './types';
3
+ export declare const createRegistry: (type: string, registryHub?: RegistryHub) => Registry;
package/dist/Registry.js CHANGED
@@ -1,117 +1,126 @@
1
1
  import LibLogger from './logger.js';
2
2
  import { isInstance } from './Instance.js';
3
+ import { createCoordinate } from './Coordinate.js';
3
4
 
4
5
  const logger = LibLogger.get("Registry");
5
- const isScopedInstance = (instance)=>{
6
- // eslint-disable-next-line no-undefined
7
- return instance.instance !== undefined;
8
- };
9
- const retrieveScopedInstance = (scopedInstanceArray, scopes)=>{
10
- let instance;
11
- if (scopes) {
12
- var _scopedInstanceArray_find;
13
- instance = (_scopedInstanceArray_find = scopedInstanceArray.find((sl)=>{
14
- return sl.scopes && scopes && scopes.every((scope)=>sl.scopes && sl.scopes.includes(scope));
15
- })) === null || _scopedInstanceArray_find === void 0 ? void 0 : _scopedInstanceArray_find.instance;
16
- } else {
17
- var _scopedInstanceArray_;
18
- instance = (_scopedInstanceArray_ = scopedInstanceArray[0]) === null || _scopedInstanceArray_ === void 0 ? void 0 : _scopedInstanceArray_.instance;
6
+ const findScopedInstance = (scopedInstances, requestedScopes)=>{
7
+ if (!requestedScopes || requestedScopes.length === 0) {
8
+ var _scopedInstances_;
9
+ // Return first instance if no scopes specified
10
+ const firstInstance = (_scopedInstances_ = scopedInstances[0]) === null || _scopedInstances_ === void 0 ? void 0 : _scopedInstances_.instance;
11
+ if (!firstInstance) {
12
+ throw new Error('No instances available');
13
+ }
14
+ return firstInstance;
19
15
  }
20
- if (!instance) {
21
- throw new Error(`No Scoped Instance for ${scopes === null || scopes === void 0 ? void 0 : scopes.join(', ')}`);
16
+ // Find instance that matches all requested scopes
17
+ const matchingInstance = scopedInstances.find((scopedInstance)=>{
18
+ if (!scopedInstance.scopes) return false;
19
+ return requestedScopes.every((scope)=>scopedInstance.scopes && scopedInstance.scopes.includes(scope));
20
+ });
21
+ if (!matchingInstance) {
22
+ throw new Error(`No instance found matching scopes: ${requestedScopes.join(', ')}`);
22
23
  }
23
- return instance;
24
+ return matchingInstance.instance;
24
25
  };
25
- const createRegistry = ()=>{
26
- // TODO: My use of Generics has Boxes be into a corner where I can't reference AbstractLib without the types
27
- const libTree = {};
28
- const register = (kta, instance, options)=>{
29
- const ktaArray = [
26
+ const createRegistry = (type, registryHub)=>{
27
+ const instanceTree = {};
28
+ const createInstance = (kta, scopes, factory)=>{
29
+ logger.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
30
+ // Create coordinate for the instance
31
+ const coordinate = createCoordinate(kta, scopes);
32
+ // Use factory to create the instance with the new context parameter
33
+ const instance = factory(coordinate, {
34
+ registry,
35
+ registryHub
36
+ });
37
+ // Validate the created instance
38
+ if (!isInstance(instance)) {
39
+ throw new Error(`Factory did not return a valid instance for: ${kta.join('.')}`);
40
+ }
41
+ // Register the instance
42
+ registerInternal(kta, instance, {
43
+ scopes
44
+ });
45
+ return instance;
46
+ };
47
+ const registerInternal = (kta, instance, options)=>{
48
+ const keyPath = [
30
49
  ...kta
31
- ];
32
- let currentTree = libTree;
33
- logger.debug(`Registering lib for KTA and scopes`, ktaArray, options === null || options === void 0 ? void 0 : options.scopes);
50
+ ].reverse(); // Work from most specific to least specific
51
+ let currentLevel = instanceTree;
52
+ logger.debug(`Registering instance for key path and scopes`, keyPath, options === null || options === void 0 ? void 0 : options.scopes, `in registry type: ${type}`);
34
53
  if (!isInstance(instance)) {
35
- throw new Error(`Attempting to register a non-instance as an instance: ${ktaArray.join('.')}`);
54
+ throw new Error(`Attempting to register a non-instance: ${kta.join('.')}`);
36
55
  }
37
- while(ktaArray.length > 0){
38
- const kt = ktaArray.pop();
39
- if (kt) {
40
- if (ktaArray.length === 0) {
41
- if (!currentTree[kt]) {
42
- currentTree[kt] = [
43
- [],
44
- null
45
- ];
46
- }
47
- currentTree[kt][0].push({
48
- scopes: options === null || options === void 0 ? void 0 : options.scopes,
49
- instance
50
- });
51
- } else {
52
- if (!currentTree[kt]) {
53
- const newTree = {};
54
- currentTree[kt] = [
55
- [],
56
- newTree
57
- ];
58
- currentTree = newTree;
59
- } else if (!currentTree[kt][1]) {
60
- const newTree = {};
61
- currentTree[kt][1] = newTree;
62
- currentTree = newTree;
63
- } else {
64
- currentTree = currentTree[kt][1];
65
- }
66
- }
56
+ // Navigate to the correct location in the tree
57
+ for(let i = 0; i < keyPath.length; i++){
58
+ const keyType = keyPath[i];
59
+ const isLeaf = i === keyPath.length - 1;
60
+ if (!currentLevel[keyType]) {
61
+ currentLevel[keyType] = {
62
+ instances: [],
63
+ children: isLeaf ? null : {}
64
+ };
65
+ }
66
+ if (isLeaf) {
67
+ // Add instance to the leaf node
68
+ currentLevel[keyType].instances.push({
69
+ scopes: options === null || options === void 0 ? void 0 : options.scopes,
70
+ instance
71
+ });
67
72
  } else {
68
- throw new Error(`Invalid KTA containing an empty false or undefined kt: ${ktaArray.join('.')}`);
73
+ // Navigate deeper into the tree
74
+ if (!currentLevel[keyType].children) {
75
+ currentLevel[keyType].children = {};
76
+ }
77
+ currentLevel = currentLevel[keyType].children;
69
78
  }
70
79
  }
71
80
  };
81
+ const register = (kta, instance, options)=>{
82
+ logger.debug('Using deprecated register method. Consider using createInstance instead.');
83
+ registerInternal(kta, instance, options);
84
+ };
72
85
  const get = (kta, options)=>{
73
- const ktaArray = [
86
+ const keyPath = [
74
87
  ...kta
75
- ];
76
- let currentTree = libTree;
77
- let instance = null;
78
- // logger.debug(`Getting lib for KTA and scopes`, ktaArray, options?.scopes);
79
- while(ktaArray.length > 0){
80
- const kt = ktaArray.pop();
81
- if (kt) {
82
- if (ktaArray.length === 0 && currentTree[kt]) {
83
- const element = currentTree[kt];
84
- const scopedInstanceArray = element[0];
85
- if (scopedInstanceArray.length > 0 && isScopedInstance(scopedInstanceArray[0])) {
86
- instance = retrieveScopedInstance(scopedInstanceArray, options === null || options === void 0 ? void 0 : options.scopes);
87
- // eslint-disable-next-line max-depth
88
- if (!instance) {
89
- var _options_scopes;
90
- 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(', ')}`);
91
- }
92
- } else {
93
- throw new Error(`No Instance not found for kta: ${JSON.stringify(ktaArray)}, Last Key not a instance: ${kt}`);
94
- }
95
- } else {
96
- if (!currentTree[kt]) {
97
- throw new Error(`Lib not found for kta: ${JSON.stringify(ktaArray)}, Subtree Not Found: ${kt}`);
98
- } else {
99
- currentTree = currentTree[kt][1];
100
- }
88
+ ].reverse();
89
+ let currentLevel = instanceTree;
90
+ // Navigate to the target node
91
+ for(let i = 0; i < keyPath.length; i++){
92
+ const keyType = keyPath[i];
93
+ const isLeaf = i === keyPath.length - 1;
94
+ if (!currentLevel[keyType]) {
95
+ throw new Error(`Instance not found for key path: ${kta.join('.')}, Missing key: ${keyType}`);
96
+ }
97
+ if (isLeaf) {
98
+ // Found the target node, extract instance
99
+ const scopedInstances = currentLevel[keyType].instances;
100
+ if (scopedInstances.length === 0) {
101
+ throw new Error(`No instances registered for key path: ${kta.join('.')}`);
101
102
  }
103
+ return findScopedInstance(scopedInstances, options === null || options === void 0 ? void 0 : options.scopes);
102
104
  } else {
103
- throw new Error(`Invalid KTA containing an empty false or undefined kt: ${JSON.stringify(ktaArray)}`);
105
+ // Continue navigation
106
+ if (!currentLevel[keyType].children) {
107
+ throw new Error(`Instance not found for key path: ${kta.join('.')}, No children for: ${keyType}`);
108
+ }
109
+ currentLevel = currentLevel[keyType].children;
104
110
  }
105
111
  }
106
- return instance;
112
+ return null;
107
113
  };
108
- return {
114
+ const registry = {
115
+ type,
116
+ registryHub,
117
+ createInstance,
109
118
  register,
110
119
  get,
111
- // TODO: Remove this once we have a better way to test
112
- libTree
120
+ instanceTree
113
121
  };
122
+ return registry;
114
123
  };
115
124
 
116
125
  export { createRegistry };
117
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
126
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const logger$1 = require('./logger.cjs');
6
+ const RegistryHubError = require('./errors/RegistryHubError.cjs');
7
+
8
+ const logger = logger$1.default.get("RegistryHub");
9
+ const createRegistryHub = ()=>{
10
+ const registries = {};
11
+ const createRegistry = (type, factory)=>{
12
+ logger.debug(`Creating new registry with type: ${type}`);
13
+ if (registries[type]) {
14
+ throw new RegistryHubError.DuplicateRegistryTypeError(type);
15
+ }
16
+ // Create the registry with a reference to this hub
17
+ const registry = factory(type, hub);
18
+ // Ensure the created registry has a reference to this hub if not already set
19
+ if (!('registryHub' in registry) || registry.registryHub !== hub) {
20
+ // @ts-expect-error: registryHub is optional and may be readonly, but we want to set it for hub awareness
21
+ registry.registryHub = hub;
22
+ }
23
+ // Register the created registry
24
+ registries[type] = registry;
25
+ logger.debug(`Successfully created and registered new registry with type: ${type}`);
26
+ return registry;
27
+ };
28
+ const registerRegistry = (registry)=>{
29
+ const type = registry.type;
30
+ logger.debug(`Registering registry with type: ${type}`);
31
+ if (registries[type]) {
32
+ throw new RegistryHubError.DuplicateRegistryTypeError(type);
33
+ }
34
+ registries[type] = registry;
35
+ // Ensure the created registry has a reference to this hub if not already set
36
+ if (!('registryHub' in registry) || registry.registryHub !== hub) {
37
+ // @ts-expect-error: registryHub is optional and may be readonly, but we want to set it for hub awareness
38
+ registry.registryHub = hub;
39
+ }
40
+ logger.debug(`Successfully registered registry with type: ${type}`);
41
+ };
42
+ const get = (type, kta, options)=>{
43
+ var _options_scopes;
44
+ 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'}`);
45
+ const registry = registries[type];
46
+ if (!registry) {
47
+ const availableTypes = Object.keys(registries);
48
+ throw new RegistryHubError.RegistryTypeNotFoundError(type, availableTypes);
49
+ }
50
+ return registry.get(kta, options);
51
+ };
52
+ const getRegistry = (type)=>{
53
+ return registries[type] || null;
54
+ };
55
+ const getRegisteredTypes = ()=>{
56
+ return Object.keys(registries);
57
+ };
58
+ const unregisterRegistry = (type)=>{
59
+ if (registries[type]) {
60
+ delete registries[type];
61
+ logger.debug(`Unregistered registry under type: ${type}`);
62
+ return true;
63
+ }
64
+ return false;
65
+ };
66
+ const hub = {
67
+ createRegistry,
68
+ registerRegistry,
69
+ get,
70
+ getRegistry,
71
+ getRegisteredTypes,
72
+ unregisterRegistry
73
+ };
74
+ return hub;
75
+ };
76
+
77
+ exports.createRegistryHub = createRegistryHub;
78
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnlIdWIuY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,3 @@
1
+ import { RegistryHub } from './types';
2
+ export type { RegistryHub } from './types';
3
+ export declare const createRegistryHub: () => RegistryHub;