@lppedd/di-wise-neo 0.17.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.
- package/README.md +4 -1
- package/dist/cjs/index.d.ts +53 -39
- package/dist/cjs/index.js +68 -72
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/index.d.mts +53 -39
- package/dist/es/index.mjs +68 -72
- package/dist/es/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<!--suppress HtmlDeprecatedAttribute -->
|
|
2
2
|
<h1 align="center">di-wise-neo</h1>
|
|
3
|
-
<p align="center">
|
|
3
|
+
<p align="center">
|
|
4
|
+
Lightweight, type-safe, flexible dependency injection library for TypeScript and JavaScript<br>
|
|
5
|
+
with a strong focus on type correctness and clear error reporting
|
|
6
|
+
</p>
|
|
4
7
|
<div align="center">
|
|
5
8
|
|
|
6
9
|
[](https://www.npmjs.com/package/@lppedd/di-wise-neo)
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
-
*
|
|
145
|
-
|
|
146
|
-
|
|
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.
|
|
@@ -290,6 +287,13 @@ interface ContainerOptions {
|
|
|
290
287
|
* @defaultValue false
|
|
291
288
|
*/
|
|
292
289
|
readonly autoRegister: boolean;
|
|
290
|
+
/**
|
|
291
|
+
* Whether to also dispose values provided via {@link ValueProvider}, which are not
|
|
292
|
+
* created or managed by the container, when the container itself is disposed.
|
|
293
|
+
*
|
|
294
|
+
* @defaultValue false
|
|
295
|
+
*/
|
|
296
|
+
readonly disposeUnmanaged: boolean;
|
|
293
297
|
}
|
|
294
298
|
/**
|
|
295
299
|
* Child container creation options.
|
|
@@ -308,19 +312,20 @@ interface ChildContainerOptions extends ContainerOptions {
|
|
|
308
312
|
interface ContainerHook {
|
|
309
313
|
/**
|
|
310
314
|
* Called when the container provides a value for a {@link Token}.
|
|
311
|
-
* - For **Container
|
|
312
|
-
* - For **Resolution
|
|
313
|
-
* - For **Transient
|
|
315
|
+
* - For **Container**-scoped tokens, it is called only once when the token is first resolved and cached.
|
|
316
|
+
* - For **Resolution**-scoped tokens, it is called once per token resolution graph.
|
|
317
|
+
* - For **Transient**-scoped tokens, it is called each time the token is resolved,
|
|
314
318
|
* which might mean multiple times per resolution graph.
|
|
315
319
|
*
|
|
316
|
-
* @param value The provided value.
|
|
317
|
-
* @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.
|
|
318
322
|
*/
|
|
319
323
|
readonly onProvide?: (value: unknown, scope: Scope) => void;
|
|
320
324
|
/**
|
|
321
325
|
* Called after the container has been disposed.
|
|
322
326
|
*
|
|
323
|
-
* @param values
|
|
327
|
+
* @param values - All distinct values that were cached by the disposed container.
|
|
328
|
+
* Currently, only **Container**-scoped token values are cached.
|
|
324
329
|
*/
|
|
325
330
|
readonly onDispose?: (values: unknown[]) => void;
|
|
326
331
|
}
|
|
@@ -347,10 +352,10 @@ interface Container {
|
|
|
347
352
|
*/
|
|
348
353
|
createChild(options?: Partial<ChildContainerOptions>): Container;
|
|
349
354
|
/**
|
|
350
|
-
* Clears and returns all distinct cached
|
|
355
|
+
* Clears and returns all distinct values that were cached by this container.
|
|
351
356
|
* Values from {@link ValueProvider} registrations are not included, as they are never cached.
|
|
352
357
|
*
|
|
353
|
-
* 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.
|
|
354
359
|
*/
|
|
355
360
|
clearCache(): unknown[];
|
|
356
361
|
/**
|
|
@@ -380,10 +385,11 @@ interface Container {
|
|
|
380
385
|
/**
|
|
381
386
|
* Removes all registrations from this container's internal registry.
|
|
382
387
|
*
|
|
383
|
-
* Returns an array of distinct
|
|
384
|
-
* Values from {@link ValueProvider} registrations are not included,
|
|
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.
|
|
385
391
|
*
|
|
386
|
-
* 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.
|
|
387
393
|
*/
|
|
388
394
|
resetRegistry(): unknown[];
|
|
389
395
|
/**
|
|
@@ -432,10 +438,11 @@ interface Container {
|
|
|
432
438
|
/**
|
|
433
439
|
* Removes all registrations for the given token from the container's internal registry.
|
|
434
440
|
*
|
|
435
|
-
* Returns an array of distinct
|
|
436
|
-
* Values from {@link ValueProvider} registrations are not included,
|
|
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.
|
|
437
444
|
*
|
|
438
|
-
* 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.
|
|
439
446
|
*/
|
|
440
447
|
unregister<Value>(token: Token<Value>, name?: string): Value[];
|
|
441
448
|
/**
|
|
@@ -650,7 +657,7 @@ declare function createContainer(options?: Partial<ContainerOptions>): Container
|
|
|
650
657
|
*
|
|
651
658
|
* @__NO_SIDE_EFFECTS__
|
|
652
659
|
*/
|
|
653
|
-
declare function AutoRegister(): ClassDecorator
|
|
660
|
+
declare function AutoRegister<This extends object>(): ClassDecorator<This>;
|
|
654
661
|
|
|
655
662
|
/**
|
|
656
663
|
* Class decorator that sets the class scope to **Container** and enables
|
|
@@ -671,7 +678,7 @@ declare function AutoRegister(): ClassDecorator;
|
|
|
671
678
|
*
|
|
672
679
|
* @__NO_SIDE_EFFECTS__
|
|
673
680
|
*/
|
|
674
|
-
declare function EagerInstantiate(): ClassDecorator
|
|
681
|
+
declare function EagerInstantiate<This extends object>(): ClassDecorator<This>;
|
|
675
682
|
|
|
676
683
|
/**
|
|
677
684
|
* Parameter decorator that injects the instance associated with the given class.
|
|
@@ -725,7 +732,14 @@ declare function Inject<Value>(tokens: TokenRef<Value>): ParameterDecorator;
|
|
|
725
732
|
* class Wand {}
|
|
726
733
|
* ```
|
|
727
734
|
*/
|
|
728
|
-
declare function Injectable<This extends
|
|
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>;
|
|
729
743
|
/**
|
|
730
744
|
* Class decorator that registers additional aliasing tokens for the decorated type
|
|
731
745
|
* when the type is first registered in the container.
|
|
@@ -743,7 +757,7 @@ declare function Injectable<This extends object, Value extends This>(...tokens:
|
|
|
743
757
|
* class Weapon {}
|
|
744
758
|
* ```
|
|
745
759
|
*/
|
|
746
|
-
declare function Injectable<This extends
|
|
760
|
+
declare function Injectable<Value, This extends Value & object>(tokens: TokenRef<Value>): ClassDecorator<This>;
|
|
747
761
|
|
|
748
762
|
/**
|
|
749
763
|
* Parameter decorator that injects all instances provided by the registrations
|
|
@@ -803,7 +817,7 @@ declare function InjectAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
|
|
|
803
817
|
*
|
|
804
818
|
* @__NO_SIDE_EFFECTS__
|
|
805
819
|
*/
|
|
806
|
-
declare function Named(name: string): ClassDecorator & ParameterDecorator;
|
|
820
|
+
declare function Named<This extends object>(name: string): ClassDecorator<This> & ParameterDecorator;
|
|
807
821
|
|
|
808
822
|
/**
|
|
809
823
|
* Parameter decorator that injects the instance associated with the given class,
|
|
@@ -901,7 +915,7 @@ declare function OptionalAll<Value>(tokens: TokenRef<Value>): ParameterDecorator
|
|
|
901
915
|
*
|
|
902
916
|
* @__NO_SIDE_EFFECTS__
|
|
903
917
|
*/
|
|
904
|
-
declare function Scoped(scope: Scope): ClassDecorator
|
|
918
|
+
declare function Scoped<This extends object>(scope: Scope): ClassDecorator<This>;
|
|
905
919
|
|
|
906
920
|
/**
|
|
907
921
|
* Injects the instance associated with the given class.
|
|
@@ -992,7 +1006,7 @@ declare function injectBy<Value>(thisArg: any, token: Token<Value>, name?: strin
|
|
|
992
1006
|
* Asserts that the current stack frame is within an injection context,
|
|
993
1007
|
* meaning it has access to injection functions (`inject`, `optional`, etc.).
|
|
994
1008
|
*
|
|
995
|
-
* @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.
|
|
996
1010
|
* @throws {Error} If the current stack frame is not within an injection context.
|
|
997
1011
|
*/
|
|
998
1012
|
declare function assertInjectionContext(fn: Function | string): void;
|
|
@@ -1103,14 +1117,14 @@ declare const Injector: Type<Injector>;
|
|
|
1103
1117
|
* This allows libraries or consumers that manipulate constructors, such as through
|
|
1104
1118
|
* class decorators, to inform the DI system about the real "identity" of a class.
|
|
1105
1119
|
*
|
|
1106
|
-
*
|
|
1107
|
-
*
|
|
1108
|
-
*
|
|
1109
|
-
* @remarks
|
|
1110
|
-
* 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.
|
|
1111
1122
|
* Incorrect usage may cause metadata to be misassociated, leading to subtle errors.
|
|
1112
1123
|
* Use only when manipulating constructors (e.g., via decorators or proxies),
|
|
1113
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.
|
|
1114
1128
|
*/
|
|
1115
1129
|
declare function setClassIdentityMapping<T extends object>(transformedClass: Constructor<T>, originalClass: Constructor<T>): void;
|
|
1116
1130
|
|
|
@@ -1172,4 +1186,4 @@ declare function optionalBy<Instance extends object>(thisArg: any, Class: Constr
|
|
|
1172
1186
|
declare function optionalBy<Value>(thisArg: any, token: Token<Value>, name?: string): Value | undefined;
|
|
1173
1187
|
|
|
1174
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 };
|
|
1175
|
-
export type { ChildContainerOptions, ClassProvider, ClassRef, Constructor, Container, ContainerHook, ContainerOptions, ExistingProvider, FactoryProvider, Provider, ProviderType, RegistrationOptions, Token, TokenRef, Tokens,
|
|
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
|
-
|
|
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
|
-
|
|
230
|
-
|
|
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.
|
|
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.
|
|
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
|
-
*
|
|
339
|
-
*
|
|
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(
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
values.add(value.current);
|
|
555
|
+
for (const registration of registrations){
|
|
556
|
+
const valueRef = registration.valueRef;
|
|
557
|
+
if (valueRef) {
|
|
558
|
+
values.add(valueRef.current);
|
|
564
559
|
}
|
|
565
|
-
|
|
566
|
-
...registration,
|
|
567
|
-
value: undefined
|
|
568
|
-
};
|
|
560
|
+
registration.valueRef = undefined;
|
|
569
561
|
}
|
|
570
562
|
}
|
|
571
563
|
return Array.from(values);
|
|
@@ -616,9 +608,11 @@ function isDisposable(value) {
|
|
|
616
608
|
this.myParent = parent;
|
|
617
609
|
this.myOptions = {
|
|
618
610
|
defaultScope: options?.defaultScope ?? "Transient",
|
|
619
|
-
autoRegister: options?.autoRegister ?? false
|
|
611
|
+
autoRegister: options?.autoRegister ?? false,
|
|
612
|
+
disposeUnmanaged: options?.disposeUnmanaged ?? false
|
|
620
613
|
};
|
|
621
|
-
|
|
614
|
+
const copyHooks = options?.copyHooks ?? true;
|
|
615
|
+
this.myHookRegistry = new HookRegistry(copyHooks ? parent?.myHookRegistry : undefined);
|
|
622
616
|
this.myTokenRegistry = new TokenRegistry(parent?.myTokenRegistry);
|
|
623
617
|
}
|
|
624
618
|
get registry() {
|
|
@@ -639,7 +633,9 @@ function isDisposable(value) {
|
|
|
639
633
|
this.checkDisposed();
|
|
640
634
|
const container = new ContainerImpl(this, {
|
|
641
635
|
defaultScope: options?.defaultScope ?? this.myOptions.defaultScope,
|
|
642
|
-
autoRegister: options?.autoRegister ?? this.myOptions.autoRegister
|
|
636
|
+
autoRegister: options?.autoRegister ?? this.myOptions.autoRegister,
|
|
637
|
+
disposeUnmanaged: options?.disposeUnmanaged ?? this.myOptions.disposeUnmanaged,
|
|
638
|
+
copyHooks: options?.copyHooks
|
|
643
639
|
});
|
|
644
640
|
this.myChildren.add(container);
|
|
645
641
|
return container;
|
|
@@ -651,16 +647,15 @@ function isDisposable(value) {
|
|
|
651
647
|
getCached(token) {
|
|
652
648
|
this.checkDisposed();
|
|
653
649
|
const registration = this.myTokenRegistry.get(token);
|
|
654
|
-
return registration?.
|
|
650
|
+
return registration?.valueRef?.current;
|
|
655
651
|
}
|
|
656
652
|
getAllCached(token) {
|
|
657
653
|
this.checkDisposed();
|
|
658
654
|
const registrations = this.myTokenRegistry.getAll(token);
|
|
659
655
|
const values = new Set();
|
|
660
|
-
for (const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
values.add(value.current);
|
|
656
|
+
for (const { valueRef } of registrations){
|
|
657
|
+
if (valueRef) {
|
|
658
|
+
values.add(valueRef.current);
|
|
664
659
|
}
|
|
665
660
|
}
|
|
666
661
|
return Array.from(values);
|
|
@@ -669,10 +664,9 @@ function isDisposable(value) {
|
|
|
669
664
|
this.checkDisposed();
|
|
670
665
|
const [, registrations] = this.myTokenRegistry.deleteAll();
|
|
671
666
|
const values = new Set();
|
|
672
|
-
for (const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
values.add(value.current);
|
|
667
|
+
for (const { valueRef } of registrations){
|
|
668
|
+
if (valueRef) {
|
|
669
|
+
values.add(valueRef.current);
|
|
676
670
|
}
|
|
677
671
|
}
|
|
678
672
|
return Array.from(values);
|
|
@@ -699,10 +693,9 @@ function isDisposable(value) {
|
|
|
699
693
|
this.checkDisposed();
|
|
700
694
|
const registrations = this.myTokenRegistry.delete(token, name);
|
|
701
695
|
const values = new Set();
|
|
702
|
-
for (const
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
values.add(value.current);
|
|
696
|
+
for (const { valueRef } of registrations){
|
|
697
|
+
if (valueRef) {
|
|
698
|
+
values.add(valueRef.current);
|
|
706
699
|
}
|
|
707
700
|
}
|
|
708
701
|
return Array.from(values);
|
|
@@ -741,18 +734,23 @@ function isDisposable(value) {
|
|
|
741
734
|
this.myChildren.clear();
|
|
742
735
|
this.myParent?.myChildren?.delete(this);
|
|
743
736
|
const [, registrations] = this.myTokenRegistry.deleteAll();
|
|
744
|
-
const
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
737
|
+
const disposeUnmanaged = this.myOptions.disposeUnmanaged;
|
|
738
|
+
const cacheValues = new Set();
|
|
739
|
+
const allValues = new Set();
|
|
740
|
+
for (const { provider, valueRef } of registrations){
|
|
741
|
+
if (valueRef) {
|
|
742
|
+
cacheValues.add(valueRef.current);
|
|
743
|
+
allValues.add(valueRef.current);
|
|
744
|
+
} else if (disposeUnmanaged && isValueProvider(provider)) {
|
|
745
|
+
allValues.add(provider.useValue);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
for (const value of allValues){
|
|
749
|
+
if (isDisposable(value)) {
|
|
750
|
+
value.dispose();
|
|
753
751
|
}
|
|
754
752
|
}
|
|
755
|
-
this.notifyDisposeHooks(Array.from(
|
|
753
|
+
this.notifyDisposeHooks(Array.from(cacheValues));
|
|
756
754
|
this.myHookRegistry.clear();
|
|
757
755
|
}
|
|
758
756
|
registerClass(Class) {
|
|
@@ -771,7 +769,7 @@ function isDisposable(value) {
|
|
|
771
769
|
this.myTokenRegistry.put(Class, registration);
|
|
772
770
|
// Register the additional tokens specified via class decorators.
|
|
773
771
|
// These tokens will point to the original Class token and will have the same scope.
|
|
774
|
-
for (const token of metadata.
|
|
772
|
+
for (const token of metadata.tokenRef.getRefTokens()){
|
|
775
773
|
this.myTokenRegistry.put(token, {
|
|
776
774
|
name: name,
|
|
777
775
|
provider: {
|
|
@@ -962,13 +960,13 @@ function isDisposable(value) {
|
|
|
962
960
|
switch(scope){
|
|
963
961
|
case "Container":
|
|
964
962
|
{
|
|
965
|
-
const valueRef = registration.
|
|
963
|
+
const valueRef = registration.valueRef;
|
|
966
964
|
if (valueRef) {
|
|
967
965
|
return valueRef.current;
|
|
968
966
|
}
|
|
969
967
|
const args = this.resolveCtorDependencies(registration);
|
|
970
968
|
const value = this.injectMethodDependencies(registration, factory(args));
|
|
971
|
-
registration.
|
|
969
|
+
registration.valueRef = {
|
|
972
970
|
current: value
|
|
973
971
|
};
|
|
974
972
|
this.notifyProvideHooks(value, scope);
|
|
@@ -1057,7 +1055,7 @@ function isDisposable(value) {
|
|
|
1057
1055
|
}
|
|
1058
1056
|
// Call context: decorator-based injection
|
|
1059
1057
|
resolveDependency(dependency, instance) {
|
|
1060
|
-
const token = dependency.tokenRef
|
|
1058
|
+
const [token] = dependency.tokenRef.getRefTokens();
|
|
1061
1059
|
check(token, `token passed to @${dependency.appliedBy} was undefined (possible circular imports)`);
|
|
1062
1060
|
const name = dependency.name;
|
|
1063
1061
|
switch(dependency.appliedBy){
|
|
@@ -1133,12 +1131,11 @@ function isDisposable(value) {
|
|
|
1133
1131
|
* @__NO_SIDE_EFFECTS__
|
|
1134
1132
|
*/ function EagerInstantiate() {
|
|
1135
1133
|
return function(Class) {
|
|
1136
|
-
const
|
|
1137
|
-
const metadata = getMetadata(ctor);
|
|
1134
|
+
const metadata = getMetadata(Class);
|
|
1138
1135
|
const currentScope = metadata.scope;
|
|
1139
1136
|
check(!currentScope || currentScope.value === "Container", ()=>{
|
|
1140
1137
|
const { value, appliedBy } = currentScope;
|
|
1141
|
-
const className = getTokenName(
|
|
1138
|
+
const className = getTokenName(Class);
|
|
1142
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.`;
|
|
1143
1140
|
});
|
|
1144
1141
|
metadata.eagerInstantiate = true;
|
|
@@ -1165,12 +1162,12 @@ function Injectable(...args) {
|
|
|
1165
1162
|
return function(Class) {
|
|
1166
1163
|
const metadata = getMetadata(Class);
|
|
1167
1164
|
const arg0 = args[0];
|
|
1168
|
-
const
|
|
1169
|
-
const existingTokensRef = metadata.
|
|
1170
|
-
metadata.
|
|
1165
|
+
const ref = isTokenRef(arg0) ? arg0 : tokenRef(()=>args);
|
|
1166
|
+
const existingTokensRef = metadata.tokenRef;
|
|
1167
|
+
metadata.tokenRef = {
|
|
1171
1168
|
getRefTokens: ()=>{
|
|
1172
1169
|
const existingTokens = existingTokensRef.getRefTokens();
|
|
1173
|
-
for (const token of
|
|
1170
|
+
for (const token of ref.getRefTokens()){
|
|
1174
1171
|
existingTokens.add(token);
|
|
1175
1172
|
}
|
|
1176
1173
|
return existingTokens;
|
|
@@ -1213,9 +1210,9 @@ function InjectAll(token) {
|
|
|
1213
1210
|
return function(target, propertyKey, parameterIndex) {
|
|
1214
1211
|
if (parameterIndex === undefined) {
|
|
1215
1212
|
// The decorator has been applied to the class
|
|
1216
|
-
const
|
|
1217
|
-
const metadata = getMetadata(
|
|
1218
|
-
const className = getTokenName(
|
|
1213
|
+
const Class = target;
|
|
1214
|
+
const metadata = getMetadata(Class);
|
|
1215
|
+
const className = getTokenName(Class);
|
|
1219
1216
|
check(metadata.name === undefined, `multiple @Named decorators on class ${className}, but only one is allowed`);
|
|
1220
1217
|
metadata.name = name;
|
|
1221
1218
|
} else {
|
|
@@ -1278,13 +1275,12 @@ function OptionalAll(token) {
|
|
|
1278
1275
|
* @__NO_SIDE_EFFECTS__
|
|
1279
1276
|
*/ function Scoped(scope) {
|
|
1280
1277
|
return function(Class) {
|
|
1281
|
-
const
|
|
1282
|
-
const metadata = getMetadata(ctor);
|
|
1278
|
+
const metadata = getMetadata(Class);
|
|
1283
1279
|
const currentScope = metadata.scope;
|
|
1284
1280
|
check(!currentScope || currentScope.value === scope, ()=>{
|
|
1285
1281
|
const { value, appliedBy } = currentScope;
|
|
1286
1282
|
const by = appliedBy === "Scoped" ? `another @${appliedBy} decorator` : `@${appliedBy}`;
|
|
1287
|
-
const className = getTokenName(
|
|
1283
|
+
const className = getTokenName(Class);
|
|
1288
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.`;
|
|
1289
1285
|
});
|
|
1290
1286
|
metadata.scope = {
|