atomic-di 0.9.1-beta.3 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +468 -102
- package/dist/index.d.mts +160 -126
- package/dist/index.d.ts +160 -126
- package/dist/index.js +41 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +41 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
@@ -1,185 +1,139 @@
|
|
1
1
|
/**
|
2
|
-
* A
|
3
|
-
*
|
4
|
-
* a different one if necessary.
|
5
|
-
*
|
6
|
-
* Passed to a provider call in a resolution context object
|
2
|
+
* A `Map` of providers to providers of the same type
|
3
|
+
* which is then passed to a provider call in a resolution context object
|
7
4
|
* in order to replace providers with their mocks.
|
8
|
-
* ```ts
|
9
|
-
* const otherProvider =
|
10
|
-
* transitive(() => ...)
|
11
|
-
* const otherProviderMock: typeof otherProvider =
|
12
|
-
* scoped(() => ...)
|
13
|
-
*
|
14
|
-
* const mocks = createMockMap()
|
15
|
-
* mocks.set(otherProvider, otherProviderMock)
|
16
|
-
*
|
17
|
-
* provider({ mocks })
|
18
|
-
* ```
|
19
5
|
*/
|
20
|
-
type MockMap = Omit<Map<
|
6
|
+
type MockMap = Omit<Map<Resolver<any>, Resolver<any>>, "set" | "get"> & {
|
21
7
|
/**
|
22
8
|
* Sets a mock for a provider.
|
23
9
|
*
|
24
10
|
* @param provider - The original provider.
|
25
11
|
* @param mock - The mock provider.
|
26
12
|
*/
|
27
|
-
set<T>(provider:
|
13
|
+
set<T>(provider: Resolver<T>, mock: Resolver<T>): MockMap;
|
28
14
|
/**
|
29
15
|
* Retrieves a mock of a provider. Returns undefined if there's none.
|
30
16
|
*
|
31
17
|
* @param provider - The provider.
|
32
18
|
*/
|
33
|
-
get<T>(provider:
|
19
|
+
get<T>(provider: Resolver<T>): Resolver<T> | undefined;
|
34
20
|
};
|
35
21
|
/**
|
36
|
-
* Creates a
|
37
|
-
*
|
38
|
-
* Lifetime is not a part of `Provider` type, so you can use
|
39
|
-
* a different one if necessary.
|
40
|
-
*
|
41
|
-
* Passed to a provider call in a resolution context object
|
22
|
+
* Creates a `Map` of providers to providers of the same type
|
23
|
+
* which is then passed to a provider call in a resolution context object
|
42
24
|
* in order to replace providers with their mocks.
|
43
|
-
* ```ts
|
44
|
-
* const otherProvider =
|
45
|
-
* transitive(() => ...)
|
46
|
-
* const otherProviderMock: typeof otherProvider =
|
47
|
-
* scoped(() => ...)
|
48
25
|
*
|
26
|
+
* @example
|
27
|
+
* ```ts
|
49
28
|
* const mocks = createMockMap()
|
50
|
-
*
|
29
|
+
* .set(getConfig, getTestConfig)
|
51
30
|
*
|
52
|
-
*
|
31
|
+
* getThing({ mocks })
|
53
32
|
* ```
|
54
33
|
*
|
55
|
-
* @returns The
|
34
|
+
* @returns The map instance.
|
56
35
|
*/
|
57
36
|
declare const createMockMap: () => MockMap;
|
58
37
|
|
59
38
|
/**
|
60
|
-
* A
|
61
|
-
*
|
62
|
-
* Passed to a provider call in a resolution context object
|
39
|
+
* A `Map` of providers to their instances
|
40
|
+
* that is then passed to a provider call in a resolution context object
|
63
41
|
* to resolve instances of scoped providers within it.
|
64
|
-
* ```ts
|
65
|
-
* const scope = createScope()
|
66
|
-
* provider({ scope })
|
67
|
-
* ```
|
68
42
|
*/
|
69
|
-
type Scope = Map<
|
43
|
+
type Scope = Map<Resolver<any>, any>;
|
70
44
|
/**
|
71
|
-
* Creates a
|
72
|
-
*
|
73
|
-
* Scope is passed to a provider call in a resolution context object
|
45
|
+
* Creates a `Map` of providers to their instances
|
46
|
+
* that is then passed to a provider call in a resolution context object
|
74
47
|
* to resolve instances of scoped providers within it.
|
48
|
+
*
|
49
|
+
* @example
|
75
50
|
* ```ts
|
76
|
-
* const
|
77
|
-
*
|
51
|
+
* const requestScope = createScope()
|
52
|
+
*
|
53
|
+
* app.use(() => {
|
54
|
+
* const db = getDb({ scope: requestScope })
|
55
|
+
* // ...
|
56
|
+
* })
|
78
57
|
* ```
|
79
58
|
*
|
80
|
-
* @returns The
|
59
|
+
* @returns The map instance.
|
81
60
|
*/
|
82
61
|
declare const createScope: () => Scope;
|
83
62
|
|
84
63
|
/**
|
85
|
-
* A
|
86
|
-
*
|
87
|
-
* Resolves an instance by calling a resolver
|
88
|
-
* with a resolution context that will be propagated
|
89
|
-
* throughout a dependency tree.
|
90
|
-
*
|
91
|
-
* When passing a scope it will try to get an instance from it
|
92
|
-
* or create a new one and put it there.
|
93
|
-
*
|
94
|
-
* When passing mocks, it will try to get its own mock version,
|
95
|
-
* and if there is one, it will use it instead of itself.
|
96
|
-
*/
|
97
|
-
type Provider<T> = (context?: ResolutionContext) => T;
|
98
|
-
/**
|
99
|
-
* A resolution lifetime.
|
100
|
-
*
|
101
|
-
* Passed when creating a provider to determine its behavior.
|
102
|
-
*
|
103
|
-
* `"transient"` doesn't provide any modifications to a resolver behaviour,
|
104
|
-
* so the resolver will create a new instance on each request.
|
105
|
-
*
|
106
|
-
* `"singleton"` forces the resolver to create an instance once
|
107
|
-
* and return it in subsequent requests.
|
108
|
-
*
|
109
|
-
* `"scoped"` forces the resolver to take its instance from a provided scope
|
110
|
-
* or create a new one and save it if there is none.
|
111
|
-
* If no scope is passed, it will create a new instance on each request.
|
64
|
+
* A function that returns a value of a particular type
|
65
|
+
* with a resolution context being passed to it.
|
112
66
|
*/
|
113
|
-
type
|
67
|
+
type Resolver<T> = (context?: ResolutionContext) => T;
|
114
68
|
/**
|
115
|
-
* A function that
|
69
|
+
* A function that resolves an instance or a `Promise` of a particular type
|
70
|
+
* based on a resolution context passed to it.
|
116
71
|
*/
|
117
|
-
type
|
72
|
+
type Provider<T> = Resolver<T>;
|
118
73
|
/**
|
119
|
-
*
|
120
|
-
*
|
121
|
-
* Passed to the provider call to resolve scope instances and mock providers.
|
74
|
+
* A context used by providers to resolve instances
|
75
|
+
* based on current scope and mocks.
|
122
76
|
*/
|
123
77
|
type ResolutionContext = {
|
124
78
|
scope?: Scope;
|
125
79
|
mocks?: MockMap;
|
126
80
|
};
|
127
81
|
/**
|
128
|
-
* Creates a provider instance
|
129
|
-
* a wrapper around a resolver(factory) for contextual dependency resolution.
|
130
|
-
*
|
131
|
-
* @param lifetime
|
132
|
-
* A resolution lifetime.
|
133
|
-
*
|
134
|
-
* `"transient"` doesn't provide any modifications to a resolver behaviour,
|
135
|
-
* so the resolver will create a new instance on each request.
|
82
|
+
* Creates a transient provider that will resolve a new instance on each call.
|
136
83
|
*
|
137
|
-
*
|
138
|
-
*
|
139
|
-
*
|
140
|
-
*
|
141
|
-
*
|
142
|
-
* If no scope is passed, it will create a new instance on each request.
|
143
|
-
*
|
144
|
-
* @param resolver
|
145
|
-
* The function that creates an instance using a resolution context.
|
146
|
-
*
|
147
|
-
* @returns The provider instance.
|
148
|
-
*/
|
149
|
-
declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>) => Provider<T>;
|
150
|
-
/**
|
151
|
-
* Creates a transient provider instance,
|
152
|
-
* a wrapper around a resolver(factory) for contextual dependency resolution
|
153
|
-
* that will create a new instance on each request.
|
84
|
+
* @example
|
85
|
+
* ```ts
|
86
|
+
* const getThing = transient(() => createThing())
|
87
|
+
* getThing() !== getThing()
|
88
|
+
* ```
|
154
89
|
*
|
155
90
|
* @param resolver
|
156
|
-
*
|
91
|
+
* A function that returns a value of a particular type
|
92
|
+
* with a resolution context being passed to it.
|
157
93
|
*
|
158
|
-
* @returns The transient provider
|
94
|
+
* @returns The transient provider.
|
159
95
|
*/
|
160
96
|
declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
161
97
|
/**
|
162
|
-
* Creates a
|
163
|
-
*
|
164
|
-
*
|
98
|
+
* Creates a singleton provider that will resolve an instance once
|
99
|
+
* and return it on every call.
|
100
|
+
*
|
101
|
+
* @example
|
102
|
+
* ```ts
|
103
|
+
* const getThing = singleton(() => createThing())
|
104
|
+
* getThing() === getThing()
|
105
|
+
* ```
|
165
106
|
*
|
166
107
|
* @param resolver
|
167
|
-
*
|
108
|
+
* A function that returns a value of a particular type
|
109
|
+
* with a resolution context being passed to it.
|
168
110
|
*
|
169
|
-
* @returns The singleton provider
|
111
|
+
* @returns The singleton provider.
|
170
112
|
*/
|
171
113
|
declare const singleton: <T>(resolver: Resolver<T>) => Provider<T>;
|
172
114
|
/**
|
173
|
-
* Creates a
|
174
|
-
* a wrapper around a resolver(factory) for contextual dependency resolution
|
175
|
-
* that will take its resolution from a provided scope
|
115
|
+
* Creates a scoped provider that will take its resolution from a passed scope
|
176
116
|
* or create a new one and save it if there is none.
|
177
|
-
* If no scope is passed, it will create a new instance on each
|
117
|
+
* If no scope is passed, it will create a new instance on each call.
|
118
|
+
*
|
119
|
+
* @example
|
120
|
+
* ```ts
|
121
|
+
* const getThing = scoped(() => createThing())
|
122
|
+
* getThing() !== getThing()
|
123
|
+
* ```
|
124
|
+
*
|
125
|
+
* @example
|
126
|
+
* ```ts
|
127
|
+
* const getThing = scoped(() => createThing())
|
128
|
+
* const scope = createScope()
|
129
|
+
* getThing({ scope }) === getThing({ scope })
|
130
|
+
* ```
|
178
131
|
*
|
179
132
|
* @param resolver
|
180
|
-
*
|
133
|
+
* A function that returns a value of a particular type
|
134
|
+
* with a resolution context being passed to it.
|
181
135
|
*
|
182
|
-
* @returns The scoped provider
|
136
|
+
* @returns The scoped provider.
|
183
137
|
*/
|
184
138
|
declare const scoped: <T>(resolver: Resolver<T>) => Provider<T>;
|
185
139
|
|
@@ -193,31 +147,111 @@ type InferProviderCollectionResolutions<Providers extends ProviderList | Provide
|
|
193
147
|
* if there'ss at least one `Promise` in the collection,
|
194
148
|
* otherwise returns an untouched type.
|
195
149
|
*/
|
196
|
-
type
|
150
|
+
type AwaitValuesInCollection<T extends any[] | Record<any, any>> = Promise<any> extends T[keyof T] ? Promise<{
|
197
151
|
[I in keyof T]: T[I] extends Promise<infer T> ? T : T[I];
|
198
152
|
}> : T;
|
199
153
|
/**
|
200
154
|
* Calls every provider in a list with a provided resolution context
|
201
|
-
* and returns a list of resolutions. Returns a
|
202
|
-
* of awaited resolutions if there's at least one
|
155
|
+
* and returns a list of resolutions. Returns a `Promise` of a list
|
156
|
+
* of awaited resolutions if there's at least one `Promise` in the resolutions.
|
157
|
+
*
|
158
|
+
* @example
|
159
|
+
* Only sync providers:
|
160
|
+
* ```ts
|
161
|
+
* const getA = scoped(() => createA())
|
162
|
+
* const getB = scoped(() => createB())
|
163
|
+
* const getC = scoped(() => createC())
|
164
|
+
*
|
165
|
+
* const scope = createScope()
|
166
|
+
* const resolutions = resolveList(
|
167
|
+
* [getA, getB, getC],
|
168
|
+
* { scope }
|
169
|
+
* )
|
170
|
+
*
|
171
|
+
* resolutions == [
|
172
|
+
* getA({ scope }),
|
173
|
+
* getB({ scope }),
|
174
|
+
* getC({ scope })
|
175
|
+
* ]
|
176
|
+
* ```
|
177
|
+
*
|
178
|
+
* @example
|
179
|
+
* Some provider is async:
|
180
|
+
* ```ts
|
181
|
+
* const getA = scoped(() => createA())
|
182
|
+
* const getB = scoped(async () => await createB())
|
183
|
+
* const getC = scoped(() => createC())
|
184
|
+
*
|
185
|
+
* const scope = createScope()
|
186
|
+
* const resolutions = resolveList(
|
187
|
+
* [getA, getB, getC],
|
188
|
+
* { scope }
|
189
|
+
* )
|
190
|
+
*
|
191
|
+
* resolutions == [
|
192
|
+
* getA({ scope }),
|
193
|
+
* await getB({ scope }),
|
194
|
+
* getC({ scope })
|
195
|
+
* ]
|
196
|
+
* ```
|
203
197
|
*
|
204
198
|
* @param providers - The list of providers.
|
205
199
|
* @param context - The resolution context.
|
206
200
|
*
|
207
201
|
* @returns The list of resolutions.
|
208
202
|
*/
|
209
|
-
declare const resolveList: <const Providers extends ProviderList>(providers: Providers, context?: ResolutionContext) =>
|
203
|
+
declare const resolveList: <const Providers extends ProviderList>(providers: Providers, context?: ResolutionContext) => AwaitValuesInCollection<InferProviderCollectionResolutions<Providers>>;
|
210
204
|
/**
|
211
205
|
* Calls every provider in a map with a provided resolution context
|
212
206
|
* and returns a map with identical keys but with resolutions in values instead.
|
213
|
-
* Returns a
|
214
|
-
*
|
207
|
+
* Returns a `Promise` of a map of awaited resolutions if there's at least one
|
208
|
+
* `Promise` in the resolutions.
|
209
|
+
*
|
210
|
+
* @example
|
211
|
+
* Only sync providers:
|
212
|
+
* ```ts
|
213
|
+
* const getA = scoped(() => createA())
|
214
|
+
* const getB = scoped(() => createB())
|
215
|
+
* const getC = scoped(() => createC())
|
216
|
+
*
|
217
|
+
* const scope = createScope()
|
218
|
+
* const resolutions = resolveMap(
|
219
|
+
* { a: getA, b: getB, c: getC },
|
220
|
+
* { scope }
|
221
|
+
* )
|
222
|
+
*
|
223
|
+
* resolutions == {
|
224
|
+
* a: getA({ scope }),
|
225
|
+
* b: getB({ scope }),
|
226
|
+
* c: getC({ scope })
|
227
|
+
* }
|
228
|
+
* ```
|
229
|
+
*
|
230
|
+
* @example
|
231
|
+
* Some provider is async:
|
232
|
+
* ```ts
|
233
|
+
* const getA = scoped(() => createA())
|
234
|
+
* const getB = scoped(async () => await createB())
|
235
|
+
* const getC = scoped(() => createC())
|
236
|
+
*
|
237
|
+
* const scope = createScope()
|
238
|
+
* const resolutions = await resolveMap(
|
239
|
+
* { a: getA, b: getB, c: getC },
|
240
|
+
* { scope }
|
241
|
+
* )
|
242
|
+
*
|
243
|
+
* resolutions == {
|
244
|
+
* a: getA({ scope }),
|
245
|
+
* b: await getB({ scope }),
|
246
|
+
* c: getC({ scope })
|
247
|
+
* }
|
248
|
+
* ```
|
215
249
|
*
|
216
250
|
* @param providers - The map of providers.
|
217
251
|
* @param context - The resolution context.
|
218
252
|
*
|
219
253
|
* @returns The map of resolutions.
|
220
254
|
*/
|
221
|
-
declare const resolveMap: <const Providers extends ProviderRecord>(providers: Providers, context?: ResolutionContext) =>
|
255
|
+
declare const resolveMap: <const Providers extends ProviderRecord>(providers: Providers, context?: ResolutionContext) => AwaitValuesInCollection<InferProviderCollectionResolutions<Providers>>;
|
222
256
|
|
223
|
-
export { type
|
257
|
+
export { type MockMap, type Provider, type ResolutionContext, type Resolver, type Scope, createMockMap, createScope, resolveList, resolveMap, scoped, singleton, transient };
|
package/dist/index.js
CHANGED
@@ -21,7 +21,6 @@ var src_exports = {};
|
|
21
21
|
__export(src_exports, {
|
22
22
|
createMockMap: () => createMockMap,
|
23
23
|
createScope: () => createScope,
|
24
|
-
provide: () => provide,
|
25
24
|
resolveList: () => resolveList,
|
26
25
|
resolveMap: () => resolveMap,
|
27
26
|
scoped: () => scoped,
|
@@ -30,35 +29,42 @@ __export(src_exports, {
|
|
30
29
|
});
|
31
30
|
module.exports = __toCommonJS(src_exports);
|
32
31
|
|
33
|
-
// src/helpers.ts
|
34
|
-
var once = (fn) => {
|
35
|
-
let returned = false;
|
36
|
-
let result;
|
37
|
-
return Object.assign((...args) => {
|
38
|
-
if (returned) return result;
|
39
|
-
result = fn(...args);
|
40
|
-
returned = true;
|
41
|
-
return result;
|
42
|
-
}, fn);
|
43
|
-
};
|
44
|
-
|
45
32
|
// src/provider.ts
|
46
|
-
var
|
47
|
-
|
48
|
-
|
33
|
+
var transient = (resolver) => {
|
34
|
+
const instance = (context) => {
|
35
|
+
var _a;
|
36
|
+
const maybeMock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
37
|
+
if (maybeMock) return maybeMock(context);
|
38
|
+
return resolver(context);
|
39
|
+
};
|
40
|
+
return instance;
|
41
|
+
};
|
42
|
+
var singleton = (resolver) => {
|
43
|
+
let resolved = false;
|
44
|
+
let resolution;
|
45
|
+
const instance = (context) => {
|
49
46
|
var _a;
|
50
|
-
const
|
51
|
-
if (
|
52
|
-
if (
|
53
|
-
|
54
|
-
|
47
|
+
const maybeMock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
48
|
+
if (maybeMock) return maybeMock(context);
|
49
|
+
if (resolved) return resolution;
|
50
|
+
resolution = resolver(context);
|
51
|
+
resolved = true;
|
55
52
|
return resolution;
|
56
53
|
};
|
57
|
-
return
|
54
|
+
return instance;
|
55
|
+
};
|
56
|
+
var scoped = (resolver) => {
|
57
|
+
const instance = (context) => {
|
58
|
+
var _a;
|
59
|
+
const maybeMock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
60
|
+
if (maybeMock) return maybeMock(context);
|
61
|
+
if (!(context == null ? void 0 : context.scope)) return resolver(context);
|
62
|
+
const resolution = context.scope.has(resolver) ? context.scope.get(resolver) : resolver(context);
|
63
|
+
context.scope.set(resolver, resolution);
|
64
|
+
return resolution;
|
65
|
+
};
|
66
|
+
return instance;
|
58
67
|
};
|
59
|
-
var transient = (resolver) => provide("transient", resolver);
|
60
|
-
var singleton = (resolver) => provide("singleton", resolver);
|
61
|
-
var scoped = (resolver) => provide("scoped", resolver);
|
62
68
|
|
63
69
|
// src/scope.ts
|
64
70
|
var createScope = () => /* @__PURE__ */ new Map();
|
@@ -69,23 +75,27 @@ var createMockMap = () => /* @__PURE__ */ new Map();
|
|
69
75
|
// src/collection-resolution.ts
|
70
76
|
var resolveList = (providers, context) => {
|
71
77
|
const resolutions = providers.map((provider) => provider(context));
|
72
|
-
|
78
|
+
const hasPromises = resolutions.some(
|
79
|
+
(resolution) => resolution instanceof Promise
|
80
|
+
);
|
81
|
+
return hasPromises ? Promise.all(resolutions) : resolutions;
|
73
82
|
};
|
74
83
|
var resolveMap = (providers, context) => {
|
75
|
-
|
84
|
+
const resolutionMapEntries = Object.entries(providers).map(
|
76
85
|
([key, provider]) => [key, provider(context)]
|
77
86
|
);
|
78
|
-
|
87
|
+
const hasPromises = resolutionMapEntries.some(
|
79
88
|
([, resolution]) => resolution instanceof Promise
|
80
|
-
)
|
89
|
+
);
|
90
|
+
if (hasPromises) {
|
81
91
|
return (async () => {
|
82
|
-
|
92
|
+
const awaitedEntries = await Promise.all(
|
83
93
|
resolutionMapEntries.map(async ([key, resolution]) => [
|
84
94
|
key,
|
85
95
|
await resolution
|
86
96
|
])
|
87
97
|
);
|
88
|
-
return Object.fromEntries(
|
98
|
+
return Object.fromEntries(awaitedEntries);
|
89
99
|
})();
|
90
100
|
}
|
91
101
|
return Object.fromEntries(resolutionMapEntries);
|
@@ -94,7 +104,6 @@ var resolveMap = (providers, context) => {
|
|
94
104
|
0 && (module.exports = {
|
95
105
|
createMockMap,
|
96
106
|
createScope,
|
97
|
-
provide,
|
98
107
|
resolveList,
|
99
108
|
resolveMap,
|
100
109
|
scoped,
|
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/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>;\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 * 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 = <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 instance;\n};\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: Resolver<T> = (context) => {\n const maybeMock = context?.mocks?.get(instance);\n if (maybeMock) return maybeMock(context);\n\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 create a new instance on each call.\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 })\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 instance: Resolver<T> = (context) => {\n const maybeMock = context?.mocks?.get(instance);\n if (maybeMock) return maybeMock(context);\n\n if (!context?.scope) return resolver(context);\n\n const resolution = context.scope.has(resolver)\n ? context.scope.get(resolver)\n : resolver(context);\n context.scope.set(resolver, 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;;;ACuCO,IAAM,YAAY,CAAI,aAAuC;AAChE,QAAM,WAAwB,CAAC,YAAY;AAxC/C;AAyCQ,UAAM,aAAY,wCAAS,UAAT,mBAAgB,IAAI;AACtC,QAAI,UAAW,QAAO,UAAU,OAAO;AAEvC,WAAO,SAAS,OAAO;AAAA,EAC3B;AAEA,SAAO;AACX;AAkBO,IAAM,YAAY,CAAI,aAAuC;AAChE,MAAI,WAAW;AACf,MAAI;AAEJ,QAAM,WAAwB,CAAC,YAAY;AAtE/C;AAuEQ,UAAM,aAAY,wCAAS,UAAT,mBAAgB,IAAI;AACtC,QAAI,UAAW,QAAO,UAAU,OAAO;AAEvC,QAAI,SAAU,QAAO;AAErB,iBAAa,SAAS,OAAO;AAC7B,eAAW;AAEX,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AA0BO,IAAM,SAAS,CAAI,aAAuC;AAC7D,QAAM,WAAwB,CAAC,YAAY;AA9G/C;AA+GQ,UAAM,aAAY,wCAAS,UAAT,mBAAgB,IAAI;AACtC,QAAI,UAAW,QAAO,UAAU,OAAO;AAEvC,QAAI,EAAC,mCAAS,OAAO,QAAO,SAAS,OAAO;AAE5C,UAAM,aAAa,QAAQ,MAAM,IAAI,QAAQ,IACvC,QAAQ,MAAM,IAAI,QAAQ,IAC1B,SAAS,OAAO;AACtB,YAAQ,MAAM,IAAI,UAAU,UAAU;AAEtC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;;;ACnGO,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":[]}
|
package/dist/index.mjs
CHANGED
@@ -1,32 +1,39 @@
|
|
1
|
-
// src/helpers.ts
|
2
|
-
var once = (fn) => {
|
3
|
-
let returned = false;
|
4
|
-
let result;
|
5
|
-
return Object.assign((...args) => {
|
6
|
-
if (returned) return result;
|
7
|
-
result = fn(...args);
|
8
|
-
returned = true;
|
9
|
-
return result;
|
10
|
-
}, fn);
|
11
|
-
};
|
12
|
-
|
13
1
|
// src/provider.ts
|
14
|
-
var
|
15
|
-
|
16
|
-
|
2
|
+
var transient = (resolver) => {
|
3
|
+
const instance = (context) => {
|
4
|
+
var _a;
|
5
|
+
const maybeMock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
6
|
+
if (maybeMock) return maybeMock(context);
|
7
|
+
return resolver(context);
|
8
|
+
};
|
9
|
+
return instance;
|
10
|
+
};
|
11
|
+
var singleton = (resolver) => {
|
12
|
+
let resolved = false;
|
13
|
+
let resolution;
|
14
|
+
const instance = (context) => {
|
17
15
|
var _a;
|
18
|
-
const
|
19
|
-
if (
|
20
|
-
if (
|
21
|
-
|
22
|
-
|
16
|
+
const maybeMock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
17
|
+
if (maybeMock) return maybeMock(context);
|
18
|
+
if (resolved) return resolution;
|
19
|
+
resolution = resolver(context);
|
20
|
+
resolved = true;
|
23
21
|
return resolution;
|
24
22
|
};
|
25
|
-
return
|
23
|
+
return instance;
|
24
|
+
};
|
25
|
+
var scoped = (resolver) => {
|
26
|
+
const instance = (context) => {
|
27
|
+
var _a;
|
28
|
+
const maybeMock = (_a = context == null ? void 0 : context.mocks) == null ? void 0 : _a.get(instance);
|
29
|
+
if (maybeMock) return maybeMock(context);
|
30
|
+
if (!(context == null ? void 0 : context.scope)) return resolver(context);
|
31
|
+
const resolution = context.scope.has(resolver) ? context.scope.get(resolver) : resolver(context);
|
32
|
+
context.scope.set(resolver, resolution);
|
33
|
+
return resolution;
|
34
|
+
};
|
35
|
+
return instance;
|
26
36
|
};
|
27
|
-
var transient = (resolver) => provide("transient", resolver);
|
28
|
-
var singleton = (resolver) => provide("singleton", resolver);
|
29
|
-
var scoped = (resolver) => provide("scoped", resolver);
|
30
37
|
|
31
38
|
// src/scope.ts
|
32
39
|
var createScope = () => /* @__PURE__ */ new Map();
|
@@ -37,23 +44,27 @@ var createMockMap = () => /* @__PURE__ */ new Map();
|
|
37
44
|
// src/collection-resolution.ts
|
38
45
|
var resolveList = (providers, context) => {
|
39
46
|
const resolutions = providers.map((provider) => provider(context));
|
40
|
-
|
47
|
+
const hasPromises = resolutions.some(
|
48
|
+
(resolution) => resolution instanceof Promise
|
49
|
+
);
|
50
|
+
return hasPromises ? Promise.all(resolutions) : resolutions;
|
41
51
|
};
|
42
52
|
var resolveMap = (providers, context) => {
|
43
|
-
|
53
|
+
const resolutionMapEntries = Object.entries(providers).map(
|
44
54
|
([key, provider]) => [key, provider(context)]
|
45
55
|
);
|
46
|
-
|
56
|
+
const hasPromises = resolutionMapEntries.some(
|
47
57
|
([, resolution]) => resolution instanceof Promise
|
48
|
-
)
|
58
|
+
);
|
59
|
+
if (hasPromises) {
|
49
60
|
return (async () => {
|
50
|
-
|
61
|
+
const awaitedEntries = await Promise.all(
|
51
62
|
resolutionMapEntries.map(async ([key, resolution]) => [
|
52
63
|
key,
|
53
64
|
await resolution
|
54
65
|
])
|
55
66
|
);
|
56
|
-
return Object.fromEntries(
|
67
|
+
return Object.fromEntries(awaitedEntries);
|
57
68
|
})();
|
58
69
|
}
|
59
70
|
return Object.fromEntries(resolutionMapEntries);
|
@@ -61,7 +72,6 @@ var resolveMap = (providers, context) => {
|
|
61
72
|
export {
|
62
73
|
createMockMap,
|
63
74
|
createScope,
|
64
|
-
provide,
|
65
75
|
resolveList,
|
66
76
|
resolveMap,
|
67
77
|
scoped,
|