atomic-di 0.7.0-beta.1
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/index.d.mts +41 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +122 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +90 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024 ensi
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Not documented yet.
|
package/dist/index.d.mts
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
type Scope = WeakMap<Provider<any>, any>;
|
2
|
+
declare const createScope: () => Scope;
|
3
|
+
|
4
|
+
type SwapMapEntries = [Provider<any>, Provider<any>][];
|
5
|
+
type SwapMap = {
|
6
|
+
entries: SwapMapEntries;
|
7
|
+
resolve<T>(provider: Provider<T>): Provider<T>;
|
8
|
+
register<T>(provider: Provider<T>, replacement: Provider<T>): SwapMap;
|
9
|
+
apply(otherSwapContext: SwapMap): SwapMap;
|
10
|
+
};
|
11
|
+
declare const createSwapMap: (entries?: SwapMapEntries) => {
|
12
|
+
entries: SwapMapEntries;
|
13
|
+
resolve: <T>(provider: Provider<T>) => Provider<T>;
|
14
|
+
register: <T>(provider: Provider<T>, replacement: Provider<T>) => SwapMap;
|
15
|
+
apply: (otherSwapContext: SwapMap) => SwapMap;
|
16
|
+
};
|
17
|
+
|
18
|
+
type ProviderCallable<T> = (scope?: Scope, swapMap?: SwapMap) => T;
|
19
|
+
type Provider<T> = ProviderCallable<T> & {
|
20
|
+
swap<U>(dependencyProvider: Provider<U>, replacement: Provider<U>): Provider<T>;
|
21
|
+
};
|
22
|
+
type Lifetime = "transient" | "singleton" | "scoped";
|
23
|
+
type UseFn = <T>(provider: Provider<T>) => T;
|
24
|
+
type Resolver<T> = (use: UseFn) => T;
|
25
|
+
declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>, swapMap?: SwapMap) => Provider<T>;
|
26
|
+
declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
27
|
+
declare const singleton: <T>(resolver: Resolver<T>) => Provider<T>;
|
28
|
+
declare const scoped: <T>(resolver: Resolver<T>) => Provider<T>;
|
29
|
+
|
30
|
+
type ProviderMap = Record<string, Provider<any>>;
|
31
|
+
type InferProviderMapOutputs<Providers extends ProviderMap> = {
|
32
|
+
[K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;
|
33
|
+
};
|
34
|
+
type ProviderSelectionCallable<Providers extends ProviderMap> = (scope?: Scope, swapMap?: SwapMap) => InferProviderMapOutputs<Providers>;
|
35
|
+
type ProviderSelection<Providers extends ProviderMap> = ProviderSelectionCallable<Providers> & {
|
36
|
+
map: Providers;
|
37
|
+
swap<T>(dependencyProvider: Provider<T>, replacement: Provider<T>): ProviderSelection<Providers>;
|
38
|
+
};
|
39
|
+
declare const select: <Providers extends ProviderMap>(map: Providers) => ProviderSelection<Providers>;
|
40
|
+
|
41
|
+
export { type Provider, type ProviderSelection, type Scope, type SwapMap, createScope, createSwapMap, provide, scoped, select, singleton, transient };
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
type Scope = WeakMap<Provider<any>, any>;
|
2
|
+
declare const createScope: () => Scope;
|
3
|
+
|
4
|
+
type SwapMapEntries = [Provider<any>, Provider<any>][];
|
5
|
+
type SwapMap = {
|
6
|
+
entries: SwapMapEntries;
|
7
|
+
resolve<T>(provider: Provider<T>): Provider<T>;
|
8
|
+
register<T>(provider: Provider<T>, replacement: Provider<T>): SwapMap;
|
9
|
+
apply(otherSwapContext: SwapMap): SwapMap;
|
10
|
+
};
|
11
|
+
declare const createSwapMap: (entries?: SwapMapEntries) => {
|
12
|
+
entries: SwapMapEntries;
|
13
|
+
resolve: <T>(provider: Provider<T>) => Provider<T>;
|
14
|
+
register: <T>(provider: Provider<T>, replacement: Provider<T>) => SwapMap;
|
15
|
+
apply: (otherSwapContext: SwapMap) => SwapMap;
|
16
|
+
};
|
17
|
+
|
18
|
+
type ProviderCallable<T> = (scope?: Scope, swapMap?: SwapMap) => T;
|
19
|
+
type Provider<T> = ProviderCallable<T> & {
|
20
|
+
swap<U>(dependencyProvider: Provider<U>, replacement: Provider<U>): Provider<T>;
|
21
|
+
};
|
22
|
+
type Lifetime = "transient" | "singleton" | "scoped";
|
23
|
+
type UseFn = <T>(provider: Provider<T>) => T;
|
24
|
+
type Resolver<T> = (use: UseFn) => T;
|
25
|
+
declare const provide: <T>(lifetime: Lifetime, resolver: Resolver<T>, swapMap?: SwapMap) => Provider<T>;
|
26
|
+
declare const transient: <T>(resolver: Resolver<T>) => Provider<T>;
|
27
|
+
declare const singleton: <T>(resolver: Resolver<T>) => Provider<T>;
|
28
|
+
declare const scoped: <T>(resolver: Resolver<T>) => Provider<T>;
|
29
|
+
|
30
|
+
type ProviderMap = Record<string, Provider<any>>;
|
31
|
+
type InferProviderMapOutputs<Providers extends ProviderMap> = {
|
32
|
+
[K in keyof Providers]: Providers[K] extends Provider<infer T> ? T : never;
|
33
|
+
};
|
34
|
+
type ProviderSelectionCallable<Providers extends ProviderMap> = (scope?: Scope, swapMap?: SwapMap) => InferProviderMapOutputs<Providers>;
|
35
|
+
type ProviderSelection<Providers extends ProviderMap> = ProviderSelectionCallable<Providers> & {
|
36
|
+
map: Providers;
|
37
|
+
swap<T>(dependencyProvider: Provider<T>, replacement: Provider<T>): ProviderSelection<Providers>;
|
38
|
+
};
|
39
|
+
declare const select: <Providers extends ProviderMap>(map: Providers) => ProviderSelection<Providers>;
|
40
|
+
|
41
|
+
export { type Provider, type ProviderSelection, type Scope, type SwapMap, createScope, createSwapMap, provide, scoped, select, singleton, transient };
|
package/dist/index.js
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
var __defProp = Object.defineProperty;
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
5
|
+
var __export = (target, all) => {
|
6
|
+
for (var name in all)
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
8
|
+
};
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
11
|
+
for (let key of __getOwnPropNames(from))
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
14
|
+
}
|
15
|
+
return to;
|
16
|
+
};
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
18
|
+
|
19
|
+
// src/index.ts
|
20
|
+
var src_exports = {};
|
21
|
+
__export(src_exports, {
|
22
|
+
createScope: () => createScope,
|
23
|
+
createSwapMap: () => createSwapMap,
|
24
|
+
provide: () => provide,
|
25
|
+
scoped: () => scoped,
|
26
|
+
select: () => select,
|
27
|
+
singleton: () => singleton,
|
28
|
+
transient: () => transient
|
29
|
+
});
|
30
|
+
module.exports = __toCommonJS(src_exports);
|
31
|
+
|
32
|
+
// src/helpers.ts
|
33
|
+
var once = (fn) => {
|
34
|
+
let cachedResult;
|
35
|
+
return Object.assign(
|
36
|
+
(...args) => cachedResult ?? (cachedResult = fn(...args)),
|
37
|
+
fn
|
38
|
+
);
|
39
|
+
};
|
40
|
+
|
41
|
+
// src/swap-map.ts
|
42
|
+
var createSwapMap = (entries = []) => {
|
43
|
+
const resolve = (provider) => {
|
44
|
+
var _a;
|
45
|
+
return ((_a = entries.find((e) => e[0] === provider)) == null ? void 0 : _a[1]) || provider;
|
46
|
+
};
|
47
|
+
const register = (provider, replacement) => {
|
48
|
+
const newEntries = entries.map(
|
49
|
+
(e) => e[0] === provider ? [e[0], replacement] : e
|
50
|
+
);
|
51
|
+
if (newEntries.length === entries.length)
|
52
|
+
newEntries.push([provider, replacement]);
|
53
|
+
return createSwapMap(newEntries);
|
54
|
+
};
|
55
|
+
const apply = (otherSwapContext) => createSwapMap([
|
56
|
+
...entries.filter(
|
57
|
+
(e) => otherSwapContext.entries.find((oe) => oe[0] === e[0]) === void 0
|
58
|
+
),
|
59
|
+
...otherSwapContext.entries
|
60
|
+
]);
|
61
|
+
return { entries, resolve, register, apply };
|
62
|
+
};
|
63
|
+
|
64
|
+
// src/provider.ts
|
65
|
+
var provide = (lifetime, resolver, swapMap = createSwapMap()) => {
|
66
|
+
const getSelf = once(() => Object.assign(resolve, properties));
|
67
|
+
const originalResolver = resolver;
|
68
|
+
resolver = lifetime === "singleton" ? once(resolver) : resolver;
|
69
|
+
const resolve = (scope, requestSwapMap) => {
|
70
|
+
const currentSwapMap = requestSwapMap ? swapMap.apply(requestSwapMap) : swapMap;
|
71
|
+
const use = (provider) => currentSwapMap.resolve(provider)(scope, currentSwapMap);
|
72
|
+
if (lifetime !== "scoped" || !scope) return resolver(use);
|
73
|
+
const resolution = scope.get(getSelf()) || resolver(use);
|
74
|
+
scope.set(getSelf(), resolution);
|
75
|
+
return resolution;
|
76
|
+
};
|
77
|
+
const swap = (dependencyProvider, replacement) => provide(
|
78
|
+
lifetime,
|
79
|
+
originalResolver,
|
80
|
+
swapMap.register(dependencyProvider, replacement)
|
81
|
+
);
|
82
|
+
const properties = {
|
83
|
+
swap
|
84
|
+
};
|
85
|
+
return getSelf();
|
86
|
+
};
|
87
|
+
var transient = (resolver) => provide("transient", resolver);
|
88
|
+
var singleton = (resolver) => provide("singleton", resolver);
|
89
|
+
var scoped = (resolver) => provide("scoped", resolver);
|
90
|
+
|
91
|
+
// src/scope.ts
|
92
|
+
var createScope = () => /* @__PURE__ */ new WeakMap();
|
93
|
+
|
94
|
+
// src/selection.ts
|
95
|
+
var select = (map) => {
|
96
|
+
const resolveAll = (scope, swapMap) => {
|
97
|
+
const resultEntries = Object.entries(map).map(
|
98
|
+
([key, provider]) => swapMap ? [key, swapMap.resolve(provider)(scope, swapMap)] : [key, provider(scope, swapMap)]
|
99
|
+
);
|
100
|
+
return Object.fromEntries(
|
101
|
+
resultEntries
|
102
|
+
);
|
103
|
+
};
|
104
|
+
const swap = (dependencyProvider, replacement) => {
|
105
|
+
const newEntries = Object.entries(map).map(
|
106
|
+
([key, provider]) => provider === dependencyProvider ? [key, replacement] : [key, provider.swap(dependencyProvider, replacement)]
|
107
|
+
);
|
108
|
+
return select(Object.fromEntries(newEntries));
|
109
|
+
};
|
110
|
+
return Object.assign(resolveAll, { map, swap });
|
111
|
+
};
|
112
|
+
// Annotate the CommonJS export names for ESM import in node:
|
113
|
+
0 && (module.exports = {
|
114
|
+
createScope,
|
115
|
+
createSwapMap,
|
116
|
+
provide,
|
117
|
+
scoped,
|
118
|
+
select,
|
119
|
+
singleton,
|
120
|
+
transient
|
121
|
+
});
|
122
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +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":[]}
|
package/dist/index.mjs
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
// src/helpers.ts
|
2
|
+
var once = (fn) => {
|
3
|
+
let cachedResult;
|
4
|
+
return Object.assign(
|
5
|
+
(...args) => cachedResult ?? (cachedResult = fn(...args)),
|
6
|
+
fn
|
7
|
+
);
|
8
|
+
};
|
9
|
+
|
10
|
+
// src/swap-map.ts
|
11
|
+
var createSwapMap = (entries = []) => {
|
12
|
+
const resolve = (provider) => {
|
13
|
+
var _a;
|
14
|
+
return ((_a = entries.find((e) => e[0] === provider)) == null ? void 0 : _a[1]) || provider;
|
15
|
+
};
|
16
|
+
const register = (provider, replacement) => {
|
17
|
+
const newEntries = entries.map(
|
18
|
+
(e) => e[0] === provider ? [e[0], replacement] : e
|
19
|
+
);
|
20
|
+
if (newEntries.length === entries.length)
|
21
|
+
newEntries.push([provider, replacement]);
|
22
|
+
return createSwapMap(newEntries);
|
23
|
+
};
|
24
|
+
const apply = (otherSwapContext) => createSwapMap([
|
25
|
+
...entries.filter(
|
26
|
+
(e) => otherSwapContext.entries.find((oe) => oe[0] === e[0]) === void 0
|
27
|
+
),
|
28
|
+
...otherSwapContext.entries
|
29
|
+
]);
|
30
|
+
return { entries, resolve, register, apply };
|
31
|
+
};
|
32
|
+
|
33
|
+
// src/provider.ts
|
34
|
+
var provide = (lifetime, resolver, swapMap = createSwapMap()) => {
|
35
|
+
const getSelf = once(() => Object.assign(resolve, properties));
|
36
|
+
const originalResolver = resolver;
|
37
|
+
resolver = lifetime === "singleton" ? once(resolver) : resolver;
|
38
|
+
const resolve = (scope, requestSwapMap) => {
|
39
|
+
const currentSwapMap = requestSwapMap ? swapMap.apply(requestSwapMap) : swapMap;
|
40
|
+
const use = (provider) => currentSwapMap.resolve(provider)(scope, currentSwapMap);
|
41
|
+
if (lifetime !== "scoped" || !scope) return resolver(use);
|
42
|
+
const resolution = scope.get(getSelf()) || resolver(use);
|
43
|
+
scope.set(getSelf(), resolution);
|
44
|
+
return resolution;
|
45
|
+
};
|
46
|
+
const swap = (dependencyProvider, replacement) => provide(
|
47
|
+
lifetime,
|
48
|
+
originalResolver,
|
49
|
+
swapMap.register(dependencyProvider, replacement)
|
50
|
+
);
|
51
|
+
const properties = {
|
52
|
+
swap
|
53
|
+
};
|
54
|
+
return getSelf();
|
55
|
+
};
|
56
|
+
var transient = (resolver) => provide("transient", resolver);
|
57
|
+
var singleton = (resolver) => provide("singleton", resolver);
|
58
|
+
var scoped = (resolver) => provide("scoped", resolver);
|
59
|
+
|
60
|
+
// src/scope.ts
|
61
|
+
var createScope = () => /* @__PURE__ */ new WeakMap();
|
62
|
+
|
63
|
+
// src/selection.ts
|
64
|
+
var select = (map) => {
|
65
|
+
const resolveAll = (scope, swapMap) => {
|
66
|
+
const resultEntries = Object.entries(map).map(
|
67
|
+
([key, provider]) => swapMap ? [key, swapMap.resolve(provider)(scope, swapMap)] : [key, provider(scope, swapMap)]
|
68
|
+
);
|
69
|
+
return Object.fromEntries(
|
70
|
+
resultEntries
|
71
|
+
);
|
72
|
+
};
|
73
|
+
const swap = (dependencyProvider, replacement) => {
|
74
|
+
const newEntries = Object.entries(map).map(
|
75
|
+
([key, provider]) => provider === dependencyProvider ? [key, replacement] : [key, provider.swap(dependencyProvider, replacement)]
|
76
|
+
);
|
77
|
+
return select(Object.fromEntries(newEntries));
|
78
|
+
};
|
79
|
+
return Object.assign(resolveAll, { map, swap });
|
80
|
+
};
|
81
|
+
export {
|
82
|
+
createScope,
|
83
|
+
createSwapMap,
|
84
|
+
provide,
|
85
|
+
scoped,
|
86
|
+
select,
|
87
|
+
singleton,
|
88
|
+
transient
|
89
|
+
};
|
90
|
+
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +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":[]}
|
package/package.json
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
{
|
2
|
+
"name": "atomic-di",
|
3
|
+
"version": "0.7.0-beta.1",
|
4
|
+
"description": "A toolset for containerless dependency injection.",
|
5
|
+
"repository": {
|
6
|
+
"type": "git",
|
7
|
+
"url": "https://github.com/ncor/atomic-di.git"
|
8
|
+
},
|
9
|
+
"bugs": {
|
10
|
+
"url": "https://github.com/ncor/atomic-di/issues"
|
11
|
+
},
|
12
|
+
"homepage": "https://github.com/ncor/atomic-di#readme",
|
13
|
+
"exports": {
|
14
|
+
".": {
|
15
|
+
"types": "./dist/index.d.ts",
|
16
|
+
"require": "./dist/index.js",
|
17
|
+
"import": "./dist/index.mjs",
|
18
|
+
"default": "./dist/index.mjs"
|
19
|
+
}
|
20
|
+
},
|
21
|
+
"files": [
|
22
|
+
"dist"
|
23
|
+
],
|
24
|
+
"author": "ensi",
|
25
|
+
"license": "MIT",
|
26
|
+
"devDependencies": {
|
27
|
+
"@vitest/coverage-v8": "^2.1.8",
|
28
|
+
"p-map": "^7.0.3",
|
29
|
+
"tsup": "^8.3.5",
|
30
|
+
"typescript": "^5.7.2",
|
31
|
+
"vitest": "^2.1.8"
|
32
|
+
},
|
33
|
+
"scripts": {
|
34
|
+
"build": "npx tsup",
|
35
|
+
"test": "pnpx vitest coverage --coverage",
|
36
|
+
"benchmark": "pnpx vitest benchmark"
|
37
|
+
}
|
38
|
+
}
|