@lppedd/di-wise-neo 0.18.0 → 0.18.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.
@@ -1,3 +1,6 @@
1
+ type ClassDecorator<Class extends object> = (target: Constructor<Class>) => Constructor<Class> | void;
2
+ type ParameterDecorator = (target: object, propertyKey: string | symbol | undefined, parameterIndex: number) => void;
3
+
1
4
  declare const Scope: {
2
5
  /**
3
6
  * Creates a new value every time the token is resolved.
@@ -126,11 +129,8 @@ declare function createType<T>(typeName: string, provider: Provider<T>, options?
126
129
  interface ClassRef<Instance extends object> {
127
130
  readonly getRefClass: () => Constructor<Instance>;
128
131
  }
129
- interface TokensRef<Value> {
130
- readonly getRefTokens: () => Set<Token<Value>>;
131
- }
132
132
  interface TokenRef<Value> {
133
- readonly getRefToken: () => Token<Value>;
133
+ readonly getRefTokens: () => Set<Token<Value>>;
134
134
  }
135
135
  /**
136
136
  * Allows referencing a class declared later in the file by wrapping it
@@ -140,15 +140,12 @@ interface TokenRef<Value> {
140
140
  */
141
141
  declare function classRef<Instance extends object>(Class: () => Constructor<Instance>): ClassRef<Instance>;
142
142
  /**
143
- * Allows referencing tokens declared later in the file by wrapping them
144
- * in a lazily evaluated function.
145
- */
146
- declare function tokenRef<Value>(token: () => Tokens<Value>): TokensRef<Value>;
147
- /**
148
- * Allows referencing a token declared later in the file by wrapping it
149
- * in a lazily evaluated function.
143
+ * Allows referencing one or multiple tokens declared later in the file by wrapping them
144
+ * into a lazily evaluated function.
145
+ *
146
+ * @__NO_SIDE_EFFECTS__
150
147
  */
151
- declare function tokenRef<Value>(token: () => Token<Value>): TokenRef<Value>;
148
+ declare function tokenRef<Value>(token: () => Token<Value> | Tokens<Value>): TokenRef<Value>;
152
149
 
153
150
  /**
154
151
  * Provides a class instance for a token via a class constructor.
@@ -320,14 +317,14 @@ interface ContainerHook {
320
317
  * - For **Transient**-scoped tokens, it is called each time the token is resolved,
321
318
  * which might mean multiple times per resolution graph.
322
319
  *
323
- * @param value The provided value.
324
- * @param scope The {@link Scope} of the provided value.
320
+ * @param value - The provided value.
321
+ * @param scope - The {@link Scope} of the provided value.
325
322
  */
326
323
  readonly onProvide?: (value: unknown, scope: Scope) => void;
327
324
  /**
328
325
  * Called after the container has been disposed.
329
326
  *
330
- * @param values All values that were cached by the container.
327
+ * @param values - All distinct values that were cached by the disposed container.
331
328
  * Currently, only **Container**-scoped token values are cached.
332
329
  */
333
330
  readonly onDispose?: (values: unknown[]) => void;
@@ -355,10 +352,10 @@ interface Container {
355
352
  */
356
353
  createChild(options?: Partial<ChildContainerOptions>): Container;
357
354
  /**
358
- * Clears and returns all distinct cached values from this container's internal registry.
355
+ * Clears and returns all distinct values that were cached by this container.
359
356
  * Values from {@link ValueProvider} registrations are not included, as they are never cached.
360
357
  *
361
- * Note that only this container is affected. Parent containers, if any, remain unchanged.
358
+ * Note that only this container is affected. Parent or child containers, if any, remain unchanged.
362
359
  */
363
360
  clearCache(): unknown[];
364
361
  /**
@@ -388,10 +385,11 @@ interface Container {
388
385
  /**
389
386
  * Removes all registrations from this container's internal registry.
390
387
  *
391
- * Returns an array of distinct cached values that were stored within the removed registrations.
392
- * Values from {@link ValueProvider} registrations are not included, as they are not cached.
388
+ * Returns an array of the distinct values that were cached by this container for the
389
+ * removed registrations. Values from {@link ValueProvider} registrations are not included,
390
+ * as they are not cached.
393
391
  *
394
- * Note that only this container is affected. Parent containers, if any, remain unchanged.
392
+ * Note that only this container is affected. Parent or child containers, if any, remain unchanged.
395
393
  */
396
394
  resetRegistry(): unknown[];
397
395
  /**
@@ -440,10 +438,11 @@ interface Container {
440
438
  /**
441
439
  * Removes all registrations for the given token from the container's internal registry.
442
440
  *
443
- * Returns an array of distinct cached values that were stored within the removed registrations.
444
- * Values from {@link ValueProvider} registrations are not included, as they are not cached.
441
+ * Returns an array of the distinct values that were cached by this container for the
442
+ * removed registrations. Values from {@link ValueProvider} registrations are not included,
443
+ * as they are not cached.
445
444
  *
446
- * Note that only this container is affected. Parent containers, if any, remain unchanged.
445
+ * Note that only this container is affected. Parent or child containers, if any, remain unchanged.
447
446
  */
448
447
  unregister<Value>(token: Token<Value>, name?: string): Value[];
449
448
  /**
@@ -658,7 +657,7 @@ declare function createContainer(options?: Partial<ContainerOptions>): Container
658
657
  *
659
658
  * @__NO_SIDE_EFFECTS__
660
659
  */
661
- declare function AutoRegister(): ClassDecorator;
660
+ declare function AutoRegister<This extends object>(): ClassDecorator<This>;
662
661
 
663
662
  /**
664
663
  * Class decorator that sets the class scope to **Container** and enables
@@ -679,7 +678,7 @@ declare function AutoRegister(): ClassDecorator;
679
678
  *
680
679
  * @__NO_SIDE_EFFECTS__
681
680
  */
682
- declare function EagerInstantiate(): ClassDecorator;
681
+ declare function EagerInstantiate<This extends object>(): ClassDecorator<This>;
683
682
 
684
683
  /**
685
684
  * Parameter decorator that injects the instance associated with the given class.
@@ -733,7 +732,14 @@ declare function Inject<Value>(tokens: TokenRef<Value>): ParameterDecorator;
733
732
  * class Wand {}
734
733
  * ```
735
734
  */
736
- declare function Injectable<This extends object, Value extends This>(...tokens: Tokens<Value>): ClassDecorator;
735
+ declare function Injectable<Value, This extends Value & object>(token: Token<Value>): ClassDecorator<This>;
736
+ declare function Injectable<VA, VB, This extends VA & VB & object>(tokenA: Token<VA>, //
737
+ tokenB: Token<VB>): ClassDecorator<This>;
738
+ declare function Injectable<VA, VB, VC, This extends VA & VB & VC & object>(tokenA: Token<VA>, tokenB: Token<VB>, tokenC: Token<VC>): ClassDecorator<This>;
739
+ declare function Injectable<VA, VB, VC, VD, This extends VA & VB & VC & VD & object>(tokenA: Token<VA>, tokenB: Token<VB>, tokenC: Token<VC>, tokenD: Token<VD>): ClassDecorator<This>;
740
+ declare function Injectable<VA, VB, VC, VD, VE, This extends VA & VB & VC & VD & VE & object>(tokenA: Token<VA>, tokenB: Token<VB>, tokenC: Token<VC>, tokenD: Token<VD>, tokenE: Token<VE>): ClassDecorator<This>;
741
+ declare function Injectable<VA, VB, VC, VD, VE, VF, This extends VA & VB & VC & VD & VE & VF & object>(tokenA: Token<VA>, tokenB: Token<VB>, tokenC: Token<VC>, tokenD: Token<VD>, tokenE: Token<VE>, tokenF: Token<VF>): ClassDecorator<This>;
742
+ declare function Injectable<This extends object>(...tokens: Tokens<unknown>): ClassDecorator<This>;
737
743
  /**
738
744
  * Class decorator that registers additional aliasing tokens for the decorated type
739
745
  * when the type is first registered in the container.
@@ -751,7 +757,7 @@ declare function Injectable<This extends object, Value extends This>(...tokens:
751
757
  * class Weapon {}
752
758
  * ```
753
759
  */
754
- declare function Injectable<This extends object, Value extends This>(tokens: TokenRef<Value> | TokensRef<Value>): ClassDecorator;
760
+ declare function Injectable<Value, This extends Value & object>(tokens: TokenRef<Value>): ClassDecorator<This>;
755
761
 
756
762
  /**
757
763
  * Parameter decorator that injects all instances provided by the registrations
@@ -811,7 +817,7 @@ declare function InjectAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
811
817
  *
812
818
  * @__NO_SIDE_EFFECTS__
813
819
  */
814
- declare function Named(name: string): ClassDecorator & ParameterDecorator;
820
+ declare function Named<This extends object>(name: string): ClassDecorator<This> & ParameterDecorator;
815
821
 
816
822
  /**
817
823
  * Parameter decorator that injects the instance associated with the given class,
@@ -909,7 +915,7 @@ declare function OptionalAll<Value>(tokens: TokenRef<Value>): ParameterDecorator
909
915
  *
910
916
  * @__NO_SIDE_EFFECTS__
911
917
  */
912
- declare function Scoped(scope: Scope): ClassDecorator;
918
+ declare function Scoped<This extends object>(scope: Scope): ClassDecorator<This>;
913
919
 
914
920
  /**
915
921
  * Injects the instance associated with the given class.
@@ -1000,7 +1006,7 @@ declare function injectBy<Value>(thisArg: any, token: Token<Value>, name?: strin
1000
1006
  * Asserts that the current stack frame is within an injection context,
1001
1007
  * meaning it has access to injection functions (`inject`, `optional`, etc.).
1002
1008
  *
1003
- * @param fn The function performing the assertion, or a string name used in the error message.
1009
+ * @param fn - The function performing the assertion, or a string name used in the error message.
1004
1010
  * @throws {Error} If the current stack frame is not within an injection context.
1005
1011
  */
1006
1012
  declare function assertInjectionContext(fn: Function | string): void;
@@ -1111,14 +1117,14 @@ declare const Injector: Type<Injector>;
1111
1117
  * This allows libraries or consumers that manipulate constructors, such as through
1112
1118
  * class decorators, to inform the DI system about the real "identity" of a class.
1113
1119
  *
1114
- * @param transformedClass - The constructor function returned by a class decorator or factory.
1115
- * @param originalClass - The original constructor function.
1116
- *
1117
- * @remarks
1118
- * This API affects the core class identity resolution mechanism of the DI system.
1120
+ * **IMPORTANT**:
1121
+ * this API affects the core class identity resolution mechanism of the DI system.
1119
1122
  * Incorrect usage may cause metadata to be misassociated, leading to subtle errors.
1120
1123
  * Use only when manipulating constructors (e.g., via decorators or proxies),
1121
1124
  * and ensure the mapping is correct.
1125
+ *
1126
+ * @param transformedClass - The constructor function returned by a class decorator or factory.
1127
+ * @param originalClass - The original constructor function.
1122
1128
  */
1123
1129
  declare function setClassIdentityMapping<T extends object>(transformedClass: Constructor<T>, originalClass: Constructor<T>): void;
1124
1130
 
@@ -1180,4 +1186,4 @@ declare function optionalBy<Instance extends object>(thisArg: any, Class: Constr
1180
1186
  declare function optionalBy<Value>(thisArg: any, token: Token<Value>, name?: string): Value | undefined;
1181
1187
 
1182
1188
  export { AutoRegister, EagerInstantiate, Inject, InjectAll, Injectable, Injector, Named, Optional, OptionalAll, Scope, Scoped, assertInjectionContext, build, classRef, createContainer, createType, inject, injectAll, injectBy, optional, optionalAll, optionalBy, setClassIdentityMapping, tokenRef };
1183
- export type { ChildContainerOptions, ClassProvider, ClassRef, Constructor, Container, ContainerHook, ContainerOptions, ExistingProvider, FactoryProvider, Provider, ProviderType, RegistrationOptions, Token, TokenRef, Tokens, TokensRef, Type, ValueProvider };
1189
+ export type { ChildContainerOptions, ClassProvider, ClassRef, Constructor, Container, ContainerHook, ContainerOptions, ExistingProvider, FactoryProvider, Provider, ProviderType, RegistrationOptions, Token, TokenRef, Tokens, Type, ValueProvider };
package/dist/cjs/index.js CHANGED
@@ -33,8 +33,9 @@ function throwResolutionError(tokenInfo, aliases, cause) {
33
33
  // @internal
34
34
  function throwParameterResolutionError(ctor, methodKey, dependency, cause) {
35
35
  const location = getLocation(ctor, methodKey);
36
+ const [token] = dependency.tokenRef.getRefTokens();
36
37
  const tokenName = getFullTokenName([
37
- dependency.tokenRef?.getRefToken(),
38
+ token,
38
39
  dependency.name
39
40
  ]);
40
41
  const msg = tag(`failed to resolve dependency for ${location}(parameter #${dependency.index}: ${tokenName})`);
@@ -167,7 +168,7 @@ function ensureInjectionContext(name) {
167
168
  * Asserts that the current stack frame is within an injection context,
168
169
  * meaning it has access to injection functions (`inject`, `optional`, etc.).
169
170
  *
170
- * @param fn The function performing the assertion, or a string name used in the error message.
171
+ * @param fn - The function performing the assertion, or a string name used in the error message.
171
172
  * @throws {Error} If the current stack frame is not within an injection context.
172
173
  */ function assertInjectionContext(fn) {
173
174
  const name = typeof fn === "function" ? `${fn.name || "<unnamed>"}()` : fn;
@@ -226,8 +227,12 @@ function injectBy(thisArg, token, name) {
226
227
  getRefClass: ()=>Class()
227
228
  };
228
229
  }
229
- // @__NO_SIDE_EFFECTS__
230
- function tokenRef(token) {
230
+ /**
231
+ * Allows referencing one or multiple tokens declared later in the file by wrapping them
232
+ * into a lazily evaluated function.
233
+ *
234
+ * @__NO_SIDE_EFFECTS__
235
+ */ function tokenRef(token) {
231
236
  return {
232
237
  getRefTokens: ()=>{
233
238
  // Normalize the single token here so that we don't have to do it at every getRefTokens call site
@@ -236,11 +241,6 @@ function tokenRef(token) {
236
241
  tokenOrTokens
237
242
  ];
238
243
  return new Set(tokensArray);
239
- },
240
- getRefToken: ()=>{
241
- const tokenOrTokens = token();
242
- check(!Array.isArray(tokenOrTokens), "internal error: ref tokens should be a single token");
243
- return tokenOrTokens;
244
244
  }
245
245
  };
246
246
  }
@@ -249,12 +249,8 @@ function isClassRef(value) {
249
249
  return value != null && typeof value === "object" && typeof value.getRefClass === "function";
250
250
  }
251
251
  // @internal
252
- function isTokensRef(value) {
253
- return value != null && typeof value === "object" && typeof value.getRefTokens === "function";
254
- }
255
- // @internal
256
252
  function isTokenRef(value) {
257
- return value != null && typeof value === "object" && typeof value.getRefToken === "function";
253
+ return value != null && typeof value === "object" && typeof value.getRefTokens === "function";
258
254
  }
259
255
 
260
256
  // @internal
@@ -264,7 +260,7 @@ class Metadata {
264
260
  ctor: [],
265
261
  methods: new Map()
266
262
  };
267
- this.tokensRef = {
263
+ this.tokenRef = {
268
264
  getRefTokens: ()=>new Set()
269
265
  };
270
266
  this.provider = {
@@ -335,14 +331,14 @@ function getMetadata(classOrRef) {
335
331
  * This allows libraries or consumers that manipulate constructors, such as through
336
332
  * class decorators, to inform the DI system about the real "identity" of a class.
337
333
  *
338
- * @param transformedClass - The constructor function returned by a class decorator or factory.
339
- * @param originalClass - The original constructor function.
340
- *
341
- * @remarks
342
- * This API affects the core class identity resolution mechanism of the DI system.
334
+ * **IMPORTANT**:
335
+ * this API affects the core class identity resolution mechanism of the DI system.
343
336
  * Incorrect usage may cause metadata to be misassociated, leading to subtle errors.
344
337
  * Use only when manipulating constructors (e.g., via decorators or proxies),
345
338
  * and ensure the mapping is correct.
339
+ *
340
+ * @param transformedClass - The constructor function returned by a class decorator or factory.
341
+ * @param originalClass - The original constructor function.
346
342
  */ function setClassIdentityMapping(transformedClass, originalClass) {
347
343
  classIdentityMap.set(transformedClass, originalClass);
348
344
  }
@@ -556,16 +552,12 @@ class TokenRegistry {
556
552
  clearCache() {
557
553
  const values = new Set();
558
554
  for (const registrations of this.myRegistrations.values()){
559
- for(let i = 0; i < registrations.length; i++){
560
- const registration = registrations[i];
555
+ for (const registration of registrations){
561
556
  const valueRef = registration.valueRef;
562
557
  if (valueRef) {
563
558
  values.add(valueRef.current);
564
559
  }
565
- registrations[i] = {
566
- ...registration,
567
- valueRef: undefined
568
- };
560
+ registration.valueRef = undefined;
569
561
  }
570
562
  }
571
563
  return Array.from(values);
@@ -777,7 +769,7 @@ function isDisposable(value) {
777
769
  this.myTokenRegistry.put(Class, registration);
778
770
  // Register the additional tokens specified via class decorators.
779
771
  // These tokens will point to the original Class token and will have the same scope.
780
- for (const token of metadata.tokensRef.getRefTokens()){
772
+ for (const token of metadata.tokenRef.getRefTokens()){
781
773
  this.myTokenRegistry.put(token, {
782
774
  name: name,
783
775
  provider: {
@@ -1063,7 +1055,7 @@ function isDisposable(value) {
1063
1055
  }
1064
1056
  // Call context: decorator-based injection
1065
1057
  resolveDependency(dependency, instance) {
1066
- const token = dependency.tokenRef?.getRefToken();
1058
+ const [token] = dependency.tokenRef.getRefTokens();
1067
1059
  check(token, `token passed to @${dependency.appliedBy} was undefined (possible circular imports)`);
1068
1060
  const name = dependency.name;
1069
1061
  switch(dependency.appliedBy){
@@ -1139,12 +1131,11 @@ function isDisposable(value) {
1139
1131
  * @__NO_SIDE_EFFECTS__
1140
1132
  */ function EagerInstantiate() {
1141
1133
  return function(Class) {
1142
- const ctor = Class;
1143
- const metadata = getMetadata(ctor);
1134
+ const metadata = getMetadata(Class);
1144
1135
  const currentScope = metadata.scope;
1145
1136
  check(!currentScope || currentScope.value === "Container", ()=>{
1146
1137
  const { value, appliedBy } = currentScope;
1147
- const className = getTokenName(ctor);
1138
+ const className = getTokenName(Class);
1148
1139
  return `class ${className}: 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.`;
1149
1140
  });
1150
1141
  metadata.eagerInstantiate = true;
@@ -1171,12 +1162,12 @@ function Injectable(...args) {
1171
1162
  return function(Class) {
1172
1163
  const metadata = getMetadata(Class);
1173
1164
  const arg0 = args[0];
1174
- const tokensRef = isTokensRef(arg0) ? arg0 : tokenRef(()=>args);
1175
- const existingTokensRef = metadata.tokensRef;
1176
- metadata.tokensRef = {
1165
+ const ref = isTokenRef(arg0) ? arg0 : tokenRef(()=>args);
1166
+ const existingTokensRef = metadata.tokenRef;
1167
+ metadata.tokenRef = {
1177
1168
  getRefTokens: ()=>{
1178
1169
  const existingTokens = existingTokensRef.getRefTokens();
1179
- for (const token of tokensRef.getRefTokens()){
1170
+ for (const token of ref.getRefTokens()){
1180
1171
  existingTokens.add(token);
1181
1172
  }
1182
1173
  return existingTokens;
@@ -1219,9 +1210,9 @@ function InjectAll(token) {
1219
1210
  return function(target, propertyKey, parameterIndex) {
1220
1211
  if (parameterIndex === undefined) {
1221
1212
  // The decorator has been applied to the class
1222
- const ctor = target;
1223
- const metadata = getMetadata(ctor);
1224
- const className = getTokenName(ctor);
1213
+ const Class = target;
1214
+ const metadata = getMetadata(Class);
1215
+ const className = getTokenName(Class);
1225
1216
  check(metadata.name === undefined, `multiple @Named decorators on class ${className}, but only one is allowed`);
1226
1217
  metadata.name = name;
1227
1218
  } else {
@@ -1284,13 +1275,12 @@ function OptionalAll(token) {
1284
1275
  * @__NO_SIDE_EFFECTS__
1285
1276
  */ function Scoped(scope) {
1286
1277
  return function(Class) {
1287
- const ctor = Class;
1288
- const metadata = getMetadata(ctor);
1278
+ const metadata = getMetadata(Class);
1289
1279
  const currentScope = metadata.scope;
1290
1280
  check(!currentScope || currentScope.value === scope, ()=>{
1291
1281
  const { value, appliedBy } = currentScope;
1292
1282
  const by = appliedBy === "Scoped" ? `another @${appliedBy} decorator` : `@${appliedBy}`;
1293
- const className = getTokenName(ctor);
1283
+ const className = getTokenName(Class);
1294
1284
  return `class ${className}: 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.`;
1295
1285
  });
1296
1286
  metadata.scope = {