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