@lppedd/di-wise-neo 0.23.1 → 0.25.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 CHANGED
@@ -512,7 +512,7 @@ Enables automatic registration of the decorated class when it is resolved if it
512
512
  been registered beforehand.
513
513
 
514
514
  ```ts
515
- @AutoRegister()
515
+ @AutoRegister
516
516
  export class ExtensionContext {
517
517
  /* ... */
518
518
  }
@@ -529,7 +529,7 @@ This causes the container to immediately create and cache the instance of the cl
529
529
  at registration time, instead of deferring instantiation until the first resolution.
530
530
 
531
531
  ```ts
532
- @EagerInstantiate()
532
+ @EagerInstantiate
533
533
  export class ExtensionContext {
534
534
  /* ... */
535
535
  }
@@ -55,9 +55,13 @@ declare function build<Value>(factory: (...args: []) => Value): Type<Value>;
55
55
  */
56
56
  interface Type<T> extends ParameterDecorator {
57
57
  /**
58
- * The name of the type.
58
+ * The type's presentable name, in the `Type<debugName>` format.
59
59
  */
60
60
  readonly name: string;
61
+ /**
62
+ * The type's debug name, as passed to {@link createType}.
63
+ */
64
+ readonly debugName: string;
61
65
  /**
62
66
  * Ensures that different `Type<T>` types are not structurally compatible.
63
67
  *
@@ -66,10 +70,6 @@ interface Type<T> extends ParameterDecorator {
66
70
  * @private
67
71
  */
68
72
  readonly __type: T | undefined;
69
- /**
70
- * Returns the type's {@link Type.name|name}.
71
- */
72
- readonly toString: () => string;
73
73
  }
74
74
  /**
75
75
  * An injectable type `T` with a default {@link Provider} and optional default registration options.
@@ -110,7 +110,7 @@ type Tokens<Value> = [Token<Value>, ...Token<Value>[]];
110
110
  * });
111
111
  * ```
112
112
  */
113
- declare function createType<T>(typeName: string): Type<T>;
113
+ declare function createType<T>(debugName: string): Type<T>;
114
114
  /**
115
115
  * Creates a type token with a default {@link Provider} and optional default registration options.
116
116
  *
@@ -124,7 +124,7 @@ declare function createType<T>(typeName: string): Type<T>;
124
124
  * container.register(ISpell);
125
125
  * ```
126
126
  */
127
- declare function createType<T>(typeName: string, provider: Provider<T>, options?: RegistrationOptions): ProviderType<T>;
127
+ declare function createType<T>(debugName: string, provider: Provider<T>, options?: RegistrationOptions): ProviderType<T>;
128
128
 
