@lppedd/di-wise-neo 0.21.0 → 0.22.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.
@@ -29,7 +29,7 @@ interface RegistrationOptions {
29
29
  /**
30
30
  * The scope of the registration.
31
31
  */
32
- readonly scope?: Scope;
32
+ readonly scope?: Scope | undefined;
33
33
  }
34
34
  /**
35
35
  * Create a one-off type token from a factory function.
@@ -82,7 +82,7 @@ interface ProviderType<T> extends Type<T> {
82
82
  /**
83
83
  * The type's default registration options.
84
84
  */
85
- readonly options?: RegistrationOptions;
85
+ readonly options?: RegistrationOptions | undefined;
86
86
  }
87
87
  /**
88
88
  * Constructor type.
@@ -168,7 +168,7 @@ interface ClassProvider<Instance extends object> {
168
168
  * }
169
169
  * ```
170
170
  */
171
- readonly name?: string;
171
+ readonly name?: string | undefined;
172
172
  }
173
173
  /**
174
174
  * Provides a value for a token via a factory function.
@@ -196,7 +196,7 @@ interface FactoryProvider<Value> {
196
196
  * }
197
197
  * ```
198
198
  */
199
- readonly name?: string;
199
+ readonly name?: string | undefined;
200
200
  }
201
201
  /**
202
202
  * Provides a static - already constructed - value for a token.
@@ -221,7 +221,7 @@ interface ValueProvider<Value> {
221
221
  * }
222
222
  * ```
223
223
  */
224
- readonly name?: string;
224
+ readonly name?: string | undefined;
225
225
  }
226
226
  /**
227
227
  * Aliases another registered token.
@@ -244,7 +244,7 @@ interface ExistingProvider<Value> {
244
244
  * });
245
245
  * ```
246
246
  */
247
- readonly useExisting: Token<Value> | [Token<Value>, string?];
247
+ readonly useExisting: Token<Value> | [Token<Value>, (string | undefined)?];
248
248
  /**
249
249
  * An optional name to qualify this provider.
250
250
  * If specified, the token must be resolved using the same name.
@@ -260,13 +260,19 @@ interface ExistingProvider<Value> {
260
260
  * }
261
261
  * ```
262
262
  */
263
- readonly name?: string;
263
+ readonly name?: string | undefined;
264
264
  }
265
265
  /**
266
266
  * A token provider.
267
267
  */
268
268
  type Provider<Value> = ClassProvider<Value & object> | FactoryProvider<Value> | ValueProvider<Value> | ExistingProvider<Value>;
269
269
 
270
+ type RequiredNonNullable<T> = {
271
+ [P in keyof T]-?: NonNullable<T[P]>;
272
+ };
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;
270
276
  /**
271
277
  * Container creation options.
272
278
  */
@@ -276,20 +282,20 @@ interface ContainerOptions {
276
282
  *
277
283
  * @defaultValue Transient
278
284
  */
279
- readonly defaultScope: Scope;
285
+ readonly defaultScope?: Scope | undefined;
280
286
  /**
281
287
  * Whether to automatically register an unregistered class when resolving it as a token.
282
288
  *
283
289
  * @defaultValue false
284
290
  */
285
- readonly autoRegister: boolean;
291
+ readonly autoRegister?: boolean | undefined;
286
292
  /**
287
293
  * Whether to also dispose values provided via {@link ValueProvider}, which are not
288
294
  * created or managed by the container, when the container itself is disposed.
289
295
  *
290
296
  * @defaultValue false
291
297
  */
292
- readonly disposeUnmanaged: boolean;
298
+ readonly disposeUnmanaged?: boolean | undefined;
293
299
  }
294
300
  /**
295
301
  * Child container creation options.
@@ -300,7 +306,7 @@ interface ChildContainerOptions extends ContainerOptions {
300
306
  *
301
307
  * @defaultValue true
302
308
  */
303
- readonly copyHooks: boolean;
309
+ readonly copyHooks?: boolean | undefined;
304
310
  }
305
311
  /**
306
312
  * A hook into the lifecycle of a {@link Container}.
@@ -316,14 +322,14 @@ interface ContainerHook {
316
322
  * @param value - The provided value.
317
323
  * @param scope - The {@link Scope} of the provided value.
318
324
  */
