@lppedd/di-wise-neo 0.3.2 → 0.5.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.
- package/README.md +42 -19
- package/dist/cjs/index.d.ts +115 -36
- package/dist/cjs/index.js +92 -32
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/index.d.mts +115 -36
- package/dist/es/index.mjs +92 -33
- package/dist/es/index.mjs.map +1 -1
- package/package.json +14 -18
package/dist/cjs/index.js
CHANGED
@@ -209,10 +209,6 @@ function isClassProvider(provider) {
|
|
209
209
|
return "useClass" in provider;
|
210
210
|
}
|
211
211
|
// @internal
|
212
|
-
function isExistingProvider(provider) {
|
213
|
-
return "useExisting" in provider;
|
214
|
-
}
|
215
|
-
// @internal
|
216
212
|
function isFactoryProvider(provider) {
|
217
213
|
return "useFactory" in provider;
|
218
214
|
}
|
@@ -220,6 +216,10 @@ function isFactoryProvider(provider) {
|
|
220
216
|
function isValueProvider(provider) {
|
221
217
|
return "useValue" in provider;
|
222
218
|
}
|
219
|
+
// @internal
|
220
|
+
function isExistingProvider(provider) {
|
221
|
+
return "useExisting" in provider;
|
222
|
+
}
|
223
223
|
|
224
224
|
const Scope = {
|
225
225
|
Inherited: "Inherited",
|
@@ -231,11 +231,11 @@ const Scope = {
|
|
231
231
|
/**
|
232
232
|
* Type API.
|
233
233
|
*/ /**
|
234
|
-
*
|
234
|
+
* Creates a type token.
|
235
235
|
*
|
236
236
|
* @example
|
237
237
|
* ```ts
|
238
|
-
* const
|
238
|
+
* const ISpell = createType<Spell>("Spell");
|
239
239
|
* ```
|
240
240
|
*
|
241
241
|
* @__NO_SIDE_EFFECTS__
|
@@ -281,8 +281,8 @@ function getTypeName(value) {
|
|
281
281
|
// @internal
|
282
282
|
class TokenRegistry {
|
283
283
|
constructor(parent){
|
284
|
-
this.parent = parent;
|
285
284
|
this.myMap = new Map();
|
285
|
+
this.myParent = parent;
|
286
286
|
}
|
287
287
|
get(token) {
|
288
288
|
// To clarify, at(-1) means we take the last added registration for this token
|
@@ -335,7 +335,7 @@ class TokenRegistry {
|
|
335
335
|
}
|
336
336
|
getAllFromParent(token) {
|
337
337
|
const registrations = this.myMap.get(token);
|
338
|
-
return registrations || this.
|
338
|
+
return registrations || this.myParent?.getAllFromParent(token);
|
339
339
|
}
|
340
340
|
}
|
341
341
|
// @internal
|
@@ -386,12 +386,11 @@ function isDisposable(value) {
|
|
386
386
|
|
387
387
|
/**
|
388
388
|
* The default implementation of a di-wise-neo {@link Container}.
|
389
|
-
*/ class
|
390
|
-
constructor(
|
391
|
-
this.myParent = myParent;
|
392
|
-
// eslint-disable-next-line no-use-before-define
|
389
|
+
*/ class ContainerImpl {
|
390
|
+
constructor(parent, options){
|
393
391
|
this.myChildren = new Set();
|
394
392
|
this.myDisposed = false;
|
393
|
+
this.myParent = parent;
|
395
394
|
this.myOptions = {
|
396
395
|
autoRegister: false,
|
397
396
|
defaultScope: Scope.Inherited,
|
@@ -415,7 +414,7 @@ function isDisposable(value) {
|
|
415
414
|
}
|
416
415
|
createChild(options) {
|
417
416
|
this.checkDisposed();
|
418
|
-
const container = new
|
417
|
+
const container = new ContainerImpl(this, {
|
419
418
|
...this.myOptions,
|
420
419
|
...options
|
421
420
|
});
|
@@ -462,20 +461,51 @@ function isDisposable(value) {
|
|
462
461
|
this.checkDisposed();
|
463
462
|
return this.myTokenRegistry.get(token) !== undefined;
|
464
463
|
}
|
464
|
+
registerClass(token, Class, options) {
|
465
|
+
// This mess will go away once/if we remove the register method
|
466
|
+
// in favor of the multiple specialized ones
|
467
|
+
if (Class) {
|
468
|
+
const ctor = Class ?? token;
|
469
|
+
this.register(token, {
|
470
|
+
useClass: ctor
|
471
|
+
}, options);
|
472
|
+
} else {
|
473
|
+
this.register(token);
|
474
|
+
}
|
475
|
+
}
|
476
|
+
registerFactory(token, factory, options) {
|
477
|
+
this.register(token, {
|
478
|
+
useFactory: factory
|
479
|
+
}, options);
|
480
|
+
}
|
481
|
+
registerValue(token, value) {
|
482
|
+
this.register(token, {
|
483
|
+
useValue: value
|
484
|
+
});
|
485
|
+
}
|
486
|
+
registerAlias(targetToken, aliasTokens) {
|
487
|
+
// De-duplicate tokens
|
488
|
+
for (const alias of new Set(aliasTokens)){
|
489
|
+
this.register(alias, {
|
490
|
+
useExisting: targetToken
|
491
|
+
});
|
492
|
+
}
|
493
|
+
}
|
465
494
|
register(...args) {
|
466
495
|
this.checkDisposed();
|
467
496
|
if (args.length == 1) {
|
468
497
|
const Class = args[0];
|
469
498
|
const metadata = getMetadata(Class);
|
470
|
-
|
471
|
-
this.myTokenRegistry.set(Class, {
|
499
|
+
const registration = {
|
472
500
|
// The provider is of type ClassProvider, initialized by getMetadata
|
473
501
|
provider: metadata.provider,
|
474
502
|
options: {
|
475
|
-
scope: metadata.scope
|
503
|
+
scope: metadata.scope ?? this.myOptions.defaultScope
|
476
504
|
},
|
477
505
|
dependencies: metadata.dependencies
|
478
|
-
}
|
506
|
+
};
|
507
|
+
// Register the class itself
|
508
|
+
this.myTokenRegistry.set(Class, registration);
|
479
509
|
// Register the additional tokens specified via class decorators.
|
480
510
|
// These tokens will point to the original Class token and will have the same scope.
|
481
511
|
for (const token of metadata.tokensRef.getRefTokens()){
|
@@ -485,21 +515,29 @@ function isDisposable(value) {
|
|
485
515
|
}
|
486
516
|
});
|
487
517
|
}
|
518
|
+
// Eager-instantiate only if the class is container-scoped
|
519
|
+
if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
|
520
|
+
this.resolve(Class);
|
521
|
+
}
|
488
522
|
} else {
|
489
523
|
const [token, provider, options] = args;
|
490
524
|
if (isClassProvider(provider)) {
|
491
|
-
const
|
492
|
-
const
|
493
|
-
this.myTokenRegistry.set(token, {
|
525
|
+
const metadata = getMetadata(provider.useClass);
|
526
|
+
const registration = {
|
494
527
|
provider: metadata.provider,
|
495
528
|
options: {
|
496
529
|
// The explicit registration options override what is specified
|
497
530
|
// via class decorators (e.g., @Scoped)
|
498
|
-
scope: metadata.scope,
|
531
|
+
scope: metadata.scope ?? this.myOptions.defaultScope,
|
499
532
|
...options
|
500
533
|
},
|
501
534
|
dependencies: metadata.dependencies
|
502
|
-
}
|
535
|
+
};
|
536
|
+
this.myTokenRegistry.set(token, registration);
|
537
|
+
// Eager-instantiate only if the provided class is container-scoped
|
538
|
+
if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
|
539
|
+
this.resolve(token);
|
540
|
+
}
|
503
541
|
} else {
|
504
542
|
if (isExistingProvider(provider)) {
|
505
543
|
assert(token !== provider.useExisting, `the useExisting token ${token.name} cannot be the same as the token being registered`);
|
@@ -787,16 +825,16 @@ function isDisposable(value) {
|
|
787
825
|
autoRegister: false,
|
788
826
|
defaultScope: Scope.Inherited
|
789
827
|
}) {
|
790
|
-
return new
|
828
|
+
return new ContainerImpl(undefined, options);
|
791
829
|
}
|
792
830
|
|
793
831
|
/**
|
794
|
-
* Class decorator
|
795
|
-
* when first
|
832
|
+
* Class decorator that enables auto-registration of an unregistered class,
|
833
|
+
* when the class is first resolved from the container.
|
796
834
|
*
|
797
835
|
* @example
|
798
836
|
* ```ts
|
799
|
-
* @AutoRegister
|
837
|
+
* @AutoRegister
|
800
838
|
* class Wizard {}
|
801
839
|
*
|
802
840
|
* const wizard = container.resolve(Wizard);
|
@@ -804,11 +842,32 @@ function isDisposable(value) {
|
|
804
842
|
* ```
|
805
843
|
*
|
806
844
|
* @__NO_SIDE_EFFECTS__
|
807
|
-
*/ function AutoRegister(
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
845
|
+
*/ function AutoRegister(Class) {
|
846
|
+
const metadata = getMetadata(Class);
|
847
|
+
metadata.autoRegister = true;
|
848
|
+
}
|
849
|
+
|
850
|
+
/**
|
851
|
+
* Class decorator that enables eager instantiation of a class when it is registered
|
852
|
+
* in the container with `Scope.Container`.
|
853
|
+
*
|
854
|
+
* This causes the container to immediately create and cache the instance of the class,
|
855
|
+
* instead of deferring instantiation until the first resolution.
|
856
|
+
*
|
857
|
+
* @example
|
858
|
+
* ```ts
|
859
|
+
* @EagerInstantiate
|
860
|
+
* @Scoped(Scope.Container)
|
861
|
+
* class Wizard {}
|
862
|
+
*
|
863
|
+
* // A Wizard instance is immediately created and cached by the container
|
864
|
+
* const wizard = container.register(Wizard);
|
865
|
+
* ```
|
866
|
+
*
|
867
|
+
* @__NO_SIDE_EFFECTS__
|
868
|
+
*/ function EagerInstantiate(Class) {
|
869
|
+
const metadata = getMetadata(Class);
|
870
|
+
metadata.eagerInstantiate = true;
|
812
871
|
}
|
813
872
|
|
814
873
|
function forwardRef(token) {
|
@@ -992,7 +1051,7 @@ function OptionalAll(token) {
|
|
992
1051
|
});
|
993
1052
|
|
994
1053
|
/**
|
995
|
-
*
|
1054
|
+
* Applies middleware functions to a container.
|
996
1055
|
*
|
997
1056
|
* Middlewares are applied in array order, but execute in reverse order.
|
998
1057
|
*
|
@@ -1036,6 +1095,7 @@ function OptionalAll(token) {
|
|
1036
1095
|
}
|
1037
1096
|
|
1038
1097
|
exports.AutoRegister = AutoRegister;
|
1098
|
+
exports.EagerInstantiate = EagerInstantiate;
|
1039
1099
|
exports.Inject = Inject;
|
1040
1100
|
exports.InjectAll = InjectAll;
|
1041
1101
|
exports.Injectable = Injectable;
|