@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.
- package/README.md +546 -0
- package/dist/Coordinate.cjs +8 -5
- package/dist/Coordinate.d.ts +1 -1
- package/dist/Coordinate.js +8 -5
- package/dist/Instance.cjs +4 -4
- package/dist/Instance.d.ts +3 -4
- package/dist/Instance.js +4 -4
- package/dist/Registry.cjs +99 -90
- package/dist/Registry.d.ts +3 -42
- package/dist/Registry.js +99 -90
- package/dist/RegistryHub.cjs +78 -0
- package/dist/RegistryHub.d.ts +3 -0
- package/dist/RegistryHub.js +74 -0
- package/dist/errors/CoordinateError.cjs +70 -0
- package/dist/errors/CoordinateError.d.ts +28 -0
- package/dist/errors/CoordinateError.js +63 -0
- package/dist/errors/InstanceError.cjs +101 -0
- package/dist/errors/InstanceError.d.ts +42 -0
- package/dist/errors/InstanceError.js +92 -0
- package/dist/errors/RegistryError.cjs +82 -0
- package/dist/errors/RegistryError.d.ts +31 -0
- package/dist/errors/RegistryError.js +75 -0
- package/dist/errors/RegistryHubError.cjs +92 -0
- package/dist/errors/RegistryHubError.d.ts +39 -0
- package/dist/errors/RegistryHubError.js +84 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/index.cjs +501 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +6 -2
- package/dist/types.d.ts +90 -0
- package/docs/TIMING_NODE_OPTIMIZATION.md +207 -0
- package/docs/TIMING_README.md +170 -0
- package/docs/memory-data/scaling-10-instances.json +526 -0
- package/docs/memory-data/scaling-100-instances.json +526 -0
- package/docs/memory-data/scaling-1000-instances.json +276 -0
- package/docs/memory-data/scaling-10000-instances.json +126 -0
- package/docs/memory-data/scaling-20-instances.json +526 -0
- package/docs/memory-data/scaling-200-instances.json +526 -0
- package/docs/memory-data/scaling-2000-instances.json +276 -0
- package/docs/memory-data/scaling-50-instances.json +526 -0
- package/docs/memory-data/scaling-500-instances.json +276 -0
- package/docs/memory-data/scaling-5000-instances.json +126 -0
- package/docs/memory-overhead.svg +120 -0
- package/docs/memory.md +430 -0
- package/docs/timing-range.svg +174 -0
- package/docs/timing.md +483 -0
- package/examples/README.md +187 -0
- package/examples/multi-level-keys.ts +374 -0
- package/examples/registry-hub-types.ts +437 -0
- package/examples/simple-example.ts +250 -0
- package/package.json +5 -3
- package/dist/Definition.cjs +0 -18
- package/dist/Definition.d.ts +0 -5
- package/dist/Definition.js +0 -14
package/dist/index.cjs
CHANGED
|
@@ -7,166 +7,555 @@ const Logging = require('@fjell/logging');
|
|
|
7
7
|
const LibLogger = Logging.getLogger('@fjell/registry');
|
|
8
8
|
|
|
9
9
|
const logger$3 = LibLogger.get("Coordinate");
|
|
10
|
-
const createCoordinate = (kta, scopes)=>{
|
|
10
|
+
const createCoordinate = (kta, scopes = [])=>{
|
|
11
|
+
const ktArray = Array.isArray(kta) ? kta : [
|
|
12
|
+
kta
|
|
13
|
+
];
|
|
11
14
|
const toString = ()=>{
|
|
12
15
|
logger$3.debug("toString", {
|
|
13
16
|
kta,
|
|
14
17
|
scopes
|
|
15
18
|
});
|
|
16
|
-
return `${
|
|
19
|
+
return `${ktArray.join(', ')} - ${scopes.join(', ')}`;
|
|
17
20
|
};
|
|
18
21
|
logger$3.debug("createCoordinate", {
|
|
19
|
-
kta,
|
|
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$2 = LibLogger.get("
|
|
31
|
-
const
|
|
32
|
-
logger$2.debug("
|
|
33
|
-
coordinate
|
|
34
|
-
});
|
|
35
|
-
return {
|
|
36
|
-
coordinate
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const logger$1 = LibLogger.get("Instance");
|
|
41
|
-
const createInstance = (definition, registry)=>{
|
|
42
|
-
logger$1.debug("createInstance", {
|
|
43
|
-
definition,
|
|
33
|
+
const logger$2 = LibLogger.get("Instance");
|
|
34
|
+
const createInstance = (registry, coordinate)=>{
|
|
35
|
+
logger$2.debug("createInstance", {
|
|
36
|
+
coordinate,
|
|
44
37
|
registry
|
|
45
38
|
});
|
|
46
39
|
return {
|
|
47
|
-
|
|
40
|
+
coordinate,
|
|
48
41
|
registry
|
|
49
42
|
};
|
|
50
43
|
};
|
|
51
44
|
const isInstance = (instance)=>{
|
|
52
|
-
return instance !== null && instance !== undefined && instance.
|
|
45
|
+
return instance !== null && instance !== undefined && instance.coordinate !== undefined && instance.registry !== undefined;
|
|
53
46
|
};
|
|
54
47
|
|
|
55
|
-
const logger = LibLogger.get("Registry");
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return sl.scopes && scopes && scopes.every((scope)=>sl.scopes && sl.scopes.includes(scope));
|
|
66
|
-
})) === null || _scopedInstanceArray_find === void 0 ? void 0 : _scopedInstanceArray_find.instance;
|
|
67
|
-
} else {
|
|
68
|
-
var _scopedInstanceArray_;
|
|
69
|
-
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;
|
|
70
58
|
}
|
|
71
|
-
|
|
72
|
-
|
|
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(', ')}`);
|
|
73
66
|
}
|
|
74
|
-
return instance;
|
|
67
|
+
return matchingInstance.instance;
|
|
75
68
|
};
|
|
76
|
-
const createRegistry = ()=>{
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
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 = [
|
|
81
92
|
...kta
|
|
82
|
-
];
|
|
83
|
-
let
|
|
84
|
-
logger.debug(`Registering
|
|
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}`);
|
|
85
96
|
if (!isInstance(instance)) {
|
|
86
|
-
throw new Error(`Attempting to register a non-instance
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const newTree = {};
|
|
105
|
-
currentTree[kt] = [
|
|
106
|
-
[],
|
|
107
|
-
newTree
|
|
108
|
-
];
|
|
109
|
-
currentTree = newTree;
|
|
110
|
-
} else if (!currentTree[kt][1]) {
|
|
111
|
-
const newTree = {};
|
|
112
|
-
currentTree[kt][1] = newTree;
|
|
113
|
-
currentTree = newTree;
|
|
114
|
-
} else {
|
|
115
|
-
currentTree = currentTree[kt][1];
|
|
116
|
-
}
|
|
117
|
-
}
|
|
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
|
+
});
|
|
118
115
|
} else {
|
|
119
|
-
|
|
116
|
+
// Navigate deeper into the tree
|
|
117
|
+
if (!currentLevel[keyType].children) {
|
|
118
|
+
currentLevel[keyType].children = {};
|
|
119
|
+
}
|
|
120
|
+
currentLevel = currentLevel[keyType].children;
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
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
|
+
};
|
|
123
128
|
const get = (kta, options)=>{
|
|
124
|
-
const
|
|
129
|
+
const keyPath = [
|
|
125
130
|
...kta
|
|
126
|
-
];
|
|
127
|
-
let
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
var _options_scopes;
|
|
141
|
-
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(', ')}`);
|
|
142
|
-
}
|
|
143
|
-
} else {
|
|
144
|
-
throw new Error(`No Instance not found for kta: ${JSON.stringify(ktaArray)}, Last Key not a instance: ${kt}`);
|
|
145
|
-
}
|
|
146
|
-
} else {
|
|
147
|
-
if (!currentTree[kt]) {
|
|
148
|
-
throw new Error(`Lib not found for kta: ${JSON.stringify(ktaArray)}, Subtree Not Found: ${kt}`);
|
|
149
|
-
} else {
|
|
150
|
-
currentTree = currentTree[kt][1];
|
|
151
|
-
}
|
|
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('.')}`);
|
|
152
145
|
}
|
|
146
|
+
return findScopedInstance(scopedInstances, options === null || options === void 0 ? void 0 : options.scopes);
|
|
153
147
|
} else {
|
|
154
|
-
|
|
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;
|
|
155
153
|
}
|
|
156
154
|
}
|
|
157
|
-
return
|
|
155
|
+
return null;
|
|
158
156
|
};
|
|
159
|
-
|
|
157
|
+
const registry = {
|
|
158
|
+
type,
|
|
159
|
+
registryHub,
|
|
160
|
+
createInstance,
|
|
160
161
|
register,
|
|
161
162
|
get,
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
instanceTree
|
|
164
|
+
};
|
|
165
|
+
return registry;
|
|
166
|
+
};
|
|
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
|
|
164
386
|
};
|
|
387
|
+
return hub;
|
|
165
388
|
};
|
|
166
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;
|
|
167
556
|
exports.createCoordinate = createCoordinate;
|
|
168
|
-
exports.createDefinition = createDefinition;
|
|
169
557
|
exports.createInstance = createInstance;
|
|
170
558
|
exports.createRegistry = createRegistry;
|
|
559
|
+
exports.createRegistryHub = createRegistryHub;
|
|
171
560
|
exports.isInstance = isInstance;
|
|
172
561
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|