@lppedd/di-wise-neo 0.11.2 → 0.12.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 +42 -39
- package/dist/cjs/index.d.ts +123 -29
- package/dist/cjs/index.js +60 -45
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/index.d.mts +123 -29
- package/dist/es/index.mjs +60 -45
- package/dist/es/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/es/index.d.mts
CHANGED
@@ -145,7 +145,19 @@ interface ValueProvider<Value> {
|
|
145
145
|
*/
|
146
146
|
interface ExistingProvider<Value> {
|
147
147
|
/**
|
148
|
-
* The existing token to alias.
|
148
|
+
* The existing token to alias, with an optional name qualifier.
|
149
|
+
*
|
150
|
+
* @example
|
151
|
+
* ```ts
|
152
|
+
* container.register(ISecretStorage, {
|
153
|
+
* useExisting: PersistentSecretStorage,
|
154
|
+
* });
|
155
|
+
*
|
156
|
+
* // Or in case we need to alias a name-qualified token
|
157
|
+
* container.register(ISecretStorage, {
|
158
|
+
* useExisting: [PersistentSecretStorage, "fileSystem"],
|
159
|
+
* });
|
160
|
+
* ```
|
149
161
|
*/
|
150
162
|
readonly useExisting: Token<Value> | [Token<Value>, string?];
|
151
163
|
/**
|
@@ -171,8 +183,22 @@ interface ExistingProvider<Value> {
|
|
171
183
|
type Provider<Value = any> = ClassProvider<Value & object> | FactoryProvider<Value> | ValueProvider<Value> | ExistingProvider<Value>;
|
172
184
|
|
173
185
|
declare const Scope: {
|
186
|
+
/**
|
187
|
+
* Creates a new value every time the token is resolved.
|
188
|
+
*/
|
174
189
|
readonly Transient: "Transient";
|
190
|
+
/**
|
191
|
+
* Creates and caches a single value per token resolution graph.
|
192
|
+
*
|
193
|
+
* The same value is reused during a single resolution request and is subsequently discarded.
|
194
|
+
*/
|
175
195
|
readonly Resolution: "Resolution";
|
196
|
+
/**
|
197
|
+
* Creates and caches a single value per container.
|
198
|
+
*
|
199
|
+
* If the value is not found in the current container, it is looked up in the parent container,
|
200
|
+
* and so on. It effectively behaves like a _singleton_ scope but allows container-specific overrides.
|
201
|
+
*/
|
176
202
|
readonly Container: "Container";
|
177
203
|
};
|
178
204
|
type Scope = (typeof Scope)[keyof typeof Scope];
|
@@ -345,9 +371,8 @@ interface Container {
|
|
345
371
|
* The scope for the automatic registration is determined by either
|
346
372
|
* the {@link Scoped} decorator on the class, or {@link ContainerOptions.defaultScope}.
|
347
373
|
*
|
348
|
-
* If
|
349
|
-
*
|
350
|
-
* Otherwise, if `optional` is true, `undefined` is returned.
|
374
|
+
* If the class is not registered in this container or any of its parent containers
|
375
|
+
* and could not be auto-registered, an error is thrown.
|
351
376
|
*
|
352
377
|
* The resolution behavior depends on the {@link Provider} used during registration:
|
353
378
|
* - For {@link ValueProvider}, the explicitly provided instance is returned.
|
@@ -359,17 +384,13 @@ interface Container {
|
|
359
384
|
* in the container's internal registry.
|
360
385
|
*/
|
361
386
|
resolve<Instance extends object>(Class: Constructor<Instance>, name?: string): Instance;
|
362
|
-
resolve<Instance extends object>(Class: Constructor<Instance>, optional?: false, name?: string): Instance;
|
363
|
-
resolve<Instance extends object>(Class: Constructor<Instance>, optional: true, name?: string): Instance | undefined;
|
364
|
-
resolve<Instance extends object>(Class: Constructor<Instance>, optional?: boolean, name?: string): Instance | undefined;
|
365
387
|
/**
|
366
388
|
* Resolves the given token to the value associated with it.
|
367
389
|
*
|
368
390
|
* If the token is registered in this container or any of its parent containers,
|
369
391
|
* its value is resolved using the most recent registration.
|
370
392
|
*
|
371
|
-
* If
|
372
|
-
* an error is thrown. Otherwise, if `optional` is true, `undefined` is returned.
|
393
|
+
* If the token is not registered in this container or any of its parent containers, an error is thrown.
|
373
394
|
*
|
374
395
|
* The resolution behavior depends on the {@link Provider} used during registration:
|
375
396
|
* - For {@link ValueProvider}, the explicitly provided value is returned.
|
@@ -381,9 +402,51 @@ interface Container {
|
|
381
402
|
* in the container's internal registry.
|
382
403
|
*/
|
383
404
|
resolve<Value>(token: Token<Value>, name?: string): Value;
|
384
|
-
|
385
|
-
|
386
|
-
|
405
|
+
/**
|
406
|
+
* Resolves the given class to the instance associated with it.
|
407
|
+
*
|
408
|
+
* If the class is registered in this container or any of its parent containers,
|
409
|
+
* an instance is created using the most recent registration.
|
410
|
+
*
|
411
|
+
* If the class is not registered, but it is decorated with {@link AutoRegister},
|
412
|
+
* or {@link ContainerOptions.autoRegister} is true, the class is registered automatically.
|
413
|
+
* Otherwise, the resolution fails.
|
414
|
+
*
|
415
|
+
* The scope for the automatic registration is determined by either
|
416
|
+
* the {@link Scoped} decorator on the class, or {@link ContainerOptions.defaultScope}.
|
417
|
+
*
|
418
|
+
* If the class is not registered in this container or any of its parent containers
|
419
|
+
* and could not be auto-registered, `undefined` is returned instead.
|
420
|
+
*
|
421
|
+
* The resolution behavior depends on the {@link Provider} used during registration:
|
422
|
+
* - For {@link ValueProvider}, the explicitly provided instance is returned.
|
423
|
+
* - For {@link FactoryProvider}, the factory function is invoked to create the instance.
|
424
|
+
* - For {@link ClassProvider}, a new instance of the class is created according to its scope.
|
425
|
+
* - For {@link ExistingProvider}, the instance is resolved by referring to another registered token.
|
426
|
+
*
|
427
|
+
* If the class is registered with _container_ scope, the resolved instance is cached
|
428
|
+
* in the container's internal registry.
|
429
|
+
*/
|
430
|
+
tryResolve<Instance extends object>(Class: Constructor<Instance>, name?: string): Instance | undefined;
|
431
|
+
/**
|
432
|
+
* Tries to resolve the given token to the value associated with it.
|
433
|
+
*
|
434
|
+
* If the token is registered in this container or any of its parent containers,
|
435
|
+
* its value is resolved using the most recent registration.
|
436
|
+
*
|
437
|
+
* If the token is not registered in this container or any of its parent containers,
|
438
|
+
* `undefined` is returned instead.
|
439
|
+
*
|
440
|
+
* The resolution behavior depends on the {@link Provider} used during registration:
|
441
|
+
* - For {@link ValueProvider}, the explicitly provided value is returned.
|
442
|
+
* - For {@link FactoryProvider}, the factory function is invoked to create the value.
|
443
|
+
* - For {@link ClassProvider}, a new instance of the class is created according to its scope.
|
444
|
+
* - For {@link ExistingProvider}, the value is resolved by referring to another registered token.
|
445
|
+
*
|
446
|
+
* If the token is registered with _container_ scope, the resolved value is cached
|
447
|
+
* in the container's internal registry.
|
448
|
+
*/
|
449
|
+
tryResolve<Value>(token: Token<Value>, name?: string): Value | undefined;
|
387
450
|
/**
|
388
451
|
* Resolves the given class to all instances provided by the registrations associated with it.
|
389
452
|
*
|
@@ -394,9 +457,8 @@ interface Container {
|
|
394
457
|
* The scope for the automatic registration is determined by either
|
395
458
|
* the {@link Scoped} decorator on the class, or {@link ContainerOptions.defaultScope}.
|
396
459
|
*
|
397
|
-
* If
|
398
|
-
*
|
399
|
-
* Otherwise, if `optional` is true, an empty array is returned.
|
460
|
+
* If the class is not registered in this container or any of its parent containers
|
461
|
+
* and could not be auto-registered, an error is thrown.
|
400
462
|
*
|
401
463
|
* The resolution behavior depends on the {@link Provider} used during registration:
|
402
464
|
* - For {@link ValueProvider}, the explicitly provided instance is returned.
|
@@ -408,17 +470,12 @@ interface Container {
|
|
408
470
|
* in the container's internal registry.
|
409
471
|
*
|
410
472
|
* A separate instance of the class is created for each provider.
|
411
|
-
*
|
412
|
-
* @see The documentation for `resolve(Class: Constructor)`
|
413
473
|
*/
|
414
|
-
resolveAll<Instance extends object>(Class: Constructor<Instance
|
415
|
-
resolveAll<Instance extends object>(Class: Constructor<Instance>, optional: true): Instance[];
|
416
|
-
resolveAll<Instance extends object>(Class: Constructor<Instance>, optional?: boolean): Instance[];
|
474
|
+
resolveAll<Instance extends object>(Class: Constructor<Instance>): Instance[];
|
417
475
|
/**
|
418
476
|
* Resolves the given token to all values provided by the registrations associated with it.
|
419
477
|
*
|
420
|
-
* If
|
421
|
-
* an error is thrown. Otherwise, if `optional` is true, an empty array is returned.
|
478
|
+
* If the token is not registered in this container or any of its parent containers, an error is thrown.
|
422
479
|
*
|
423
480
|
* The resolution behavior depends on the {@link Provider} used during registration:
|
424
481
|
* - For {@link ValueProvider}, the explicitly provided value is returned.
|
@@ -428,12 +485,49 @@ interface Container {
|
|
428
485
|
*
|
429
486
|
* If the token is registered with _container_ scope, the resolved values are cached
|
430
487
|
* in the container's internal registry.
|
488
|
+
*/
|
489
|
+
resolveAll<Value>(token: Token<Value>): Value[];
|
490
|
+
/**
|
491
|
+
* Resolves the given class to all instances provided by the registrations associated with it.
|
492
|
+
*
|
493
|
+
* If the class is not registered, but it is decorated with {@link AutoRegister},
|
494
|
+
* or {@link ContainerOptions.autoRegister} is true, the class is registered automatically.
|
495
|
+
* Otherwise, the resolution fails.
|
431
496
|
*
|
432
|
-
*
|
497
|
+
* The scope for the automatic registration is determined by either
|
498
|
+
* the {@link Scoped} decorator on the class, or {@link ContainerOptions.defaultScope}.
|
499
|
+
*
|
500
|
+
* If the class is not registered in this container or any of its parent containers
|
501
|
+
* and could not be auto-registered, an empty array is returned instead.
|
502
|
+
*
|
503
|
+
* The resolution behavior depends on the {@link Provider} used during registration:
|
504
|
+
* - For {@link ValueProvider}, the explicitly provided instance is returned.
|
505
|
+
* - For {@link FactoryProvider}, the factory function is invoked to create the instance.
|
506
|
+
* - For {@link ClassProvider}, a new instance of the class is created according to its scope.
|
507
|
+
* - For {@link ExistingProvider}, the instance is resolved by referring to another registered token.
|
508
|
+
*
|
509
|
+
* If the class is registered with _container_ scope, the resolved instances are cached
|
510
|
+
* in the container's internal registry.
|
511
|
+
*
|
512
|
+
* A separate instance of the class is created for each provider.
|
513
|
+
*/
|
514
|
+
tryResolveAll<Instance extends object>(Class: Constructor<Instance>): Instance[];
|
515
|
+
/**
|
516
|
+
* Resolves the given token to all values provided by the registrations associated with it.
|
517
|
+
*
|
518
|
+
* If the token is not registered in this container or any of its parent containers,
|
519
|
+
* an empty array is returned instead.
|
520
|
+
*
|
521
|
+
* The resolution behavior depends on the {@link Provider} used during registration:
|
522
|
+
* - For {@link ValueProvider}, the explicitly provided value is returned.
|
523
|
+
* - For {@link FactoryProvider}, the factory function is invoked to create the value.
|
524
|
+
* - For {@link ClassProvider}, a new instance of the class is created according to its scope.
|
525
|
+
* - For {@link ExistingProvider}, the value is resolved by referring to another registered token.
|
526
|
+
*
|
527
|
+
* If the token is registered with _container_ scope, the resolved values are cached
|
528
|
+
* in the container's internal registry.
|
433
529
|
*/
|
434
|
-
|
435
|
-
resolveAll<Value>(token: Token<Value>, optional: true): Value[];
|
436
|
-
resolveAll<Value>(token: Token<Value>, optional?: boolean): Value[];
|
530
|
+
tryResolveAll<Value>(token: Token<Value>): Value[];
|
437
531
|
/**
|
438
532
|
* Disposes this container and all its cached values.
|
439
533
|
*
|
@@ -833,7 +927,7 @@ interface Injector {
|
|
833
927
|
* are only usable synchronously: they cannot be called from asynchronous callbacks
|
834
928
|
* or after any `await` points.
|
835
929
|
*
|
836
|
-
* @param fn The function to be run in the context of this injector.
|
930
|
+
* @param fn - The function to be run in the context of this injector.
|
837
931
|
* @returns The return value of the function, if any.
|
838
932
|
*/
|
839
933
|
runInContext<ReturnType>(fn: () => ReturnType): ReturnType;
|
@@ -865,8 +959,8 @@ declare const Injector: Type<Injector>;
|
|
865
959
|
* This allows libraries or consumers that manipulate constructors, such as through
|
866
960
|
* class decorators, to inform the DI system about the real "identity" of a class.
|
867
961
|
*
|
868
|
-
* @param transformedClass The constructor function returned by a class decorator or factory.
|
869
|
-
* @param originalClass The original constructor function.
|
962
|
+
* @param transformedClass - The constructor function returned by a class decorator or factory.
|
963
|
+
* @param originalClass - The original constructor function.
|
870
964
|
*
|
871
965
|
* @remarks
|
872
966
|
* This API affects the core class identity resolution mechanism of the DI system.
|
package/dist/es/index.mjs
CHANGED
@@ -169,10 +169,9 @@ function injectBy(thisArg, token, name) {
|
|
169
169
|
if (!currentFrame) {
|
170
170
|
return inject(token, name);
|
171
171
|
}
|
172
|
-
const
|
172
|
+
const cleanup = resolution.dependents.set(currentFrame.provider, {
|
173
173
|
current: thisArg
|
174
|
-
};
|
175
|
-
const cleanup = resolution.dependents.set(currentFrame.provider, currentRef);
|
174
|
+
});
|
176
175
|
try {
|
177
176
|
return inject(token, name);
|
178
177
|
} finally{
|
@@ -262,8 +261,8 @@ function getMetadata(Class) {
|
|
262
261
|
* This allows libraries or consumers that manipulate constructors, such as through
|
263
262
|
* class decorators, to inform the DI system about the real "identity" of a class.
|
264
263
|
*
|
265
|
-
* @param transformedClass The constructor function returned by a class decorator or factory.
|
266
|
-
* @param originalClass The original constructor function.
|
264
|
+
* @param transformedClass - The constructor function returned by a class decorator or factory.
|
265
|
+
* @param originalClass - The original constructor function.
|
267
266
|
*
|
268
267
|
* @remarks
|
269
268
|
* This API affects the core class identity resolution mechanism of the DI system.
|
@@ -278,7 +277,7 @@ const metadataMap = new WeakMap();
|
|
278
277
|
|
279
278
|
function optional(token, name) {
|
280
279
|
const context = ensureInjectionContext("optional()");
|
281
|
-
return context.container.
|
280
|
+
return context.container.tryResolve(token, name);
|
282
281
|
}
|
283
282
|
function optionalBy(thisArg, token, name) {
|
284
283
|
const context = ensureInjectionContext("optionalBy()");
|
@@ -287,10 +286,9 @@ function optionalBy(thisArg, token, name) {
|
|
287
286
|
if (!currentFrame) {
|
288
287
|
return optional(token, name);
|
289
288
|
}
|
290
|
-
const
|
289
|
+
const cleanup = resolution.dependents.set(currentFrame.provider, {
|
291
290
|
current: thisArg
|
292
|
-
};
|
293
|
-
const cleanup = resolution.dependents.set(currentFrame.provider, currentRef);
|
291
|
+
});
|
294
292
|
try {
|
295
293
|
return optional(token, name);
|
296
294
|
} finally{
|
@@ -300,7 +298,7 @@ function optionalBy(thisArg, token, name) {
|
|
300
298
|
|
301
299
|
function optionalAll(token) {
|
302
300
|
const context = ensureInjectionContext("optionalAll()");
|
303
|
-
return context.container.
|
301
|
+
return context.container.tryResolveAll(token);
|
304
302
|
}
|
305
303
|
|
306
304
|
// @internal
|
@@ -321,9 +319,20 @@ function isExistingProvider(provider) {
|
|
321
319
|
}
|
322
320
|
|
323
321
|
const Scope = {
|
324
|
-
|
325
|
-
|
326
|
-
|
322
|
+
/**
|
323
|
+
* Creates a new value every time the token is resolved.
|
324
|
+
*/ Transient: "Transient",
|
325
|
+
/**
|
326
|
+
* Creates and caches a single value per token resolution graph.
|
327
|
+
*
|
328
|
+
* The same value is reused during a single resolution request and is subsequently discarded.
|
329
|
+
*/ Resolution: "Resolution",
|
330
|
+
/**
|
331
|
+
* Creates and caches a single value per container.
|
332
|
+
*
|
333
|
+
* If the value is not found in the current container, it is looked up in the parent container,
|
334
|
+
* and so on. It effectively behaves like a _singleton_ scope but allows container-specific overrides.
|
335
|
+
*/ Container: "Container"
|
327
336
|
};
|
328
337
|
|
329
338
|
/**
|
@@ -646,39 +655,21 @@ function isDisposable(value) {
|
|
646
655
|
}
|
647
656
|
return Array.from(values);
|
648
657
|
}
|
649
|
-
resolve(token,
|
658
|
+
resolve(token, name) {
|
650
659
|
this.checkDisposed();
|
651
|
-
|
652
|
-
let localName;
|
653
|
-
if (typeof optionalOrName === "string") {
|
654
|
-
localName = optionalOrName;
|
655
|
-
} else {
|
656
|
-
localOptional = optionalOrName;
|
657
|
-
localName = name;
|
658
|
-
}
|
659
|
-
let registration = this.myTokenRegistry.get(token, localName);
|
660
|
-
if (!registration && isConstructor(token)) {
|
661
|
-
registration = this.autoRegisterClass(token, localName);
|
662
|
-
}
|
663
|
-
return this.resolveRegistration(token, registration, localOptional, localName)?.value;
|
660
|
+
return this.resolveToken(token, name, false);
|
664
661
|
}
|
665
|
-
|
662
|
+
tryResolve(token, name) {
|
666
663
|
this.checkDisposed();
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
if (registrations.length === 0 && !optional) {
|
677
|
-
throwUnregisteredError([
|
678
|
-
token
|
679
|
-
]);
|
680
|
-
}
|
681
|
-
return registrations.map((registration)=>this.resolveRegistration(token, registration, optional)).filter((result)=>result !== undefined).map((result)=>result.value);
|
664
|
+
return this.resolveToken(token, name, true);
|
665
|
+
}
|
666
|
+
resolveAll(token) {
|
667
|
+
this.checkDisposed();
|
668
|
+
return this.resolveAllToken(token, false);
|
669
|
+
}
|
670
|
+
tryResolveAll(token) {
|
671
|
+
this.checkDisposed();
|
672
|
+
return this.resolveAllToken(token, true);
|
682
673
|
}
|
683
674
|
dispose() {
|
684
675
|
if (this.myDisposed) {
|
@@ -705,6 +696,30 @@ function isDisposable(value) {
|
|
705
696
|
// Allow values to be GCed
|
706
697
|
disposedRefs.clear();
|
707
698
|
}
|
699
|
+
resolveToken(token, name, optional) {
|
700
|
+
let registration = this.myTokenRegistry.get(token, name);
|
701
|
+
if (!registration && isConstructor(token)) {
|
702
|
+
registration = this.autoRegisterClass(token, name);
|
703
|
+
}
|
704
|
+
return this.resolveRegistration(token, registration, optional, name)?.value;
|
705
|
+
}
|
706
|
+
resolveAllToken(token, optional) {
|
707
|
+
let registrations = this.myTokenRegistry.getAll(token);
|
708
|
+
if (registrations.length === 0 && isConstructor(token)) {
|
709
|
+
const registration = this.autoRegisterClass(token);
|
710
|
+
if (registration) {
|
711
|
+
registrations = [
|
712
|
+
registration
|
713
|
+
];
|
714
|
+
}
|
715
|
+
}
|
716
|
+
if (registrations.length === 0 && !optional) {
|
717
|
+
throwUnregisteredError([
|
718
|
+
token
|
719
|
+
]);
|
720
|
+
}
|
721
|
+
return registrations.map((registration)=>this.resolveRegistration(token, registration, optional)).filter((result)=>result !== undefined).map((result)=>result.value);
|
722
|
+
}
|
708
723
|
resolveRegistration(token, registration, optional, name) {
|
709
724
|
const aliases = [];
|
710
725
|
while(registration && isExistingProvider(registration.provider)){
|
@@ -916,9 +931,9 @@ function isDisposable(value) {
|
|
916
931
|
case "InjectAll":
|
917
932
|
return instance ? injectAll(token) : this.resolveAll(token);
|
918
933
|
case "Optional":
|
919
|
-
return instance ? optionalBy(instance, token, name) : this.
|
934
|
+
return instance ? optionalBy(instance, token, name) : this.tryResolve(token, name);
|
920
935
|
case "OptionalAll":
|
921
|
-
return instance ? optionalAll(token) : this.
|
936
|
+
return instance ? optionalAll(token) : this.tryResolveAll(token);
|
922
937
|
}
|
923
938
|
}
|
924
939
|
checkDisposed() {
|