@lppedd/di-wise-neo 0.3.0 → 0.3.2

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/src/container.ts DELETED
@@ -1,292 +0,0 @@
1
- import { DefaultContainer } from "./defaultContainer";
2
- import type { ClassProvider, ExistingProvider, FactoryProvider, ValueProvider } from "./provider";
3
- import { Scope } from "./scope";
4
- import type { Constructor, Token } from "./token";
5
- import type { RegistrationOptions, TokenRegistry } from "./tokenRegistry";
6
-
7
- /**
8
- * Container creation options.
9
- */
10
- export interface ContainerOptions {
11
- /**
12
- * Whether to automatically register an unregistered class when resolving it as a token.
13
- *
14
- * @defaultValue false
15
- */
16
- readonly autoRegister: boolean;
17
-
18
- /**
19
- * The default scope for registrations.
20
- *
21
- * @defaultValue Scope.Inherited
22
- */
23
- readonly defaultScope: Scope;
24
- }
25
-
26
- /**
27
- * Container API.
28
- */
29
- export interface Container {
30
- /**
31
- * @internal
32
- */
33
- api?: Readonly<Container>;
34
-
35
- /**
36
- * @internal
37
- */
38
- readonly registry: TokenRegistry;
39
-
40
- /**
41
- * The options used to create this container.
42
- */
43
- readonly options: ContainerOptions;
44
-
45
- /**
46
- * The parent container, or `undefined` if this is the root container.
47
- */
48
- readonly parent: Container | undefined;
49
-
50
- /**
51
- * Whether this container is disposed.
52
- */
53
- readonly isDisposed: boolean;
54
-
55
- /**
56
- * Creates a new child container that inherits this container's options.
57
- *
58
- * You can pass specific options to override the inherited ones.
59
- */
60
- createChild(options?: Partial<ContainerOptions>): Container;
61
-
62
- /**
63
- * Clears and returns all distinct cached values from this container's internal registry.
64
- * Values from {@link ValueProvider} registrations are not included, as they are never cached.
65
- *
66
- * Note that only this container is affected. Parent containers, if any, remain unchanged.
67
- */
68
- clearCache(): unknown[];
69
-
70
- /**
71
- * Returns the cached value from the most recent registration of the token,
72
- * or `undefined` if no value has been cached yet (the token has not been resolved yet).
73
- *
74
- * If the token has at least one registration in this container,
75
- * the cached value is taken from the most recent of those registrations.
76
- * Otherwise, it may be retrieved from parent containers, if any.
77
- *
78
- * Values are never cached for tokens with _transient_ or _resolution_ scope,
79
- * or for {@link ValueProvider} registrations.
80
- */
81
- getCached<Value>(token: Token<Value>): Value | undefined;
82
-
83
- /**
84
- * Returns all cached values associated with registrations of the token,
85
- * in the order they were registered, or an empty array if none have been cached.
86
- *
87
- * If the token has at least one registration in the current container,
88
- * cached values are taken from those registrations.
89
- * Otherwise, cached values may be retrieved from parent containers, if any.
90
- *
91
- * Values are never cached for tokens with _transient_ or _resolution_ scope,
92
- * or for {@link ValueProvider} registrations.
93
- */
94
- getAllCached<Value>(token: Token<Value>): Value[];
95
-
96
- /**
97
- * Removes all registrations from this container's internal registry.
98
- *
99
- * Returns an array of distinct cached values that were stored within the removed registrations.
100
- * Values from {@link ValueProvider} registrations are not included, as they are not cached.
101
- *
102
- * Note that only this container is affected. Parent containers, if any, remain unchanged.
103
- */
104
- resetRegistry(): unknown[];
105
-
106
- /**
107
- * Returns whether the token is registered in this container or in parent containers, if any.
108
- */
109
- isRegistered(token: Token): boolean;
110
-
111
- /**
112
- * Registers a {@link ClassProvider}, using the class itself as its token.
113
- *
114
- * Tokens provided to the {@link Injectable} decorator applied to the class
115
- * are also registered as aliases. The scope is determined by the {@link Scoped}
116
- * decorator, if present.
117
- */
118
- register<Instance extends object>(Class: Constructor<Instance>): this;
119
-
120
- /**
121
- * Registers a {@link ClassProvider} with a token.
122
- */
123
- register<Instance extends object, ProviderInstance extends Instance>(
124
- token: Token<Instance>,
125
- provider: ClassProvider<ProviderInstance>,
126
- options?: RegistrationOptions,
127
- ): this;
128
-
129
- /**
130
- * Registers a {@link FactoryProvider} with a token.
131
- */
132
- register<Value, ProviderValue extends Value>(
133
- token: Token<Value>,
134
- provider: FactoryProvider<ProviderValue>,
135
- options?: RegistrationOptions,
136
- ): this;
137
-
138
- /**
139
- * Registers an {@link ExistingProvider} with a token.
140
- *
141
- * The token will alias the one set in `useExisting`.
142
- */
143
- register<Value, ProviderValue extends Value>(
144
- token: Token<Value>,
145
- provider: ExistingProvider<ProviderValue>,
146
- ): this;
147
-
148
- /**
149
- * Registers a {@link ValueProvider} with a token.
150
- *
151
- * Values provided via `useValue` are never cached (scopes do not apply)
152
- * and are simply returned as-is.
153
- */
154
- register<Value, ProviderValue extends Value>(
155
- token: Token<Value>,
156
- provider: ValueProvider<ProviderValue>,
157
- ): this;
158
-
159
- /**
160
- * Removes all registrations for the given token from the container's internal registry.
161
- *
162
- * Returns an array of distinct cached values that were stored within the removed registrations.
163
- * Values from {@link ValueProvider} registrations are not included, as they are not cached.
164
- *
165
- * Note that only this container is affected. Parent containers, if any, remain unchanged.
166
- */
167
- unregister<Value>(token: Token<Value>): Value[];
168
-
169
- /**
170
- * Resolves the given class to the instance associated with it.
171
- *
172
- * If the class is registered in this container or any of its parent containers,
173
- * an instance is created using the most recent registration.
174
- *
175
- * If the class is not registered, but it is decorated with {@link AutoRegister},
176
- * or {@link ContainerOptions.autoRegister} is true, the class is registered automatically.
177
- * Otherwise, resolution fails.
178
- * The scope for the automatic registration is determined by either
179
- * the {@link Scoped} decorator on the class, or {@link ContainerOptions.defaultScope}.
180
- *
181
- * If `optional` is false or is not passed and the class is not registered in the container
182
- * (and could not be auto-registered), an error is thrown.
183
- * Otherwise, if `optional` is true, `undefined` is returned.
184
- *
185
- * The resolution behavior depends on the {@link Provider} used during registration:
186
- * - For {@link ValueProvider}, the explicitly provided instance is returned.
187
- * - For {@link FactoryProvider}, the factory function is invoked to create the instance.
188
- * - For {@link ClassProvider}, a new instance of the class is created according to its scope.
189
- * - For {@link ExistingProvider}, the instance is resolved by referring to another registered token.
190
- *
191
- * If the class is registered with _container_ scope, the resolved instance is cached
192
- * in the container's internal registry.
193
- */
194
- resolve<Instance extends object>(Class: Constructor<Instance>, optional?: false): Instance;
195
- resolve<Instance extends object>(Class: Constructor<Instance>, optional: true): Instance | undefined;
196
- resolve<Instance extends object>(Class: Constructor<Instance>, optional: boolean): Instance | undefined;
197
-
198
- /**
199
- * Resolves the given token to the value associated with it.
200
- *
201
- * If the token is registered in this container or any of its parent containers,
202
- * its value is resolved using the most recent registration.
203
- *
204
- * If `optional` is false or not passed and the token is not registered in the container,
205
- * an error is thrown. Otherwise, if `optional` is true, `undefined` is returned.
206
- *
207
- * The resolution behavior depends on the {@link Provider} used during registration:
208
- * - For {@link ValueProvider}, the explicitly provided value is returned.
209
- * - For {@link FactoryProvider}, the factory function is invoked to create the value.
210
- * - For {@link ClassProvider}, a new instance of the class is created according to its scope.
211
- * - For {@link ExistingProvider}, the value is resolved by referring to another registered token.
212
- *
213
- * If the token is registered with _container_ scope, the resolved value is cached
214
- * in the container's internal registry.
215
- */
216
- resolve<Value>(token: Token<Value>, optional?: false): Value;
217
- resolve<Value>(token: Token<Value>, optional: true): Value | undefined;
218
- resolve<Value>(token: Token<Value>, optional: boolean): Value | undefined;
219
-
220
- /**
221
- * Resolves the given class to all instances provided by the registrations associated with it.
222
- *
223
- * If the class is not registered, but it is decorated with {@link AutoRegister},
224
- * or {@link ContainerOptions.autoRegister} is true, the class is registered automatically.
225
- * Otherwise, resolution fails.
226
- * The scope for the automatic registration is determined by either
227
- * the {@link Scoped} decorator on the class, or {@link ContainerOptions.defaultScope}.
228
- *
229
- * If `optional` is false or is not passed and the class is not registered in the container
230
- * (and could not be auto-registered), an error is thrown.
231
- * Otherwise, if `optional` is true, an empty array is returned.
232
- *
233
- * The resolution behavior depends on the {@link Provider} used during registration:
234
- * - For {@link ValueProvider}, the explicitly provided instance is returned.
235
- * - For {@link FactoryProvider}, the factory function is invoked to create the instance.
236
- * - For {@link ClassProvider}, a new instance of the class is created according to its scope.
237
- * - For {@link ExistingProvider}, the instance is resolved by referring to another registered token.
238
- *
239
- * If the class is registered with _container_ scope, the resolved instances are cached
240
- * in the container's internal registry.
241
- *
242
- * A separate instance of the class is created for each provider.
243
- *
244
- * @see The documentation for `resolve(Class: Constructor)`
245
- */
246
- resolveAll<Instance extends object>(Class: Constructor<Instance>, optional?: false): Instance[];
247
- resolveAll<Instance extends object>(Class: Constructor<Instance>, optional: true): Instance[];
248
- resolveAll<Instance extends object>(Class: Constructor<Instance>, optional: boolean): Instance[];
249
-
250
- /**
251
- * Resolves the given token to all values provided by the registrations associated with it.
252
- *
253
- * If `optional` is false or not passed and the token is not registered in the container,
254
- * an error is thrown. Otherwise, if `optional` is true, an empty array is returned.
255
- *
256
- * The resolution behavior depends on the {@link Provider} used during registration:
257
- * - For {@link ValueProvider}, the explicitly provided value is returned.
258
- * - For {@link FactoryProvider}, the factory function is invoked to create the value.
259
- * - For {@link ClassProvider}, a new instance of the class is created according to its scope.
260
- * - For {@link ExistingProvider}, the value is resolved by referring to another registered token.
261
- *
262
- * If the token is registered with _container_ scope, the resolved values are cached
263
- * in the container's internal registry.
264
- *
265
- * @see The documentation for `resolve(token: Token)`
266
- */
267
- resolveAll<Value>(token: Token<Value>, optional?: false): NonNullable<Value>[];
268
- resolveAll<Value>(token: Token<Value>, optional: true): NonNullable<Value>[];
269
- resolveAll<Value>(token: Token<Value>, optional: boolean): NonNullable<Value>[];
270
-
271
- /**
272
- * Disposes this container and all its cached values.
273
- *
274
- * Token values implementing a `Disposable` interface (e.g., objects with a `dispose()` function)
275
- * are automatically disposed during this process.
276
- *
277
- * Note that children containers are disposed first, in creation order.
278
- */
279
- dispose(): void;
280
- }
281
-
282
- /**
283
- * Creates a new container.
284
- */
285
- export function createContainer(
286
- options: Partial<ContainerOptions> = {
287
- autoRegister: false,
288
- defaultScope: Scope.Inherited,
289
- },
290
- ): Container {
291
- return new DefaultContainer(undefined, options);
292
- }
@@ -1,24 +0,0 @@
1
- import { getMetadata } from "../metadata";
2
- import type { Constructor } from "../token";
3
-
4
- /**
5
- * Class decorator for enabling auto-registration of an unregistered class
6
- * when first resolving it from the container.
7
- *
8
- * @example
9
- * ```ts
10
- * @AutoRegister()
11
- * class Wizard {}
12
- *
13
- * const wizard = container.resolve(Wizard);
14
- * container.isRegistered(Wizard); // => true
15
- * ```
16
- *
17
- * @__NO_SIDE_EFFECTS__
18
- */
19
- export function AutoRegister(enable: boolean = true): ClassDecorator {
20
- return function (Class) {
21
- const metadata = getMetadata(Class as any as Constructor<any>);
22
- metadata.autoRegister = enable;
23
- };
24
- }
@@ -1,47 +0,0 @@
1
- import { assert } from "../errors";
2
- import { getMetadata } from "../metadata";
3
- import type { Constructor, Token } from "../token";
4
- import type { Decorator } from "../tokenRegistry";
5
- import { forwardRef, isTokenRef, type TokenRef } from "../tokensRef";
6
-
7
- export function processDecoratedParameter(
8
- decorator: Decorator,
9
- token: Token | TokenRef,
10
- target: object,
11
- propertyKey: string | symbol | undefined,
12
- parameterIndex: number,
13
- ): void {
14
- // Error out immediately if the decorator has been applied
15
- // to a static property or a static method
16
- if (propertyKey !== undefined && typeof target === "function") {
17
- assert(false, `@${decorator} cannot be used on static member ${target.name}.${String(propertyKey)}`);
18
- }
19
-
20
- const tokenRef = isTokenRef(token) ? token : forwardRef(() => token);
21
-
22
- if (propertyKey === undefined) {
23
- // Constructor
24
- const metadata = getMetadata(target as Constructor<any>);
25
- metadata.dependencies.constructor.push({
26
- decorator: decorator,
27
- tokenRef: tokenRef,
28
- index: parameterIndex,
29
- });
30
- } else {
31
- // Normal instance method
32
- const metadata = getMetadata(target.constructor as Constructor<any>);
33
- const methods = metadata.dependencies.methods;
34
- let dep = methods.get(propertyKey);
35
-
36
- if (dep === undefined) {
37
- dep = [];
38
- methods.set(propertyKey, dep);
39
- }
40
-
41
- dep.push({
42
- decorator: decorator,
43
- tokenRef: tokenRef,
44
- index: parameterIndex,
45
- });
46
- }
47
- }
@@ -1,7 +0,0 @@
1
- export { AutoRegister } from "./autoRegister";
2
- export { Inject } from "./inject";
3
- export { Injectable } from "./injectable";
4
- export { InjectAll } from "./injectAll";
5
- export { Optional } from "./optional";
6
- export { OptionalAll } from "./optionalAll";
7
- export { Scoped } from "./scoped";
@@ -1,42 +0,0 @@
1
- import type { Constructor, Token } from "../token";
2
- import type { TokenRef } from "../tokensRef";
3
- import { processDecoratedParameter } from "./decorators";
4
-
5
- /**
6
- * Parameter decorator that injects the instance associated with the given class.
7
- *
8
- * Throws an error if the class is not registered in the container.
9
- */
10
- export function Inject<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
11
-
12
- /**
13
- * Parameter decorator that injects the value associated with the given token.
14
- *
15
- * Throws an error if the token is not registered in the container.
16
- */
17
- export function Inject<Value>(token: Token<Value>): ParameterDecorator;
18
-
19
- /**
20
- * Parameter decorator that injects the value associated with the given token.
21
- *
22
- * Allows referencing a token that is declared later in the file by using
23
- * the {@link forwardRef} helper function.
24
- *
25
- * Throws an error if the token is not registered in the container.
26
- *
27
- * @example
28
- * ```ts
29
- * class Wizard {
30
- * constructor(@Inject(forwardRef(() => Wand)) readonly wand: Wand) {}
31
- * }
32
- * // Other code...
33
- * class Wand {}
34
- * ```
35
- */
36
- export function Inject<Value>(tokens: TokenRef<Value>): ParameterDecorator;
37
-
38
- export function Inject<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
39
- return function (target, propertyKey, parameterIndex: number): void {
40
- processDecoratedParameter("Inject", token, target, propertyKey, parameterIndex);
41
- };
42
- }
@@ -1,45 +0,0 @@
1
- import type { Constructor, Token } from "../token";
2
- import type { TokenRef } from "../tokensRef";
3
- import { processDecoratedParameter } from "./decorators";
4
-
5
- /**
6
- * Parameter decorator that injects all instances provided by the registrations
7
- * associated with the given class.
8
- *
9
- * Throws an error if the class is not registered in the container.
10
- */
11
- export function InjectAll<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
12
-
13
- /**
14
- * Parameter decorator that injects all values provided by the registrations
15
- * associated with the given token.
16
- *
17
- * Throws an error if the token is not registered in the container.
18
- */
19
- export function InjectAll<Value>(token: Token<Value>): ParameterDecorator;
20
-
21
- /**
22
- * Parameter decorator that injects all values provided by the registrations
23
- * associated with the given token.
24
- *
25
- * Allows referencing a token that is declared later in the file by using
26
- * the {@link forwardRef} helper function.
27
- *
28
- * Throws an error if the token is not registered in the container.
29
- *
30
- * @example
31
- * ```ts
32
- * class Wizard {
33
- * constructor(@InjectAll(forwardRef(() => Wand)) readonly wands: Wand[]) {}
34
- * }
35
- * // Other code...
36
- * class Wand {}
37
- * ```
38
- */
39
- export function InjectAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
40
-
41
- export function InjectAll<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
42
- return function (target, propertyKey, parameterIndex: number): void {
43
- processDecoratedParameter("InjectAll", token, target, propertyKey, parameterIndex);
44
- };
45
- }
@@ -1,61 +0,0 @@
1
- import { getMetadata } from "../metadata";
2
- import type { Constructor, Tokens } from "../token";
3
- import { forwardRef, isTokensRef, type TokenRef, type TokensRef } from "../tokensRef";
4
-
5
- /**
6
- * Class decorator for registering additional aliasing tokens for the decorated type
7
- * when registering it.
8
- *
9
- * The container uses {@link ExistingProvider} under the hood.
10
- *
11
- * @example
12
- * ```ts
13
- * @Injectable(Weapon)
14
- * class Wand {}
15
- * ```
16
- */
17
- export function Injectable<This extends object, Value extends This>(...tokens: Tokens<Value>): ClassDecorator;
18
-
19
- /**
20
- * Class decorator for registering additional aliasing tokens for the decorated type
21
- * when registering it.
22
- *
23
- * The container uses {@link ExistingProvider} under the hood.
24
- *
25
- * Allows referencing tokens that are declared later in the file by using
26
- * the {@link forwardRef} helper function.
27
- *
28
- * @example
29
- * ```ts
30
- * @Injectable(forwardRef() => Weapon) // Weapon is declared after Wand
31
- * class Wizard {}
32
- * // Other code...
33
- * class Weapon {}
34
- * ```
35
- */
36
- export function Injectable<This extends object, Value extends This>(
37
- tokens: TokenRef<Value> | TokensRef<Value>,
38
- ): ClassDecorator;
39
-
40
- /**
41
- * @__NO_SIDE_EFFECTS__
42
- */
43
- export function Injectable(...args: unknown[]): ClassDecorator {
44
- return function (Class): void {
45
- const metadata = getMetadata(Class as any as Constructor<any>);
46
- const arg0 = args[0];
47
- const tokensRef = isTokensRef(arg0) ? arg0 : forwardRef(() => args as Tokens);
48
- const existingTokensRef = metadata.tokensRef;
49
- metadata.tokensRef = {
50
- getRefTokens: () => {
51
- const existingTokens = existingTokensRef.getRefTokens();
52
-
53
- for (const token of tokensRef.getRefTokens()) {
54
- existingTokens.add(token);
55
- }
56
-
57
- return existingTokens;
58
- },
59
- };
60
- };
61
- }
@@ -1,39 +0,0 @@
1
- import type { Constructor, Token } from "../token";
2
- import type { TokenRef } from "../tokensRef";
3
- import { processDecoratedParameter } from "./decorators";
4
-
5
- /**
6
- * Parameter decorator that injects the instance associated with the given class,
7
- * or `undefined` if the class is not registered in the container.
8
- */
9
- export function Optional<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
10
-
11
- /**
12
- * Parameter decorator that injects the value associated with the given token,
13
- * or `undefined` if the token is not registered in the container.
14
- */
15
- export function Optional<Value>(token: Token<Value>): ParameterDecorator;
16
-
17
- /**
18
- * Parameter decorator that injects the value associated with the given token,
19
- * or `undefined` if the token is not registered in the container.
20
- *
21
- * Allows referencing a token that is declared later in the file by using
22
- * the {@link forwardRef} helper function.
23
- *
24
- * @example
25
- * ```ts
26
- * class Wizard {
27
- * constructor(@Optional(forwardRef(() => Wand)) readonly wand: Wand | undefined) {}
28
- * }
29
- * // Other code...
30
- * class Wand {}
31
- * ```
32
- */
33
- export function Optional<Value>(tokens: TokenRef<Value>): ParameterDecorator;
34
-
35
- export function Optional<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
36
- return function (target, propertyKey, parameterIndex: number): void {
37
- processDecoratedParameter("Optional", token, target, propertyKey, parameterIndex);
38
- };
39
- }
@@ -1,42 +0,0 @@
1
- import type { Constructor, Token } from "../token";
2
- import type { TokenRef } from "../tokensRef";
3
- import { processDecoratedParameter } from "./decorators";
4
-
5
- /**
6
- * Parameter decorator that injects all instances provided by the registrations
7
- * associated with the given class, or an empty array if the class is not registered
8
- * in the container.
9
- */
10
- export function OptionalAll<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
11
-
12
- /**
13
- * Parameter decorator that injects all values provided by the registrations
14
- * associated with the given token, or an empty array if the token is not registered
15
- * in the container.
16
- */
17
- export function OptionalAll<Value>(token: Token<Value>): ParameterDecorator;
18
-
19
- /**
20
- * Parameter decorator that injects all values provided by the registrations
21
- * associated with the given token, or an empty array if the token is not registered
22
- * in the container.
23
- *
24
- * Allows referencing a token that is declared later in the file by using
25
- * the {@link forwardRef} helper function.
26
- *
27
- * @example
28
- * ```ts
29
- * class Wizard {
30
- * constructor(@OptionalAll(forwardRef(() => Wand)) readonly wands: Wand[]) {}
31
- * }
32
- * // Other code...
33
- * class Wand {}
34
- * ```
35
- */
36
- export function OptionalAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
37
-
38
- export function OptionalAll<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
39
- return function (target, propertyKey, parameterIndex: number): void {
40
- processDecoratedParameter("OptionalAll", token, target, propertyKey, parameterIndex);
41
- };
42
- }
@@ -1,32 +0,0 @@
1
- import { getMetadata } from "../metadata";
2
- import type { Scope } from "../scope";
3
- import type { Constructor } from "../token";
4
-
5
- /**
6
- * Class decorator for setting the scope of the decorated type when registering it.
7
- *
8
- * The scope set by this decorator can be overridden by explicit registration options, if provided.
9
- *
10
- * @example
11
- * ```ts
12
- * @Scoped(Scope.Container)
13
- * class Wizard {}
14
- *
15
- * container.register(Wizard);
16
- *
17
- * // Under the hood
18
- * container.register(
19
- * Wizard,
20
- * { useClass: Wizard },
21
- * { scope: Scope.Container },
22
- * );
23
- * ```
24
- *
25
- * @__NO_SIDE_EFFECTS__
26
- */
27
- export function Scoped(scope: Scope): ClassDecorator {
28
- return function (Class): void {
29
- const metadata = getMetadata(Class as any as Constructor<any>);
30
- metadata.scope = scope;
31
- };
32
- }