atomic-di 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -12
- package/dist/index.d.mts +101 -78
- package/dist/index.d.ts +101 -78
- package/dist/index.js +51 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +51 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -233,22 +233,13 @@ IoC containers implement this by defining copies of a container in different par
|
|
|
233
233
|
### Creating a scope
|
|
234
234
|
|
|
235
235
|
There are two ways to create a scope:
|
|
236
|
-
-
|
|
237
|
-
```ts
|
|
238
|
-
const scope = new Map<Resolver<any>, any>()
|
|
239
|
-
```
|
|
240
|
-
- Use `createScope` function.
|
|
236
|
+
- By calling `createScope` function.
|
|
241
237
|
```ts
|
|
242
238
|
const scope = createScope()
|
|
243
239
|
```
|
|
244
|
-
|
|
245
|
-
It is important to note that a scope must be created **once** during an entire lifecycle of a program.
|
|
240
|
+
- By creating a `Map` with the correct type manually.
|
|
246
241
|
```ts
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
app.use(() => {
|
|
250
|
-
// use the scope here
|
|
251
|
-
})
|
|
242
|
+
const scope = new Map<Resolver<any>, any>()
|
|
252
243
|
```
|
|
253
244
|
|
|
254
245
|
### Resolving with a scope
|
package/dist/index.d.mts
CHANGED
|
@@ -1,50 +1,75 @@
|
|
|
1
|
+
type PromiseAwarePartial<T> = T extends Promise<infer U> ? Promise<Partial<U>> : Partial<T>;
|
|
2
|
+
type Mock<T> = {
|
|
3
|
+
isPartial: false;
|
|
4
|
+
resolver: Resolver<T>;
|
|
5
|
+
} | {
|
|
6
|
+
isPartial: true;
|
|
7
|
+
resolver: Resolver<PromiseAwarePartial<T>>;
|
|
8
|
+
};
|
|
1
9
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
10
|
+
* Immutable map that registers and provides mocks.
|
|
11
|
+
* Is passed in a resolution context and used by resolvers
|
|
12
|
+
* to replace or partially replace themselves with a mock if one is defined.
|
|
5
13
|
*/
|
|
6
|
-
type MockMap =
|
|
14
|
+
type MockMap = {
|
|
15
|
+
/**
|
|
16
|
+
* Registers a mock for a resolver,
|
|
17
|
+
* creating a new `MockMap` with this registration.
|
|
18
|
+
*
|
|
19
|
+
* @param original - The original resolver.
|
|
20
|
+
* @param mock - The mock resolver.
|
|
21
|
+
*/
|
|
22
|
+
mock<T>(original: Resolver<T>, mock: Resolver<T>): MockMap;
|
|
7
23
|
/**
|
|
8
|
-
*
|
|
24
|
+
* Registers a partial mock for a resolver,
|
|
25
|
+
* creating a new `MockMap` with this registration.
|
|
26
|
+
* In this case, the mock resolver's resolution object will be
|
|
27
|
+
* merged with the original resolver's resolution object,
|
|
28
|
+
* overwriting certain fields.
|
|
9
29
|
*
|
|
10
|
-
* @param
|
|
11
|
-
* @param mock - The mock
|
|
30
|
+
* @param original - The original resolver.
|
|
31
|
+
* @param mock - The mock resolver.
|
|
12
32
|
*/
|
|
13
|
-
|
|
33
|
+
mockPartially<T extends object>(original: Resolver<T>, mock: Resolver<PromiseAwarePartial<T>>): MockMap;
|
|
14
34
|
/**
|
|
15
|
-
*
|
|
35
|
+
* Returns a mock of a resolver
|
|
36
|
+
* or `undefined` if one is not registered.
|
|
16
37
|
*
|
|
17
|
-
* @param
|
|
38
|
+
* @param original - The original resolver.
|
|
18
39
|
*/
|
|
19
|
-
get<T>(
|
|
40
|
+
get<T>(original: Resolver<T>): Mock<T> | undefined;
|
|
20
41
|
};
|
|
21
42
|
/**
|
|
22
|
-
* Creates a
|
|
23
|
-
*
|
|
24
|
-
*
|
|
43
|
+
* Creates a mock map, an immutable map that registers and provides mocks.
|
|
44
|
+
* Is passed in a resolution context and used by resolvers
|
|
45
|
+
* to replace or partially replace themselves with a mock if one is defined.
|
|
25
46
|
*
|
|
26
47
|
* @example
|
|
27
48
|
* ```ts
|
|
28
49
|
* const mocks = createMockMap()
|
|
29
|
-
* .
|
|
50
|
+
* .mock(getDependency, getDependencyMock)
|
|
51
|
+
* .mockPartially(
|
|
52
|
+
* getOtherDepedency,
|
|
53
|
+
* transient(() => ({ someField: "mock" }))
|
|
54
|
+
* )
|
|
30
55
|
*
|
|
31
|
-
*
|
|
56
|
+
* const entityWithMocks = getEntity({ mocks })
|
|
32
57
|
* ```
|
|
33
58
|
*
|
|
34
|
-
* @returns The map
|
|
59
|
+
* @returns The mock map.
|
|
35
60
|
*/
|
|
36
61
|
declare const createMockMap: () => MockMap;
|
|
37
62
|
|
|
38
63
|
/**
|
|
39
|
-
* A `Map` of
|
|
40
|
-
*
|
|
41
|
-
* to
|
|
64
|
+
* A `Map` of resolvers to their resolutions.
|
|
65
|
+
* Is passed in a resolution context and used by scoped resolvers
|
|
66
|
+
* to retrieve or save resolution within it.
|
|
42
67
|
*/
|
|
43
68
|
type Scope = Map<Resolver<any>, any>;
|
|
44
69
|
/**
|
|
45
|
-
* Creates a `Map` of providers to their instances
|
|
46
|
-
*
|
|
47
|
-
* to
|
|
70
|
+
* Creates a `Map` of providers to their instances.
|
|
71
|
+
* Is passed in a resolution context and used by scoped resolvers
|
|
72
|
+
* to retrieve or save resolution within it.
|
|
48
73
|
*
|
|
49
74
|
* @example
|
|
50
75
|
* ```ts
|
|
@@ -52,97 +77,95 @@ type Scope = Map<Resolver<any>, any>;
|
|
|
52
77
|
*
|
|
53
78
|
* app.use(() => {
|
|
54
79
|
* const db = getDb({ scope: requestScope })
|
|
55
|
-
* // ...
|
|
56
80
|
* })
|
|
57
81
|
* ```
|
|
58
82
|
*
|
|
59
|
-
* @returns The map
|
|
83
|
+
* @returns The map.
|
|
60
84
|
*/
|
|
61
85
|
declare const createScope: () => Scope;
|
|
62
86
|
|
|
63
87
|
/**
|
|
64
|
-
* A function that
|
|
65
|
-
*
|
|
88
|
+
* A function that takes a resolution context
|
|
89
|
+
* and returns a value of some type.
|
|
66
90
|
*/
|
|
67
|
-
type
|
|
91
|
+
type ResolverFn<T> = (context?: ResolutionContext) => T;
|
|
68
92
|
/**
|
|
69
|
-
* A function that
|
|
70
|
-
* based on a resolution context
|
|
93
|
+
* A function that returns a value of some type
|
|
94
|
+
* based on a resolution context.
|
|
71
95
|
*/
|
|
72
|
-
type
|
|
73
|
-
__brand: "provider";
|
|
74
|
-
};
|
|
96
|
+
type Resolver<T> = ResolverFn<T>;
|
|
75
97
|
/**
|
|
76
|
-
* A context used by
|
|
77
|
-
*
|
|
98
|
+
* A context used by resolvers that defines the behaviour of the resolver
|
|
99
|
+
* with the passed mocks and scope.
|
|
78
100
|
*/
|
|
79
101
|
type ResolutionContext = {
|
|
80
102
|
scope?: Scope;
|
|
81
103
|
mocks?: MockMap;
|
|
82
104
|
};
|
|
83
105
|
/**
|
|
84
|
-
* Creates a
|
|
106
|
+
* Creates a resolver that creates a new resolution on each call.
|
|
85
107
|
*
|
|
86
108
|
* @example
|
|
87
109
|
* ```ts
|
|
88
|
-
* const
|
|
89
|
-
*
|
|
110
|
+
* const getEntity = transient(() => createEntity())
|
|
111
|
+
* getEntity() !== getEntity()
|
|
90
112
|
* ```
|
|
91
113
|
*
|
|
92
114
|
* @param resolver
|
|
93
|
-
* A function that
|
|
94
|
-
*
|
|
115
|
+
* A function that takes a resolution context
|
|
116
|
+
* and returns a value of some type.
|
|
95
117
|
*
|
|
96
|
-
* @returns The transient
|
|
118
|
+
* @returns The transient resolver.
|
|
97
119
|
*/
|
|
98
|
-
declare const transient: <T>(
|
|
120
|
+
declare const transient: <T>(fn: ResolverFn<T>) => Resolver<T>;
|
|
99
121
|
/**
|
|
100
|
-
* Creates a
|
|
101
|
-
* and return it on
|
|
122
|
+
* Creates a resolver that creates
|
|
123
|
+
* a resolution once and return it on each call.
|
|
102
124
|
*
|
|
103
125
|
* @example
|
|
104
126
|
* ```ts
|
|
105
|
-
* const
|
|
106
|
-
*
|
|
127
|
+
* const getEntity = singleton(() => createEntity())
|
|
128
|
+
* getEntity() === getEntity()
|
|
107
129
|
* ```
|
|
108
130
|
*
|
|
109
|
-
* @param
|
|
110
|
-
* A function that
|
|
111
|
-
*
|
|
131
|
+
* @param fn
|
|
132
|
+
* A function that takes a resolution context
|
|
133
|
+
* and returns a value of some type.
|
|
112
134
|
*
|
|
113
|
-
* @returns The singleton
|
|
135
|
+
* @returns The singleton resolver.
|
|
114
136
|
*/
|
|
115
|
-
declare const singleton: <T>(
|
|
137
|
+
declare const singleton: <T>(fn: ResolverFn<T>) => Resolver<T>;
|
|
116
138
|
/**
|
|
117
|
-
* Creates a
|
|
118
|
-
* or create a new one and save it if there is none.
|
|
119
|
-
* If no scope
|
|
139
|
+
* Creates a resolver that takes its resolution
|
|
140
|
+
* from a scope or create a new one and save it if there is none.
|
|
141
|
+
* If no scope was passed in a resolution context,
|
|
142
|
+
* it will act as a singleton.
|
|
120
143
|
*
|
|
121
144
|
* @example
|
|
122
145
|
* ```ts
|
|
123
|
-
* const
|
|
124
|
-
*
|
|
146
|
+
* const getEntity = scoped(() => createEntity())
|
|
147
|
+
* getEntity() === getEntity()
|
|
125
148
|
* ```
|
|
126
149
|
*
|
|
127
150
|
* @example
|
|
128
151
|
* ```ts
|
|
129
|
-
* const
|
|
152
|
+
* const getEntity = scoped(() => createEntity())
|
|
130
153
|
* const scope = createScope()
|
|
131
|
-
*
|
|
154
|
+
* getEntity({ scope }) === getEntity({ scope }) !== getEntity()
|
|
132
155
|
* ```
|
|
133
156
|
*
|
|
134
|
-
* @param
|
|
135
|
-
* A function that
|
|
136
|
-
*
|
|
157
|
+
* @param fn
|
|
158
|
+
* A function that takes a resolution context
|
|
159
|
+
* and returns a value of some type.
|
|
137
160
|
*
|
|
138
|
-
* @returns The scoped
|
|
161
|
+
* @returns The scoped resolver.
|
|
139
162
|
*/
|
|
140
|
-
declare const scoped: <T>(
|
|
163
|
+
declare const scoped: <T>(fn: ResolverFn<T>) => Resolver<T>;
|
|
141
164
|
|
|
142
|
-
type
|
|
143
|
-
type
|
|
144
|
-
type
|
|
145
|
-
[K in keyof
|
|
165
|
+
type ResolverList = Resolver<any>[];
|
|
166
|
+
type ResolverRecord = Record<string, Resolver<any>>;
|
|
167
|
+
type InferResolverCollectionResolutions<Resolvers extends ResolverList | ResolverRecord> = {
|
|
168
|
+
[K in keyof Resolvers]: Resolvers[K] extends Resolver<infer T> ? T : never;
|
|
146
169
|
};
|
|
147
170
|
/**
|
|
148
171
|
* Awaits all promises and wraps the collection in a promise
|
|
@@ -153,12 +176,12 @@ type AwaitValuesInCollection<T extends any[] | Record<any, any>> = Promise<any>
|
|
|
153
176
|
[I in keyof T]: T[I] extends Promise<infer T> ? T : T[I];
|
|
154
177
|
}> : T;
|
|
155
178
|
/**
|
|
156
|
-
* Calls every
|
|
179
|
+
* Calls every resolver in a list with a provided resolution context
|
|
157
180
|
* and returns a list of resolutions. Returns a `Promise` of a list
|
|
158
181
|
* of awaited resolutions if there's at least one `Promise` in the resolutions.
|
|
159
182
|
*
|
|
160
183
|
* @example
|
|
161
|
-
* Only sync
|
|
184
|
+
* Only sync resolvers:
|
|
162
185
|
* ```ts
|
|
163
186
|
* const getA = scoped(() => createA())
|
|
164
187
|
* const getB = scoped(() => createB())
|
|
@@ -178,7 +201,7 @@ type AwaitValuesInCollection<T extends any[] | Record<any, any>> = Promise<any>
|
|
|
178
201
|
* ```
|
|
179
202
|
*
|
|
180
203
|
* @example
|
|
181
|
-
* Some
|
|
204
|
+
* Some resolver is async:
|
|
182
205
|
* ```ts
|
|
183
206
|
* const getA = scoped(() => createA())
|
|
184
207
|
* const getB = scoped(async () => await createB())
|
|
@@ -197,20 +220,20 @@ type AwaitValuesInCollection<T extends any[] | Record<any, any>> = Promise<any>
|
|
|
197
220
|
* ]
|
|
198
221
|
* ```
|
|
199
222
|
*
|
|
200
|
-
* @param
|
|
223
|
+
* @param resolvers - The list of resolvers.
|
|
201
224
|
* @param context - The resolution context.
|
|
202
225
|
*
|
|
203
226
|
* @returns The list of resolutions.
|
|
204
227
|
*/
|
|
205
|
-
declare const resolveList: <const
|
|
228
|
+
declare const resolveList: <const Resolvers extends ResolverList>(resolvers: Resolvers, context?: ResolutionContext) => AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>>;
|
|
206
229
|
/**
|
|
207
|
-
* Calls every
|
|
230
|
+
* Calls every resolver in a map with a provided resolution context
|
|
208
231
|
* and returns a map with identical keys but with resolutions in values instead.
|
|
209
232
|
* Returns a `Promise` of a map of awaited resolutions if there's at least one
|
|
210
233
|
* `Promise` in the resolutions.
|
|
211
234
|
*
|
|
212
235
|
* @example
|
|
213
|
-
* Only sync
|
|
236
|
+
* Only sync resolvers:
|
|
214
237
|
* ```ts
|
|
215
238
|
* const getA = scoped(() => createA())
|
|
216
239
|
* const getB = scoped(() => createB())
|
|
@@ -230,7 +253,7 @@ declare const resolveList: <const Providers extends ProviderList>(providers: Pro
|
|
|
230
253
|
* ```
|
|
231
254
|
*
|
|
232
255
|
* @example
|
|
233
|
-
* Some
|
|
256
|
+
* Some resolver is async:
|
|
234
257
|
* ```ts
|
|
235
258
|
* const getA = scoped(() => createA())
|
|
236
259
|
* const getB = scoped(async () => await createB())
|
|
@@ -249,11 +272,11 @@ declare const resolveList: <const Providers extends ProviderList>(providers: Pro
|
|
|
249
272
|
* }
|
|
250
273
|
* ```
|
|
251
274
|
*
|
|
252
|
-
* @param
|
|
275
|
+
* @param resolvers - The map of resolvers.
|
|
253
276
|
* @param context - The resolution context.
|
|
254
277
|
*
|
|
255
278
|
* @returns The map of resolutions.
|
|
256
279
|
*/
|
|
257
|
-
declare const resolveMap: <const
|
|
280
|
+
declare const resolveMap: <const Resolvers extends ResolverRecord>(resolvers: Resolvers, context?: ResolutionContext) => AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>>;
|
|
258
281
|
|
|
259
|
-
export { type MockMap, type
|
|
282
|
+
export { type MockMap, type ResolutionContext, type Resolver, type ResolverFn, type Scope, createMockMap, createScope, resolveList, resolveMap, scoped, singleton, transient };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,50 +1,75 @@
|
|
|
1
|
+
type PromiseAwarePartial<T> = T extends Promise<infer U> ? Promise<Partial<U>> : Partial<T>;
|
|
2
|
+
type Mock<T> = {
|
|
3
|
+
isPartial: false;
|
|
4
|
+
resolver: Resolver<T>;
|
|
5
|
+
} | {
|
|
6
|
+
isPartial: true;
|
|
7
|
+
resolver: Resolver<PromiseAwarePartial<T>>;
|
|
8
|
+
};
|
|
1
9
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
10
|
+
* Immutable map that registers and provides mocks.
|
|
11
|
+
* Is passed in a resolution context and used by resolvers
|
|
12
|
+
* to replace or partially replace themselves with a mock if one is defined.
|
|
5
13
|
*/
|
|
6
|
-
type MockMap =
|
|
14
|
+
type MockMap = {
|
|
15
|
+
/**
|
|
16
|
+
* Registers a mock for a resolver,
|
|
17
|
+
* creating a new `MockMap` with this registration.
|
|
18
|
+
*
|
|
19
|
+
* @param original - The original resolver.
|
|
20
|
+
* @param mock - The mock resolver.
|
|
21
|
+
*/
|
|
22
|
+
mock<T>(original: Resolver<T>, mock: Resolver<T>): MockMap;
|
|
7
23
|
/**
|
|
8
|
-
*
|
|
24
|
+
* Registers a partial mock for a resolver,
|
|
25
|
+
* creating a new `MockMap` with this registration.
|
|
26
|
+
* In this case, the mock resolver's resolution object will be
|
|
27
|
+
* merged with the original resolver's resolution object,
|
|
28
|
+
* overwriting certain fields.
|
|
9
29
|
*
|
|
10
|
-
* @param
|
|
11
|
-
* @param mock - The mock
|
|
30
|
+
* @param original - The original resolver.
|
|
31
|
+
* @param mock - The mock resolver.
|
|
12
32
|
*/
|
|
13
|
-
|
|
33
|
+
mockPartially<T extends object>(original: Resolver<T>, mock: Resolver<PromiseAwarePartial<T>>): MockMap;
|
|
14
34
|
/**
|
|
15
|
-
*
|
|
35
|
+
* Returns a mock of a resolver
|
|
36
|
+
* or `undefined` if one is not registered.
|
|
16
37
|
*
|
|
17
|
-
* @param
|
|
38
|
+
* @param original - The original resolver.
|
|
18
39
|
*/
|
|
19
|
-
get<T>(
|
|
40
|
+
get<T>(original: Resolver<T>): Mock<T> | undefined;
|
|
20
41
|
};
|
|
21
42
|
/**
|
|
22
|
-
* Creates a
|
|
23
|
-
*
|
|
24
|
-
*
|
|
43
|
+
* Creates a mock map, an immutable map that registers and provides mocks.
|
|
44
|
+
* Is passed in a resolution context and used by resolvers
|
|
45
|
+
* to replace or partially replace themselves with a mock if one is defined.
|
|
25
46
|
*
|
|
26
47
|
* @example
|
|
27
48
|
* ```ts
|
|
28
49
|
* const mocks = createMockMap()
|
|
29
|
-
* .
|
|
50
|
+
* .mock(getDependency, getDependencyMock)
|
|
51
|
+
* .mockPartially(
|
|
52
|
+
* getOtherDepedency,
|
|
53
|
+
* transient(() => ({ someField: "mock" }))
|
|
54
|
+
* )
|
|
30
55
|
*
|
|
31
|
-
*
|
|
56
|
+
* const entityWithMocks = getEntity({ mocks })
|
|
32
57
|
* ```
|
|
33
58
|
*
|
|
34
|
-
* @returns The map
|
|
59
|
+
* @returns The mock map.
|
|
35
60
|
*/
|
|
36
61
|
declare const createMockMap: () => MockMap;
|
|
37
62
|
|
|
38
63
|
/**
|
|
39
|
-
* A `Map` of
|
|
40
|
-
*
|
|
41
|
-
* to
|
|
64
|
+
* A `Map` of resolvers to their resolutions.
|
|
65
|
+
* Is passed in a resolution context and used by scoped resolvers
|
|
66
|
+
* to retrieve or save resolution within it.
|
|
42
67
|
*/
|
|
43
68
|
type Scope = Map<Resolver<any>, any>;
|
|
44
69
|
/**
|
|
45
|
-
* Creates a `Map` of providers to their instances
|
|
46
|
-
*
|
|
47
|
-
* to
|
|
70
|
+
* Creates a `Map` of providers to their instances.
|
|
71
|
+
* Is passed in a resolution context and used by scoped resolvers
|
|
72
|
+
* to retrieve or save resolution within it.
|
|
48
73
|
*
|
|
49
74
|
* @example
|
|
50
75
|
* ```ts
|
|
@@ -52,97 +77,95 @@ type Scope = Map<Resolver<any>, any>;
|
|
|
52
77
|
*
|
|
53
78
|
* app.use(() => {
|
|
54
79
|
* const db = getDb({ scope: requestScope })
|
|
55
|
-
* // ...
|
|
56
80
|
* })
|
|
57
81
|
* ```
|
|
58
82
|
*
|
|
59
|
-
* @returns The map
|
|
83
|
+
* @returns The map.
|
|
60
84
|
*/
|
|
61
85
|
declare const createScope: () => Scope;
|
|
62
86
|
|
|
63
87
|
/**
|
|
64
|
-
* A function that
|
|
65
|
-
*
|
|
88
|
+
* A function that takes a resolution context
|
|
89
|
+
* and returns a value of some type.
|
|
66
90
|
*/
|
|
67
|
-
type
|
|
91
|
+
type ResolverFn<T> = (context?: ResolutionContext) => T;
|
|
68
92
|
/**
|
|
69
|
-
* A function that
|
|
70
|
-
* based on a resolution context
|
|
93
|
+
* A function that returns a value of some type
|
|
94
|
+
* based on a resolution context.
|
|
71
95
|
*/
|
|
72
|
-
type
|
|
73
|
-
__brand: "provider";
|
|
74
|
-
};
|
|
96
|
+
type Resolver<T> = ResolverFn<T>;
|
|
75
97
|
/**
|
|
76
|
-
* A context used by
|
|
77
|
-
*
|
|
98
|
+
* A context used by resolvers that defines the behaviour of the resolver
|
|
99
|
+
* with the passed mocks and scope.
|
|
78
100
|
*/
|
|
79
101
|
type ResolutionContext = {
|
|
80
102
|
scope?: Scope;
|
|
81
103
|
mocks?: MockMap;
|
|
82
104
|
};
|
|
83
105
|
/**
|
|
84
|
-
* Creates a
|
|
106
|
+
* Creates a resolver that creates a new resolution on each call.
|
|
85
107
|
*
|
|
86
108
|
* @example
|
|
87
109
|
* ```ts
|
|
88
|
-
* const
|
|
89
|
-
*
|
|
110
|
+
* const getEntity = transient(() => createEntity())
|
|
111
|
+
* getEntity() !== getEntity()
|
|
90
112
|
* ```
|
|
91
113
|
*
|
|
92
114
|
* @param resolver
|
|
93
|
-
* A function that
|
|
94
|
-
*
|
|
115
|
+
* A function that takes a resolution context
|
|
116
|
+
* and returns a value of some type.
|
|
95
117
|
*
|
|
96
|
-
* @returns The transient
|
|
118
|
+
* @returns The transient resolver.
|
|
97
119
|
*/
|
|
98
|
-
declare const transient: <T>(
|
|
120
|
+
declare const transient: <T>(fn: ResolverFn<T>) => Resolver<T>;
|
|
99
121
|
/**
|
|
100
|
-
* Creates a
|
|
101
|
-
* and return it on
|
|
122
|
+
* Creates a resolver that creates
|
|
123
|
+
* a resolution once and return it on each call.
|
|
102
124
|
*
|
|
103
125
|
* @example
|
|
104
126
|
* ```ts
|
|
105
|
-
* const
|
|
106
|
-
*
|
|
127
|
+
* const getEntity = singleton(() => createEntity())
|
|
128
|
+
* getEntity() === getEntity()
|
|
107
129
|
* ```
|
|
108
130
|
*
|
|
109
|
-
* @param
|
|
110
|
-
* A function that
|
|
111
|
-
*
|
|
131
|
+
* @param fn
|
|
132
|
+
* A function that takes a resolution context
|
|
133
|
+
* and returns a value of some type.
|
|
112
134
|
*
|
|
113
|
-
* @returns The singleton
|
|
135
|
+
* @returns The singleton resolver.
|
|
114
136
|
*/
|
|
115
|
-
declare const singleton: <T>(
|
|
137
|
+
declare const singleton: <T>(fn: ResolverFn<T>) => Resolver<T>;
|
|
116
138
|
/**
|
|
117
|
-
* Creates a
|
|
118
|
-
* or create a new one and save it if there is none.
|
|
119
|
-
* If no scope
|
|
139
|
+
* Creates a resolver that takes its resolution
|
|
140
|
+
* from a scope or create a new one and save it if there is none.
|
|
141
|
+
* If no scope was passed in a resolution context,
|
|
142
|
+
* it will act as a singleton.
|
|
120
143
|
*
|
|
121
144
|
* @example
|
|
122
145
|
* ```ts
|
|
123
|
-
* const
|
|
124
|
-
*
|
|
146
|
+
* const getEntity = scoped(() => createEntity())
|
|
147
|
+
* getEntity() === getEntity()
|
|
125
148
|
* ```
|
|
126
149
|
*
|
|
127
150
|
* @example
|
|
128
151
|
* ```ts
|
|
129
|
-
* const
|
|
152
|
+
* const getEntity = scoped(() => createEntity())
|
|
130
153
|
* const scope = createScope()
|
|
131
|
-
*
|
|
154
|
+
* getEntity({ scope }) === getEntity({ scope }) !== getEntity()
|
|
132
155
|
* ```
|
|
133
156
|
*
|
|
134
|
-
* @param
|
|
135
|
-
* A function that
|
|
136
|
-
*
|
|
157
|
+
* @param fn
|
|
158
|
+
* A function that takes a resolution context
|
|
159
|
+
* and returns a value of some type.
|
|
137
160
|
*
|
|
138
|
-
* @returns The scoped
|
|
161
|
+
* @returns The scoped resolver.
|
|
139
162
|
*/
|
|
140
|
-
declare const scoped: <T>(
|
|
163
|
+
declare const scoped: <T>(fn: ResolverFn<T>) => Resolver<T>;
|
|
141
164
|
|
|
142
|
-
type
|
|
143
|
-
type
|
|
144
|
-
type
|
|
145
|
-
[K in keyof
|
|
165
|
+
type ResolverList = Resolver<any>[];
|
|
166
|
+
type ResolverRecord = Record<string, Resolver<any>>;
|
|
167
|
+
type InferResolverCollectionResolutions<Resolvers extends ResolverList | ResolverRecord> = {
|
|
168
|
+
[K in keyof Resolvers]: Resolvers[K] extends Resolver<infer T> ? T : never;
|
|
146
169
|
};
|
|
147
170
|
/**
|
|
148
171
|
* Awaits all promises and wraps the collection in a promise
|
|
@@ -153,12 +176,12 @@ type AwaitValuesInCollection<T extends any[] | Record<any, any>> = Promise<any>
|
|
|
153
176
|
[I in keyof T]: T[I] extends Promise<infer T> ? T : T[I];
|
|
154
177
|
}> : T;
|
|
155
178
|
/**
|
|
156
|
-
* Calls every
|
|
179
|
+
* Calls every resolver in a list with a provided resolution context
|
|
157
180
|
* and returns a list of resolutions. Returns a `Promise` of a list
|
|
158
181
|
* of awaited resolutions if there's at least one `Promise` in the resolutions.
|
|
159
182
|
*
|
|
160
183
|
* @example
|
|
161
|
-
* Only sync
|
|
184
|
+
* Only sync resolvers:
|
|
162
185
|
* ```ts
|
|
163
186
|
* const getA = scoped(() => createA())
|
|
164
187
|
* const getB = scoped(() => createB())
|
|
@@ -178,7 +201,7 @@ type AwaitValuesInCollection<T extends any[] | Record<any, any>> = Promise<any>
|
|
|
178
201
|
* ```
|
|
179
202
|
*
|
|
180
203
|
* @example
|
|
181
|
-
* Some
|
|
204
|
+
* Some resolver is async:
|
|
182
205
|
* ```ts
|
|
183
206
|
* const getA = scoped(() => createA())
|
|
184
207
|
* const getB = scoped(async () => await createB())
|
|
@@ -197,20 +220,20 @@ type AwaitValuesInCollection<T extends any[] | Record<any, any>> = Promise<any>
|
|
|
197
220
|
* ]
|
|
198
221
|
* ```
|
|
199
222
|
*
|
|
200
|
-
* @param
|
|
223
|
+
* @param resolvers - The list of resolvers.
|
|
201
224
|
* @param context - The resolution context.
|
|
202
225
|
*
|
|
203
226
|
* @returns The list of resolutions.
|
|
204
227
|
*/
|
|
205
|
-
declare const resolveList: <const
|
|
228
|
+
declare const resolveList: <const Resolvers extends ResolverList>(resolvers: Resolvers, context?: ResolutionContext) => AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>>;
|
|
206
229
|
/**
|
|
207
|
-
* Calls every
|
|
230
|
+
* Calls every resolver in a map with a provided resolution context
|
|
208
231
|
* and returns a map with identical keys but with resolutions in values instead.
|
|
209
232
|
* Returns a `Promise` of a map of awaited resolutions if there's at least one
|
|
210
233
|
* `Promise` in the resolutions.
|
|
211
234
|
*
|
|
212
235
|
* @example
|
|
213
|
-
* Only sync
|
|
236
|
+
* Only sync resolvers:
|
|
214
237
|
* ```ts
|
|
215
238
|
* const getA = scoped(() => createA())
|
|
216
239
|
* const getB = scoped(() => createB())
|
|
@@ -230,7 +253,7 @@ declare const resolveList: <const Providers extends ProviderList>(providers: Pro
|
|
|
230
253
|
* ```
|
|
231
254
|
*
|
|
232
255
|
* @example
|
|
233
|
-
* Some
|
|
256
|
+
* Some resolver is async:
|
|
234
257
|
* ```ts
|
|
235
258
|
* const getA = scoped(() => createA())
|
|
236
259
|
* const getB = scoped(async () => await createB())
|
|
@@ -249,11 +272,11 @@ declare const resolveList: <const Providers extends ProviderList>(providers: Pro
|
|
|
249
272
|
* }
|
|
250
273
|
* ```
|
|
251
274
|
*
|
|
252
|
-
* @param
|
|
275
|
+
* @param resolvers - The map of resolvers.
|
|
253
276
|
* @param context - The resolution context.
|
|
254
277
|
*
|
|
255
278
|
* @returns The map of resolutions.
|
|
256
279
|
*/
|
|
257
|
-
declare const resolveMap: <const
|
|
280
|
+
declare const resolveMap: <const Resolvers extends ResolverRecord>(resolvers: Resolvers, context?: ResolutionContext) => AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>>;
|
|
258
281
|
|
|
259
|
-
export { type MockMap, type
|
|
282
|
+
export { type MockMap, type ResolutionContext, type Resolver, type ResolverFn, type Scope, createMockMap, createScope, resolveList, resolveMap, scoped, singleton, transient };
|
package/dist/index.js
CHANGED
|
@@ -29,33 +29,40 @@ __export(src_exports, {
|
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(src_exports);
|
|
31
31
|
|
|
32
|
-
// src/
|
|
33
|
-
var
|
|
32
|
+
// src/resolver.ts
|
|
33
|
+
var mockable = (fn) => {
|
|
34
34
|
const instance = (context) => {
|
|
35
35
|
var _a;
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
return resolver(context);
|
|
36
|
+
const mock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
|
37
|
+
if (!mock) return fn(context);
|
|
38
|
+
if (!mock.isPartial) return mock.resolver(context);
|
|
39
|
+
const resolution = fn(context);
|
|
40
|
+
const mockResolution = mock.resolver(context);
|
|
41
|
+
if (resolution instanceof Promise && mockResolution instanceof Promise)
|
|
42
|
+
return Promise.all([resolution, mockResolution]).then(
|
|
43
|
+
([a, b]) => Object.assign(a, b)
|
|
44
|
+
);
|
|
45
|
+
return Object.assign(resolution, mockResolution);
|
|
39
46
|
};
|
|
40
|
-
return
|
|
47
|
+
return instance;
|
|
41
48
|
};
|
|
42
|
-
var transient =
|
|
43
|
-
var singleton = (
|
|
49
|
+
var transient = (fn) => mockable(fn);
|
|
50
|
+
var singleton = (fn) => {
|
|
44
51
|
let resolved = false;
|
|
45
52
|
let resolution;
|
|
46
|
-
const instance =
|
|
53
|
+
const instance = mockable((context) => {
|
|
47
54
|
if (resolved) return resolution;
|
|
48
|
-
resolution =
|
|
55
|
+
resolution = fn(context);
|
|
49
56
|
resolved = true;
|
|
50
57
|
return resolution;
|
|
51
58
|
});
|
|
52
59
|
return instance;
|
|
53
60
|
};
|
|
54
|
-
var scoped = (
|
|
55
|
-
const singletonFallback = singleton(
|
|
56
|
-
const instance =
|
|
61
|
+
var scoped = (fn) => {
|
|
62
|
+
const singletonFallback = singleton(fn);
|
|
63
|
+
const instance = mockable((context) => {
|
|
57
64
|
if (!(context == null ? void 0 : context.scope)) return singletonFallback(context);
|
|
58
|
-
const resolution = context.scope.has(instance) ? context.scope.get(instance) :
|
|
65
|
+
const resolution = context.scope.has(instance) ? context.scope.get(instance) : fn(context);
|
|
59
66
|
context.scope.set(instance, resolution);
|
|
60
67
|
return resolution;
|
|
61
68
|
});
|
|
@@ -66,19 +73,43 @@ var scoped = (resolver) => {
|
|
|
66
73
|
var createScope = () => /* @__PURE__ */ new Map();
|
|
67
74
|
|
|
68
75
|
// src/mock-map.ts
|
|
69
|
-
var
|
|
76
|
+
var createMockMapWithEntries = (entries = []) => {
|
|
77
|
+
const set = (key, value) => createMockMapWithEntries([
|
|
78
|
+
...entries.filter((entry) => entry[0] !== key),
|
|
79
|
+
[key, value]
|
|
80
|
+
]);
|
|
81
|
+
return {
|
|
82
|
+
mock(original, mock) {
|
|
83
|
+
return set(original, {
|
|
84
|
+
isPartial: false,
|
|
85
|
+
resolver: mock
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
mockPartially(original, mock) {
|
|
89
|
+
return set(original, {
|
|
90
|
+
isPartial: true,
|
|
91
|
+
resolver: mock
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
get(original) {
|
|
95
|
+
var _a;
|
|
96
|
+
return (_a = entries.find((entry) => entry[0] === original)) == null ? void 0 : _a[1];
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
var createMockMap = () => createMockMapWithEntries();
|
|
70
101
|
|
|
71
102
|
// src/collection-resolution.ts
|
|
72
|
-
var resolveList = (
|
|
73
|
-
const resolutions =
|
|
103
|
+
var resolveList = (resolvers, context) => {
|
|
104
|
+
const resolutions = resolvers.map((resolver) => resolver(context));
|
|
74
105
|
const hasPromises = resolutions.some(
|
|
75
106
|
(resolution) => resolution instanceof Promise
|
|
76
107
|
);
|
|
77
108
|
return hasPromises ? Promise.all(resolutions) : resolutions;
|
|
78
109
|
};
|
|
79
|
-
var resolveMap = (
|
|
80
|
-
const resolutionMapEntries = Object.entries(
|
|
81
|
-
([key,
|
|
110
|
+
var resolveMap = (resolvers, context) => {
|
|
111
|
+
const resolutionMapEntries = Object.entries(resolvers).map(
|
|
112
|
+
([key, resolver]) => [key, resolver(context)]
|
|
82
113
|
);
|
|
83
114
|
const hasPromises = resolutionMapEntries.some(
|
|
84
115
|
([, resolution]) => resolution instanceof Promise
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.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","import { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n */\nexport type Resolver<T> = (context?: ResolutionContext) => T;\n\n/**\n * A function that resolves an instance or a `Promise` of a particular type\n * based on a resolution context passed to it.\n */\nexport type Provider<T> = Resolver<T> & { __brand: \"provider\" };\n\n/**\n * A context used by providers to resolve instances\n * based on current scope and mocks.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Creating a nominal type value and introducing common functionality.\n */\nconst createProvider = <T>(resolver: Resolver<T>): Provider<T> => {\n const instance: Resolver<T> = (context) => {\n const maybeMock = context?.mocks?.get(instance);\n if (maybeMock) return maybeMock(context);\n\n return resolver(context);\n };\n\n return Object.assign(instance, { __brand: \"provider\" as const });\n};\n\n/**\n * Creates a transient provider that will resolve a new instance on each call.\n *\n * @example\n * ```ts\n * const getThing = transient(() => createThing())\n * getThing() !== getThing()\n * ```\n *\n * @param resolver\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n *\n * @returns The transient provider.\n */\nexport const transient = createProvider;\n\n/**\n * Creates a singleton provider that will resolve an instance once\n * and return it on every call.\n *\n * @example\n * ```ts\n * const getThing = singleton(() => createThing())\n * getThing() === getThing()\n * ```\n *\n * @param resolver\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n *\n * @returns The singleton provider.\n */\nexport const singleton = <T>(resolver: Resolver<T>): Provider<T> => {\n let resolved = false;\n let resolution: T | undefined;\n\n const instance = createProvider((context) => {\n if (resolved) return resolution!;\n\n resolution = resolver(context);\n resolved = true;\n\n return resolution;\n });\n\n return instance;\n};\n\n/**\n * Creates a scoped provider that will take its resolution from a passed scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will act as a singleton.\n *\n * @example\n * ```ts\n * const getThing = scoped(() => createThing())\n * getThing() === getThing()\n * ```\n *\n * @example\n * ```ts\n * const getThing = scoped(() => createThing())\n * const scope = createScope()\n * getThing({ scope }) === getThing({ scope }) !== getThing()\n * ```\n *\n * @param resolver\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n *\n * @returns The scoped provider.\n */\nexport const scoped = <T>(resolver: Resolver<T>): Provider<T> => {\n const singletonFallback = singleton(resolver);\n\n const instance = createProvider((context) => {\n if (!context?.scope) return singletonFallback(context);\n\n const resolution = context.scope.has(instance)\n ? context.scope.get(instance)\n : resolver(context);\n context.scope.set(instance, resolution);\n\n return resolution;\n });\n\n return instance;\n};\n","import { Resolver } from \"./provider\";\n\n/**\n * A `Map` of providers to their instances\n * that is then passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n */\nexport type Scope = Map<Resolver<any>, any>;\n\n/**\n * Creates a `Map` of providers to their instances\n * that is then passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n *\n * @example\n * ```ts\n * const requestScope = createScope()\n *\n * app.use(() => {\n * const db = getDb({ scope: requestScope })\n * // ...\n * })\n * ```\n *\n * @returns The map instance.\n */\nexport const createScope = (): Scope => new Map();\n","import { Resolver } from \"./provider\";\n\n/**\n * A `Map` of providers to providers of the same type\n * which is then passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n */\nexport type MockMap = Omit<Map<Resolver<any>, Resolver<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: Resolver<T>, mock: Resolver<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: Resolver<T>): Resolver<T> | undefined;\n};\n\n/**\n * Creates a `Map` of providers to providers of the same type\n * which is then passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n *\n * @example\n * ```ts\n * const mocks = createMockMap()\n * .set(getConfig, getTestConfig)\n *\n * getThing({ mocks })\n * ```\n *\n * @returns The 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 AwaitValuesInCollection<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 * @example\n * Only sync providers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * getB({ scope }),\n * getC({ scope })\n * ]\n * ```\n *\n * @example\n * Some provider is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * await getB({ scope }),\n * getC({ scope })\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): AwaitValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutions = providers.map((provider) => provider(context));\n\n const hasPromises = resolutions.some(\n (resolution) => resolution instanceof Promise,\n );\n\n return (hasPromises ? Promise.all(resolutions) : resolutions) 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 * @example\n * Only sync providers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: getB({ scope }),\n * c: getC({ scope })\n * }\n * ```\n *\n * @example\n * Some provider is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = await resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: await getB({ scope }),\n * c: getC({ scope })\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): AwaitValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutionMapEntries = Object.entries(providers).map(\n ([key, provider]) => [key, provider(context)],\n );\n\n const hasPromises = resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n );\n\n if (hasPromises) {\n return (async () => {\n const awaitedEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n return Object.fromEntries(awaitedEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC2BA,IAAM,iBAAiB,CAAI,aAAuC;AAC9D,QAAM,WAAwB,CAAC,YAAY;AA5B/C;AA6BQ,UAAM,aAAY,wCAAS,UAAT,mBAAgB,IAAI;AACtC,QAAI,UAAW,QAAO,UAAU,OAAO;AAEvC,WAAO,SAAS,OAAO;AAAA,EAC3B;AAEA,SAAO,OAAO,OAAO,UAAU,EAAE,SAAS,WAAoB,CAAC;AACnE;AAiBO,IAAM,YAAY;AAkBlB,IAAM,YAAY,CAAI,aAAuC;AAChE,MAAI,WAAW;AACf,MAAI;AAEJ,QAAM,WAAW,eAAe,CAAC,YAAY;AACzC,QAAI,SAAU,QAAO;AAErB,iBAAa,SAAS,OAAO;AAC7B,eAAW;AAEX,WAAO;AAAA,EACX,CAAC;AAED,SAAO;AACX;AA0BO,IAAM,SAAS,CAAI,aAAuC;AAC7D,QAAM,oBAAoB,UAAU,QAAQ;AAE5C,QAAM,WAAW,eAAe,CAAC,YAAY;AACzC,QAAI,EAAC,mCAAS,OAAO,QAAO,kBAAkB,OAAO;AAErD,UAAM,aAAa,QAAQ,MAAM,IAAI,QAAQ,IACvC,QAAQ,MAAM,IAAI,QAAQ,IAC1B,SAAS,OAAO;AACtB,YAAQ,MAAM,IAAI,UAAU,UAAU;AAEtC,WAAO;AAAA,EACX,CAAC;AAED,SAAO;AACX;;;ACpGO,IAAM,cAAc,MAAa,oBAAI,IAAI;;;ACYzC,IAAM,gBAAgB,MAAe,oBAAI,IAAI;;;ACmC7C,IAAM,cAAc,CACvB,WACA,YAGC;AACD,QAAM,cAAc,UAAU,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAEjE,QAAM,cAAc,YAAY;AAAA,IAC5B,CAAC,eAAe,sBAAsB;AAAA,EAC1C;AAEA,SAAQ,cAAc,QAAQ,IAAI,WAAW,IAAI;AACrD;AAqDO,IAAM,aAAa,CACtB,WACA,YAGC;AACD,QAAM,uBAAuB,OAAO,QAAQ,SAAS,EAAE;AAAA,IACnD,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,OAAO,CAAC;AAAA,EAChD;AAEA,QAAM,cAAc,qBAAqB;AAAA,IACrC,CAAC,CAAC,EAAE,UAAU,MAAM,sBAAsB;AAAA,EAC9C;AAEA,MAAI,aAAa;AACb,YAAQ,YAAY;AAChB,YAAM,iBAAiB,MAAM,QAAQ;AAAA,QACjC,qBAAqB,IAAI,OAAO,CAAC,KAAK,UAAU,MAAM;AAAA,UAClD;AAAA,UACA,MAAM;AAAA,QACV,CAAC;AAAA,MACL;AACA,aAAO,OAAO,YAAY,cAAc;AAAA,IAC5C,GAAG;AAAA,EACP;AAEA,SAAO,OAAO,YAAY,oBAAoB;AAClD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/resolver.ts","../src/scope.ts","../src/mock-map.ts","../src/collection-resolution.ts"],"sourcesContent":["export * from \"./resolver\";\nexport * from \"./scope\";\nexport * from \"./mock-map\";\nexport * from \"./collection-resolution\";\n","import { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A function that takes a resolution context\n * and returns a value of some type.\n */\nexport type ResolverFn<T> = (context?: ResolutionContext) => T;\n\n/**\n * A function that returns a value of some type\n * based on a resolution context.\n */\nexport type Resolver<T> = ResolverFn<T>;\n\n/**\n * A context used by resolvers that defines the behaviour of the resolver\n * with the passed mocks and scope.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Makes the resolver function capable of replacing itself\n * with a mock if one is defined in the resolution context.\n */\nconst mockable = <T>(fn: ResolverFn<T>): ResolverFn<T> => {\n const instance = (context?: ResolutionContext) => {\n const mock = context?.mocks?.get(instance);\n if (!mock) return fn(context);\n\n if (!mock.isPartial) return mock.resolver(context);\n\n const resolution = fn(context);\n const mockResolution = mock.resolver(context);\n\n if (resolution instanceof Promise && mockResolution instanceof Promise)\n return Promise.all([resolution, mockResolution]).then(([a, b]) =>\n Object.assign(a as object, b),\n ) as T;\n\n return Object.assign(resolution as object, mockResolution);\n };\n\n return instance;\n};\n\n/**\n * Creates a resolver that creates a new resolution on each call.\n *\n * @example\n * ```ts\n * const getEntity = transient(() => createEntity())\n * getEntity() !== getEntity()\n * ```\n *\n * @param resolver\n * A function that takes a resolution context\n * and returns a value of some type.\n *\n * @returns The transient resolver.\n */\nexport const transient = <T>(fn: ResolverFn<T>): Resolver<T> => mockable(fn);\n\n/**\n * Creates a resolver that creates\n * a resolution once and return it on each call.\n *\n * @example\n * ```ts\n * const getEntity = singleton(() => createEntity())\n * getEntity() === getEntity()\n * ```\n *\n * @param fn\n * A function that takes a resolution context\n * and returns a value of some type.\n *\n * @returns The singleton resolver.\n */\nexport const singleton = <T>(fn: ResolverFn<T>): Resolver<T> => {\n let resolved = false;\n let resolution: T | undefined;\n\n const instance = mockable((context) => {\n if (resolved) return resolution!;\n\n resolution = fn(context);\n resolved = true;\n\n return resolution;\n });\n\n return instance;\n};\n\n/**\n * Creates a resolver that takes its resolution\n * from a scope or create a new one and save it if there is none.\n * If no scope was passed in a resolution context,\n * it will act as a singleton.\n *\n * @example\n * ```ts\n * const getEntity = scoped(() => createEntity())\n * getEntity() === getEntity()\n * ```\n *\n * @example\n * ```ts\n * const getEntity = scoped(() => createEntity())\n * const scope = createScope()\n * getEntity({ scope }) === getEntity({ scope }) !== getEntity()\n * ```\n *\n * @param fn\n * A function that takes a resolution context\n * and returns a value of some type.\n *\n * @returns The scoped resolver.\n */\nexport const scoped = <T>(fn: ResolverFn<T>): Resolver<T> => {\n const singletonFallback = singleton(fn);\n\n const instance = mockable((context) => {\n if (!context?.scope) return singletonFallback(context);\n\n const resolution = context.scope.has(instance)\n ? context.scope.get(instance)\n : fn(context);\n\n context.scope.set(instance, resolution);\n\n return resolution;\n });\n\n return instance;\n};\n","import { Resolver } from \"./resolver\";\n\n/**\n * A `Map` of resolvers to their resolutions.\n * Is passed in a resolution context and used by scoped resolvers\n * to retrieve or save resolution within it.\n */\nexport type Scope = Map<Resolver<any>, any>;\n\n/**\n * Creates a `Map` of providers to their instances.\n * Is passed in a resolution context and used by scoped resolvers\n * to retrieve or save resolution within it.\n *\n * @example\n * ```ts\n * const requestScope = createScope()\n *\n * app.use(() => {\n * const db = getDb({ scope: requestScope })\n * })\n * ```\n *\n * @returns The map.\n */\nexport const createScope = (): Scope => new Map();\n","import { Resolver } from \"./resolver\";\n\ntype PromiseAwarePartial<T> =\n T extends Promise<infer U> ? Promise<Partial<U>> : Partial<T>;\n\ntype Mock<T> =\n | {\n isPartial: false;\n resolver: Resolver<T>;\n }\n | {\n isPartial: true;\n resolver: Resolver<PromiseAwarePartial<T>>;\n };\n\ntype MocksEntries = [Resolver<any>, Mock<any>][];\n\n/**\n * Immutable map that registers and provides mocks.\n * Is passed in a resolution context and used by resolvers\n * to replace or partially replace themselves with a mock if one is defined.\n */\nexport type MockMap = {\n /**\n * Registers a mock for a resolver,\n * creating a new `MockMap` with this registration.\n *\n * @param original - The original resolver.\n * @param mock - The mock resolver.\n */\n mock<T>(original: Resolver<T>, mock: Resolver<T>): MockMap;\n /**\n * Registers a partial mock for a resolver,\n * creating a new `MockMap` with this registration.\n * In this case, the mock resolver's resolution object will be\n * merged with the original resolver's resolution object,\n * overwriting certain fields.\n *\n * @param original - The original resolver.\n * @param mock - The mock resolver.\n */\n mockPartially<T extends object>(\n original: Resolver<T>,\n mock: Resolver<PromiseAwarePartial<T>>,\n ): MockMap;\n /**\n * Returns a mock of a resolver\n * or `undefined` if one is not registered.\n *\n * @param original - The original resolver.\n */\n get<T>(original: Resolver<T>): Mock<T> | undefined;\n};\n\n/**\n * Internal implementation that accepts entries.\n */\nconst createMockMapWithEntries = (entries: MocksEntries = []): MockMap => {\n const set = (key: Resolver<any>, value: Mock<any>) =>\n createMockMapWithEntries([\n ...entries.filter((entry) => entry[0] !== key),\n [key, value],\n ]);\n\n return {\n mock(original, mock) {\n return set(original, {\n isPartial: false,\n resolver: mock,\n });\n },\n mockPartially(original, mock) {\n return set(original, {\n isPartial: true,\n resolver: mock,\n });\n },\n get(original) {\n return entries.find((entry) => entry[0] === original)?.[1] as any;\n },\n };\n};\n\n/**\n * Creates a mock map, an immutable map that registers and provides mocks.\n * Is passed in a resolution context and used by resolvers\n * to replace or partially replace themselves with a mock if one is defined.\n *\n * @example\n * ```ts\n * const mocks = createMockMap()\n * .mock(getDependency, getDependencyMock)\n * .mockPartially(\n * getOtherDepedency,\n * transient(() => ({ someField: \"mock\" }))\n * )\n *\n * const entityWithMocks = getEntity({ mocks })\n * ```\n *\n * @returns The mock map.\n */\nexport const createMockMap = (): MockMap => createMockMapWithEntries();\n","import { ResolutionContext, Resolver } from \"./resolver\";\n\ntype ResolverList = Resolver<any>[];\ntype ResolverRecord = Record<string, Resolver<any>>;\n\ntype InferResolverCollectionResolutions<\n Resolvers extends ResolverList | ResolverRecord,\n> = {\n [K in keyof Resolvers]: Resolvers[K] extends Resolver<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 AwaitValuesInCollection<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 resolver 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 * @example\n * Only sync resolvers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * getB({ scope }),\n * getC({ scope })\n * ]\n * ```\n *\n * @example\n * Some resolver is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * await getB({ scope }),\n * getC({ scope })\n * ]\n * ```\n *\n * @param resolvers - The list of resolvers.\n * @param context - The resolution context.\n *\n * @returns The list of resolutions.\n */\nexport const resolveList = <const Resolvers extends ResolverList>(\n resolvers: Resolvers,\n context?: ResolutionContext,\n): AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>> => {\n const resolutions = resolvers.map((resolver) => resolver(context));\n\n const hasPromises = resolutions.some(\n (resolution) => resolution instanceof Promise,\n );\n\n return (hasPromises ? Promise.all(resolutions) : resolutions) as any;\n};\n\n/**\n * Calls every resolver 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 * @example\n * Only sync resolvers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: getB({ scope }),\n * c: getC({ scope })\n * }\n * ```\n *\n * @example\n * Some resolver is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = await resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: await getB({ scope }),\n * c: getC({ scope })\n * }\n * ```\n *\n * @param resolvers - The map of resolvers.\n * @param context - The resolution context.\n *\n * @returns The map of resolutions.\n */\nexport const resolveMap = <const Resolvers extends ResolverRecord>(\n resolvers: Resolvers,\n context?: ResolutionContext,\n): AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>> => {\n const resolutionMapEntries = Object.entries(resolvers).map(\n ([key, resolver]) => [key, resolver(context)],\n );\n\n const hasPromises = resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n );\n\n if (hasPromises) {\n return (async () => {\n const awaitedEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n return Object.fromEntries(awaitedEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,30 +1,37 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var
|
|
1
|
+
// src/resolver.ts
|
|
2
|
+
var mockable = (fn) => {
|
|
3
3
|
const instance = (context) => {
|
|
4
4
|
var _a;
|
|
5
|
-
const
|
|
6
|
-
if (
|
|
7
|
-
return resolver(context);
|
|
5
|
+
const mock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
|
6
|
+
if (!mock) return fn(context);
|
|
7
|
+
if (!mock.isPartial) return mock.resolver(context);
|
|
8
|
+
const resolution = fn(context);
|
|
9
|
+
const mockResolution = mock.resolver(context);
|
|
10
|
+
if (resolution instanceof Promise && mockResolution instanceof Promise)
|
|
11
|
+
return Promise.all([resolution, mockResolution]).then(
|
|
12
|
+
([a, b]) => Object.assign(a, b)
|
|
13
|
+
);
|
|
14
|
+
return Object.assign(resolution, mockResolution);
|
|
8
15
|
};
|
|
9
|
-
return
|
|
16
|
+
return instance;
|
|
10
17
|
};
|
|
11
|
-
var transient =
|
|
12
|
-
var singleton = (
|
|
18
|
+
var transient = (fn) => mockable(fn);
|
|
19
|
+
var singleton = (fn) => {
|
|
13
20
|
let resolved = false;
|
|
14
21
|
let resolution;
|
|
15
|
-
const instance =
|
|
22
|
+
const instance = mockable((context) => {
|
|
16
23
|
if (resolved) return resolution;
|
|
17
|
-
resolution =
|
|
24
|
+
resolution = fn(context);
|
|
18
25
|
resolved = true;
|
|
19
26
|
return resolution;
|
|
20
27
|
});
|
|
21
28
|
return instance;
|
|
22
29
|
};
|
|
23
|
-
var scoped = (
|
|
24
|
-
const singletonFallback = singleton(
|
|
25
|
-
const instance =
|
|
30
|
+
var scoped = (fn) => {
|
|
31
|
+
const singletonFallback = singleton(fn);
|
|
32
|
+
const instance = mockable((context) => {
|
|
26
33
|
if (!(context == null ? void 0 : context.scope)) return singletonFallback(context);
|
|
27
|
-
const resolution = context.scope.has(instance) ? context.scope.get(instance) :
|
|
34
|
+
const resolution = context.scope.has(instance) ? context.scope.get(instance) : fn(context);
|
|
28
35
|
context.scope.set(instance, resolution);
|
|
29
36
|
return resolution;
|
|
30
37
|
});
|
|
@@ -35,19 +42,43 @@ var scoped = (resolver) => {
|
|
|
35
42
|
var createScope = () => /* @__PURE__ */ new Map();
|
|
36
43
|
|
|
37
44
|
// src/mock-map.ts
|
|
38
|
-
var
|
|
45
|
+
var createMockMapWithEntries = (entries = []) => {
|
|
46
|
+
const set = (key, value) => createMockMapWithEntries([
|
|
47
|
+
...entries.filter((entry) => entry[0] !== key),
|
|
48
|
+
[key, value]
|
|
49
|
+
]);
|
|
50
|
+
return {
|
|
51
|
+
mock(original, mock) {
|
|
52
|
+
return set(original, {
|
|
53
|
+
isPartial: false,
|
|
54
|
+
resolver: mock
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
mockPartially(original, mock) {
|
|
58
|
+
return set(original, {
|
|
59
|
+
isPartial: true,
|
|
60
|
+
resolver: mock
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
get(original) {
|
|
64
|
+
var _a;
|
|
65
|
+
return (_a = entries.find((entry) => entry[0] === original)) == null ? void 0 : _a[1];
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
var createMockMap = () => createMockMapWithEntries();
|
|
39
70
|
|
|
40
71
|
// src/collection-resolution.ts
|
|
41
|
-
var resolveList = (
|
|
42
|
-
const resolutions =
|
|
72
|
+
var resolveList = (resolvers, context) => {
|
|
73
|
+
const resolutions = resolvers.map((resolver) => resolver(context));
|
|
43
74
|
const hasPromises = resolutions.some(
|
|
44
75
|
(resolution) => resolution instanceof Promise
|
|
45
76
|
);
|
|
46
77
|
return hasPromises ? Promise.all(resolutions) : resolutions;
|
|
47
78
|
};
|
|
48
|
-
var resolveMap = (
|
|
49
|
-
const resolutionMapEntries = Object.entries(
|
|
50
|
-
([key,
|
|
79
|
+
var resolveMap = (resolvers, context) => {
|
|
80
|
+
const resolutionMapEntries = Object.entries(resolvers).map(
|
|
81
|
+
([key, resolver]) => [key, resolver(context)]
|
|
51
82
|
);
|
|
52
83
|
const hasPromises = resolutionMapEntries.some(
|
|
53
84
|
([, resolution]) => resolution instanceof Promise
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.ts","../src/scope.ts","../src/mock-map.ts","../src/collection-resolution.ts"],"sourcesContent":["import { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n */\nexport type Resolver<T> = (context?: ResolutionContext) => T;\n\n/**\n * A function that resolves an instance or a `Promise` of a particular type\n * based on a resolution context passed to it.\n */\nexport type Provider<T> = Resolver<T> & { __brand: \"provider\" };\n\n/**\n * A context used by providers to resolve instances\n * based on current scope and mocks.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Creating a nominal type value and introducing common functionality.\n */\nconst createProvider = <T>(resolver: Resolver<T>): Provider<T> => {\n const instance: Resolver<T> = (context) => {\n const maybeMock = context?.mocks?.get(instance);\n if (maybeMock) return maybeMock(context);\n\n return resolver(context);\n };\n\n return Object.assign(instance, { __brand: \"provider\" as const });\n};\n\n/**\n * Creates a transient provider that will resolve a new instance on each call.\n *\n * @example\n * ```ts\n * const getThing = transient(() => createThing())\n * getThing() !== getThing()\n * ```\n *\n * @param resolver\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n *\n * @returns The transient provider.\n */\nexport const transient = createProvider;\n\n/**\n * Creates a singleton provider that will resolve an instance once\n * and return it on every call.\n *\n * @example\n * ```ts\n * const getThing = singleton(() => createThing())\n * getThing() === getThing()\n * ```\n *\n * @param resolver\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n *\n * @returns The singleton provider.\n */\nexport const singleton = <T>(resolver: Resolver<T>): Provider<T> => {\n let resolved = false;\n let resolution: T | undefined;\n\n const instance = createProvider((context) => {\n if (resolved) return resolution!;\n\n resolution = resolver(context);\n resolved = true;\n\n return resolution;\n });\n\n return instance;\n};\n\n/**\n * Creates a scoped provider that will take its resolution from a passed scope\n * or create a new one and save it if there is none.\n * If no scope is passed, it will act as a singleton.\n *\n * @example\n * ```ts\n * const getThing = scoped(() => createThing())\n * getThing() === getThing()\n * ```\n *\n * @example\n * ```ts\n * const getThing = scoped(() => createThing())\n * const scope = createScope()\n * getThing({ scope }) === getThing({ scope }) !== getThing()\n * ```\n *\n * @param resolver\n * A function that returns a value of a particular type\n * with a resolution context being passed to it.\n *\n * @returns The scoped provider.\n */\nexport const scoped = <T>(resolver: Resolver<T>): Provider<T> => {\n const singletonFallback = singleton(resolver);\n\n const instance = createProvider((context) => {\n if (!context?.scope) return singletonFallback(context);\n\n const resolution = context.scope.has(instance)\n ? context.scope.get(instance)\n : resolver(context);\n context.scope.set(instance, resolution);\n\n return resolution;\n });\n\n return instance;\n};\n","import { Resolver } from \"./provider\";\n\n/**\n * A `Map` of providers to their instances\n * that is then passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n */\nexport type Scope = Map<Resolver<any>, any>;\n\n/**\n * Creates a `Map` of providers to their instances\n * that is then passed to a provider call in a resolution context object\n * to resolve instances of scoped providers within it.\n *\n * @example\n * ```ts\n * const requestScope = createScope()\n *\n * app.use(() => {\n * const db = getDb({ scope: requestScope })\n * // ...\n * })\n * ```\n *\n * @returns The map instance.\n */\nexport const createScope = (): Scope => new Map();\n","import { Resolver } from \"./provider\";\n\n/**\n * A `Map` of providers to providers of the same type\n * which is then passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n */\nexport type MockMap = Omit<Map<Resolver<any>, Resolver<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: Resolver<T>, mock: Resolver<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: Resolver<T>): Resolver<T> | undefined;\n};\n\n/**\n * Creates a `Map` of providers to providers of the same type\n * which is then passed to a provider call in a resolution context object\n * in order to replace providers with their mocks.\n *\n * @example\n * ```ts\n * const mocks = createMockMap()\n * .set(getConfig, getTestConfig)\n *\n * getThing({ mocks })\n * ```\n *\n * @returns The 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 AwaitValuesInCollection<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 * @example\n * Only sync providers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * getB({ scope }),\n * getC({ scope })\n * ]\n * ```\n *\n * @example\n * Some provider is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * await getB({ scope }),\n * getC({ scope })\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): AwaitValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutions = providers.map((provider) => provider(context));\n\n const hasPromises = resolutions.some(\n (resolution) => resolution instanceof Promise,\n );\n\n return (hasPromises ? Promise.all(resolutions) : resolutions) 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 * @example\n * Only sync providers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: getB({ scope }),\n * c: getC({ scope })\n * }\n * ```\n *\n * @example\n * Some provider is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = await resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: await getB({ scope }),\n * c: getC({ scope })\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): AwaitValuesInCollection<\n InferProviderCollectionResolutions<Providers>\n> => {\n const resolutionMapEntries = Object.entries(providers).map(\n ([key, provider]) => [key, provider(context)],\n );\n\n const hasPromises = resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n );\n\n if (hasPromises) {\n return (async () => {\n const awaitedEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n return Object.fromEntries(awaitedEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":";AA2BA,IAAM,iBAAiB,CAAI,aAAuC;AAC9D,QAAM,WAAwB,CAAC,YAAY;AA5B/C;AA6BQ,UAAM,aAAY,wCAAS,UAAT,mBAAgB,IAAI;AACtC,QAAI,UAAW,QAAO,UAAU,OAAO;AAEvC,WAAO,SAAS,OAAO;AAAA,EAC3B;AAEA,SAAO,OAAO,OAAO,UAAU,EAAE,SAAS,WAAoB,CAAC;AACnE;AAiBO,IAAM,YAAY;AAkBlB,IAAM,YAAY,CAAI,aAAuC;AAChE,MAAI,WAAW;AACf,MAAI;AAEJ,QAAM,WAAW,eAAe,CAAC,YAAY;AACzC,QAAI,SAAU,QAAO;AAErB,iBAAa,SAAS,OAAO;AAC7B,eAAW;AAEX,WAAO;AAAA,EACX,CAAC;AAED,SAAO;AACX;AA0BO,IAAM,SAAS,CAAI,aAAuC;AAC7D,QAAM,oBAAoB,UAAU,QAAQ;AAE5C,QAAM,WAAW,eAAe,CAAC,YAAY;AACzC,QAAI,EAAC,mCAAS,OAAO,QAAO,kBAAkB,OAAO;AAErD,UAAM,aAAa,QAAQ,MAAM,IAAI,QAAQ,IACvC,QAAQ,MAAM,IAAI,QAAQ,IAC1B,SAAS,OAAO;AACtB,YAAQ,MAAM,IAAI,UAAU,UAAU;AAEtC,WAAO;AAAA,EACX,CAAC;AAED,SAAO;AACX;;;ACpGO,IAAM,cAAc,MAAa,oBAAI,IAAI;;;ACYzC,IAAM,gBAAgB,MAAe,oBAAI,IAAI;;;ACmC7C,IAAM,cAAc,CACvB,WACA,YAGC;AACD,QAAM,cAAc,UAAU,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAEjE,QAAM,cAAc,YAAY;AAAA,IAC5B,CAAC,eAAe,sBAAsB;AAAA,EAC1C;AAEA,SAAQ,cAAc,QAAQ,IAAI,WAAW,IAAI;AACrD;AAqDO,IAAM,aAAa,CACtB,WACA,YAGC;AACD,QAAM,uBAAuB,OAAO,QAAQ,SAAS,EAAE;AAAA,IACnD,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,OAAO,CAAC;AAAA,EAChD;AAEA,QAAM,cAAc,qBAAqB;AAAA,IACrC,CAAC,CAAC,EAAE,UAAU,MAAM,sBAAsB;AAAA,EAC9C;AAEA,MAAI,aAAa;AACb,YAAQ,YAAY;AAChB,YAAM,iBAAiB,MAAM,QAAQ;AAAA,QACjC,qBAAqB,IAAI,OAAO,CAAC,KAAK,UAAU,MAAM;AAAA,UAClD;AAAA,UACA,MAAM;AAAA,QACV,CAAC;AAAA,MACL;AACA,aAAO,OAAO,YAAY,cAAc;AAAA,IAC5C,GAAG;AAAA,EACP;AAEA,SAAO,OAAO,YAAY,oBAAoB;AAClD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/resolver.ts","../src/scope.ts","../src/mock-map.ts","../src/collection-resolution.ts"],"sourcesContent":["import { MockMap } from \"./mock-map\";\nimport { Scope } from \"./scope\";\n\n/**\n * A function that takes a resolution context\n * and returns a value of some type.\n */\nexport type ResolverFn<T> = (context?: ResolutionContext) => T;\n\n/**\n * A function that returns a value of some type\n * based on a resolution context.\n */\nexport type Resolver<T> = ResolverFn<T>;\n\n/**\n * A context used by resolvers that defines the behaviour of the resolver\n * with the passed mocks and scope.\n */\nexport type ResolutionContext = {\n scope?: Scope;\n mocks?: MockMap;\n};\n\n/**\n * Makes the resolver function capable of replacing itself\n * with a mock if one is defined in the resolution context.\n */\nconst mockable = <T>(fn: ResolverFn<T>): ResolverFn<T> => {\n const instance = (context?: ResolutionContext) => {\n const mock = context?.mocks?.get(instance);\n if (!mock) return fn(context);\n\n if (!mock.isPartial) return mock.resolver(context);\n\n const resolution = fn(context);\n const mockResolution = mock.resolver(context);\n\n if (resolution instanceof Promise && mockResolution instanceof Promise)\n return Promise.all([resolution, mockResolution]).then(([a, b]) =>\n Object.assign(a as object, b),\n ) as T;\n\n return Object.assign(resolution as object, mockResolution);\n };\n\n return instance;\n};\n\n/**\n * Creates a resolver that creates a new resolution on each call.\n *\n * @example\n * ```ts\n * const getEntity = transient(() => createEntity())\n * getEntity() !== getEntity()\n * ```\n *\n * @param resolver\n * A function that takes a resolution context\n * and returns a value of some type.\n *\n * @returns The transient resolver.\n */\nexport const transient = <T>(fn: ResolverFn<T>): Resolver<T> => mockable(fn);\n\n/**\n * Creates a resolver that creates\n * a resolution once and return it on each call.\n *\n * @example\n * ```ts\n * const getEntity = singleton(() => createEntity())\n * getEntity() === getEntity()\n * ```\n *\n * @param fn\n * A function that takes a resolution context\n * and returns a value of some type.\n *\n * @returns The singleton resolver.\n */\nexport const singleton = <T>(fn: ResolverFn<T>): Resolver<T> => {\n let resolved = false;\n let resolution: T | undefined;\n\n const instance = mockable((context) => {\n if (resolved) return resolution!;\n\n resolution = fn(context);\n resolved = true;\n\n return resolution;\n });\n\n return instance;\n};\n\n/**\n * Creates a resolver that takes its resolution\n * from a scope or create a new one and save it if there is none.\n * If no scope was passed in a resolution context,\n * it will act as a singleton.\n *\n * @example\n * ```ts\n * const getEntity = scoped(() => createEntity())\n * getEntity() === getEntity()\n * ```\n *\n * @example\n * ```ts\n * const getEntity = scoped(() => createEntity())\n * const scope = createScope()\n * getEntity({ scope }) === getEntity({ scope }) !== getEntity()\n * ```\n *\n * @param fn\n * A function that takes a resolution context\n * and returns a value of some type.\n *\n * @returns The scoped resolver.\n */\nexport const scoped = <T>(fn: ResolverFn<T>): Resolver<T> => {\n const singletonFallback = singleton(fn);\n\n const instance = mockable((context) => {\n if (!context?.scope) return singletonFallback(context);\n\n const resolution = context.scope.has(instance)\n ? context.scope.get(instance)\n : fn(context);\n\n context.scope.set(instance, resolution);\n\n return resolution;\n });\n\n return instance;\n};\n","import { Resolver } from \"./resolver\";\n\n/**\n * A `Map` of resolvers to their resolutions.\n * Is passed in a resolution context and used by scoped resolvers\n * to retrieve or save resolution within it.\n */\nexport type Scope = Map<Resolver<any>, any>;\n\n/**\n * Creates a `Map` of providers to their instances.\n * Is passed in a resolution context and used by scoped resolvers\n * to retrieve or save resolution within it.\n *\n * @example\n * ```ts\n * const requestScope = createScope()\n *\n * app.use(() => {\n * const db = getDb({ scope: requestScope })\n * })\n * ```\n *\n * @returns The map.\n */\nexport const createScope = (): Scope => new Map();\n","import { Resolver } from \"./resolver\";\n\ntype PromiseAwarePartial<T> =\n T extends Promise<infer U> ? Promise<Partial<U>> : Partial<T>;\n\ntype Mock<T> =\n | {\n isPartial: false;\n resolver: Resolver<T>;\n }\n | {\n isPartial: true;\n resolver: Resolver<PromiseAwarePartial<T>>;\n };\n\ntype MocksEntries = [Resolver<any>, Mock<any>][];\n\n/**\n * Immutable map that registers and provides mocks.\n * Is passed in a resolution context and used by resolvers\n * to replace or partially replace themselves with a mock if one is defined.\n */\nexport type MockMap = {\n /**\n * Registers a mock for a resolver,\n * creating a new `MockMap` with this registration.\n *\n * @param original - The original resolver.\n * @param mock - The mock resolver.\n */\n mock<T>(original: Resolver<T>, mock: Resolver<T>): MockMap;\n /**\n * Registers a partial mock for a resolver,\n * creating a new `MockMap` with this registration.\n * In this case, the mock resolver's resolution object will be\n * merged with the original resolver's resolution object,\n * overwriting certain fields.\n *\n * @param original - The original resolver.\n * @param mock - The mock resolver.\n */\n mockPartially<T extends object>(\n original: Resolver<T>,\n mock: Resolver<PromiseAwarePartial<T>>,\n ): MockMap;\n /**\n * Returns a mock of a resolver\n * or `undefined` if one is not registered.\n *\n * @param original - The original resolver.\n */\n get<T>(original: Resolver<T>): Mock<T> | undefined;\n};\n\n/**\n * Internal implementation that accepts entries.\n */\nconst createMockMapWithEntries = (entries: MocksEntries = []): MockMap => {\n const set = (key: Resolver<any>, value: Mock<any>) =>\n createMockMapWithEntries([\n ...entries.filter((entry) => entry[0] !== key),\n [key, value],\n ]);\n\n return {\n mock(original, mock) {\n return set(original, {\n isPartial: false,\n resolver: mock,\n });\n },\n mockPartially(original, mock) {\n return set(original, {\n isPartial: true,\n resolver: mock,\n });\n },\n get(original) {\n return entries.find((entry) => entry[0] === original)?.[1] as any;\n },\n };\n};\n\n/**\n * Creates a mock map, an immutable map that registers and provides mocks.\n * Is passed in a resolution context and used by resolvers\n * to replace or partially replace themselves with a mock if one is defined.\n *\n * @example\n * ```ts\n * const mocks = createMockMap()\n * .mock(getDependency, getDependencyMock)\n * .mockPartially(\n * getOtherDepedency,\n * transient(() => ({ someField: \"mock\" }))\n * )\n *\n * const entityWithMocks = getEntity({ mocks })\n * ```\n *\n * @returns The mock map.\n */\nexport const createMockMap = (): MockMap => createMockMapWithEntries();\n","import { ResolutionContext, Resolver } from \"./resolver\";\n\ntype ResolverList = Resolver<any>[];\ntype ResolverRecord = Record<string, Resolver<any>>;\n\ntype InferResolverCollectionResolutions<\n Resolvers extends ResolverList | ResolverRecord,\n> = {\n [K in keyof Resolvers]: Resolvers[K] extends Resolver<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 AwaitValuesInCollection<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 resolver 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 * @example\n * Only sync resolvers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * getB({ scope }),\n * getC({ scope })\n * ]\n * ```\n *\n * @example\n * Some resolver is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveList(\n * [getA, getB, getC],\n * { scope }\n * )\n *\n * resolutions == [\n * getA({ scope }),\n * await getB({ scope }),\n * getC({ scope })\n * ]\n * ```\n *\n * @param resolvers - The list of resolvers.\n * @param context - The resolution context.\n *\n * @returns The list of resolutions.\n */\nexport const resolveList = <const Resolvers extends ResolverList>(\n resolvers: Resolvers,\n context?: ResolutionContext,\n): AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>> => {\n const resolutions = resolvers.map((resolver) => resolver(context));\n\n const hasPromises = resolutions.some(\n (resolution) => resolution instanceof Promise,\n );\n\n return (hasPromises ? Promise.all(resolutions) : resolutions) as any;\n};\n\n/**\n * Calls every resolver 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 * @example\n * Only sync resolvers:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(() => createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: getB({ scope }),\n * c: getC({ scope })\n * }\n * ```\n *\n * @example\n * Some resolver is async:\n * ```ts\n * const getA = scoped(() => createA())\n * const getB = scoped(async () => await createB())\n * const getC = scoped(() => createC())\n *\n * const scope = createScope()\n * const resolutions = await resolveMap(\n * { a: getA, b: getB, c: getC },\n * { scope }\n * )\n *\n * resolutions == {\n * a: getA({ scope }),\n * b: await getB({ scope }),\n * c: getC({ scope })\n * }\n * ```\n *\n * @param resolvers - The map of resolvers.\n * @param context - The resolution context.\n *\n * @returns The map of resolutions.\n */\nexport const resolveMap = <const Resolvers extends ResolverRecord>(\n resolvers: Resolvers,\n context?: ResolutionContext,\n): AwaitValuesInCollection<InferResolverCollectionResolutions<Resolvers>> => {\n const resolutionMapEntries = Object.entries(resolvers).map(\n ([key, resolver]) => [key, resolver(context)],\n );\n\n const hasPromises = resolutionMapEntries.some(\n ([, resolution]) => resolution instanceof Promise,\n );\n\n if (hasPromises) {\n return (async () => {\n const awaitedEntries = await Promise.all(\n resolutionMapEntries.map(async ([key, resolution]) => [\n key,\n await resolution,\n ]),\n );\n return Object.fromEntries(awaitedEntries);\n })() as any;\n }\n\n return Object.fromEntries(resolutionMapEntries);\n};\n"],"mappings":";AA4BA,IAAM,WAAW,CAAI,OAAqC;AACtD,QAAM,WAAW,CAAC,YAAgC;AA7BtD;AA8BQ,UAAM,QAAO,wCAAS,UAAT,mBAAgB,IAAI;AACjC,QAAI,CAAC,KAAM,QAAO,GAAG,OAAO;AAE5B,QAAI,CAAC,KAAK,UAAW,QAAO,KAAK,SAAS,OAAO;AAEjD,UAAM,aAAa,GAAG,OAAO;AAC7B,UAAM,iBAAiB,KAAK,SAAS,OAAO;AAE5C,QAAI,sBAAsB,WAAW,0BAA0B;AAC3D,aAAO,QAAQ,IAAI,CAAC,YAAY,cAAc,CAAC,EAAE;AAAA,QAAK,CAAC,CAAC,GAAG,CAAC,MACxD,OAAO,OAAO,GAAa,CAAC;AAAA,MAChC;AAEJ,WAAO,OAAO,OAAO,YAAsB,cAAc;AAAA,EAC7D;AAEA,SAAO;AACX;AAiBO,IAAM,YAAY,CAAI,OAAmC,SAAS,EAAE;AAkBpE,IAAM,YAAY,CAAI,OAAmC;AAC5D,MAAI,WAAW;AACf,MAAI;AAEJ,QAAM,WAAW,SAAS,CAAC,YAAY;AACnC,QAAI,SAAU,QAAO;AAErB,iBAAa,GAAG,OAAO;AACvB,eAAW;AAEX,WAAO;AAAA,EACX,CAAC;AAED,SAAO;AACX;AA2BO,IAAM,SAAS,CAAI,OAAmC;AACzD,QAAM,oBAAoB,UAAU,EAAE;AAEtC,QAAM,WAAW,SAAS,CAAC,YAAY;AACnC,QAAI,EAAC,mCAAS,OAAO,QAAO,kBAAkB,OAAO;AAErD,UAAM,aAAa,QAAQ,MAAM,IAAI,QAAQ,IACvC,QAAQ,MAAM,IAAI,QAAQ,IAC1B,GAAG,OAAO;AAEhB,YAAQ,MAAM,IAAI,UAAU,UAAU;AAEtC,WAAO;AAAA,EACX,CAAC;AAED,SAAO;AACX;;;AClHO,IAAM,cAAc,MAAa,oBAAI,IAAI;;;ACgChD,IAAM,2BAA2B,CAAC,UAAwB,CAAC,MAAe;AACtE,QAAM,MAAM,CAAC,KAAoB,UAC7B,yBAAyB;AAAA,IACrB,GAAG,QAAQ,OAAO,CAAC,UAAU,MAAM,CAAC,MAAM,GAAG;AAAA,IAC7C,CAAC,KAAK,KAAK;AAAA,EACf,CAAC;AAEL,SAAO;AAAA,IACH,KAAK,UAAU,MAAM;AACjB,aAAO,IAAI,UAAU;AAAA,QACjB,WAAW;AAAA,QACX,UAAU;AAAA,MACd,CAAC;AAAA,IACL;AAAA,IACA,cAAc,UAAU,MAAM;AAC1B,aAAO,IAAI,UAAU;AAAA,QACjB,WAAW;AAAA,QACX,UAAU;AAAA,MACd,CAAC;AAAA,IACL;AAAA,IACA,IAAI,UAAU;AA7EtB;AA8EY,cAAO,aAAQ,KAAK,CAAC,UAAU,MAAM,CAAC,MAAM,QAAQ,MAA7C,mBAAiD;AAAA,IAC5D;AAAA,EACJ;AACJ;AAqBO,IAAM,gBAAgB,MAAe,yBAAyB;;;AC7B9D,IAAM,cAAc,CACvB,WACA,YACyE;AACzE,QAAM,cAAc,UAAU,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAEjE,QAAM,cAAc,YAAY;AAAA,IAC5B,CAAC,eAAe,sBAAsB;AAAA,EAC1C;AAEA,SAAQ,cAAc,QAAQ,IAAI,WAAW,IAAI;AACrD;AAqDO,IAAM,aAAa,CACtB,WACA,YACyE;AACzE,QAAM,uBAAuB,OAAO,QAAQ,SAAS,EAAE;AAAA,IACnD,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,OAAO,CAAC;AAAA,EAChD;AAEA,QAAM,cAAc,qBAAqB;AAAA,IACrC,CAAC,CAAC,EAAE,UAAU,MAAM,sBAAsB;AAAA,EAC9C;AAEA,MAAI,aAAa;AACb,YAAQ,YAAY;AAChB,YAAM,iBAAiB,MAAM,QAAQ;AAAA,QACjC,qBAAqB,IAAI,OAAO,CAAC,KAAK,UAAU,MAAM;AAAA,UAClD;AAAA,UACA,MAAM;AAAA,QACV,CAAC;AAAA,MACL;AACA,aAAO,OAAO,YAAY,cAAc;AAAA,IAC5C,GAAG;AAAA,EACP;AAEA,SAAO,OAAO,YAAY,oBAAoB;AAClD;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atomic-di",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "Lifetimes, scopes and mocking for pure dependency injection
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "Lifetimes, scopes and mocking for pure dependency injection",
|
|
5
5
|
"repository": "https://github.com/ncor/atomic-di",
|
|
6
6
|
"bugs": "https://github.com/ncor/atomic-di/issues",
|
|
7
7
|
"homepage": "https://github.com/ncor/atomic-di#readme",
|