composed-di 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/serviceModule.d.ts +1 -1
- package/dist/serviceModule.d.ts.map +1 -1
- package/dist/serviceModule.js +9 -2
- package/dist/serviceModule.js.map +1 -1
- package/package.json +1 -1
- package/src/serviceModule.ts +101 -91
package/dist/serviceModule.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ export declare class ServiceModule implements ServiceProvider {
|
|
|
5
5
|
private readonly factories;
|
|
6
6
|
constructor(factories: Set<ServiceFactory<unknown, ServiceKey<unknown>[]>>);
|
|
7
7
|
inject<T>(key: ServiceKey<T>): Promise<T>;
|
|
8
|
-
static from(
|
|
8
|
+
static from(entries: (ServiceModule | ServiceFactory<unknown, ServiceKey<unknown>[]>)[]): ServiceModule;
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=serviceModule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceModule.d.ts","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;gBAEhD,SAAS,EAAE,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAQ7D,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBtD,MAAM,CAAC,IAAI,CACT,
|
|
1
|
+
{"version":3,"file":"serviceModule.d.ts","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;gBAEhD,SAAS,EAAE,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAQ7D,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBtD,MAAM,CAAC,IAAI,CACT,OAAO,EAAE,CAAC,aAAa,GAAG,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,GAC1E,aAAa;CAajB"}
|
package/dist/serviceModule.js
CHANGED
|
@@ -36,8 +36,15 @@ class ServiceModule {
|
|
|
36
36
|
return factory.initialize(...dependencies);
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
static from(
|
|
40
|
-
return new ServiceModule(new Set(
|
|
39
|
+
static from(entries) {
|
|
40
|
+
return new ServiceModule(new Set(entries.flatMap((e) => {
|
|
41
|
+
if (e instanceof ServiceModule) {
|
|
42
|
+
return e.factories;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return [e];
|
|
46
|
+
}
|
|
47
|
+
})));
|
|
41
48
|
}
|
|
42
49
|
}
|
|
43
50
|
exports.ServiceModule = ServiceModule;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceModule.js","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAa,aAAa;IAGxB,YAAY,SAA8D;QAFzD,cAAS,GAA+B,EAAE,CAAC;QAG1D,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACjC,0BAA0B,CAAC,OAAO,CAAC,CAAC;YACpC,wBAAwB,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC;IAEY,MAAM,CAAI,GAAkB;;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC9C,OAAO,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YAEH,+DAA+D;YAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,yCAAyC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACvE,CAAC;YAED,iCAAiC;YACjC,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,aAAkC,EAAE,EAAE;gBAC3D,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC,CAAC,CACH,CAAC;YAEF,8CAA8C;YAC9C,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,YAAY,CAAC,CAAC;QAC7C,CAAC;KAAA;IAED,MAAM,CAAC,IAAI,CACT,
|
|
1
|
+
{"version":3,"file":"serviceModule.js","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/serviceModule.ts
CHANGED
|
@@ -1,91 +1,101 @@
|
|
|
1
|
-
import { ServiceKey } from './serviceKey';
|
|
2
|
-
import { ServiceFactory } from './serviceFactory';
|
|
3
|
-
import { ServiceProvider } from './serviceProvider';
|
|
4
|
-
|
|
5
|
-
export class ServiceModule implements ServiceProvider {
|
|
6
|
-
private readonly factories: ServiceFactory<any, any>[] = [];
|
|
7
|
-
|
|
8
|
-
constructor(factories: Set<ServiceFactory<unknown, ServiceKey<unknown>[]>>) {
|
|
9
|
-
this.factories = Array.from(factories);
|
|
10
|
-
this.factories.forEach((factory) => {
|
|
11
|
-
checkRecursiveDependencies(factory);
|
|
12
|
-
checkMissingDependencies(factory, this.factories);
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public async inject<T>(key: ServiceKey<T>): Promise<T> {
|
|
17
|
-
const factory = this.factories.find((factory) => {
|
|
18
|
-
return isSuitable(key, factory);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// Check if a factory to supply the requested key was not found
|
|
22
|
-
if (!factory) {
|
|
23
|
-
throw new Error(`Could not find a suitable factory for ${key.name}`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Resolve all dependencies first
|
|
27
|
-
const dependencies = await Promise.all(
|
|
28
|
-
factory.dependsOn.map((dependencyKey: ServiceKey<unknown>) => {
|
|
29
|
-
return this.inject(dependencyKey);
|
|
30
|
-
}),
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
// Call the factory to retrieve the dependency
|
|
34
|
-
return factory.initialize(...dependencies);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
static from(
|
|
38
|
-
|
|
39
|
-
): ServiceModule {
|
|
40
|
-
return new ServiceModule(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
1
|
+
import { ServiceKey } from './serviceKey';
|
|
2
|
+
import { ServiceFactory } from './serviceFactory';
|
|
3
|
+
import { ServiceProvider } from './serviceProvider';
|
|
4
|
+
|
|
5
|
+
export class ServiceModule implements ServiceProvider {
|
|
6
|
+
private readonly factories: ServiceFactory<any, any>[] = [];
|
|
7
|
+
|
|
8
|
+
constructor(factories: Set<ServiceFactory<unknown, ServiceKey<unknown>[]>>) {
|
|
9
|
+
this.factories = Array.from(factories);
|
|
10
|
+
this.factories.forEach((factory) => {
|
|
11
|
+
checkRecursiveDependencies(factory);
|
|
12
|
+
checkMissingDependencies(factory, this.factories);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async inject<T>(key: ServiceKey<T>): Promise<T> {
|
|
17
|
+
const factory = this.factories.find((factory) => {
|
|
18
|
+
return isSuitable(key, factory);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Check if a factory to supply the requested key was not found
|
|
22
|
+
if (!factory) {
|
|
23
|
+
throw new Error(`Could not find a suitable factory for ${key.name}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Resolve all dependencies first
|
|
27
|
+
const dependencies = await Promise.all(
|
|
28
|
+
factory.dependsOn.map((dependencyKey: ServiceKey<unknown>) => {
|
|
29
|
+
return this.inject(dependencyKey);
|
|
30
|
+
}),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Call the factory to retrieve the dependency
|
|
34
|
+
return factory.initialize(...dependencies);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static from(
|
|
38
|
+
entries: (ServiceModule | ServiceFactory<unknown, ServiceKey<unknown>[]>)[],
|
|
39
|
+
): ServiceModule {
|
|
40
|
+
return new ServiceModule(
|
|
41
|
+
new Set(
|
|
42
|
+
entries.flatMap((e) => {
|
|
43
|
+
if (e instanceof ServiceModule) {
|
|
44
|
+
return e.factories;
|
|
45
|
+
} else {
|
|
46
|
+
return [e];
|
|
47
|
+
}
|
|
48
|
+
}),
|
|
49
|
+
),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function checkRecursiveDependencies(
|
|
55
|
+
factory: ServiceFactory<unknown, ServiceKey<unknown>[]>,
|
|
56
|
+
) {
|
|
57
|
+
const recursive = factory.dependsOn.some((dependencyKey) => {
|
|
58
|
+
return dependencyKey === factory.provides;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (recursive) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
'Recursive dependency detected on: ' + factory.provides.name,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function checkMissingDependencies(
|
|
69
|
+
factory: ServiceFactory<unknown, ServiceKey<unknown>[]>,
|
|
70
|
+
factories: ServiceFactory<unknown>[],
|
|
71
|
+
) {
|
|
72
|
+
const missingDependencies = factory.dependsOn.filter(
|
|
73
|
+
(dependencyKey: ServiceKey<any>) => {
|
|
74
|
+
return !isRegistered(dependencyKey, factories);
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
if (missingDependencies.length === 0) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const dependencyList = missingDependencies
|
|
82
|
+
.map((dependencyKey) => ` -> ${dependencyKey.name}`)
|
|
83
|
+
.join('\n');
|
|
84
|
+
throw new Error(
|
|
85
|
+
`${factory.provides.name} will fail because it depends on:\n ${dependencyList}`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function isRegistered(
|
|
90
|
+
key: ServiceKey<unknown>,
|
|
91
|
+
factories: ServiceFactory<unknown>[],
|
|
92
|
+
) {
|
|
93
|
+
return factories.some((factory) => factory.provides === key);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isSuitable<T, D extends ServiceKey<unknown>[]>(
|
|
97
|
+
key: ServiceKey<T>,
|
|
98
|
+
factory: ServiceFactory<unknown, D>,
|
|
99
|
+
): factory is ServiceFactory<T, D> {
|
|
100
|
+
return factory?.provides === key;
|
|
101
|
+
}
|