composed-di 0.3.0 → 0.4.1-alpha.0
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/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +277 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compiler/analyzer.d.ts +37 -0
- package/dist/compiler/analyzer.d.ts.map +1 -0
- package/dist/compiler/analyzer.js +208 -0
- package/dist/compiler/analyzer.js.map +1 -0
- package/dist/compiler/callGraphWalker.d.ts +46 -0
- package/dist/compiler/callGraphWalker.d.ts.map +1 -0
- package/dist/compiler/callGraphWalker.js +211 -0
- package/dist/compiler/callGraphWalker.js.map +1 -0
- package/dist/compiler/codeGenerator.d.ts +36 -0
- package/dist/compiler/codeGenerator.d.ts.map +1 -0
- package/dist/compiler/codeGenerator.js +182 -0
- package/dist/compiler/codeGenerator.js.map +1 -0
- package/dist/compiler/dependencyResolver.d.ts +34 -0
- package/dist/compiler/dependencyResolver.d.ts.map +1 -0
- package/dist/compiler/dependencyResolver.js +147 -0
- package/dist/compiler/dependencyResolver.js.map +1 -0
- package/dist/compiler/index.d.ts +26 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +78 -0
- package/dist/compiler/index.js.map +1 -0
- package/dist/compiler/types.d.ts +73 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/compiler/types.js +6 -0
- package/dist/compiler/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/openTelemetryTracer.d.ts +16 -0
- package/dist/openTelemetryTracer.d.ts.map +1 -0
- package/dist/openTelemetryTracer.js +56 -0
- package/dist/openTelemetryTracer.js.map +1 -0
- package/dist/serviceModule.d.ts +40 -1
- package/dist/serviceModule.d.ts.map +1 -1
- package/dist/serviceModule.js +107 -12
- package/dist/serviceModule.js.map +1 -1
- package/dist/traceable.d.ts +18 -0
- package/dist/traceable.d.ts.map +1 -0
- package/dist/traceable.js +32 -0
- package/dist/traceable.js.map +1 -0
- package/dist/tracer.d.ts +24 -0
- package/dist/tracer.d.ts.map +1 -0
- package/dist/tracer.js +27 -0
- package/dist/tracer.js.map +1 -0
- package/dist/tracing/consoleTracer.d.ts +12 -0
- package/dist/tracing/consoleTracer.d.ts.map +1 -0
- package/dist/tracing/consoleTracer.js +48 -0
- package/dist/tracing/consoleTracer.js.map +1 -0
- package/dist/tracing/noopTracer.d.ts +13 -0
- package/dist/tracing/noopTracer.d.ts.map +1 -0
- package/dist/tracing/noopTracer.js +18 -0
- package/dist/tracing/noopTracer.js.map +1 -0
- package/dist/tracing/otelTracer.d.ts +16 -0
- package/dist/tracing/otelTracer.d.ts.map +1 -0
- package/dist/tracing/otelTracer.js +56 -0
- package/dist/tracing/otelTracer.js.map +1 -0
- package/dist/tracing/tracer.d.ts +13 -0
- package/dist/tracing/tracer.d.ts.map +1 -0
- package/dist/tracing/tracer.js +3 -0
- package/dist/tracing/tracer.js.map +1 -0
- package/dist/tracing/xrayTracer.d.ts +15 -0
- package/dist/tracing/xrayTracer.d.ts.map +1 -0
- package/dist/tracing/xrayTracer.js +51 -0
- package/dist/tracing/xrayTracer.js.map +1 -0
- package/dist/tracing-test/otel-demo.d.ts +14 -0
- package/dist/tracing-test/otel-demo.d.ts.map +1 -0
- package/dist/tracing-test/otel-demo.js +213 -0
- package/dist/tracing-test/otel-demo.js.map +1 -0
- package/package.json +10 -1
- package/src/index.ts +1 -0
- package/src/serviceModule.ts +151 -15
- package/src/tracing/consoleTracer.ts +47 -0
- package/src/tracing/noopTracer.ts +15 -0
- package/src/tracing/otelTracer.ts +58 -0
- package/src/tracing/tracer.ts +12 -0
- package/src/tracing/xrayTracer.ts +50 -0
- package/src/tracing-test/otel-demo.ts +225 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CallGraphWalker = void 0;
|
|
37
|
+
const ts = __importStar(require("typescript"));
|
|
38
|
+
/**
|
|
39
|
+
* Walks the call graph starting from an entry point function
|
|
40
|
+
* and collects all ServiceKey usages via module.get() and module.getOrNull()
|
|
41
|
+
*/
|
|
42
|
+
class CallGraphWalker {
|
|
43
|
+
constructor(program, checker, analysis) {
|
|
44
|
+
this.visitedFunctions = new Set();
|
|
45
|
+
this.collectedKeys = new Set();
|
|
46
|
+
this.program = program;
|
|
47
|
+
this.checker = checker;
|
|
48
|
+
this.analysis = analysis;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Starts walking from the entry point function
|
|
52
|
+
* @param entryPointFile Path to the file containing the entry point
|
|
53
|
+
* @param entryPointFunction Name of the entry point function
|
|
54
|
+
* @returns Set of ServiceKey variable names used in the call graph
|
|
55
|
+
*/
|
|
56
|
+
walk(entryPointFile, entryPointFunction) {
|
|
57
|
+
const sourceFile = this.program.getSourceFile(entryPointFile);
|
|
58
|
+
if (!sourceFile) {
|
|
59
|
+
throw new Error(`Entry point file not found: ${entryPointFile}`);
|
|
60
|
+
}
|
|
61
|
+
// Find the entry point function
|
|
62
|
+
const entryPoint = this.findFunction(sourceFile, entryPointFunction);
|
|
63
|
+
if (!entryPoint) {
|
|
64
|
+
throw new Error(`Entry point function not found: ${entryPointFunction} in ${entryPointFile}`);
|
|
65
|
+
}
|
|
66
|
+
// Start the walk
|
|
67
|
+
this.visitFunction(entryPoint, sourceFile);
|
|
68
|
+
return this.collectedKeys;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Finds a function declaration by name in a source file
|
|
72
|
+
*/
|
|
73
|
+
findFunction(sourceFile, functionName) {
|
|
74
|
+
let result;
|
|
75
|
+
const visit = (node) => {
|
|
76
|
+
var _a;
|
|
77
|
+
// Check for function declarations
|
|
78
|
+
if (ts.isFunctionDeclaration(node) && ((_a = node.name) === null || _a === void 0 ? void 0 : _a.text) === functionName) {
|
|
79
|
+
result = node;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Check for variable declarations with arrow functions or function expressions
|
|
83
|
+
if (ts.isVariableStatement(node)) {
|
|
84
|
+
for (const declaration of node.declarationList.declarations) {
|
|
85
|
+
if (declaration.name.getText(sourceFile) === functionName &&
|
|
86
|
+
declaration.initializer &&
|
|
87
|
+
(ts.isArrowFunction(declaration.initializer) ||
|
|
88
|
+
ts.isFunctionExpression(declaration.initializer))) {
|
|
89
|
+
result = declaration.initializer;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
ts.forEachChild(node, visit);
|
|
95
|
+
};
|
|
96
|
+
visit(sourceFile);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Visits a function and collects all service key usages
|
|
101
|
+
*/
|
|
102
|
+
visitFunction(func, sourceFile) {
|
|
103
|
+
const funcId = this.getFunctionId(func, sourceFile);
|
|
104
|
+
if (this.visitedFunctions.has(funcId)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.visitedFunctions.add(funcId);
|
|
108
|
+
if (!func.body) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const visit = (node) => {
|
|
112
|
+
// Look for module.get(Key) or module.getOrNull(Key) calls
|
|
113
|
+
if (ts.isCallExpression(node)) {
|
|
114
|
+
this.checkServiceModuleCall(node, sourceFile);
|
|
115
|
+
this.checkFunctionCall(node, sourceFile);
|
|
116
|
+
}
|
|
117
|
+
ts.forEachChild(node, visit);
|
|
118
|
+
};
|
|
119
|
+
visit(func.body);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Checks if a call expression is module.get() or module.getOrNull()
|
|
123
|
+
*/
|
|
124
|
+
checkServiceModuleCall(callExpr, sourceFile) {
|
|
125
|
+
// Check if it's a property access (e.g., module.get)
|
|
126
|
+
if (!ts.isPropertyAccessExpression(callExpr.expression)) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const propAccess = callExpr.expression;
|
|
130
|
+
const methodName = propAccess.name.text;
|
|
131
|
+
// Check if the method is 'get' or 'getOrNull'
|
|
132
|
+
if (methodName !== 'get' && methodName !== 'getOrNull') {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
// Check if the object is a ServiceModule (we do this by checking the type)
|
|
136
|
+
// For simplicity, we'll check if the variable name contains 'module' or if it's typed as ServiceModule
|
|
137
|
+
const objectText = propAccess.expression.getText(sourceFile);
|
|
138
|
+
// Try to get the type of the expression
|
|
139
|
+
const type = this.checker.getTypeAtLocation(propAccess.expression);
|
|
140
|
+
const typeString = this.checker.typeToString(type);
|
|
141
|
+
// Check if it's a ServiceModule or if the variable name suggests it's a module
|
|
142
|
+
const isServiceModule = typeString.includes('ServiceModule') ||
|
|
143
|
+
objectText.toLowerCase().includes('module');
|
|
144
|
+
if (!isServiceModule) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// Extract the ServiceKey argument
|
|
148
|
+
const keyArg = callExpr.arguments[0];
|
|
149
|
+
if (!keyArg) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const keyName = keyArg.getText(sourceFile);
|
|
153
|
+
// Check if this is a known ServiceKey
|
|
154
|
+
if (this.analysis.serviceKeys.has(keyName)) {
|
|
155
|
+
this.collectedKeys.add(keyName);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Checks if a call expression is a function call and follows it
|
|
160
|
+
*/
|
|
161
|
+
checkFunctionCall(callExpr, sourceFile) {
|
|
162
|
+
try {
|
|
163
|
+
// Get the symbol of the called function
|
|
164
|
+
const symbol = this.checker.getSymbolAtLocation(callExpr.expression);
|
|
165
|
+
if (!symbol) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// Get the declaration of the function
|
|
169
|
+
const declarations = symbol.getDeclarations();
|
|
170
|
+
if (!declarations || declarations.length === 0) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
for (const declaration of declarations) {
|
|
174
|
+
if (ts.isFunctionDeclaration(declaration) ||
|
|
175
|
+
ts.isMethodDeclaration(declaration) ||
|
|
176
|
+
ts.isArrowFunction(declaration) ||
|
|
177
|
+
ts.isFunctionExpression(declaration)) {
|
|
178
|
+
const declSourceFile = declaration.getSourceFile();
|
|
179
|
+
this.visitFunction(declaration, declSourceFile);
|
|
180
|
+
}
|
|
181
|
+
else if (ts.isVariableDeclaration(declaration)) {
|
|
182
|
+
// Handle const myFunc = () => {} pattern
|
|
183
|
+
if (declaration.initializer &&
|
|
184
|
+
(ts.isArrowFunction(declaration.initializer) ||
|
|
185
|
+
ts.isFunctionExpression(declaration.initializer))) {
|
|
186
|
+
const declSourceFile = declaration.getSourceFile();
|
|
187
|
+
this.visitFunction(declaration.initializer, declSourceFile);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
// Ignore errors when resolving symbols (might be external functions)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Gets a unique identifier for a function
|
|
198
|
+
*/
|
|
199
|
+
getFunctionId(func, sourceFile) {
|
|
200
|
+
const pos = func.getStart(sourceFile);
|
|
201
|
+
return `${sourceFile.fileName}:${pos}`;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Gets all collected ServiceKey names
|
|
205
|
+
*/
|
|
206
|
+
getCollectedKeys() {
|
|
207
|
+
return this.collectedKeys;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.CallGraphWalker = CallGraphWalker;
|
|
211
|
+
//# sourceMappingURL=callGraphWalker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callGraphWalker.js","sourceRoot":"","sources":["../../src/compiler/callGraphWalker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AnalysisResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Generates code for a ServiceModule from a list of required factories
|
|
4
|
+
*/
|
|
5
|
+
export declare class CodeGenerator {
|
|
6
|
+
private analysis;
|
|
7
|
+
constructor(analysis: AnalysisResult);
|
|
8
|
+
/**
|
|
9
|
+
* Generates the ServiceModule.from() code
|
|
10
|
+
* @param factoryNames Array of factory variable names in dependency order
|
|
11
|
+
* @param outputFile Path where the generated file will be written (for relative imports)
|
|
12
|
+
* @returns Generated TypeScript code
|
|
13
|
+
*/
|
|
14
|
+
generate(factoryNames: string[], outputFile: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Generates import statements for all required factories
|
|
17
|
+
*/
|
|
18
|
+
private generateImports;
|
|
19
|
+
/**
|
|
20
|
+
* Generates the ServiceModule.from() call
|
|
21
|
+
*/
|
|
22
|
+
private generateModuleCode;
|
|
23
|
+
/**
|
|
24
|
+
* Converts an absolute file path to a relative import path
|
|
25
|
+
*/
|
|
26
|
+
private getRelativeImportPath;
|
|
27
|
+
/**
|
|
28
|
+
* Generates a JSON manifest of the module structure
|
|
29
|
+
*/
|
|
30
|
+
generateManifest(factoryNames: string[]): string;
|
|
31
|
+
/**
|
|
32
|
+
* Generates a diagnostic report
|
|
33
|
+
*/
|
|
34
|
+
generateDiagnostics(factoryNames: string[], warnings: string[]): string;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=codeGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeGenerator.d.ts","sourceRoot":"","sources":["../../src/compiler/codeGenerator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAA2B,MAAM,SAAS,CAAC;AAElE;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAiB;gBAErB,QAAQ,EAAE,cAAc;IAIpC;;;;;OAKG;IACI,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAOnE;;OAEG;IACH,OAAO,CAAC,eAAe;IAoCvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;OAEG;IACI,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM;IAsBvD;;OAEG;IACI,mBAAmB,CACxB,YAAY,EAAE,MAAM,EAAE,EACtB,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM;CAkDV"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CodeGenerator = void 0;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
/**
|
|
39
|
+
* Generates code for a ServiceModule from a list of required factories
|
|
40
|
+
*/
|
|
41
|
+
class CodeGenerator {
|
|
42
|
+
constructor(analysis) {
|
|
43
|
+
this.analysis = analysis;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generates the ServiceModule.from() code
|
|
47
|
+
* @param factoryNames Array of factory variable names in dependency order
|
|
48
|
+
* @param outputFile Path where the generated file will be written (for relative imports)
|
|
49
|
+
* @returns Generated TypeScript code
|
|
50
|
+
*/
|
|
51
|
+
generate(factoryNames, outputFile) {
|
|
52
|
+
const imports = this.generateImports(factoryNames, outputFile);
|
|
53
|
+
const moduleCode = this.generateModuleCode(factoryNames);
|
|
54
|
+
return `${imports}\n${moduleCode}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Generates import statements for all required factories
|
|
58
|
+
*/
|
|
59
|
+
generateImports(factoryNames, outputFile) {
|
|
60
|
+
const imports = [];
|
|
61
|
+
const outputDir = path.dirname(outputFile);
|
|
62
|
+
// Add ServiceModule import
|
|
63
|
+
const lazyDiImport = `import { ServiceModule } from 'lazy-di';`;
|
|
64
|
+
imports.push(lazyDiImport);
|
|
65
|
+
// Group factories by file
|
|
66
|
+
const factoriesByFile = new Map();
|
|
67
|
+
for (const factoryName of factoryNames) {
|
|
68
|
+
const factory = this.analysis.serviceFactories.get(factoryName);
|
|
69
|
+
if (!factory) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const filePath = factory.filePath;
|
|
73
|
+
if (!factoriesByFile.has(filePath)) {
|
|
74
|
+
factoriesByFile.set(filePath, []);
|
|
75
|
+
}
|
|
76
|
+
factoriesByFile.get(filePath).push(factoryName);
|
|
77
|
+
}
|
|
78
|
+
// Generate import statements
|
|
79
|
+
for (const [filePath, factories] of factoriesByFile) {
|
|
80
|
+
const relativePath = this.getRelativeImportPath(outputDir, filePath);
|
|
81
|
+
const importNames = factories.join(', ');
|
|
82
|
+
imports.push(`import { ${importNames} } from '${relativePath}';`);
|
|
83
|
+
}
|
|
84
|
+
return imports.join('\n');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generates the ServiceModule.from() call
|
|
88
|
+
*/
|
|
89
|
+
generateModuleCode(factoryNames) {
|
|
90
|
+
const factoryList = factoryNames.map((name) => ` ${name},`).join('\n');
|
|
91
|
+
return `
|
|
92
|
+
/**
|
|
93
|
+
* Auto-generated ServiceModule
|
|
94
|
+
* DO NOT EDIT - This file is generated by the ServiceModule compiler
|
|
95
|
+
*/
|
|
96
|
+
export const appModule = ServiceModule.from([
|
|
97
|
+
${factoryList}
|
|
98
|
+
]);
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Converts an absolute file path to a relative import path
|
|
103
|
+
*/
|
|
104
|
+
getRelativeImportPath(fromDir, toFile) {
|
|
105
|
+
let relativePath = path.relative(fromDir, toFile);
|
|
106
|
+
// Remove .ts extension
|
|
107
|
+
relativePath = relativePath.replace(/\.ts$/, '');
|
|
108
|
+
// Ensure the path starts with ./ or ../
|
|
109
|
+
if (!relativePath.startsWith('.')) {
|
|
110
|
+
relativePath = './' + relativePath;
|
|
111
|
+
}
|
|
112
|
+
// Normalize path separators for cross-platform compatibility
|
|
113
|
+
relativePath = relativePath.split(path.sep).join('/');
|
|
114
|
+
return relativePath;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Generates a JSON manifest of the module structure
|
|
118
|
+
*/
|
|
119
|
+
generateManifest(factoryNames) {
|
|
120
|
+
const manifest = {
|
|
121
|
+
generatedAt: new Date().toISOString(),
|
|
122
|
+
factories: factoryNames.map((name) => {
|
|
123
|
+
const factory = this.analysis.serviceFactories.get(name);
|
|
124
|
+
if (!factory) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
name: factory.name,
|
|
129
|
+
provides: factory.provides,
|
|
130
|
+
dependsOn: factory.dependsOn,
|
|
131
|
+
type: factory.factoryType,
|
|
132
|
+
file: factory.filePath,
|
|
133
|
+
};
|
|
134
|
+
}).filter(Boolean),
|
|
135
|
+
};
|
|
136
|
+
return JSON.stringify(manifest, null, 2);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Generates a diagnostic report
|
|
140
|
+
*/
|
|
141
|
+
generateDiagnostics(factoryNames, warnings) {
|
|
142
|
+
const lines = [];
|
|
143
|
+
lines.push('=== ServiceModule Compiler Diagnostics ===\n');
|
|
144
|
+
// Summary
|
|
145
|
+
lines.push(`Total factories: ${this.analysis.serviceFactories.size}`);
|
|
146
|
+
lines.push(`Required factories: ${factoryNames.length}`);
|
|
147
|
+
lines.push(`Unused factories: ${this.analysis.serviceFactories.size - factoryNames.length}`);
|
|
148
|
+
lines.push('');
|
|
149
|
+
// Warnings
|
|
150
|
+
if (warnings.length > 0) {
|
|
151
|
+
lines.push('Warnings:');
|
|
152
|
+
for (const warning of warnings) {
|
|
153
|
+
lines.push(` - ${warning}`);
|
|
154
|
+
}
|
|
155
|
+
lines.push('');
|
|
156
|
+
}
|
|
157
|
+
// Unused factories
|
|
158
|
+
const unusedFactories = [];
|
|
159
|
+
for (const [factoryName, factory] of this.analysis.serviceFactories) {
|
|
160
|
+
if (!factoryNames.includes(factoryName)) {
|
|
161
|
+
unusedFactories.push(` - ${factoryName} (provides: ${factory.provides}) in ${factory.filePath}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (unusedFactories.length > 0) {
|
|
165
|
+
lines.push('Unused Factories:');
|
|
166
|
+
lines.push(...unusedFactories);
|
|
167
|
+
lines.push('');
|
|
168
|
+
}
|
|
169
|
+
// Required factories in dependency order
|
|
170
|
+
lines.push('Required Factories (in dependency order):');
|
|
171
|
+
for (const factoryName of factoryNames) {
|
|
172
|
+
const factory = this.analysis.serviceFactories.get(factoryName);
|
|
173
|
+
if (factory) {
|
|
174
|
+
const deps = factory.dependsOn.length > 0 ? ` [depends on: ${factory.dependsOn.join(', ')}]` : '';
|
|
175
|
+
lines.push(` - ${factoryName} (provides: ${factory.provides})${deps}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return lines.join('\n');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.CodeGenerator = CodeGenerator;
|
|
182
|
+
//# sourceMappingURL=codeGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeGenerator.js","sourceRoot":"","sources":["../../src/compiler/codeGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AnalysisResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves transitive dependencies for a set of ServiceKeys
|
|
4
|
+
*/
|
|
5
|
+
export declare class DependencyResolver {
|
|
6
|
+
private analysis;
|
|
7
|
+
constructor(analysis: AnalysisResult);
|
|
8
|
+
/**
|
|
9
|
+
* Computes the transitive closure of dependencies for a set of ServiceKeys
|
|
10
|
+
* @param initialKeys Set of ServiceKey variable names to start from
|
|
11
|
+
* @returns Array of factory names in dependency order (dependencies first)
|
|
12
|
+
*/
|
|
13
|
+
resolve(initialKeys: Set<string>): {
|
|
14
|
+
factories: string[];
|
|
15
|
+
warnings: string[];
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Expands a ServiceKey, adding it and its selector values to the set
|
|
19
|
+
*/
|
|
20
|
+
private expandKey;
|
|
21
|
+
/**
|
|
22
|
+
* Recursively collects all dependencies for a ServiceKey
|
|
23
|
+
*/
|
|
24
|
+
private collectDependencies;
|
|
25
|
+
/**
|
|
26
|
+
* Performs topological sort on factories to ensure dependencies come first
|
|
27
|
+
*/
|
|
28
|
+
private topologicalSort;
|
|
29
|
+
/**
|
|
30
|
+
* Gets analysis result
|
|
31
|
+
*/
|
|
32
|
+
getAnalysis(): AnalysisResult;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=dependencyResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencyResolver.d.ts","sourceRoot":"","sources":["../../src/compiler/dependencyResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA2B,MAAM,SAAS,CAAC;AAElE;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAiB;gBAErB,QAAQ,EAAE,cAAc;IAIpC;;;;OAIG;IACI,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG;QACxC,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IAuCD;;OAEG;IACH,OAAO,CAAC,SAAS;IAgBjB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAuC3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAqDvB;;OAEG;IACI,WAAW,IAAI,cAAc;CAGrC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DependencyResolver = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Resolves transitive dependencies for a set of ServiceKeys
|
|
6
|
+
*/
|
|
7
|
+
class DependencyResolver {
|
|
8
|
+
constructor(analysis) {
|
|
9
|
+
this.analysis = analysis;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Computes the transitive closure of dependencies for a set of ServiceKeys
|
|
13
|
+
* @param initialKeys Set of ServiceKey variable names to start from
|
|
14
|
+
* @returns Array of factory names in dependency order (dependencies first)
|
|
15
|
+
*/
|
|
16
|
+
resolve(initialKeys) {
|
|
17
|
+
const warnings = [];
|
|
18
|
+
const requiredKeys = new Set();
|
|
19
|
+
const visited = new Set();
|
|
20
|
+
// Expand initial keys (handling ServiceSelectorKey)
|
|
21
|
+
const keysToProcess = new Set();
|
|
22
|
+
for (const key of initialKeys) {
|
|
23
|
+
this.expandKey(key, keysToProcess);
|
|
24
|
+
}
|
|
25
|
+
// Collect all required keys transitively
|
|
26
|
+
for (const key of keysToProcess) {
|
|
27
|
+
this.collectDependencies(key, requiredKeys, visited, warnings);
|
|
28
|
+
}
|
|
29
|
+
// Convert keys to factories
|
|
30
|
+
const requiredFactories = new Set();
|
|
31
|
+
for (const key of requiredKeys) {
|
|
32
|
+
const factoryName = this.analysis.keyToFactory.get(key);
|
|
33
|
+
if (factoryName) {
|
|
34
|
+
requiredFactories.add(factoryName);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
warnings.push(`No factory found for ServiceKey: ${key}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Sort factories in dependency order
|
|
41
|
+
const sortedFactories = this.topologicalSort(Array.from(requiredFactories), warnings);
|
|
42
|
+
return {
|
|
43
|
+
factories: sortedFactories,
|
|
44
|
+
warnings,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Expands a ServiceKey, adding it and its selector values to the set
|
|
49
|
+
*/
|
|
50
|
+
expandKey(keyName, result) {
|
|
51
|
+
const key = this.analysis.serviceKeys.get(keyName);
|
|
52
|
+
if (!key) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (key.isSelector && key.selectorValues) {
|
|
56
|
+
// Add all keys in the selector
|
|
57
|
+
for (const value of key.selectorValues) {
|
|
58
|
+
this.expandKey(value, result);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
result.add(keyName);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Recursively collects all dependencies for a ServiceKey
|
|
67
|
+
*/
|
|
68
|
+
collectDependencies(keyName, result, visited, warnings) {
|
|
69
|
+
if (visited.has(keyName)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
visited.add(keyName);
|
|
73
|
+
// Add this key to the result
|
|
74
|
+
result.add(keyName);
|
|
75
|
+
// Find the factory that provides this key
|
|
76
|
+
const factoryName = this.analysis.keyToFactory.get(keyName);
|
|
77
|
+
if (!factoryName) {
|
|
78
|
+
warnings.push(`No factory found for ServiceKey: ${keyName}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const factory = this.analysis.serviceFactories.get(factoryName);
|
|
82
|
+
if (!factory) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Process all dependencies
|
|
86
|
+
for (const depKey of factory.dependsOn) {
|
|
87
|
+
// Expand the dependency key (might be a selector)
|
|
88
|
+
const expandedKeys = new Set();
|
|
89
|
+
this.expandKey(depKey, expandedKeys);
|
|
90
|
+
// Recursively collect dependencies for each expanded key
|
|
91
|
+
for (const expandedKey of expandedKeys) {
|
|
92
|
+
this.collectDependencies(expandedKey, result, visited, warnings);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Performs topological sort on factories to ensure dependencies come first
|
|
98
|
+
*/
|
|
99
|
+
topologicalSort(factoryNames, warnings) {
|
|
100
|
+
const sorted = [];
|
|
101
|
+
const visited = new Set();
|
|
102
|
+
const visiting = new Set();
|
|
103
|
+
const visit = (factoryName) => {
|
|
104
|
+
if (visited.has(factoryName)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (visiting.has(factoryName)) {
|
|
108
|
+
warnings.push(`Circular dependency detected involving: ${factoryName}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
visiting.add(factoryName);
|
|
112
|
+
const factory = this.analysis.serviceFactories.get(factoryName);
|
|
113
|
+
if (!factory) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// Visit all dependencies first
|
|
117
|
+
for (const depKey of factory.dependsOn) {
|
|
118
|
+
// Expand the dependency key
|
|
119
|
+
const expandedKeys = new Set();
|
|
120
|
+
this.expandKey(depKey, expandedKeys);
|
|
121
|
+
// Visit the factory for each expanded key
|
|
122
|
+
for (const expandedKey of expandedKeys) {
|
|
123
|
+
const depFactoryName = this.analysis.keyToFactory.get(expandedKey);
|
|
124
|
+
if (depFactoryName && factoryNames.includes(depFactoryName)) {
|
|
125
|
+
visit(depFactoryName);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
visiting.delete(factoryName);
|
|
130
|
+
visited.add(factoryName);
|
|
131
|
+
sorted.push(factoryName);
|
|
132
|
+
};
|
|
133
|
+
// Visit all factories
|
|
134
|
+
for (const factoryName of factoryNames) {
|
|
135
|
+
visit(factoryName);
|
|
136
|
+
}
|
|
137
|
+
return sorted;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Gets analysis result
|
|
141
|
+
*/
|
|
142
|
+
getAnalysis() {
|
|
143
|
+
return this.analysis;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.DependencyResolver = DependencyResolver;
|
|
147
|
+
//# sourceMappingURL=dependencyResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencyResolver.js","sourceRoot":"","sources":["../../src/compiler/dependencyResolver.ts"],"names":[],"mappings":"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"}
|