129
129
  interface ClassRef<Instance extends object> {
130
130
  readonly getRefClass: () => Constructor<Instance>;
@@ -271,8 +271,6 @@ type RequiredNonNullable<T> = {
271
271
  [P in keyof T]-?: NonNullable<T[P]>;
272
272
  };
273
273
 
274
- type ProviderFor<V> = V extends object ? Provider<V> : Exclude<Provider<V>, ClassProvider<any>>;
275
- type RegistrationOptionsFor<P> = P extends ValueProvider<any> ? never : RegistrationOptions;
276
274
  /**
277
275
  * Container creation options.
278
276
  */
@@ -412,23 +410,6 @@ interface Container {
412
410
  * Registers a token type with a default {@link Provider} and optional default registration options.
413
411
  */
414
412
  register<Value>(token: ProviderType<Value>): Container;
415
- /**
416
- * Registers a {@link Provider} with a token or class.
417
- *
418
- * The provider must be one of:
419
- * - {@link ClassProvider} via `useClass`
420
- * - {@link FactoryProvider} via `useFactory`
421
- * - {@link ValueProvider} via `useValue`
422
- * - {@link ExistingProvider} via `useExisting`
423
- *
424
- * For {@link ClassProvider} registrations, the default scope is determined by the {@link Scoped}
425
- * decorator applied to the provided class - if present - or by the {@link ContainerOptions.defaultScope}
426
- * value, but it can be overridden by passing explicit registration options.
427
- *
428
- * For {@link ValueProvider} registrations, the provided value is returned as-is and never cached,
429
- * and registration options do not apply.
430
- */
431
- register<Value, ProviderValue extends Value, Provider extends ProviderFor<ProviderValue>>(token: Token<Value>, provider: ProviderFor<ProviderValue> & Provider, options?: RegistrationOptionsFor<Provider>): Container;
432
413
  /**
433
414
  * Registers a {@link ClassProvider} with a token.
434
415
  *
@@ -669,14 +650,14 @@ declare function createContainer(options?: ContainerOptions): Container;
669
650
  *
670
651
  * Example:
671
652
  * ```ts
672
- * @AutoRegister()
653
+ * @AutoRegister
673
654
  * class Wizard {}
674
655
  *
675
656
  * const wizard = container.resolve(Wizard);
676
657
  * container.isRegistered(Wizard); // => true
677
658
  * ```
678
659
  */
679
- declare function AutoRegister<This extends object>(): ClassDecorator<This>;
660
+ declare function AutoRegister<This extends object, Ctor extends Constructor<This>>(target: Ctor): void;
680
661
 
681
662
  /**
682
663
  * Class decorator that sets the class scope to **Container** and enables
@@ -689,7 +670,7 @@ declare function AutoRegister<This extends object>(): ClassDecorator<This>;
689
670
  *
690
671
  * Example:
691
672
  * ```ts
692
- * @EagerInstantiate()
673
+ * @EagerInstantiate
693
674
  * class Wizard {}
694
675
  *
695
676
  * // Wizard is registered with Container scope, and an instance
@@ -697,7 +678,7 @@ declare function AutoRegister<This extends object>(): ClassDecorator<This>;
697
678
  * container.register(Wizard);
698
679
  * ```
699
680
  */
700
- declare function EagerInstantiate<This extends object>(): ClassDecorator<This>;
681
+ declare function EagerInstantiate<This extends object, Ctor extends Constructor<This>>(target: Ctor): void;
701
682
 
702
683
  /**
703
684
  * Parameter decorator that injects the instance associated with the given class.
@@ -938,13 +919,13 @@ declare function OptionalAll<Value>(tokens: TokenRef<Value>): ParameterDecorator
938
919
  *
939
920
  * Example:
940
921
  * ```ts
941
- * @ContainerScoped()
922
+ * @ContainerScoped
942
923
  * class Wizard {
943
924
  * // ...
944
925
  * }
945
926
  * ```
946
927
  */
947
- declare function ContainerScoped<This extends object>(): ClassDecorator<This>;
928
+ declare function ContainerScoped<This extends object, Ctor extends Constructor<This>>(target: Ctor): void;
948
929
  /**
949
930
  * Class decorator that registers the decorated type with the **Resolution** scope.
950
931
  *
@@ -953,13 +934,13 @@ declare function ContainerScoped<This extends object>(): ClassDecorator<This>;
953
934
  *
954
935
  * Example:
955
936
  * ```ts
956
- * @ResolutionScoped()
937
+ * @ResolutionScoped
957
938
  * class Wand {
958
939
  * // ...
959
940
  * }
960
941
  * ```
961
942
  */
962
- declare function ResolutionScoped<This extends object>(): ClassDecorator<This>;
943
+ declare function ResolutionScoped<This extends object, Ctor extends Constructor<This>>(target: Ctor): void;
963
944
  /**
964
945
  * Class decorator that registers the decorated type with the **Transient** scope.
965
946
  *
@@ -967,13 +948,13 @@ declare function ResolutionScoped<This extends object>(): ClassDecorator<This>;
967
948
  *
968
949
  * Example:
969
950
  * ```ts
970
- * @TransientScoped()
951
+ * @TransientScoped
971
952
  * class Wand {
972
953
  * // ...
973
954
  * }
974
955
  * ```
975
956
  */
976
- declare function TransientScoped<This extends object>(): ClassDecorator<This>;
957
+ declare function TransientScoped<This extends object, Ctor extends Constructor<This>>(target: Ctor): void;
977
958
  /**
978
959
  * Class decorator for setting the scope of the decorated type when registering it.
979
960
  *
package/dist/cjs/index.js CHANGED
@@ -54,14 +54,12 @@ function getTokenPath(tokens) {
54
54
  function getTokenName(token) {
55
55
  return token.name || "<unnamed>";
56
56
  }
57
+ // @internal
57
58
  function getFullTokenName([token, name]) {
58
59
  const tokenName = token ? token.name || "<unnamed>" : "<undefined token>";
59
- return name !== undefined ? `${tokenName}["${name}"]` : tokenName;
60
+ return name !== undefined ? `${tokenName}['${name}']` : tokenName;
60
61
  }
61
62
  function getCause(error) {
62
- if (!error) {
63
- return "";
64
- }
65
63
  const msg = isError(error) ? error.message : String(error);
66
64
  return `\n [cause] ${untag(msg)}`;
67
65
  }
@@ -439,24 +437,25 @@ function describeParam(target, methodKey, parameterIndex) {
439
437
  }
440
438
 
441
439
  // @__NO_SIDE_EFFECTS__
442
- function createType(typeName, provider, options) {
443
- const name = `Type<${typeName}>`;
440
+ function createType(debugName, provider, options) {
444
441
  const type = (target, propertyKey, parameterIndex)=>{
445
- updateParameterMetadata(name, target, propertyKey, parameterIndex, (dependency)=>{
442
+ updateParameterMetadata(debugName, target, propertyKey, parameterIndex, (dependency)=>{
446
443
  checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
447
444
  dependency.appliedBy = "Inject";
448
445
  dependency.tokenRef = tokenRef(()=>type);
449
446
  });
450
447
  };
448
+ const name = `Type<${debugName}>`;
451
449
  Object.defineProperty(type, "name", {
452
450
  value: name
453
451
  });
452
+ type.debugName = debugName;
453
+ type.__type = undefined;
454
+ type.toString = ()=>name;
454
455
  if (provider) {
455
456
  type.provider = provider;
456
457
  type.options = options;
457
458
  }
458
- type.__type = undefined;
459
- type.toString = ()=>name;
460
459
  return type;
461
460
  }
462
461
  // @internal
@@ -513,7 +512,10 @@ class TokenRegistry {
513
512
  const name = registration.name;
514
513
  if (name !== undefined) {
515
514
  const existing = registrations.filter((r)=>r.name === name);
516
- check(existing.length === 0, `token ${getTokenName(token)} with name '${name}' is already registered`);
515
+ check(existing.length === 0, `token ${getFullTokenName([
516
+ token,
517
+ name
518
+ ])} is already registered`);
517
519
  }
518
520
  } else {
519
521
  this.myRegistrations.set(token, registrations = []);
@@ -581,8 +583,8 @@ function isBuilder(provider) {
581
583
  return builders.has(provider);
582
584
  }
583
585
  // @__NO_SIDE_EFFECTS__
584
- function build(factory, name) {
585
- const token = createType(name ?? `Build<${getTypeName(factory)}>`);
586
+ function build(factory, debugName) {
587
+ const token = createType(debugName ?? `Build<${getTypeName(factory)}>`);
586
588
  const provider = {
587
589
  useFactory: factory
588
590
  };
@@ -1119,18 +1121,16 @@ function isDisposable(value) {
1119
1121
  *
1120
1122
  * Example:
1121
1123
  * ```ts
1122
- * @AutoRegister()
1124
+ * @AutoRegister
1123
1125
  * class Wizard {}
1124
1126
  *
1125
1127
  * const wizard = container.resolve(Wizard);
1126
1128
  * container.isRegistered(Wizard); // => true
1127
1129
  * ```
1128
1130
  */ // @__NO_SIDE_EFFECTS__
1129
- function AutoRegister() {
1130
- return (Class)=>{
1131
- const metadata = getMetadata(Class);
1132
- metadata.autoRegister = true;
1133
- };
1131
+ function AutoRegister(target) {
1132
+ const metadata = getMetadata(target);
1133
+ metadata.autoRegister = true;
1134
1134
  }
1135
1135
 
1136
1136
  /**
@@ -1144,7 +1144,7 @@ function AutoRegister() {
1144
1144
  *
1145
1145
  * Example:
1146
1146
  * ```ts
1147
- * @EagerInstantiate()
1147
+ * @EagerInstantiate
1148
1148
  * class Wizard {}
1149
1149
  *
1150
1150
  * // Wizard is registered with Container scope, and an instance
@@ -1152,21 +1152,19 @@ function AutoRegister() {
1152
1152
  * container.register(Wizard);
1153
1153
  * ```
1154
1154
  */ // @__NO_SIDE_EFFECTS__
1155
- function EagerInstantiate() {
1156
- return (Class)=>{
1157
- const metadata = getMetadata(Class);
1158
- const currentScope = metadata.scope;
1159
- check(!currentScope || currentScope.value === "Container", ()=>{
1160
- const { value, appliedBy } = currentScope;
1161
- const by = appliedBy === "Scoped" ? `${appliedBy}(${value})` : appliedBy;
1162
- const className = getTokenName(Class);
1163
- return `class ${className}: scope ${value} was already set by @${by},\n ` + `but @EagerInstantiate is trying to set a conflicting scope Container.\n ` + `Only one decorator should set the class scope, or all must use the same value.`;
1164
- });
1165
- metadata.eagerInstantiate = true;
1166
- metadata.scope = {
1167
- value: "Container",
1168
- appliedBy: "EagerInstantiate"
1169
- };
1155
+ function EagerInstantiate(target) {
1156
+ const metadata = getMetadata(target);
1157
+ const currentScope = metadata.scope;
1158
+ check(!currentScope || currentScope.value === "Container", ()=>{
1159
+ const { value, appliedBy } = currentScope;
1160
+ const by = appliedBy === "Scoped" ? `${appliedBy}(${value})` : appliedBy;
1161
+ const className = getTokenName(target);
1162
+ return `class ${className}: scope ${value} was already set by @${by},\n ` + `but @EagerInstantiate is trying to set a conflicting scope Container.\n ` + `Only one decorator should set the class scope, or all must use the same value.`;
1163
+ });
1164
+ metadata.eagerInstantiate = true;
1165
+ metadata.scope = {
1166
+ value: "Container",
1167
+ appliedBy: "EagerInstantiate"
1170
1168
  };
1171
1169
  }
1172
1170
 
@@ -1183,8 +1181,8 @@ function Inject(token) {
1183
1181
 
1184
1182
  // @__NO_SIDE_EFFECTS__
1185
1183
  function Injectable(...args) {
1186
- return (Class)=>{
1187
- const metadata = getMetadata(Class);
1184
+ return (target)=>{
1185
+ const metadata = getMetadata(target);
1188
1186
  const arg0 = args[0];
1189
1187
  const ref = isTokenRef(arg0) ? arg0 : tokenRef(()=>args);
1190
1188
  const currentRef = metadata.tokenRef;
@@ -1285,14 +1283,14 @@ function OptionalAll(token) {
1285
1283
  *
1286
1284
  * Example:
1287
1285
  * ```ts
1288
- * @ContainerScoped()
1286
+ * @ContainerScoped
1289
1287
  * class Wizard {
1290
1288
  * // ...
1291
1289
  * }
1292
1290
  * ```
1293
1291
  */ // @__NO_SIDE_EFFECTS__
1294
- function ContainerScoped() {
1295
- return scoped("Container", "ContainerScoped");
1292
+ function ContainerScoped(target) {
1293
+ scoped(target, "Container", "ContainerScoped");
1296
1294
  }
1297
1295
  /**
1298
1296
  * Class decorator that registers the decorated type with the **Resolution** scope.
@@ -1302,14 +1300,14 @@ function ContainerScoped() {
1302
1300
  *
1303
1301
  * Example:
1304
1302
  * ```ts
1305
- * @ResolutionScoped()
1303
+ * @ResolutionScoped
1306
1304
  * class Wand {
1307
1305
  * // ...
1308
1306
  * }
1309
1307
  * ```
1310
1308
  */ // @__NO_SIDE_EFFECTS__
1311
- function ResolutionScoped() {
1312
- return scoped("Resolution", "ResolutionScoped");
1309
+ function ResolutionScoped(target) {
1310
+ scoped(target, "Resolution", "ResolutionScoped");
1313
1311
  }
1314
1312
  /**
1315
1313
  * Class decorator that registers the decorated type with the **Transient** scope.
@@ -1318,14 +1316,14 @@ function ResolutionScoped() {
1318
1316
  *
1319
1317
  * Example:
1320
1318
  * ```ts
1321
- * @TransientScoped()
1319
+ * @TransientScoped
1322
1320
  * class Wand {
1323
1321
  * // ...
1324
1322
  * }
1325
1323
  * ```
1326
1324
  */ // @__NO_SIDE_EFFECTS__
1327
- function TransientScoped() {
1328
- return scoped("Transient", "TransientScoped");
1325
+ function TransientScoped(target) {
1326
+ scoped(target, "Transient", "TransientScoped");
1329
1327
  }
1330
1328
  /**
1331
1329
  * Class decorator for setting the scope of the decorated type when registering it.
@@ -1348,22 +1346,20 @@ function TransientScoped() {
1348
1346
  * ```
1349
1347
  */ // @__NO_SIDE_EFFECTS__
1350
1348
  function Scoped(scope) {
1351
- return scoped(scope, "Scoped");
1352
- }
1353
- function scoped(scope, decorator) {
1354
- return (Class)=>{
1355
- const metadata = getMetadata(Class);
1356
- const currentScope = metadata.scope;
1357
- check(!currentScope || currentScope.value === scope, ()=>{
1358
- const { value, appliedBy } = currentScope;
1359
- const by = appliedBy === "Scoped" ? `${appliedBy}(${value})` : appliedBy;
1360
- const className = getTokenName(Class);
1361
- return `class ${className}: scope ${value} was already set by @${by},\n ` + `but @${decorator} is trying to set a conflicting scope ${scope}.\n ` + `Only one decorator should set the class scope, or all must use the same value.`;
1362
- });
1363
- metadata.scope = {
1364
- value: scope,
1365
- appliedBy: decorator
1366
- };
1349
+ return (target)=>scoped(target, scope, "Scoped");
1350
+ }
1351
+ function scoped(target, scope, decorator) {
1352
+ const metadata = getMetadata(target);
1353
+ const currentScope = metadata.scope;
1354
+ check(!currentScope || currentScope.value === scope, ()=>{
1355
+ const { value, appliedBy } = currentScope;
1356
+ const by = appliedBy === "Scoped" ? `${appliedBy}(${value})` : appliedBy;
1357
+ const className = getTokenName(target);
1358
+ return `class ${className}: scope ${value} was already set by @${by},\n ` + `but @${decorator} is trying to set a conflicting scope ${scope}.\n ` + `Only one decorator should set the class scope, or all must use the same value.`;
1359
+ });
1360
+ metadata.scope = {
1361
+ value: scope,
1362
+ appliedBy: decorator
1367
1363
  };
1368
1364
  }
1369
1365