composed-di 0.0.3 → 0.0.5-alpha

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.
@@ -9,36 +9,46 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.singletonFactory = singletonFactory;
13
- exports.oneShotFactory = oneShotFactory;
14
- function singletonFactory({ provides, dependsOn = [], initialize, dispose = () => { }, }) {
15
- let instance;
16
- return {
17
- provides,
18
- dependsOn,
19
- initialize(...dependencies) {
20
- return __awaiter(this, void 0, void 0, function* () {
21
- if (instance) {
12
+ exports.ServiceFactory = void 0;
13
+ class ServiceFactory {
14
+ /**
15
+ * Creates a singleton service factory that ensures a single instance of the provided service is initialized
16
+ * and used throughout its lifecycle.
17
+ */
18
+ static singleton({ provides, dependsOn = [], initialize, dispose = () => { }, }) {
19
+ let instance;
20
+ return {
21
+ provides,
22
+ dependsOn,
23
+ initialize(...dependencies) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ if (instance) {
26
+ return instance;
27
+ }
28
+ instance = yield initialize(...dependencies);
22
29
  return instance;
30
+ });
31
+ },
32
+ dispose(serviceInstance) {
33
+ if (instance === serviceInstance) {
34
+ dispose(serviceInstance);
35
+ instance = undefined;
23
36
  }
24
- instance = yield initialize(...dependencies);
25
- return instance;
26
- });
27
- },
28
- dispose(serviceInstance) {
29
- if (instance === serviceInstance) {
30
- dispose(serviceInstance);
31
- instance = undefined;
32
- }
33
- },
34
- };
37
+ },
38
+ };
39
+ }
40
+ /**
41
+ * Creates a one-shot service factory that initializes a new instance of the provided service
42
+ * every time it is requested.
43
+ */
44
+ static oneShot({ provides, dependsOn, initialize, dispose = () => { }, }) {
45
+ return {
46
+ provides,
47
+ dependsOn,
48
+ initialize,
49
+ dispose,
50
+ };
51
+ }
35
52
  }
36
- function oneShotFactory({ provides, dependsOn, initialize, dispose = () => { }, }) {
37
- return {
38
- provides,
39
- dependsOn,
40
- initialize,
41
- dispose,
42
- };
43
- }
44
- //# sourceMappingURL=serviceFactory.js.map
53
+ exports.ServiceFactory = ServiceFactory;
54
+ //# sourceMappingURL=ServiceFactory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serviceFactory.js","sourceRoot":"","sources":["../src/serviceFactory.ts"],"names":[],"mappings":";;;;;;;;;;;AAmBA,4CA8BC;AAED,wCAiBC;AAjDD,SAAgB,gBAAgB,CAA0C,EACxE,QAAQ,EACR,SAAS,GAAG,EAAkB,EAC9B,UAAU,EACV,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,GAMnB;IACC,IAAI,QAAuB,CAAC;IAE5B,OAAO;QACL,QAAQ;QACR,SAAS;QACH,UAAU,CAAC,GAAG,YAAgC;;gBAClD,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBACD,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,YAAY,CAAC,CAAC;gBAC7C,OAAO,QAAQ,CAAC;YAClB,CAAC;SAAA;QACD,OAAO,CAAC,eAAkB;YACxB,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;gBACjC,OAAO,CAAC,eAAe,CAAC,CAAC;gBACzB,QAAQ,GAAG,SAAS,CAAC;YACvB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,cAAc,CAA0C,EACtE,QAAQ,EACR,SAAS,EACT,UAAU,EACV,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,GAMnB;IACC,OAAO;QACL,QAAQ;QACR,SAAS;QACT,UAAU;QACV,OAAO;KACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"ServiceFactory.js","sourceRoot":"","sources":["../src/ServiceFactory.ts"],"names":[],"mappings":";;;;;;;;;;;;AAUA,MAAsB,cAAc;IAWlC;;;OAGG;IACH,MAAM,CAAC,SAAS,CAGd,EACA,QAAQ,EACR,SAAS,GAAG,EAAkB,EAC9B,UAAU,EACV,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,GAMnB;QACC,IAAI,QAAuB,CAAC;QAE5B,OAAO;YACL,QAAQ;YACR,SAAS;YACH,UAAU,CAAC,GAAG,YAAgC;;oBAClD,IAAI,QAAQ,EAAE,CAAC;wBACb,OAAO,QAAQ,CAAC;oBAClB,CAAC;oBACD,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,YAAY,CAAC,CAAC;oBAC7C,OAAO,QAAQ,CAAC;gBAClB,CAAC;aAAA;YACD,OAAO,CAAC,eAAkB;gBACxB,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;oBACjC,OAAO,CAAC,eAAe,CAAC,CAAC;oBACzB,QAAQ,GAAG,SAAS,CAAC;gBACvB,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,OAAO,CAA+D,EAC3E,QAAQ,EACR,SAAS,EACT,UAAU,EACV,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,GAMnB;QACC,OAAO;YACL,QAAQ;YACR,SAAS;YACT,UAAU;YACV,OAAO;SACR,CAAC;IACJ,CAAC;CACF;AAxED,wCAwEC"}
@@ -3,4 +3,4 @@ export declare class ServiceKey<T> {
3
3
  private readonly symbol;
4
4
  constructor(name: string);
5
5
  }
