@twin.org/core 0.0.3-next.17 → 0.0.3-next.19
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.
|
@@ -103,14 +103,25 @@ export class Factory {
|
|
|
103
103
|
* Register a new generator.
|
|
104
104
|
* @param name The name of the generator.
|
|
105
105
|
* @param generator The function to create an instance.
|
|
106
|
+
* @param options Options for the generator.
|
|
107
|
+
* @param options.isDefault Whether the generator is the default one i.e. should be the first generator.
|
|
106
108
|
*/
|
|
107
|
-
register(name, generator) {
|
|
109
|
+
register(name, generator, options) {
|
|
108
110
|
Guards.stringValue(Factory.CLASS_NAME, "name", name);
|
|
109
111
|
Guards.function(Factory.CLASS_NAME, "generator", generator);
|
|
110
112
|
this._generators[name] = {
|
|
111
113
|
generator,
|
|
112
114
|
order: this._orderCounter++
|
|
113
115
|
};
|
|
116
|
+
// If this is the default generator, we want to make sure it is the first one by resetting the order of all generators.
|
|
117
|
+
if (options?.isDefault ?? false) {
|
|
118
|
+
let lowestOrder = 0;
|
|
119
|
+
for (const generatorName in this._generators) {
|
|
120
|
+
lowestOrder = Math.min(lowestOrder, this._generators[generatorName].order);
|
|
121
|
+
this._generators[generatorName].order++;
|
|
122
|
+
}
|
|
123
|
+
this._generators[name].order = lowestOrder;
|
|
124
|
+
}
|
|
114
125
|
// Remove any existing instance
|
|
115
126
|
this.removeInstance(name);
|
|
116
127
|
if (this._autoInstance) {
|
|
@@ -153,25 +164,6 @@ export class Factory {
|
|
|
153
164
|
}
|
|
154
165
|
return instance;
|
|
155
166
|
}
|
|
156
|
-
/**
|
|
157
|
-
* Create a new instance without caching it.
|
|
158
|
-
* @param name The name of the instance to generate.
|
|
159
|
-
* @param args The arguments to pass to the generator.
|
|
160
|
-
* @returns A new instance of the item.
|
|
161
|
-
* @throws GuardError if the parameters are invalid.
|
|
162
|
-
* @throws GeneralError if no item exists to create.
|
|
163
|
-
*/
|
|
164
|
-
create(name, args) {
|
|
165
|
-
Guards.stringValue(Factory.CLASS_NAME, "name", name);
|
|
166
|
-
const matchName = this._matcher(Object.keys(this._generators), name);
|
|
167
|
-
if (Is.stringValue(matchName) && this._generators[matchName]) {
|
|
168
|
-
return this._generators[matchName].generator(args);
|
|
169
|
-
}
|
|
170
|
-
throw new GeneralError(Factory.CLASS_NAME, "noGet", {
|
|
171
|
-
typeName: this._typeName,
|
|
172
|
-
name
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
167
|
/**
|
|
176
168
|
* Get a generator instance with no exceptions.
|
|
177
169
|
* @param name The name of the instance to generate.
|
|
@@ -192,6 +184,40 @@ export class Factory {
|
|
|
192
184
|
}
|
|
193
185
|
}
|
|
194
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Create a new instance without caching it.
|
|
189
|
+
* @param name The name of the instance to generate.
|
|
190
|
+
* @param args The arguments to pass to the generator.
|
|
191
|
+
* @returns A new instance of the item.
|
|
192
|
+
* @throws GuardError if the parameters are invalid.
|
|
193
|
+
* @throws GeneralError if no item exists to create.
|
|
194
|
+
*/
|
|
195
|
+
create(name, args) {
|
|
196
|
+
Guards.stringValue(Factory.CLASS_NAME, "name", name);
|
|
197
|
+
const instance = this.createIfExists(name, args);
|
|
198
|
+
if (!instance) {
|
|
199
|
+
throw new GeneralError(Factory.CLASS_NAME, "noCreate", {
|
|
200
|
+
typeName: this._typeName,
|
|
201
|
+
name,
|
|
202
|
+
args: Is.undefined(args) ? "" : JSON.stringify(args)
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return instance;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Create a new instance without caching it if it exists.
|
|
209
|
+
* @param name The name of the instance to generate.
|
|
210
|
+
* @param args The arguments to pass to the generator.
|
|
211
|
+
* @returns A new instance of the item if it exists.
|
|
212
|
+
* @throws GuardError if the parameters are invalid.
|
|
213
|
+
*/
|
|
214
|
+
createIfExists(name, args) {
|
|
215
|
+
Guards.stringValue(Factory.CLASS_NAME, "name", name);
|
|
216
|
+
const matchName = this._matcher(Object.keys(this._generators), name);
|
|
217
|
+
if (Is.stringValue(matchName) && this._generators[matchName]) {
|
|
218
|
+
return this._generators[matchName].generator(args);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
195
221
|
/**
|
|
196
222
|
* Remove all the instances and leave the generators intact.
|
|
197
223
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/factories/factory.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { GeneralError } from \"../errors/generalError.js\";\nimport { Guards } from \"../utils/guards.js\";\nimport { Is } from \"../utils/is.js\";\nimport { SharedStore } from \"../utils/sharedStore.js\";\n\n/**\n * Factory for creating implementation of generic types.\n */\nexport class Factory<T> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Factory<unknown>>();\n\n\t/**\n\t * Type name for the instances.\n\t * @internal\n\t */\n\tprivate readonly _typeName: string;\n\n\t/**\n\t * Store the generators.\n\t * @internal\n\t */\n\tprivate _generators: {\n\t\t[name: string]: {\n\t\t\tgenerator: (args?: unknown) => T;\n\t\t\torder: number;\n\t\t};\n\t};\n\n\t/**\n\t * Store the created instances.\n\t * @internal\n\t */\n\tprivate _instances: { [name: string]: T };\n\n\t/**\n\t * Counter for the ordering.\n\t * @internal\n\t */\n\tprivate _orderCounter: number;\n\n\t/**\n\t * Automatically created an instance when registered.\n\t * @internal\n\t */\n\tprivate readonly _autoInstance: boolean;\n\n\t/**\n\t * Match the name of the instance.\n\t * @internal\n\t */\n\tprivate readonly _matcher: (names: string[], name: string) => string | undefined;\n\n\t/**\n\t * Create a new instance of Factory, private use createFactory.\n\t * @param typeName The type name for the instances.\n\t * @param autoInstance Automatically create an instance when registered.\n\t * @param matcher Match the name of the instance.\n\t * @internal\n\t */\n\tprivate constructor(\n\t\ttypeName: string,\n\t\tautoInstance: boolean = false,\n\t\tmatcher?: (names: string[], name: string) => string | undefined\n\t) {\n\t\tthis._typeName = typeName;\n\t\tthis._generators = {};\n\t\tthis._instances = {};\n\t\tthis._orderCounter = 0;\n\t\tthis._autoInstance = autoInstance;\n\t\tthis._matcher = matcher ?? this.defaultMatcher.bind(this);\n\t}\n\n\t/**\n\t * Create a new factory, which is shared throughout all library instances.\n\t * @param typeName The type name for the instances.\n\t * @param autoInstance Automatically create an instance when registered.\n\t * @param matcher Match the name of the instance.\n\t * @returns The factory instance.\n\t */\n\tpublic static createFactory<U>(\n\t\ttypeName: string,\n\t\tautoInstance: boolean = false,\n\t\tmatcher?: (names: string[], name: string) => string | undefined\n\t): Factory<U> {\n\t\tconst factories = Factory.getFactories();\n\n\t\tif (Is.undefined(factories[typeName])) {\n\t\t\tfactories[typeName] = new Factory<U>(typeName, autoInstance, matcher);\n\t\t}\n\t\treturn factories[typeName] as Factory<U>;\n\t}\n\n\t/**\n\t * Get all the factories.\n\t * @returns All the factories.\n\t */\n\tpublic static getFactories(): { [typeName: string]: Factory<unknown> } {\n\t\tlet factories = SharedStore.get<{\n\t\t\t[typeName: string]: Factory<unknown>;\n\t\t}>(\"factories\");\n\n\t\tif (Is.undefined(factories)) {\n\t\t\tfactories = {};\n\t\t\tSharedStore.set(\"factories\", factories);\n\t\t}\n\n\t\treturn factories;\n\t}\n\n\t/**\n\t * Reset all the factories, which removes any created instances, but not the registrations.\n\t */\n\tpublic static resetFactories(): void {\n\t\tconst factories = Factory.getFactories();\n\n\t\tfor (const typeName in factories) {\n\t\t\tfactories[typeName].reset();\n\t\t}\n\t}\n\n\t/**\n\t * Clear all the factories, which removes anything registered with the factories.\n\t */\n\tpublic static clearFactories(): void {\n\t\tconst factories = Factory.getFactories();\n\n\t\tfor (const typeName in factories) {\n\t\t\tfactories[typeName].clear();\n\t\t}\n\t}\n\n\t/**\n\t * Register a new generator.\n\t * @param name The name of the generator.\n\t * @param generator The function to create an instance.\n\t */\n\tpublic register<U extends T>(name: string, generator: (args?: unknown) => U): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tGuards.function(Factory.CLASS_NAME, nameof(generator), generator);\n\t\tthis._generators[name] = {\n\t\t\tgenerator,\n\t\t\torder: this._orderCounter++\n\t\t};\n\t\t// Remove any existing instance\n\t\tthis.removeInstance(name);\n\t\tif (this._autoInstance) {\n\t\t\tthis._instances[name] = generator();\n\t\t}\n\t}\n\n\t/**\n\t * Unregister a generator.\n\t * @param name The name of the generator to unregister.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no generator exists.\n\t */\n\tpublic unregister(name: string): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tif (!this._generators[name]) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noUnregister\", {\n\t\t\t\ttypeName: this._typeName,\n\t\t\t\tname\n\t\t\t});\n\t\t}\n\t\tdelete this._generators[name];\n\t\t// Remove any existing instance\n\t\tthis.removeInstance(name);\n\t}\n\n\t/**\n\t * Get a generator instance.\n\t * @param name The name of the instance to generate.\n\t * @returns An instance of the item.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no item exists to get.\n\t */\n\tpublic get<U extends T>(name: string): U {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tconst instance = this.getIfExists(name);\n\t\tif (!instance) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noGet\", {\n\t\t\t\ttypeName: this._typeName,\n\t\t\t\tname\n\t\t\t});\n\t\t}\n\t\treturn instance as U;\n\t}\n\n\t/**\n\t * Create a new instance without caching it.\n\t * @param name The name of the instance to generate.\n\t * @param args The arguments to pass to the generator.\n\t * @returns A new instance of the item.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no item exists to create.\n\t */\n\tpublic create<U extends T>(name: string, args?: unknown): U {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tconst matchName = this._matcher(Object.keys(this._generators), name);\n\n\t\tif (Is.stringValue(matchName) && this._generators[matchName]) {\n\t\t\treturn this._generators[matchName].generator(args) as U;\n\t\t}\n\n\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noGet\", {\n\t\t\ttypeName: this._typeName,\n\t\t\tname\n\t\t});\n\t}\n\n\t/**\n\t * Get a generator instance with no exceptions.\n\t * @param name The name of the instance to generate.\n\t * @returns An instance of the item or undefined if it does not exist.\n\t */\n\tpublic getIfExists<U extends T>(name?: string): U | undefined {\n\t\tif (Is.empty(name)) {\n\t\t\treturn;\n\t\t}\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\n\t\tconst matchName = this._matcher(Object.keys(this._generators), name);\n\n\t\tif (Is.stringValue(matchName) && this._generators[matchName]) {\n\t\t\tif (!this._instances[matchName]) {\n\t\t\t\tthis._instances[matchName] = this._generators[matchName].generator();\n\t\t\t}\n\t\t\tif (this._instances[matchName]) {\n\t\t\t\treturn this._instances[matchName] as U;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Remove all the instances and leave the generators intact.\n\t */\n\tpublic reset(): void {\n\t\tfor (const name in this._generators) {\n\t\t\tthis.removeInstance(name);\n\t\t}\n\t\tthis._instances = {};\n\t}\n\n\t/**\n\t * Remove all the instances and the generators.\n\t */\n\tpublic clear(): void {\n\t\tthis._instances = {};\n\t\tthis._generators = {};\n\t\tthis._orderCounter = 0;\n\t}\n\n\t/**\n\t * Get all the instances as a map.\n\t * @returns The instances as a map.\n\t */\n\tpublic instancesMap(): { [name: string]: T } {\n\t\treturn this._instances;\n\t}\n\n\t/**\n\t * Get all the instances as a list in the order they were registered.\n\t * @returns The instances as a list in the order they were registered.\n\t */\n\tpublic instancesList(): T[] {\n\t\tconst orderedInstances: { instance: T; order: number }[] = [];\n\t\tfor (const instanceName in this._instances) {\n\t\t\torderedInstances.push({\n\t\t\t\tinstance: this._instances[instanceName],\n\t\t\t\torder: this._generators[instanceName].order\n\t\t\t});\n\t\t}\n\t\treturn orderedInstances.sort((a, b) => a.order - b.order).map(o => o.instance);\n\t}\n\n\t/**\n\t * Get all the generator names in the order they were registered.\n\t * @returns The ordered generator names.\n\t */\n\tpublic names(): string[] {\n\t\tconst orderedNames: { name: string; order: number }[] = [];\n\t\tfor (const generator in this._generators) {\n\t\t\torderedNames.push({\n\t\t\t\tname: generator,\n\t\t\t\torder: this._generators[generator].order\n\t\t\t});\n\t\t}\n\t\treturn orderedNames.sort((a, b) => a.order - b.order).map(o => o.name);\n\t}\n\n\t/**\n\t * Does the factory contain the name.\n\t * @param name The name of the instance to find.\n\t * @returns True if the factory has a matching name.\n\t */\n\tpublic hasName(name: string): boolean {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\treturn Is.stringValue(this._matcher(Object.keys(this._generators), name));\n\t}\n\n\t/**\n\t * Remove any instances of the given name.\n\t * @param name The name of the instances to remove.\n\t * @internal\n\t */\n\tprivate removeInstance(name: string): void {\n\t\tdelete this._instances[name];\n\t}\n\n\t/**\n\t * Match the requested name to the generator name.\n\t * @param names The list of names for all the generators.\n\t * @param name The name to match.\n\t * @returns The matched name or undefined if no match.\n\t * @internal\n\t */\n\tprivate defaultMatcher(names: string[], name: string): string | undefined {\n\t\treturn this._generators[name] ? name : undefined;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/factories/factory.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { GeneralError } from \"../errors/generalError.js\";\nimport { Guards } from \"../utils/guards.js\";\nimport { Is } from \"../utils/is.js\";\nimport { SharedStore } from \"../utils/sharedStore.js\";\n\n/**\n * Factory for creating implementation of generic types.\n */\nexport class Factory<T> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Factory<unknown>>();\n\n\t/**\n\t * Type name for the instances.\n\t * @internal\n\t */\n\tprivate readonly _typeName: string;\n\n\t/**\n\t * Store the generators.\n\t * @internal\n\t */\n\tprivate _generators: {\n\t\t[name: string]: {\n\t\t\tgenerator: (args?: unknown) => T;\n\t\t\torder: number;\n\t\t};\n\t};\n\n\t/**\n\t * Store the created instances.\n\t * @internal\n\t */\n\tprivate _instances: { [name: string]: T };\n\n\t/**\n\t * Counter for the ordering.\n\t * @internal\n\t */\n\tprivate _orderCounter: number;\n\n\t/**\n\t * Automatically created an instance when registered.\n\t * @internal\n\t */\n\tprivate readonly _autoInstance: boolean;\n\n\t/**\n\t * Match the name of the instance.\n\t * @internal\n\t */\n\tprivate readonly _matcher: (names: string[], name: string) => string | undefined;\n\n\t/**\n\t * Create a new instance of Factory, private use createFactory.\n\t * @param typeName The type name for the instances.\n\t * @param autoInstance Automatically create an instance when registered.\n\t * @param matcher Match the name of the instance.\n\t * @internal\n\t */\n\tprivate constructor(\n\t\ttypeName: string,\n\t\tautoInstance: boolean = false,\n\t\tmatcher?: (names: string[], name: string) => string | undefined\n\t) {\n\t\tthis._typeName = typeName;\n\t\tthis._generators = {};\n\t\tthis._instances = {};\n\t\tthis._orderCounter = 0;\n\t\tthis._autoInstance = autoInstance;\n\t\tthis._matcher = matcher ?? this.defaultMatcher.bind(this);\n\t}\n\n\t/**\n\t * Create a new factory, which is shared throughout all library instances.\n\t * @param typeName The type name for the instances.\n\t * @param autoInstance Automatically create an instance when registered.\n\t * @param matcher Match the name of the instance.\n\t * @returns The factory instance.\n\t */\n\tpublic static createFactory<U>(\n\t\ttypeName: string,\n\t\tautoInstance: boolean = false,\n\t\tmatcher?: (names: string[], name: string) => string | undefined\n\t): Factory<U> {\n\t\tconst factories = Factory.getFactories();\n\n\t\tif (Is.undefined(factories[typeName])) {\n\t\t\tfactories[typeName] = new Factory<U>(typeName, autoInstance, matcher);\n\t\t}\n\t\treturn factories[typeName] as Factory<U>;\n\t}\n\n\t/**\n\t * Get all the factories.\n\t * @returns All the factories.\n\t */\n\tpublic static getFactories(): { [typeName: string]: Factory<unknown> } {\n\t\tlet factories = SharedStore.get<{\n\t\t\t[typeName: string]: Factory<unknown>;\n\t\t}>(\"factories\");\n\n\t\tif (Is.undefined(factories)) {\n\t\t\tfactories = {};\n\t\t\tSharedStore.set(\"factories\", factories);\n\t\t}\n\n\t\treturn factories;\n\t}\n\n\t/**\n\t * Reset all the factories, which removes any created instances, but not the registrations.\n\t */\n\tpublic static resetFactories(): void {\n\t\tconst factories = Factory.getFactories();\n\n\t\tfor (const typeName in factories) {\n\t\t\tfactories[typeName].reset();\n\t\t}\n\t}\n\n\t/**\n\t * Clear all the factories, which removes anything registered with the factories.\n\t */\n\tpublic static clearFactories(): void {\n\t\tconst factories = Factory.getFactories();\n\n\t\tfor (const typeName in factories) {\n\t\t\tfactories[typeName].clear();\n\t\t}\n\t}\n\n\t/**\n\t * Register a new generator.\n\t * @param name The name of the generator.\n\t * @param generator The function to create an instance.\n\t * @param options Options for the generator.\n\t * @param options.isDefault Whether the generator is the default one i.e. should be the first generator.\n\t */\n\tpublic register<U extends T>(\n\t\tname: string,\n\t\tgenerator: (args?: unknown) => U,\n\t\toptions?: { isDefault?: boolean }\n\t): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tGuards.function(Factory.CLASS_NAME, nameof(generator), generator);\n\t\tthis._generators[name] = {\n\t\t\tgenerator,\n\t\t\torder: this._orderCounter++\n\t\t};\n\n\t\t// If this is the default generator, we want to make sure it is the first one by resetting the order of all generators.\n\t\tif (options?.isDefault ?? false) {\n\t\t\tlet lowestOrder = 0;\n\t\t\tfor (const generatorName in this._generators) {\n\t\t\t\tlowestOrder = Math.min(lowestOrder, this._generators[generatorName].order);\n\t\t\t\tthis._generators[generatorName].order++;\n\t\t\t}\n\n\t\t\tthis._generators[name].order = lowestOrder;\n\t\t}\n\n\t\t// Remove any existing instance\n\t\tthis.removeInstance(name);\n\t\tif (this._autoInstance) {\n\t\t\tthis._instances[name] = generator();\n\t\t}\n\t}\n\n\t/**\n\t * Unregister a generator.\n\t * @param name The name of the generator to unregister.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no generator exists.\n\t */\n\tpublic unregister(name: string): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tif (!this._generators[name]) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noUnregister\", {\n\t\t\t\ttypeName: this._typeName,\n\t\t\t\tname\n\t\t\t});\n\t\t}\n\t\tdelete this._generators[name];\n\t\t// Remove any existing instance\n\t\tthis.removeInstance(name);\n\t}\n\n\t/**\n\t * Get a generator instance.\n\t * @param name The name of the instance to generate.\n\t * @returns An instance of the item.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no item exists to get.\n\t */\n\tpublic get<U extends T>(name: string): U {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tconst instance = this.getIfExists(name);\n\t\tif (!instance) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noGet\", {\n\t\t\t\ttypeName: this._typeName,\n\t\t\t\tname\n\t\t\t});\n\t\t}\n\t\treturn instance as U;\n\t}\n\n\t/**\n\t * Get a generator instance with no exceptions.\n\t * @param name The name of the instance to generate.\n\t * @returns An instance of the item or undefined if it does not exist.\n\t */\n\tpublic getIfExists<U extends T>(name?: string): U | undefined {\n\t\tif (Is.empty(name)) {\n\t\t\treturn;\n\t\t}\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\n\t\tconst matchName = this._matcher(Object.keys(this._generators), name);\n\n\t\tif (Is.stringValue(matchName) && this._generators[matchName]) {\n\t\t\tif (!this._instances[matchName]) {\n\t\t\t\tthis._instances[matchName] = this._generators[matchName].generator();\n\t\t\t}\n\t\t\tif (this._instances[matchName]) {\n\t\t\t\treturn this._instances[matchName] as U;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Create a new instance without caching it.\n\t * @param name The name of the instance to generate.\n\t * @param args The arguments to pass to the generator.\n\t * @returns A new instance of the item.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no item exists to create.\n\t */\n\tpublic create<U extends T>(name: string, args?: unknown): U {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tconst instance = this.createIfExists(name, args);\n\t\tif (!instance) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noCreate\", {\n\t\t\t\ttypeName: this._typeName,\n\t\t\t\tname,\n\t\t\t\targs: Is.undefined(args) ? \"\" : JSON.stringify(args)\n\t\t\t});\n\t\t}\n\t\treturn instance as U;\n\t}\n\n\t/**\n\t * Create a new instance without caching it if it exists.\n\t * @param name The name of the instance to generate.\n\t * @param args The arguments to pass to the generator.\n\t * @returns A new instance of the item if it exists.\n\t * @throws GuardError if the parameters are invalid.\n\t */\n\tpublic createIfExists<U extends T>(name: string, args?: unknown): U | undefined {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\tconst matchName = this._matcher(Object.keys(this._generators), name);\n\n\t\tif (Is.stringValue(matchName) && this._generators[matchName]) {\n\t\t\treturn this._generators[matchName].generator(args) as U;\n\t\t}\n\t}\n\n\t/**\n\t * Remove all the instances and leave the generators intact.\n\t */\n\tpublic reset(): void {\n\t\tfor (const name in this._generators) {\n\t\t\tthis.removeInstance(name);\n\t\t}\n\t\tthis._instances = {};\n\t}\n\n\t/**\n\t * Remove all the instances and the generators.\n\t */\n\tpublic clear(): void {\n\t\tthis._instances = {};\n\t\tthis._generators = {};\n\t\tthis._orderCounter = 0;\n\t}\n\n\t/**\n\t * Get all the instances as a map.\n\t * @returns The instances as a map.\n\t */\n\tpublic instancesMap(): { [name: string]: T } {\n\t\treturn this._instances;\n\t}\n\n\t/**\n\t * Get all the instances as a list in the order they were registered.\n\t * @returns The instances as a list in the order they were registered.\n\t */\n\tpublic instancesList(): T[] {\n\t\tconst orderedInstances: { instance: T; order: number }[] = [];\n\t\tfor (const instanceName in this._instances) {\n\t\t\torderedInstances.push({\n\t\t\t\tinstance: this._instances[instanceName],\n\t\t\t\torder: this._generators[instanceName].order\n\t\t\t});\n\t\t}\n\t\treturn orderedInstances.sort((a, b) => a.order - b.order).map(o => o.instance);\n\t}\n\n\t/**\n\t * Get all the generator names in the order they were registered.\n\t * @returns The ordered generator names.\n\t */\n\tpublic names(): string[] {\n\t\tconst orderedNames: { name: string; order: number }[] = [];\n\t\tfor (const generator in this._generators) {\n\t\t\torderedNames.push({\n\t\t\t\tname: generator,\n\t\t\t\torder: this._generators[generator].order\n\t\t\t});\n\t\t}\n\t\treturn orderedNames.sort((a, b) => a.order - b.order).map(o => o.name);\n\t}\n\n\t/**\n\t * Does the factory contain the name.\n\t * @param name The name of the instance to find.\n\t * @returns True if the factory has a matching name.\n\t */\n\tpublic hasName(name: string): boolean {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\t\treturn Is.stringValue(this._matcher(Object.keys(this._generators), name));\n\t}\n\n\t/**\n\t * Remove any instances of the given name.\n\t * @param name The name of the instances to remove.\n\t * @internal\n\t */\n\tprivate removeInstance(name: string): void {\n\t\tdelete this._instances[name];\n\t}\n\n\t/**\n\t * Match the requested name to the generator name.\n\t * @param names The list of names for all the generators.\n\t * @param name The name to match.\n\t * @returns The matched name or undefined if no match.\n\t * @internal\n\t */\n\tprivate defaultMatcher(names: string[], name: string): string | undefined {\n\t\treturn this._generators[name] ? name : undefined;\n\t}\n}\n"]}
|
|
@@ -33,8 +33,12 @@ export declare class Factory<T> {
|
|
|
33
33
|
* Register a new generator.
|
|
34
34
|
* @param name The name of the generator.
|
|
35
35
|
* @param generator The function to create an instance.
|
|
36
|
+
* @param options Options for the generator.
|
|
37
|
+
* @param options.isDefault Whether the generator is the default one i.e. should be the first generator.
|
|
36
38
|
*/
|
|
37
|
-
register<U extends T>(name: string, generator: (args?: unknown) => U
|
|
39
|
+
register<U extends T>(name: string, generator: (args?: unknown) => U, options?: {
|
|
40
|
+
isDefault?: boolean;
|
|
41
|
+
}): void;
|
|
38
42
|
/**
|
|
39
43
|
* Unregister a generator.
|
|
40
44
|
* @param name The name of the generator to unregister.
|
|
@@ -50,6 +54,12 @@ export declare class Factory<T> {
|
|
|
50
54
|
* @throws GeneralError if no item exists to get.
|
|
51
55
|
*/
|
|
52
56
|
get<U extends T>(name: string): U;
|
|
57
|
+
/**
|
|
58
|
+
* Get a generator instance with no exceptions.
|
|
59
|
+
* @param name The name of the instance to generate.
|
|
60
|
+
* @returns An instance of the item or undefined if it does not exist.
|
|
61
|
+
*/
|
|
62
|
+
getIfExists<U extends T>(name?: string): U | undefined;
|
|
53
63
|
/**
|
|
54
64
|
* Create a new instance without caching it.
|
|
55
65
|
* @param name The name of the instance to generate.
|
|
@@ -60,11 +70,13 @@ export declare class Factory<T> {
|
|
|
60
70
|
*/
|
|
61
71
|
create<U extends T>(name: string, args?: unknown): U;
|
|
62
72
|
/**
|
|
63
|
-
*
|
|
73
|
+
* Create a new instance without caching it if it exists.
|
|
64
74
|
* @param name The name of the instance to generate.
|
|
65
|
-
* @
|
|
75
|
+
* @param args The arguments to pass to the generator.
|
|
76
|
+
* @returns A new instance of the item if it exists.
|
|
77
|
+
* @throws GuardError if the parameters are invalid.
|
|
66
78
|
*/
|
|
67
|
-
|
|
79
|
+
createIfExists<U extends T>(name: string, args?: unknown): U | undefined;
|
|
68
80
|
/**
|
|
69
81
|
* Remove all the instances and leave the generators intact.
|
|
70
82
|
*/
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @twin.org/core - Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.19](https://github.com/twinfoundation/framework/compare/core-v0.0.3-next.18...core-v0.0.3-next.19) (2026-02-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add isDefault option to factory registration ([a8a700b](https://github.com/twinfoundation/framework/commit/a8a700bb8ddaf7dd5097869a358b8fc5f7c40ce7))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/nameof bumped from 0.0.3-next.18 to 0.0.3-next.19
|
|
16
|
+
* devDependencies
|
|
17
|
+
* @twin.org/nameof-transformer bumped from 0.0.3-next.18 to 0.0.3-next.19
|
|
18
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.3-next.18 to 0.0.3-next.19
|
|
19
|
+
|
|
20
|
+
## [0.0.3-next.18](https://github.com/twinfoundation/framework/compare/core-v0.0.3-next.17...core-v0.0.3-next.18) (2026-02-23)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* add factory.createIfExists ([aad5a53](https://github.com/twinfoundation/framework/commit/aad5a53cef1b1c2e04344ea46244d41e371dff9b))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Dependencies
|
|
29
|
+
|
|
30
|
+
* The following workspace dependencies were updated
|
|
31
|
+
* dependencies
|
|
32
|
+
* @twin.org/nameof bumped from 0.0.3-next.17 to 0.0.3-next.18
|
|
33
|
+
* devDependencies
|
|
34
|
+
* @twin.org/nameof-transformer bumped from 0.0.3-next.17 to 0.0.3-next.18
|
|
35
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.3-next.17 to 0.0.3-next.18
|
|
36
|
+
|
|
3
37
|
## [0.0.3-next.17](https://github.com/twinfoundation/framework/compare/core-v0.0.3-next.16...core-v0.0.3-next.17) (2026-02-09)
|
|
4
38
|
|
|
5
39
|
|
|
@@ -98,7 +98,7 @@ Clear all the factories, which removes anything registered with the factories.
|
|
|
98
98
|
|
|
99
99
|
### register()
|
|
100
100
|
|
|
101
|
-
> **register**\<`U`\>(`name`, `generator`): `void`
|
|
101
|
+
> **register**\<`U`\>(`name`, `generator`, `options?`): `void`
|
|
102
102
|
|
|
103
103
|
Register a new generator.
|
|
104
104
|
|
|
@@ -122,6 +122,16 @@ The name of the generator.
|
|
|
122
122
|
|
|
123
123
|
The function to create an instance.
|
|
124
124
|
|
|
125
|
+
##### options?
|
|
126
|
+
|
|
127
|
+
Options for the generator.
|
|
128
|
+
|
|
129
|
+
###### isDefault?
|
|
130
|
+
|
|
131
|
+
`boolean`
|
|
132
|
+
|
|
133
|
+
Whether the generator is the default one i.e. should be the first generator.
|
|
134
|
+
|
|
125
135
|
#### Returns
|
|
126
136
|
|
|
127
137
|
`void`
|
|
@@ -192,6 +202,34 @@ GeneralError if no item exists to get.
|
|
|
192
202
|
|
|
193
203
|
***
|
|
194
204
|
|
|
205
|
+
### getIfExists()
|
|
206
|
+
|
|
207
|
+
> **getIfExists**\<`U`\>(`name?`): `U` \| `undefined`
|
|
208
|
+
|
|
209
|
+
Get a generator instance with no exceptions.
|
|
210
|
+
|
|
211
|
+
#### Type Parameters
|
|
212
|
+
|
|
213
|
+
##### U
|
|
214
|
+
|
|
215
|
+
`U`
|
|
216
|
+
|
|
217
|
+
#### Parameters
|
|
218
|
+
|
|
219
|
+
##### name?
|
|
220
|
+
|
|
221
|
+
`string`
|
|
222
|
+
|
|
223
|
+
The name of the instance to generate.
|
|
224
|
+
|
|
225
|
+
#### Returns
|
|
226
|
+
|
|
227
|
+
`U` \| `undefined`
|
|
228
|
+
|
|
229
|
+
An instance of the item or undefined if it does not exist.
|
|
230
|
+
|
|
231
|
+
***
|
|
232
|
+
|
|
195
233
|
### create()
|
|
196
234
|
|
|
197
235
|
> **create**\<`U`\>(`name`, `args?`): `U`
|
|
@@ -234,11 +272,11 @@ GeneralError if no item exists to create.
|
|
|
234
272
|
|
|
235
273
|
***
|
|
236
274
|
|
|
237
|
-
###
|
|
275
|
+
### createIfExists()
|
|
238
276
|
|
|
239
|
-
> **
|
|
277
|
+
> **createIfExists**\<`U`\>(`name`, `args?`): `U` \| `undefined`
|
|
240
278
|
|
|
241
|
-
|
|
279
|
+
Create a new instance without caching it if it exists.
|
|
242
280
|
|
|
243
281
|
#### Type Parameters
|
|
244
282
|
|
|
@@ -248,17 +286,27 @@ Get a generator instance with no exceptions.
|
|
|
248
286
|
|
|
249
287
|
#### Parameters
|
|
250
288
|
|
|
251
|
-
##### name
|
|
289
|
+
##### name
|
|
252
290
|
|
|
253
291
|
`string`
|
|
254
292
|
|
|
255
293
|
The name of the instance to generate.
|
|
256
294
|
|
|
295
|
+
##### args?
|
|
296
|
+
|
|
297
|
+
`unknown`
|
|
298
|
+
|
|
299
|
+
The arguments to pass to the generator.
|
|
300
|
+
|
|
257
301
|
#### Returns
|
|
258
302
|
|
|
259
303
|
`U` \| `undefined`
|
|
260
304
|
|
|
261
|
-
|
|
305
|
+
A new instance of the item if it exists.
|
|
306
|
+
|
|
307
|
+
#### Throws
|
|
308
|
+
|
|
309
|
+
GuardError if the parameters are invalid.
|
|
262
310
|
|
|
263
311
|
***
|
|
264
312
|
|
package/locales/en.json
CHANGED
|
@@ -84,7 +84,8 @@
|
|
|
84
84
|
},
|
|
85
85
|
"factory": {
|
|
86
86
|
"noUnregister": "There is no {typeName} registered with the name \"{name}\"",
|
|
87
|
-
"noGet": "The requested {typeName} \"{name}\" does not exist in the factory"
|
|
87
|
+
"noGet": "The requested {typeName} \"{name}\" does not exist in the factory",
|
|
88
|
+
"noCreate": "The requested {typeName} \"{name}\" cannot be created by the factory, with params \"{params}\""
|
|
88
89
|
},
|
|
89
90
|
"bitString": {
|
|
90
91
|
"outOfRange": "The index should be >= 0 and less than the length of the bit string, the index is \"{index}\" and the number of bit is \"{numberBits}\""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/core",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.19",
|
|
4
4
|
"description": "Helper methods/classes for data type checking/validation/guarding/error handling",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=20.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/nameof": "0.0.3-next.
|
|
17
|
+
"@twin.org/nameof": "0.0.3-next.19",
|
|
18
18
|
"intl-messageformat": "10.7.18",
|
|
19
19
|
"rfc6902": "5.1.2"
|
|
20
20
|
},
|