@lppedd/di-wise-neo 0.8.0 → 0.9.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/dist/cjs/index.js +75 -71
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/index.mjs +75 -71
- package/dist/es/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/es/index.mjs
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
/**
|
2
|
+
* Type API.
|
3
|
+
*/ /**
|
4
|
+
* Creates a type token.
|
5
|
+
*
|
6
|
+
* @example
|
7
|
+
* ```ts
|
8
|
+
* const ISpell = createType<Spell>("Spell");
|
9
|
+
* ```
|
10
|
+
*
|
11
|
+
* @__NO_SIDE_EFFECTS__
|
12
|
+
*/ function createType(typeName) {
|
13
|
+
const type = {
|
14
|
+
name: `Type<${typeName}>`,
|
15
|
+
inter: createType,
|
16
|
+
union: createType,
|
17
|
+
toString () {
|
18
|
+
return type.name;
|
19
|
+
}
|
20
|
+
};
|
21
|
+
return type;
|
22
|
+
}
|
23
|
+
// @internal
|
24
|
+
function isConstructor(token) {
|
25
|
+
return typeof token === "function";
|
26
|
+
}
|
27
|
+
|
1
28
|
// @internal
|
2
29
|
function assert(condition, message) {
|
3
30
|
if (!condition) {
|
@@ -9,8 +36,10 @@ function expectNever(value) {
|
|
9
36
|
throw new TypeError(tag(`unexpected value ${String(value)}`));
|
10
37
|
}
|
11
38
|
// @internal
|
12
|
-
function throwUnregisteredError(token) {
|
13
|
-
|
39
|
+
function throwUnregisteredError(token, name) {
|
40
|
+
const type = isConstructor(token) ? "class" : "token";
|
41
|
+
const spec = name !== undefined ? `[name=${name}]` : "";
|
42
|
+
throw new Error(tag(`unregistered ${type} ${token.name}${spec}`));
|
14
43
|
}
|
15
44
|
// @internal
|
16
45
|
function throwExistingUnregisteredError(sourceToken, targetTokenOrError) {
|
@@ -74,6 +103,7 @@ class WeakRefMap {
|
|
74
103
|
}
|
75
104
|
this.myMap.delete(key);
|
76
105
|
}
|
106
|
+
return undefined;
|
77
107
|
}
|
78
108
|
set(key, value) {
|
79
109
|
invariant(!this.get(key));
|
@@ -288,33 +318,6 @@ const Scope = {
|
|
288
318
|
Container: "Container"
|
289
319
|
};
|
290
320
|
|
291
|
-
/**
|
292
|
-
* Type API.
|
293
|
-
*/ /**
|
294
|
-
* Creates a type token.
|
295
|
-
*
|
296
|
-
* @example
|
297
|
-
* ```ts
|
298
|
-
* const ISpell = createType<Spell>("Spell");
|
299
|
-
* ```
|
300
|
-
*
|
301
|
-
* @__NO_SIDE_EFFECTS__
|
302
|
-
*/ function createType(typeName) {
|
303
|
-
const type = {
|
304
|
-
name: `Type<${typeName}>`,
|
305
|
-
inter: createType,
|
306
|
-
union: createType,
|
307
|
-
toString () {
|
308
|
-
return type.name;
|
309
|
-
}
|
310
|
-
};
|
311
|
-
return type;
|
312
|
-
}
|
313
|
-
// @internal
|
314
|
-
function isConstructor(token) {
|
315
|
-
return typeof token === "function";
|
316
|
-
}
|
317
|
-
|
318
321
|
// @internal
|
319
322
|
function getTypeName(value) {
|
320
323
|
switch(typeof value){
|
@@ -612,29 +615,30 @@ function isDisposable(value) {
|
|
612
615
|
localOptional = optionalOrName;
|
613
616
|
localName = name;
|
614
617
|
}
|
615
|
-
|
618
|
+
let registration = this.myTokenRegistry.get(token, localName);
|
619
|
+
if (!registration && isConstructor(token)) {
|
620
|
+
registration = this.autoRegisterClass(token, localName);
|
621
|
+
}
|
616
622
|
if (registration) {
|
617
623
|
return this.resolveRegistration(token, registration, localName);
|
618
624
|
}
|
619
|
-
|
620
|
-
return this.instantiateClass(token, localOptional);
|
621
|
-
}
|
622
|
-
return optionalOrName ? undefined : throwUnregisteredError(token);
|
625
|
+
return localOptional ? undefined : throwUnregisteredError(token, localName);
|
623
626
|
}
|
624
627
|
resolveAll(token, optional) {
|
625
628
|
this.checkDisposed();
|
626
|
-
|
629
|
+
let registrations = this.myTokenRegistry.getAll(token);
|
630
|
+
if (registrations.length === 0 && isConstructor(token)) {
|
631
|
+
const registration = this.autoRegisterClass(token);
|
632
|
+
if (registration) {
|
633
|
+
registrations = [
|
634
|
+
registration
|
635
|
+
];
|
636
|
+
}
|
637
|
+
}
|
627
638
|
if (registrations.length > 0) {
|
628
639
|
return registrations //
|
629
640
|
.map((registration)=>this.resolveRegistration(token, registration)).filter((value)=>value != null);
|
630
641
|
}
|
631
|
-
if (isConstructor(token)) {
|
632
|
-
const instance = this.instantiateClass(token, optional);
|
633
|
-
return instance === undefined // = could not resolve, but since it is optional
|
634
|
-
? [] : [
|
635
|
-
instance
|
636
|
-
];
|
637
|
-
}
|
638
642
|
return optional ? [] : throwUnregisteredError(token);
|
639
643
|
}
|
640
644
|
dispose() {
|
@@ -684,37 +688,22 @@ function isDisposable(value) {
|
|
684
688
|
throw e;
|
685
689
|
}
|
686
690
|
}
|
687
|
-
|
691
|
+
autoRegisterClass(Class, name) {
|
688
692
|
const metadata = getMetadata(Class);
|
689
|
-
|
690
|
-
|
691
|
-
//
|
693
|
+
const autoRegister = metadata.autoRegister ?? this.myOptions.autoRegister;
|
694
|
+
if (autoRegister && (name === undefined || metadata.name === name)) {
|
695
|
+
// Temporarily set eagerInstantiate to false to avoid potentially resolving
|
696
|
+
// the class inside register()
|
692
697
|
const eagerInstantiate = metadata.eagerInstantiate;
|
693
698
|
metadata.eagerInstantiate = false;
|
694
699
|
try {
|
695
700
|
this.register(Class);
|
696
|
-
return this.
|
701
|
+
return this.myTokenRegistry.get(Class, name ?? metadata.name);
|
697
702
|
} finally{
|
698
703
|
metadata.eagerInstantiate = eagerInstantiate;
|
699
704
|
}
|
700
705
|
}
|
701
|
-
|
702
|
-
if (optional && scope === Scope.Container) {
|
703
|
-
// It would not be possible to resolve the class in container scope,
|
704
|
-
// as that would require prior registration.
|
705
|
-
// However, since resolution is marked optional, we simply return undefined.
|
706
|
-
return undefined;
|
707
|
-
}
|
708
|
-
assert(scope !== Scope.Container, `unregistered class ${Class.name} cannot be resolved in container scope`);
|
709
|
-
const registration = {
|
710
|
-
provider: metadata.provider,
|
711
|
-
options: {
|
712
|
-
scope: scope
|
713
|
-
},
|
714
|
-
dependencies: metadata.dependencies
|
715
|
-
};
|
716
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
717
|
-
return this.resolveScopedValue(registration, (args)=>new Class(...args));
|
706
|
+
return undefined;
|
718
707
|
}
|
719
708
|
resolveProviderValue(registration, provider) {
|
720
709
|
assert(registration.provider === provider, "internal error: mismatching provider");
|
@@ -986,10 +975,22 @@ function updateParameterMetadata(decorator, target, propertyKey, parameterIndex,
|
|
986
975
|
updateFn(dependency);
|
987
976
|
}
|
988
977
|
}
|
978
|
+
// Checks that a constructor or method parameter has only one injection decorator.
|
979
|
+
// For example, if both `@Inject` and `@Optional` are used, it becomes difficult to
|
980
|
+
// understand which one "wins", unless the user is aware of the decorator evaluation order.
|
981
|
+
//
|
982
|
+
// @internal
|
983
|
+
function checkSingleDecorator(dependency, target, propertyKey, parameterIndex) {
|
984
|
+
assert(!dependency.appliedBy, ()=>{
|
985
|
+
const where = propertyKey === undefined ? `${target.name} constructor` : `${target.constructor.name}.${String(propertyKey)}`;
|
986
|
+
return `${where} parameter ${parameterIndex} declares multiple injection decorators, but only one is allowed`;
|
987
|
+
});
|
988
|
+
}
|
989
989
|
|
990
990
|
function Inject(token) {
|
991
991
|
return function(target, propertyKey, parameterIndex) {
|
992
992
|
updateParameterMetadata("Inject", target, propertyKey, parameterIndex, (dependency)=>{
|
993
|
+
checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
|
993
994
|
dependency.appliedBy = "Inject";
|
994
995
|
dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
|
995
996
|
});
|
@@ -1019,6 +1020,7 @@ function Inject(token) {
|
|
1019
1020
|
function InjectAll(token) {
|
1020
1021
|
return function(target, propertyKey, parameterIndex) {
|
1021
1022
|
updateParameterMetadata("InjectAll", target, propertyKey, parameterIndex, (dependency)=>{
|
1023
|
+
checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
|
1022
1024
|
dependency.appliedBy = "InjectAll";
|
1023
1025
|
dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
|
1024
1026
|
});
|
@@ -1066,6 +1068,7 @@ function InjectAll(token) {
|
|
1066
1068
|
function Optional(token) {
|
1067
1069
|
return function(target, propertyKey, parameterIndex) {
|
1068
1070
|
updateParameterMetadata("Optional", target, propertyKey, parameterIndex, (dependency)=>{
|
1071
|
+
checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
|
1069
1072
|
dependency.appliedBy = "Optional";
|
1070
1073
|
dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
|
1071
1074
|
});
|
@@ -1075,6 +1078,7 @@ function Optional(token) {
|
|
1075
1078
|
function OptionalAll(token) {
|
1076
1079
|
return function(target, propertyKey, parameterIndex) {
|
1077
1080
|
updateParameterMetadata("OptionalAll", target, propertyKey, parameterIndex, (dependency)=>{
|
1081
|
+
checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
|
1078
1082
|
dependency.appliedBy = "OptionalAll";
|
1079
1083
|
dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
|
1080
1084
|
});
|
@@ -1140,7 +1144,7 @@ function OptionalAll(token) {
|
|
1140
1144
|
const resolution = context.resolution;
|
1141
1145
|
const dependentFrame = resolution.stack.peek();
|
1142
1146
|
const dependentRef = dependentFrame && resolution.dependents.get(dependentFrame.provider);
|
1143
|
-
|
1147
|
+
const runInContext = (fn)=>{
|
1144
1148
|
if (useInjectionContext()) {
|
1145
1149
|
return fn();
|
1146
1150
|
}
|
@@ -1154,13 +1158,13 @@ function OptionalAll(token) {
|
|
1154
1158
|
} finally{
|
1155
1159
|
cleanups.forEach((cleanup)=>cleanup?.());
|
1156
1160
|
}
|
1157
|
-
}
|
1161
|
+
};
|
1158
1162
|
return {
|
1159
|
-
inject: (token, name)=>
|
1160
|
-
injectAll: (token)=>
|
1161
|
-
optional: (token, name)=>
|
1162
|
-
optionalAll: (token)=>
|
1163
|
-
runInContext
|
1163
|
+
inject: (token, name)=>runInContext(()=>inject(token, name)),
|
1164
|
+
injectAll: (token)=>runInContext(()=>injectAll(token)),
|
1165
|
+
optional: (token, name)=>runInContext(()=>optional(token, name)),
|
1166
|
+
optionalAll: (token)=>runInContext(()=>optionalAll(token)),
|
1167
|
+
runInContext
|
1164
1168
|
};
|
1165
1169
|
}, "Injector");
|
1166
1170
|
|