@bobtail.software/b-durable 1.0.4 → 1.0.5

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.
@@ -1,58 +1,721 @@
1
1
  #!/usr/bin/env node
2
- import R from"path";import{existsSync as L,mkdirSync as K,rmSync as _}from"fs";import b from"path";import*as k from"prettier";import{Node as g,Project as z,SyntaxKind as E,ts as B,VariableDeclarationKind as M}from"ts-morph";var U="bDurable",A=B.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope|B.TypeFormatFlags.NoTruncation;async function H(e){let t=e.getFilePath(),s=e.getFullText(),n=await k.resolveConfig(t),a=await k.format(s,{...n,parser:"typescript"});e.replaceWithText(a)}async function O(e){console.log("Iniciando compilador de workflows duraderos...");let{inputDir:t,outputDir:s,packageName:n}=e,a=new z({tsConfigFilePath:b.resolve(process.cwd(),"tsconfig.json")}),i=a.addSourceFilesAtPaths(`${t}/**/*.ts`);L(s)&&(console.log(`Limpiando directorio de salida: ${s}`),_(s,{recursive:!0,force:!0})),K(s,{recursive:!0});let S=a.createDirectory(s);console.log(`Encontrados ${i.length} archivos de workflow para procesar.`);let o=[],c=[];for(let l of i){console.log(`
3
- Procesando archivo: ${l.getBaseName()}`);let r=l.getDescendantsOfKind(E.CallExpression).filter(d=>d.getExpression().getText()===U);if(r.length!==0)for(let d of r){let p=d.getParentIfKind(E.VariableDeclaration);if(!p)continue;let u=p.getName();console.log(` -> Transformando workflow: ${u}`);let[f]=d.getArguments();if(!g.isObjectLiteralExpression(f))continue;let x=f.getProperty("workflow");if(!x||!g.isPropertyAssignment(x))continue;let m=x.getInitializer();if(!m||!g.isArrowFunction(m))continue;let P=l.getBaseName().replace(/\.ts$/,".compiled.mts"),$=b.join(S.getPath(),P),I=a.createSourceFile($,"",{overwrite:!0});c.push(I),q(u,m,d,I,n),console.log(` -> Archivo generado: ${b.relative(process.cwd(),$)}`);let y=P;o.push({name:u,importPath:`./${y}`})}}if(o.length>0){let l=b.join(S.getPath(),"index.mts"),r=a.createSourceFile(l,"",{overwrite:!0});c.push(r),r.addStatements(`// Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.
4
- `),r.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:n,namedImports:["DurableFunction"]});for(let p of o)r.addImportDeclaration({moduleSpecifier:p.importPath,namedImports:[p.name]});r.addExportDeclaration({namedExports:o.map(p=>p.name)}),r.addStatements(`
5
- `),r.addVariableStatement({declarationKind:M.Const,declarations:[{name:"durableFunctions",type:"Map<string, DurableFunction<any, any>>",initializer:"new Map()"}]});let d=o.map(p=>`durableFunctions.set(${p.name}.name, ${p.name});`);r.addStatements(d),r.addStatements(`
6
- `),r.addExportAssignment({isExportEquals:!1,expression:"durableFunctions"}),console.log(`
7
- -> Archivo de \xEDndice generado: ${b.basename(l)}`)}console.log(`
8
- Formateando archivos generados con Prettier...`);for(let l of c)await H(l);await a.save(),console.log(`
9
- Compilaci\xF3n completada exitosamente.`)}function q(e,t,s,n,a){let i=t.getBody();if(!g.isBlock(i))throw new Error(`El cuerpo del workflow '${e}' debe ser un bloque {}.`);let{clauses:S}=w(i.getStatements(),{step:0,persistedVariables:new Map}),o=t.getReturnType();o.getSymbol()?.getName()==="Promise"&&o.isObject()&&(o=o.getTypeArguments()[0]||o);let c=o.getText(void 0,A),l=new Set,r=t.getSourceFile(),d=s.getTypeArguments(),p=d.length>0?d[0].getText():"unknown";r.getImportDeclarations().forEach(m=>{if(m.getModuleSpecifierValue()===a)return;let h=m.getModuleSpecifierValue();if(h.includes(".workflow")){let y=b.parse(h),T=b.join(y.dir,y.base+".compiled.mts");!T.startsWith(".")&&!b.isAbsolute(T)&&(T="./"+T),h=T.replace(/\\/g,"/")}else h.startsWith(".")&&b.extname(h)===""&&(h+=".mjs");let P=[],$=[];m.getNamedImports().forEach(y=>{let T=y.getName(),F=y.getAliasNode()?.getText(),v=F?`${T} as ${F}`:T,V=(y.getNameNode().getSymbol()?.getAliasedSymbol()??y.getNameNode().getSymbol())?.getDeclarations()??[],j=V.some(D=>g.isEnumDeclaration(D));y.isTypeOnly()||!j&&V.every(D=>g.isInterfaceDeclaration(D)||g.isTypeAliasDeclaration(D))?$.push(v):P.push(v)}),P.length>0&&n.addImportDeclaration({moduleSpecifier:h,namedImports:P}),$.length>0&&n.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:h,namedImports:$});let I=m.getDefaultImport();I&&n.addImportDeclaration({moduleSpecifier:h,defaultImport:I.getText()})}),r.getInterfaces().forEach(m=>{l.add(m.getText().startsWith("export")?m.getText():`export ${m.getText()}`)}),r.getTypeAliases().forEach(m=>{l.add(m.getText().startsWith("export")?m.getText():`export ${m.getText()}`)});let[u]=t.getParameters(),f="";if(u){let m=u.getNameNode().getText();m!=="input"&&(f=`const ${m} = input;`)}n.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:a,namedImports:["DurableFunction","WorkflowContext","Instruction"]}),l.size>0&&(n.addStatements(`
10
- `),n.addStatements(Array.from(l))),n.addStatements(`
11
- // Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.
12
- `);let x=`{
2
+
3
+ // src/compiler/cli.ts
4
+ import path2 from "path";
5
+
6
+ // src/compiler/compile.ts
7
+ import { existsSync, mkdirSync, rmSync } from "fs";
8
+ import path from "path";
9
+ import * as prettier from "prettier";
10
+ import {
11
+ Node,
12
+ Project,
13
+ SyntaxKind,
14
+ ts,
15
+ VariableDeclarationKind
16
+ } from "ts-morph";
17
+ var DURABLE_WRAPPER_NAME = "bDurable";
18
+ var TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | ts.TypeFormatFlags.NoTruncation;
19
+ async function formatSourceFileWithPrettier(sourceFile) {
20
+ const filePath = sourceFile.getFilePath();
21
+ const unformattedText = sourceFile.getFullText();
22
+ const prettierConfig = await prettier.resolveConfig(filePath);
23
+ const formattedText = await prettier.format(unformattedText, {
24
+ ...prettierConfig,
25
+ parser: "typescript"
26
+ });
27
+ sourceFile.replaceWithText(formattedText);
28
+ }
29
+ async function compileWorkflows(options) {
30
+ console.log("Iniciando compilador de workflows duraderos...");
31
+ const { inputDir, outputDir, packageName } = options;
32
+ const project = new Project({
33
+ tsConfigFilePath: path.resolve(process.cwd(), "tsconfig.json")
34
+ });
35
+ const sourceFiles = project.addSourceFilesAtPaths(`${inputDir}/**/*.ts`);
36
+ if (existsSync(outputDir)) {
37
+ console.log(`Limpiando directorio de salida: ${outputDir}`);
38
+ rmSync(outputDir, { recursive: true, force: true });
39
+ }
40
+ mkdirSync(outputDir, { recursive: true });
41
+ const compiledDir = project.createDirectory(outputDir);
42
+ console.log(`Encontrados ${sourceFiles.length} archivos de workflow para procesar.`);
43
+ const workflowRegistry = [];
44
+ const generatedFiles = [];
45
+ for (const sourceFile of sourceFiles) {
46
+ console.log(`
47
+ Procesando archivo: ${sourceFile.getBaseName()}`);
48
+ const durableCalls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).filter((call) => call.getExpression().getText() === DURABLE_WRAPPER_NAME);
49
+ if (durableCalls.length === 0) continue;
50
+ for (const call of durableCalls) {
51
+ const workflowVarDecl = call.getParentIfKind(SyntaxKind.VariableDeclaration);
52
+ if (!workflowVarDecl) continue;
53
+ const workflowName = workflowVarDecl.getName();
54
+ console.log(` -> Transformando workflow: ${workflowName}`);
55
+ const [arg] = call.getArguments();
56
+ if (!Node.isObjectLiteralExpression(arg)) continue;
57
+ const workflowProperty = arg.getProperty("workflow");
58
+ if (!workflowProperty || !Node.isPropertyAssignment(workflowProperty)) continue;
59
+ const workflowFunc = workflowProperty.getInitializer();
60
+ if (!workflowFunc || !Node.isArrowFunction(workflowFunc)) continue;
61
+ const originalBaseName = sourceFile.getBaseName();
62
+ const compiledFileName = originalBaseName.replace(/\.ts$/, ".compiled.mts");
63
+ const newFilePath = path.join(compiledDir.getPath(), compiledFileName);
64
+ const newSourceFile = project.createSourceFile(newFilePath, "", {
65
+ overwrite: true
66
+ });
67
+ generatedFiles.push(newSourceFile);
68
+ transformWorkflowFunction(
69
+ workflowName,
70
+ workflowFunc,
71
+ call,
72
+ newSourceFile,
73
+ packageName
74
+ );
75
+ console.log(
76
+ ` -> Archivo generado: ${path.relative(process.cwd(), newFilePath)}`
77
+ );
78
+ const importPathName = compiledFileName;
79
+ workflowRegistry.push({ name: workflowName, importPath: `./${importPathName}` });
80
+ }
81
+ }
82
+ if (workflowRegistry.length > 0) {
83
+ const indexFilePath = path.join(compiledDir.getPath(), "index.mts");
84
+ const indexSourceFile = project.createSourceFile(indexFilePath, "", {
85
+ overwrite: true
86
+ });
87
+ generatedFiles.push(indexSourceFile);
88
+ indexSourceFile.addStatements(
89
+ "// Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.\n"
90
+ );
91
+ indexSourceFile.addImportDeclaration({
92
+ isTypeOnly: true,
93
+ moduleSpecifier: packageName,
94
+ namedImports: ["DurableFunction"]
95
+ });
96
+ for (const wf of workflowRegistry) {
97
+ indexSourceFile.addImportDeclaration({
98
+ moduleSpecifier: wf.importPath,
99
+ namedImports: [wf.name]
100
+ });
101
+ }
102
+ indexSourceFile.addExportDeclaration({
103
+ namedExports: workflowRegistry.map((wf) => wf.name)
104
+ });
105
+ indexSourceFile.addStatements("\n");
106
+ indexSourceFile.addVariableStatement({
107
+ declarationKind: VariableDeclarationKind.Const,
108
+ declarations: [
109
+ {
110
+ name: "durableFunctions",
111
+ type: "Map<string, DurableFunction<any, any, any>>",
112
+ initializer: "new Map()"
113
+ }
114
+ ]
115
+ });
116
+ const setStatements = workflowRegistry.map(
117
+ (wf) => `durableFunctions.set(${wf.name}.name, ${wf.name});`
118
+ );
119
+ indexSourceFile.addStatements(setStatements);
120
+ indexSourceFile.addStatements("\n");
121
+ indexSourceFile.addExportAssignment({
122
+ isExportEquals: false,
123
+ expression: "durableFunctions"
124
+ });
125
+ console.log(`
126
+ -> Archivo de \xEDndice generado: ${path.basename(indexFilePath)}`);
127
+ }
128
+ console.log("\nFormateando archivos generados con Prettier...");
129
+ for (const file of generatedFiles) {
130
+ await formatSourceFileWithPrettier(file);
131
+ }
132
+ await project.save();
133
+ console.log("\nCompilaci\xF3n completada exitosamente.");
134
+ }
135
+ function transformWorkflowFunction(workflowName, func, bDurableCall, targetSourceFile, packageName) {
136
+ const body = func.getBody();
137
+ if (!Node.isBlock(body)) {
138
+ throw new Error(`El cuerpo del workflow '${workflowName}' debe ser un bloque {}.`);
139
+ }
140
+ const { clauses: caseClauses } = processStatementsRecursive(body.getStatements(), {
141
+ step: 0,
142
+ persistedVariables: /* @__PURE__ */ new Map()
143
+ });
144
+ let returnTypeNode = func.getReturnType();
145
+ if (returnTypeNode.getSymbol()?.getName() === "Promise" && returnTypeNode.isObject()) {
146
+ returnTypeNode = returnTypeNode.getTypeArguments()[0] || returnTypeNode;
147
+ }
148
+ const returnType = returnTypeNode.getText(void 0, TYPE_FORMAT_FLAGS);
149
+ const dependencyStatements = /* @__PURE__ */ new Set();
150
+ const originalSourceFile = func.getSourceFile();
151
+ const typeArgs = bDurableCall.getTypeArguments();
152
+ const paramType = typeArgs.length > 0 ? typeArgs[0].getText() : "unknown";
153
+ const eventsType = typeArgs.length > 2 ? typeArgs[2].getText() : "Record<string, never>";
154
+ originalSourceFile.getImportDeclarations().forEach((importDecl) => {
155
+ if (importDecl.getModuleSpecifierValue() === packageName) return;
156
+ let moduleSpecifier = importDecl.getModuleSpecifierValue();
157
+ if (moduleSpecifier.includes(".workflow")) {
158
+ const parsedPath = path.parse(moduleSpecifier);
159
+ let joinedPath = path.join(parsedPath.dir, parsedPath.base + ".compiled.mts");
160
+ if (!joinedPath.startsWith(".") && !path.isAbsolute(joinedPath)) {
161
+ joinedPath = "./" + joinedPath;
162
+ }
163
+ moduleSpecifier = joinedPath.replace(/\\/g, "/");
164
+ } else if (moduleSpecifier.startsWith(".")) {
165
+ if (path.extname(moduleSpecifier) === "") {
166
+ moduleSpecifier += ".mjs";
167
+ }
168
+ }
169
+ const valueImports = [];
170
+ const typeImports = [];
171
+ importDecl.getNamedImports().forEach((specifier) => {
172
+ const name = specifier.getName();
173
+ const alias = specifier.getAliasNode()?.getText();
174
+ const importText = alias ? `${name} as ${alias}` : name;
175
+ const symbol = specifier.getNameNode().getSymbol()?.getAliasedSymbol() ?? specifier.getNameNode().getSymbol();
176
+ const declarations = symbol?.getDeclarations() ?? [];
177
+ const isEnum = declarations.some((d) => Node.isEnumDeclaration(d));
178
+ const isPurelyType = specifier.isTypeOnly() || !isEnum && declarations.every(
179
+ (d) => Node.isInterfaceDeclaration(d) || Node.isTypeAliasDeclaration(d)
180
+ );
181
+ if (isPurelyType) {
182
+ typeImports.push(importText);
183
+ } else {
184
+ valueImports.push(importText);
185
+ }
186
+ });
187
+ if (valueImports.length > 0) {
188
+ targetSourceFile.addImportDeclaration({
189
+ moduleSpecifier,
190
+ namedImports: valueImports
191
+ });
192
+ }
193
+ if (typeImports.length > 0) {
194
+ targetSourceFile.addImportDeclaration({
195
+ isTypeOnly: true,
196
+ moduleSpecifier,
197
+ namedImports: typeImports
198
+ });
199
+ }
200
+ const defaultImport = importDecl.getDefaultImport();
201
+ if (defaultImport) {
202
+ targetSourceFile.addImportDeclaration({
203
+ moduleSpecifier,
204
+ defaultImport: defaultImport.getText()
205
+ });
206
+ }
207
+ });
208
+ originalSourceFile.getInterfaces().forEach((iface) => {
209
+ dependencyStatements.add(
210
+ iface.getText().startsWith("export") ? iface.getText() : `export ${iface.getText()}`
211
+ );
212
+ });
213
+ originalSourceFile.getTypeAliases().forEach((typeAlias) => {
214
+ dependencyStatements.add(
215
+ typeAlias.getText().startsWith("export") ? typeAlias.getText() : `export ${typeAlias.getText()}`
216
+ );
217
+ });
218
+ const [params] = func.getParameters();
219
+ let paramAssignment = "";
220
+ if (params) {
221
+ const paramName = params.getNameNode().getText();
222
+ if (paramName !== "input") {
223
+ paramAssignment = `const ${paramName} = input;`;
224
+ }
225
+ }
226
+ targetSourceFile.addImportDeclaration({
227
+ isTypeOnly: true,
228
+ moduleSpecifier: packageName,
229
+ namedImports: ["DurableFunction", "WorkflowContext", "Instruction"]
230
+ });
231
+ if (dependencyStatements.size > 0) {
232
+ targetSourceFile.addStatements("\n");
233
+ targetSourceFile.addStatements(Array.from(dependencyStatements));
234
+ }
235
+ targetSourceFile.addStatements(
236
+ "\n// Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.\n"
237
+ );
238
+ const initializerObjectString = `{
13
239
  __isDurable: true,
14
- name: '${e}',
15
- async execute(context: WorkflowContext<${p}>): Promise<Instruction<${c}>> {
240
+ name: '${workflowName}',
241
+ async execute(context: WorkflowContext<${paramType}>): Promise<Instruction<${returnType}>> {
16
242
  const { input, state, result, log, workflowId } = context;
17
- ${f}
243
+ ${paramAssignment}
18
244
  while (true) {
19
245
  switch (context.step) {
20
- ${S.join(`
21
- `)}
246
+ ${caseClauses.join("\n")}
22
247
  default:
23
248
  throw new Error(\`Paso desconocido: \${context.step}\`);
24
249
  }
25
250
  }
26
251
  }
27
- }`;n.addVariableStatement({isExported:!0,declarationKind:M.Const,declarations:[{name:e,type:`DurableFunction<${p}, ${c}>`,initializer:x}]}),n.organizeImports()}function w(e,t){if(e.length===0){let f=[];if(t.pendingStateAssignment){let x=`case ${t.step}: {
28
- ${t.pendingStateAssignment}
252
+ }`;
253
+ targetSourceFile.addVariableStatement({
254
+ isExported: true,
255
+ declarationKind: VariableDeclarationKind.Const,
256
+ declarations: [
257
+ {
258
+ name: workflowName,
259
+ type: `DurableFunction<${paramType}, ${returnType}, ${eventsType}>`,
260
+ initializer: initializerObjectString
261
+ }
262
+ ]
263
+ });
264
+ targetSourceFile.organizeImports();
265
+ }
266
+ function processStatementsRecursive(statements, initialState) {
267
+ if (statements.length === 0) {
268
+ const clauses = [];
269
+ if (initialState.pendingStateAssignment) {
270
+ const finalClause = `case ${initialState.step}: {
271
+ ${initialState.pendingStateAssignment}
29
272
  return { type: 'COMPLETE', result: undefined };
30
- }`;f.push(x)}return{clauses:f,nextStep:t.step+1}}let{syncBlock:s,durableStatement:n,nextStatements:a}=te(e),{rewrittenSyncStatements:i,newlyPersistedVariables:S}=Y(s,n?[n,...a]:[],t.persistedVariables);t.pendingStateAssignment&&i.unshift(t.pendingStateAssignment);let o=new Map([...t.persistedVariables,...S]);if(!n){let f=i.join(`
31
- `),m=s.length>0&&g.isReturnStatement(s[s.length-1])?"":`
32
- return { type: 'COMPLETE', result: undefined };`;return{clauses:[`case ${t.step}: {
33
- ${f}${m}
34
- }`],nextStep:t.step+1}}if(g.isIfStatement(n))return G(n,a,{...t,persistedVariables:o},i);if(g.isTryStatement(n))return X(n,a,{...t,persistedVariables:o},i);let{instruction:c,nextPendingStateAssignment:l}=Q(n,o);i.push(c);let r=i.join(`
35
- `),d=`case ${t.step}: {
36
- ${r}
37
- }`,p={step:t.step+1,persistedVariables:o,pendingStateAssignment:l},u=w(a,p);return{clauses:[d,...u.clauses],nextStep:u.nextStep}}function G(e,t,s,n){let a=C(e.getExpression(),s.persistedVariables),i=e.getThenStatement(),S=g.isBlock(i)?i.getStatements():[i],o=w(S,{step:s.step+1,persistedVariables:new Map(s.persistedVariables)}),c,l=e.getElseStatement();if(l){let x=g.isBlock(l)?l.getStatements():[l];c=w(x,{step:o.nextStep,persistedVariables:new Map(s.persistedVariables)})}let r=c?c.nextStep:o.nextStep,d=w(t,{step:r,persistedVariables:s.persistedVariables}),p=n.join(`
38
- `),u=o.nextStep;return{clauses:[`
39
- case ${s.step}: {
40
- ${p}
41
- if (${a}) {
42
- context.step = ${s.step+1};
273
+ }`;
274
+ clauses.push(finalClause);
275
+ }
276
+ return { clauses, nextStep: initialState.step + 1 };
277
+ }
278
+ const { syncBlock, durableStatement, nextStatements } = splitAtNextDurableCall(statements);
279
+ const { rewrittenSyncStatements, newlyPersistedVariables } = processSyncBlock(
280
+ syncBlock,
281
+ durableStatement ? [durableStatement, ...nextStatements] : [],
282
+ initialState.persistedVariables
283
+ );
284
+ if (initialState.pendingStateAssignment) {
285
+ rewrittenSyncStatements.unshift(initialState.pendingStateAssignment);
286
+ }
287
+ const updatedPersistedVariables = new Map([
288
+ ...initialState.persistedVariables,
289
+ ...newlyPersistedVariables
290
+ ]);
291
+ if (!durableStatement) {
292
+ const syncCode2 = rewrittenSyncStatements.join("\n");
293
+ const lastStatementIsReturn = syncBlock.length > 0 && Node.isReturnStatement(syncBlock[syncBlock.length - 1]);
294
+ const finalInstruction = lastStatementIsReturn ? "" : `
295
+ return { type: 'COMPLETE', result: undefined };`;
296
+ const clause = `case ${initialState.step}: {
297
+ ${syncCode2}${finalInstruction}
298
+ }`;
299
+ return { clauses: [clause], nextStep: initialState.step + 1 };
300
+ }
301
+ if (Node.isIfStatement(durableStatement)) {
302
+ return processIfStatement(
303
+ durableStatement,
304
+ nextStatements,
305
+ {
306
+ ...initialState,
307
+ persistedVariables: updatedPersistedVariables
308
+ },
309
+ rewrittenSyncStatements
310
+ );
311
+ }
312
+ if (Node.isTryStatement(durableStatement)) {
313
+ return processTryStatement(
314
+ durableStatement,
315
+ nextStatements,
316
+ { ...initialState, persistedVariables: updatedPersistedVariables },
317
+ rewrittenSyncStatements
318
+ );
319
+ }
320
+ const { instruction, nextPendingStateAssignment } = generateDurableInstruction(
321
+ durableStatement,
322
+ updatedPersistedVariables
323
+ );
324
+ rewrittenSyncStatements.push(instruction);
325
+ const syncCode = rewrittenSyncStatements.join("\n");
326
+ const currentClause = `case ${initialState.step}: {
327
+ ${syncCode}
328
+ }`;
329
+ const nextState = {
330
+ step: initialState.step + 1,
331
+ persistedVariables: updatedPersistedVariables,
332
+ pendingStateAssignment: nextPendingStateAssignment
333
+ };
334
+ const restResult = processStatementsRecursive(nextStatements, nextState);
335
+ return {
336
+ clauses: [currentClause, ...restResult.clauses],
337
+ nextStep: restResult.nextStep
338
+ };
339
+ }
340
+ function processIfStatement(ifStatement, followingStatements, currentState, rewrittenSyncStatements) {
341
+ const condition = rewriteNode(ifStatement.getExpression(), currentState.persistedVariables);
342
+ const thenBlock = ifStatement.getThenStatement();
343
+ const thenStatements = Node.isBlock(thenBlock) ? thenBlock.getStatements() : [thenBlock];
344
+ const thenResult = processStatementsRecursive(thenStatements, {
345
+ step: currentState.step + 1,
346
+ persistedVariables: new Map(currentState.persistedVariables)
347
+ // Clona para aislamiento de ramas
348
+ });
349
+ let elseResult;
350
+ const elseStatement = ifStatement.getElseStatement();
351
+ if (elseStatement) {
352
+ const elseStatements = Node.isBlock(elseStatement) ? elseStatement.getStatements() : [elseStatement];
353
+ elseResult = processStatementsRecursive(elseStatements, {
354
+ step: thenResult.nextStep,
355
+ // La rama 'else' comienza donde termina la 'then'
356
+ persistedVariables: new Map(currentState.persistedVariables)
357
+ });
358
+ }
359
+ const nextStepAfterIf = elseResult ? elseResult.nextStep : thenResult.nextStep;
360
+ const afterIfResult = processStatementsRecursive(followingStatements, {
361
+ step: nextStepAfterIf,
362
+ persistedVariables: currentState.persistedVariables
363
+ // Usa el mapa original
364
+ });
365
+ const syncCode = rewrittenSyncStatements.join("\n");
366
+ const jumpToElseStep = thenResult.nextStep;
367
+ const ifClause = `
368
+ case ${currentState.step}: {
369
+ ${syncCode}
370
+ if (${condition}) {
371
+ context.step = ${currentState.step + 1};
43
372
  } else {
44
- ${l?`context.step = ${u};`:`context.step = ${r};`}
373
+ ${elseStatement ? `context.step = ${jumpToElseStep};` : `context.step = ${nextStepAfterIf};`}
45
374
  }
46
375
  break;
47
376
  }
48
- `,...o.clauses,...c?c.clauses:[],...d.clauses],nextStep:d.nextStep}}function X(e,t,s,n){let{step:a,persistedVariables:i}=s,S=e.getTryBlock(),o=e.getCatchClause(),c=e.getFinallyBlock(),l=w(S.getStatements(),{step:a+1,persistedVariables:new Map(i)}),r,d,p=l.nextStep;if(o){let y=o.getBlock(),T=o.getVariableDeclaration();T&&(d=T.getName()),r=w(y.getStatements(),{step:p,persistedVariables:new Map(i)})}let u,f=r?r.nextStep:p;c&&(u=w(c.getStatements(),{step:f,persistedVariables:new Map(i)}));let x=u?u.nextStep:f,m=w(t,{step:x,persistedVariables:i}),h=`{ catchStep: ${o?p:"undefined"}, finallyStep: ${c?f:"undefined"} }`,P=`
49
- case ${a}: {
50
- ${n.join(`
51
- `)}
377
+ `;
378
+ return {
379
+ clauses: [
380
+ ifClause,
381
+ ...thenResult.clauses,
382
+ ...elseResult ? elseResult.clauses : [],
383
+ ...afterIfResult.clauses
384
+ ],
385
+ nextStep: afterIfResult.nextStep
386
+ };
387
+ }
388
+ function processTryStatement(tryStatement, followingStatements, currentState, rewrittenSyncStatements) {
389
+ const { step, persistedVariables } = currentState;
390
+ const tryBlock = tryStatement.getTryBlock();
391
+ const catchClause = tryStatement.getCatchClause();
392
+ const finallyBlock = tryStatement.getFinallyBlock();
393
+ const tryResult = processStatementsRecursive(tryBlock.getStatements(), {
394
+ step: step + 1,
395
+ // El bloque try comienza en el siguiente step
396
+ persistedVariables: new Map(persistedVariables)
397
+ });
398
+ let catchResult;
399
+ let catchVarName;
400
+ const catchStep = tryResult.nextStep;
401
+ if (catchClause) {
402
+ const catchBlock = catchClause.getBlock();
403
+ const varDeclaration = catchClause.getVariableDeclaration();
404
+ if (varDeclaration) {
405
+ catchVarName = varDeclaration.getName();
406
+ }
407
+ catchResult = processStatementsRecursive(catchBlock.getStatements(), {
408
+ step: catchStep,
409
+ persistedVariables: new Map(persistedVariables)
410
+ });
411
+ }
412
+ let finallyResult;
413
+ const finallyStep = catchResult ? catchResult.nextStep : catchStep;
414
+ if (finallyBlock) {
415
+ finallyResult = processStatementsRecursive(finallyBlock.getStatements(), {
416
+ step: finallyStep,
417
+ persistedVariables: new Map(persistedVariables)
418
+ });
419
+ }
420
+ const endStep = finallyResult ? finallyResult.nextStep : finallyStep;
421
+ const afterTryResult = processStatementsRecursive(followingStatements, {
422
+ step: endStep,
423
+ persistedVariables
424
+ });
425
+ const handler = `{ catchStep: ${catchClause ? catchStep : "undefined"}, finallyStep: ${finallyBlock ? finallyStep : "undefined"} }`;
426
+ const pushClause = `
427
+ case ${step}: {
428
+ ${rewrittenSyncStatements.join("\n")}
52
429
  state.tryCatchStack = state.tryCatchStack || [];
53
- state.tryCatchStack.push(${h});
54
- context.step = ${a+1}; // Salta al inicio del bloque try
430
+ state.tryCatchStack.push(${handler});
431
+ context.step = ${step + 1}; // Salta al inicio del bloque try
55
432
  break;
56
433
  }
57
- `,$=l.clauses.pop()||"",I=c?f:x;if(l.clauses.push($.replace(/return { type: 'COMPLETE'.* };/,`context.step = ${I}; break;`)),r){if(d){let T=r.clauses[0]||`case ${p}: {}`;r.clauses[0]=T.replace("{",`{
58
- const ${d} = result as Error;`)}let y=r.clauses.pop()||"";r.clauses.push(y.replace(/return { type: 'COMPLETE'.* };/,`context.step = ${I}; break;`))}if(u){let y=u.clauses.pop()||"";u.clauses.push(y.replace(/return { type: 'COMPLETE'.* };/,`state.tryCatchStack?.pop(); context.step = ${x}; break;`))}return{clauses:[P,...l.clauses,...r?r.clauses:[],...u?u.clauses:[],...m.clauses],nextStep:m.nextStep}}function Y(e,t,s){let n=[],a=new Map,i=Z(t),S=new Map(s);for(let o of e){let c=!1;if(g.isVariableStatement(o))for(let l of o.getDeclarations()){let r=l.getInitializer();if(!r)continue;let d=J(l),p=d.filter(u=>i.has(u.name));if(p.length>0){let u=C(r,s);for(let{name:f,type:x}of p){a.set(f,{type:x}),S.set(f,{type:x});let m=d.length>1?`${u}.${f}`:u;n.push(`state.${f} = ${m};`)}p.length===d.length&&(c=!0)}}c||n.push(C(o,S))}return{rewrittenSyncStatements:n,newlyPersistedVariables:a}}function J(e){let t=e.getNameNode(),s=[];if(g.isIdentifier(t)){let n=e.getType().getText(e,A);s.push({name:t.getText(),type:n})}else if(g.isObjectBindingPattern(t))for(let n of t.getElements()){let a=n.getName(),i=n.getType().getText(n,A);s.push({name:a,type:i})}return s}function Q(e,t){if(g.isReturnStatement(e))return{instruction:`return { type: 'COMPLETE', result: ${e.getExpression()?C(e.getExpressionOrThrow(),t):"undefined"} };`,nextPendingStateAssignment:void 0};let s,n=e.getFirstDescendantByKind(E.VariableDeclaration);if(n){let i=n.getName(),S=n.getType().getText(n,A);t.set(i,{type:S}),s=`state.${i} = result;`}let a=e.getFirstDescendantByKind(E.AwaitExpression);if(a){let i=a.getExpression();if(g.isCallExpression(i))return{instruction:`return ${ee(i,t)};`,nextPendingStateAssignment:s}}return{instruction:C(e,t),nextPendingStateAssignment:s}}function Z(e){let t=new Set;for(let s of e)s.getDescendantsOfKind(E.Identifier).forEach(n=>{t.add(n.getText())});return t}function C(e,t){let s=e.getProject().createSourceFile(`temp_rewrite_${Math.random()}.ts`,`const temp = ${e.getText()};`,{overwrite:!0}),n=s.getVariableDeclarationOrThrow("temp").getInitializerOrThrow(),a=[n,...n.getDescendants()].reverse();for(let c of a)if(g.isIdentifier(c)&&!c.wasForgotten()&&t.has(c.getText())){let l=c.getText(),r=c.getParent(),d=g.isVariableDeclaration(r)&&r.getNameNode()===c,p=g.isPropertyAccessExpression(r)&&r.getNameNode()===c||g.isPropertyAssignment(r)&&r.getNameNode()===c,u=g.isBindingElement(r)&&r.getNameNode()===c;if(!d&&!p&&!u){let f=t.get(l);c.replaceWithText(`(state.${l} as ${f.type})`)}}let i=s.getFullText().trim();s.forget();let S="const temp = ",o=i;return o.startsWith(S)&&(o=o.substring(S.length)),o.endsWith(";")&&(o=o.slice(0,-1)),o}function ee(e,t){let s=e.getExpression(),n,a=!1;g.isPropertyAccessExpression(s)?(s.getExpression().getText()==="context"&&(a=!0),n=s.getName()):n=s.getText();let i=e.getArguments().map(r=>C(r,t)).join(", ");if(a){if(n==="bSleep")return`{ type: 'SCHEDULE_SLEEP', duration: ${i} }`;if(n==="bWaitForEvent")return`{ type: 'WAIT_FOR_EVENT', eventName: ${i} }`;if(n==="bExecute"){let[r,d]=e.getArguments(),p=r.getText(),u=d?C(d,t):"undefined";return`{ type: 'EXECUTE_SUBWORKFLOW', workflowName: ${p}.name, input: ${u} }`}throw new Error(`Funci\xF3n de contexto durable desconocida: '${n}'.`)}let S=s.getSymbol();if(!S)throw new Error(`S\xEDmbolo no encontrado para '${n}'.`);let o=S.getDeclarations()[0]?.asKind(E.ImportSpecifier);if(!o)throw new Error(`'${n}' debe ser importada.`);let c=o.getImportDeclaration().getModuleSpecifierSourceFileOrThrow();return`{ type: 'SCHEDULE_TASK', modulePath: '${b.relative(process.cwd(),c.getFilePath()).replace(/\\/g,"/")}', exportName: '${n}', args: [${i}] }`}function N(e){for(let t of e.getDescendantsOfKind(E.AwaitExpression)){let s=t.getExpressionIfKind(E.CallExpression);if(s){let n=s.getExpression();if(g.isPropertyAccessExpression(n)){let a=n.getName();if(n.getExpression().getText()==="context"&&(a==="bSleep"||a==="bWaitForEvent"||a==="bExecute")||n.getSymbol()?.getDeclarations()[0]?.isKind(E.ImportSpecifier))return!0}else if(n.getSymbol()?.getDeclarations()[0]?.isKind(E.ImportSpecifier))return!0}}if(g.isTryStatement(e)&&(N(e.getTryBlock())||e.getCatchClause()&&N(e.getCatchClause().getBlock())||e.getFinallyBlock()&&N(e.getFinallyBlock())))return!0;if(g.isIfStatement(e)){let t=N(e.getThenStatement()),s=e.getElseStatement()?N(e.getElseStatement()):!1;return t||s}return g.isBlock(e)?e.getStatements().some(N):!1}function te(e){for(let t=0;t<e.length;t++){let s=e[t];if(g.isReturnStatement(s)||N(s)||g.isTryStatement(s))return{syncBlock:e.slice(0,t),durableStatement:s,nextStatements:e.slice(t+1)}}return{syncBlock:e,durableStatement:null,nextStatements:[]}}var W=e=>{let t=process.argv.indexOf(e);if(t!==-1&&process.argv.length>t+1)return process.argv[t+1]};async function ne(){let e=W("--in"),t=W("--out");(!e||!t)&&(console.error("Uso: b-durable-compiler --in <directorio_entrada> --out <directorio_salida>"),process.exit(1));let s=R.resolve(process.cwd(),e),n=R.resolve(process.cwd(),t);await O({inputDir:s,outputDir:n,packageName:"@bobtail.software/b-durable"})}ne().catch(e=>{console.error("Error durante la compilaci\xF3n:",e),process.exit(1)});
434
+ `;
435
+ const lastTryClause = tryResult.clauses.pop() || "";
436
+ const jumpToAfterTryStep = finallyBlock ? finallyStep : endStep;
437
+ tryResult.clauses.push(
438
+ lastTryClause.replace(
439
+ /return { type: 'COMPLETE'.* };/,
440
+ `context.step = ${jumpToAfterTryStep}; break;`
441
+ )
442
+ );
443
+ if (catchResult) {
444
+ if (catchVarName) {
445
+ const firstCatchClause = catchResult.clauses[0] || `case ${catchStep}: {}`;
446
+ catchResult.clauses[0] = firstCatchClause.replace(
447
+ "{",
448
+ `{
449
+ const ${catchVarName} = result as Error;`
450
+ );
451
+ }
452
+ const lastCatchClause = catchResult.clauses.pop() || "";
453
+ catchResult.clauses.push(
454
+ lastCatchClause.replace(
455
+ /return { type: 'COMPLETE'.* };/,
456
+ `context.step = ${jumpToAfterTryStep}; break;`
457
+ )
458
+ );
459
+ }
460
+ if (finallyResult) {
461
+ const lastFinallyClause = finallyResult.clauses.pop() || "";
462
+ finallyResult.clauses.push(
463
+ lastFinallyClause.replace(
464
+ /return { type: 'COMPLETE'.* };/,
465
+ `state.tryCatchStack?.pop(); context.step = ${endStep}; break;`
466
+ )
467
+ );
468
+ }
469
+ return {
470
+ clauses: [
471
+ pushClause,
472
+ ...tryResult.clauses,
473
+ ...catchResult ? catchResult.clauses : [],
474
+ ...finallyResult ? finallyResult.clauses : [],
475
+ ...afterTryResult.clauses
476
+ ],
477
+ nextStep: afterTryResult.nextStep
478
+ };
479
+ }
480
+ function processSyncBlock(syncBlock, followingStatements, persistedVariables) {
481
+ const rewrittenSyncStatements = [];
482
+ const newlyPersistedVariables = /* @__PURE__ */ new Map();
483
+ const usedLaterIdentifiers = findUsedIdentifiers(followingStatements);
484
+ const currentPersistedVars = new Map(persistedVariables);
485
+ for (const statement of syncBlock) {
486
+ let handledAsStatePersistence = false;
487
+ if (Node.isVariableStatement(statement)) {
488
+ for (const decl of statement.getDeclarations()) {
489
+ const initializer = decl.getInitializer();
490
+ if (!initializer) continue;
491
+ const varInfos = getVarInfoFromDeclaration(decl);
492
+ const varsToPersist = varInfos.filter(
493
+ (v) => usedLaterIdentifiers.has(v.name)
494
+ );
495
+ if (varsToPersist.length > 0) {
496
+ const rewrittenInitializer = rewriteNode(
497
+ initializer,
498
+ persistedVariables
499
+ );
500
+ for (const { name, type } of varsToPersist) {
501
+ newlyPersistedVariables.set(name, { type });
502
+ currentPersistedVars.set(name, { type });
503
+ const assignmentRightHand = varInfos.length > 1 ? `${rewrittenInitializer}.${name}` : rewrittenInitializer;
504
+ rewrittenSyncStatements.push(
505
+ `state.${name} = ${assignmentRightHand};`
506
+ );
507
+ }
508
+ if (varsToPersist.length === varInfos.length) {
509
+ handledAsStatePersistence = true;
510
+ }
511
+ }
512
+ }
513
+ }
514
+ if (!handledAsStatePersistence) {
515
+ rewrittenSyncStatements.push(rewriteNode(statement, currentPersistedVars));
516
+ }
517
+ }
518
+ return { rewrittenSyncStatements, newlyPersistedVariables };
519
+ }
520
+ function getVarInfoFromDeclaration(decl) {
521
+ const nameNode = decl.getNameNode();
522
+ const result = [];
523
+ if (Node.isIdentifier(nameNode)) {
524
+ const type = decl.getType().getText(decl, TYPE_FORMAT_FLAGS);
525
+ result.push({ name: nameNode.getText(), type });
526
+ } else if (Node.isObjectBindingPattern(nameNode)) {
527
+ for (const element of nameNode.getElements()) {
528
+ const name = element.getName();
529
+ const type = element.getType().getText(element, TYPE_FORMAT_FLAGS);
530
+ result.push({ name, type });
531
+ }
532
+ }
533
+ return result;
534
+ }
535
+ function generateDurableInstruction(statement, persistedVariables) {
536
+ if (Node.isReturnStatement(statement)) {
537
+ const returnExpr = statement.getExpression() ? rewriteNode(statement.getExpressionOrThrow(), persistedVariables) : "undefined";
538
+ return {
539
+ instruction: `return { type: 'COMPLETE', result: ${returnExpr} };`,
540
+ nextPendingStateAssignment: void 0
541
+ };
542
+ }
543
+ let nextPendingStateAssignment = void 0;
544
+ const varDecl = statement.getFirstDescendantByKind(SyntaxKind.VariableDeclaration);
545
+ if (varDecl) {
546
+ const varName = varDecl.getName();
547
+ const varType = varDecl.getType().getText(varDecl, TYPE_FORMAT_FLAGS);
548
+ persistedVariables.set(varName, { type: varType });
549
+ nextPendingStateAssignment = `state.${varName} = result;`;
550
+ }
551
+ const awaitExpression = statement.getFirstDescendantByKind(SyntaxKind.AwaitExpression);
552
+ if (awaitExpression) {
553
+ const callExpr = awaitExpression.getExpression();
554
+ if (Node.isCallExpression(callExpr)) {
555
+ return {
556
+ instruction: `return ${createInstructionForCall(callExpr, persistedVariables)};`,
557
+ nextPendingStateAssignment
558
+ };
559
+ }
560
+ }
561
+ return {
562
+ instruction: rewriteNode(statement, persistedVariables),
563
+ nextPendingStateAssignment
564
+ };
565
+ }
566
+ function findUsedIdentifiers(nodes) {
567
+ const identifiers = /* @__PURE__ */ new Set();
568
+ for (const node of nodes) {
569
+ node.getDescendantsOfKind(SyntaxKind.Identifier).forEach((ident) => {
570
+ identifiers.add(ident.getText());
571
+ });
572
+ }
573
+ return identifiers;
574
+ }
575
+ function rewriteNode(node, persistedVariables) {
576
+ const tempSourceFile = node.getProject().createSourceFile(
577
+ `temp_rewrite_${Math.random()}.ts`,
578
+ `const temp = ${node.getText()};`,
579
+ // Se envuelve para asegurar que sea un AST válido
580
+ { overwrite: true }
581
+ );
582
+ const nodeClone = tempSourceFile.getVariableDeclarationOrThrow("temp").getInitializerOrThrow();
583
+ const descendants = [nodeClone, ...nodeClone.getDescendants()].reverse();
584
+ for (const currentNode of descendants) {
585
+ if (Node.isIdentifier(currentNode) && !currentNode.wasForgotten() && persistedVariables.has(currentNode.getText())) {
586
+ const varName = currentNode.getText();
587
+ const parent = currentNode.getParent();
588
+ const isDeclaration = Node.isVariableDeclaration(parent) && parent.getNameNode() === currentNode;
589
+ const isProperty = Node.isPropertyAccessExpression(parent) && parent.getNameNode() === currentNode || Node.isPropertyAssignment(parent) && parent.getNameNode() === currentNode;
590
+ const isBindingElement = Node.isBindingElement(parent) && parent.getNameNode() === currentNode;
591
+ if (!isDeclaration && !isProperty && !isBindingElement) {
592
+ const typeInfo = persistedVariables.get(varName);
593
+ currentNode.replaceWithText(`(state.${varName} as ${typeInfo.type})`);
594
+ }
595
+ }
596
+ }
597
+ const fullText = tempSourceFile.getFullText().trim();
598
+ tempSourceFile.forget();
599
+ const prefix = "const temp = ";
600
+ let newText = fullText;
601
+ if (newText.startsWith(prefix)) {
602
+ newText = newText.substring(prefix.length);
603
+ }
604
+ if (newText.endsWith(";")) {
605
+ newText = newText.slice(0, -1);
606
+ }
607
+ return newText;
608
+ }
609
+ function createInstructionForCall(callExpr, persistedVariables) {
610
+ const identifier = callExpr.getExpression();
611
+ let functionName;
612
+ let isContextCall = false;
613
+ if (Node.isPropertyAccessExpression(identifier)) {
614
+ const expr = identifier.getExpression();
615
+ if (expr.getText() === "context") {
616
+ isContextCall = true;
617
+ }
618
+ functionName = identifier.getName();
619
+ } else {
620
+ functionName = identifier.getText();
621
+ }
622
+ const args = callExpr.getArguments().map((arg) => rewriteNode(arg, persistedVariables)).join(", ");
623
+ if (isContextCall) {
624
+ if (functionName === "bSleep") {
625
+ return `{ type: 'SCHEDULE_SLEEP', duration: ${args} }`;
626
+ }
627
+ if (functionName === "bWaitForEvent") {
628
+ return `{ type: 'WAIT_FOR_EVENT', eventName: ${args} }`;
629
+ }
630
+ if (functionName === "bExecute") {
631
+ const [workflowArg, inputArg] = callExpr.getArguments();
632
+ const subWorkflowName = workflowArg.getText();
633
+ const subWorkflowInput = inputArg ? rewriteNode(inputArg, persistedVariables) : "undefined";
634
+ return `{ type: 'EXECUTE_SUBWORKFLOW', workflowName: ${subWorkflowName}.name, input: ${subWorkflowInput} }`;
635
+ }
636
+ throw new Error(`Funci\xF3n de contexto durable desconocida: '${functionName}'.`);
637
+ }
638
+ const symbol = identifier.getSymbol();
639
+ if (!symbol) throw new Error(`S\xEDmbolo no encontrado para '${functionName}'.`);
640
+ const importSpecifier = symbol.getDeclarations()[0]?.asKind(SyntaxKind.ImportSpecifier);
641
+ if (!importSpecifier) throw new Error(`'${functionName}' debe ser importada.`);
642
+ const sourceFile = importSpecifier.getImportDeclaration().getModuleSpecifierSourceFileOrThrow();
643
+ const relativeSourcePath = path.relative(process.cwd(), sourceFile.getFilePath()).replace(/\\/g, "/");
644
+ return `{ type: 'SCHEDULE_TASK', modulePath: '${relativeSourcePath}', exportName: '${functionName}', args: [${args}] }`;
645
+ }
646
+ function hasDurableCall(node) {
647
+ for (const awaitExpr of node.getDescendantsOfKind(SyntaxKind.AwaitExpression)) {
648
+ const callExpr = awaitExpr.getExpressionIfKind(SyntaxKind.CallExpression);
649
+ if (callExpr) {
650
+ const expression = callExpr.getExpression();
651
+ if (Node.isPropertyAccessExpression(expression)) {
652
+ const propName = expression.getName();
653
+ if (expression.getExpression().getText() === "context" && (propName === "bSleep" || propName === "bWaitForEvent" || propName === "bExecute") || expression.getSymbol()?.getDeclarations()[0]?.isKind(SyntaxKind.ImportSpecifier)) {
654
+ return true;
655
+ }
656
+ } else {
657
+ if (expression.getSymbol()?.getDeclarations()[0]?.isKind(SyntaxKind.ImportSpecifier)) {
658
+ return true;
659
+ }
660
+ }
661
+ }
662
+ }
663
+ if (Node.isTryStatement(node)) {
664
+ if (hasDurableCall(node.getTryBlock())) return true;
665
+ if (node.getCatchClause() && hasDurableCall(node.getCatchClause().getBlock()))
666
+ return true;
667
+ if (node.getFinallyBlock() && hasDurableCall(node.getFinallyBlock())) return true;
668
+ }
669
+ if (Node.isIfStatement(node)) {
670
+ const thenHas = hasDurableCall(node.getThenStatement());
671
+ const elseHas = node.getElseStatement() ? hasDurableCall(node.getElseStatement()) : false;
672
+ return thenHas || elseHas;
673
+ }
674
+ if (Node.isBlock(node)) {
675
+ return node.getStatements().some(hasDurableCall);
676
+ }
677
+ return false;
678
+ }
679
+ function splitAtNextDurableCall(statements) {
680
+ for (let i = 0; i < statements.length; i++) {
681
+ const statement = statements[i];
682
+ if (Node.isReturnStatement(statement) || hasDurableCall(statement) || Node.isTryStatement(statement)) {
683
+ return {
684
+ syncBlock: statements.slice(0, i),
685
+ durableStatement: statement,
686
+ nextStatements: statements.slice(i + 1)
687
+ };
688
+ }
689
+ }
690
+ return { syncBlock: statements, durableStatement: null, nextStatements: [] };
691
+ }
692
+
693
+ // src/compiler/cli.ts
694
+ var getArg = (name) => {
695
+ const argIndex = process.argv.indexOf(name);
696
+ if (argIndex !== -1 && process.argv.length > argIndex + 1) {
697
+ return process.argv[argIndex + 1];
698
+ }
699
+ return void 0;
700
+ };
701
+ async function run() {
702
+ const inputDir = getArg("--in");
703
+ const outputDir = getArg("--out");
704
+ if (!inputDir || !outputDir) {
705
+ console.error(
706
+ "Uso: b-durable-compiler --in <directorio_entrada> --out <directorio_salida>"
707
+ );
708
+ process.exit(1);
709
+ }
710
+ const absInput = path2.resolve(process.cwd(), inputDir);
711
+ const absOutput = path2.resolve(process.cwd(), outputDir);
712
+ await compileWorkflows({
713
+ inputDir: absInput,
714
+ outputDir: absOutput,
715
+ packageName: "@bobtail.software/b-durable"
716
+ });
717
+ }
718
+ run().catch((error) => {
719
+ console.error("Error durante la compilaci\xF3n:", error);
720
+ process.exit(1);
721
+ });