319
- readonly onProvide?: (value: unknown, scope: Scope) => void;
325
+ readonly onProvide?: ((value: unknown, scope: Scope) => void) | undefined;
320
326
  /**
321
327
  * Called after the container has been disposed.
322
328
  *
323
329
  * @param values - All distinct values that were cached by the disposed container.
324
330
  * Currently, only **Container**-scoped token values are cached.
325
331
  */
326
- readonly onDispose?: (values: unknown[]) => void;
332
+ readonly onDispose?: ((values: unknown[]) => void) | undefined;
327
333
  }
328
334
  /**
329
335
  * A Dependency Injection container.
@@ -332,7 +338,7 @@ interface Container {
332
338
  /**
333
339
  * The options used to create this container.
334
340
  */
335
- readonly options: ContainerOptions;
341
+ readonly options: RequiredNonNullable<ContainerOptions>;
336
342
  /**
337
343
  * The parent container, or `undefined` if this is the root container.
338
344
  */
@@ -346,7 +352,7 @@ interface Container {
346
352
  *
347
353
  * You can pass specific options to override the inherited ones.
348
354
  */
349
- createChild(options?: Partial<ChildContainerOptions>): Container;
355
+ createChild(options?: ChildContainerOptions): Container;
350
356
  /**
351
357
  * Clears and returns all distinct values cached by this container.
352
358
  * Values from {@link ValueProvider} registrations are not included, as they are never cached.
@@ -406,6 +412,23 @@ interface Container {
406
412
  * Registers a token type with a default {@link Provider} and optional default registration options.
407
413
  */
408
414
  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;
409
432
  /**
410
433
  * Registers a {@link ClassProvider} with a token.
411
434
  *
@@ -638,7 +661,7 @@ interface Container {
638
661
  /**
639
662
  * Creates a new container.
640
663
  */
641
- declare function createContainer(options?: Partial<ContainerOptions>): Container;
664
+ declare function createContainer(options?: ContainerOptions): Container;
642
665
 
643
666
  /**
644
667
  * Class decorator that enables auto-registration of an unregistered class
package/dist/cjs/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
2
 
3
- // @internal
4
3
  function check(condition, message) {
5
4
  if (!condition) {
6
5
  throw new Error(tag(typeof message === "string" ? message : message()));
@@ -104,7 +103,7 @@ class KeyedStack {
104
103
  return this.myEntries.at(-1)?.value;
105
104
  }
106
105
  push(key, value) {
107
- check(!this.has(key), "invariant violation");
106
+ check(!this.has(key), "internal: invariant violation");
108
107
  this.myKeys.add(key);
109
108
  this.myEntries.push({
110
109
  key,
@@ -135,7 +134,7 @@ class WeakRefMap {
135
134
  return undefined;
136
135
  }
137
136
  set(key, value) {
138
- check(!this.get(key), "invariant violation");
137
+ check(!this.get(key), "internal: invariant violation");
139
138
  this.myMap.set(key, new WeakRef(value));
140
139
  return ()=>{
141
140
  this.myMap.delete(key);
@@ -230,7 +229,7 @@ function tokenRef(token) {
230
229
  return {
231
230
  getRefToken: ()=>{
232
231
  const tokenOrTokens = token();
233
- check(!Array.isArray(tokenOrTokens), "internal error: single token expected");
232
+ check(!Array.isArray(tokenOrTokens), "internal: unexpected array of tokens");
234
233
  return tokenOrTokens;
235
234
  },
236
235
  getRefTokens: ()=>{
@@ -260,10 +259,7 @@ class Metadata {
260
259
  methods: new Map()
261
260
  };
262
261
  this.tokenRef = {
263
- // prettier-ignore
264
- getRefToken: ()=>{
265
- check(false, "internal error: unexpected call");
266
- },
262
+ getRefToken: ()=>check(false, "internal: unexpected getRefToken call"),
267
263
  getRefTokens: ()=>new Set()
268
264
  };
269
265
  this.provider = {
@@ -471,6 +467,7 @@ function isConstructor(token) {
471
467
 
472
468
  // @internal
473
469
  function getTypeName(value) {
470
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
474
471
  switch(typeof value){
475
472
  case "string":
476
473
  return `"${value}"`;
@@ -511,7 +508,7 @@ class TokenRegistry {
511
508
  ] || this.getAllFromParent(token, name);
512
509
  }
513
510
  put(token, registration) {
514
- check(!internals.has(token), `cannot register reserved token ${token.name}`);
511
+ check(!internals.has(token), `internal: cannot register reserved token ${token.name}`);
515
512
  let registrations = this.myRegistrations.get(token);
516
513
  if (registrations) {
517
514
  const name = registration.name;
@@ -575,7 +572,7 @@ class TokenRegistry {
575
572
  let registrations = this.myRegistrations.get(token) || this.myParent?.getAllFromParent(token, name);
576
573
  if (registrations && name !== undefined) {
577
574
  registrations = registrations.filter((r)=>r.name === name);
578
- check(registrations.length < 2, `internal error: more than one registration named '${name}'`);
575
+ check(registrations.length < 2, `internal: multiple registrations with name '${name}'`);
579
576
  }
580
577
  return registrations ?? [];
581
578
  }
@@ -644,7 +641,7 @@ function isDisposable(value) {
644
641
  defaultScope: options?.defaultScope ?? this.myOptions.defaultScope,
645
642
  autoRegister: options?.autoRegister ?? this.myOptions.autoRegister,
646
643
  disposeUnmanaged: options?.disposeUnmanaged ?? this.myOptions.disposeUnmanaged,
647
- copyHooks: options?.copyHooks
644
+ copyHooks: options?.copyHooks ?? true
648
645
  });
649
646
  this.myChildren.add(container);
650
647
  return container;
@@ -732,9 +729,11 @@ function isDisposable(value) {
732
729
  return this.resolveAllToken(token, true);
733
730
  }
734
731
  addHook(hook) {
732
+ this.checkDisposed();
735
733
  this.myHookRegistry.add(hook);
736
734
  }
737
735
  removeHook(hook) {
736
+ this.checkDisposed();
738
737
  this.myHookRegistry.delete(hook);
739
738
  }
740
739
  dispose() {
@@ -948,7 +947,7 @@ function isDisposable(value) {
948
947
  if (isValueProvider(provider)) {
949
948
  return provider.useValue;
950
949
  }
951
- check(false, "internal error: unexpected ExistingProvider");
950
+ check(false, "internal: unexpected ExistingProvider");
952
951
  }
953
952
  resolveScopedValue(token, registration, factory) {
954
953
  let context = useInjectionContext();
@@ -1024,7 +1023,7 @@ function isDisposable(value) {
1024
1023
  resolveCtorDependencies(registration) {
1025
1024
  const dependencies = registration.dependencies;
1026
1025
  if (dependencies) {
1027
- check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
1026
+ check(isClassProvider(registration.provider), `internal: expected a ClassProvider`);
1028
1027
  const ctorDeps = dependencies.ctor.filter((d)=>d.appliedBy);
1029
1028
  if (ctorDeps.length > 0) {
1030
1029
  // Let's check if all necessary constructor parameters are decorated.
@@ -1043,7 +1042,7 @@ function isDisposable(value) {
1043
1042
  injectMethodDependencies(registration, instance) {
1044
1043
  const dependencies = registration.dependencies;
1045
1044
  if (dependencies) {
1046
- check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
1045
+ check(isClassProvider(registration.provider), `internal: expected a ClassProvider`);
1047
1046
  const ctor = registration.provider.useClass;
1048
1047
  // Perform method injection
1049
1048
  for (const entry of dependencies.methods){
@@ -1090,6 +1089,8 @@ function isDisposable(value) {
1090
1089
  return instance ? optionalBy(instance, token, name) : this.tryResolve(token, name);
1091
1090
  case "OptionalAll":
1092
1091
  return instance ? optionalAll(token) : this.tryResolveAll(token);
1092
+ case undefined:
1093
+ check(false, "internal: unexpected undefined appliedBy");
1093
1094
  }
1094
1095
  }
1095
1096
  notifyProvideHooks(value, scope) {