@flopod/compiler 0.1.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.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +78 -0
- package/dist/cli.js.map +1 -0
- package/dist/diagnose.d.ts +27 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +253 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/transpile.d.ts +109 -0
- package/dist/transpile.d.ts.map +1 -0
- package/dist/transpile.js +631 -0
- package/dist/transpile.js.map +1 -0
- package/package.json +32 -0
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
3
|
+
import { join, dirname, resolve } from 'path';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { transpileSource } from './transpile.js';
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const [cmd, ...rest] = process.argv.slice(2);
|
|
9
|
+
if (cmd === 'dev') {
|
|
10
|
+
// flopod dev <entry.ts> [--port 3847]
|
|
11
|
+
const portIdx = rest.indexOf('--port');
|
|
12
|
+
const port = portIdx !== -1 ? parseInt(rest[portIdx + 1], 10) : 3847;
|
|
13
|
+
const skipIdx = new Set(portIdx !== -1 ? [portIdx, portIdx + 1] : []);
|
|
14
|
+
const inputFile = rest.find((a, i) => !a.startsWith('--') && !skipIdx.has(i));
|
|
15
|
+
if (!inputFile) {
|
|
16
|
+
console.error('Usage: flopod dev <entry.ts> [--port <port>]');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
// Resolve runtime package paths from the transpiler's own location
|
|
20
|
+
const runtimeDist = resolve(__dirname, '../../flopod-runtime/dist');
|
|
21
|
+
const runtimeUrl = pathToFileURL(join(runtimeDist, 'index.js')).href;
|
|
22
|
+
const devUrl = pathToFileURL(join(runtimeDist, 'dev/index.js')).href;
|
|
23
|
+
const source = readFileSync(inputFile, 'utf8');
|
|
24
|
+
const result = transpileSource(source, inputFile, { runtimeUrl, devUrl, port });
|
|
25
|
+
const outDir = join(process.cwd(), '.flopod-dev');
|
|
26
|
+
const outFile = join(outDir, 'main.ts');
|
|
27
|
+
mkdirSync(outDir, { recursive: true });
|
|
28
|
+
writeFileSync(outFile, result.code, 'utf8');
|
|
29
|
+
// Find tsx in node_modules up the tree
|
|
30
|
+
const tsxBin = findTsx();
|
|
31
|
+
if (!tsxBin) {
|
|
32
|
+
console.error('[flopod dev] error: tsx not found — run: npm install -D tsx');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
console.log(`[flopod dev] transpiled ${inputFile}`);
|
|
36
|
+
const proc = spawn(process.execPath, [tsxBin, outFile], {
|
|
37
|
+
stdio: 'inherit',
|
|
38
|
+
cwd: process.cwd(),
|
|
39
|
+
});
|
|
40
|
+
proc.on('exit', code => process.exit(code ?? 0));
|
|
41
|
+
}
|
|
42
|
+
else if (cmd === undefined || cmd === '--help' || cmd === 'help') {
|
|
43
|
+
console.log('Usage:');
|
|
44
|
+
console.log(' flopod dev <entry.ts> Run workflow with live dev UI');
|
|
45
|
+
console.log(' flopod-transpile <in> <out> Transpile only');
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Legacy: flopod-transpile <input> <output>
|
|
49
|
+
const [inputFile, outputFile] = [cmd, ...rest];
|
|
50
|
+
if (!inputFile || !outputFile) {
|
|
51
|
+
console.error('Usage: flopod-transpile <input.ts> <output.ts>');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const source = readFileSync(inputFile, 'utf8');
|
|
55
|
+
const result = transpileSource(source, inputFile);
|
|
56
|
+
mkdirSync(dirname(outputFile), { recursive: true });
|
|
57
|
+
writeFileSync(outputFile, result.code, 'utf8');
|
|
58
|
+
console.log(`Transpiled ${inputFile} → ${outputFile}`);
|
|
59
|
+
console.log(`Activities: ${result.activities.join(', ')}`);
|
|
60
|
+
}
|
|
61
|
+
function findTsx() {
|
|
62
|
+
// Walk up from cwd looking for node_modules/.bin/tsx or node_modules/tsx/dist/cli.mjs
|
|
63
|
+
let dir = process.cwd();
|
|
64
|
+
for (let i = 0; i < 6; i++) {
|
|
65
|
+
const candidate = join(dir, 'node_modules', 'tsx', 'dist', 'cli.mjs');
|
|
66
|
+
try {
|
|
67
|
+
readFileSync(candidate);
|
|
68
|
+
return candidate;
|
|
69
|
+
}
|
|
70
|
+
catch { /* */ }
|
|
71
|
+
const parent = dirname(dir);
|
|
72
|
+
if (parent === dir)
|
|
73
|
+
break;
|
|
74
|
+
dir = parent;
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
export interface Diagnostic {
|
|
3
|
+
message: string;
|
|
4
|
+
line: number;
|
|
5
|
+
column: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class TranspileError extends Error {
|
|
8
|
+
readonly diagnostics: Diagnostic[];
|
|
9
|
+
constructor(diagnostics: Diagnostic[], fileName: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Diagnose all workflow functions in the file.
|
|
13
|
+
*
|
|
14
|
+
* Convention: every non-default top-level function is an activity.
|
|
15
|
+
* The default export is the workflow root.
|
|
16
|
+
*
|
|
17
|
+
* Rules for activities:
|
|
18
|
+
* - Cannot call other activities
|
|
19
|
+
* - Cannot use wf.*
|
|
20
|
+
*
|
|
21
|
+
* Rules for the workflow root:
|
|
22
|
+
* - No try/catch — move into an activity
|
|
23
|
+
* - No setTimeout/setInterval — move into an activity
|
|
24
|
+
* - No await on non-top-level functions — must be top-level to be recorded in the event log
|
|
25
|
+
*/
|
|
26
|
+
export declare function diagnoseWorkflowFile(sourceFile: ts.SourceFile, activities: Set<string>): Diagnostic[];
|
|
27
|
+
//# sourceMappingURL=diagnose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,qBAAa,cAAe,SAAQ,KAAK;aAErB,WAAW,EAAE,UAAU,EAAE;gBAAzB,WAAW,EAAE,UAAU,EAAE,EACzC,QAAQ,EAAE,MAAM;CAQnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACtB,UAAU,EAAE,CA2Pd"}
|
package/dist/diagnose.js
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
export class TranspileError extends Error {
|
|
3
|
+
diagnostics;
|
|
4
|
+
constructor(diagnostics, fileName) {
|
|
5
|
+
const lines = diagnostics
|
|
6
|
+
.map(d => ` ${fileName}:${d.line}:${d.column} ${d.message}`)
|
|
7
|
+
.join('\n');
|
|
8
|
+
super(`Workflow has ${diagnostics.length} error(s):\n\n${lines}\n`);
|
|
9
|
+
this.diagnostics = diagnostics;
|
|
10
|
+
this.name = 'TranspileError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Diagnose all workflow functions in the file.
|
|
15
|
+
*
|
|
16
|
+
* Convention: every non-default top-level function is an activity.
|
|
17
|
+
* The default export is the workflow root.
|
|
18
|
+
*
|
|
19
|
+
* Rules for activities:
|
|
20
|
+
* - Cannot call other activities
|
|
21
|
+
* - Cannot use wf.*
|
|
22
|
+
*
|
|
23
|
+
* Rules for the workflow root:
|
|
24
|
+
* - No try/catch — move into an activity
|
|
25
|
+
* - No setTimeout/setInterval — move into an activity
|
|
26
|
+
* - No await on non-top-level functions — must be top-level to be recorded in the event log
|
|
27
|
+
*/
|
|
28
|
+
export function diagnoseWorkflowFile(sourceFile, activities) {
|
|
29
|
+
const diagnostics = [];
|
|
30
|
+
for (const node of sourceFile.statements) {
|
|
31
|
+
if (!ts.isFunctionDeclaration(node) || !node.body)
|
|
32
|
+
continue;
|
|
33
|
+
const isDefault = !!node.modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword);
|
|
34
|
+
if (!isDefault) {
|
|
35
|
+
// Leaves: check for cross-activity calls and wf.* access
|
|
36
|
+
ts.forEachChild(node.body, function walkLeaf(child) {
|
|
37
|
+
if (ts.isCallExpression(child)) {
|
|
38
|
+
const callee = child.expression;
|
|
39
|
+
if (ts.isIdentifier(callee) && activities.has(callee.text)) {
|
|
40
|
+
report(child, `${callee.text}() is an activity — activities cannot call other activities. ` +
|
|
41
|
+
`Move this call to the workflow body.`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (ts.isPropertyAccessExpression(child)) {
|
|
45
|
+
const obj = child.expression;
|
|
46
|
+
if (ts.isIdentifier(obj) && obj.text === 'wf') {
|
|
47
|
+
report(child, `wf.${child.name.text}() is not allowed inside an activity — activities are leaves with no access to workflow primitives. ` +
|
|
48
|
+
`Move this call to the workflow body.`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
ts.forEachChild(child, walkLeaf);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Branch: full workflow rules
|
|
56
|
+
walkBlock(node.body);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return diagnostics;
|
|
60
|
+
function report(node, message) {
|
|
61
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
62
|
+
diagnostics.push({ message, line: line + 1, column: character + 1 });
|
|
63
|
+
}
|
|
64
|
+
function walkBlock(block, nested = false) {
|
|
65
|
+
for (const stmt of block.statements) {
|
|
66
|
+
walkStatement(stmt, nested);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function walkStatement(stmt, nested = false) {
|
|
70
|
+
if (ts.isTryStatement(stmt)) {
|
|
71
|
+
report(stmt, 'try/catch is not allowed in the workflow root — move the try/catch into an activity function');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// C-style for and for-in are not auto-convertible — keep as errors
|
|
75
|
+
if (ts.isForStatement(stmt) || ts.isForInStatement(stmt)) {
|
|
76
|
+
report(stmt, 'C-style for and for-in loops are not supported in the workflow root — use for...of instead');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// for-of, if/else, while — transpiler converts these; recurse to check bodies for real violations
|
|
80
|
+
if (ts.isForOfStatement(stmt)) {
|
|
81
|
+
const body = stmt.statement;
|
|
82
|
+
if (ts.isBlock(body))
|
|
83
|
+
walkBlock(body, true);
|
|
84
|
+
else
|
|
85
|
+
walkStatement(body, true);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (ts.isIfStatement(stmt)) {
|
|
89
|
+
walkIfBranches(stmt);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (ts.isWhileStatement(stmt) || ts.isDoStatement(stmt)) {
|
|
93
|
+
const body = stmt.statement;
|
|
94
|
+
if (ts.isBlock(body))
|
|
95
|
+
walkBlock(body, true);
|
|
96
|
+
else
|
|
97
|
+
walkStatement(body, true);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (ts.isBlock(stmt)) {
|
|
101
|
+
walkBlock(stmt, nested);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Direct (non-awaited) leaf call as a bare statement — result won't be recorded, skipped on replay
|
|
105
|
+
if (ts.isExpressionStatement(stmt) && ts.isCallExpression(stmt.expression)) {
|
|
106
|
+
const callee = stmt.expression.expression;
|
|
107
|
+
if (ts.isIdentifier(callee) && activities.has(callee.text)) {
|
|
108
|
+
report(stmt.expression, `${callee.text}() is an activity — call it with: await wf.activity('${callee.text}', () => ${callee.text}(...))`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
ts.forEachChild(stmt, function walk(node) {
|
|
113
|
+
// wf.* callback arrows are safe — the runtime wraps them
|
|
114
|
+
if (ts.isArrowFunction(node) && isInsideWfCall(node))
|
|
115
|
+
return;
|
|
116
|
+
// Non-wf arrow functions or function expressions may contain illegal activity calls
|
|
117
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
|
|
118
|
+
walkInsideNonWfFn(node);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
checkNode(node);
|
|
122
|
+
ts.forEachChild(node, walk);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function walkIfBranches(stmt) {
|
|
126
|
+
const then = stmt.thenStatement;
|
|
127
|
+
if (ts.isBlock(then))
|
|
128
|
+
walkBlock(then, true);
|
|
129
|
+
else
|
|
130
|
+
walkStatement(then, true);
|
|
131
|
+
if (stmt.elseStatement) {
|
|
132
|
+
if (ts.isIfStatement(stmt.elseStatement))
|
|
133
|
+
walkIfBranches(stmt.elseStatement);
|
|
134
|
+
else if (ts.isBlock(stmt.elseStatement))
|
|
135
|
+
walkBlock(stmt.elseStatement, true);
|
|
136
|
+
else
|
|
137
|
+
walkStatement(stmt.elseStatement, true);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function isInsideWfCall(arrow) {
|
|
141
|
+
const parent = arrow.parent;
|
|
142
|
+
if (!parent || !ts.isCallExpression(parent))
|
|
143
|
+
return false;
|
|
144
|
+
const callee = parent.expression;
|
|
145
|
+
return ts.isPropertyAccessExpression(callee) &&
|
|
146
|
+
ts.isIdentifier(callee.expression) &&
|
|
147
|
+
callee.expression.text === 'wf';
|
|
148
|
+
}
|
|
149
|
+
// Walk inside a non-wf arrow/function-expression and flag any activity calls found there.
|
|
150
|
+
// Activity calls in this context are not durable — the transpiler cannot checkpoint them.
|
|
151
|
+
function walkInsideNonWfFn(fnNode) {
|
|
152
|
+
ts.forEachChild(fnNode, function walk(node) {
|
|
153
|
+
if ((ts.isArrowFunction(node) || ts.isFunctionExpression(node)) && isInsideWfCall(node))
|
|
154
|
+
return;
|
|
155
|
+
if (ts.isAwaitExpression(node)) {
|
|
156
|
+
const inner = node.expression;
|
|
157
|
+
if (ts.isCallExpression(inner) && ts.isIdentifier(inner.expression) && activities.has(inner.expression.text)) {
|
|
158
|
+
report(node, `${inner.expression.text}() is an activity — activity calls inside inline functions are not durable. ` +
|
|
159
|
+
`Move this call to the workflow body directly.`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
ts.forEachChild(node, walk);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function checkNode(node) {
|
|
167
|
+
if (ts.isCallExpression(node)) {
|
|
168
|
+
const expr = node.expression;
|
|
169
|
+
// Activity call used as an argument — nested activities produce invisible intermediate values
|
|
170
|
+
// Exception: parallel(act1(), act2()) is the intended pattern; the transpiler handles it
|
|
171
|
+
const isParallelCall = ts.isIdentifier(expr) && expr.text === 'parallel';
|
|
172
|
+
if (!isParallelCall) {
|
|
173
|
+
for (const arg of node.arguments) {
|
|
174
|
+
const inner = ts.isAwaitExpression(arg) ? arg.expression : arg;
|
|
175
|
+
if (ts.isCallExpression(inner)) {
|
|
176
|
+
const callee = inner.expression;
|
|
177
|
+
if (ts.isIdentifier(callee) && activities.has(callee.text)) {
|
|
178
|
+
report(arg, `${callee.text}() is an activity — nested activity calls are not allowed. ` +
|
|
179
|
+
`Assign to a variable first: const x = await ${callee.text}(...)`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Promise.all([activityFn(), ...]) — activities inside Promise.all are not recorded in the event log
|
|
185
|
+
if (ts.isPropertyAccessExpression(expr) &&
|
|
186
|
+
ts.isIdentifier(expr.expression) &&
|
|
187
|
+
expr.expression.text === 'Promise' &&
|
|
188
|
+
expr.name.text === 'all') {
|
|
189
|
+
const arg = node.arguments[0];
|
|
190
|
+
if (arg && ts.isArrayLiteralExpression(arg)) {
|
|
191
|
+
for (const element of arg.elements) {
|
|
192
|
+
const call = ts.isAwaitExpression(element) ? element.expression : element;
|
|
193
|
+
if (ts.isCallExpression(call)) {
|
|
194
|
+
const callee = call.expression;
|
|
195
|
+
if (ts.isIdentifier(callee) && activities.has(callee.text)) {
|
|
196
|
+
report(element, `${callee.text}() is an activity — Promise.all() does not record activities in the event log. ` +
|
|
197
|
+
`Use parallel() for concurrent activity calls: const [a, b] = await parallel(${callee.text}(...), otherActivity(...))`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Direct identifier calls
|
|
204
|
+
if (ts.isIdentifier(expr)) {
|
|
205
|
+
if (expr.text === 'setTimeout') {
|
|
206
|
+
report(node, 'setTimeout() is not allowed in the workflow root — move it into an activity function');
|
|
207
|
+
}
|
|
208
|
+
if (expr.text === 'setInterval') {
|
|
209
|
+
report(node, 'setInterval() is not allowed in the workflow root — move it into an activity function');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// console.* calls — side effect that re-runs on every replay
|
|
213
|
+
if (ts.isPropertyAccessExpression(expr) && ts.isIdentifier(expr.expression)) {
|
|
214
|
+
const obj = expr.expression.text;
|
|
215
|
+
const method = expr.name.text;
|
|
216
|
+
if (obj === 'console') {
|
|
217
|
+
report(node, `console.${method}() is a side effect — wrap it in a leaf function: async function log(...) { console.${method}(...) }`);
|
|
218
|
+
}
|
|
219
|
+
// fetch() as property access (e.g. globalThis.fetch)
|
|
220
|
+
if (obj === 'globalThis' && method === 'fetch') {
|
|
221
|
+
report(node, `fetch() is a side effect — move it into a leaf function`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// Top-level fetch() call
|
|
225
|
+
if (ts.isIdentifier(expr) && expr.text === 'fetch') {
|
|
226
|
+
report(node, `fetch() is a side effect — move it into a leaf function`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Math.random() — non-deterministic, breaks replay
|
|
230
|
+
if (ts.isCallExpression(node) &&
|
|
231
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
232
|
+
ts.isIdentifier(node.expression.expression) &&
|
|
233
|
+
node.expression.expression.text === 'Math' &&
|
|
234
|
+
node.expression.name.text === 'random') {
|
|
235
|
+
report(node, 'Math.random() is non-deterministic — move it into a leaf function');
|
|
236
|
+
}
|
|
237
|
+
if (ts.isAwaitExpression(node)) {
|
|
238
|
+
const inner = node.expression;
|
|
239
|
+
if (ts.isCallExpression(inner)) {
|
|
240
|
+
const callee = inner.expression;
|
|
241
|
+
// await on a non-top-level function — not durable
|
|
242
|
+
if (ts.isIdentifier(callee) && !activities.has(callee.text)) {
|
|
243
|
+
// Allow the compiler-recognized durable builtins: parallel() (fan-out), sleep()
|
|
244
|
+
// (timer), and waitForSignal() (block for an external event).
|
|
245
|
+
if (callee.text === 'parallel' || callee.text === 'sleep' || callee.text === 'waitForSignal')
|
|
246
|
+
return;
|
|
247
|
+
report(node, `await ${callee.text}() — ${callee.text} must be a top-level function to be used in the workflow root`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=diagnose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { transpileSource, transpileViaIR, assembleFromBody, compileToResult, createIRTransformer, getWorkflowMeta } from './transpile.js';
|
|
2
|
+
export type { TranspileResult, CompileResult, Rejection, DevModeOptions, WorkflowMeta } from './transpile.js';
|
|
3
|
+
export { TranspileError } from './diagnose.js';
|
|
4
|
+
export type { Diagnostic } from './diagnose.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC1I,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9G,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE1I,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import type { LowerErrorCode } from '@flopod/ir';
|
|
3
|
+
export interface TranspileResult {
|
|
4
|
+
code: string;
|
|
5
|
+
activities: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A compile rejection as DATA (never thrown). Unifies the two error sources:
|
|
9
|
+
* - `diagnoseWorkflowFile`'s `Diagnostic` (leaf/branch pre-check — message + loc only), and
|
|
10
|
+
* - the IR's `LowerError` (rich: `code` / `found` / `fix`).
|
|
11
|
+
*
|
|
12
|
+
* Preserving `code`/`found`/`fix` structurally (rather than the flattened string that
|
|
13
|
+
* `TranspileError` carries) is the whole point: it is the agent's tightest feedback loop.
|
|
14
|
+
*/
|
|
15
|
+
export interface Rejection {
|
|
16
|
+
code?: LowerErrorCode;
|
|
17
|
+
message: string;
|
|
18
|
+
loc?: {
|
|
19
|
+
line: number;
|
|
20
|
+
column: number;
|
|
21
|
+
};
|
|
22
|
+
found?: string;
|
|
23
|
+
fix?: string;
|
|
24
|
+
}
|
|
25
|
+
export type CompileResult = {
|
|
26
|
+
ok: true;
|
|
27
|
+
code: string;
|
|
28
|
+
activities: string[];
|
|
29
|
+
} | {
|
|
30
|
+
ok: false;
|
|
31
|
+
rejections: Rejection[];
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The compile path that **returns data and never throws** — the core function behind
|
|
35
|
+
* `flopod compile` (CLI, for the agent) and the dev server's compile route (HTTP, for the
|
|
36
|
+
* UI). Mirrors `transpileViaIR`'s pipeline (`diagnose → lower → emit → assemble`) but
|
|
37
|
+
* surfaces failures as structured `Rejection[]` with `code`/`found`/`fix` intact, instead
|
|
38
|
+
* of throwing a `TranspileError` that stringifies them.
|
|
39
|
+
*/
|
|
40
|
+
export declare function compileToResult(source: string, fileName?: string): CompileResult;
|
|
41
|
+
export interface DevModeOptions {
|
|
42
|
+
runtimeUrl: string;
|
|
43
|
+
devUrl: string;
|
|
44
|
+
port?: number;
|
|
45
|
+
/** True when the operator passed --port explicitly; an occupied port then fails loud instead of roaming. */
|
|
46
|
+
explicitPort?: boolean;
|
|
47
|
+
activityDelayMs?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Production control-plane (`flopod serve`) instead of the local dev tool:
|
|
50
|
+
* headless (no browser), no artificial activity delays, and it does NOT
|
|
51
|
+
* auto-run a default run — it boots the persistent control plane and waits for
|
|
52
|
+
* runs triggered over HTTP. Same durable FileBackend + run-list hydration.
|
|
53
|
+
*/
|
|
54
|
+
serve?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The default compile path. Routes the supported language through the IR
|
|
58
|
+
* (`transpileViaIR` — `diagnose → lower → emit`), making the IR the execution center.
|
|
59
|
+
*
|
|
60
|
+
* The IR enforces the strict branch-expression algebra (Expr = result-capture only,
|
|
61
|
+
* §5): ternaries, `??`, method chains and spread in the branch are rejected — they belong
|
|
62
|
+
* in leaves (optional chaining `?.` is admitted as a null-safe member read). This is
|
|
63
|
+
* *stricter* than the legacy transpiler (§19#6, decided: adopt strict).
|
|
64
|
+
*
|
|
65
|
+
* Dev mode ([5] Part 2b) also routes through the IR: the runtime runs the IR-emitted
|
|
66
|
+
* durable calls (derived ids) and the static graph is built from `toGraph(IR)` — the same
|
|
67
|
+
* derived ids on both sides, so live status overlays the static nodes by path. Deferred
|
|
68
|
+
* constructs (durable `let`, `while` — §19#2) surface as a `TranspileError`; there is no
|
|
69
|
+
* legacy fallback (§21/§23: legacy deleted, the IR is the only path).
|
|
70
|
+
*/
|
|
71
|
+
export declare function transpileSource(source: string, fileName?: string, devMode?: DevModeOptions): TranspileResult;
|
|
72
|
+
/**
|
|
73
|
+
* The IR-routed compile path: `diagnose → lower → emit → assemble`. Produces the same
|
|
74
|
+
* module as `transpileSource`, but the branch is lowered to the IR and emitted from it
|
|
75
|
+
* (the §13 [4] convergence). `diagnose` runs first as the friendly multi-error pre-check
|
|
76
|
+
* (leaf rules + branch hints it owns); `lower`'s structured `LowerError` is mapped into
|
|
77
|
+
* the same `TranspileError` surface so consumers see ONE error type (§19#3 decision).
|
|
78
|
+
*/
|
|
79
|
+
export declare function transpileViaIR(source: string, fileName?: string): TranspileResult;
|
|
80
|
+
/**
|
|
81
|
+
* Assemble a full module using a pre-emitted branch body (e.g. from `@flopod/ir`'s
|
|
82
|
+
* `emit`) instead of the AST-rewrite path. Reuses every other part of the module
|
|
83
|
+
* frame (imports, leaf passthrough, runtime setup, input handling, invocation) so
|
|
84
|
+
* the IR path differs from `transpileSource` only in how `main`'s body is produced.
|
|
85
|
+
* This is the seam for routing the transpiler through the IR (docs/flopod-ir.md [4]).
|
|
86
|
+
*/
|
|
87
|
+
export declare function assembleFromBody(mainBody: string, source: string, fileName?: string): TranspileResult;
|
|
88
|
+
export interface WorkflowMeta {
|
|
89
|
+
defaultFnName: string | null;
|
|
90
|
+
hasParams: boolean;
|
|
91
|
+
}
|
|
92
|
+
export declare function getWorkflowMeta(source: string, fileName?: string): WorkflowMeta;
|
|
93
|
+
/**
|
|
94
|
+
* Build-path transformer driven by the IR (§23 stage 3). Like `createFlopodTransformer`
|
|
95
|
+
* it returns a `ts.TransformerFactory` that `ts.transpileModule` runs to produce JS +
|
|
96
|
+
* source maps — but the default export's body is no longer rewritten by AST surgery.
|
|
97
|
+
* Instead the branch is lowered to the IR, emitted as durable `wf.*` calls (`emitBranch`),
|
|
98
|
+
* and the emitted statements are spliced in as **synthetic** nodes (positions cleared so
|
|
99
|
+
* the printer emits them structurally, not by slicing the original text). Each top-level
|
|
100
|
+
* emitted statement is given a `setSourceMapRange` back to its original statement position
|
|
101
|
+
* (from `lowerWithProvenance`), and `NoNestedSourceMaps` so its sub-nodes (which carry
|
|
102
|
+
* temp-parse positions) do not emit bogus mappings. TS then generates an accurate
|
|
103
|
+
* JS→original map in one pass — no map composition needed.
|
|
104
|
+
*
|
|
105
|
+
* A `LowerError` (deferred `let`/`while`, §19#2) surfaces as a `TranspileError`, the same
|
|
106
|
+
* single error contract the rest of the compiler uses.
|
|
107
|
+
*/
|
|
108
|
+
export declare function createIRTransformer(): ts.TransformerFactory<ts.SourceFile>;
|
|
109
|
+
//# sourceMappingURL=transpile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transpile.d.ts","sourceRoot":"","sources":["../src/transpile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,YAAY,CAAC;AAW/D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAChD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAgB,GAAG,aAAa,CA8BvF;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4GAA4G;IAC5G,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,SAAgB,EACxB,OAAO,CAAC,EAAE,cAAc,GACvB,eAAe,CAIjB;AAgFD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAgB,GAAG,eAAe,CAoBxF;AAaD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,SAAgB,GACvB,eAAe,CASjB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAgB,GAAG,YAAY,CAMtF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,IAAI,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,CAAC,CA0E1E"}
|
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { lowerSource, lowerWithProvenance, emitBranch, toGraph, toBoxTree, LowerError } from '@flopod/ir';
|
|
4
|
+
import { diagnoseWorkflowFile, TranspileError } from './diagnose.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fingerprint of the workflow source. Stamped into the event log so a run can
|
|
7
|
+
* only be resumed by the same code that produced it (see WorkflowCodeChangedError).
|
|
8
|
+
*/
|
|
9
|
+
function codeVersionOf(source) {
|
|
10
|
+
return createHash('sha256').update(source).digest('hex').slice(0, 16);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The compile path that **returns data and never throws** — the core function behind
|
|
14
|
+
* `flopod compile` (CLI, for the agent) and the dev server's compile route (HTTP, for the
|
|
15
|
+
* UI). Mirrors `transpileViaIR`'s pipeline (`diagnose → lower → emit → assemble`) but
|
|
16
|
+
* surfaces failures as structured `Rejection[]` with `code`/`found`/`fix` intact, instead
|
|
17
|
+
* of throwing a `TranspileError` that stringifies them.
|
|
18
|
+
*/
|
|
19
|
+
export function compileToResult(source, fileName = 'workflow.ts') {
|
|
20
|
+
const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.ES2022, true);
|
|
21
|
+
const activities = collectActivities(sourceFile);
|
|
22
|
+
// 1. friendly pre-check (leaf validation + branch hints) — message + loc, no code/fix
|
|
23
|
+
const diagnostics = diagnoseWorkflowFile(sourceFile, activities);
|
|
24
|
+
if (diagnostics.length > 0) {
|
|
25
|
+
return {
|
|
26
|
+
ok: false,
|
|
27
|
+
rejections: diagnostics.map(d => ({ message: d.message, loc: { line: d.line, column: d.column } })),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// 2. lower + emit — a LowerError here keeps its structured fields
|
|
31
|
+
let body;
|
|
32
|
+
try {
|
|
33
|
+
body = emitBranch(lowerSource(source, fileName));
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
if (e instanceof LowerError) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
rejections: [{ code: e.code, message: e.message, loc: e.loc, found: e.found, fix: e.fix }],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
throw e; // not a compile rejection — a real bug; let it surface
|
|
43
|
+
}
|
|
44
|
+
// 3. assemble the full module around the IR-emitted body
|
|
45
|
+
const code = emit(source, sourceFile, activities, undefined, body);
|
|
46
|
+
return { ok: true, code, activities: [...activities] };
|
|
47
|
+
}
|
|
48
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
49
|
+
/**
|
|
50
|
+
* The default compile path. Routes the supported language through the IR
|
|
51
|
+
* (`transpileViaIR` — `diagnose → lower → emit`), making the IR the execution center.
|
|
52
|
+
*
|
|
53
|
+
* The IR enforces the strict branch-expression algebra (Expr = result-capture only,
|
|
54
|
+
* §5): ternaries, `??`, method chains and spread in the branch are rejected — they belong
|
|
55
|
+
* in leaves (optional chaining `?.` is admitted as a null-safe member read). This is
|
|
56
|
+
* *stricter* than the legacy transpiler (§19#6, decided: adopt strict).
|
|
57
|
+
*
|
|
58
|
+
* Dev mode ([5] Part 2b) also routes through the IR: the runtime runs the IR-emitted
|
|
59
|
+
* durable calls (derived ids) and the static graph is built from `toGraph(IR)` — the same
|
|
60
|
+
* derived ids on both sides, so live status overlays the static nodes by path. Deferred
|
|
61
|
+
* constructs (durable `let`, `while` — §19#2) surface as a `TranspileError`; there is no
|
|
62
|
+
* legacy fallback (§21/§23: legacy deleted, the IR is the only path).
|
|
63
|
+
*/
|
|
64
|
+
export function transpileSource(source, fileName = 'workflow.ts', devMode) {
|
|
65
|
+
return devMode
|
|
66
|
+
? transpileDevViaIR(source, fileName, devMode)
|
|
67
|
+
: transpileViaIR(source, fileName);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Dev compile path routed through the IR ([5] Part 2b). Lowers the branch, emits the
|
|
71
|
+
* durable body from the IR (derived ids), and builds the static graph from `toGraph(IR)`
|
|
72
|
+
* — no dry run. A `LowerError` (durable `let`/`while` — §19#2/§21) is mapped to the single
|
|
73
|
+
* `TranspileError` surface so it reaches the operator as a clean "unsupported" message; the
|
|
74
|
+
* legacy fallback is gone (the IR is the only path — §21 decision).
|
|
75
|
+
*/
|
|
76
|
+
function transpileDevViaIR(source, fileName, devMode) {
|
|
77
|
+
const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.ES2022, true);
|
|
78
|
+
const activities = collectActivities(sourceFile);
|
|
79
|
+
const diagnostics = diagnoseWorkflowFile(sourceFile, activities);
|
|
80
|
+
if (diagnostics.length > 0)
|
|
81
|
+
throw new TranspileError(diagnostics, fileName);
|
|
82
|
+
let body;
|
|
83
|
+
let staticNodes;
|
|
84
|
+
let boxTree;
|
|
85
|
+
try {
|
|
86
|
+
const ir = lowerSource(source, fileName);
|
|
87
|
+
body = emitBranch(ir);
|
|
88
|
+
staticNodes = buildStaticNodes(ir, sourceFile, source);
|
|
89
|
+
boxTree = buildBoxTree(ir, sourceFile);
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
if (e instanceof LowerError)
|
|
93
|
+
throw new TranspileError([lowerErrorToDiagnostic(e)], fileName);
|
|
94
|
+
throw e;
|
|
95
|
+
}
|
|
96
|
+
const code = emit(source, sourceFile, activities, devMode, body, staticNodes, boxTree);
|
|
97
|
+
return { code, activities: [...activities] };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Build the dev control-plane's static graph nodes from the IR (the [5] reconciliation:
|
|
101
|
+
* `toGraph` node paths are the runtime template paths, so live events overlay them). JSDoc
|
|
102
|
+
* activity titles/descriptions are merged in by label. Control-flow JSDoc metadata (titles
|
|
103
|
+
* on branch/loop nodes) is not merged — `toGraph` supplies control-node labels directly.
|
|
104
|
+
*/
|
|
105
|
+
function buildStaticNodes(ir, sourceFile, source) {
|
|
106
|
+
const activityMeta = extractActivityMeta(sourceFile);
|
|
107
|
+
return toGraph(ir).nodes.map(n => ({
|
|
108
|
+
path: n.path,
|
|
109
|
+
kind: n.kind,
|
|
110
|
+
label: n.label,
|
|
111
|
+
...(n.varName ? { varName: n.varName } : {}),
|
|
112
|
+
...(activityMeta.get(n.label) ?? {}),
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Build the dev control-plane's NESTED box tree from the IR (the new designer's structure
|
|
117
|
+
* source — `toBoxTree`). Same template-path ids as `buildStaticNodes`, so live status
|
|
118
|
+
* overlays by path. Activity boxes are decorated with the leaf's JSDoc summary (`title`)
|
|
119
|
+
* and `@description` prose (`doc`) — the "what it's doing" a hover surfaces — which the
|
|
120
|
+
* pure IR arrow can't know (JSDoc lives in the source, not the IR).
|
|
121
|
+
*/
|
|
122
|
+
function buildBoxTree(ir, sourceFile) {
|
|
123
|
+
const activityMeta = extractActivityMeta(sourceFile);
|
|
124
|
+
const decorate = (box) => {
|
|
125
|
+
if (box.kind === 'activity') {
|
|
126
|
+
const m = activityMeta.get(box.label);
|
|
127
|
+
if (m?.title)
|
|
128
|
+
box.title = m.title;
|
|
129
|
+
if (m?.description)
|
|
130
|
+
box.doc = m.description;
|
|
131
|
+
}
|
|
132
|
+
box.children.forEach(decorate);
|
|
133
|
+
};
|
|
134
|
+
const tree = toBoxTree(ir);
|
|
135
|
+
tree.body.forEach(decorate);
|
|
136
|
+
return tree;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The IR-routed compile path: `diagnose → lower → emit → assemble`. Produces the same
|
|
140
|
+
* module as `transpileSource`, but the branch is lowered to the IR and emitted from it
|
|
141
|
+
* (the §13 [4] convergence). `diagnose` runs first as the friendly multi-error pre-check
|
|
142
|
+
* (leaf rules + branch hints it owns); `lower`'s structured `LowerError` is mapped into
|
|
143
|
+
* the same `TranspileError` surface so consumers see ONE error type (§19#3 decision).
|
|
144
|
+
*/
|
|
145
|
+
export function transpileViaIR(source, fileName = 'workflow.ts') {
|
|
146
|
+
const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.ES2022, true);
|
|
147
|
+
const activities = collectActivities(sourceFile);
|
|
148
|
+
// 1. friendly pre-check (leaf validation + branch hints, all errors at once)
|
|
149
|
+
const diagnostics = diagnoseWorkflowFile(sourceFile, activities);
|
|
150
|
+
if (diagnostics.length > 0)
|
|
151
|
+
throw new TranspileError(diagnostics, fileName);
|
|
152
|
+
// 2. lower the branch to IR and emit durable calls; unify the rejection contract
|
|
153
|
+
let body;
|
|
154
|
+
try {
|
|
155
|
+
body = emitBranch(lowerSource(source, fileName));
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
if (e instanceof LowerError)
|
|
159
|
+
throw new TranspileError([lowerErrorToDiagnostic(e)], fileName);
|
|
160
|
+
throw e;
|
|
161
|
+
}
|
|
162
|
+
// 3. assemble the full module around the IR-emitted body
|
|
163
|
+
const code = emit(source, sourceFile, activities, undefined, body);
|
|
164
|
+
return { code, activities: [...activities] };
|
|
165
|
+
}
|
|
166
|
+
// Map a structured LowerError into the transpiler's Diagnostic shape so a single
|
|
167
|
+
// error surface (TranspileError) reaches consumers.
|
|
168
|
+
function lowerErrorToDiagnostic(e) {
|
|
169
|
+
const why = e.message.replace(/^\[[A-Z_]+\][^—]*—\s*/, '').split('\n')[0].trim();
|
|
170
|
+
return {
|
|
171
|
+
message: `[${e.code}] ${why}${e.fix ? ` — fix: ${e.fix}` : ''}`,
|
|
172
|
+
line: e.loc?.line ?? 1,
|
|
173
|
+
column: e.loc?.column ?? 1,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Assemble a full module using a pre-emitted branch body (e.g. from `@flopod/ir`'s
|
|
178
|
+
* `emit`) instead of the AST-rewrite path. Reuses every other part of the module
|
|
179
|
+
* frame (imports, leaf passthrough, runtime setup, input handling, invocation) so
|
|
180
|
+
* the IR path differs from `transpileSource` only in how `main`'s body is produced.
|
|
181
|
+
* This is the seam for routing the transpiler through the IR (docs/flopod-ir.md [4]).
|
|
182
|
+
*/
|
|
183
|
+
export function assembleFromBody(mainBody, source, fileName = 'workflow.ts') {
|
|
184
|
+
const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.ES2022, true);
|
|
185
|
+
const activities = collectActivities(sourceFile);
|
|
186
|
+
const diagnostics = diagnoseWorkflowFile(sourceFile, activities);
|
|
187
|
+
if (diagnostics.length > 0)
|
|
188
|
+
throw new TranspileError(diagnostics, fileName);
|
|
189
|
+
const code = emit(source, sourceFile, activities, undefined, mainBody);
|
|
190
|
+
return { code, activities: [...activities] };
|
|
191
|
+
}
|
|
192
|
+
export function getWorkflowMeta(source, fileName = 'workflow.ts') {
|
|
193
|
+
const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.ES2022, true);
|
|
194
|
+
return {
|
|
195
|
+
defaultFnName: findDefaultExportName(sourceFile),
|
|
196
|
+
hasParams: defaultExportHasParams(sourceFile),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Build-path transformer driven by the IR (§23 stage 3). Like `createFlopodTransformer`
|
|
201
|
+
* it returns a `ts.TransformerFactory` that `ts.transpileModule` runs to produce JS +
|
|
202
|
+
* source maps — but the default export's body is no longer rewritten by AST surgery.
|
|
203
|
+
* Instead the branch is lowered to the IR, emitted as durable `wf.*` calls (`emitBranch`),
|
|
204
|
+
* and the emitted statements are spliced in as **synthetic** nodes (positions cleared so
|
|
205
|
+
* the printer emits them structurally, not by slicing the original text). Each top-level
|
|
206
|
+
* emitted statement is given a `setSourceMapRange` back to its original statement position
|
|
207
|
+
* (from `lowerWithProvenance`), and `NoNestedSourceMaps` so its sub-nodes (which carry
|
|
208
|
+
* temp-parse positions) do not emit bogus mappings. TS then generates an accurate
|
|
209
|
+
* JS→original map in one pass — no map composition needed.
|
|
210
|
+
*
|
|
211
|
+
* A `LowerError` (deferred `let`/`while`, §19#2) surfaces as a `TranspileError`, the same
|
|
212
|
+
* single error contract the rest of the compiler uses.
|
|
213
|
+
*/
|
|
214
|
+
export function createIRTransformer() {
|
|
215
|
+
return (context) => (sourceFile) => {
|
|
216
|
+
const activities = collectActivities(sourceFile);
|
|
217
|
+
const factory = context.factory;
|
|
218
|
+
const diagnostics = diagnoseWorkflowFile(sourceFile, activities);
|
|
219
|
+
if (diagnostics.length > 0)
|
|
220
|
+
throw new TranspileError(diagnostics, sourceFile.fileName);
|
|
221
|
+
let lowered;
|
|
222
|
+
try {
|
|
223
|
+
lowered = lowerWithProvenance(sourceFile.text, sourceFile.fileName);
|
|
224
|
+
}
|
|
225
|
+
catch (e) {
|
|
226
|
+
if (e instanceof LowerError)
|
|
227
|
+
throw new TranspileError([lowerErrorToDiagnostic(e)], sourceFile.fileName);
|
|
228
|
+
throw e;
|
|
229
|
+
}
|
|
230
|
+
const { workflow, prov } = lowered;
|
|
231
|
+
// Parse the emitted durable body into statements (wrapped in a throwaway fn so it is
|
|
232
|
+
// a valid parse), then make every node synthetic so the printer emits structurally.
|
|
233
|
+
const bodyText = emitBranch(workflow);
|
|
234
|
+
const tmp = ts.createSourceFile('body.ts', `async function __m(){\n${bodyText}\n}`, ts.ScriptTarget.ES2022, true);
|
|
235
|
+
const emittedFn = tmp.statements[0];
|
|
236
|
+
const emittedStmts = emittedFn.body ? [...emittedFn.body.statements] : [];
|
|
237
|
+
for (const s of emittedStmts)
|
|
238
|
+
makeSynthetic(s);
|
|
239
|
+
// Map each top-level emitted statement to its source position. emit produces exactly
|
|
240
|
+
// one top-level statement per top-level IR step, in order — so they zip 1:1.
|
|
241
|
+
emittedStmts.forEach((stmt, idx) => {
|
|
242
|
+
const step = workflow.body[idx];
|
|
243
|
+
const sp = step ? prov.get(step) : undefined;
|
|
244
|
+
if (sp)
|
|
245
|
+
ts.setSourceMapRange(stmt, sourceRange(sourceFile, sp));
|
|
246
|
+
ts.setEmitFlags(stmt, ts.EmitFlags.NoNestedSourceMaps);
|
|
247
|
+
});
|
|
248
|
+
// Runtime setup (backend / runId / wf) — never mapped to source.
|
|
249
|
+
const setupStmts = buildSetupStatements(undefined, codeVersionOf(sourceFile.text));
|
|
250
|
+
for (const s of setupStmts)
|
|
251
|
+
ts.setEmitFlags(s, ts.EmitFlags.NoSourceMap);
|
|
252
|
+
const newStatements = [];
|
|
253
|
+
for (const stmt of sourceFile.statements) {
|
|
254
|
+
if (ts.isImportDeclaration(stmt)) {
|
|
255
|
+
const mod = stmt.moduleSpecifier.text;
|
|
256
|
+
if (mod === 'flopod')
|
|
257
|
+
continue;
|
|
258
|
+
newStatements.push(stmt);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (ts.isFunctionDeclaration(stmt) &&
|
|
262
|
+
stmt.name &&
|
|
263
|
+
stmt.modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)) {
|
|
264
|
+
const newBody = factory.createBlock([...setupStmts, ...emittedStmts], true);
|
|
265
|
+
ts.setSourceMapRange(newBody, stmt.body);
|
|
266
|
+
const newFn = factory.createFunctionDeclaration([factory.createToken(ts.SyntaxKind.AsyncKeyword)], undefined, stmt.name, stmt.typeParameters, stmt.parameters, stmt.type, newBody);
|
|
267
|
+
ts.setSourceMapRange(newFn, stmt);
|
|
268
|
+
newStatements.push(newFn);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
newStatements.push(stmt);
|
|
272
|
+
}
|
|
273
|
+
return factory.updateSourceFile(sourceFile, newStatements);
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
// Recursively clear text positions so the printer treats a parsed node (and its whole
|
|
277
|
+
// subtree) as synthesized — i.e. emits from structure, not by slicing the source text.
|
|
278
|
+
function makeSynthetic(node) {
|
|
279
|
+
ts.setTextRange(node, { pos: -1, end: -1 });
|
|
280
|
+
node.forEachChild(makeSynthetic);
|
|
281
|
+
}
|
|
282
|
+
// A source-map range covering the original statement's line (start → end of that line).
|
|
283
|
+
function sourceRange(sf, sp) {
|
|
284
|
+
const pos = sf.getPositionOfLineAndCharacter(sp.line, sp.column);
|
|
285
|
+
let end = pos;
|
|
286
|
+
try {
|
|
287
|
+
end = sf.getPositionOfLineAndCharacter(sp.line + 1, 0) - 1;
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
end = sf.text.length;
|
|
291
|
+
}
|
|
292
|
+
return { pos, end };
|
|
293
|
+
}
|
|
294
|
+
function getJsDocText(comment) {
|
|
295
|
+
if (!comment)
|
|
296
|
+
return '';
|
|
297
|
+
if (typeof comment === 'string')
|
|
298
|
+
return comment;
|
|
299
|
+
return comment.map(c => ('text' in c ? c.text : '')).join('');
|
|
300
|
+
}
|
|
301
|
+
function extractActivityMeta(sourceFile) {
|
|
302
|
+
const meta = new Map();
|
|
303
|
+
for (const node of sourceFile.statements) {
|
|
304
|
+
if (!ts.isFunctionDeclaration(node) || !node.name)
|
|
305
|
+
continue;
|
|
306
|
+
if (node.modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword))
|
|
307
|
+
continue;
|
|
308
|
+
const name = node.name.text;
|
|
309
|
+
const jsdocs = ts.getJSDocCommentsAndTags(node).filter(ts.isJSDoc);
|
|
310
|
+
if (!jsdocs.length)
|
|
311
|
+
continue;
|
|
312
|
+
const jsdoc = jsdocs[jsdocs.length - 1];
|
|
313
|
+
const summaryText = getJsDocText(jsdoc.comment);
|
|
314
|
+
const firstLine = summaryText.split('\n')[0].trim();
|
|
315
|
+
const title = firstLine || undefined;
|
|
316
|
+
const descTag = ts.getJSDocTags(node).find(t => t.tagName.text === 'description');
|
|
317
|
+
const description = descTag ? getJsDocText(descTag.comment).trim() || undefined : undefined;
|
|
318
|
+
if (title || description)
|
|
319
|
+
meta.set(name, { title, description });
|
|
320
|
+
}
|
|
321
|
+
return meta;
|
|
322
|
+
}
|
|
323
|
+
// ── Collect activities (every non-default top-level function) ─────────────────
|
|
324
|
+
function collectActivities(sourceFile) {
|
|
325
|
+
const names = new Set();
|
|
326
|
+
for (const node of sourceFile.statements) {
|
|
327
|
+
if (ts.isFunctionDeclaration(node) &&
|
|
328
|
+
node.name &&
|
|
329
|
+
!node.modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword)) {
|
|
330
|
+
names.add(node.name.text);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return names;
|
|
334
|
+
}
|
|
335
|
+
// ── Setup statement builders ──────────────────────────────────────────────────
|
|
336
|
+
function buildSetupStatements(devMode, codeVersion) {
|
|
337
|
+
const factory = ts.factory;
|
|
338
|
+
const runtimeProps = () => {
|
|
339
|
+
const props = [
|
|
340
|
+
factory.createShorthandPropertyAssignment('runId'),
|
|
341
|
+
factory.createShorthandPropertyAssignment('backend'),
|
|
342
|
+
];
|
|
343
|
+
if (codeVersion) {
|
|
344
|
+
props.push(factory.createPropertyAssignment('codeVersion', factory.createStringLiteral(codeVersion)));
|
|
345
|
+
}
|
|
346
|
+
return props;
|
|
347
|
+
};
|
|
348
|
+
if (devMode) {
|
|
349
|
+
return [
|
|
350
|
+
makeConst('backend', factory.createNewExpression(factory.createIdentifier('NullBackend'), undefined, [])),
|
|
351
|
+
makeConst('runId', factory.createStringLiteral('dev-run')),
|
|
352
|
+
makeConst('wf', factory.createAwaitExpression(factory.createCallExpression(factory.createIdentifier('createRuntime'), undefined, [
|
|
353
|
+
factory.createObjectLiteralExpression(runtimeProps()),
|
|
354
|
+
]))),
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
// Backend is resolved from the environment so one compiled artifact runs
|
|
358
|
+
// anywhere: no env → SQLite ./workflow.db (local default, unchanged); a
|
|
359
|
+
// DATABASE_URL → managed Postgres (e.g. a DigitalOcean Droplet/App Platform
|
|
360
|
+
// deploy). FLOPOD_BACKEND can force the choice explicitly — e.g. `file` for a
|
|
361
|
+
// dependency-free JSONL log under FLOPOD_DATA_DIR (mount a volume to persist).
|
|
362
|
+
const procEnv = (name) => factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createIdentifier('process'), 'env'), name);
|
|
363
|
+
const backendSpec = factory.createBinaryExpression(procEnv('FLOPOD_BACKEND'), ts.SyntaxKind.QuestionQuestionToken, factory.createParenthesizedExpression(factory.createConditionalExpression(procEnv('DATABASE_URL'), factory.createToken(ts.SyntaxKind.QuestionToken), factory.createStringLiteral('postgres'), factory.createToken(ts.SyntaxKind.ColonToken), factory.createStringLiteral('sqlite'))));
|
|
364
|
+
const backendOpts = factory.createObjectLiteralExpression([
|
|
365
|
+
factory.createPropertyAssignment('dbPath', factory.createBinaryExpression(procEnv('FLOPOD_DB_PATH'), ts.SyntaxKind.QuestionQuestionToken, factory.createStringLiteral('./workflow.db'))),
|
|
366
|
+
factory.createPropertyAssignment('connectionString', procEnv('DATABASE_URL')),
|
|
367
|
+
factory.createPropertyAssignment('dataDir', procEnv('FLOPOD_DATA_DIR')),
|
|
368
|
+
], false);
|
|
369
|
+
return [
|
|
370
|
+
makeConst('backend', factory.createAwaitExpression(factory.createCallExpression(factory.createIdentifier('resolveBackend'), undefined, [
|
|
371
|
+
backendSpec,
|
|
372
|
+
backendOpts,
|
|
373
|
+
]))),
|
|
374
|
+
makeConst('runId', factory.createBinaryExpression(factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createIdentifier('process'), 'env'), 'FLOPOD_RUN_ID'), ts.SyntaxKind.QuestionQuestionToken, factory.createStringLiteral('main-run'))),
|
|
375
|
+
makeConst('wf', factory.createAwaitExpression(factory.createCallExpression(factory.createIdentifier('createRuntime'), undefined, [
|
|
376
|
+
factory.createObjectLiteralExpression(runtimeProps()),
|
|
377
|
+
]))),
|
|
378
|
+
];
|
|
379
|
+
}
|
|
380
|
+
// ── Module assembly (frames the IR-emitted branch body) ───────────────────────
|
|
381
|
+
// Builds the full output module around a pre-emitted `main` body (`mainBodyOverride`,
|
|
382
|
+
// always supplied now that every path routes through the IR). Dev mode embeds the
|
|
383
|
+
// IR-built static graph (`staticNodes`) as a compile-time literal — no dry run.
|
|
384
|
+
function emit(source, sourceFile, activities, devMode, mainBodyOverride, staticNodes, boxTree) {
|
|
385
|
+
const parts = [];
|
|
386
|
+
if (devMode) {
|
|
387
|
+
parts.push(`import { createRuntime, FileBackend, OTelPlugin, STOP } from '${devMode.runtimeUrl}';\n`);
|
|
388
|
+
parts.push(`import { FlopodDevServer } from '${devMode.devUrl}';\n`);
|
|
389
|
+
parts.push(`import { readFileSync } from 'fs';\n`);
|
|
390
|
+
const port = devMode.port ?? 3847;
|
|
391
|
+
// Serve mode is headless with no artificial pacing; dev keeps the animation delay.
|
|
392
|
+
// serve always uses an explicit, deliberate port (containerized) → fail loud, never roam.
|
|
393
|
+
const explicitPort = devMode.serve || devMode.explicitPort;
|
|
394
|
+
const optsParts = devMode.serve
|
|
395
|
+
? `, openBrowser: false, activityDelayMs: 0, explicitPort: true`
|
|
396
|
+
: `${explicitPort ? `, explicitPort: true` : ''}${devMode.activityDelayMs !== undefined ? `, activityDelayMs: ${devMode.activityDelayMs}` : ''}`;
|
|
397
|
+
// One durable backend shared by every run (keyed internally by runId), so the
|
|
398
|
+
// control plane survives restarts: events persist, and the run list hydrates
|
|
399
|
+
// from backend.listRuns() on startup. FLOPOD_DATA_DIR overrides the location.
|
|
400
|
+
parts.push(`const _backend = new FileBackend();\n`);
|
|
401
|
+
parts.push(`const _devServer = new FlopodDevServer({ port: ${port}${optsParts}, backend: _backend });\n`);
|
|
402
|
+
parts.push(`let _flopodWfFactory;\n`);
|
|
403
|
+
parts.push(`await _devServer.start();\n`);
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
parts.push(`import { createRuntime, SqliteBackend, STOP } from '@flopod/runtime';\n`);
|
|
407
|
+
parts.push(`import { readFileSync } from 'fs';\n`);
|
|
408
|
+
}
|
|
409
|
+
for (const node of sourceFile.statements) {
|
|
410
|
+
if (ts.isImportDeclaration(node)) {
|
|
411
|
+
const mod = node.moduleSpecifier.text;
|
|
412
|
+
if (mod === 'flopod')
|
|
413
|
+
continue;
|
|
414
|
+
parts.push(source.slice(node.getStart(sourceFile), node.getEnd()) + '\n');
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
418
|
+
const isDefault = !!node.modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword);
|
|
419
|
+
if (isDefault) {
|
|
420
|
+
parts.push(emitMain(source, sourceFile, node, activities, devMode, mainBodyOverride));
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
parts.push(source.slice(node.getStart(sourceFile), node.getEnd()) + '\n');
|
|
424
|
+
}
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
parts.push(source.slice(node.getStart(sourceFile), node.getEnd()) + '\n');
|
|
428
|
+
}
|
|
429
|
+
const defaultFn = findDefaultExportName(sourceFile);
|
|
430
|
+
if (defaultFn) {
|
|
431
|
+
const hasParams = defaultExportHasParams(sourceFile);
|
|
432
|
+
const port = devMode?.port ?? 3847;
|
|
433
|
+
if (!devMode) {
|
|
434
|
+
parts.push(`\nconsole.log('[flopod] starting run:', process.env.FLOPOD_RUN_ID ?? 'main-run');\n`);
|
|
435
|
+
}
|
|
436
|
+
if (hasParams) {
|
|
437
|
+
// In dev mode a missing input is not fatal — the daemon stays up and the
|
|
438
|
+
// operator starts runs from the control plane instead.
|
|
439
|
+
const noInputLine = devMode
|
|
440
|
+
? `if (args.length === 0) { return undefined; }`
|
|
441
|
+
: `if (args.length === 0) { console.error('[flopod] error: workflow requires input — pass --input input.json or --key value flags'); process.exit(1); }`;
|
|
442
|
+
parts.push(`const _input = (() => {
|
|
443
|
+
const args = process.argv.slice(2);
|
|
444
|
+
if (args.length === 0 && process.env.FLOPOD_INPUT) return JSON.parse(process.env.FLOPOD_INPUT);
|
|
445
|
+
${noInputLine}
|
|
446
|
+
const inputIdx = args.indexOf('--input');
|
|
447
|
+
if (inputIdx !== -1) return JSON.parse(readFileSync(args[inputIdx + 1], 'utf8'));
|
|
448
|
+
const obj: Record<string, unknown> = {};
|
|
449
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
450
|
+
const key = args[i].replace(/^--/, '');
|
|
451
|
+
const raw = args[i + 1] ?? 'true';
|
|
452
|
+
try { obj[key] = JSON.parse(raw); } catch { obj[key] = raw; }
|
|
453
|
+
}
|
|
454
|
+
return obj;
|
|
455
|
+
})();\n`);
|
|
456
|
+
}
|
|
457
|
+
if (devMode) {
|
|
458
|
+
const wfName = workflowDisplayName(sourceFile, defaultFn);
|
|
459
|
+
const paramsSpec = hasParams ? extractParamsSpec(sourceFile) : null;
|
|
460
|
+
// Static graph built from the IR at compile time ([5] Part 2b) — `toGraph`'s node
|
|
461
|
+
// paths are the runtime template paths, so live events overlay them by path.
|
|
462
|
+
parts.push(`\n// Static graph from the IR (toGraph) — no dry run needed`);
|
|
463
|
+
parts.push(`const _runId = process.env.FLOPOD_RUN_ID ?? 'dev-run';`);
|
|
464
|
+
parts.push(`const _staticNodes = ${JSON.stringify(staticNodes)};`);
|
|
465
|
+
// Nested box tree (toBoxTree) — the new designer's structure source; same paths as
|
|
466
|
+
// the static nodes, so live status overlays it too.
|
|
467
|
+
parts.push(`const _boxTree = ${JSON.stringify(boxTree)};`);
|
|
468
|
+
parts.push(`\n// Run starter — used for the initial CLI run and for runs started from the control plane`);
|
|
469
|
+
parts.push(`function _flopodStart(runId: string, input: unknown): Promise<void> {`);
|
|
470
|
+
parts.push(` _flopodWfFactory = async () => createRuntime({ runId, backend: _backend, codeVersion: ${JSON.stringify(codeVersionOf(source))}, plugins: [new OTelPlugin({ processors: [_devServer] }), _devServer] });`);
|
|
471
|
+
parts.push(` _devServer.pushStaticGraph(runId, _staticNodes);`);
|
|
472
|
+
parts.push(` _devServer.pushBoxTree(runId, _boxTree);`);
|
|
473
|
+
parts.push(` return _devServer.run(runId, () => ${hasParams ? `${defaultFn}(input as any)` : `${defaultFn}()`}, { input: input ?? null });`);
|
|
474
|
+
parts.push(`}`);
|
|
475
|
+
parts.push(`_devServer.registerWorkflow({ name: ${JSON.stringify(wfName)}, params: ${JSON.stringify(paramsSpec)}, start: _flopodStart });`);
|
|
476
|
+
if (devMode.serve) {
|
|
477
|
+
// A persistent control plane: never auto-run a default run — boot, hydrate
|
|
478
|
+
// the run list, and wait for runs triggered over HTTP (POST /runs). The
|
|
479
|
+
// HTTP server keeps the process alive.
|
|
480
|
+
parts.push(`console.log('[flopod serve] control plane ready → http://localhost:${port}/__flopod (POST /runs to start a run)');\n`);
|
|
481
|
+
}
|
|
482
|
+
else if (hasParams) {
|
|
483
|
+
parts.push(`if (_input === undefined) {`);
|
|
484
|
+
parts.push(` console.log('[flopod dev] no input provided — start a run from the control plane: http://localhost:${port}/__flopod');`);
|
|
485
|
+
parts.push(`} else {`);
|
|
486
|
+
parts.push(` await _flopodStart(_runId, _input);`);
|
|
487
|
+
parts.push(`}\n`);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
parts.push(`await _flopodStart(_runId, undefined);\n`);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
if (hasParams) {
|
|
495
|
+
parts.push(`${defaultFn}(_input as any).catch(err => { console.error(err); process.exit(1); });\n`);
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
parts.push(`${defaultFn}().catch(err => { console.error(err); process.exit(1); });\n`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return parts.join('\n');
|
|
503
|
+
}
|
|
504
|
+
function emitMain(source, sourceFile, node, activities, devMode, mainBodyOverride) {
|
|
505
|
+
if (!node.body || mainBodyOverride === undefined)
|
|
506
|
+
return '';
|
|
507
|
+
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
508
|
+
// Assemble main from the runtime setup + the pre-emitted IR body, then reparse/reprint
|
|
509
|
+
// so the body's formatting is canonical.
|
|
510
|
+
const params = node.parameters.map(p => p.getText(sourceFile)).join(', ');
|
|
511
|
+
const ret = node.type ? `: ${node.type.getText(sourceFile)}` : '';
|
|
512
|
+
const setup = devMode
|
|
513
|
+
? `const wf = await _flopodWfFactory();\n`
|
|
514
|
+
: `const backend = new SqliteBackend("./workflow.db");\n` +
|
|
515
|
+
`const runId = process.env.FLOPOD_RUN_ID ?? "main-run";\n` +
|
|
516
|
+
`const wf = await createRuntime({ runId, backend, codeVersion: ${JSON.stringify(codeVersionOf(source))} });\n`;
|
|
517
|
+
const mainText = `async function ${node.name.text}(${params})${ret} {\n${setup}${mainBodyOverride}\n}`;
|
|
518
|
+
const tmp = ts.createSourceFile('main.ts', mainText, ts.ScriptTarget.ES2022, true);
|
|
519
|
+
return printer.printNode(ts.EmitHint.Unspecified, tmp.statements[0], tmp) + '\n';
|
|
520
|
+
}
|
|
521
|
+
// ── AST utilities ─────────────────────────────────────────────────────────────
|
|
522
|
+
function findDefaultExportName(sourceFile) {
|
|
523
|
+
for (const node of sourceFile.statements) {
|
|
524
|
+
if (ts.isFunctionDeclaration(node) &&
|
|
525
|
+
node.modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword) &&
|
|
526
|
+
node.name) {
|
|
527
|
+
return node.name.text;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
function defaultExportHasParams(sourceFile) {
|
|
533
|
+
for (const node of sourceFile.statements) {
|
|
534
|
+
if (ts.isFunctionDeclaration(node) &&
|
|
535
|
+
node.modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword)) {
|
|
536
|
+
return node.parameters.length > 0;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Human-facing workflow name for the control plane header. Uses the source file
|
|
543
|
+
* basename; for generic names (main/index) falls back to the project directory
|
|
544
|
+
* (the segment before /src/), then to the default function name.
|
|
545
|
+
*/
|
|
546
|
+
function workflowDisplayName(sourceFile, defaultFn) {
|
|
547
|
+
const normalized = sourceFile.fileName.replace(/\\/g, '/');
|
|
548
|
+
const base = (normalized.split('/').pop() ?? '').replace(/\.[^.]+$/, '');
|
|
549
|
+
if (base && base !== 'main' && base !== 'index')
|
|
550
|
+
return base;
|
|
551
|
+
const segments = normalized.split('/');
|
|
552
|
+
const srcIdx = segments.lastIndexOf('src');
|
|
553
|
+
if (srcIdx > 0)
|
|
554
|
+
return segments[srcIdx - 1];
|
|
555
|
+
return base || defaultFn;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Derive a form schema from the default export's first parameter type so the
|
|
559
|
+
* control plane can render a typed start-run form. Supports inline type
|
|
560
|
+
* literals and same-file interfaces/type aliases with primitive members;
|
|
561
|
+
* anything more complex degrades to a single JSON field.
|
|
562
|
+
*/
|
|
563
|
+
function extractParamsSpec(sourceFile) {
|
|
564
|
+
let fn;
|
|
565
|
+
for (const node of sourceFile.statements) {
|
|
566
|
+
if (ts.isFunctionDeclaration(node) && node.modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword)) {
|
|
567
|
+
fn = node;
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
if (!fn || fn.parameters.length === 0)
|
|
572
|
+
return null;
|
|
573
|
+
const param = fn.parameters[0];
|
|
574
|
+
const fallbackName = ts.isIdentifier(param.name) ? param.name.text : 'input';
|
|
575
|
+
const fallback = [{ name: fallbackName, type: 'json', required: !param.questionToken }];
|
|
576
|
+
let members = null;
|
|
577
|
+
const typeNode = param.type;
|
|
578
|
+
if (!typeNode)
|
|
579
|
+
return fallback;
|
|
580
|
+
if (ts.isTypeLiteralNode(typeNode)) {
|
|
581
|
+
members = typeNode.members;
|
|
582
|
+
}
|
|
583
|
+
else if (ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName)) {
|
|
584
|
+
const refName = typeNode.typeName.text;
|
|
585
|
+
for (const st of sourceFile.statements) {
|
|
586
|
+
if (ts.isInterfaceDeclaration(st) && st.name.text === refName) {
|
|
587
|
+
members = st.members;
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
if (ts.isTypeAliasDeclaration(st) && st.name.text === refName && ts.isTypeLiteralNode(st.type)) {
|
|
591
|
+
members = st.type.members;
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
if (!members)
|
|
597
|
+
return fallback;
|
|
598
|
+
const specs = [];
|
|
599
|
+
for (const m of members) {
|
|
600
|
+
if (!ts.isPropertySignature(m) || !m.name || !m.type)
|
|
601
|
+
continue;
|
|
602
|
+
const name = ts.isIdentifier(m.name) || ts.isStringLiteral(m.name) ? m.name.text : m.name.getText(sourceFile);
|
|
603
|
+
specs.push({ name, required: !m.questionToken, ...mapParamType(m.type) });
|
|
604
|
+
}
|
|
605
|
+
return specs.length > 0 ? specs : fallback;
|
|
606
|
+
}
|
|
607
|
+
function mapParamType(t) {
|
|
608
|
+
switch (t.kind) {
|
|
609
|
+
case ts.SyntaxKind.StringKeyword: return { type: 'string' };
|
|
610
|
+
case ts.SyntaxKind.NumberKeyword: return { type: 'number' };
|
|
611
|
+
case ts.SyntaxKind.BooleanKeyword: return { type: 'boolean' };
|
|
612
|
+
}
|
|
613
|
+
if (ts.isUnionTypeNode(t)) {
|
|
614
|
+
const options = [];
|
|
615
|
+
for (const member of t.types) {
|
|
616
|
+
if (ts.isLiteralTypeNode(member) && ts.isStringLiteral(member.literal)) {
|
|
617
|
+
options.push(member.literal.text);
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
return { type: 'json' };
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
if (options.length > 0)
|
|
624
|
+
return { type: 'enum', options };
|
|
625
|
+
}
|
|
626
|
+
return { type: 'json' };
|
|
627
|
+
}
|
|
628
|
+
function makeConst(name, init) {
|
|
629
|
+
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(name, undefined, undefined, init)], ts.NodeFlags.Const));
|
|
630
|
+
}
|
|
631
|
+
//# sourceMappingURL=transpile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transpile.js","sourceRoot":"","sources":["../src/transpile.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flopod/compiler",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist"
|
|
7
|
+
],
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"flopod-compile": "./dist/cli.js"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"test": "vitest run"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@flopod/ir": "^0.1.0",
|
|
26
|
+
"typescript": "^5.5.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@flopod/runtime": "^0.1.0",
|
|
30
|
+
"@types/node": "^22.0.0"
|
|
31
|
+
}
|
|
32
|
+
}
|