6
- //# sourceMappingURL=serviceKey.d.ts.map
6
+ //# sourceMappingURL=ServiceKey.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"serviceKey.d.ts","sourceRoot":"","sources":["../src/serviceKey.ts"],"names":[],"mappings":"AACA,qBAAa,UAAU,CAAC,CAAC;aAGK,IAAI,EAAE,MAAM;IAFxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEJ,IAAI,EAAE,MAAM;CAGzC"}
1
+ {"version":3,"file":"ServiceKey.d.ts","sourceRoot":"","sources":["../src/ServiceKey.ts"],"names":[],"mappings":"AACA,qBAAa,UAAU,CAAC,CAAC;aAGK,IAAI,EAAE,MAAM;IAFxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEJ,IAAI,EAAE,MAAM;CAGzC"}
@@ -9,4 +9,4 @@ class ServiceKey {
9
9
  }
10
10
  }
11
11
  exports.ServiceKey = ServiceKey;
12
- //# sourceMappingURL=serviceKey.js.map
12
+ //# sourceMappingURL=ServiceKey.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serviceKey.js","sourceRoot":"","sources":["../src/serviceKey.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,MAAa,UAAU;IAGrB,YAA4B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACF;AAND,gCAMC"}
1
+ {"version":3,"file":"ServiceKey.js","sourceRoot":"","sources":["../src/ServiceKey.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,MAAa,UAAU;IAGrB,YAA4B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACF;AAND,gCAMC"}
@@ -1,10 +1,9 @@
1
- import { ServiceKey } from './serviceKey';
2
- import { ServiceFactory } from './serviceFactory';
3
- import { ServiceProvider } from './serviceProvider';
4
- export declare class ServiceModule implements ServiceProvider {
5
- private readonly factories;
6
- constructor(factories: Set<ServiceFactory<unknown, ServiceKey<unknown>[]>>);
1
+ import { ServiceKey } from './ServiceKey';
2
+ import { ServiceFactory } from './ServiceFactory';
3
+ export declare class ServiceModule {
4
+ readonly factories: ServiceFactory<any, any>[];
5
+ constructor(factories: Set<ServiceFactory<unknown, readonly ServiceKey<unknown>[]>>);
7
6
  get<T>(key: ServiceKey<T>): Promise<T>;
8
- static from(entries: (ServiceModule | ServiceFactory<unknown, ServiceKey<unknown>[]>)[]): ServiceModule;
7
+ static from(entries: (ServiceModule | ServiceFactory<unknown, readonly ServiceKey<unknown>[]>)[]): ServiceModule;
9
8
  }
10
- //# sourceMappingURL=serviceModule.d.ts.map
9
+ //# 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,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBnD,MAAM,CAAC,IAAI,CACT,OAAO,EAAE,CAAC,aAAa,GAAG,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,GAC1E,aAAa;CAajB"}
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;AAElD,qBAAa,aAAa;IACxB,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAM;gBAGlD,SAAS,EAAE,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAS5D,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBnD,MAAM,CAAC,IAAI,CACT,OAAO,EAAE,CAAC,aAAa,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,GACnF,aAAa;CAajB"}
@@ -74,4 +74,4 @@ function isRegistered(key, factories) {
74
74
  function isSuitable(key, factory) {
75
75
  return (factory === null || factory === void 0 ? void 0 : factory.provides) === key;
76
76
  }
77
- //# sourceMappingURL=serviceModule.js.map
77
+ //# sourceMappingURL=ServiceModule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serviceModule.js","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ServiceModule.js","sourceRoot":"","sources":["../src/ServiceModule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { ServiceModule } from './ServiceModule';
2
+ export interface DotGraphOptions {
3
+ /** Graph direction: 'TB' (top-bottom), 'LR' (left-right), 'BT' (bottom-top), 'RL' (right-left) */
4
+ direction?: 'TB' | 'LR' | 'BT' | 'RL';
5
+ /** Title for the graph */
6
+ title?: string;
7
+ /** Show nodes with no dependencies in a different color */
8
+ highlightLeaves?: boolean;
9
+ /** Show nodes with no dependents in a different color */
10
+ highlightRoots?: boolean;
11
+ }
12
+ /**
13
+ * Generates a DOT notation graph from a ServiceModule.
14
+ * The output can be visualized using Graphviz tools or online viewers like:
15
+ * - https://dreampuf.github.io/GraphvizOnline/
16
+ * - https://edotor.net/
17
+ *
18
+ * Arrows point from dependencies to dependents (from what is needed to what needs it).
19
+ *
20
+ * @param module - The ServiceModule to convert to DOT notation
21
+ * @param options - Optional configuration for the graph appearance
22
+ * @returns A string containing the DOT notation graph
23
+ */
24
+ export declare function createDotGraph(module: ServiceModule, { direction, title, highlightLeaves, highlightRoots }?: DotGraphOptions): string;
25
+ export declare function printDotGraph(module: ServiceModule): void;
26
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,MAAM,WAAW,eAAe;IAC9B,kGAAkG;IAClG,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACtC,0BAA0B;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AASD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,GAAE,eAKtD,GACA,MAAM,CA6FR;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,QAIlD"}
package/dist/utils.js ADDED
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDotGraph = createDotGraph;
4
+ exports.printDotGraph = printDotGraph;
5
+ /**
6
+ * Escapes special characters in strings for DOT notation
7
+ */
8
+ function escapeDotString(str) {
9
+ return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
10
+ }
11
+ /**
12
+ * Generates a DOT notation graph from a ServiceModule.
13
+ * The output can be visualized using Graphviz tools or online viewers like:
14
+ * - https://dreampuf.github.io/GraphvizOnline/
15
+ * - https://edotor.net/
16
+ *
17
+ * Arrows point from dependencies to dependents (from what is needed to what needs it).
18
+ *
19
+ * @param module - The ServiceModule to convert to DOT notation
20
+ * @param options - Optional configuration for the graph appearance
21
+ * @returns A string containing the DOT notation graph
22
+ */
23
+ function createDotGraph(module, { direction, title, highlightLeaves, highlightRoots } = {
24
+ direction: 'BT',
25
+ title: 'Service Dependency Graph',
26
+ highlightLeaves: true,
27
+ highlightRoots: true,
28
+ }) {
29
+ const factories = module.factories;
30
+ const lines = [];
31
+ // Start the digraph
32
+ lines.push('digraph ServiceDependencies {');
33
+ lines.push(` label="${title}";`);
34
+ lines.push(' labelloc="t";');
35
+ lines.push(' fontsize=16;');
36
+ lines.push(` rankdir=${direction};`);
37
+ lines.push('');
38
+ // Default node styling
39
+ lines.push(' node [');
40
+ lines.push(' shape=box,');
41
+ lines.push(' style="rounded,filled",');
42
+ lines.push(' fillcolor="#e1f5ff",');
43
+ lines.push(' color="#0288d1",');
44
+ lines.push(' fontname="Arial",');
45
+ lines.push(' fontsize=12');
46
+ lines.push(' ];');
47
+ lines.push('');
48
+ // Default edge styling
49
+ lines.push(' edge [');
50
+ lines.push(' color="#666666",');
51
+ lines.push(' arrowsize=0.8');
52
+ lines.push(' ];');
53
+ lines.push('');
54
+ // Build dependency maps to identify leaves and roots
55
+ const hasDependencies = new Set();
56
+ const hasDependents = new Set();
57
+ factories.forEach((factory) => {
58
+ const serviceName = factory.provides.name;
59
+ if (factory.dependsOn.length > 0) {
60
+ hasDependencies.add(serviceName);
61
+ }
62
+ factory.dependsOn.forEach((dependency) => {
63
+ hasDependents.add(dependency.name);
64
+ });
65
+ });
66
+ // Define nodes with special styling for leaves and roots
67
+ const nodeIds = new Map();
68
+ let nodeCounter = 0;
69
+ factories.forEach((factory) => {
70
+ const serviceName = factory.provides.name;
71
+ const nodeId = `node${nodeCounter++}`;
72
+ nodeIds.set(serviceName, nodeId);
73
+ const isLeaf = !hasDependencies.has(serviceName);
74
+ const isRoot = !hasDependents.has(serviceName);
75
+ let nodeStyle = '';
76
+ if (highlightLeaves && isLeaf) {
77
+ nodeStyle = ' [fillcolor="#c8e6c9", color="#388e3c"]';
78
+ }
79
+ else if (highlightRoots && isRoot) {
80
+ nodeStyle = ' [fillcolor="#ffccbc", color="#d84315"]';
81
+ }
82
+ lines.push(` ${nodeId} [label="${escapeDotString(serviceName)}"]${nodeStyle};`);
83
+ });
84
+ lines.push('');
85
+ // Define edges (dependencies)
86
+ factories.forEach((factory) => {
87
+ const serviceName = factory.provides.name;
88
+ const serviceNodeId = nodeIds.get(serviceName);
89
+ factory.dependsOn.forEach((dependency) => {
90
+ const depName = dependency.name;
91
+ const depNodeId = nodeIds.get(depName);
92
+ if (depNodeId) {
93
+ // Arrow points from dependency to dependent (what provides -> what needs it)
94
+ lines.push(` ${depNodeId} -> ${serviceNodeId};`);
95
+ }
96
+ });
97
+ });
98
+ // Close the digraph
99
+ lines.push('}');
100
+ return lines.join('\n');
101
+ }
102
+ function printDotGraph(module) {
103
+ console.log(createDotGraph(module));
104
+ console.log('\n\nCopy the DOT output above and paste it into:');
105
+ console.log('https://dreampuf.github.io/GraphvizOnline/');
106
+ }
107
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "composed-di",
3
3
  "private": false,
4
- "version": "0.0.3",
4
+ "version": "0.0.5-alpha",
5
5
  "author": "Juan Herrera juanhr454@gmail.com",
6
6
  "type": "commonjs",
7
7
  "main": "./dist/index.js",
@@ -0,0 +1,83 @@
1
+ import { ServiceKey } from './ServiceKey';
2
+
3
+ // Helper types to extract the type from ServiceKey
4
+ type ServiceType<T> = T extends ServiceKey<infer U> ? U : never;
5
+
6
+ // Helper types to convert an array/tuple of ServiceKey to tuple of their types
7
+ type DependencyTypes<T extends readonly ServiceKey<unknown>[]> = {
8
+ [K in keyof T]: ServiceType<T[K]>;
9
+ };
10
+
11
+ export abstract class ServiceFactory<
12
+ const T,
13
+ const D extends readonly ServiceKey<unknown>[] = [],
14
+ > {
15
+ abstract provides: ServiceKey<T>;
16
+ abstract dependsOn: D;
17
+
18
+ abstract initialize(...dependencies: DependencyTypes<D>): T | Promise<T>;
19
+
20
+ abstract dispose(instance: T): void;
21
+
22
+ /**
23
+ * Creates a singleton service factory that ensures a single instance of the provided service is initialized
24
+ * and used throughout its lifecycle.
25
+ */
26
+ static singleton<
27
+ const T,
28
+ const D extends readonly ServiceKey<unknown>[] = [],
29
+ >({
30
+ provides,
31
+ dependsOn = [] as unknown as D,
32
+ initialize,
33
+ dispose = () => {},
34
+ }: {
35
+ provides: ServiceKey<T>;
36
+ dependsOn?: D;
37
+ initialize: (...dependencies: DependencyTypes<D>) => T | Promise<T>;
38
+ dispose?: (instance: T) => void;
39
+ }): ServiceFactory<T, D> {
40
+ let instance: T | undefined;
41
+
42
+ return {
43
+ provides,
44
+ dependsOn,
45
+ async initialize(...dependencies: DependencyTypes<D>): Promise<T> {
46
+ if (instance) {
47
+ return instance;
48
+ }
49
+ instance = await initialize(...dependencies);
50
+ return instance;
51
+ },
52
+ dispose(serviceInstance: T): void {
53
+ if (instance === serviceInstance) {
54
+ dispose(serviceInstance);
55
+ instance = undefined;
56
+ }
57
+ },
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Creates a one-shot service factory that initializes a new instance of the provided service
63
+ * every time it is requested.
64
+ */
65
+ static oneShot<const T, const D extends readonly ServiceKey<unknown>[] = []>({
66
+ provides,
67
+ dependsOn,
68
+ initialize,
69
+ dispose = () => {},
70
+ }: {
71
+ provides: ServiceKey<T>;
72
+ dependsOn: D;
73
+ initialize: (...dependencies: DependencyTypes<D>) => T | Promise<T>;
74
+ dispose?: (instance: T) => void;
75
+ }): ServiceFactory<T, D> {
76
+ return {
77
+ provides,
78
+ dependsOn,
79
+ initialize,
80
+ dispose,
81
+ };
82
+ }
83
+ }
@@ -1,101 +1,102 @@
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 get<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.get(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
- }
1
+ import { ServiceKey } from './ServiceKey';
2
+ import { ServiceFactory } from './ServiceFactory';
3
+
4
+ export class ServiceModule {
5
+ readonly factories: ServiceFactory<any, any>[] = [];
6
+
7
+ constructor(
8
+ factories: Set<ServiceFactory<unknown, readonly ServiceKey<unknown>[]>>,
9
+ ) {
10
+ this.factories = Array.from(factories);
11
+ this.factories.forEach((factory) => {
12
+ checkRecursiveDependencies(factory);
13
+ checkMissingDependencies(factory, this.factories);
14
+ });
15
+ }
16
+
17
+ public async get<T>(key: ServiceKey<T>): Promise<T> {
18
+ const factory = this.factories.find((factory) => {
19
+ return isSuitable(key, factory);
20
+ });
21
+
22
+ // Check if a factory to supply the requested key was not found
23
+ if (!factory) {
24
+ throw new Error(`Could not find a suitable factory for ${key.name}`);
25
+ }
26
+
27
+ // Resolve all dependencies first
28
+ const dependencies = await Promise.all(
29
+ factory.dependsOn.map((dependencyKey: ServiceKey<unknown>) => {
30
+ return this.get(dependencyKey);
31
+ }),
32
+ );
33
+
34
+ // Call the factory to retrieve the dependency
35
+ return factory.initialize(...dependencies);
36
+ }
37
+
38
+ static from(
39
+ entries: (ServiceModule | ServiceFactory<unknown, readonly ServiceKey<unknown>[]>)[],
40
+ ): ServiceModule {
41
+ return new ServiceModule(
42
+ new Set(
43
+ entries.flatMap((e) => {
44
+ if (e instanceof ServiceModule) {
45
+ return e.factories;
46
+ } else {
47
+ return [e];
48
+ }
49
+ }),
50
+ ),
51
+ );
52
+ }
53
+ }
54
+
55
+ function checkRecursiveDependencies(
56
+ factory: ServiceFactory<unknown, readonly ServiceKey<unknown>[]>,
57
+ ) {
58
+ const recursive = factory.dependsOn.some((dependencyKey) => {
59
+ return dependencyKey === factory.provides;
60
+ });
61
+
62
+ if (recursive) {
63
+ throw new Error(
64
+ 'Recursive dependency detected on: ' + factory.provides.name,
65
+ );
66
+ }
67
+ }
68
+
69
+ function checkMissingDependencies(
70
+ factory: ServiceFactory<unknown, readonly ServiceKey<unknown>[]>,
71
+ factories: ServiceFactory<unknown>[],
72
+ ) {
73
+ const missingDependencies = factory.dependsOn.filter(
74
+ (dependencyKey: ServiceKey<any>) => {
75
+ return !isRegistered(dependencyKey, factories);
76
+ },
77
+ );
78
+ if (missingDependencies.length === 0) {
79
+ return;
80
+ }
81
+
82
+ const dependencyList = missingDependencies
83
+ .map((dependencyKey) => ` -> ${dependencyKey.name}`)
84
+ .join('\n');
85
+ throw new Error(
86
+ `${factory.provides.name} will fail because it depends on:\n ${dependencyList}`,
87
+ );
88
+ }
89
+
90
+ function isRegistered(
91
+ key: ServiceKey<unknown>,
92
+ factories: ServiceFactory<unknown>[],
93
+ ) {
94
+ return factories.some((factory) => factory.provides === key);
95
+ }
96
+
97
+ function isSuitable<T, D extends readonly ServiceKey<unknown>[]>(
98
+ key: ServiceKey<T>,
99
+ factory: ServiceFactory<unknown, D>,
100
+ ): factory is ServiceFactory<T, D> {
101
+ return factory?.provides === key;
102
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { ServiceKey } from './serviceKey';
2
- export { ServiceModule } from './serviceModule';
3
- export { type ServiceFactory, singletonFactory, oneShotFactory } from './serviceFactory';
4
- export { type ServiceProvider } from './serviceProvider';
1
+ export * from './ServiceKey';
2
+ export * from './ServiceModule';
3
+ export * from './ServiceFactory';
4
+ export * from './utils'