@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/es/index.mjs CHANGED
@@ -1,4 +1,3 @@
1
- // @internal
2
1
  function check(condition, message) {
3
2
  if (!condition) {
4
3
  throw new Error(tag(typeof message === "string" ? message : message()));
@@ -102,7 +101,7 @@ class KeyedStack {
102
101
  return this.myEntries.at(-1)?.value;
103
102
  }
104
103
  push(key, value) {
105
- check(!this.has(key), "invariant violation");
104
+ check(!this.has(key), "internal: invariant violation");
106
105
  this.myKeys.add(key);
107
106
  this.myEntries.push({
108
107
  key,
@@ -133,7 +132,7 @@ class WeakRefMap {
133
132
  return undefined;
134
133
  }
135
134
  set(key, value) {
136
- check(!this.get(key), "invariant violation");
135
+ check(!this.get(key), "internal: invariant violation");
137
136
  this.myMap.set(key, new WeakRef(value));
138
137
  return ()=>{
139
138
  this.myMap.delete(key);
@@ -228,7 +227,7 @@ function tokenRef(token) {
228
227
  return {
229
228
  getRefToken: ()=>{
230
229
  const tokenOrTokens = token();
231
- check(!Array.isArray(tokenOrTokens), "internal error: single token expected");
230
+ check(!Array.isArray(tokenOrTokens), "internal: unexpected array of tokens");
232
231
  return tokenOrTokens;
233
232
  },
234
233
  getRefTokens: ()=>{
@@ -258,10 +257,7 @@ class Metadata {
258
257
  methods: new Map()
259
258
  };
260
259
  this.tokenRef = {
261
- // prettier-ignore
262
- getRefToken: ()=>{
263
- check(false, "internal error: unexpected call");
264
- },
260
+ getRefToken: ()=>check(false, "internal: unexpected getRefToken call"),
265
261
  getRefTokens: ()=>new Set()
266
262
  };
267
263
  this.provider = {
@@ -469,6 +465,7 @@ function isConstructor(token) {
469
465
 
470
466
  // @internal
471
467
  function getTypeName(value) {
468
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
472
469
  switch(typeof value){
473
470
  case "string":
474
471
  return `"${value}"`;
@@ -509,7 +506,7 @@ class TokenRegistry {
509
506
  ] || this.getAllFromParent(token, name);
510
507
  }
511
508
  put(token, registration) {
512
- check(!internals.has(token), `cannot register reserved token ${token.name}`);
509
+ check(!internals.has(token), `internal: cannot register reserved token ${token.name}`);
513
510
  let registrations = this.myRegistrations.get(token);
514
511
  if (registrations) {
515
512
  const name = registration.name;
@@ -573,7 +570,7 @@ class TokenRegistry {
573
570
  let registrations = this.myRegistrations.get(token) || this.myParent?.getAllFromParent(token, name);
574
571
  if (registrations && name !== undefined) {
575
572
  registrations = registrations.filter((r)=>r.name === name);
576
- check(registrations.length < 2, `internal error: more than one registration named '${name}'`);
573
+ check(registrations.length < 2, `internal: multiple registrations with name '${name}'`);
577
574
  }
578
575
  return registrations ?? [];
579
576
  }
@@ -642,7 +639,7 @@ function isDisposable(value) {
642
639
  defaultScope: options?.defaultScope ?? this.myOptions.defaultScope,
643
640
  autoRegister: options?.autoRegister ?? this.myOptions.autoRegister,
644
641
  disposeUnmanaged: options?.disposeUnmanaged ?? this.myOptions.disposeUnmanaged,
645
- copyHooks: options?.copyHooks
642
+ copyHooks: options?.copyHooks ?? true
646
643
  });
647
644
  this.myChildren.add(container);
648
645
  return container;
@@ -730,9 +727,11 @@ function isDisposable(value) {
730
727
  return this.resolveAllToken(token, true);
731
728
  }
732
729
  addHook(hook) {
730
+ this.checkDisposed();
733
731
  this.myHookRegistry.add(hook);
734
732
  }
735
733
  removeHook(hook) {
734
+ this.checkDisposed();
736
735
  this.myHookRegistry.delete(hook);
737
736
  }
738
737
  dispose() {
@@ -946,7 +945,7 @@ function isDisposable(value) {
946
945
  if (isValueProvider(provider)) {
947
946
  return provider.useValue;
948
947
  }
949
- check(false, "internal error: unexpected ExistingProvider");
948
+ check(false, "internal: unexpected ExistingProvider");
950
949
  }
951
950
  resolveScopedValue(token, registration, factory) {
952
951
  let context = useInjectionContext();
@@ -1022,7 +1021,7 @@ function isDisposable(value) {
1022
1021
  resolveCtorDependencies(registration) {
1023
1022
  const dependencies = registration.dependencies;
1024
1023
  if (dependencies) {
1025
- check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
1024
+ check(isClassProvider(registration.provider), `internal: expected a ClassProvider`);
1026
1025
  const ctorDeps = dependencies.ctor.filter((d)=>d.appliedBy);
1027
1026
  if (ctorDeps.length > 0) {
1028
1027
  // Let's check if all necessary constructor parameters are decorated.
@@ -1041,7 +1040,7 @@ function isDisposable(value) {
1041
1040
  injectMethodDependencies(registration, instance) {
1042
1041
  const dependencies = registration.dependencies;
1043
1042
  if (dependencies) {
1044
- check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
1043
+ check(isClassProvider(registration.provider), `internal: expected a ClassProvider`);
1045
1044
  const ctor = registration.provider.useClass;
1046
1045
  // Perform method injection
1047
1046
  for (const entry of dependencies.methods){
@@ -1088,6 +1087,8 @@ function isDisposable(value) {
1088
1087
  return instance ? optionalBy(instance, token, name) : this.tryResolve(token, name);
1089
1088
  case "OptionalAll":
1090
1089
  return instance ? optionalAll(token) : this.tryResolveAll(token);
1090
+ case undefined:
1091
+ check(false, "internal: unexpected undefined appliedBy");
1091
1092
  }
1092
1093
  }
1093
1094
  notifyProvideHooks(value, scope) {