atomic-di 0.7.0-beta.1 → 0.7.1-beta.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.mts +183 -17
- package/dist/index.d.ts +183 -17
- package/dist/index.js +23 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
@@ -1,41 +1,207 @@
|
|
1
|
+
/**
|
2
|
+
* A map of providers to their instances.
|
3
|
+
* Passed to the provider call to resolve instances
|
4
|
+
* of scoped providers within it.
|
5
|
+
*/
|
1
6
|
type Scope = WeakMap<Provider<any>, any>;
|
7
|
+
/**
|
8
|
+
* Creates a new scope, map of providers to their instances.
|
9
|
+
* Scope is passed to the provider call to resolve instances
|
10
|
+
* of scoped providers within it.
|
11
|
+
*
|
12
|
+
* @returns A new scope.
|
13
|
+
*/
|
2
14
|
declare const createScope: () => Scope;
|
3
15
|
|
4
|
-
type
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
16
|
+
type MockMapEntries = [Provider<any>, Provider<any>][];
|
17
|
+
/**
|
18
|
+
* Stores and provides provider mocks.
|
19
|
+
*/
|
20
|
+
type MockMap = {
|
21
|
+
entries: MockMapEntries;
|
22
|
+
/**
|
23
|
+
* Returns the provider's mock or the provider itself
|
24
|
+
* depending on the presence of the mock.
|
25
|
+
*
|
26
|
+
* @returns The passed provider or its mock.
|
27
|
+
*/
|
28
|
+
map<T>(
|
29
|
+
/**
|
30
|
+
* An original provider whose mock is needed to get.
|
31
|
+
*/
|
32
|
+
provider: Provider<T>): Provider<T>;
|
33
|
+
/**
|
34
|
+
* Registers a mock provider and retursns a new mock map with that mock.
|
35
|
+
*
|
36
|
+
* @returns A new mock map with added mock.
|
37
|
+
*/
|
38
|
+
add<T>(
|
39
|
+
/**
|
40
|
+
* An original provider.
|
41
|
+
*/
|
42
|
+
provider: Provider<T>,
|
43
|
+
/**
|
44
|
+
* A provider that will be a mock of the first provider.
|
45
|
+
*/
|
46
|
+
replacement: Provider<T>): MockMap;
|
47
|
+
/**
|
48
|
+
* Applies mocks from another map to the current one and returns a new map.
|
49
|
+
* If there are identical keys (original providers),
|
50
|
+
* they will be overwritten by mocks from the other map.
|
51
|
+
*
|
52
|
+
* @returns A new mock map with applied mocks.
|
53
|
+
*/
|
54
|
+
apply(
|
55
|
+
/**
|
56
|
+
* A mock map that will be applied.
|
57
|
+
*/
|
58
|
+
otherMockMap: MockMap): MockMap;
|
10
59
|
};
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
60
|
+
/**
|
61
|
+
* Creates a new mock map that stores and provides provider mocks.
|
62
|
+
*
|
63
|
+
* @returns A new mock map.
|
64
|
+
*/
|
65
|
+
declare const createMockMap: (entries?: MockMapEntries) => {
|
66
|
+
entries: MockMapEntries;
|
67
|
+
map: <T>(provider: Provider<T>) => Provider<T>;
|
68
|
+
add: <T>(provider: Provider<T>, replacement: Provider<T>) => MockMap;
|
69
|
+
apply: (otherMockMap: MockMap) => MockMap;
|
16
70
|
};
|
17
71
|
|
18
|
-
|
72
|
+
/**
|
73
|
+
* Calls a resolver(factory) with an optional scope and a mock map
|
74
|
+
* and returns an instance.
|
75
|
+
*
|
76
|
+
* A passed scope will be propagated up a graph and will be passed
|
77
|
+
* to all scoped providers to resolve their instance within this scope.
|
78
|
+
* If a provider is scoped, it will either create a new instance
|
79
|
+
* and store it in the scope, or retrieve an already created instance
|
80
|
+
* from the scope.
|
81
|
+
*
|
82
|
+
* It is also possible to explicitly pass a mock map, but It's not recommended.
|
83
|
+
* If you want to mock(replace) providers for a resolution,
|
84
|
+
* it's best to use `mock` method.
|
85
|
+
*/
|
86
|
+
type ProviderCallable<T> = (scope?: Scope, mockMap?: MockMap) => T;
|
87
|
+
/**
|
88
|
+
* Instance factory with lifetime and dynamic context.
|
89
|
+
*/
|
19
90
|
type Provider<T> = ProviderCallable<T> & {
|
20
|
-
|
91
|
+
/**
|
92
|
+
* Mocks(replaces) a provider within the visible graph,
|
93
|
+
* returning a new provider with that mock.
|
94
|
+
*
|
95
|
+
* @returns A new provider with the mocked dependency provider.
|
96
|
+
*/
|
97
|
+
mock<U>(
|
98
|
+
/**
|
99
|
+
* A provider used by the current provider
|
100
|
+
* that needs to be replaced.
|
101
|
+
*/
|
102
|
+
dependencyProvider: Provider<U>,
|
103
|
+
/**
|
104
|
+
* A provider with a same interface
|
105
|
+
* that will be a replacement for the first one.
|
106
|
+
*/
|
107
|
+
replacement: Provider<U>): Provider<T>;
|
21
108
|
};
|
22
109
|
type Lifetime = "transient" | "singleton" | "scoped";
|
110
|
+
/**
|
111
|
+
* A function that resolves an instance of a passed provider.
|
112
|
+
* It's needed to resolve correct instance in a scope
|
113
|
+
* and to use mock of the passed provider, if any.
|
114
|
+
*/
|
23
115
|
type UseFn = <T>(provider: Provider<T>) => T;
|
116
|
+
/**
|
117
|
+
* A function that creates an instance by resolving its dependencies.
|
118
|
+
* If there are dependencies, you must use `use` function passed
|
119
|
+
* in the first argument.
|
120
|
+
*/
|
24
121
|
type Resolver<T> = (use: UseFn) => T;
|
25
|
-
|
122
|
+
/**
|
123
|
+
* Creates a new provider, instance factory with lifetime and dynamic context.
|
124
|
+
*
|
125
|
+
* @returns A new provider.
|
126
|
+
*/
|
127
|
+
declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>, mockMap?: MockMap) => Provider<T>;
|
128
|
+
/**
|
129
|
+
* Creates a new transient provider.
|
130
|
+
* This provider will return a new instance on each resolution.
|
131
|
+
*
|
132
|
+
* @returns A new transient provider.
|
133
|
+
*/
|
26
134
|
declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
135
|
+
/**
|
136
|
+
* Creates a new singleton provider.
|
137
|
+
* This provider will create an instance once and return it on every request.
|
138
|
+
*
|
139
|
+
* @returns A new singleton provider.
|
140
|
+
*/
|
27
141
|
declare const singleton: <T>(resolver: Resolver<T>) => Provider<T>;
|
142
|
+
/**
|
143
|
+
* Creates a new transient provider.
|
144
|
+
* This provider will save the instance in scope on first resolution
|
145
|
+
* and will retrieve it from scope on next resolutions.
|
146
|
+
* If scope was not specified, will create a new instance on each resolution.
|
147
|
+
*
|
148
|
+
* @returns A new scoped provider.
|
149
|
+
*/
|
28
150
|
declare const scoped: <T>(resolver: Resolver<T>) => Provider<T>;
|
29
151
|
|
152
|
+
/**
|
153
|
+
* A map of string keys to providers.
|
154
|
+
*/
|
30
155
|
type ProviderMap = Record<string, Provider<any>>;
|
31
156
|
type InferProviderMapOutputs<Providers extends ProviderMap> = {
|
32
157
|
[K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;
|
33
158
|
};
|
34
|
-
|
159
|
+
/**
|
160
|
+
* Resolves all providers in a `ProviderMap` and
|
161
|
+
* returns an object containing their instances.
|
162
|
+
*
|
163
|
+
* @returns An object containing the resolved instances of the providers.
|
164
|
+
*/
|
165
|
+
type ProviderSelectionCallable<Providers extends ProviderMap> = (
|
166
|
+
/**
|
167
|
+
* An optional scope to use for scoped providers.
|
168
|
+
*/
|
169
|
+
scope?: Scope,
|
170
|
+
/**
|
171
|
+
* An optional mock map to use for mocking providers.
|
172
|
+
*/
|
173
|
+
mockMap?: MockMap) => InferProviderMapOutputs<Providers>;
|
174
|
+
/**
|
175
|
+
* A selection of providers.
|
176
|
+
*/
|
35
177
|
type ProviderSelection<Providers extends ProviderMap> = ProviderSelectionCallable<Providers> & {
|
178
|
+
/**
|
179
|
+
* The `ProviderMap` that the selection is based on.
|
180
|
+
*/
|
36
181
|
map: Providers;
|
37
|
-
|
182
|
+
/**
|
183
|
+
* Mocks a provider within the selection, returning a new
|
184
|
+
* `ProviderSelection` with the mock applied.
|
185
|
+
*
|
186
|
+
* @returns A new `ProviderSelection` with the mocked provider.
|
187
|
+
*/
|
188
|
+
mock<T>(
|
189
|
+
/**
|
190
|
+
* A provider used by the current provider
|
191
|
+
* that needs to be replaced.
|
192
|
+
*/
|
193
|
+
dependencyProvider: Provider<T>,
|
194
|
+
/**
|
195
|
+
* A provider with a same interface that will be
|
196
|
+
* a replacement for the first one.
|
197
|
+
*/
|
198
|
+
replacement: Provider<T>): ProviderSelection<Providers>;
|
38
199
|
};
|
200
|
+
/**
|
201
|
+
* Creates a new provider selection from a provider map.
|
202
|
+
*
|
203
|
+
* @returns A new provider selection.
|
204
|
+
*/
|
39
205
|
declare const select: <Providers extends ProviderMap>(map: Providers) => ProviderSelection<Providers>;
|
40
206
|
|
41
|
-
export { type Provider, type ProviderSelection, type Scope,
|
207
|
+
export { type MockMap, type Provider, type ProviderSelection, type Scope, createMockMap, createScope, provide, scoped, select, singleton, transient };
|
package/dist/index.d.ts
CHANGED
@@ -1,41 +1,207 @@
|
|
1
|
+
/**
|
2
|
+
* A map of providers to their instances.
|
3
|
+
* Passed to the provider call to resolve instances
|
4
|
+
* of scoped providers within it.
|
5
|
+
*/
|
1
6
|
type Scope = WeakMap<Provider<any>, any>;
|
7
|
+
/**
|
8
|
+
* Creates a new scope, map of providers to their instances.
|
9
|
+
* Scope is passed to the provider call to resolve instances
|
10
|
+
* of scoped providers within it.
|
11
|
+
*
|
12
|
+
* @returns A new scope.
|
13
|
+
*/
|
2
14
|
declare const createScope: () => Scope;
|
3
15
|
|
4
|
-
type
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
16
|
+
type MockMapEntries = [Provider<any>, Provider<any>][];
|
17
|
+
/**
|
18
|
+
* Stores and provides provider mocks.
|
19
|
+
*/
|
20
|
+
type MockMap = {
|
21
|
+
entries: MockMapEntries;
|
22
|
+
/**
|
23
|
+
* Returns the provider's mock or the provider itself
|
24
|
+
* depending on the presence of the mock.
|
25
|
+
*
|
26
|
+
* @returns The passed provider or its mock.
|
27
|
+
*/
|
28
|
+
map<T>(
|
29
|
+
/**
|
30
|
+
* An original provider whose mock is needed to get.
|
31
|
+
*/
|
32
|
+
provider: Provider<T>): Provider<T>;
|
33
|
+
/**
|
34
|
+
* Registers a mock provider and retursns a new mock map with that mock.
|
35
|
+
*
|
36
|
+
* @returns A new mock map with added mock.
|
37
|
+
*/
|
38
|
+
add<T>(
|
39
|
+
/**
|
40
|
+
* An original provider.
|
41
|
+
*/
|
42
|
+
provider: Provider<T>,
|
43
|
+
/**
|
44
|
+
* A provider that will be a mock of the first provider.
|
45
|
+
*/
|
46
|
+
replacement: Provider<T>): MockMap;
|
47
|
+
/**
|
48
|
+
* Applies mocks from another map to the current one and returns a new map.
|
49
|
+
* If there are identical keys (original providers),
|
50
|
+
* they will be overwritten by mocks from the other map.
|
51
|
+
*
|
52
|
+
* @returns A new mock map with applied mocks.
|
53
|
+
*/
|
54
|
+
apply(
|
55
|
+
/**
|
56
|
+
* A mock map that will be applied.
|
57
|
+
*/
|
58
|
+
otherMockMap: MockMap): MockMap;
|
10
59
|
};
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
60
|
+
/**
|
61
|
+
* Creates a new mock map that stores and provides provider mocks.
|
62
|
+
*
|
63
|
+
* @returns A new mock map.
|
64
|
+
*/
|
65
|
+
declare const createMockMap: (entries?: MockMapEntries) => {
|
66
|
+
entries: MockMapEntries;
|
67
|
+
map: <T>(provider: Provider<T>) => Provider<T>;
|
68
|
+
add: <T>(provider: Provider<T>, replacement: Provider<T>) => MockMap;
|
69
|
+
apply: (otherMockMap: MockMap) => MockMap;
|
16
70
|
};
|
17
71
|
|
18
|
-
|
72
|
+
/**
|
73
|
+
* Calls a resolver(factory) with an optional scope and a mock map
|
74
|
+
* and returns an instance.
|
75
|
+
*
|
76
|
+
* A passed scope will be propagated up a graph and will be passed
|
77
|
+
* to all scoped providers to resolve their instance within this scope.
|
78
|
+
* If a provider is scoped, it will either create a new instance
|
79
|
+
* and store it in the scope, or retrieve an already created instance
|
80
|
+
* from the scope.
|
81
|
+
*
|
82
|
+
* It is also possible to explicitly pass a mock map, but It's not recommended.
|
83
|
+
* If you want to mock(replace) providers for a resolution,
|
84
|
+
* it's best to use `mock` method.
|
85
|
+
*/
|
86
|
+
type ProviderCallable<T> = (scope?: Scope, mockMap?: MockMap) => T;
|
87
|
+
/**
|
88
|
+
* Instance factory with lifetime and dynamic context.
|
89
|
+
*/
|
19
90
|
type Provider<T> = ProviderCallable<T> & {
|
20
|
-
|
91
|
+
/**
|
92
|
+
* Mocks(replaces) a provider within the visible graph,
|
93
|
+
* returning a new provider with that mock.
|
94
|
+
*
|
95
|
+
* @returns A new provider with the mocked dependency provider.
|
96
|
+
*/
|
97
|
+
mock<U>(
|
98
|
+
/**
|
99
|
+
* A provider used by the current provider
|
100
|
+
* that needs to be replaced.
|
101
|
+
*/
|
102
|
+
dependencyProvider: Provider<U>,
|
103
|
+
/**
|
104
|
+
* A provider with a same interface
|
105
|
+
* that will be a replacement for the first one.
|
106
|
+
*/
|
107
|
+
replacement: Provider<U>): Provider<T>;
|
21
108
|
};
|
22
109
|
type Lifetime = "transient" | "singleton" | "scoped";
|
110
|
+
/**
|
111
|
+
* A function that resolves an instance of a passed provider.
|
112
|
+
* It's needed to resolve correct instance in a scope
|
113
|
+
* and to use mock of the passed provider, if any.
|
114
|
+
*/
|
23
115
|
type UseFn = <T>(provider: Provider<T>) => T;
|
116
|
+
/**
|
117
|
+
* A function that creates an instance by resolving its dependencies.
|
118
|
+
* If there are dependencies, you must use `use` function passed
|
119
|
+
* in the first argument.
|
120
|
+
*/
|
24
121
|
type Resolver<T> = (use: UseFn) => T;
|
25
|
-
|
122
|
+
/**
|
123
|
+
* Creates a new provider, instance factory with lifetime and dynamic context.
|
124
|
+
*
|
125
|
+
* @returns A new provider.
|
126
|
+
*/
|
127
|
+
declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>, mockMap?: MockMap) => Provider<T>;
|
128
|
+
/**
|
129
|
+
* Creates a new transient provider.
|
130
|
+
* This provider will return a new instance on each resolution.
|
131
|
+
*
|
132
|
+
* @returns A new transient provider.
|
133
|
+
*/
|
26
134
|
declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
135
|
+
/**
|
136
|
+
* Creates a new singleton provider.
|
137
|
+
* This provider will create an instance once and return it on every request.
|
138
|
+
*
|
139
|
+
* @returns A new singleton provider.
|
140
|
+
*/
|
27
141
|
declare const singleton: <T>(resolver: Resolver<T>) => Provider<T>;
|
142
|
+
/**
|
143
|
+
* Creates a new transient provider.
|
144
|
+
* This provider will save the instance in scope on first resolution
|
145
|
+
* and will retrieve it from scope on next resolutions.
|
146
|
+
* If scope was not specified, will create a new instance on each resolution.
|
147
|
+
*
|
148
|
+
* @returns A new scoped provider.
|
149
|
+
*/
|
28
150
|
declare const scoped: <T>(resolver: Resolver<T>) => Provider<T>;
|
29
151
|
|
152
|
+
/**
|
153
|
+
* A map of string keys to providers.
|
154
|
+
*/
|
30
155
|
type ProviderMap = Record<string, Provider<any>>;
|
31
156
|
type InferProviderMapOutputs<Providers extends ProviderMap> = {
|
32
157
|
[K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;
|
33
158
|
};
|
34
|
-
|
159
|
+
/**
|
160
|
+
* Resolves all providers in a `ProviderMap` and
|
161
|
+
* returns an object containing their instances.
|
162
|
+
*
|
163
|
+
* @returns An object containing the resolved instances of the providers.
|
164
|
+
*/
|
165
|
+
type ProviderSelectionCallable<Providers extends ProviderMap> = (
|
166
|
+
/**
|
167
|
+
* An optional scope to use for scoped providers.
|
168
|
+
*/
|
169
|
+
scope?: Scope,
|
170
|
+
/**
|
171
|
+
* An optional mock map to use for mocking providers.
|
172
|
+
*/
|
173
|
+
mockMap?: MockMap) => InferProviderMapOutputs<Providers>;
|
174
|
+
/**
|
175
|
+
* A selection of providers.
|
176
|
+
*/
|
35
177
|
type ProviderSelection<Providers extends ProviderMap> = ProviderSelectionCallable<Providers> & {
|
178
|
+
/**
|
179
|
+
* The `ProviderMap` that the selection is based on.
|
180
|
+
*/
|
36
181
|
map: Providers;
|
37
|
-
|
182
|
+
/**
|
183
|
+
* Mocks a provider within the selection, returning a new
|
184
|
+
* `ProviderSelection` with the mock applied.
|
185
|
+
*
|
186
|
+
* @returns A new `ProviderSelection` with the mocked provider.
|
187
|
+
*/
|
188
|
+
mock<T>(
|
189
|
+
/**
|
190
|
+
* A provider used by the current provider
|
191
|
+
* that needs to be replaced.
|
192
|
+
*/
|
193
|
+
dependencyProvider: Provider<T>,
|
194
|
+
/**
|
195
|
+
* A provider with a same interface that will be
|
196
|
+
* a replacement for the first one.
|
197
|
+
*/
|
198
|
+
replacement: Provider<T>): ProviderSelection<Providers>;
|
38
199
|
};
|
200
|
+
/**
|
201
|
+
* Creates a new provider selection from a provider map.
|
202
|
+
*
|
203
|
+
* @returns A new provider selection.
|
204
|
+
*/
|
39
205
|
declare const select: <Providers extends ProviderMap>(map: Providers) => ProviderSelection<Providers>;
|
40
206
|
|
41
|
-
export { type Provider, type ProviderSelection, type Scope,
|
207
|
+
export { type MockMap, type Provider, type ProviderSelection, type Scope, createMockMap, createScope, provide, scoped, select, singleton, transient };
|
package/dist/index.js
CHANGED
@@ -19,8 +19,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
19
19
|
// src/index.ts
|
20
20
|
var src_exports = {};
|
21
21
|
__export(src_exports, {
|
22
|
+
createMockMap: () => createMockMap,
|
22
23
|
createScope: () => createScope,
|
23
|
-
createSwapMap: () => createSwapMap,
|
24
24
|
provide: () => provide,
|
25
25
|
scoped: () => scoped,
|
26
26
|
select: () => select,
|
@@ -38,49 +38,49 @@ var once = (fn) => {
|
|
38
38
|
);
|
39
39
|
};
|
40
40
|
|
41
|
-
// src/
|
42
|
-
var
|
43
|
-
const
|
41
|
+
// src/mock-map.ts
|
42
|
+
var createMockMap = (entries = []) => {
|
43
|
+
const map = (provider) => {
|
44
44
|
var _a;
|
45
45
|
return ((_a = entries.find((e) => e[0] === provider)) == null ? void 0 : _a[1]) || provider;
|
46
46
|
};
|
47
|
-
const
|
47
|
+
const add = (provider, replacement) => {
|
48
48
|
const newEntries = entries.map(
|
49
49
|
(e) => e[0] === provider ? [e[0], replacement] : e
|
50
50
|
);
|
51
51
|
if (newEntries.length === entries.length)
|
52
52
|
newEntries.push([provider, replacement]);
|
53
|
-
return
|
53
|
+
return createMockMap(newEntries);
|
54
54
|
};
|
55
|
-
const apply = (
|
55
|
+
const apply = (otherMockMap) => createMockMap([
|
56
56
|
...entries.filter(
|
57
|
-
(e) =>
|
57
|
+
(e) => otherMockMap.entries.find((oe) => oe[0] === e[0]) === void 0
|
58
58
|
),
|
59
|
-
...
|
59
|
+
...otherMockMap.entries
|
60
60
|
]);
|
61
|
-
return { entries,
|
61
|
+
return { entries, map, add, apply };
|
62
62
|
};
|
63
63
|
|
64
64
|
// src/provider.ts
|
65
|
-
var provide = (lifetime, resolver,
|
65
|
+
var provide = (lifetime, resolver, mockMap = createMockMap()) => {
|
66
66
|
const getSelf = once(() => Object.assign(resolve, properties));
|
67
67
|
const originalResolver = resolver;
|
68
68
|
resolver = lifetime === "singleton" ? once(resolver) : resolver;
|
69
|
-
const resolve = (scope,
|
70
|
-
const
|
71
|
-
const use = (provider) =>
|
69
|
+
const resolve = (scope, requestMockMap) => {
|
70
|
+
const currentMockMap = requestMockMap ? mockMap.apply(requestMockMap) : mockMap;
|
71
|
+
const use = (provider) => currentMockMap.map(provider)(scope, currentMockMap);
|
72
72
|
if (lifetime !== "scoped" || !scope) return resolver(use);
|
73
73
|
const resolution = scope.get(getSelf()) || resolver(use);
|
74
74
|
scope.set(getSelf(), resolution);
|
75
75
|
return resolution;
|
76
76
|
};
|
77
|
-
const
|
77
|
+
const mock = (dependencyProvider, replacement) => provide(
|
78
78
|
lifetime,
|
79
79
|
originalResolver,
|
80
|
-
|
80
|
+
mockMap.add(dependencyProvider, replacement)
|
81
81
|
);
|
82
82
|
const properties = {
|
83
|
-
|
83
|
+
mock
|
84
84
|
};
|
85
85
|
return getSelf();
|
86
86
|
};
|
@@ -93,26 +93,26 @@ var createScope = () => /* @__PURE__ */ new WeakMap();
|
|
93
93
|
|
94
94
|
// src/selection.ts
|
95
95
|
var select = (map) => {
|
96
|
-
const resolveAll = (scope,
|
96
|
+
const resolveAll = (scope, mockMap) => {
|
97
97
|
const resultEntries = Object.entries(map).map(
|
98
|
-
([key, provider]) =>
|
98
|
+
([key, provider]) => mockMap ? [key, mockMap.map(provider)(scope, mockMap)] : [key, provider(scope, mockMap)]
|
99
99
|
);
|
100
100
|
return Object.fromEntries(
|
101
101
|
resultEntries
|
102
102
|
);
|
103
103
|
};
|
104
|
-
const
|
104
|
+
const mock = (dependencyProvider, replacement) => {
|
105
105
|
const newEntries = Object.entries(map).map(
|
106
|
-
([key, provider]) => provider === dependencyProvider ? [key, replacement] : [key, provider.
|
106
|
+
([key, provider]) => provider === dependencyProvider ? [key, replacement] : [key, provider.mock(dependencyProvider, replacement)]
|
107
107
|
);
|
108
108
|
return select(Object.fromEntries(newEntries));
|
109
109
|
};
|
110
|
-
return Object.assign(resolveAll, { map,
|
110
|
+
return Object.assign(resolveAll, { map, mock });
|
111
111
|
};
|
112
112
|
// Annotate the CommonJS export names for ESM import in node:
|
113
113
|
0 && (module.exports = {
|
114
|
+
createMockMap,
|
114
115
|
createScope,
|
115
|
-
createSwapMap,
|
116
116
|
provide,
|
117
117
|
scoped,
|
118
118
|
select,
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/helpers.ts","../src/swap-map.ts","../src/provider.ts","../src/scope.ts","../src/selection.ts"],"sourcesContent":["export * from \"./provider\";\nexport * from \"./scope\";\nexport * from \"./selection\";\nexport * from \"./swap-map\";\n","export const once = <A extends any[], R>(fn: (...args: A) => R) => {\n let cachedResult: R | undefined;\n\n return Object.assign(\n (...args: A) => cachedResult ?? (cachedResult = fn(...args)),\n fn,\n );\n};\n","import { Provider } from \"./provider\";\n\ntype SwapMapEntries = [Provider<any>, Provider<any>][];\n\nexport type SwapMap = {\n entries: SwapMapEntries;\n resolve<T>(provider: Provider<T>): Provider<T>;\n register<T>(provider: Provider<T>, replacement: Provider<T>): SwapMap;\n apply(otherSwapContext: SwapMap): SwapMap;\n};\n\nexport const createSwapMap = (entries: SwapMapEntries = []) => {\n const resolve: SwapMap[\"resolve\"] = (provider) =>\n entries.find((e) => e[0] === provider)?.[1] || provider;\n\n const register: SwapMap[\"register\"] = (provider, replacement) => {\n const newEntries: SwapMapEntries = entries.map((e) =>\n e[0] === provider ? [e[0], replacement] : e,\n );\n\n if (newEntries.length === entries.length)\n newEntries.push([provider, replacement]);\n\n return createSwapMap(newEntries);\n };\n\n const apply: SwapMap[\"apply\"] = (otherSwapContext) =>\n createSwapMap([\n ...entries.filter(\n (e) =>\n otherSwapContext.entries.find((oe) => oe[0] === e[0]) ===\n undefined,\n ),\n ...otherSwapContext.entries,\n ]);\n\n return { entries, resolve, register, apply };\n};\n","import { once } from \"./helpers\";\nimport { Scope } from \"./scope\";\nimport { createSwapMap, SwapMap } from \"./swap-map\";\n\ntype ProviderCallable<T> = (scope?: Scope, swapMap?: SwapMap) => T;\nexport type Provider<T> = ProviderCallable<T> & {\n swap<U>(\n dependencyProvider: Provider<U>,\n replacement: Provider<U>,\n ): Provider<T>;\n};\n\ntype Lifetime = \"transient\" | \"singleton\" | \"scoped\";\ntype UseFn = <T>(provider: Provider<T>) => T;\ntype Resolver<T> = (use: UseFn) => T;\n\nexport const provide = <T>(\n lifetime: Lifetime,\n resolver: Resolver<T>,\n swapMap: SwapMap = createSwapMap(),\n): Provider<T> => {\n type ProviderType = Provider<T>;\n\n const getSelf = once(() => Object.assign(resolve, properties));\n\n const originalResolver = resolver;\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: ProviderCallable<T> = (scope, requestSwapMap) => {\n const currentSwapMap = requestSwapMap\n ? swapMap.apply(requestSwapMap)\n : swapMap;\n\n const use: UseFn = (provider) =>\n currentSwapMap.resolve(provider)(scope, currentSwapMap);\n\n if (lifetime !== \"scoped\" || !scope) return resolver(use);\n\n const resolution = scope.get(getSelf()) || resolver(use);\n scope.set(getSelf(), resolution);\n\n return resolution;\n };\n\n const swap: ProviderType[\"swap\"] = (dependencyProvider, replacement) =>\n provide(\n lifetime,\n originalResolver,\n swapMap.register(dependencyProvider, replacement),\n );\n\n const properties = {\n swap,\n };\n\n return getSelf();\n};\n\nexport const transient = <T>(resolver: Resolver<T>) =>\n provide(\"transient\", resolver);\n\nexport const singleton = <T>(resolver: Resolver<T>) =>\n provide(\"singleton\", resolver);\n\nexport const scoped = <T>(resolver: Resolver<T>) => provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\nexport type Scope = WeakMap<Provider<any>, any>;\n\nexport const createScope = (): Scope => new WeakMap();\n","import { Provider } from \"./provider\";\nimport { Scope } from \"./scope\";\nimport { SwapMap } from \"./swap-map\";\n\ntype ProviderMap = Record<string, Provider<any>>;\n\ntype InferProviderMapOutputs<Providers extends ProviderMap> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\ntype ProviderSelectionCallable<Providers extends ProviderMap> = (\n scope?: Scope,\n swapMap?: SwapMap,\n) => InferProviderMapOutputs<Providers>;\n\nexport type ProviderSelection<Providers extends ProviderMap> =\n ProviderSelectionCallable<Providers> & {\n map: Providers;\n swap<T>(\n dependencyProvider: Provider<T>,\n replacement: Provider<T>,\n ): ProviderSelection<Providers>;\n };\n\nexport const select = <Providers extends ProviderMap>(\n map: Providers,\n): ProviderSelection<Providers> => {\n type SelectionType = ProviderSelection<Providers>;\n\n const resolveAll: ProviderSelectionCallable<Providers> = (\n scope,\n swapMap,\n ) => {\n const resultEntries = Object.entries(map).map(([key, provider]) =>\n swapMap\n ? [key, swapMap.resolve(provider)(scope, swapMap)]\n : [key, provider(scope, swapMap)],\n );\n\n return Object.fromEntries(\n resultEntries,\n ) as InferProviderMapOutputs<Providers>;\n };\n\n const swap: SelectionType[\"swap\"] = (dependencyProvider, replacement) => {\n const newEntries = Object.entries(map).map(([key, provider]) =>\n provider === dependencyProvider\n ? [key, replacement]\n : [key, provider.swap(dependencyProvider, replacement)],\n );\n\n return select(Object.fromEntries(newEntries) as Providers);\n };\n\n return Object.assign(resolveAll, { map, swap });\n};\n"],"mappings":"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","names":[]}
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/helpers.ts","../src/mock-map.ts","../src/provider.ts","../src/scope.ts","../src/selection.ts"],"sourcesContent":["export * from \"./provider\";\nexport * from \"./scope\";\nexport * from \"./selection\";\nexport * from \"./mock-map\";\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 cachedResult: R | undefined;\n\n return Object.assign(\n (...args: A) => cachedResult ?? (cachedResult = fn(...args)),\n fn,\n );\n};\n","import { Provider } from \"./provider\";\n\ntype MockMapEntries = [Provider<any>, Provider<any>][];\n\n/**\n * Stores and provides provider mocks.\n */\nexport type MockMap = {\n entries: MockMapEntries;\n\n /**\n * Returns the provider's mock or the provider itself\n * depending on the presence of the mock.\n *\n * @returns The passed provider or its mock.\n */\n map<T>(\n /**\n * An original provider whose mock is needed to get.\n */\n provider: Provider<T>,\n ): Provider<T>;\n\n /**\n * Registers a mock provider and retursns a new mock map with that mock.\n *\n * @returns A new mock map with added mock.\n */\n add<T>(\n /**\n * An original provider.\n */\n provider: Provider<T>,\n /**\n * A provider that will be a mock of the first provider.\n */\n replacement: Provider<T>,\n ): MockMap;\n\n /**\n * Applies mocks from another map to the current one and returns a new map.\n * If there are identical keys (original providers),\n * they will be overwritten by mocks from the other map.\n *\n * @returns A new mock map with applied mocks.\n */\n apply(\n /**\n * A mock map that will be applied.\n */\n otherMockMap: MockMap,\n ): MockMap;\n};\n\n/**\n * Creates a new mock map that stores and provides provider mocks.\n *\n * @returns A new mock map.\n */\nexport const createMockMap = (\n /**\n * Entries of a mock map.\n */\n entries: MockMapEntries = [],\n) => {\n const map: MockMap[\"map\"] = (provider) =>\n entries.find((e) => e[0] === provider)?.[1] || provider;\n\n const add: MockMap[\"add\"] = (provider, replacement) => {\n const newEntries: MockMapEntries = entries.map((e) =>\n e[0] === provider ? [e[0], replacement] : e,\n );\n\n if (newEntries.length === entries.length)\n newEntries.push([provider, replacement]);\n\n return createMockMap(newEntries);\n };\n\n const apply: MockMap[\"apply\"] = (otherMockMap) =>\n createMockMap([\n ...entries.filter(\n (e) =>\n otherMockMap.entries.find((oe) => oe[0] === e[0]) ===\n undefined,\n ),\n ...otherMockMap.entries,\n ]);\n\n return { entries, map, add, apply };\n};\n","import { once } from \"./helpers\";\nimport { Scope } from \"./scope\";\nimport { createMockMap, MockMap } from \"./mock-map\";\n\n/**\n * Calls a resolver(factory) with an optional scope and a mock map\n * and returns an instance.\n *\n * A passed scope will be propagated up a graph and will be passed\n * to all scoped providers to resolve their instance within this scope.\n * If a provider is scoped, it will either create a new instance\n * and store it in the scope, or retrieve an already created instance\n * from the scope.\n *\n * It is also possible to explicitly pass a mock map, but It's not recommended.\n * If you want to mock(replace) providers for a resolution,\n * it's best to use `mock` method.\n */\ntype ProviderCallable<T> = (scope?: Scope, mockMap?: MockMap) => T;\n\n/**\n * Instance factory with lifetime and dynamic context.\n */\nexport type Provider<T> = ProviderCallable<T> & {\n /**\n * Mocks(replaces) a provider within the visible graph,\n * returning a new provider with that mock.\n *\n * @returns A new provider with the mocked dependency provider.\n */\n mock<U>(\n /**\n * A provider used by the current provider\n * that needs to be replaced.\n */\n dependencyProvider: Provider<U>,\n /**\n * A provider with a same interface\n * that will be a replacement for the first one.\n */\n replacement: Provider<U>,\n ): Provider<T>;\n};\n\ntype Lifetime = \"transient\" | \"singleton\" | \"scoped\";\n\n/**\n * A function that resolves an instance of a passed provider.\n * It's needed to resolve correct instance in a scope\n * and to use mock of the passed provider, if any.\n */\ntype UseFn = <T>(provider: Provider<T>) => T;\n\n/**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\ntype Resolver<T> = (use: UseFn) => T;\n\n/**\n * Creates a new provider, instance factory with lifetime and dynamic context.\n *\n * @returns A new provider.\n */\nexport const provide = <T>(\n /**\n * Instance lifetime. Can be `\"transient\"`, `\"singleton\"` or `\"scoped\"`.\n *\n * If `\"transient\"`, will return a new instance on each resolution.\n *\n * If `\"singleton\"`, will create an instance once and return it on every request.\n *\n * If `\"scoped\"`, will save the instance in scope on first resolution\n * and will retrieve it from scope on next resolutions.\n * If scope was not specified, will create a new instance on each resolution.\n */\n lifetime: Lifetime,\n\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n\n /**\n * An optional mock map. Not recommended to specify explicitly,\n * use `mock` method to mock providers.\n */\n mockMap: MockMap = createMockMap(),\n): Provider<T> => {\n type ProviderType = Provider<T>;\n\n const getSelf = once(() => Object.assign(resolve, properties));\n\n const originalResolver = resolver;\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: ProviderCallable<T> = (scope, requestMockMap) => {\n const currentMockMap = requestMockMap\n ? mockMap.apply(requestMockMap)\n : mockMap;\n\n const use: UseFn = (provider) =>\n currentMockMap.map(provider)(scope, currentMockMap);\n\n if (lifetime !== \"scoped\" || !scope) return resolver(use);\n\n const resolution = scope.get(getSelf()) || resolver(use);\n scope.set(getSelf(), resolution);\n\n return resolution;\n };\n\n const mock: ProviderType[\"mock\"] = (dependencyProvider, replacement) =>\n provide(\n lifetime,\n originalResolver,\n mockMap.add(dependencyProvider, replacement),\n );\n\n const properties = {\n mock,\n };\n\n return getSelf();\n};\n\n/**\n * Creates a new transient provider.\n * This provider will return a new instance on each resolution.\n *\n * @returns A new transient provider.\n */\nexport const transient = <T>(\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n) => provide(\"transient\", resolver);\n\n/**\n * Creates a new singleton provider.\n * This provider will create an instance once and return it on every request.\n *\n * @returns A new singleton provider.\n */\nexport const singleton = <T>(\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n) => provide(\"singleton\", resolver);\n\n/**\n * Creates a new transient provider.\n * This provider will save the instance in scope on first resolution\n * and will retrieve it from scope on next resolutions.\n * If scope was not specified, will create a new instance on each resolution.\n *\n * @returns A new scoped provider.\n */\nexport const scoped = <T>(\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n) => provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to their instances.\n * Passed to the provider call to resolve instances\n * of scoped providers within it.\n */\nexport type Scope = WeakMap<Provider<any>, any>;\n\n/**\n * Creates a new scope, map of providers to their instances.\n * Scope is passed to the provider call to resolve instances\n * of scoped providers within it.\n *\n * @returns A new scope.\n */\nexport const createScope = (): Scope => new WeakMap();\n","import { Provider } from \"./provider\";\nimport { Scope } from \"./scope\";\nimport { MockMap } from \"./mock-map\";\n\n/**\n * A map of string keys to providers.\n */\ntype ProviderMap = Record<string, Provider<any>>;\n\ntype InferProviderMapOutputs<Providers extends ProviderMap> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\n/**\n * Resolves all providers in a `ProviderMap` and\n * returns an object containing their instances.\n *\n * @returns An object containing the resolved instances of the providers.\n */\ntype ProviderSelectionCallable<Providers extends ProviderMap> = (\n /**\n * An optional scope to use for scoped providers.\n */\n scope?: Scope,\n /**\n * An optional mock map to use for mocking providers.\n */\n mockMap?: MockMap,\n) => InferProviderMapOutputs<Providers>;\n\n/**\n * A selection of providers.\n */\nexport type ProviderSelection<Providers extends ProviderMap> =\n ProviderSelectionCallable<Providers> & {\n /**\n * The `ProviderMap` that the selection is based on.\n */\n map: Providers;\n /**\n * Mocks a provider within the selection, returning a new\n * `ProviderSelection` with the mock applied.\n *\n * @returns A new `ProviderSelection` with the mocked provider.\n */\n mock<T>(\n /**\n * A provider used by the current provider\n * that needs to be replaced.\n */\n dependencyProvider: Provider<T>,\n /**\n * A provider with a same interface that will be\n * a replacement for the first one.\n */\n replacement: Provider<T>,\n ): ProviderSelection<Providers>;\n };\n\n/**\n * Creates a new provider selection from a provider map.\n *\n * @returns A new provider selection.\n */\nexport const select = <Providers extends ProviderMap>(\n /**\n * A map of string keys to providers.\n */\n map: Providers,\n): ProviderSelection<Providers> => {\n type SelectionType = ProviderSelection<Providers>;\n\n const resolveAll: ProviderSelectionCallable<Providers> = (\n scope,\n mockMap,\n ) => {\n const resultEntries = Object.entries(map).map(([key, provider]) =>\n mockMap\n ? [key, mockMap.map(provider)(scope, mockMap)]\n : [key, provider(scope, mockMap)],\n );\n\n return Object.fromEntries(\n resultEntries,\n ) as InferProviderMapOutputs<Providers>;\n };\n\n const mock: SelectionType[\"mock\"] = (dependencyProvider, replacement) => {\n const newEntries = Object.entries(map).map(([key, provider]) =>\n provider === dependencyProvider\n ? [key, replacement]\n : [key, provider.mock(dependencyProvider, replacement)],\n );\n\n return select(Object.fromEntries(newEntries) as Providers);\n };\n\n return Object.assign(resolveAll, { map, mock });\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
@@ -7,49 +7,49 @@ var once = (fn) => {
|
|
7
7
|
);
|
8
8
|
};
|
9
9
|
|
10
|
-
// src/
|
11
|
-
var
|
12
|
-
const
|
10
|
+
// src/mock-map.ts
|
11
|
+
var createMockMap = (entries = []) => {
|
12
|
+
const map = (provider) => {
|
13
13
|
var _a;
|
14
14
|
return ((_a = entries.find((e) => e[0] === provider)) == null ? void 0 : _a[1]) || provider;
|
15
15
|
};
|
16
|
-
const
|
16
|
+
const add = (provider, replacement) => {
|
17
17
|
const newEntries = entries.map(
|
18
18
|
(e) => e[0] === provider ? [e[0], replacement] : e
|
19
19
|
);
|
20
20
|
if (newEntries.length === entries.length)
|
21
21
|
newEntries.push([provider, replacement]);
|
22
|
-
return
|
22
|
+
return createMockMap(newEntries);
|
23
23
|
};
|
24
|
-
const apply = (
|
24
|
+
const apply = (otherMockMap) => createMockMap([
|
25
25
|
...entries.filter(
|
26
|
-
(e) =>
|
26
|
+
(e) => otherMockMap.entries.find((oe) => oe[0] === e[0]) === void 0
|
27
27
|
),
|
28
|
-
...
|
28
|
+
...otherMockMap.entries
|
29
29
|
]);
|
30
|
-
return { entries,
|
30
|
+
return { entries, map, add, apply };
|
31
31
|
};
|
32
32
|
|
33
33
|
// src/provider.ts
|
34
|
-
var provide = (lifetime, resolver,
|
34
|
+
var provide = (lifetime, resolver, mockMap = createMockMap()) => {
|
35
35
|
const getSelf = once(() => Object.assign(resolve, properties));
|
36
36
|
const originalResolver = resolver;
|
37
37
|
resolver = lifetime === "singleton" ? once(resolver) : resolver;
|
38
|
-
const resolve = (scope,
|
39
|
-
const
|
40
|
-
const use = (provider) =>
|
38
|
+
const resolve = (scope, requestMockMap) => {
|
39
|
+
const currentMockMap = requestMockMap ? mockMap.apply(requestMockMap) : mockMap;
|
40
|
+
const use = (provider) => currentMockMap.map(provider)(scope, currentMockMap);
|
41
41
|
if (lifetime !== "scoped" || !scope) return resolver(use);
|
42
42
|
const resolution = scope.get(getSelf()) || resolver(use);
|
43
43
|
scope.set(getSelf(), resolution);
|
44
44
|
return resolution;
|
45
45
|
};
|
46
|
-
const
|
46
|
+
const mock = (dependencyProvider, replacement) => provide(
|
47
47
|
lifetime,
|
48
48
|
originalResolver,
|
49
|
-
|
49
|
+
mockMap.add(dependencyProvider, replacement)
|
50
50
|
);
|
51
51
|
const properties = {
|
52
|
-
|
52
|
+
mock
|
53
53
|
};
|
54
54
|
return getSelf();
|
55
55
|
};
|
@@ -62,25 +62,25 @@ var createScope = () => /* @__PURE__ */ new WeakMap();
|
|
62
62
|
|
63
63
|
// src/selection.ts
|
64
64
|
var select = (map) => {
|
65
|
-
const resolveAll = (scope,
|
65
|
+
const resolveAll = (scope, mockMap) => {
|
66
66
|
const resultEntries = Object.entries(map).map(
|
67
|
-
([key, provider]) =>
|
67
|
+
([key, provider]) => mockMap ? [key, mockMap.map(provider)(scope, mockMap)] : [key, provider(scope, mockMap)]
|
68
68
|
);
|
69
69
|
return Object.fromEntries(
|
70
70
|
resultEntries
|
71
71
|
);
|
72
72
|
};
|
73
|
-
const
|
73
|
+
const mock = (dependencyProvider, replacement) => {
|
74
74
|
const newEntries = Object.entries(map).map(
|
75
|
-
([key, provider]) => provider === dependencyProvider ? [key, replacement] : [key, provider.
|
75
|
+
([key, provider]) => provider === dependencyProvider ? [key, replacement] : [key, provider.mock(dependencyProvider, replacement)]
|
76
76
|
);
|
77
77
|
return select(Object.fromEntries(newEntries));
|
78
78
|
};
|
79
|
-
return Object.assign(resolveAll, { map,
|
79
|
+
return Object.assign(resolveAll, { map, mock });
|
80
80
|
};
|
81
81
|
export {
|
82
|
+
createMockMap,
|
82
83
|
createScope,
|
83
|
-
createSwapMap,
|
84
84
|
provide,
|
85
85
|
scoped,
|
86
86
|
select,
|
package/dist/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/helpers.ts","../src/swap-map.ts","../src/provider.ts","../src/scope.ts","../src/selection.ts"],"sourcesContent":["export const once = <A extends any[], R>(fn: (...args: A) => R) => {\n let cachedResult: R | undefined;\n\n return Object.assign(\n (...args: A) => cachedResult ?? (cachedResult = fn(...args)),\n fn,\n );\n};\n","import { Provider } from \"./provider\";\n\ntype SwapMapEntries = [Provider<any>, Provider<any>][];\n\nexport type SwapMap = {\n entries: SwapMapEntries;\n resolve<T>(provider: Provider<T>): Provider<T>;\n register<T>(provider: Provider<T>, replacement: Provider<T>): SwapMap;\n apply(otherSwapContext: SwapMap): SwapMap;\n};\n\nexport const createSwapMap = (entries: SwapMapEntries = []) => {\n const resolve: SwapMap[\"resolve\"] = (provider) =>\n entries.find((e) => e[0] === provider)?.[1] || provider;\n\n const register: SwapMap[\"register\"] = (provider, replacement) => {\n const newEntries: SwapMapEntries = entries.map((e) =>\n e[0] === provider ? [e[0], replacement] : e,\n );\n\n if (newEntries.length === entries.length)\n newEntries.push([provider, replacement]);\n\n return createSwapMap(newEntries);\n };\n\n const apply: SwapMap[\"apply\"] = (otherSwapContext) =>\n createSwapMap([\n ...entries.filter(\n (e) =>\n otherSwapContext.entries.find((oe) => oe[0] === e[0]) ===\n undefined,\n ),\n ...otherSwapContext.entries,\n ]);\n\n return { entries, resolve, register, apply };\n};\n","import { once } from \"./helpers\";\nimport { Scope } from \"./scope\";\nimport { createSwapMap, SwapMap } from \"./swap-map\";\n\ntype ProviderCallable<T> = (scope?: Scope, swapMap?: SwapMap) => T;\nexport type Provider<T> = ProviderCallable<T> & {\n swap<U>(\n dependencyProvider: Provider<U>,\n replacement: Provider<U>,\n ): Provider<T>;\n};\n\ntype Lifetime = \"transient\" | \"singleton\" | \"scoped\";\ntype UseFn = <T>(provider: Provider<T>) => T;\ntype Resolver<T> = (use: UseFn) => T;\n\nexport const provide = <T>(\n lifetime: Lifetime,\n resolver: Resolver<T>,\n swapMap: SwapMap = createSwapMap(),\n): Provider<T> => {\n type ProviderType = Provider<T>;\n\n const getSelf = once(() => Object.assign(resolve, properties));\n\n const originalResolver = resolver;\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: ProviderCallable<T> = (scope, requestSwapMap) => {\n const currentSwapMap = requestSwapMap\n ? swapMap.apply(requestSwapMap)\n : swapMap;\n\n const use: UseFn = (provider) =>\n currentSwapMap.resolve(provider)(scope, currentSwapMap);\n\n if (lifetime !== \"scoped\" || !scope) return resolver(use);\n\n const resolution = scope.get(getSelf()) || resolver(use);\n scope.set(getSelf(), resolution);\n\n return resolution;\n };\n\n const swap: ProviderType[\"swap\"] = (dependencyProvider, replacement) =>\n provide(\n lifetime,\n originalResolver,\n swapMap.register(dependencyProvider, replacement),\n );\n\n const properties = {\n swap,\n };\n\n return getSelf();\n};\n\nexport const transient = <T>(resolver: Resolver<T>) =>\n provide(\"transient\", resolver);\n\nexport const singleton = <T>(resolver: Resolver<T>) =>\n provide(\"singleton\", resolver);\n\nexport const scoped = <T>(resolver: Resolver<T>) => provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\nexport type Scope = WeakMap<Provider<any>, any>;\n\nexport const createScope = (): Scope => new WeakMap();\n","import { Provider } from \"./provider\";\nimport { Scope } from \"./scope\";\nimport { SwapMap } from \"./swap-map\";\n\ntype ProviderMap = Record<string, Provider<any>>;\n\ntype InferProviderMapOutputs<Providers extends ProviderMap> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\ntype ProviderSelectionCallable<Providers extends ProviderMap> = (\n scope?: Scope,\n swapMap?: SwapMap,\n) => InferProviderMapOutputs<Providers>;\n\nexport type ProviderSelection<Providers extends ProviderMap> =\n ProviderSelectionCallable<Providers> & {\n map: Providers;\n swap<T>(\n dependencyProvider: Provider<T>,\n replacement: Provider<T>,\n ): ProviderSelection<Providers>;\n };\n\nexport const select = <Providers extends ProviderMap>(\n map: Providers,\n): ProviderSelection<Providers> => {\n type SelectionType = ProviderSelection<Providers>;\n\n const resolveAll: ProviderSelectionCallable<Providers> = (\n scope,\n swapMap,\n ) => {\n const resultEntries = Object.entries(map).map(([key, provider]) =>\n swapMap\n ? [key, swapMap.resolve(provider)(scope, swapMap)]\n : [key, provider(scope, swapMap)],\n );\n\n return Object.fromEntries(\n resultEntries,\n ) as InferProviderMapOutputs<Providers>;\n };\n\n const swap: SelectionType[\"swap\"] = (dependencyProvider, replacement) => {\n const newEntries = Object.entries(map).map(([key, provider]) =>\n provider === dependencyProvider\n ? [key, replacement]\n : [key, provider.swap(dependencyProvider, replacement)],\n );\n\n return select(Object.fromEntries(newEntries) as Providers);\n };\n\n return Object.assign(resolveAll, { map, swap });\n};\n"],"mappings":"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","names":[]}
|
1
|
+
{"version":3,"sources":["../src/helpers.ts","../src/mock-map.ts","../src/provider.ts","../src/scope.ts","../src/selection.ts"],"sourcesContent":["/**\n * Creates a function that will invoke the provided function `fn` only once,\n * caching the result for subsequent calls with the same arguments.\n *\n * @returns A new function that returns the cached result after the first call.\n */\nexport const once = <A extends any[], R>(\n /**\n * The function to invoke once and cache the result.\n */\n fn: (...args: A) => R,\n) => {\n let cachedResult: R | undefined;\n\n return Object.assign(\n (...args: A) => cachedResult ?? (cachedResult = fn(...args)),\n fn,\n );\n};\n","import { Provider } from \"./provider\";\n\ntype MockMapEntries = [Provider<any>, Provider<any>][];\n\n/**\n * Stores and provides provider mocks.\n */\nexport type MockMap = {\n entries: MockMapEntries;\n\n /**\n * Returns the provider's mock or the provider itself\n * depending on the presence of the mock.\n *\n * @returns The passed provider or its mock.\n */\n map<T>(\n /**\n * An original provider whose mock is needed to get.\n */\n provider: Provider<T>,\n ): Provider<T>;\n\n /**\n * Registers a mock provider and retursns a new mock map with that mock.\n *\n * @returns A new mock map with added mock.\n */\n add<T>(\n /**\n * An original provider.\n */\n provider: Provider<T>,\n /**\n * A provider that will be a mock of the first provider.\n */\n replacement: Provider<T>,\n ): MockMap;\n\n /**\n * Applies mocks from another map to the current one and returns a new map.\n * If there are identical keys (original providers),\n * they will be overwritten by mocks from the other map.\n *\n * @returns A new mock map with applied mocks.\n */\n apply(\n /**\n * A mock map that will be applied.\n */\n otherMockMap: MockMap,\n ): MockMap;\n};\n\n/**\n * Creates a new mock map that stores and provides provider mocks.\n *\n * @returns A new mock map.\n */\nexport const createMockMap = (\n /**\n * Entries of a mock map.\n */\n entries: MockMapEntries = [],\n) => {\n const map: MockMap[\"map\"] = (provider) =>\n entries.find((e) => e[0] === provider)?.[1] || provider;\n\n const add: MockMap[\"add\"] = (provider, replacement) => {\n const newEntries: MockMapEntries = entries.map((e) =>\n e[0] === provider ? [e[0], replacement] : e,\n );\n\n if (newEntries.length === entries.length)\n newEntries.push([provider, replacement]);\n\n return createMockMap(newEntries);\n };\n\n const apply: MockMap[\"apply\"] = (otherMockMap) =>\n createMockMap([\n ...entries.filter(\n (e) =>\n otherMockMap.entries.find((oe) => oe[0] === e[0]) ===\n undefined,\n ),\n ...otherMockMap.entries,\n ]);\n\n return { entries, map, add, apply };\n};\n","import { once } from \"./helpers\";\nimport { Scope } from \"./scope\";\nimport { createMockMap, MockMap } from \"./mock-map\";\n\n/**\n * Calls a resolver(factory) with an optional scope and a mock map\n * and returns an instance.\n *\n * A passed scope will be propagated up a graph and will be passed\n * to all scoped providers to resolve their instance within this scope.\n * If a provider is scoped, it will either create a new instance\n * and store it in the scope, or retrieve an already created instance\n * from the scope.\n *\n * It is also possible to explicitly pass a mock map, but It's not recommended.\n * If you want to mock(replace) providers for a resolution,\n * it's best to use `mock` method.\n */\ntype ProviderCallable<T> = (scope?: Scope, mockMap?: MockMap) => T;\n\n/**\n * Instance factory with lifetime and dynamic context.\n */\nexport type Provider<T> = ProviderCallable<T> & {\n /**\n * Mocks(replaces) a provider within the visible graph,\n * returning a new provider with that mock.\n *\n * @returns A new provider with the mocked dependency provider.\n */\n mock<U>(\n /**\n * A provider used by the current provider\n * that needs to be replaced.\n */\n dependencyProvider: Provider<U>,\n /**\n * A provider with a same interface\n * that will be a replacement for the first one.\n */\n replacement: Provider<U>,\n ): Provider<T>;\n};\n\ntype Lifetime = \"transient\" | \"singleton\" | \"scoped\";\n\n/**\n * A function that resolves an instance of a passed provider.\n * It's needed to resolve correct instance in a scope\n * and to use mock of the passed provider, if any.\n */\ntype UseFn = <T>(provider: Provider<T>) => T;\n\n/**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\ntype Resolver<T> = (use: UseFn) => T;\n\n/**\n * Creates a new provider, instance factory with lifetime and dynamic context.\n *\n * @returns A new provider.\n */\nexport const provide = <T>(\n /**\n * Instance lifetime. Can be `\"transient\"`, `\"singleton\"` or `\"scoped\"`.\n *\n * If `\"transient\"`, will return a new instance on each resolution.\n *\n * If `\"singleton\"`, will create an instance once and return it on every request.\n *\n * If `\"scoped\"`, will save the instance in scope on first resolution\n * and will retrieve it from scope on next resolutions.\n * If scope was not specified, will create a new instance on each resolution.\n */\n lifetime: Lifetime,\n\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n\n /**\n * An optional mock map. Not recommended to specify explicitly,\n * use `mock` method to mock providers.\n */\n mockMap: MockMap = createMockMap(),\n): Provider<T> => {\n type ProviderType = Provider<T>;\n\n const getSelf = once(() => Object.assign(resolve, properties));\n\n const originalResolver = resolver;\n resolver = lifetime === \"singleton\" ? once(resolver) : resolver;\n\n const resolve: ProviderCallable<T> = (scope, requestMockMap) => {\n const currentMockMap = requestMockMap\n ? mockMap.apply(requestMockMap)\n : mockMap;\n\n const use: UseFn = (provider) =>\n currentMockMap.map(provider)(scope, currentMockMap);\n\n if (lifetime !== \"scoped\" || !scope) return resolver(use);\n\n const resolution = scope.get(getSelf()) || resolver(use);\n scope.set(getSelf(), resolution);\n\n return resolution;\n };\n\n const mock: ProviderType[\"mock\"] = (dependencyProvider, replacement) =>\n provide(\n lifetime,\n originalResolver,\n mockMap.add(dependencyProvider, replacement),\n );\n\n const properties = {\n mock,\n };\n\n return getSelf();\n};\n\n/**\n * Creates a new transient provider.\n * This provider will return a new instance on each resolution.\n *\n * @returns A new transient provider.\n */\nexport const transient = <T>(\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n) => provide(\"transient\", resolver);\n\n/**\n * Creates a new singleton provider.\n * This provider will create an instance once and return it on every request.\n *\n * @returns A new singleton provider.\n */\nexport const singleton = <T>(\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n) => provide(\"singleton\", resolver);\n\n/**\n * Creates a new transient provider.\n * This provider will save the instance in scope on first resolution\n * and will retrieve it from scope on next resolutions.\n * If scope was not specified, will create a new instance on each resolution.\n *\n * @returns A new scoped provider.\n */\nexport const scoped = <T>(\n /**\n * A function that creates an instance by resolving its dependencies.\n * If there are dependencies, you must use `use` function passed\n * in the first argument.\n */\n resolver: Resolver<T>,\n) => provide(\"scoped\", resolver);\n","import { Provider } from \"./provider\";\n\n/**\n * A map of providers to their instances.\n * Passed to the provider call to resolve instances\n * of scoped providers within it.\n */\nexport type Scope = WeakMap<Provider<any>, any>;\n\n/**\n * Creates a new scope, map of providers to their instances.\n * Scope is passed to the provider call to resolve instances\n * of scoped providers within it.\n *\n * @returns A new scope.\n */\nexport const createScope = (): Scope => new WeakMap();\n","import { Provider } from \"./provider\";\nimport { Scope } from \"./scope\";\nimport { MockMap } from \"./mock-map\";\n\n/**\n * A map of string keys to providers.\n */\ntype ProviderMap = Record<string, Provider<any>>;\n\ntype InferProviderMapOutputs<Providers extends ProviderMap> = {\n [K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;\n};\n\n/**\n * Resolves all providers in a `ProviderMap` and\n * returns an object containing their instances.\n *\n * @returns An object containing the resolved instances of the providers.\n */\ntype ProviderSelectionCallable<Providers extends ProviderMap> = (\n /**\n * An optional scope to use for scoped providers.\n */\n scope?: Scope,\n /**\n * An optional mock map to use for mocking providers.\n */\n mockMap?: MockMap,\n) => InferProviderMapOutputs<Providers>;\n\n/**\n * A selection of providers.\n */\nexport type ProviderSelection<Providers extends ProviderMap> =\n ProviderSelectionCallable<Providers> & {\n /**\n * The `ProviderMap` that the selection is based on.\n */\n map: Providers;\n /**\n * Mocks a provider within the selection, returning a new\n * `ProviderSelection` with the mock applied.\n *\n * @returns A new `ProviderSelection` with the mocked provider.\n */\n mock<T>(\n /**\n * A provider used by the current provider\n * that needs to be replaced.\n */\n dependencyProvider: Provider<T>,\n /**\n * A provider with a same interface that will be\n * a replacement for the first one.\n */\n replacement: Provider<T>,\n ): ProviderSelection<Providers>;\n };\n\n/**\n * Creates a new provider selection from a provider map.\n *\n * @returns A new provider selection.\n */\nexport const select = <Providers extends ProviderMap>(\n /**\n * A map of string keys to providers.\n */\n map: Providers,\n): ProviderSelection<Providers> => {\n type SelectionType = ProviderSelection<Providers>;\n\n const resolveAll: ProviderSelectionCallable<Providers> = (\n scope,\n mockMap,\n ) => {\n const resultEntries = Object.entries(map).map(([key, provider]) =>\n mockMap\n ? [key, mockMap.map(provider)(scope, mockMap)]\n : [key, provider(scope, mockMap)],\n );\n\n return Object.fromEntries(\n resultEntries,\n ) as InferProviderMapOutputs<Providers>;\n };\n\n const mock: SelectionType[\"mock\"] = (dependencyProvider, replacement) => {\n const newEntries = Object.entries(map).map(([key, provider]) =>\n provider === dependencyProvider\n ? [key, replacement]\n : [key, provider.mock(dependencyProvider, replacement)],\n );\n\n return select(Object.fromEntries(newEntries) as Providers);\n };\n\n return Object.assign(resolveAll, { map, mock });\n};\n"],"mappings":"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","names":[]}
|