@lppedd/di-wise-neo 0.5.2 → 0.6.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 +16 -12
- package/dist/cjs/index.d.ts +8 -8
- package/dist/cjs/index.js +56 -18
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/index.d.mts +8 -8
- package/dist/es/index.mjs +56 -18
- package/dist/es/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/es/index.d.mts
CHANGED
@@ -422,7 +422,7 @@ declare function createContainer(options?: Partial<ContainerOptions>): Container
|
|
422
422
|
*
|
423
423
|
* @example
|
424
424
|
* ```ts
|
425
|
-
* @AutoRegister
|
425
|
+
* @AutoRegister()
|
426
426
|
* class Wizard {}
|
427
427
|
*
|
428
428
|
* const wizard = container.resolve(Wizard);
|
@@ -431,28 +431,28 @@ declare function createContainer(options?: Partial<ContainerOptions>): Container
|
|
431
431
|
*
|
432
432
|
* @__NO_SIDE_EFFECTS__
|
433
433
|
*/
|
434
|
-
declare function AutoRegister
|
434
|
+
declare function AutoRegister(): ClassDecorator;
|
435
435
|
|
436
436
|
/**
|
437
|
-
* Class decorator that
|
438
|
-
* in the container
|
437
|
+
* Class decorator that sets the class scope to **Container** and enables
|
438
|
+
* eager instantiation when the class is registered in the container.
|
439
439
|
*
|
440
440
|
* This causes the container to immediately create and cache the instance of the class,
|
441
441
|
* instead of deferring instantiation until the first resolution.
|
442
442
|
*
|
443
443
|
* @example
|
444
444
|
* ```ts
|
445
|
-
* @EagerInstantiate
|
446
|
-
* @Scoped(Scope.Container)
|
445
|
+
* @EagerInstantiate()
|
447
446
|
* class Wizard {}
|
448
447
|
*
|
449
|
-
* //
|
448
|
+
* // Wizard is registered with Container scope, and an instance
|
449
|
+
* // is immediately created and cached by the container
|
450
450
|
* const wizard = container.register(Wizard);
|
451
451
|
* ```
|
452
452
|
*
|
453
453
|
* @__NO_SIDE_EFFECTS__
|
454
454
|
*/
|
455
|
-
declare function EagerInstantiate
|
455
|
+
declare function EagerInstantiate(): ClassDecorator;
|
456
456
|
|
457
457
|
interface TokensRef<Value = any> {
|
458
458
|
readonly getRefTokens: () => Set<Token<Value>>;
|
package/dist/es/index.mjs
CHANGED
@@ -190,6 +190,22 @@ function getMetadata(Class) {
|
|
190
190
|
}
|
191
191
|
});
|
192
192
|
}
|
193
|
+
if (metadata.provider.useClass !== Class) {
|
194
|
+
// This is part of the class identity mapping API (see setClassIdentityMapping).
|
195
|
+
//
|
196
|
+
// Scenario:
|
197
|
+
// 1. Metadata is created for class A (the original class) because of a parameter decorator.
|
198
|
+
// 2. Later, because of a class decorator that extends the decorated class, a third-party
|
199
|
+
// registers a class identity mapping from class B to class A, where B is the class
|
200
|
+
// generated from the class decorator by extending A.
|
201
|
+
//
|
202
|
+
// We must update useClass to be the extender class B so that instances created by the
|
203
|
+
// DI container match the consumer's registered class. Without this update, the DI
|
204
|
+
// system would instantiate the original class A, causing behavior inconsistencies.
|
205
|
+
//
|
206
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
207
|
+
metadata.provider.useClass = Class;
|
208
|
+
}
|
193
209
|
return metadata;
|
194
210
|
}
|
195
211
|
const classIdentityMap = new WeakMap();
|
@@ -518,7 +534,7 @@ function isDisposable(value) {
|
|
518
534
|
// The provider is of type ClassProvider, initialized by getMetadata
|
519
535
|
provider: metadata.provider,
|
520
536
|
options: {
|
521
|
-
scope: metadata.scope ?? this.myOptions.defaultScope
|
537
|
+
scope: metadata.scope?.value ?? this.myOptions.defaultScope
|
522
538
|
},
|
523
539
|
dependencies: metadata.dependencies
|
524
540
|
};
|
@@ -535,7 +551,7 @@ function isDisposable(value) {
|
|
535
551
|
}
|
536
552
|
// Eager-instantiate only if the class is container-scoped
|
537
553
|
if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
|
538
|
-
this.
|
554
|
+
this.resolveProviderValue(registration, registration.provider);
|
539
555
|
}
|
540
556
|
} else {
|
541
557
|
const [token, provider, options] = args;
|
@@ -546,7 +562,7 @@ function isDisposable(value) {
|
|
546
562
|
options: {
|
547
563
|
// The explicit registration options override what is specified
|
548
564
|
// via class decorators (e.g., @Scoped)
|
549
|
-
scope: metadata.scope ?? this.myOptions.defaultScope,
|
565
|
+
scope: metadata.scope?.value ?? this.myOptions.defaultScope,
|
550
566
|
...options
|
551
567
|
},
|
552
568
|
dependencies: metadata.dependencies
|
@@ -554,7 +570,7 @@ function isDisposable(value) {
|
|
554
570
|
this.myTokenRegistry.set(token, registration);
|
555
571
|
// Eager-instantiate only if the provided class is container-scoped
|
556
572
|
if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
|
557
|
-
this.
|
573
|
+
this.resolveProviderValue(registration, registration.provider);
|
558
574
|
}
|
559
575
|
} else {
|
560
576
|
if (isExistingProvider(provider)) {
|
@@ -670,7 +686,7 @@ function isDisposable(value) {
|
|
670
686
|
metadata.eagerInstantiate = eagerInstantiate;
|
671
687
|
}
|
672
688
|
}
|
673
|
-
const scope = this.resolveScope(metadata.scope);
|
689
|
+
const scope = this.resolveScope(metadata.scope?.value);
|
674
690
|
if (optional && scope === Scope.Container) {
|
675
691
|
// It would not be possible to resolve the class in container scope,
|
676
692
|
// as that would require prior registration.
|
@@ -860,7 +876,7 @@ function isDisposable(value) {
|
|
860
876
|
*
|
861
877
|
* @example
|
862
878
|
* ```ts
|
863
|
-
* @AutoRegister
|
879
|
+
* @AutoRegister()
|
864
880
|
* class Wizard {}
|
865
881
|
*
|
866
882
|
* const wizard = container.resolve(Wizard);
|
@@ -868,32 +884,45 @@ function isDisposable(value) {
|
|
868
884
|
* ```
|
869
885
|
*
|
870
886
|
* @__NO_SIDE_EFFECTS__
|
871
|
-
*/ function AutoRegister(
|
872
|
-
|
873
|
-
|
887
|
+
*/ function AutoRegister() {
|
888
|
+
return function(Class) {
|
889
|
+
const metadata = getMetadata(Class);
|
890
|
+
metadata.autoRegister = true;
|
891
|
+
};
|
874
892
|
}
|
875
893
|
|
876
894
|
/**
|
877
|
-
* Class decorator that
|
878
|
-
* in the container
|
895
|
+
* Class decorator that sets the class scope to **Container** and enables
|
896
|
+
* eager instantiation when the class is registered in the container.
|
879
897
|
*
|
880
898
|
* This causes the container to immediately create and cache the instance of the class,
|
881
899
|
* instead of deferring instantiation until the first resolution.
|
882
900
|
*
|
883
901
|
* @example
|
884
902
|
* ```ts
|
885
|
-
* @EagerInstantiate
|
886
|
-
* @Scoped(Scope.Container)
|
903
|
+
* @EagerInstantiate()
|
887
904
|
* class Wizard {}
|
888
905
|
*
|
889
|
-
* //
|
906
|
+
* // Wizard is registered with Container scope, and an instance
|
907
|
+
* // is immediately created and cached by the container
|
890
908
|
* const wizard = container.register(Wizard);
|
891
909
|
* ```
|
892
910
|
*
|
893
911
|
* @__NO_SIDE_EFFECTS__
|
894
|
-
*/ function EagerInstantiate(
|
895
|
-
|
896
|
-
|
912
|
+
*/ function EagerInstantiate() {
|
913
|
+
return function(Class) {
|
914
|
+
const metadata = getMetadata(Class);
|
915
|
+
const currentScope = metadata.scope;
|
916
|
+
assert(!currentScope || currentScope.value === Scope.Container, ()=>{
|
917
|
+
const { value, appliedBy } = currentScope;
|
918
|
+
return `class ${Class.name}: Scope.${value} was already set by @${appliedBy},\n ` + `but @EagerInstantiate is trying to set a conflicting Scope.Container.\n ` + `Only one decorator should set the class scope, or all must agree on the same value.`;
|
919
|
+
});
|
920
|
+
metadata.eagerInstantiate = true;
|
921
|
+
metadata.scope = {
|
922
|
+
value: Scope.Container,
|
923
|
+
appliedBy: "EagerInstantiate"
|
924
|
+
};
|
925
|
+
};
|
897
926
|
}
|
898
927
|
|
899
928
|
function forwardRef(token) {
|
@@ -1025,7 +1054,16 @@ function OptionalAll(token) {
|
|
1025
1054
|
*/ function Scoped(scope) {
|
1026
1055
|
return function(Class) {
|
1027
1056
|
const metadata = getMetadata(Class);
|
1028
|
-
|
1057
|
+
const currentScope = metadata.scope;
|
1058
|
+
assert(!currentScope || currentScope.value === scope, ()=>{
|
1059
|
+
const { value, appliedBy } = currentScope;
|
1060
|
+
const by = appliedBy === "Scoped" ? `another @${appliedBy} decorator` : `@${appliedBy}`;
|
1061
|
+
return `class ${Class.name}: Scope.${value} was already set by ${by},\n ` + `but @Scoped is trying to set a conflicting Scope.${scope}.\n ` + `Only one decorator should set the class scope, or all must agree on the same value.`;
|
1062
|
+
});
|
1063
|
+
metadata.scope = {
|
1064
|
+
value: scope,
|
1065
|
+
appliedBy: "Scoped"
|
1066
|
+
};
|
1029
1067
|
};
|
1030
1068
|
}
|
1031
1069
|
|