atomic-di 0.9.1-beta.2 → 0.9.1-beta.4
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 +226 -0
- package/dist/index.d.mts +50 -1
- package/dist/index.d.ts +50 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# atomic-di
|
2
|
+
|
3
|
+
> **This is not an IoC container or a service locator.**
|
4
|
+
|
5
|
+
This library provides a set of tools that implement missing features such as lifetimes, scopes and mocking in a pure factory-based dependency injection.
|
6
|
+
|
7
|
+
### Key features
|
8
|
+
|
9
|
+
- **Small & fast.** The usage is based on the use of a thin, performant abstraction that wraps factories, adding a couple of operations needed for resolution in a dynamic context.
|
10
|
+
- **Transparent.** All the logic for creating instances is written by the developer himself.
|
11
|
+
- **Non-invasive.** Does not require adding decorators, registrations or any additional logic to the business logic of the application.
|
12
|
+
- **Atomic.** There's no global container. The creation of instances occurs in factories that can be shared among themselves.
|
13
|
+
|
1
14
|
# Installation
|
2
15
|
|
3
16
|
You can use any package manager.
|
@@ -5,10 +18,223 @@ You can use any package manager.
|
|
5
18
|
```bash
|
6
19
|
npm add atomic-di
|
7
20
|
```
|
21
|
+
|
8
22
|
```bash
|
9
23
|
npx jsr add @ensi/di
|
10
24
|
```
|
11
25
|
|
26
|
+
# Usage
|
27
|
+
|
28
|
+
Not written yet.
|
29
|
+
|
30
|
+
# API
|
31
|
+
|
32
|
+
## `Provider`
|
33
|
+
|
34
|
+
```ts
|
35
|
+
type Provider<T> = (context?: ResolutionContext) => T;
|
36
|
+
```
|
37
|
+
|
38
|
+
A function wrapper around the [resolver](#Resolver)(factory) for contextual dependency resolution. Resolves an instance by calling a resolver with an **optional** [resolution context](#ResolutionContext) that will be propagated throughout a dependency tree. Can act as a transient, singleton or scoped, which is [determined by the lifetime](#Lifetime) at creation.
|
39
|
+
|
40
|
+
```ts
|
41
|
+
provider({ scope, mocks });
|
42
|
+
```
|
43
|
+
|
44
|
+
When passing a [scope](#Scope) it will try to get an instance from it or create a new one and put it there.
|
45
|
+
|
46
|
+
When passing [mocks](#MockMap), it will try to get its own mock version and if there is one, it will use it instead of itself.
|
47
|
+
|
48
|
+
### `provide`
|
49
|
+
|
50
|
+
```ts
|
51
|
+
function provide<T>(lifetime: Lifetime, resolver: Resolver<T>): Provider<T>;
|
52
|
+
```
|
53
|
+
|
54
|
+
Creates a provider instance.
|
55
|
+
|
56
|
+
- `lifetime`: A resolution [lifetime](#Lifetime).
|
57
|
+
- `resolver`: A function that creates an instance using a [resolution context](#ResolutionContext). If the function calls other providers, the context **must** be passed to their calls.
|
58
|
+
|
59
|
+
```ts
|
60
|
+
const getInstance = provide("transient", (context) =>
|
61
|
+
createInstance(getOtherInstance(context)),
|
62
|
+
);
|
63
|
+
```
|
64
|
+
|
65
|
+
### `transient`
|
66
|
+
|
67
|
+
```ts
|
68
|
+
function transient<T>(resolver: Resolver<T>): Provider<T>;
|
69
|
+
```
|
70
|
+
|
71
|
+
An alias for [provide](#provide) with `"transient"` lifetime. Creates a [transient](#Lifetime) provider instance.
|
72
|
+
|
73
|
+
```ts
|
74
|
+
const getInstance = transient((context) =>
|
75
|
+
createInstance(...)
|
76
|
+
)
|
77
|
+
|
78
|
+
getInstance() !== getInstance()
|
79
|
+
```
|
80
|
+
|
81
|
+
### `singleton`
|
82
|
+
|
83
|
+
```ts
|
84
|
+
function singleton<T>(resolver: Resolver<T>): Provider<T>;
|
85
|
+
```
|
86
|
+
|
87
|
+
An alias for [provide](#provide) with `"singleton"` lifetime. Creates a [singleton](#Lifetime) provider instance.
|
88
|
+
|
89
|
+
```ts
|
90
|
+
const getInstance = singleton((context) =>
|
91
|
+
createInstance(...)
|
92
|
+
)
|
93
|
+
|
94
|
+
getInstance() === getInstance()
|
95
|
+
```
|
96
|
+
|
97
|
+
### `scoped`
|
98
|
+
|
99
|
+
```ts
|
100
|
+
function scoped<T>(resolver: Resolver<T>): Provider<T>;
|
101
|
+
```
|
102
|
+
|
103
|
+
An alias for [provide](#provide) with `"scoped"` lifetime. Creates a [scoped](#Lifetime) provider instance.
|
104
|
+
|
105
|
+
```ts
|
106
|
+
const getInstance = scoped((context) =>
|
107
|
+
createInstance(...)
|
108
|
+
)
|
109
|
+
|
110
|
+
getInstance() !== getInstance()
|
111
|
+
getInstance({ scope }) === getInstance({ scope })
|
112
|
+
```
|
113
|
+
|
114
|
+
## `Resolver`
|
115
|
+
|
116
|
+
```ts
|
117
|
+
type Resolver<T> = (context?: ResolutionContext) => T;
|
118
|
+
```
|
119
|
+
|
120
|
+
A function that creates an instance using a [resolution context](#ResolutionContext).
|
121
|
+
|
122
|
+
## `Lifetime`
|
123
|
+
|
124
|
+
```ts
|
125
|
+
type Lifetime = "transient" | "singleton" | "scoped";
|
126
|
+
```
|
127
|
+
|
128
|
+
A resolution lifetime. Passed when [creating a provider](#provide) to determine its behaviour.
|
129
|
+
|
130
|
+
- `"transient"` doesn't provide any modifications to a resolver behaviour, so the resolver will create a new instance on each request.
|
131
|
+
- `"singleton"` forces the resolver to create an instance once and return it in subsequent requests.
|
132
|
+
- `"scoped"` forces the resolver to take its instance from a provided [scope](#Scope) or create a new one and save it if there is none. If no scope is passed, it will create a new instance on each request.
|
133
|
+
|
134
|
+
## `ResolutionContext`
|
135
|
+
|
136
|
+
```ts
|
137
|
+
type ResolutionContext = {
|
138
|
+
scope?: Scope;
|
139
|
+
mocks?: MockMap;
|
140
|
+
};
|
141
|
+
```
|
142
|
+
|
143
|
+
An object that holds information about a [scope](#Scope) and provider [mocks](#MockMap). Passed to the [provider call](#Provider) to resolve scope instances and mock providers.
|
144
|
+
|
145
|
+
## `Scope`
|
146
|
+
|
147
|
+
```ts
|
148
|
+
type Scope = Map<Provider<any>, any>;
|
149
|
+
```
|
150
|
+
|
151
|
+
A `Map` of [providers](#Provider) to their instances. Passed to a provider call in a resolution context object to resolve instances of scoped providers within it.
|
152
|
+
|
153
|
+
```ts
|
154
|
+
const scope = createScope();
|
155
|
+
provider({ scope });
|
156
|
+
```
|
157
|
+
|
158
|
+
### `createScope`
|
159
|
+
|
160
|
+
```ts
|
161
|
+
function createScope(): Scope;
|
162
|
+
```
|
163
|
+
|
164
|
+
Creates a scope instance.
|
165
|
+
|
166
|
+
## `MockMap`
|
167
|
+
|
168
|
+
```ts
|
169
|
+
type MockMap = Omit<Map<Provider<any>, Provider<any>>, "set" | "get"> & {
|
170
|
+
set<T>(provider: Provider<T>, mock: Provider<T>): MockMap;
|
171
|
+
get<T>(provider: Provider<T>): Provider<T> | undefined;
|
172
|
+
};
|
173
|
+
```
|
174
|
+
|
175
|
+
A `Map` of [providers](#Provider) to providers of the same type. [Lifetime](#Lifetime) is not a part of `Provider` type, so you can use a different one if necessary. Passed to a provider call in a [resolution context](#ResolutionContext) object in order to replace providers with their mocks.
|
176
|
+
|
177
|
+
```ts
|
178
|
+
const otherProvider =
|
179
|
+
transitive(() => ...)
|
180
|
+
const otherProviderMock: typeof otherProvider =
|
181
|
+
scoped(() => ...)
|
182
|
+
|
183
|
+
const mocks = createMockMap()
|
184
|
+
mocks.set(otherProvider, otherProviderMock)
|
185
|
+
|
186
|
+
provider({ mocks })
|
187
|
+
```
|
188
|
+
|
189
|
+
### `createMockMap`
|
190
|
+
|
191
|
+
```ts
|
192
|
+
function createMockMap(): MockMap;
|
193
|
+
```
|
194
|
+
|
195
|
+
Creates a mock map instance.
|
196
|
+
|
197
|
+
## Bulk resolutions
|
198
|
+
|
199
|
+
### `resolveList`
|
200
|
+
|
201
|
+
```ts
|
202
|
+
function resolveList<const Providers extends ProviderList>(
|
203
|
+
providers: Providers,
|
204
|
+
context?: ResolutionContext,
|
205
|
+
): AwaitAllValuesInCollection<InferProviderCollectionResolutions<Providers>>;
|
206
|
+
```
|
207
|
+
|
208
|
+
- `providers`: A list of providers.
|
209
|
+
- `context`: A resolution context.
|
210
|
+
|
211
|
+
Calls every provider in a list with a provided resolution context and returns a list of resolutions. Returns a promise of a list of awaited resolutions if there's at least one promise in the resolutions.
|
212
|
+
|
213
|
+
```ts
|
214
|
+
const resolutions = resolveList([getA, getB, getC], { scope, mocks });
|
215
|
+
```
|
216
|
+
|
217
|
+
### `resolveMap`
|
218
|
+
|
219
|
+
```ts
|
220
|
+
function resolveMap<const Providers extends ProviderRecord>(
|
221
|
+
providers: Providers,
|
222
|
+
context?: ResolutionContext,
|
223
|
+
): AwaitAllValuesInCollection<InferProviderCollectionResolutions<Providers>>;
|
224
|
+
```
|
225
|
+
|
226
|
+
- `providers`: A map of providers.
|
227
|
+
- `context`: A resolution context.
|
228
|
+
|
229
|
+
Calsl every provider in a map with a provided resolution context and returns a map with identical keys but with resolutions in values instead. Returns a promise of a map of awaited resolutions if there's at least one promise in the resolutions.
|
230
|
+
|
231
|
+
```ts
|
232
|
+
const resolutionMap = resolveMap(
|
233
|
+
{ a: getA, b: getB, c: getC },
|
234
|
+
{ scope, mocks },
|
235
|
+
);
|
236
|
+
```
|
237
|
+
|
12
238
|
# Contribution
|
13
239
|
|
14
240
|
This is free and open source project licensed under the [MIT License](LICENSE). You could help its development by contributing via [pull requests](https://github.com/ncor/atomic-di/fork) or [submitting an issue](https://github.com/ncor/atomic-di/issues).
|
package/dist/index.d.mts
CHANGED
@@ -85,8 +85,11 @@ declare const createScope: () => Scope;
|
|
85
85
|
* A wrapper around the resolver(factory) for contextual dependency resolution.
|
86
86
|
*
|
87
87
|
* Resolves an instance by calling a resolver
|
88
|
-
* with
|
88
|
+
* with an **optional** resolution context that will be propagated
|
89
89
|
* throughout a dependency tree.
|
90
|
+
* ```ts
|
91
|
+
* provider({ scope, mocks })
|
92
|
+
* ```
|
90
93
|
*
|
91
94
|
* When passing a scope it will try to get an instance from it
|
92
95
|
* or create a new one and put it there.
|
@@ -127,6 +130,13 @@ type ResolutionContext = {
|
|
127
130
|
/**
|
128
131
|
* Creates a provider instance,
|
129
132
|
* a wrapper around a resolver(factory) for contextual dependency resolution.
|
133
|
+
* ```ts
|
134
|
+
* const getInstance = provide("transient", () =>
|
135
|
+
* createInstance(
|
136
|
+
* getOtherInstance(context)
|
137
|
+
* )
|
138
|
+
* )
|
139
|
+
* ```
|
130
140
|
*
|
131
141
|
* @param lifetime
|
132
142
|
* A resolution lifetime.
|
@@ -143,14 +153,24 @@ type ResolutionContext = {
|
|
143
153
|
*
|
144
154
|
* @param resolver
|
145
155
|
* The function that creates an instance using a resolution context.
|
156
|
+
* If the function calls other providers,
|
157
|
+
* the context **must** be passed to their calls.
|
146
158
|
*
|
147
159
|
* @returns The provider instance.
|
148
160
|
*/
|
149
161
|
declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>) => Provider<T>;
|
150
162
|
/**
|
163
|
+
* An alias for `provide("transient", ...)`.
|
151
164
|
* Creates a transient provider instance,
|
152
165
|
* a wrapper around a resolver(factory) for contextual dependency resolution
|
153
166
|
* that will create a new instance on each request.
|
167
|
+
* ```ts
|
168
|
+
* const getInstance = transient((context) =>
|
169
|
+
* createInstance(...)
|
170
|
+
* )
|
171
|
+
*
|
172
|
+
* getInstance() !== getInstance()
|
173
|
+
* ```
|
154
174
|
*
|
155
175
|
* @param resolver
|
156
176
|
* The function that creates an instance using a resolution context.
|
@@ -159,9 +179,17 @@ declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>) => Provide
|
|
159
179
|
*/
|
160
180
|
declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
161
181
|
/**
|
182
|
+
* An alias for `provide("singleton", ...)`.
|
162
183
|
* Creates a transient provider instance,
|
163
184
|
* a wrapper around a resolver(factory) for contextual dependency resolution
|
164
185
|
* that will create an instance once and return it in subsequent requests.
|
186
|
+
* ```ts
|
187
|
+
* const getInstance = singleton((context) =>
|
188
|
+
* createInstance(...)
|
189
|
+
* )
|
190
|
+
*
|
191
|
+
* getInstance() === getInstance()
|
192
|
+
* ```
|
165
193
|
*
|
166
194
|
* @param resolver
|
167
195
|
* The function that creates an instance using a resolution context.
|
@@ -170,11 +198,20 @@ declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
|
170
198
|
*/
|
171
199
|
declare const singleton: <T>(resolver: Resolver<T>) => Provider<T>;
|
172
200
|
/**
|
201
|
+
* An alias for `provide("scoped", ...)`.
|
173
202
|
* Creates a transient provider instance,
|
174
203
|
* a wrapper around a resolver(factory) for contextual dependency resolution
|
175
204
|
* that will take its resolution from a provided scope
|
176
205
|
* or create a new one and save it if there is none.
|
177
206
|
* If no scope is passed, it will create a new instance on each request.
|
207
|
+
* ```ts
|
208
|
+
* const getInstance = scoped((context) =>
|
209
|
+
* createInstance(...)
|
210
|
+
* )
|
211
|
+
*
|
212
|
+
* getInstance() !== getInstance()
|
213
|
+
* getInstance({ scope }) === getInstance({ scope })
|
214
|
+
* ```
|
178
215
|
*
|
179
216
|
* @param resolver
|
180
217
|
* The function that creates an instance using a resolution context.
|
@@ -200,6 +237,12 @@ type AwaitAllValuesInCollection<T extends any[] | Record<any, any>> = Promise<an
|
|
200
237
|
* Calls every provider in a list with a provided resolution context
|
201
238
|
* and returns a list of resolutions. Returns a promise of a list
|
202
239
|
* of awaited resolutions if there's at least one promise in the resolutions.
|
240
|
+
* ```ts
|
241
|
+
* const resolutions = resolveList(
|
242
|
+
* [getA, getB, getC],
|
243
|
+
* { scope, mocks }
|
244
|
+
* )
|
245
|
+
* ```
|
203
246
|
*
|
204
247
|
* @param providers - The list of providers.
|
205
248
|
* @param context - The resolution context.
|
@@ -212,6 +255,12 @@ declare const resolveList: <const Providers extends ProviderList>(providers: Pro
|
|
212
255
|
* and returns a map with identical keys but with resolutions in values instead.
|
213
256
|
* Returns a promise of a map of awaited resolutions if there's at least one
|
214
257
|
* promise in the resolutions.
|
258
|
+
* ```ts
|
259
|
+
* const resolutionMap = resolveMap(
|
260
|
+
* { a: getA, b: getB, c: getC },
|
261
|
+
* { scope, mocks }
|
262
|
+
* )
|
263
|
+
* ```
|
215
264
|
*
|
216
265
|
* @param providers - The map of providers.
|
217
266
|
* @param context - The resolution context.
|
package/dist/index.d.ts
CHANGED
@@ -85,8 +85,11 @@ declare const createScope: () => Scope;
|
|
85
85
|
* A wrapper around the resolver(factory) for contextual dependency resolution.
|
86
86
|
*
|
87
87
|
* Resolves an instance by calling a resolver
|
88
|
-
* with
|
88
|
+
* with an **optional** resolution context that will be propagated
|
89
89
|
* throughout a dependency tree.
|
90
|
+
* ```ts
|
91
|
+
* provider({ scope, mocks })
|
92
|
+
* ```
|
90
93
|
*
|
91
94
|
* When passing a scope it will try to get an instance from it
|
92
95
|
* or create a new one and put it there.
|
@@ -127,6 +130,13 @@ type ResolutionContext = {
|
|
127
130
|
/**
|
128
131
|
* Creates a provider instance,
|
129
132
|
* a wrapper around a resolver(factory) for contextual dependency resolution.
|
133
|
+
* ```ts
|
134
|
+
* const getInstance = provide("transient", () =>
|
135
|
+
* createInstance(
|
136
|
+
* getOtherInstance(context)
|
137
|
+
* )
|
138
|
+
* )
|
139
|
+
* ```
|
130
140
|
*
|
131
141
|
* @param lifetime
|
132
142
|
* A resolution lifetime.
|
@@ -143,14 +153,24 @@ type ResolutionContext = {
|
|
143
153
|
*
|
144
154
|
* @param resolver
|
145
155
|
* The function that creates an instance using a resolution context.
|
156
|
+
* If the function calls other providers,
|
157
|
+
* the context **must** be passed to their calls.
|
146
158
|
*
|
147
159
|
* @returns The provider instance.
|
148
160
|
*/
|
149
161
|
declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>) => Provider<T>;
|
150
162
|
/**
|
163
|
+
* An alias for `provide("transient", ...)`.
|
151
164
|
* Creates a transient provider instance,
|
152
165
|
* a wrapper around a resolver(factory) for contextual dependency resolution
|
153
166
|
* that will create a new instance on each request.
|
167
|
+
* ```ts
|
168
|
+
* const getInstance = transient((context) =>
|
169
|
+
* createInstance(...)
|
170
|
+
* )
|
171
|
+
*
|
172
|
+
* getInstance() !== getInstance()
|
173
|
+
* ```
|
154
174
|
*
|
155
175
|
* @param resolver
|
156
176
|
* The function that creates an instance using a resolution context.
|
@@ -159,9 +179,17 @@ declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>) => Provide
|
|
159
179
|
*/
|
160
180
|
declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
161
181
|
/**
|
182
|
+
* An alias for `provide("singleton", ...)`.
|
162
183
|
* Creates a transient provider instance,
|
163
184
|
* a wrapper around a resolver(factory) for contextual dependency resolution
|
164
185
|
* that will create an instance once and return it in subsequent requests.
|
186
|
+
* ```ts
|
187
|
+
* const getInstance = singleton((context) =>
|
188
|
+
* createInstance(...)
|
189
|
+
* )
|
190
|
+
*
|
191
|
+
* getInstance() === getInstance()
|
192
|
+
* ```
|
165
193
|
*
|
166
194
|
* @param resolver
|
167
195
|
* The function that creates an instance using a resolution context.
|
@@ -170,11 +198,20 @@ declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
|
170
198
|
*/
|
171
199
|
declare const singleton: <T>(resolver: Resolver<T>) => Provider<T>;
|
172
200
|
/**
|
201
|
+
* An alias for `provide("scoped", ...)`.
|
173
202
|
* Creates a transient provider instance,
|
174
203
|
* a wrapper around a resolver(factory) for contextual dependency resolution
|
175
204
|
* that will take its resolution from a provided scope
|
176
205
|
* or create a new one and save it if there is none.
|
177
206
|
* If no scope is passed, it will create a new instance on each request.
|
207
|
+
* ```ts
|
208
|
+
* const getInstance = scoped((context) =>
|
209
|
+
* createInstance(...)
|
210
|
+
* )
|
211
|
+
*
|
212
|
+
* getInstance() !== getInstance()
|
213
|
+
* getInstance({ scope }) === getInstance({ scope })
|
214
|
+
* ```
|
178
215
|
*
|
179
216
|
* @param resolver
|
180
217
|
* The function that creates an instance using a resolution context.
|
@@ -200,6 +237,12 @@ type AwaitAllValuesInCollection<T extends any[] | Record<any, any>> = Promise<an
|
|
200
237
|
* Calls every provider in a list with a provided resolution context
|
201
238
|
* and returns a list of resolutions. Returns a promise of a list
|
202
239
|
* of awaited resolutions if there's at least one promise in the resolutions.
|
240
|
+
* ```ts
|
241
|
+
* const resolutions = resolveList(
|
242
|
+
* [getA, getB, getC],
|
243
|
+
* { scope, mocks }
|
244
|
+
* )
|
245
|
+
* ```
|
203
246
|
*
|
204
247
|
* @param providers - The list of providers.
|
205
248
|
* @param context - The resolution context.
|
@@ -212,6 +255,12 @@ declare const resolveList: <const Providers extends ProviderList>(providers: Pro
|
|
212
255
|
* and returns a map with identical keys but with resolutions in values instead.
|
213
256
|
* Returns a promise of a map of awaited resolutions if there's at least one
|
214
257
|
* promise in the resolutions.
|
258
|
+
* ```ts
|
259
|
+
* const resolutionMap = resolveMap(
|
260
|
+
* { a: getA, b: getB, c: getC },
|
261
|
+
* { scope, mocks }
|
262
|
+
* )
|
263
|
+
* ```
|
215
264
|
*
|
216
265
|
* @param providers - The map of providers.
|
217
266
|
* @param context - The resolution context.
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/helpers.ts","../src/provider.ts","../src/scope.ts","../src/mock-map.ts","../src/collection-resolution.ts"],"sourcesContent":["export * from \"./provider\";\nexport * from \"./scope\";\nexport * from \"./mock-map\";\nexport * from \"./collection-resolution\";\n","/**\n * Creates a function that will invoke the provided function `fn` only once,\n * caching the result for subsequent calls with the same arguments.\n *\n * @returns A new function that returns the cached result after the first call.\n */\nexport const once = <A extends any[], R>(\n /**\n * The function to invoke once and cache the result.\n */\n fn: (...args: A) => R,\n) => {\n let returned = false;\n let result: R | undefined;\n\n return Object.assign((...args: A): R => {\n if (returned) return result!;\n\n result = fn(...args);\n returned = true;\n\n return result;\n }, fn);\n};\n","import { once } from \"./helpers\";\nimport { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A wrapper around the resolver(factory) for contextual dependency resolution.\n *\n * Resolves an instance by calling a resolver\n * with a resolution context that will be propagated\n * throughout a dependency tree.\n *\n * When passing a scope it will try to get an instance from it\n * or create a new one and put it there.\n *\n * When passing mocks, it will try to get its own mock version,\n * and if there is one, it will use it instead of itself.\n */\nexport type Provider<T> = (context?: ResolutionContext) => T;\n\n/**\n * A resolution lifetime.\n *\n * Passed when creating a provider to determine its behavior.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its instance from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n */\nexport type Lifetime = \"transient\" | \"singleton\" | \"scoped\";\n\n/**\n * A function that creates an instance using a resolution context.\n */\nexport type Resolver<T> = (context?: ResolutionContext) => T;\n\n/**\n * An object that holds information about a scope and provider mocks.\n *\n * Passed to the provider call to resolve scope instances and mock providers.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Creates a provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution.\n *\n * @param lifetime\n * A resolution lifetime.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The provider instance.\n */\nexport const provide = <T>(\n lifetime: Lifetime,\n resolver: Resolver<T>,\n): Provider<T> => {\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: Provider<T> = (context) => {\n const maybeOwnMock = context?.mocks?.get(resolve);\n if (maybeOwnMock) return maybeOwnMock(context);\n\n if (lifetime !== \"scoped\" || !context?.scope) return resolver(context);\n\n const resolution = context.scope.has(resolve)\n ? context.scope.get(resolve)\n : resolver(context);\n context.scope.set(resolve, resolution);\n\n return resolution;\n };\n\n return resolve;\n};\n\n/**\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The transient provider instance.\n */\nexport const transient = <T>(resolver: Resolver<T>) =>\n provide(\"transient\", resolver);\n\n/**\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create an instance once and return it in subsequent requests.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The singleton provider instance.\n */\nexport const singleton = <T>(resolver: Resolver<T>) =>\n provide(\"singleton\", resolver);\n\n/**\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The scoped provider instance.\n */\nexport const scoped = <T>(resolver: Resolver<T>) => provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to their instances.\n *\n * Passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n */\nexport type Scope = Map<Provider<any>, any>;\n\n/**\n * Creates a scope instance.\n *\n * Scope is passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n *\n * @returns The scope instance.\n */\nexport const createScope = (): Scope => new Map();\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n */\nexport type MockMap = Omit<Map<Provider<any>, Provider<any>>, \"set\" | \"get\"> & {\n /**\n * Sets a mock for a provider.\n *\n * @param provider - The original provider.\n * @param mock - The mock provider.\n */\n set<T>(provider: Provider<T>, mock: Provider<T>): MockMap;\n /**\n * Retrieves a mock of a provider. Returns undefined if there's none.\n *\n * @param provider - The provider.\n */\n get<T>(provider: Provider<T>): Provider<T> | undefined;\n};\n\n/**\n * Creates a mock map instance,\n * a map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n *\n * @returns The mock map instance.\n */\nexport const createMockMap = (): MockMap => new Map();\n","import { Provider, ResolutionContext } from \"./provider\";\n\ntype ProviderList = Provider<any>[];\ntype ProviderRecord = Record<string, Provider<any>>;\n\ntype InferProviderCollectionResolutions<\n Providers extends ProviderList | ProviderRecord,\n> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\n/**\n * Awaits all promises and wraps the collection in a promise\n * if there'ss at least one `Promise` in the collection,\n * otherwise returns an untouched type.\n */\ntype AwaitAllValuesInCollection<T extends any[] | Record<any, any>> =\n Promise<any> extends T[keyof T]\n ? Promise<{\n [I in keyof T]: T[I] extends Promise<infer T> ? T : T[I];\n }>\n : T;\n\n/**\n * Calls every provider in a list with a provided resolution context\n * and returns a list of resolutions. Returns a promise of a list\n * of awaited resolutions if there's at least one promise in the resolutions.\n *\n * @param providers - The list of providers.\n * @param context - The resolution context.\n *\n * @returns The list of resolutions.\n */\nexport const resolveList = <const Providers extends ProviderList>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutions = providers.map((provider) => provider(context));\n\n return (\n resolutions.some((resolution) => resolution instanceof Promise)\n ? Promise.all(resolutions)\n : resolutions\n ) as any;\n};\n\n/**\n * Calls every provider in a map with a provided resolution context\n * and returns a map with identical keys but with resolutions in values instead.\n * Returns a promise of a map of awaited resolutions if there's at least one\n * promise in the resolutions.\n *\n * @param providers - The map of providers.\n * @param context - The resolution context.\n *\n * @returns The map of resolutions.\n */\nexport const resolveMap = <const Providers extends ProviderRecord>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n let resolutionMapEntries = Object.entries(providers).map(\n ([key, provider]) => [key, provider(context)],\n );\n\n if (\n resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n )\n ) {\n return (async () => {\n resolutionMapEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n\n return Object.fromEntries(resolutionMapEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMO,IAAM,OAAO,CAIhB,OACC;AACD,MAAI,WAAW;AACf,MAAI;AAEJ,SAAO,OAAO,OAAO,IAAI,SAAe;AACpC,QAAI,SAAU,QAAO;AAErB,aAAS,GAAG,GAAG,IAAI;AACnB,eAAW;AAEX,WAAO;AAAA,EACX,GAAG,EAAE;AACT;;;ACkDO,IAAM,UAAU,CACnB,UACA,aACc;AACd,aAAW,aAAa,cAAc,KAAK,QAAQ,IAAI;AAEvD,QAAM,UAAuB,CAAC,YAAY;AA/E9C;AAgFQ,UAAM,gBAAe,wCAAS,UAAT,mBAAgB,IAAI;AACzC,QAAI,aAAc,QAAO,aAAa,OAAO;AAE7C,QAAI,aAAa,YAAY,EAAC,mCAAS,OAAO,QAAO,SAAS,OAAO;AAErE,UAAM,aAAa,QAAQ,MAAM,IAAI,OAAO,IACtC,QAAQ,MAAM,IAAI,OAAO,IACzB,SAAS,OAAO;AACtB,YAAQ,MAAM,IAAI,SAAS,UAAU;AAErC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAYO,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAY1B,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAc1B,IAAM,SAAS,CAAI,aAA0B,QAAQ,UAAU,QAAQ;;;AC5GvE,IAAM,cAAc,MAAa,oBAAI,IAAI;;;ACiCzC,IAAM,gBAAgB,MAAe,oBAAI,IAAI;;;AC1B7C,IAAM,cAAc,CACvB,WACA,YAGC;AACD,QAAM,cAAc,UAAU,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAEjE,SACI,YAAY,KAAK,CAAC,eAAe,sBAAsB,OAAO,IACxD,QAAQ,IAAI,WAAW,IACvB;AAEd;AAaO,IAAM,aAAa,CACtB,WACA,YAGC;AACD,MAAI,uBAAuB,OAAO,QAAQ,SAAS,EAAE;AAAA,IACjD,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,OAAO,CAAC;AAAA,EAChD;AAEA,MACI,qBAAqB;AAAA,IACjB,CAAC,CAAC,EAAE,UAAU,MAAM,sBAAsB;AAAA,EAC9C,GACF;AACE,YAAQ,YAAY;AAChB,6BAAuB,MAAM,QAAQ;AAAA,QACjC,qBAAqB,IAAI,OAAO,CAAC,KAAK,UAAU,MAAM;AAAA,UAClD;AAAA,UACA,MAAM;AAAA,QACV,CAAC;AAAA,MACL;AAEA,aAAO,OAAO,YAAY,oBAAoB;AAAA,IAClD,GAAG;AAAA,EACP;AAEA,SAAO,OAAO,YAAY,oBAAoB;AAClD;","names":[]}
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/helpers.ts","../src/provider.ts","../src/scope.ts","../src/mock-map.ts","../src/collection-resolution.ts"],"sourcesContent":["export * from \"./provider\";\nexport * from \"./scope\";\nexport * from \"./mock-map\";\nexport * from \"./collection-resolution\";\n","/**\n * Creates a function that will invoke the provided function `fn` only once,\n * caching the result for subsequent calls with the same arguments.\n *\n * @param fn - The function to invoke once and cache the result.\n *\n * @returns A new function that returns the cached result after the first call.\n */\nexport const once = <A extends any[], R>(fn: (...args: A) => R) => {\n let returned = false;\n let result: R | undefined;\n\n return Object.assign((...args: A): R => {\n if (returned) return result!;\n\n result = fn(...args);\n returned = true;\n\n return result;\n }, fn);\n};\n","import { once } from \"./helpers\";\nimport { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A wrapper around the resolver(factory) for contextual dependency resolution.\n *\n * Resolves an instance by calling a resolver\n * with an **optional** resolution context that will be propagated\n * throughout a dependency tree.\n * ```ts\n * provider({ scope, mocks })\n * ```\n *\n * When passing a scope it will try to get an instance from it\n * or create a new one and put it there.\n *\n * When passing mocks, it will try to get its own mock version,\n * and if there is one, it will use it instead of itself.\n */\nexport type Provider<T> = (context?: ResolutionContext) => T;\n\n/**\n * A resolution lifetime.\n *\n * Passed when creating a provider to determine its behavior.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its instance from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n */\nexport type Lifetime = \"transient\" | \"singleton\" | \"scoped\";\n\n/**\n * A function that creates an instance using a resolution context.\n */\nexport type Resolver<T> = (context?: ResolutionContext) => T;\n\n/**\n * An object that holds information about a scope and provider mocks.\n *\n * Passed to the provider call to resolve scope instances and mock providers.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Creates a provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution.\n * ```ts\n * const getInstance = provide(\"transient\", () =>\n * createInstance(\n * getOtherInstance(context)\n * )\n * )\n * ```\n *\n * @param lifetime\n * A resolution lifetime.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n * If the function calls other providers,\n * the context **must** be passed to their calls.\n *\n * @returns The provider instance.\n */\nexport const provide = <T>(\n lifetime: Lifetime,\n resolver: Resolver<T>,\n): Provider<T> => {\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: Provider<T> = (context) => {\n const maybeOwnMock = context?.mocks?.get(resolve);\n if (maybeOwnMock) return maybeOwnMock(context);\n\n if (lifetime !== \"scoped\" || !context?.scope) return resolver(context);\n\n const resolution = context.scope.has(resolve)\n ? context.scope.get(resolve)\n : resolver(context);\n context.scope.set(resolve, resolution);\n\n return resolution;\n };\n\n return resolve;\n};\n\n/**\n * An alias for `provide(\"transient\", ...)`.\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create a new instance on each request.\n * ```ts\n * const getInstance = transient((context) =>\n * createInstance(...)\n * )\n *\n * getInstance() !== getInstance()\n * ```\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The transient provider instance.\n */\nexport const transient = <T>(resolver: Resolver<T>): Provider<T> =>\n provide(\"transient\", resolver);\n\n/**\n * An alias for `provide(\"singleton\", ...)`.\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create an instance once and return it in subsequent requests.\n * ```ts\n * const getInstance = singleton((context) =>\n * createInstance(...)\n * )\n *\n * getInstance() === getInstance()\n * ```\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The singleton provider instance.\n */\nexport const singleton = <T>(resolver: Resolver<T>): Provider<T> =>\n provide(\"singleton\", resolver);\n\n/**\n * An alias for `provide(\"scoped\", ...)`.\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n * ```ts\n * const getInstance = scoped((context) =>\n * createInstance(...)\n * )\n *\n * getInstance() !== getInstance()\n * getInstance({ scope }) === getInstance({ scope })\n * ```\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The scoped provider instance.\n */\nexport const scoped = <T>(resolver: Resolver<T>): Provider<T> =>\n provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to their instances.\n *\n * Passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n */\nexport type Scope = Map<Provider<any>, any>;\n\n/**\n * Creates a scope instance.\n *\n * Scope is passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n *\n * @returns The scope instance.\n */\nexport const createScope = (): Scope => new Map();\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n */\nexport type MockMap = Omit<Map<Provider<any>, Provider<any>>, \"set\" | \"get\"> & {\n /**\n * Sets a mock for a provider.\n *\n * @param provider - The original provider.\n * @param mock - The mock provider.\n */\n set<T>(provider: Provider<T>, mock: Provider<T>): MockMap;\n /**\n * Retrieves a mock of a provider. Returns undefined if there's none.\n *\n * @param provider - The provider.\n */\n get<T>(provider: Provider<T>): Provider<T> | undefined;\n};\n\n/**\n * Creates a mock map instance,\n * a map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n *\n * @returns The mock map instance.\n */\nexport const createMockMap = (): MockMap => new Map();\n","import { Provider, ResolutionContext } from \"./provider\";\n\ntype ProviderList = Provider<any>[];\ntype ProviderRecord = Record<string, Provider<any>>;\n\ntype InferProviderCollectionResolutions<\n Providers extends ProviderList | ProviderRecord,\n> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\n/**\n * Awaits all promises and wraps the collection in a promise\n * if there'ss at least one `Promise` in the collection,\n * otherwise returns an untouched type.\n */\ntype AwaitAllValuesInCollection<T extends any[] | Record<any, any>> =\n Promise<any> extends T[keyof T]\n ? Promise<{\n [I in keyof T]: T[I] extends Promise<infer T> ? T : T[I];\n }>\n : T;\n\n/**\n * Calls every provider in a list with a provided resolution context\n * and returns a list of resolutions. Returns a promise of a list\n * of awaited resolutions if there's at least one promise in the resolutions.\n * ```ts\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope, mocks }\n * )\n * ```\n *\n * @param providers - The list of providers.\n * @param context - The resolution context.\n *\n * @returns The list of resolutions.\n */\nexport const resolveList = <const Providers extends ProviderList>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutions = providers.map((provider) => provider(context));\n\n return (\n resolutions.some((resolution) => resolution instanceof Promise)\n ? Promise.all(resolutions)\n : resolutions\n ) as any;\n};\n\n/**\n * Calls every provider in a map with a provided resolution context\n * and returns a map with identical keys but with resolutions in values instead.\n * Returns a promise of a map of awaited resolutions if there's at least one\n * promise in the resolutions.\n * ```ts\n * const resolutionMap = resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope, mocks }\n * )\n * ```\n *\n * @param providers - The map of providers.\n * @param context - The resolution context.\n *\n * @returns The map of resolutions.\n */\nexport const resolveMap = <const Providers extends ProviderRecord>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n let resolutionMapEntries = Object.entries(providers).map(\n ([key, provider]) => [key, provider(context)],\n );\n\n if (\n resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n )\n ) {\n return (async () => {\n resolutionMapEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n\n return Object.fromEntries(resolutionMapEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,OAAO,CAAqB,OAA0B;AAC/D,MAAI,WAAW;AACf,MAAI;AAEJ,SAAO,OAAO,OAAO,IAAI,SAAe;AACpC,QAAI,SAAU,QAAO;AAErB,aAAS,GAAG,GAAG,IAAI;AACnB,eAAW;AAEX,WAAO;AAAA,EACX,GAAG,EAAE;AACT;;;ACiEO,IAAM,UAAU,CACnB,UACA,aACc;AACd,aAAW,aAAa,cAAc,KAAK,QAAQ,IAAI;AAEvD,QAAM,UAAuB,CAAC,YAAY;AA3F9C;AA4FQ,UAAM,gBAAe,wCAAS,UAAT,mBAAgB,IAAI;AACzC,QAAI,aAAc,QAAO,aAAa,OAAO;AAE7C,QAAI,aAAa,YAAY,EAAC,mCAAS,OAAO,QAAO,SAAS,OAAO;AAErE,UAAM,aAAa,QAAQ,MAAM,IAAI,OAAO,IACtC,QAAQ,MAAM,IAAI,OAAO,IACzB,SAAS,OAAO;AACtB,YAAQ,MAAM,IAAI,SAAS,UAAU;AAErC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAoBO,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAoB1B,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAuB1B,IAAM,SAAS,CAAI,aACtB,QAAQ,UAAU,QAAQ;;;AClJvB,IAAM,cAAc,MAAa,oBAAI,IAAI;;;ACiCzC,IAAM,gBAAgB,MAAe,oBAAI,IAAI;;;ACpB7C,IAAM,cAAc,CACvB,WACA,YAGC;AACD,QAAM,cAAc,UAAU,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAEjE,SACI,YAAY,KAAK,CAAC,eAAe,sBAAsB,OAAO,IACxD,QAAQ,IAAI,WAAW,IACvB;AAEd;AAmBO,IAAM,aAAa,CACtB,WACA,YAGC;AACD,MAAI,uBAAuB,OAAO,QAAQ,SAAS,EAAE;AAAA,IACjD,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,OAAO,CAAC;AAAA,EAChD;AAEA,MACI,qBAAqB;AAAA,IACjB,CAAC,CAAC,EAAE,UAAU,MAAM,sBAAsB;AAAA,EAC9C,GACF;AACE,YAAQ,YAAY;AAChB,6BAAuB,MAAM,QAAQ;AAAA,QACjC,qBAAqB,IAAI,OAAO,CAAC,KAAK,UAAU,MAAM;AAAA,UAClD;AAAA,UACA,MAAM;AAAA,QACV,CAAC;AAAA,MACL;AAEA,aAAO,OAAO,YAAY,oBAAoB;AAAA,IAClD,GAAG;AAAA,EACP;AAEA,SAAO,OAAO,YAAY,oBAAoB;AAClD;","names":[]}
|
package/dist/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/helpers.ts","../src/provider.ts","../src/scope.ts","../src/mock-map.ts","../src/collection-resolution.ts"],"sourcesContent":["/**\n * Creates a function that will invoke the provided function `fn` only once,\n * caching the result for subsequent calls with the same arguments.\n *\n * @returns A new function that returns the cached result after the first call.\n */\nexport const once = <A extends any[], R>(\n /**\n * The function to invoke once and cache the result.\n */\n fn: (...args: A) => R,\n) => {\n let returned = false;\n let result: R | undefined;\n\n return Object.assign((...args: A): R => {\n if (returned) return result!;\n\n result = fn(...args);\n returned = true;\n\n return result;\n }, fn);\n};\n","import { once } from \"./helpers\";\nimport { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A wrapper around the resolver(factory) for contextual dependency resolution.\n *\n * Resolves an instance by calling a resolver\n * with a resolution context that will be propagated\n * throughout a dependency tree.\n *\n * When passing a scope it will try to get an instance from it\n * or create a new one and put it there.\n *\n * When passing mocks, it will try to get its own mock version,\n * and if there is one, it will use it instead of itself.\n */\nexport type Provider<T> = (context?: ResolutionContext) => T;\n\n/**\n * A resolution lifetime.\n *\n * Passed when creating a provider to determine its behavior.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its instance from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n */\nexport type Lifetime = \"transient\" | \"singleton\" | \"scoped\";\n\n/**\n * A function that creates an instance using a resolution context.\n */\nexport type Resolver<T> = (context?: ResolutionContext) => T;\n\n/**\n * An object that holds information about a scope and provider mocks.\n *\n * Passed to the provider call to resolve scope instances and mock providers.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Creates a provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution.\n *\n * @param lifetime\n * A resolution lifetime.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The provider instance.\n */\nexport const provide = <T>(\n lifetime: Lifetime,\n resolver: Resolver<T>,\n): Provider<T> => {\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: Provider<T> = (context) => {\n const maybeOwnMock = context?.mocks?.get(resolve);\n if (maybeOwnMock) return maybeOwnMock(context);\n\n if (lifetime !== \"scoped\" || !context?.scope) return resolver(context);\n\n const resolution = context.scope.has(resolve)\n ? context.scope.get(resolve)\n : resolver(context);\n context.scope.set(resolve, resolution);\n\n return resolution;\n };\n\n return resolve;\n};\n\n/**\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The transient provider instance.\n */\nexport const transient = <T>(resolver: Resolver<T>) =>\n provide(\"transient\", resolver);\n\n/**\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create an instance once and return it in subsequent requests.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The singleton provider instance.\n */\nexport const singleton = <T>(resolver: Resolver<T>) =>\n provide(\"singleton\", resolver);\n\n/**\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The scoped provider instance.\n */\nexport const scoped = <T>(resolver: Resolver<T>) => provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to their instances.\n *\n * Passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n */\nexport type Scope = Map<Provider<any>, any>;\n\n/**\n * Creates a scope instance.\n *\n * Scope is passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n *\n * @returns The scope instance.\n */\nexport const createScope = (): Scope => new Map();\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n */\nexport type MockMap = Omit<Map<Provider<any>, Provider<any>>, \"set\" | \"get\"> & {\n /**\n * Sets a mock for a provider.\n *\n * @param provider - The original provider.\n * @param mock - The mock provider.\n */\n set<T>(provider: Provider<T>, mock: Provider<T>): MockMap;\n /**\n * Retrieves a mock of a provider. Returns undefined if there's none.\n *\n * @param provider - The provider.\n */\n get<T>(provider: Provider<T>): Provider<T> | undefined;\n};\n\n/**\n * Creates a mock map instance,\n * a map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n *\n * @returns The mock map instance.\n */\nexport const createMockMap = (): MockMap => new Map();\n","import { Provider, ResolutionContext } from \"./provider\";\n\ntype ProviderList = Provider<any>[];\ntype ProviderRecord = Record<string, Provider<any>>;\n\ntype InferProviderCollectionResolutions<\n Providers extends ProviderList | ProviderRecord,\n> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\n/**\n * Awaits all promises and wraps the collection in a promise\n * if there'ss at least one `Promise` in the collection,\n * otherwise returns an untouched type.\n */\ntype AwaitAllValuesInCollection<T extends any[] | Record<any, any>> =\n Promise<any> extends T[keyof T]\n ? Promise<{\n [I in keyof T]: T[I] extends Promise<infer T> ? T : T[I];\n }>\n : T;\n\n/**\n * Calls every provider in a list with a provided resolution context\n * and returns a list of resolutions. Returns a promise of a list\n * of awaited resolutions if there's at least one promise in the resolutions.\n *\n * @param providers - The list of providers.\n * @param context - The resolution context.\n *\n * @returns The list of resolutions.\n */\nexport const resolveList = <const Providers extends ProviderList>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutions = providers.map((provider) => provider(context));\n\n return (\n resolutions.some((resolution) => resolution instanceof Promise)\n ? Promise.all(resolutions)\n : resolutions\n ) as any;\n};\n\n/**\n * Calls every provider in a map with a provided resolution context\n * and returns a map with identical keys but with resolutions in values instead.\n * Returns a promise of a map of awaited resolutions if there's at least one\n * promise in the resolutions.\n *\n * @param providers - The map of providers.\n * @param context - The resolution context.\n *\n * @returns The map of resolutions.\n */\nexport const resolveMap = <const Providers extends ProviderRecord>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n let resolutionMapEntries = Object.entries(providers).map(\n ([key, provider]) => [key, provider(context)],\n );\n\n if (\n resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n )\n ) {\n return (async () => {\n resolutionMapEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n\n return Object.fromEntries(resolutionMapEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":";AAMO,IAAM,OAAO,CAIhB,OACC;AACD,MAAI,WAAW;AACf,MAAI;AAEJ,SAAO,OAAO,OAAO,IAAI,SAAe;AACpC,QAAI,SAAU,QAAO;AAErB,aAAS,GAAG,GAAG,IAAI;AACnB,eAAW;AAEX,WAAO;AAAA,EACX,GAAG,EAAE;AACT;;;ACkDO,IAAM,UAAU,CACnB,UACA,aACc;AACd,aAAW,aAAa,cAAc,KAAK,QAAQ,IAAI;AAEvD,QAAM,UAAuB,CAAC,YAAY;AA/E9C;AAgFQ,UAAM,gBAAe,wCAAS,UAAT,mBAAgB,IAAI;AACzC,QAAI,aAAc,QAAO,aAAa,OAAO;AAE7C,QAAI,aAAa,YAAY,EAAC,mCAAS,OAAO,QAAO,SAAS,OAAO;AAErE,UAAM,aAAa,QAAQ,MAAM,IAAI,OAAO,IACtC,QAAQ,MAAM,IAAI,OAAO,IACzB,SAAS,OAAO;AACtB,YAAQ,MAAM,IAAI,SAAS,UAAU;AAErC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAYO,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAY1B,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAc1B,IAAM,SAAS,CAAI,aAA0B,QAAQ,UAAU,QAAQ;;;AC5GvE,IAAM,cAAc,MAAa,oBAAI,IAAI;;;ACiCzC,IAAM,gBAAgB,MAAe,oBAAI,IAAI;;;AC1B7C,IAAM,cAAc,CACvB,WACA,YAGC;AACD,QAAM,cAAc,UAAU,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAEjE,SACI,YAAY,KAAK,CAAC,eAAe,sBAAsB,OAAO,IACxD,QAAQ,IAAI,WAAW,IACvB;AAEd;AAaO,IAAM,aAAa,CACtB,WACA,YAGC;AACD,MAAI,uBAAuB,OAAO,QAAQ,SAAS,EAAE;AAAA,IACjD,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,OAAO,CAAC;AAAA,EAChD;AAEA,MACI,qBAAqB;AAAA,IACjB,CAAC,CAAC,EAAE,UAAU,MAAM,sBAAsB;AAAA,EAC9C,GACF;AACE,YAAQ,YAAY;AAChB,6BAAuB,MAAM,QAAQ;AAAA,QACjC,qBAAqB,IAAI,OAAO,CAAC,KAAK,UAAU,MAAM;AAAA,UAClD;AAAA,UACA,MAAM;AAAA,QACV,CAAC;AAAA,MACL;AAEA,aAAO,OAAO,YAAY,oBAAoB;AAAA,IAClD,GAAG;AAAA,EACP;AAEA,SAAO,OAAO,YAAY,oBAAoB;AAClD;","names":[]}
|
1
|
+
{"version":3,"sources":["../src/helpers.ts","../src/provider.ts","../src/scope.ts","../src/mock-map.ts","../src/collection-resolution.ts"],"sourcesContent":["/**\n * Creates a function that will invoke the provided function `fn` only once,\n * caching the result for subsequent calls with the same arguments.\n *\n * @param fn - The function to invoke once and cache the result.\n *\n * @returns A new function that returns the cached result after the first call.\n */\nexport const once = <A extends any[], R>(fn: (...args: A) => R) => {\n let returned = false;\n let result: R | undefined;\n\n return Object.assign((...args: A): R => {\n if (returned) return result!;\n\n result = fn(...args);\n returned = true;\n\n return result;\n }, fn);\n};\n","import { once } from \"./helpers\";\nimport { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A wrapper around the resolver(factory) for contextual dependency resolution.\n *\n * Resolves an instance by calling a resolver\n * with an **optional** resolution context that will be propagated\n * throughout a dependency tree.\n * ```ts\n * provider({ scope, mocks })\n * ```\n *\n * When passing a scope it will try to get an instance from it\n * or create a new one and put it there.\n *\n * When passing mocks, it will try to get its own mock version,\n * and if there is one, it will use it instead of itself.\n */\nexport type Provider<T> = (context?: ResolutionContext) => T;\n\n/**\n * A resolution lifetime.\n *\n * Passed when creating a provider to determine its behavior.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its instance from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n */\nexport type Lifetime = \"transient\" | \"singleton\" | \"scoped\";\n\n/**\n * A function that creates an instance using a resolution context.\n */\nexport type Resolver<T> = (context?: ResolutionContext) => T;\n\n/**\n * An object that holds information about a scope and provider mocks.\n *\n * Passed to the provider call to resolve scope instances and mock providers.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Creates a provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution.\n * ```ts\n * const getInstance = provide(\"transient\", () =>\n * createInstance(\n * getOtherInstance(context)\n * )\n * )\n * ```\n *\n * @param lifetime\n * A resolution lifetime.\n *\n * `\"transient\"` doesn't provide any modifications to a resolver behaviour,\n * so the resolver will create a new instance on each request.\n *\n * `\"singleton\"` forces the resolver to create an instance once\n * and return it in subsequent requests.\n *\n * `\"scoped\"` forces the resolver to take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n * If the function calls other providers,\n * the context **must** be passed to their calls.\n *\n * @returns The provider instance.\n */\nexport const provide = <T>(\n lifetime: Lifetime,\n resolver: Resolver<T>,\n): Provider<T> => {\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: Provider<T> = (context) => {\n const maybeOwnMock = context?.mocks?.get(resolve);\n if (maybeOwnMock) return maybeOwnMock(context);\n\n if (lifetime !== \"scoped\" || !context?.scope) return resolver(context);\n\n const resolution = context.scope.has(resolve)\n ? context.scope.get(resolve)\n : resolver(context);\n context.scope.set(resolve, resolution);\n\n return resolution;\n };\n\n return resolve;\n};\n\n/**\n * An alias for `provide(\"transient\", ...)`.\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create a new instance on each request.\n * ```ts\n * const getInstance = transient((context) =>\n * createInstance(...)\n * )\n *\n * getInstance() !== getInstance()\n * ```\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The transient provider instance.\n */\nexport const transient = <T>(resolver: Resolver<T>): Provider<T> =>\n provide(\"transient\", resolver);\n\n/**\n * An alias for `provide(\"singleton\", ...)`.\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will create an instance once and return it in subsequent requests.\n * ```ts\n * const getInstance = singleton((context) =>\n * createInstance(...)\n * )\n *\n * getInstance() === getInstance()\n * ```\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The singleton provider instance.\n */\nexport const singleton = <T>(resolver: Resolver<T>): Provider<T> =>\n provide(\"singleton\", resolver);\n\n/**\n * An alias for `provide(\"scoped\", ...)`.\n * Creates a transient provider instance,\n * a wrapper around a resolver(factory) for contextual dependency resolution\n * that will take its resolution from a provided scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will create a new instance on each request.\n * ```ts\n * const getInstance = scoped((context) =>\n * createInstance(...)\n * )\n *\n * getInstance() !== getInstance()\n * getInstance({ scope }) === getInstance({ scope })\n * ```\n *\n * @param resolver\n * The function that creates an instance using a resolution context.\n *\n * @returns The scoped provider instance.\n */\nexport const scoped = <T>(resolver: Resolver<T>): Provider<T> =>\n provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to their instances.\n *\n * Passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n */\nexport type Scope = Map<Provider<any>, any>;\n\n/**\n * Creates a scope instance.\n *\n * Scope is passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n * ```ts\n * const scope = createScope()\n * provider({ scope })\n * ```\n *\n * @returns The scope instance.\n */\nexport const createScope = (): Scope => new Map();\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n */\nexport type MockMap = Omit<Map<Provider<any>, Provider<any>>, \"set\" | \"get\"> & {\n /**\n * Sets a mock for a provider.\n *\n * @param provider - The original provider.\n * @param mock - The mock provider.\n */\n set<T>(provider: Provider<T>, mock: Provider<T>): MockMap;\n /**\n * Retrieves a mock of a provider. Returns undefined if there's none.\n *\n * @param provider - The provider.\n */\n get<T>(provider: Provider<T>): Provider<T> | undefined;\n};\n\n/**\n * Creates a mock map instance,\n * a map of providers to providers of the same type.\n * Lifetime is not a part of `Provider` type, so you can use\n * a different one if necessary.\n *\n * Passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n * ```ts\n * const otherProvider =\n * transitive(() => ...)\n * const otherProviderMock: typeof otherProvider =\n * scoped(() => ...)\n *\n * const mocks = createMockMap()\n * mocks.set(otherProvider, otherProviderMock)\n *\n * provider({ mocks })\n * ```\n *\n * @returns The mock map instance.\n */\nexport const createMockMap = (): MockMap => new Map();\n","import { Provider, ResolutionContext } from \"./provider\";\n\ntype ProviderList = Provider<any>[];\ntype ProviderRecord = Record<string, Provider<any>>;\n\ntype InferProviderCollectionResolutions<\n Providers extends ProviderList | ProviderRecord,\n> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\n/**\n * Awaits all promises and wraps the collection in a promise\n * if there'ss at least one `Promise` in the collection,\n * otherwise returns an untouched type.\n */\ntype AwaitAllValuesInCollection<T extends any[] | Record<any, any>> =\n Promise<any> extends T[keyof T]\n ? Promise<{\n [I in keyof T]: T[I] extends Promise<infer T> ? T : T[I];\n }>\n : T;\n\n/**\n * Calls every provider in a list with a provided resolution context\n * and returns a list of resolutions. Returns a promise of a list\n * of awaited resolutions if there's at least one promise in the resolutions.\n * ```ts\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope, mocks }\n * )\n * ```\n *\n * @param providers - The list of providers.\n * @param context - The resolution context.\n *\n * @returns The list of resolutions.\n */\nexport const resolveList = <const Providers extends ProviderList>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutions = providers.map((provider) => provider(context));\n\n return (\n resolutions.some((resolution) => resolution instanceof Promise)\n ? Promise.all(resolutions)\n : resolutions\n ) as any;\n};\n\n/**\n * Calls every provider in a map with a provided resolution context\n * and returns a map with identical keys but with resolutions in values instead.\n * Returns a promise of a map of awaited resolutions if there's at least one\n * promise in the resolutions.\n * ```ts\n * const resolutionMap = resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope, mocks }\n * )\n * ```\n *\n * @param providers - The map of providers.\n * @param context - The resolution context.\n *\n * @returns The map of resolutions.\n */\nexport const resolveMap = <const Providers extends ProviderRecord>(\n providers: Providers,\n context?: ResolutionContext,\n): AwaitAllValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n let resolutionMapEntries = Object.entries(providers).map(\n ([key, provider]) => [key, provider(context)],\n );\n\n if (\n resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n )\n ) {\n return (async () => {\n resolutionMapEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n\n return Object.fromEntries(resolutionMapEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":";AAQO,IAAM,OAAO,CAAqB,OAA0B;AAC/D,MAAI,WAAW;AACf,MAAI;AAEJ,SAAO,OAAO,OAAO,IAAI,SAAe;AACpC,QAAI,SAAU,QAAO;AAErB,aAAS,GAAG,GAAG,IAAI;AACnB,eAAW;AAEX,WAAO;AAAA,EACX,GAAG,EAAE;AACT;;;ACiEO,IAAM,UAAU,CACnB,UACA,aACc;AACd,aAAW,aAAa,cAAc,KAAK,QAAQ,IAAI;AAEvD,QAAM,UAAuB,CAAC,YAAY;AA3F9C;AA4FQ,UAAM,gBAAe,wCAAS,UAAT,mBAAgB,IAAI;AACzC,QAAI,aAAc,QAAO,aAAa,OAAO;AAE7C,QAAI,aAAa,YAAY,EAAC,mCAAS,OAAO,QAAO,SAAS,OAAO;AAErE,UAAM,aAAa,QAAQ,MAAM,IAAI,OAAO,IACtC,QAAQ,MAAM,IAAI,OAAO,IACzB,SAAS,OAAO;AACtB,YAAQ,MAAM,IAAI,SAAS,UAAU;AAErC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAoBO,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAoB1B,IAAM,YAAY,CAAI,aACzB,QAAQ,aAAa,QAAQ;AAuB1B,IAAM,SAAS,CAAI,aACtB,QAAQ,UAAU,QAAQ;;;AClJvB,IAAM,cAAc,MAAa,oBAAI,IAAI;;;ACiCzC,IAAM,gBAAgB,MAAe,oBAAI,IAAI;;;ACpB7C,IAAM,cAAc,CACvB,WACA,YAGC;AACD,QAAM,cAAc,UAAU,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAEjE,SACI,YAAY,KAAK,CAAC,eAAe,sBAAsB,OAAO,IACxD,QAAQ,IAAI,WAAW,IACvB;AAEd;AAmBO,IAAM,aAAa,CACtB,WACA,YAGC;AACD,MAAI,uBAAuB,OAAO,QAAQ,SAAS,EAAE;AAAA,IACjD,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,OAAO,CAAC;AAAA,EAChD;AAEA,MACI,qBAAqB;AAAA,IACjB,CAAC,CAAC,EAAE,UAAU,MAAM,sBAAsB;AAAA,EAC9C,GACF;AACE,YAAQ,YAAY;AAChB,6BAAuB,MAAM,QAAQ;AAAA,QACjC,qBAAqB,IAAI,OAAO,CAAC,KAAK,UAAU,MAAM;AAAA,UAClD;AAAA,UACA,MAAM;AAAA,QACV,CAAC;AAAA,MACL;AAEA,aAAO,OAAO,YAAY,oBAAoB;AAAA,IAClD,GAAG;AAAA,EACP;AAEA,SAAO,OAAO,YAAY,oBAAoB;AAClD;","names":[]}
|
package/package.json
CHANGED