@twin.org/core 0.9.3-next.9 → 0.10.0
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.
|
@@ -33,7 +33,8 @@ export class Factory {
|
|
|
33
33
|
*/
|
|
34
34
|
_facadeFactory;
|
|
35
35
|
/**
|
|
36
|
-
* The facades applied to the instances, in the order they were activated
|
|
36
|
+
* The facades applied to the instances, in the order they were activated, each with the
|
|
37
|
+
* instance types it is not applied to. The facade is
|
|
37
38
|
* resolved when it is activated rather than when an instance is produced, so unregistering or
|
|
38
39
|
* replacing it afterwards cannot affect a factory which has already activated it.
|
|
39
40
|
* @internal
|
|
@@ -240,7 +241,7 @@ export class Factory {
|
|
|
240
241
|
if (Is.stringValue(matchName) && this._generators[matchName]) {
|
|
241
242
|
const instance = this._generators[matchName].generator(args);
|
|
242
243
|
if (!Is.empty(instance)) {
|
|
243
|
-
return this.applyFacades(instance);
|
|
244
|
+
return this.applyFacades(matchName, instance);
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
247
|
}
|
|
@@ -269,11 +270,13 @@ export class Factory {
|
|
|
269
270
|
* An instance is passed through the facades in the order they were activated, so the facade
|
|
270
271
|
* activated first is the outermost. Activating a facade which is already active does nothing.
|
|
271
272
|
* @param name The name of the facade, as registered with the facade factory.
|
|
273
|
+
* @param excludeTypes Patterns matching the instance types the facade is not applied to, tested
|
|
274
|
+
* against the names they are registered with in this factory.
|
|
272
275
|
* @throws GuardError if the parameters are invalid.
|
|
273
276
|
* @throws GeneralError if no facade is registered with the name, or the factory is the facade
|
|
274
277
|
* factory itself.
|
|
275
278
|
*/
|
|
276
|
-
useFacade(name) {
|
|
279
|
+
useFacade(name, excludeTypes) {
|
|
277
280
|
Guards.stringValue(Factory.CLASS_NAME, "name", name);
|
|
278
281
|
const facadeFactory = this.facadeFactory();
|
|
279
282
|
// Wrapping the facades themselves would mean resolving a facade in order to apply it.
|
|
@@ -287,7 +290,11 @@ export class Factory {
|
|
|
287
290
|
});
|
|
288
291
|
}
|
|
289
292
|
if (!this._facades.some(f => f.name === name)) {
|
|
290
|
-
this._facades.push({
|
|
293
|
+
this._facades.push({
|
|
294
|
+
name,
|
|
295
|
+
facade: facadeFactory.get(name),
|
|
296
|
+
excludeTypes: excludeTypes ?? []
|
|
297
|
+
});
|
|
291
298
|
// Instances handed out before this point keep the facades they were built with, the
|
|
292
299
|
// change applies to instances produced from here on.
|
|
293
300
|
this._wrappedInstances = {};
|
|
@@ -385,25 +392,28 @@ export class Factory {
|
|
|
385
392
|
* @internal
|
|
386
393
|
*/
|
|
387
394
|
wrappedInstance(name) {
|
|
388
|
-
this._wrappedInstances[name] ??= this.applyFacades(this._instances[name]);
|
|
395
|
+
this._wrappedInstances[name] ??= this.applyFacades(name, this._instances[name]);
|
|
389
396
|
return this._wrappedInstances[name];
|
|
390
397
|
}
|
|
391
398
|
/**
|
|
392
399
|
* Wrap an instance in the active facades. The first activated facade ends up outermost.
|
|
400
|
+
* @param name The instance type being wrapped, used to honour the exclusions.
|
|
393
401
|
* @param instance The instance to wrap.
|
|
394
|
-
* @returns The wrapped instance, or the instance itself when no facades
|
|
402
|
+
* @returns The wrapped instance, or the instance itself when no facades apply to it.
|
|
395
403
|
* @throws GeneralError if a facade does not return a wrapped instance.
|
|
396
404
|
* @internal
|
|
397
405
|
*/
|
|
398
|
-
applyFacades(instance) {
|
|
406
|
+
applyFacades(name, instance) {
|
|
399
407
|
let wrapped = instance;
|
|
400
408
|
for (let i = this._facades.length - 1; i >= 0; i--) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
409
|
+
if (!this._facades[i].excludeTypes.some(excludeType => !Is.empty(name.match(excludeType)))) {
|
|
410
|
+
wrapped = this._facades[i].facade.wrap(wrapped);
|
|
411
|
+
if (Is.empty(wrapped)) {
|
|
412
|
+
throw new GeneralError(Factory.CLASS_NAME, "noFacadeWrap", {
|
|
413
|
+
typeName: this._typeName,
|
|
414
|
+
name: this._facades[i].name
|
|
415
|
+
});
|
|
416
|
+
}
|
|
407
417
|
}
|
|
408
418
|
}
|
|
409
419
|
return wrapped;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/factories/factory.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;GAEG;AACH,MAAM,OAAO,OAAO;IACnB;;OAEG;IACI,MAAM,CAAU,UAAU,aAAsC;IAEvE;;;OAGG;IACc,SAAS,CAAS;IAEnC;;;OAGG;IACK,WAAW,CAKjB;IAEF;;;OAGG;IACK,UAAU,CAAwB;IAE1C;;;;;OAKG;IACK,cAAc,CAAoB;IAE1C;;;;;OAKG;IACK,QAAQ,CAAsC;IAEtD;;;;;OAKG;IACK,iBAAiB,CAAwB;IAEjD;;;OAGG;IACK,aAAa,CAAS;IAE9B;;;OAGG;IACc,aAAa,CAAU;IAExC;;;OAGG;IACc,QAAQ,CAAwD;IAEjF;;;;;;OAMG;IACH,YACC,QAAgB,EAChB,eAAwB,KAAK,EAC7B,OAA+D;QAE/D,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,aAAa,CAC1B,QAAgB,EAChB,eAAwB,KAAK,EAC7B,OAA+D;QAE/D,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAEzC,IAAI,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YACvC,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAI,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,SAAS,CAAC,QAAQ,CAAe,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,YAAY;QACzB,OAAO,WAAW,CAAC,GAAG,CAEnB,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,UAAU,CAAc,QAAgB;QACrD,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAEzC,OAAO,SAAS,CAAC,QAAQ,CAA2B,CAAC;IACtD,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,cAAc;QAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAEzC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,SAAS,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;IACF,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,cAAc;QAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAEzC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,SAAS,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,QAAQ;QACd,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAc,IAAY,EAAE,SAAgC;QAC1E,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAC3D,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,eAAqB,SAAS,CAAC,CAAC;QAClE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG;YACxB,SAAS;YACT,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE;SAC3B,CAAC;QAEF,+BAA+B;QAC/B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC;QACrC,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACI,UAAU,CAAC,IAAY;QAC7B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,EAAE;gBAC1D,QAAQ,EAAE,IAAI,CAAC,SAAS;gBACxB,IAAI;aACJ,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9B,+BAA+B;QAC/B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED;;;;;;OAMG;IACI,GAAG,CAAc,IAAY;QACnC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,MAAM,IAAI,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE;gBACnD,QAAQ,EAAE,IAAI,CAAC,SAAS;gBACxB,IAAI;aACJ,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,QAAa,CAAC;IACtB,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAc,IAAa;QAC5C,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,OAAO;QACR,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;QAErE,IAAI,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,CAAC;YACtE,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAM,CAAC;YAC7C,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAc,IAAY,EAAE,IAAc;QACtD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,MAAM,IAAI,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE;gBACtD,QAAQ,EAAE,IAAI,CAAC,SAAS;gBACxB,IAAI;gBACJ,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aACpD,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,QAAa,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACI,cAAc,CAAc,IAAY,EAAE,IAAc;QAC9D,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;QAErE,IAAI,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAE7D,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAM,CAAC;YACzC,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACI,KAAK;QACX,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,KAAK;QACX,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;IACxB,CAAC;IAED;;;;;;;;OAQG;IACI,SAAS,CAAC,IAAY;QAC5B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAE3D,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAE3C,sFAAsF;QACtF,IAAI,IAAI,CAAC,SAAS,KAAK,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC;YACjD,MAAM,IAAI,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE;gBACtD,QAAQ,EAAE,IAAI,CAAC,SAAS;gBACxB,IAAI;aACJ,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9D,oFAAoF;YACpF,qDAAqD;YACrD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC7B,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,IAAY;QAC9B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAE3D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC5D,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC7B,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,YAAY,CAAC,UAAoB;QACvC,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,UAAU,CAAC;QACxB,CAAC;QAED,MAAM,SAAS,GAA0B,EAAE,CAAC;QAC5C,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,SAAS,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,UAAoB;QACxC,MAAM,gBAAgB,GAAqC,EAAE,CAAC;QAC9D,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,gBAAgB,CAAC,IAAI,CAAC;gBACrB,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBACzF,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,KAAK;aAC3C,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAChF,CAAC;IAED;;;OAGG;IACI,KAAK;QACX,MAAM,YAAY,GAAsC,EAAE,CAAC;QAC3D,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,YAAY,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK;aACxC,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAED;;;;OAIG;IACI,OAAO,CAAC,IAAY;QAC1B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAC3D,OAAO,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED;;;;OAIG;IACK,cAAc,CAAC,IAAY;QAClC,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACK,aAAa;QACpB,IAAI,CAAC,cAAc,KAAK,OAAO,CAAC,aAAa,CAAU,QAAQ,CAAC,CAAC;QAEjE,OAAO,IAAI,CAAC,cAAc,CAAC;IAC5B,CAAC;IAED;;;;;;OAMG;IACK,eAAe,CAAC,IAAY;QACnC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1E,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACK,YAAY,CAAC,QAAW;QAC/B,IAAI,OAAO,GAAG,QAAQ,CAAC;QAEvB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAM,CAAC;YAErD,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,EAAE;oBAC1D,QAAQ,EAAE,IAAI,CAAC,SAAS;oBACxB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;iBAC3B,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAED;;;;;;OAMG;IACK,cAAc,CAAC,KAAe,EAAE,IAAY;QACnD,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAClD,CAAC","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 type { IFacade } from \"../models/IFacade.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 * The factory the facades are resolved from, held once resolved. It cannot be resolved in the\n\t * constructor, because createFactory only stores a factory after constructing it, so the facade\n\t * factory would recurse while constructing itself.\n\t * @internal\n\t */\n\tprivate _facadeFactory?: Factory<IFacade>;\n\n\t/**\n\t * The facades applied to the instances, in the order they were activated. The facade is\n\t * resolved when it is activated rather than when an instance is produced, so unregistering or\n\t * replacing it afterwards cannot affect a factory which has already activated it.\n\t * @internal\n\t */\n\tprivate _facades: { name: string; facade: IFacade }[];\n\n\t/**\n\t * Store the instances with the facades applied, keyed as the instances are.\n\t * The unwrapped instances stay in _instances, so activating or deactivating a facade only has\n\t * to discard this cache rather than rebuild the components themselves.\n\t * @internal\n\t */\n\tprivate _wrappedInstances: { [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._facades = [];\n\t\tthis._wrappedInstances = {};\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\treturn SharedStore.get<{\n\t\t\t[typeName: string]: Factory<unknown>;\n\t\t}>(\"factories\", () => ({}));\n\t}\n\n\t/**\n\t * Get a specific factory by type name.\n\t * @param typeName The type name of the factory.\n\t * @returns The factory instance if it exists, otherwise undefined.\n\t */\n\tpublic static getFactory<T = unknown>(typeName: string): Factory<T> | undefined {\n\t\tconst factories = Factory.getFactories();\n\n\t\treturn factories[typeName] as Factory<T> | undefined;\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 * Get the type name of the factory.\n\t * @returns The type name of the factory.\n\t */\n\tpublic typeName(): string {\n\t\treturn this._typeName;\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\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.wrappedInstance(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\tconst instance = this._generators[matchName].generator(args);\n\n\t\t\tif (!Is.empty(instance)) {\n\t\t\t\treturn this.applyFacades(instance) 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\tthis._wrappedInstances = {};\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._wrappedInstances = {};\n\t\tthis._facades = [];\n\t\tthis._generators = {};\n\t\tthis._orderCounter = 0;\n\t}\n\n\t/**\n\t * Activate a facade for this factory, so every instance it produces is wrapped by it.\n\t * An instance is passed through the facades in the order they were activated, so the facade\n\t * activated first is the outermost. Activating a facade which is already active does nothing.\n\t * @param name The name of the facade, as registered with the facade factory.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no facade is registered with the name, or the factory is the facade\n\t * factory itself.\n\t */\n\tpublic useFacade(name: string): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\n\t\tconst facadeFactory = this.facadeFactory();\n\n\t\t// Wrapping the facades themselves would mean resolving a facade in order to apply it.\n\t\tif (this._typeName === facadeFactory.typeName()) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noFacadeOnFacades\");\n\t\t}\n\n\t\tif (!facadeFactory.hasName(name)) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noFacade\", {\n\t\t\t\ttypeName: this._typeName,\n\t\t\t\tname\n\t\t\t});\n\t\t}\n\n\t\tif (!this._facades.some(f => f.name === name)) {\n\t\t\tthis._facades.push({ name, facade: facadeFactory.get(name) });\n\t\t\t// Instances handed out before this point keep the facades they were built with, the\n\t\t\t// change applies to instances produced from here on.\n\t\t\tthis._wrappedInstances = {};\n\t\t}\n\t}\n\n\t/**\n\t * Deactivate a facade for this factory. Deactivating a facade which is not active does nothing.\n\t * @param name The name of the facade to deactivate.\n\t * @throws GuardError if the parameters are invalid.\n\t */\n\tpublic unuseFacade(name: string): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\n\t\tconst index = this._facades.findIndex(f => f.name === name);\n\t\tif (index >= 0) {\n\t\t\tthis._facades.splice(index, 1);\n\t\t\tthis._wrappedInstances = {};\n\t\t}\n\t}\n\n\t/**\n\t * Get all the instances as a map.\n\t * @param withFacade Return the instances with the active facades applied, defaults to false.\n\t * @returns The instances as a map.\n\t */\n\tpublic instancesMap(withFacade?: boolean): { [name: string]: T } {\n\t\tif (!withFacade) {\n\t\t\treturn this._instances;\n\t\t}\n\n\t\tconst instances: { [name: string]: T } = {};\n\t\tfor (const instanceName in this._instances) {\n\t\t\tinstances[instanceName] = this.wrappedInstance(instanceName);\n\t\t}\n\t\treturn instances;\n\t}\n\n\t/**\n\t * Get all the instances as a list in the order they were registered.\n\t * @param withFacade Return the instances with the active facades applied, defaults to false.\n\t * @returns The instances as a list in the order they were registered.\n\t */\n\tpublic instancesList(withFacade?: boolean): 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: withFacade ? this.wrappedInstance(instanceName) : 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\tdelete this._wrappedInstances[name];\n\t}\n\n\t/**\n\t * Get the factory the facades are resolved from, resolving it on first use.\n\t * @returns The facade factory.\n\t * @internal\n\t */\n\tprivate facadeFactory(): Factory<IFacade> {\n\t\tthis._facadeFactory ??= Factory.createFactory<IFacade>(\"facade\");\n\n\t\treturn this._facadeFactory;\n\t}\n\n\t/**\n\t * Get an instance with the active facades applied, wrapping it on first use.\n\t * @param name The name of the instance, which must already have been created.\n\t * @returns The wrapped instance.\n\t * @throws GeneralError if a facade does not return a wrapped instance.\n\t * @internal\n\t */\n\tprivate wrappedInstance(name: string): T {\n\t\tthis._wrappedInstances[name] ??= this.applyFacades(this._instances[name]);\n\n\t\treturn this._wrappedInstances[name];\n\t}\n\n\t/**\n\t * Wrap an instance in the active facades. The first activated facade ends up outermost.\n\t * @param instance The instance to wrap.\n\t * @returns The wrapped instance, or the instance itself when no facades are active.\n\t * @throws GeneralError if a facade does not return a wrapped instance.\n\t * @internal\n\t */\n\tprivate applyFacades(instance: T): T {\n\t\tlet wrapped = instance;\n\n\t\tfor (let i = this._facades.length - 1; i >= 0; i--) {\n\t\t\twrapped = this._facades[i].facade.wrap(wrapped) as T;\n\n\t\t\tif (Is.empty(wrapped)) {\n\t\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noFacadeWrap\", {\n\t\t\t\t\ttypeName: this._typeName,\n\t\t\t\t\tname: this._facades[i].name\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn wrapped;\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 type { IFacade } from \"../models/IFacade.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 * The factory the facades are resolved from, held once resolved. It cannot be resolved in the\n\t * constructor, because createFactory only stores a factory after constructing it, so the facade\n\t * factory would recurse while constructing itself.\n\t * @internal\n\t */\n\tprivate _facadeFactory?: Factory<IFacade>;\n\n\t/**\n\t * The facades applied to the instances, in the order they were activated, each with the\n\t * instance types it is not applied to. The facade is\n\t * resolved when it is activated rather than when an instance is produced, so unregistering or\n\t * replacing it afterwards cannot affect a factory which has already activated it.\n\t * @internal\n\t */\n\tprivate _facades: { name: string; facade: IFacade; excludeTypes: RegExp[] }[];\n\n\t/**\n\t * Store the instances with the facades applied, keyed as the instances are.\n\t * The unwrapped instances stay in _instances, so activating or deactivating a facade only has\n\t * to discard this cache rather than rebuild the components themselves.\n\t * @internal\n\t */\n\tprivate _wrappedInstances: { [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._facades = [];\n\t\tthis._wrappedInstances = {};\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\treturn SharedStore.get<{\n\t\t\t[typeName: string]: Factory<unknown>;\n\t\t}>(\"factories\", () => ({}));\n\t}\n\n\t/**\n\t * Get a specific factory by type name.\n\t * @param typeName The type name of the factory.\n\t * @returns The factory instance if it exists, otherwise undefined.\n\t */\n\tpublic static getFactory<T = unknown>(typeName: string): Factory<T> | undefined {\n\t\tconst factories = Factory.getFactories();\n\n\t\treturn factories[typeName] as Factory<T> | undefined;\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 * Get the type name of the factory.\n\t * @returns The type name of the factory.\n\t */\n\tpublic typeName(): string {\n\t\treturn this._typeName;\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\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.wrappedInstance(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\tconst instance = this._generators[matchName].generator(args);\n\n\t\t\tif (!Is.empty(instance)) {\n\t\t\t\treturn this.applyFacades(matchName, instance) 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\tthis._wrappedInstances = {};\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._wrappedInstances = {};\n\t\tthis._facades = [];\n\t\tthis._generators = {};\n\t\tthis._orderCounter = 0;\n\t}\n\n\t/**\n\t * Activate a facade for this factory, so every instance it produces is wrapped by it.\n\t * An instance is passed through the facades in the order they were activated, so the facade\n\t * activated first is the outermost. Activating a facade which is already active does nothing.\n\t * @param name The name of the facade, as registered with the facade factory.\n\t * @param excludeTypes Patterns matching the instance types the facade is not applied to, tested\n\t * against the names they are registered with in this factory.\n\t * @throws GuardError if the parameters are invalid.\n\t * @throws GeneralError if no facade is registered with the name, or the factory is the facade\n\t * factory itself.\n\t */\n\tpublic useFacade(name: string, excludeTypes?: RegExp[]): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\n\t\tconst facadeFactory = this.facadeFactory();\n\n\t\t// Wrapping the facades themselves would mean resolving a facade in order to apply it.\n\t\tif (this._typeName === facadeFactory.typeName()) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noFacadeOnFacades\");\n\t\t}\n\n\t\tif (!facadeFactory.hasName(name)) {\n\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noFacade\", {\n\t\t\t\ttypeName: this._typeName,\n\t\t\t\tname\n\t\t\t});\n\t\t}\n\n\t\tif (!this._facades.some(f => f.name === name)) {\n\t\t\tthis._facades.push({\n\t\t\t\tname,\n\t\t\t\tfacade: facadeFactory.get(name),\n\t\t\t\texcludeTypes: excludeTypes ?? []\n\t\t\t});\n\t\t\t// Instances handed out before this point keep the facades they were built with, the\n\t\t\t// change applies to instances produced from here on.\n\t\t\tthis._wrappedInstances = {};\n\t\t}\n\t}\n\n\t/**\n\t * Deactivate a facade for this factory. Deactivating a facade which is not active does nothing.\n\t * @param name The name of the facade to deactivate.\n\t * @throws GuardError if the parameters are invalid.\n\t */\n\tpublic unuseFacade(name: string): void {\n\t\tGuards.stringValue(Factory.CLASS_NAME, nameof(name), name);\n\n\t\tconst index = this._facades.findIndex(f => f.name === name);\n\t\tif (index >= 0) {\n\t\t\tthis._facades.splice(index, 1);\n\t\t\tthis._wrappedInstances = {};\n\t\t}\n\t}\n\n\t/**\n\t * Get all the instances as a map.\n\t * @param withFacade Return the instances with the active facades applied, defaults to false.\n\t * @returns The instances as a map.\n\t */\n\tpublic instancesMap(withFacade?: boolean): { [name: string]: T } {\n\t\tif (!withFacade) {\n\t\t\treturn this._instances;\n\t\t}\n\n\t\tconst instances: { [name: string]: T } = {};\n\t\tfor (const instanceName in this._instances) {\n\t\t\tinstances[instanceName] = this.wrappedInstance(instanceName);\n\t\t}\n\t\treturn instances;\n\t}\n\n\t/**\n\t * Get all the instances as a list in the order they were registered.\n\t * @param withFacade Return the instances with the active facades applied, defaults to false.\n\t * @returns The instances as a list in the order they were registered.\n\t */\n\tpublic instancesList(withFacade?: boolean): 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: withFacade ? this.wrappedInstance(instanceName) : 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\tdelete this._wrappedInstances[name];\n\t}\n\n\t/**\n\t * Get the factory the facades are resolved from, resolving it on first use.\n\t * @returns The facade factory.\n\t * @internal\n\t */\n\tprivate facadeFactory(): Factory<IFacade> {\n\t\tthis._facadeFactory ??= Factory.createFactory<IFacade>(\"facade\");\n\n\t\treturn this._facadeFactory;\n\t}\n\n\t/**\n\t * Get an instance with the active facades applied, wrapping it on first use.\n\t * @param name The name of the instance, which must already have been created.\n\t * @returns The wrapped instance.\n\t * @throws GeneralError if a facade does not return a wrapped instance.\n\t * @internal\n\t */\n\tprivate wrappedInstance(name: string): T {\n\t\tthis._wrappedInstances[name] ??= this.applyFacades(name, this._instances[name]);\n\n\t\treturn this._wrappedInstances[name];\n\t}\n\n\t/**\n\t * Wrap an instance in the active facades. The first activated facade ends up outermost.\n\t * @param name The instance type being wrapped, used to honour the exclusions.\n\t * @param instance The instance to wrap.\n\t * @returns The wrapped instance, or the instance itself when no facades apply to it.\n\t * @throws GeneralError if a facade does not return a wrapped instance.\n\t * @internal\n\t */\n\tprivate applyFacades(name: string, instance: T): T {\n\t\tlet wrapped = instance;\n\n\t\tfor (let i = this._facades.length - 1; i >= 0; i--) {\n\t\t\tif (!this._facades[i].excludeTypes.some(excludeType => !Is.empty(name.match(excludeType)))) {\n\t\t\t\twrapped = this._facades[i].facade.wrap(wrapped) as T;\n\n\t\t\t\tif (Is.empty(wrapped)) {\n\t\t\t\t\tthrow new GeneralError(Factory.CLASS_NAME, \"noFacadeWrap\", {\n\t\t\t\t\t\ttypeName: this._typeName,\n\t\t\t\t\t\tname: this._facades[i].name\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn wrapped;\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"]}
|
|
@@ -97,11 +97,13 @@ export declare class Factory<T> {
|
|
|
97
97
|
* An instance is passed through the facades in the order they were activated, so the facade
|
|
98
98
|
* activated first is the outermost. Activating a facade which is already active does nothing.
|
|
99
99
|
* @param name The name of the facade, as registered with the facade factory.
|
|
100
|
+
* @param excludeTypes Patterns matching the instance types the facade is not applied to, tested
|
|
101
|
+
* against the names they are registered with in this factory.
|
|
100
102
|
* @throws GuardError if the parameters are invalid.
|
|
101
103
|
* @throws GeneralError if no facade is registered with the name, or the factory is the facade
|
|
102
104
|
* factory itself.
|
|
103
105
|
*/
|
|
104
|
-
useFacade(name: string): void;
|
|
106
|
+
useFacade(name: string, excludeTypes?: RegExp[]): void;
|
|
105
107
|
/**
|
|
106
108
|
* Deactivate a facade for this factory. Deactivating a facade which is not active does nothing.
|
|
107
109
|
* @param name The name of the facade to deactivate.
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,79 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.0](https://github.com/iotaledger/twin-framework/compare/core-v0.10.0...core-v0.10.0) (2026-09-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* release to production ([b24cba1](https://github.com/iotaledger/twin-framework/commit/b24cba1b6a969278d638e632590602ec881e49fb))
|
|
9
|
+
* release to production ([787287d](https://github.com/iotaledger/twin-framework/commit/787287d06ea8319657401589d61fff369310c422))
|
|
10
|
+
* release to production ([53f4843](https://github.com/iotaledger/twin-framework/commit/53f484326b2851d7a506d2620db24c4a65cee7b3))
|
|
11
|
+
* release to production ([56cda4d](https://github.com/iotaledger/twin-framework/commit/56cda4da93e978c5be19ec7cfd421ae2a7fe4147))
|
|
12
|
+
* release to production ([f7c6586](https://github.com/iotaledger/twin-framework/commit/f7c6586f6976b903b647b4c5ac5ad9421e0c9051))
|
|
13
|
+
* release to production ([829d53d](https://github.com/iotaledger/twin-framework/commit/829d53d3953b1e1b40b0243c04cfdfd3842aac7b))
|
|
14
|
+
* release to production ([5cf3a76](https://github.com/iotaledger/twin-framework/commit/5cf3a76a09eff2e6414d0cba846c7c37400a11d6))
|
|
15
|
+
* release to production ([#330](https://github.com/iotaledger/twin-framework/issues/330)) ([d73f565](https://github.com/iotaledger/twin-framework/commit/d73f565588d156d23ef49b2a5718973756f7a696))
|
|
16
|
+
* release to production ([#382](https://github.com/iotaledger/twin-framework/issues/382)) ([bbed01a](https://github.com/iotaledger/twin-framework/commit/bbed01a605ee9724bda77a0f7feab249118c2d90))
|
|
17
|
+
* release to production ([#417](https://github.com/iotaledger/twin-framework/issues/417)) ([59727e7](https://github.com/iotaledger/twin-framework/commit/59727e73903a137310ca48fe469189cf29879cb9))
|
|
18
|
+
* release to production ([#459](https://github.com/iotaledger/twin-framework/issues/459)) ([e26e2d9](https://github.com/iotaledger/twin-framework/commit/e26e2d9a88767364c32494c45232033447b26e22))
|
|
19
|
+
* release to production ([#504](https://github.com/iotaledger/twin-framework/issues/504)) ([cfde07f](https://github.com/iotaledger/twin-framework/commit/cfde07f7790c62269e71144b95243ec441df38ba))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Miscellaneous Chores
|
|
23
|
+
|
|
24
|
+
* release to production ([63cae24](https://github.com/iotaledger/twin-framework/commit/63cae2401f6c11f93b2a01260b665064e8bd28e0))
|
|
25
|
+
|
|
26
|
+
## [0.9.3-next.12](https://github.com/iotaledger/twin-framework/compare/core-v0.9.3-next.11...core-v0.9.3-next.12) (2026-09-14)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Miscellaneous Chores
|
|
30
|
+
|
|
31
|
+
* **core:** Synchronize repo versions
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Dependencies
|
|
35
|
+
|
|
36
|
+
* The following workspace dependencies were updated
|
|
37
|
+
* dependencies
|
|
38
|
+
* @twin.org/nameof bumped from 0.9.3-next.11 to 0.9.3-next.12
|
|
39
|
+
* devDependencies
|
|
40
|
+
* @twin.org/nameof-transformer bumped from 0.9.3-next.11 to 0.9.3-next.12
|
|
41
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.11 to 0.9.3-next.12
|
|
42
|
+
|
|
43
|
+
## [0.9.3-next.11](https://github.com/iotaledger/twin-framework/compare/core-v0.9.3-next.10...core-v0.9.3-next.11) (2026-09-10)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
### Features
|
|
47
|
+
|
|
48
|
+
* factory facade exclude types as reg ex ([ae34b54](https://github.com/iotaledger/twin-framework/commit/ae34b544cd6fd2618784ecece5a7fec6fa833699))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
### Dependencies
|
|
52
|
+
|
|
53
|
+
* The following workspace dependencies were updated
|
|
54
|
+
* dependencies
|
|
55
|
+
* @twin.org/nameof bumped from 0.9.3-next.10 to 0.9.3-next.11
|
|
56
|
+
* devDependencies
|
|
57
|
+
* @twin.org/nameof-transformer bumped from 0.9.3-next.10 to 0.9.3-next.11
|
|
58
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.10 to 0.9.3-next.11
|
|
59
|
+
|
|
60
|
+
## [0.9.3-next.10](https://github.com/iotaledger/twin-framework/compare/core-v0.9.3-next.9...core-v0.9.3-next.10) (2026-09-10)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### Features
|
|
64
|
+
|
|
65
|
+
* exclude instance types from a facade ([#492](https://github.com/iotaledger/twin-framework/issues/492)) ([5962e7a](https://github.com/iotaledger/twin-framework/commit/5962e7a98603a5b6674953cce89c2221dc0281a9))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Dependencies
|
|
69
|
+
|
|
70
|
+
* The following workspace dependencies were updated
|
|
71
|
+
* dependencies
|
|
72
|
+
* @twin.org/nameof bumped from 0.9.3-next.9 to 0.9.3-next.10
|
|
73
|
+
* devDependencies
|
|
74
|
+
* @twin.org/nameof-transformer bumped from 0.9.3-next.9 to 0.9.3-next.10
|
|
75
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.9 to 0.9.3-next.10
|
|
76
|
+
|
|
3
77
|
## [0.9.3-next.9](https://github.com/iotaledger/twin-framework/compare/core-v0.9.3-next.8...core-v0.9.3-next.9) (2026-09-10)
|
|
4
78
|
|
|
5
79
|
|
|
@@ -368,7 +368,7 @@ Remove all the instances and the generators.
|
|
|
368
368
|
|
|
369
369
|
### useFacade() {#usefacade}
|
|
370
370
|
|
|
371
|
-
> **useFacade**(`name`): `void`
|
|
371
|
+
> **useFacade**(`name`, `excludeTypes?`): `void`
|
|
372
372
|
|
|
373
373
|
Activate a facade for this factory, so every instance it produces is wrapped by it.
|
|
374
374
|
An instance is passed through the facades in the order they were activated, so the facade
|
|
@@ -382,6 +382,13 @@ activated first is the outermost. Activating a facade which is already active do
|
|
|
382
382
|
|
|
383
383
|
The name of the facade, as registered with the facade factory.
|
|
384
384
|
|
|
385
|
+
##### excludeTypes?
|
|
386
|
+
|
|
387
|
+
`RegExp`[]
|
|
388
|
+
|
|
389
|
+
Patterns matching the instance types the facade is not applied to, tested
|
|
390
|
+
against the names they are registered with in this factory.
|
|
391
|
+
|
|
385
392
|
#### Returns
|
|
386
393
|
|
|
387
394
|
`void`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
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": ">=24.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/nameof": "0.
|
|
17
|
+
"@twin.org/nameof": "^0.10.0",
|
|
18
18
|
"intl-messageformat": "11.2.13",
|
|
19
19
|
"rfc6902": "5.3.0"
|
|
20
20
|
},
|