@needle-di/core 1.1.3 → 1.2.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 +9 -0
- package/dist/container.d.ts +40 -15
- package/dist/container.js +109 -19
- package/dist/container.js.map +1 -1
- package/dist/context.d.ts +19 -3
- package/dist/context.js +27 -4
- package/dist/context.js.map +1 -1
- package/dist/factory.d.ts +23 -3
- package/dist/factory.js +68 -64
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +66 -0
- package/dist/providers.js +16 -1
- package/dist/providers.js.map +1 -1
- package/dist/utils.d.ts +6 -6
- package/dist/utils.js +8 -8
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,6 +66,15 @@ deno add jsr:@needle-di/core
|
|
|
66
66
|
|
|
67
67
|
Check out our docs on [https://needle-di.io](https://needle-di.io/concepts/binding.html).
|
|
68
68
|
|
|
69
|
+
## Using AI coding agents?
|
|
70
|
+
|
|
71
|
+
Our documentation is available in an LLM-friendly format:
|
|
72
|
+
|
|
73
|
+
- [https://needle-di.io/llms.txt](https://needle-di.io/llms.txt) - a compact index of all documentation pages
|
|
74
|
+
- [https://needle-di.io/llms-full.txt](https://needle-di.io/llms-full.txt) - the full documentation as a single file
|
|
75
|
+
|
|
76
|
+
See [AI agent instructions](https://needle-di.io/ai/agents.html) for guidance on using Needle DI with AI coding agents.
|
|
77
|
+
|
|
69
78
|
## License
|
|
70
79
|
|
|
71
80
|
License under the MIT License (MIT)
|
package/dist/container.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Token } from "./tokens.ts";
|
|
2
|
-
import type { Provider } from "./providers.ts";
|
|
2
|
+
import type { Provider, ProviderList } from "./providers.ts";
|
|
3
3
|
/**
|
|
4
4
|
* A dependency injection (DI) container will keep track of all bindings
|
|
5
5
|
* and hold the actual instances of your services.
|
|
@@ -7,24 +7,27 @@ import type { Provider } from "./providers.ts";
|
|
|
7
7
|
export declare class Container {
|
|
8
8
|
private readonly providers;
|
|
9
9
|
private readonly singletons;
|
|
10
|
+
/**
|
|
11
|
+
* Async constructions that have been started but have not settled yet, keyed by token.
|
|
12
|
+
*
|
|
13
|
+
* Without this, two overlapping `getAsync()` calls for the same token would both see an
|
|
14
|
+
* empty `singletons` entry and construct it twice, breaking singleton semantics.
|
|
15
|
+
*/
|
|
16
|
+
private readonly pending;
|
|
10
17
|
private readonly parent?;
|
|
11
18
|
private readonly factory;
|
|
12
19
|
constructor(parent?: Container);
|
|
13
20
|
/**
|
|
14
21
|
* Binds multiple providers to this container.
|
|
15
22
|
*
|
|
16
|
-
*
|
|
23
|
+
* Providers may be passed individually or as (nested) arrays. To define a list of providers
|
|
24
|
+
* upfront, outside of a container, use `defineProviders()`.
|
|
25
|
+
*
|
|
26
|
+
* @param providers one or more providers, optionally nested in arrays
|
|
27
|
+
*
|
|
28
|
+
* {@link https://needle-di.io/concepts/binding.html#binding-multiple-providers}
|
|
17
29
|
*/
|
|
18
|
-
bindAll<
|
|
19
|
-
bindAll<A, B>(p1: Provider<A>, p2: Provider<B>): this;
|
|
20
|
-
bindAll<A, B, C>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>): this;
|
|
21
|
-
bindAll<A, B, C, D>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>, p4: Provider<D>): this;
|
|
22
|
-
bindAll<A, B, C, D, E>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>, p4: Provider<D>, p5: Provider<E>): this;
|
|
23
|
-
bindAll<A, B, C, D, E, F>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>, p4: Provider<D>, p5: Provider<E>, p6: Provider<F>): this;
|
|
24
|
-
bindAll<A, B, C, D, E, F, G>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>, p4: Provider<D>, p5: Provider<E>, p6: Provider<F>, p7: Provider<G>): this;
|
|
25
|
-
bindAll<A, B, C, D, E, F, G, H>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>, p4: Provider<D>, p5: Provider<E>, p6: Provider<F>, p7: Provider<G>, p8: Provider<H>): this;
|
|
26
|
-
bindAll<A, B, C, D, E, F, G, H, I>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>, p4: Provider<D>, p5: Provider<E>, p6: Provider<F>, p7: Provider<G>, p8: Provider<H>, p9: Provider<I>): this;
|
|
27
|
-
bindAll<A, B, C, D, E, F, G, H, I>(p1: Provider<A>, p2: Provider<B>, p3: Provider<C>, p4: Provider<D>, p5: Provider<E>, p6: Provider<F>, p7: Provider<G>, p8: Provider<H>, p9: Provider<I>, ...providers: Provider<any>[]): this;
|
|
30
|
+
bindAll<T extends readonly unknown[]>(...providers: ProviderList<T>): this;
|
|
28
31
|
/**
|
|
29
32
|
* Binds a provider to this container.
|
|
30
33
|
*
|
|
@@ -32,11 +35,14 @@ export declare class Container {
|
|
|
32
35
|
*/
|
|
33
36
|
bind<T>(provider: Provider<T>): this;
|
|
34
37
|
/**
|
|
35
|
-
* Unbinds a
|
|
38
|
+
* Unbinds a token.
|
|
36
39
|
*
|
|
37
|
-
*
|
|
40
|
+
* This removes all providers for that token, including multi-providers,
|
|
41
|
+
* as well as any instances that were already constructed.
|
|
42
|
+
*
|
|
43
|
+
* {@link https://needle-di.io/concepts/binding.html#clear-binding}
|
|
38
44
|
*/
|
|
39
|
-
unbind<T>(
|
|
45
|
+
unbind<T>(token: Token<T>): this;
|
|
40
46
|
/**
|
|
41
47
|
* Unbinds all providers.
|
|
42
48
|
*
|
|
@@ -127,6 +133,18 @@ export declare class Container {
|
|
|
127
133
|
multi?: boolean;
|
|
128
134
|
lazy?: boolean;
|
|
129
135
|
}): Promise<T | T[] | undefined> | (() => Promise<T | T[] | undefined>);
|
|
136
|
+
/**
|
|
137
|
+
* Runs a function within an injection context backed by this container, so that it
|
|
138
|
+
* can use `inject()` and `injectAsync()` instead of `container.get()`. The return
|
|
139
|
+
* value of the function is passed through.
|
|
140
|
+
*
|
|
141
|
+
* The injection context is only active for as long as the function runs
|
|
142
|
+
* synchronously. When passing an async function, `inject()` and `injectAsync()`
|
|
143
|
+
* must therefore be called before its first `await`.
|
|
144
|
+
*
|
|
145
|
+
* {@link https://needle-di.io/concepts/injection.html#running-in-an-injection-context}
|
|
146
|
+
*/
|
|
147
|
+
runInInjectionContext<T>(block: (container: Container) => T): T;
|
|
130
148
|
/**
|
|
131
149
|
* Creates a child container.
|
|
132
150
|
*
|
|
@@ -137,6 +155,13 @@ export declare class Container {
|
|
|
137
155
|
* Returns whether the container has one or more providers for this token.
|
|
138
156
|
*/
|
|
139
157
|
has<T>(token: Token<T>): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Constructs the providers for a token asynchronously, ensuring that concurrent
|
|
160
|
+
* requests for the same token share a single construction and therefore a single
|
|
161
|
+
* instance. Callers that join an already running construction inherit its result,
|
|
162
|
+
* not its chain: their own chain has already been checked for cycles by the caller.
|
|
163
|
+
*/
|
|
164
|
+
private constructOnce;
|
|
140
165
|
private autoBindIfNeeded;
|
|
141
166
|
private existingProviderAlreadyProvided;
|
|
142
167
|
}
|
package/dist/container.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isClassToken, toString, isInjectionToken, getToken } from "./tokens.js";
|
|
2
2
|
import * as Guards from "./providers.js";
|
|
3
3
|
import { getInjectableTargets, isInjectable } from "./decorators.js";
|
|
4
|
-
import { assertPresent, assertSingle, getParentClasses, promiseTry, windowedSlice } from "./utils.js";
|
|
5
|
-
import { Factory } from "./factory.js";
|
|
6
|
-
import { injectionContext } from "./context.js";
|
|
4
|
+
import { assertPresent, assertSingle, flattenDeep, getParentClasses, promiseTry, windowedSlice } from "./utils.js";
|
|
5
|
+
import { assertNoCycle, Factory } from "./factory.js";
|
|
6
|
+
import { currentResolutionChain, injectionContext } from "./context.js";
|
|
7
7
|
/**
|
|
8
8
|
* A dependency injection (DI) container will keep track of all bindings
|
|
9
9
|
* and hold the actual instances of your services.
|
|
@@ -11,6 +11,13 @@ import { injectionContext } from "./context.js";
|
|
|
11
11
|
export class Container {
|
|
12
12
|
providers = new Map();
|
|
13
13
|
singletons = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Async constructions that have been started but have not settled yet, keyed by token.
|
|
16
|
+
*
|
|
17
|
+
* Without this, two overlapping `getAsync()` calls for the same token would both see an
|
|
18
|
+
* empty `singletons` entry and construct it twice, breaking singleton semantics.
|
|
19
|
+
*/
|
|
20
|
+
pending = new Map();
|
|
14
21
|
parent;
|
|
15
22
|
factory;
|
|
16
23
|
constructor(parent) {
|
|
@@ -21,9 +28,18 @@ export class Container {
|
|
|
21
28
|
useValue: this,
|
|
22
29
|
});
|
|
23
30
|
}
|
|
24
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Binds multiple providers to this container.
|
|
33
|
+
*
|
|
34
|
+
* Providers may be passed individually or as (nested) arrays. To define a list of providers
|
|
35
|
+
* upfront, outside of a container, use `defineProviders()`.
|
|
36
|
+
*
|
|
37
|
+
* @param providers one or more providers, optionally nested in arrays
|
|
38
|
+
*
|
|
39
|
+
* {@link https://needle-di.io/concepts/binding.html#binding-multiple-providers}
|
|
40
|
+
*/
|
|
25
41
|
bindAll(...providers) {
|
|
26
|
-
providers.forEach((it) => this.bind(it));
|
|
42
|
+
flattenDeep(providers).forEach((it) => this.bind(it));
|
|
27
43
|
return this;
|
|
28
44
|
}
|
|
29
45
|
/**
|
|
@@ -76,14 +92,17 @@ export class Container {
|
|
|
76
92
|
return this;
|
|
77
93
|
}
|
|
78
94
|
/**
|
|
79
|
-
* Unbinds a
|
|
95
|
+
* Unbinds a token.
|
|
80
96
|
*
|
|
81
|
-
*
|
|
97
|
+
* This removes all providers for that token, including multi-providers,
|
|
98
|
+
* as well as any instances that were already constructed.
|
|
99
|
+
*
|
|
100
|
+
* {@link https://needle-di.io/concepts/binding.html#clear-binding}
|
|
82
101
|
*/
|
|
83
|
-
unbind(
|
|
84
|
-
const token = getToken(provider);
|
|
102
|
+
unbind(token) {
|
|
85
103
|
this.providers.delete(token);
|
|
86
104
|
this.singletons.delete(token);
|
|
105
|
+
this.pending.delete(token);
|
|
87
106
|
return this;
|
|
88
107
|
}
|
|
89
108
|
/**
|
|
@@ -94,17 +113,25 @@ export class Container {
|
|
|
94
113
|
unbindAll() {
|
|
95
114
|
this.providers.clear();
|
|
96
115
|
this.singletons.clear();
|
|
116
|
+
this.pending.clear();
|
|
97
117
|
return this;
|
|
98
118
|
}
|
|
99
119
|
get(token, options) {
|
|
100
120
|
const lazy = options?.lazy ?? false;
|
|
101
121
|
if (lazy) {
|
|
122
|
+
// Lazy injection deliberately starts a new resolution when the getter is invoked,
|
|
123
|
+
// which is exactly what makes it usable to break a cycle.
|
|
102
124
|
return () => this.get(token, { ...options, lazy: false });
|
|
103
125
|
}
|
|
126
|
+
// The resolution we are part of, if any. Read from the active injection context
|
|
127
|
+
// rather than passed as an argument, so that the public API stays unchanged.
|
|
128
|
+
const chain = currentResolutionChain();
|
|
104
129
|
this.autoBindIfNeeded(token);
|
|
105
130
|
const optional = options?.optional ?? false;
|
|
106
131
|
if (!this.providers.has(token)) {
|
|
107
132
|
if (this.parent) {
|
|
133
|
+
// Delegation happens synchronously, so the context this chain was read from is
|
|
134
|
+
// still active and the parent observes the very same chain.
|
|
108
135
|
return this.parent.get(token, { ...options, lazy: false });
|
|
109
136
|
}
|
|
110
137
|
if (optional) {
|
|
@@ -114,10 +141,8 @@ export class Container {
|
|
|
114
141
|
}
|
|
115
142
|
const providers = assertPresent(this.providers.get(token));
|
|
116
143
|
if (!this.singletons.has(token)) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.singletons.set(token, values);
|
|
120
|
-
});
|
|
144
|
+
const values = providers.flatMap((provider) => this.factory.construct(provider, token, chain));
|
|
145
|
+
this.singletons.set(token, values);
|
|
121
146
|
}
|
|
122
147
|
const singletons = assertPresent(this.singletons.get(token));
|
|
123
148
|
const multi = options?.multi ?? false;
|
|
@@ -132,13 +157,20 @@ export class Container {
|
|
|
132
157
|
getAsync(token, options) {
|
|
133
158
|
const lazy = options?.lazy ?? false;
|
|
134
159
|
if (lazy) {
|
|
160
|
+
// Lazy injection deliberately starts a new resolution when the getter is invoked,
|
|
161
|
+
// which is exactly what makes it usable to break a cycle.
|
|
135
162
|
return () => this.getAsync(token, { ...options, lazy: false });
|
|
136
163
|
}
|
|
164
|
+
// Must be read here, before the first `await`: the injection context we inherit this
|
|
165
|
+
// from is restored as soon as our caller's synchronous block returns.
|
|
166
|
+
const chain = currentResolutionChain();
|
|
137
167
|
return promiseTry(async () => {
|
|
138
168
|
this.autoBindIfNeeded(token);
|
|
139
169
|
const optional = options?.optional ?? false;
|
|
140
170
|
if (!this.providers.has(token)) {
|
|
141
171
|
if (this.parent) {
|
|
172
|
+
// Still part of the synchronous prefix, so the context is active and the parent
|
|
173
|
+
// observes the very same chain.
|
|
142
174
|
return this.parent.getAsync(token, { ...options, lazy: false });
|
|
143
175
|
}
|
|
144
176
|
if (optional) {
|
|
@@ -147,13 +179,17 @@ export class Container {
|
|
|
147
179
|
throw Error(`No provider(s) found for ${toString(token)}`);
|
|
148
180
|
}
|
|
149
181
|
const providers = assertPresent(this.providers.get(token));
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
182
|
+
let singletons = this.singletons.get(token);
|
|
183
|
+
if (!singletons) {
|
|
184
|
+
// Cycle detection has to happen before we join an in-flight construction below:
|
|
185
|
+
// a genuine cycle would otherwise await the pending promise of a token that is
|
|
186
|
+
// waiting on us, and hang instead of reporting itself.
|
|
187
|
+
providers.forEach((provider) => assertNoCycle(chain, provider));
|
|
188
|
+
// We use the values the construction produced instead of reading `singletons`
|
|
189
|
+
// back, so that a token that was unbound while we were suspended still resolves
|
|
190
|
+
// to the result of the construction we started.
|
|
191
|
+
singletons = await this.constructOnce(token, providers, chain);
|
|
155
192
|
}
|
|
156
|
-
const singletons = assertPresent(this.singletons.get(token));
|
|
157
193
|
const multi = options?.multi ?? false;
|
|
158
194
|
if (multi) {
|
|
159
195
|
return singletons;
|
|
@@ -164,6 +200,27 @@ export class Container {
|
|
|
164
200
|
}
|
|
165
201
|
});
|
|
166
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Runs a function within an injection context backed by this container, so that it
|
|
205
|
+
* can use `inject()` and `injectAsync()` instead of `container.get()`. The return
|
|
206
|
+
* value of the function is passed through.
|
|
207
|
+
*
|
|
208
|
+
* The injection context is only active for as long as the function runs
|
|
209
|
+
* synchronously. When passing an async function, `inject()` and `injectAsync()`
|
|
210
|
+
* must therefore be called before its first `await`.
|
|
211
|
+
*
|
|
212
|
+
* {@link https://needle-di.io/concepts/injection.html#running-in-an-injection-context}
|
|
213
|
+
*/
|
|
214
|
+
runInInjectionContext(block) {
|
|
215
|
+
// A fresh context per call, never one cached per container: contexts are scoped to
|
|
216
|
+
// a single resolution, and sharing one would interleave concurrent resolutions.
|
|
217
|
+
//
|
|
218
|
+
// The chain is inherited rather than reset. Called from user code it is empty
|
|
219
|
+
// anyway, but called from within a construction the block is part of that
|
|
220
|
+
// resolution, so continuing its chain is what keeps circular dependencies
|
|
221
|
+
// detectable instead of recursing until the stack overflows.
|
|
222
|
+
return injectionContext(this, currentResolutionChain()).run(block);
|
|
223
|
+
}
|
|
167
224
|
/**
|
|
168
225
|
* Creates a child container.
|
|
169
226
|
*
|
|
@@ -178,6 +235,39 @@ export class Container {
|
|
|
178
235
|
has(token) {
|
|
179
236
|
return this.providers.has(token) || (this.parent?.has(token) ?? false);
|
|
180
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Constructs the providers for a token asynchronously, ensuring that concurrent
|
|
240
|
+
* requests for the same token share a single construction and therefore a single
|
|
241
|
+
* instance. Callers that join an already running construction inherit its result,
|
|
242
|
+
* not its chain: their own chain has already been checked for cycles by the caller.
|
|
243
|
+
*/
|
|
244
|
+
constructOnce(token, providers, chain) {
|
|
245
|
+
const existing = this.pending.get(token);
|
|
246
|
+
if (existing) {
|
|
247
|
+
return existing;
|
|
248
|
+
}
|
|
249
|
+
const pending = promiseTry(async () => {
|
|
250
|
+
const values = await Promise.all(providers.map((it) => this.factory.constructAsync(it, chain)));
|
|
251
|
+
return values.flat();
|
|
252
|
+
});
|
|
253
|
+
this.pending.set(token, pending);
|
|
254
|
+
// A construction may only write back if it is still the current one for this token.
|
|
255
|
+
// If it was unbound or superseded while in flight, the container has moved on and
|
|
256
|
+
// storing the result would resurrect a token that is no longer bound.
|
|
257
|
+
const isCurrent = () => this.pending.get(token) === pending;
|
|
258
|
+
pending.then((values) => {
|
|
259
|
+
if (isCurrent()) {
|
|
260
|
+
this.pending.delete(token);
|
|
261
|
+
this.singletons.set(token, values);
|
|
262
|
+
}
|
|
263
|
+
}, () => {
|
|
264
|
+
// A failed construction must not be cached, so a later attempt can retry.
|
|
265
|
+
if (isCurrent()) {
|
|
266
|
+
this.pending.delete(token);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
return pending;
|
|
270
|
+
}
|
|
181
271
|
autoBindIfNeeded(token) {
|
|
182
272
|
if (this.singletons.has(token)) {
|
|
183
273
|
return;
|
package/dist/container.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,OAAO,EAAwB,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAExE;;;GAGG;AACH,MAAM,OAAO,SAAS;IACH,SAAS,GAAgB,IAAI,GAAG,EAAE,CAAC;IACnC,UAAU,GAAiB,IAAI,GAAG,EAAE,CAAC;IAEtD;;;;;OAKG;IACc,OAAO,GAAe,IAAI,GAAG,EAAE,CAAC;IAEhC,MAAM,CAAa;IACnB,OAAO,CAAU;IAElC,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC;YACR,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACI,OAAO,CAA+B,GAAG,SAA0B;QACxE,WAAW,CAAoB,SAA+B,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACI,IAAI,CAAI,QAAqB;QAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEjC,8BAA8B;QAC9B,IAAI,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC;YACrF,MAAM,KAAK,CAAC,0BAA0B,QAAQ,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACtG,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACvE,MAAM,KAAK,CACT,kCAAkC,QAAQ,CAAC,KAAK,CAAC,wDAAwD,CAC1G,CAAC;QACJ,CAAC;QAED,qDAAqD;QACrD,IACE,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YACnC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC;YAChC,IAAI,CAAC,+BAA+B,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,EACjE,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAElD,+CAA+C;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAE/C,IAAI,KAAK,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM,KAAK,CACT,eAAe,QAAQ,CAAC,KAAK,CAAC,sFAAsF,CACrH,CAAC;QACJ,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAChD,MAAM,KAAK,CACT,eAAe,QAAQ,CAAC,KAAK,CAAC,6EAA6E,CAC5G,CAAC;YACJ,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEzE,iFAAiF;QACjF,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YACxG,aAAa,CAAC,CAAC,KAAK,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE;gBACvF,MAAM,cAAc,GAAgC;oBAClD,OAAO,EAAE,WAAW;oBACpB,WAAW,EAAE,UAAU;oBACvB,KAAK,EAAE,IAAI;iBACZ,CAAC;gBACF,MAAM,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;gBACtE,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC;oBACnE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,uBAAuB,EAAE,cAAc,CAAC,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAI,KAAe;QAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACI,SAAS;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAErB,OAAO,IAAI,CAAC;IACd,CAAC;IAoBM,GAAG,CACR,KAAe,EACf,OAAiE;QAEjE,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,KAAK,CAAC;QAEpC,IAAI,IAAI,EAAE,CAAC;YACT,kFAAkF;YAClF,0DAA0D;YAC1D,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,gFAAgF;QAChF,6EAA6E;QAC7E,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC;QAEvC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAE7B,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC;QAE5C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,+EAA+E;gBAC/E,4DAA4D;gBAC5D,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,MAAM,KAAK,CAAC,4BAA4B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YAC/F,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC;QAEtC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,UAAU,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,YAAY,CAAC,UAAU,EAAE,GAAG,EAAE,CACnC,KAAK,CACH,iCAAiC,QAAQ,CAAC,KAAK,CAAC,uCAAuC;gBACrF,+FAA+F,CAClG,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAkCM,QAAQ,CACb,KAAe,EACf,OAIC;QAED,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,KAAK,CAAC;QAEpC,IAAI,IAAI,EAAE,CAAC;YACT,kFAAkF;YAClF,0DAA0D;YAC1D,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,qFAAqF;QACrF,sEAAsE;QACtE,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC;QAEvC,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAE7B,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC;YAE5C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,gFAAgF;oBAChF,gCAAgC;oBAChC,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBAClE,CAAC;gBACD,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,SAAS,CAAC;gBACnB,CAAC;gBACD,MAAM,KAAK,CAAC,4BAA4B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7D,CAAC;YAED,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YAE3D,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAE5C,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,gFAAgF;gBAChF,+EAA+E;gBAC/E,uDAAuD;gBACvD,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;gBAEhE,8EAA8E;gBAC9E,gFAAgF;gBAChF,gDAAgD;gBAChD,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACjE,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC;YAEtC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,UAAU,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,OAAO,YAAY,CACjB,UAAU,EACV,GAAG,EAAE,CACH,IAAI,KAAK,CACP,iCAAiC,QAAQ,CAAC,KAAK,CAAC,uCAAuC;oBACrF,+FAA+F,CAClG,CACJ,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;OAUG;IACI,qBAAqB,CAAI,KAAkC;QAChE,mFAAmF;QACnF,gFAAgF;QAChF,EAAE;QACF,8EAA8E;QAC9E,0EAA0E;QAC1E,0EAA0E;QAC1E,6DAA6D;QAC7D,OAAO,gBAAgB,CAAC,IAAI,EAAE,sBAAsB,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;IAED;;;;OAIG;IACI,WAAW;QAChB,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,GAAG,CAAI,KAAe;QAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACK,aAAa,CAAI,KAAe,EAAE,SAAwB,EAAE,KAAsB;QACxF,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEzC,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YACpC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;YAChG,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEjC,oFAAoF;QACpF,kFAAkF;QAClF,sEAAsE;QACtE,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC;QAE5D,OAAO,CAAC,IAAI,CACV,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,SAAS,EAAE,EAAE,CAAC;gBAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,EACD,GAAG,EAAE;YACH,0EAA0E;YAC1E,IAAI,SAAS,EAAE,EAAE,CAAC;gBAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC,CACF,CAAC;QAEF,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,gBAAgB,CAAI,KAAe;QACzC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,MAAM,aAAa,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAElD,aAAa;iBACV,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;iBACzD,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;gBACvB,IAAI,CAAC,IAAI,CAAC;oBACR,OAAO,EAAE,WAAW;oBACpB,QAAQ,EAAE,WAAW;oBACrB,KAAK,EAAE,IAAI;iBACZ,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YAC3F,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAClC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC;oBACR,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK;oBACZ,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO;iBAClC,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,KAAK,EAAE,CAAC;gBACjB,IAAI,CAAC,IAAI,CAAC;oBACR,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,IAAI;oBACX,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO;iBAClC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAEO,+BAA+B,CAAC,KAAqB,EAAE,aAA6B;QAC1F,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC3C,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,OAAO,KAAK,KAAK,IAAI,EAAE,CAAC,WAAW,KAAK,aAAa,CAClG,CAAC;IACJ,CAAC;CACF;AAoBD;;GAEG;AACH,MAAM,UAAU,SAAS,CAAI,KAAe;IAC1C,OAAO,IAAI,SAAS,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAI,KAAe;IAC/C,OAAO,IAAI,SAAS,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC"}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Container } from "./container.ts";
|
|
2
|
+
import type { ResolutionChain } from "./factory.ts";
|
|
2
3
|
import type { Token } from "./tokens.ts";
|
|
3
4
|
/**
|
|
4
5
|
* Injects a service within the current injection context, using the token provided.
|
|
@@ -63,9 +64,14 @@ export declare function injectAsync<T>(token: Token<T>, options: {
|
|
|
63
64
|
/**
|
|
64
65
|
* A context has a specific container associated to it and allows you to run sync or async code.
|
|
65
66
|
*
|
|
67
|
+
* It also carries the {@link ResolutionChain} of the resolution it belongs to, so that
|
|
68
|
+
* `inject()` and `injectAsync()` calls made by user code continue that chain instead of
|
|
69
|
+
* starting a new one.
|
|
70
|
+
*
|
|
66
71
|
* @internal
|
|
67
72
|
*/
|
|
68
|
-
interface Context {
|
|
73
|
+
export interface Context {
|
|
74
|
+
readonly chain: ResolutionChain;
|
|
69
75
|
run<T>(block: (container: Container) => T): T;
|
|
70
76
|
runAsync<T>(block: (container: Container) => Promise<T>): Promise<T>;
|
|
71
77
|
}
|
|
@@ -74,5 +80,15 @@ interface Context {
|
|
|
74
80
|
*
|
|
75
81
|
* @internal
|
|
76
82
|
*/
|
|
77
|
-
export declare function injectionContext(container: Container): Context;
|
|
78
|
-
|
|
83
|
+
export declare function injectionContext(container: Container, chain?: ResolutionChain): Context;
|
|
84
|
+
/**
|
|
85
|
+
* Returns the resolution chain of the injection context that is currently active, or an
|
|
86
|
+
* empty chain when there is none (i.e., when a resolution is started from user code).
|
|
87
|
+
*
|
|
88
|
+
* Like `inject()` and `injectAsync()`, this must be read synchronously while the context
|
|
89
|
+
* is still active: the context is restored as soon as the current synchronous block
|
|
90
|
+
* returns, so it cannot be read after an `await`.
|
|
91
|
+
*
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
export declare function currentResolutionChain(): ResolutionChain;
|
package/dist/context.js
CHANGED
|
@@ -25,12 +25,17 @@ export function injectAsync(token, options) {
|
|
|
25
25
|
return Promise.reject(error);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* The chain of a resolution that has no parent, i.e., one started from user code.
|
|
30
|
+
*/
|
|
31
|
+
const EMPTY_RESOLUTION_CHAIN = Object.freeze([]);
|
|
28
32
|
/**
|
|
29
33
|
* The global context does not allow dependency injection.
|
|
30
34
|
*
|
|
31
35
|
* @internal
|
|
32
36
|
*/
|
|
33
37
|
class GlobalContext {
|
|
38
|
+
chain = EMPTY_RESOLUTION_CHAIN;
|
|
34
39
|
run() {
|
|
35
40
|
throw new NeedsInjectionContextError();
|
|
36
41
|
}
|
|
@@ -45,8 +50,10 @@ class GlobalContext {
|
|
|
45
50
|
*/
|
|
46
51
|
class InjectionContext {
|
|
47
52
|
container;
|
|
48
|
-
|
|
53
|
+
chain;
|
|
54
|
+
constructor(container, chain) {
|
|
49
55
|
this.container = container;
|
|
56
|
+
this.chain = chain;
|
|
50
57
|
}
|
|
51
58
|
run(block) {
|
|
52
59
|
const originalContext = _currentContext;
|
|
@@ -81,8 +88,21 @@ let _currentContext = new GlobalContext();
|
|
|
81
88
|
*
|
|
82
89
|
* @internal
|
|
83
90
|
*/
|
|
84
|
-
export function injectionContext(container) {
|
|
85
|
-
return new InjectionContext(container);
|
|
91
|
+
export function injectionContext(container, chain = EMPTY_RESOLUTION_CHAIN) {
|
|
92
|
+
return new InjectionContext(container, chain);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Returns the resolution chain of the injection context that is currently active, or an
|
|
96
|
+
* empty chain when there is none (i.e., when a resolution is started from user code).
|
|
97
|
+
*
|
|
98
|
+
* Like `inject()` and `injectAsync()`, this must be read synchronously while the context
|
|
99
|
+
* is still active: the context is restored as soon as the current synchronous block
|
|
100
|
+
* returns, so it cannot be read after an `await`.
|
|
101
|
+
*
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
export function currentResolutionChain() {
|
|
105
|
+
return _currentContext.chain;
|
|
86
106
|
}
|
|
87
107
|
/**
|
|
88
108
|
* An error that occurs when `inject()` or `injectAsync()` is used outside an injection context.
|
|
@@ -91,7 +111,10 @@ export function injectionContext(container) {
|
|
|
91
111
|
*/
|
|
92
112
|
class NeedsInjectionContextError extends Error {
|
|
93
113
|
constructor() {
|
|
94
|
-
super(`You can only invoke inject() or injectAsync() within an injection context`
|
|
114
|
+
super(`You can only invoke inject() or injectAsync() within an injection context. ` +
|
|
115
|
+
`If you entered one using container.runInInjectionContext(), note that it is no longer ` +
|
|
116
|
+
`active after its first await. ` +
|
|
117
|
+
`See https://needle-di.io/concepts/injection.html#running-in-an-injection-context`);
|
|
95
118
|
}
|
|
96
119
|
}
|
|
97
120
|
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/factory.d.ts
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
import { type Provider } from "./providers.ts";
|
|
2
2
|
import { type Token } from "./tokens.ts";
|
|
3
3
|
import { Container } from "./container.ts";
|
|
4
|
+
/**
|
|
5
|
+
* The providers that are currently being constructed, ordered from the root of a
|
|
6
|
+
* resolution down to the provider that is being constructed right now.
|
|
7
|
+
*
|
|
8
|
+
* A chain belongs to a single resolution and is treated as immutable: every nested
|
|
9
|
+
* injection receives its own extended copy. This is what keeps concurrent resolutions
|
|
10
|
+
* isolated. A single mutable stack shared by the whole container would interleave
|
|
11
|
+
* them, and any provider two overlapping resolutions have in common would be reported
|
|
12
|
+
* as a circular dependency.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export type ResolutionChain = readonly Provider<unknown>[];
|
|
17
|
+
/**
|
|
18
|
+
* Asserts that constructing `provider` as the next step of `chain` does not close a
|
|
19
|
+
* cycle, i.e., that the provider does not (transitively) depend on itself.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export declare function assertNoCycle(chain: ResolutionChain, provider: Provider<unknown>): void;
|
|
4
24
|
/**
|
|
5
25
|
* @internal
|
|
6
26
|
*/
|
|
7
27
|
export declare class Factory {
|
|
8
28
|
private readonly container;
|
|
9
|
-
private readonly underConstruction;
|
|
10
29
|
constructor(container: Container);
|
|
11
|
-
construct<T>(provider: Provider<T>, token: Token<T
|
|
12
|
-
constructAsync<T>(provider: Provider<T
|
|
30
|
+
construct<T>(provider: Provider<T>, token: Token<T>, chain: ResolutionChain): T[];
|
|
31
|
+
constructAsync<T>(provider: Provider<T>, chain: ResolutionChain): Promise<T[]>;
|
|
13
32
|
private doConstruct;
|
|
33
|
+
private enter;
|
|
14
34
|
}
|
package/dist/factory.js
CHANGED
|
@@ -4,89 +4,93 @@ import * as Guards from "./providers.js";
|
|
|
4
4
|
import { assertNever, retryOn } from "./utils.js";
|
|
5
5
|
import { Container } from "./container.js";
|
|
6
6
|
import { injectionContext } from "./context.js";
|
|
7
|
+
/**
|
|
8
|
+
* Asserts that constructing `provider` as the next step of `chain` does not close a
|
|
9
|
+
* cycle, i.e., that the provider does not (transitively) depend on itself.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export function assertNoCycle(chain, provider) {
|
|
14
|
+
if (chain.includes(provider)) {
|
|
15
|
+
throw new CircularDependencyError([...chain, provider].map(getToken).map(toString));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns the chain that the dependencies of `provider` should be resolved with.
|
|
20
|
+
* Throws a {@link CircularDependencyError} if `provider` is already part of `chain`.
|
|
21
|
+
*/
|
|
22
|
+
function extend(chain, provider) {
|
|
23
|
+
assertNoCycle(chain, provider);
|
|
24
|
+
return [...chain, provider];
|
|
25
|
+
}
|
|
7
26
|
/**
|
|
8
27
|
* @internal
|
|
9
28
|
*/
|
|
10
29
|
export class Factory {
|
|
11
30
|
container;
|
|
12
|
-
underConstruction = [];
|
|
13
31
|
constructor(container) {
|
|
14
32
|
this.container = container;
|
|
15
33
|
}
|
|
16
|
-
construct(provider, token) {
|
|
34
|
+
construct(provider, token, chain) {
|
|
17
35
|
if (Guards.isAsyncProvider(provider)) {
|
|
18
36
|
throw new AsyncProvidersInSyncInjectionContextError(token);
|
|
19
37
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
38
|
+
return this.doConstruct(provider, extend(chain, provider));
|
|
39
|
+
}
|
|
40
|
+
async constructAsync(provider, chain) {
|
|
41
|
+
// The chain that this provider's own dependencies are resolved with. Since it is a
|
|
42
|
+
// fresh array rather than a shared stack, there is nothing to unwind afterwards:
|
|
43
|
+
// it simply goes out of scope, no matter when (or whether) this construction settles.
|
|
44
|
+
const nested = extend(chain, provider);
|
|
45
|
+
if (Guards.isAsyncProvider(provider)) {
|
|
46
|
+
return [await this.enter(nested).runAsync(() => provider.useFactory(this.container))];
|
|
27
47
|
}
|
|
28
|
-
|
|
29
|
-
|
|
48
|
+
// in class and constructor providers, we allow stuff to be synchronously injected,
|
|
49
|
+
// by just retrying when we encounter an async dependency down the road.
|
|
50
|
+
// todo: this feels like an ugly workaround, so let's create something nice for this.
|
|
51
|
+
if (Guards.isClassProvider(provider) || Guards.isConstructorProvider(provider)) {
|
|
52
|
+
const create = Guards.isConstructorProvider(provider) ? () => [new provider()] : () => [new provider.useClass()];
|
|
53
|
+
return retryOn(AsyncProvidersInSyncInjectionContextError,
|
|
54
|
+
// retries run in a later tick, when the original injection context is no longer
|
|
55
|
+
// active, so each attempt must explicitly (re-)enter the injection context for
|
|
56
|
+
// the field initializers' inject() calls to work.
|
|
57
|
+
async () => this.enter(nested).run(() => create()), async (error) => {
|
|
58
|
+
// Resolving the async dependency is part of this construction, so it has to
|
|
59
|
+
// continue this chain. Entering the context again is what carries it across
|
|
60
|
+
// the tick boundary introduced by the retry.
|
|
61
|
+
await this.enter(nested).runAsync(() => this.container.getAsync(error.token, { multi: true, optional: true }));
|
|
62
|
+
});
|
|
30
63
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (this.underConstruction.includes(provider)) {
|
|
34
|
-
const dependencyGraph = [...this.underConstruction, provider].map(getToken).map(toString);
|
|
35
|
-
throw new CircularDependencyError(dependencyGraph);
|
|
64
|
+
if (Guards.isExistingProvider(provider)) {
|
|
65
|
+
return await this.enter(nested).runAsync(() => this.container.getAsync(provider.useExisting, { multi: true }));
|
|
36
66
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
// all other types of providers are constructed synchronously anyway.
|
|
68
|
+
return this.doConstruct(provider, nested);
|
|
69
|
+
}
|
|
70
|
+
doConstruct(provider, chain) {
|
|
71
|
+
// User code runs inside the injection context, so that the inject() calls it makes
|
|
72
|
+
// resolve from the right container and continue this resolution's chain.
|
|
73
|
+
return this.enter(chain).run(() => {
|
|
74
|
+
if (Guards.isConstructorProvider(provider)) {
|
|
75
|
+
return [new provider()];
|
|
41
76
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// todo: this feels like an ugly workaround, so let's create something nice for this.
|
|
45
|
-
if (Guards.isClassProvider(provider) || Guards.isConstructorProvider(provider)) {
|
|
46
|
-
const create = Guards.isConstructorProvider(provider)
|
|
47
|
-
? () => [new provider()]
|
|
48
|
-
: () => [new provider.useClass()];
|
|
49
|
-
return retryOn(AsyncProvidersInSyncInjectionContextError,
|
|
50
|
-
// retries run in a later tick, when the original injection context is no longer
|
|
51
|
-
// active, so each attempt must explicitly (re-)enter the injection context for
|
|
52
|
-
// the field initializers' inject() calls to work.
|
|
53
|
-
async () => injectionContext(this.container).run(() => create()), async (error) => {
|
|
54
|
-
await this.container.getAsync(error.token, { multi: true, optional: true });
|
|
55
|
-
});
|
|
77
|
+
else if (Guards.isClassProvider(provider)) {
|
|
78
|
+
return [new provider.useClass()];
|
|
56
79
|
}
|
|
57
|
-
if (Guards.
|
|
58
|
-
return
|
|
80
|
+
else if (Guards.isValueProvider(provider)) {
|
|
81
|
+
return [provider.useValue];
|
|
59
82
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
finally {
|
|
64
|
-
// Concurrent async constructions can settle in any order, so `pop()` might remove
|
|
65
|
-
// another in-flight construction's entry and leave our own entry stranded, causing
|
|
66
|
-
// phantom `CircularDependencyError`s on retries. Remove our own entry by identity instead.
|
|
67
|
-
const index = this.underConstruction.lastIndexOf(provider);
|
|
68
|
-
if (index !== -1) {
|
|
69
|
-
this.underConstruction.splice(index, 1);
|
|
83
|
+
else if (Guards.isFactoryProvider(provider)) {
|
|
84
|
+
return [provider.useFactory(this.container)];
|
|
70
85
|
}
|
|
71
|
-
|
|
86
|
+
else if (Guards.isExistingProvider(provider)) {
|
|
87
|
+
return this.container.get(provider.useExisting, { multi: true });
|
|
88
|
+
}
|
|
89
|
+
return assertNever(provider);
|
|
90
|
+
});
|
|
72
91
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return [new provider()];
|
|
76
|
-
}
|
|
77
|
-
else if (Guards.isClassProvider(provider)) {
|
|
78
|
-
return [new provider.useClass()];
|
|
79
|
-
}
|
|
80
|
-
else if (Guards.isValueProvider(provider)) {
|
|
81
|
-
return [provider.useValue];
|
|
82
|
-
}
|
|
83
|
-
else if (Guards.isFactoryProvider(provider)) {
|
|
84
|
-
return [provider.useFactory(this.container)];
|
|
85
|
-
}
|
|
86
|
-
else if (Guards.isExistingProvider(provider)) {
|
|
87
|
-
return this.container.get(provider.useExisting, { multi: true });
|
|
88
|
-
}
|
|
89
|
-
return assertNever(provider);
|
|
92
|
+
enter(chain) {
|
|
93
|
+
return injectionContext(this.container, chain);
|
|
90
94
|
}
|
|
91
95
|
}
|
|
92
96
|
/**
|
package/dist/factory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAc,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Container, bootstrap, bootstrapAsync } from "./container.ts";
|
|
2
2
|
export { inject, injectAsync } from "./context.ts";
|
|
3
3
|
export { injectable } from "./decorators.ts";
|
|
4
|
-
export type { Provider, SyncProvider, AsyncProvider, ExistingProvider, ConstructorProvider, ClassProvider, ValueProvider, FactoryProvider, AsyncFactoryProvider, SyncFactoryProvider, } from "./providers.ts";
|
|
4
|
+
export type { Provider, SyncProvider, AsyncProvider, ExistingProvider, ConstructorProvider, ClassProvider, ValueProvider, FactoryProvider, AsyncFactoryProvider, SyncFactoryProvider, ProviderList, } from "./providers.ts";
|
|
5
|
+
export { defineProviders } from "./providers.ts";
|
|
5
6
|
export { InjectionToken } from "./tokens.ts";
|
|
6
7
|
export type { Token } from "./tokens.ts";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { Container, bootstrap, bootstrapAsync } from "./container.js";
|
|
2
2
|
export { inject, injectAsync } from "./context.js";
|
|
3
3
|
export { injectable } from "./decorators.js";
|
|
4
|
+
export { defineProviders } from "./providers.js";
|
|
4
5
|
export { InjectionToken } from "./tokens.js";
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAc7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/providers.d.ts
CHANGED
|
@@ -72,3 +72,69 @@ export declare function isFactoryProvider<T>(provider: Provider<T>): provider is
|
|
|
72
72
|
export declare function isAsyncProvider<T>(provider: Provider<T>): provider is AsyncProvider<T>;
|
|
73
73
|
export declare function isExistingProvider<T>(provider: Provider<T>): provider is ExistingProvider<T>;
|
|
74
74
|
export declare function isMultiProvider<T>(provider: Provider<T>): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* A single provider, or an arbitrarily nested array of providers.
|
|
77
|
+
*/
|
|
78
|
+
type ProviderNode = Provider<unknown> | readonly ProviderNode[];
|
|
79
|
+
/**
|
|
80
|
+
* Recursively unwraps nested arrays, yielding the union of all leaf types.
|
|
81
|
+
*/
|
|
82
|
+
type ExtractProviders<T> = T extends readonly unknown[] ? ExtractProviders<T[number]> : T;
|
|
83
|
+
/**
|
|
84
|
+
* Every provider variant that is an object literal, i.e. all of them except
|
|
85
|
+
* {@link ConstructorProvider}, which is a class reference.
|
|
86
|
+
*/
|
|
87
|
+
type ObjectProvider<T> = ClassProvider<T> | ValueProvider<T> | SyncFactoryProvider<T> | AsyncFactoryProvider<T> | ExistingProvider<T>;
|
|
88
|
+
/**
|
|
89
|
+
* `keyof` distributed over the members of a union, rather than the keys they have in common.
|
|
90
|
+
*/
|
|
91
|
+
type KeysOfUnion<T> = T extends unknown ? keyof T : never;
|
|
92
|
+
/**
|
|
93
|
+
* Every property name that may appear on an object-based provider.
|
|
94
|
+
*/
|
|
95
|
+
type ProviderKey = KeysOfUnion<ObjectProvider<unknown>>;
|
|
96
|
+
/**
|
|
97
|
+
* Rejects properties that do not exist on any provider, by requiring them to be `never`.
|
|
98
|
+
*
|
|
99
|
+
* TypeScript only applies its built-in excess property check to *fresh* object literals.
|
|
100
|
+
* Since {@link ProviderList} first captures the arguments in an inferred type parameter,
|
|
101
|
+
* that freshness is lost, so the check is reproduced here explicitly.
|
|
102
|
+
*/
|
|
103
|
+
type NoExcessProperties<T> = Record<Exclude<keyof T, ProviderKey>, never>;
|
|
104
|
+
/**
|
|
105
|
+
* Type-checks a single element: either a nested array, or a provider whose value type
|
|
106
|
+
* is correlated with the token it is provided for.
|
|
107
|
+
*/
|
|
108
|
+
type CheckProviderNode<T> = T extends readonly unknown[] ? CheckedProviderList<T> : T extends {
|
|
109
|
+
provide: Token<infer U>;
|
|
110
|
+
} ? Exclude<keyof T, ProviderKey> extends never ? Provider<U> : Provider<U> & NoExcessProperties<T> : Provider<unknown>;
|
|
111
|
+
/**
|
|
112
|
+
* Type-checks every element of an (arbitrarily nested) list of providers.
|
|
113
|
+
*/
|
|
114
|
+
type CheckedProviderList<T extends readonly unknown[]> = {
|
|
115
|
+
[K in keyof T]: CheckProviderNode<T[K]>;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* The list of arguments accepted by {@link Container.bindAll} and {@link defineProviders}:
|
|
119
|
+
* one or more providers, optionally nested in arrays, preserving the correlation between each
|
|
120
|
+
* token and the value it provides.
|
|
121
|
+
*
|
|
122
|
+
* When the given arguments already satisfy this, they are accepted as-is. Otherwise this type
|
|
123
|
+
* resolves to the expected shape, so that TypeScript reports the mismatch on the offending
|
|
124
|
+
* element rather than on the call as a whole.
|
|
125
|
+
*/
|
|
126
|
+
export type ProviderList<T extends readonly unknown[]> = T extends readonly [] ? readonly [ProviderNode] : T extends CheckedProviderList<T> ? T : CheckedProviderList<T>;
|
|
127
|
+
/**
|
|
128
|
+
* Defines a list of providers upfront, outside of a container.
|
|
129
|
+
*
|
|
130
|
+
* Providers may be passed individually or as (nested) arrays, and are returned as a single
|
|
131
|
+
* flattened array. Unlike annotating a variable as `Provider<unknown>[]`, this preserves the
|
|
132
|
+
* correlation between each token and the value it provides.
|
|
133
|
+
*
|
|
134
|
+
* @param providers one or more providers, optionally nested in arrays
|
|
135
|
+
* @returns a flat array containing every given provider
|
|
136
|
+
*
|
|
137
|
+
* {@link https://needle-di.io/concepts/binding.html#defining-providers-upfront}
|
|
138
|
+
*/
|
|
139
|
+
export declare function defineProviders<T extends readonly unknown[]>(...providers: ProviderList<T>): ExtractProviders<T>[];
|
|
140
|
+
export {};
|
package/dist/providers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isClassLike } from "./utils.js";
|
|
1
|
+
import { flattenDeep, isClassLike } from "./utils.js";
|
|
2
2
|
export function isConstructorProvider(provider) {
|
|
3
3
|
return isClassLike(provider);
|
|
4
4
|
}
|
|
@@ -20,4 +20,19 @@ export function isExistingProvider(provider) {
|
|
|
20
20
|
export function isMultiProvider(provider) {
|
|
21
21
|
return "provide" in provider && "multi" in provider && provider.multi === true;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Defines a list of providers upfront, outside of a container.
|
|
25
|
+
*
|
|
26
|
+
* Providers may be passed individually or as (nested) arrays, and are returned as a single
|
|
27
|
+
* flattened array. Unlike annotating a variable as `Provider<unknown>[]`, this preserves the
|
|
28
|
+
* correlation between each token and the value it provides.
|
|
29
|
+
*
|
|
30
|
+
* @param providers one or more providers, optionally nested in arrays
|
|
31
|
+
* @returns a flat array containing every given provider
|
|
32
|
+
*
|
|
33
|
+
* {@link https://needle-di.io/concepts/binding.html#defining-providers-upfront}
|
|
34
|
+
*/
|
|
35
|
+
export function defineProviders(...providers) {
|
|
36
|
+
return flattenDeep(providers);
|
|
37
|
+
}
|
|
23
38
|
//# sourceMappingURL=providers.js.map
|
package/dist/providers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkFlE,MAAM,UAAU,qBAAqB,CAAI,QAAqB;IAC5D,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,eAAe,CAAI,QAAqB;IACtD,OAAO,SAAS,IAAI,QAAQ,IAAI,UAAU,IAAI,QAAQ,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,eAAe,CAAI,QAAqB;IACtD,OAAO,SAAS,IAAI,QAAQ,IAAI,UAAU,IAAI,QAAQ,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAI,QAAqB;IACxD,OAAO,SAAS,IAAI,QAAQ,IAAI,YAAY,IAAI,QAAQ,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,eAAe,CAAI,QAAqB;IACtD,OAAO,iBAAiB,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAI,QAAqB;IACzD,OAAO,SAAS,IAAI,QAAQ,IAAI,aAAa,IAAI,QAAQ,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,eAAe,CAAI,QAAqB;IACtD,OAAO,SAAS,IAAI,QAAQ,IAAI,OAAO,IAAI,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC;AACjF,CAAC;AA6ED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAA+B,GAAG,SAA0B;IACzF,OAAO,WAAW,CAAC,SAA+B,CAAC,CAAC;AACtD,CAAC"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -15,6 +15,12 @@ export declare function isClassLike(target: unknown): target is Class<unknown> |
|
|
|
15
15
|
* @internal
|
|
16
16
|
*/
|
|
17
17
|
export declare function getParentClasses(target: Class<unknown>): Class<unknown>[];
|
|
18
|
+
/**
|
|
19
|
+
* Recursively flattens an arbitrarily nested array into a flat array.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export declare function flattenDeep<T>(values: readonly unknown[]): T[];
|
|
18
24
|
/**
|
|
19
25
|
* Ensures a given value is not null or undefined.
|
|
20
26
|
*
|
|
@@ -55,9 +61,3 @@ export declare function assertNever(_: never): never;
|
|
|
55
61
|
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/try
|
|
56
62
|
*/
|
|
57
63
|
export declare function promiseTry<T>(block: () => T | PromiseLike<T>): Promise<Awaited<T>>;
|
|
58
|
-
/**
|
|
59
|
-
* Simple function that returns a Promise with a certain delay.
|
|
60
|
-
*
|
|
61
|
-
* @internal
|
|
62
|
-
*/
|
|
63
|
-
export declare function delay(delayInMs: number): Promise<void>;
|
package/dist/utils.js
CHANGED
|
@@ -21,6 +21,14 @@ export function getParentClasses(target) {
|
|
|
21
21
|
}
|
|
22
22
|
return parentClasses;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Recursively flattens an arbitrarily nested array into a flat array.
|
|
26
|
+
*
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
export function flattenDeep(values) {
|
|
30
|
+
return values.flat(Infinity);
|
|
31
|
+
}
|
|
24
32
|
/**
|
|
25
33
|
* Ensures a given value is not null or undefined.
|
|
26
34
|
*
|
|
@@ -94,12 +102,4 @@ export function assertNever(_) {
|
|
|
94
102
|
export async function promiseTry(block) {
|
|
95
103
|
return await new Promise((resolve) => resolve(block()));
|
|
96
104
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Simple function that returns a Promise with a certain delay.
|
|
99
|
-
*
|
|
100
|
-
* @internal
|
|
101
|
-
*/
|
|
102
|
-
export function delay(delayInMs) {
|
|
103
|
-
return new Promise((resolve) => setTimeout(resolve, delayInMs));
|
|
104
|
-
}
|
|
105
105
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,OAAO,OAAO,MAAM,KAAK,UAAU,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,MAAM,aAAa,GAAqB,EAAE,CAAC;IAC3C,IAAI,YAAY,GAAG,MAAM,CAAC;IAC1B,OAAO,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,WAAW,GAAmB,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACxE,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChC,YAAY,GAAG,WAAW,CAAC;IAC7B,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAI,KAA2B;IAC1D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AASD,MAAM,UAAU,aAAa,CAAI,KAAU,EAAE,IAAI,GAAG,CAAC;IACnD,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAClB,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAyB,EACzB,KAA6B,EAC7B,OAAyC;IAEzC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC,EAAE,CAAC;gBACnC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAI,KAAU,EAAE,aAA4B;IACtE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,6DAA6D;AAC7D,MAAM,UAAU,WAAW,CAAC,CAAQ;IAClC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAI,KAA+B;IACjE,OAAO,MAAM,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC7D,CAAC
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,OAAO,OAAO,MAAM,KAAK,UAAU,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,MAAM,aAAa,GAAqB,EAAE,CAAC;IAC3C,IAAI,YAAY,GAAG,MAAM,CAAC;IAC1B,OAAO,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,WAAW,GAAmB,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACxE,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChC,YAAY,GAAG,WAAW,CAAC;IAC7B,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAI,MAA0B;IACvD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAQ,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAI,KAA2B;IAC1D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AASD,MAAM,UAAU,aAAa,CAAI,KAAU,EAAE,IAAI,GAAG,CAAC;IACnD,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAClB,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAyB,EACzB,KAA6B,EAC7B,OAAyC;IAEzC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC,EAAE,CAAC;gBACnC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAI,KAAU,EAAE,aAA4B;IACtE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,6DAA6D;AAC7D,MAAM,UAAU,WAAW,CAAC,CAAQ;IAClC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAI,KAA+B;IACjE,OAAO,MAAM,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC7D,CAAC"}
|