atomic-di 0.9.1-beta.3 → 1.0.0-rc.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,
|