@lppedd/di-wise-neo 0.8.0 → 0.8.1

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/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) {
@@ -10,7 +37,8 @@ function expectNever(value) {
10
37
  }
11
38
  // @internal
12
39
  function throwUnregisteredError(token) {
13
- throw new Error(tag(`unregistered token ${token.name}`));
40
+ const type = isConstructor(token) ? "class" : "token";
41
+ throw new Error(tag(`unregistered ${type} ${token.name}`));
14
42
  }
15
43
  // @internal
16
44
  function throwExistingUnregisteredError(sourceToken, targetTokenOrError) {
@@ -288,33 +316,6 @@ const Scope = {
288
316
  Container: "Container"
289
317
  };
290
318
 
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
319
  // @internal
319
320
  function getTypeName(value) {
320
321
  switch(typeof value){
@@ -619,7 +620,7 @@ function isDisposable(value) {
619
620
  if (isConstructor(token)) {
620
621
  return this.instantiateClass(token, localOptional);
621
622
  }
622
- return optionalOrName ? undefined : throwUnregisteredError(token);
623
+ return localOptional ? undefined : throwUnregisteredError(token);
623
624
  }
624
625
  resolveAll(token, optional) {
625
626
  this.checkDisposed();
@@ -986,10 +987,22 @@ function updateParameterMetadata(decorator, target, propertyKey, parameterIndex,
986
987
  updateFn(dependency);
987
988
  }
988
989
  }
990
+ // Checks that a constructor or method parameter has only one injection decorator.
991
+ // For example, if both `@Inject` and `@Optional` are used, it becomes difficult to
992
+ // understand which one "wins", unless the user is aware of the decorator evaluation order.
993
+ //
994
+ // @internal
995
+ function checkSingleDecorator(dependency, target, propertyKey, parameterIndex) {
996
+ assert(!dependency.appliedBy, ()=>{
997
+ const where = propertyKey === undefined ? `${target.name} constructor` : `${target.constructor.name}.${String(propertyKey)}`;
998
+ return `${where} parameter ${parameterIndex} declares multiple injection decorators, but only one is allowed`;
999
+ });
1000
+ }
989
1001
 
990
1002
  function Inject(token) {
991
1003
  return function(target, propertyKey, parameterIndex) {
992
1004
  updateParameterMetadata("Inject", target, propertyKey, parameterIndex, (dependency)=>{
1005
+ checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
993
1006
  dependency.appliedBy = "Inject";
994
1007
  dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
995
1008
  });
@@ -1019,6 +1032,7 @@ function Inject(token) {
1019
1032
  function InjectAll(token) {
1020
1033
  return function(target, propertyKey, parameterIndex) {
1021
1034
  updateParameterMetadata("InjectAll", target, propertyKey, parameterIndex, (dependency)=>{
1035
+ checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
1022
1036
  dependency.appliedBy = "InjectAll";
1023
1037
  dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
1024
1038
  });
@@ -1066,6 +1080,7 @@ function InjectAll(token) {
1066
1080
  function Optional(token) {
1067
1081
  return function(target, propertyKey, parameterIndex) {
1068
1082
  updateParameterMetadata("Optional", target, propertyKey, parameterIndex, (dependency)=>{
1083
+ checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
1069
1084
  dependency.appliedBy = "Optional";
1070
1085
  dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
1071
1086
  });
@@ -1075,6 +1090,7 @@ function Optional(token) {
1075
1090
  function OptionalAll(token) {
1076
1091
  return function(target, propertyKey, parameterIndex) {
1077
1092
  updateParameterMetadata("OptionalAll", target, propertyKey, parameterIndex, (dependency)=>{
1093
+ checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
1078
1094
  dependency.appliedBy = "OptionalAll";
1079
1095
  dependency.tokenRef = isTokenRef(token) ? token : forwardRef(()=>token);
1080
1096
  });
@@ -1140,7 +1156,7 @@ function OptionalAll(token) {
1140
1156
  const resolution = context.resolution;
1141
1157
  const dependentFrame = resolution.stack.peek();
1142
1158
  const dependentRef = dependentFrame && resolution.dependents.get(dependentFrame.provider);
1143
- function withContext(fn) {
1159
+ const runInContext = (fn)=>{
1144
1160
  if (useInjectionContext()) {
1145
1161
  return fn();
1146
1162
  }
@@ -1154,13 +1170,13 @@ function OptionalAll(token) {
1154
1170
  } finally{
1155
1171
  cleanups.forEach((cleanup)=>cleanup?.());
1156
1172
  }
1157
- }
1173
+ };
1158
1174
  return {
1159
- inject: (token, name)=>withContext(()=>inject(token, name)),
1160
- injectAll: (token)=>withContext(()=>injectAll(token)),
1161
- optional: (token, name)=>withContext(()=>optional(token, name)),
1162
- optionalAll: (token)=>withContext(()=>optionalAll(token)),
1163
- runInContext: withContext
1175
+ inject: (token, name)=>runInContext(()=>inject(token, name)),
1176
+ injectAll: (token)=>runInContext(()=>injectAll(token)),
1177
+ optional: (token, name)=>runInContext(()=>optional(token, name)),
1178
+ optionalAll: (token)=>runInContext(()=>optionalAll(token)),
1179
+ runInContext
1164
1180
  };
1165
1181
  }, "Injector");
1166
1182