@bobtail.software/b-durable 1.0.8 → 1.0.9

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,64 +1,74 @@
1
1
  #!/usr/bin/env node
2
- import H from"path";import{existsSync as X,mkdirSync as Y,rmSync as J}from"fs";import T from"path";import*as M from"prettier";import{Node as i,Project as Q,SyntaxKind as b,ts as _,VariableDeclarationKind as z}from"ts-morph";var Z="bDurable",V=_.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope|_.TypeFormatFlags.NoTruncation;async function ee(e){let n=e.getFilePath(),o=e.getFullText(),s=await M.resolveConfig(n),a=await M.format(o,{...s,parser:"typescript"});e.replaceWithText(a)}async function U(e){console.log("Iniciando compilador de workflows duraderos...");let{inputDir:n,outputDir:o,packageName:s}=e,a=new Q({tsConfigFilePath:T.resolve(process.cwd(),"tsconfig.json")}),c=a.addSourceFilesAtPaths(`${n}/**/*.ts`);X(o)&&(console.log(`Limpiando directorio de salida: ${o}`),J(o,{recursive:!0,force:!0})),Y(o,{recursive:!0});let g=a.createDirectory(o);console.log(`Encontrados ${c.length} archivos de workflow para procesar.`);let r=[],l=[];for(let u of c){console.log(`
3
- Procesando archivo: ${u.getBaseName()}`);let t=u.getDescendantsOfKind(b.CallExpression).filter(m=>m.getExpression().getText()===Z);if(t.length!==0)for(let m of t){let p=m.getParentIfKind(b.VariableDeclaration);if(!p)continue;let d=p.getName();console.log(` -> Transformando workflow: ${d}`);let[f]=m.getArguments();if(!i.isObjectLiteralExpression(f))continue;let S=f.getProperty("workflow");if(!S||!i.isPropertyAssignment(S))continue;let x=S.getInitializer();if(!x||!i.isArrowFunction(x))continue;let D=u.getBaseName().replace(/\.ts$/,".compiled.mts"),I=T.join(g.getPath(),D),w=a.createSourceFile(I,"",{overwrite:!0});l.push(w),te(d,x,m,w,s),console.log(` -> Archivo generado: ${T.relative(process.cwd(),I)}`);let E=D;r.push({name:d,importPath:`./${E}`})}}if(r.length>0){let u=T.join(g.getPath(),"index.mts"),t=a.createSourceFile(u,"",{overwrite:!0});l.push(t),t.addStatements(`// Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.
4
- `),t.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:s,namedImports:["DurableFunction"]});for(let p of r)t.addImportDeclaration({moduleSpecifier:p.importPath,namedImports:[p.name]});t.addExportDeclaration({namedExports:r.map(p=>p.name)}),t.addStatements(`
5
- `),t.addVariableStatement({declarationKind:z.Const,declarations:[{name:"durableFunctions",type:"Map<string, DurableFunction<any, any, any, any>>",initializer:"new Map()"}]});let m=r.map(p=>`durableFunctions.set(${p.name}.name, ${p.name});`);t.addStatements(m),t.addStatements(`
6
- `),t.addExportAssignment({isExportEquals:!1,expression:"durableFunctions"}),console.log(`
7
- -> Archivo de \xEDndice generado: ${T.basename(u)}`)}console.log(`
8
- Formateando archivos generados con Prettier...`);for(let u of l)await ee(u);await a.save(),console.log(`
9
- Compilaci\xF3n completada exitosamente.`)}function te(e,n,o,s,a){let c=n.getBody();if(!i.isBlock(c))throw new Error(`El cuerpo del workflow '${e}' debe ser un bloque {}.`);let[g]=o.getArguments();if(!i.isObjectLiteralExpression(g))throw new Error("El argumento de bDurable debe ser un objeto.");let r=g.getProperty("version");if(!r||!i.isPropertyAssignment(r))throw new Error(`El workflow '${e}' debe tener una propiedad 'version'.`);let l=r.getInitializer();if(!l||!i.isStringLiteral(l))throw new Error(`La versi\xF3n del workflow '${e}' debe ser un string literal.`);let u=g.getProperty("retryOptions"),t="undefined";u&&i.isPropertyAssignment(u)&&(t=u.getInitializer()?.getText()||"undefined");let{clauses:m}=$(c.getStatements(),{step:0,persistedVariables:new Map}),p=n.getReturnType();p.getSymbol()?.getName()==="Promise"&&p.isObject()&&(p=p.getTypeArguments()[0]||p);let d=p.getText(void 0,V),f=new Set,S=n.getSourceFile(),x=o.getTypeArguments(),N=x.length>0?x[0].getText():"unknown",D=x.length>2?x[2].getText():"Record<string, never>",I=x.length>3?x[3].getText():"Record<string, never>";S.getImportDeclarations().forEach(y=>{if(y.getModuleSpecifierValue()===a)return;let h=y.getModuleSpecifierValue();if(h.includes(".workflow")){let A=T.parse(h),C=T.join(A.dir,A.base+".compiled.mts");!C.startsWith(".")&&!T.isAbsolute(C)&&(C="./"+C),h=C.replace(/\\/g,"/")}else h.startsWith(".")&&T.extname(h)===""&&(h+=".mjs");let R=[],B=[];y.getNamedImports().forEach(A=>{let C=A.getName(),j=A.getAliasNode()?.getText(),W=j?`${C} as ${j}`:C,K=(A.getNameNode().getSymbol()?.getAliasedSymbol()??A.getNameNode().getSymbol())?.getDeclarations()??[],G=K.some(O=>i.isEnumDeclaration(O));A.isTypeOnly()||!G&&K.every(O=>i.isInterfaceDeclaration(O)||i.isTypeAliasDeclaration(O))?B.push(W):R.push(W)}),R.length>0&&s.addImportDeclaration({moduleSpecifier:h,namedImports:R}),B.length>0&&s.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:h,namedImports:B});let L=y.getDefaultImport();L&&s.addImportDeclaration({moduleSpecifier:h,defaultImport:L.getText()})}),S.getInterfaces().forEach(y=>{f.add(y.getText().startsWith("export")?y.getText():`export ${y.getText()}`)}),S.getTypeAliases().forEach(y=>{f.add(y.getText().startsWith("export")?y.getText():`export ${y.getText()}`)});let[w]=n.getParameters(),E="";if(w){let y=w.getNameNode().getText();y!=="input"&&(E=`const ${y} = input;`)}s.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:a,namedImports:["DurableFunction","WorkflowContext","Instruction"]}),f.size>0&&(s.addStatements(`
10
- `),s.addStatements(Array.from(f))),s.addStatements(`
2
+ import q from"path";import{createHash as X}from"crypto";import{existsSync as K,mkdirSync as Y,readFileSync as Q,rmSync as Z,writeFileSync as ee}from"fs";import N from"path";import*as j from"prettier";import{Node as a,Project as te,SyntaxKind as P,ts as U,VariableDeclarationKind as _}from"ts-morph";var ne="bDurable",L=U.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope|U.TypeFormatFlags.NoTruncation;function se(e){return X("sha256").update(e).digest("hex")}async function re(e){let t=e.getFilePath(),o=e.getFullText(),n=await j.resolveConfig(t),i=await j.format(o,{...n,parser:"typescript"});e.replaceWithText(i)}async function H(e){console.log("Iniciando compilador de workflows duraderos...");let{inputDir:t,outputDir:o,packageName:n,mode:i}=e,c=N.resolve(process.cwd(),"durable.lock.json"),l={};if(K(c))try{l=JSON.parse(Q(c,"utf-8"))}catch(p){console.warn("Advertencia: durable.lock.json corrupto, iniciando uno nuevo.",p)}let r=new te({tsConfigFilePath:N.resolve(process.cwd(),"tsconfig.json")}),g=r.addSourceFilesAtPaths(`${t}/**/*.ts`);K(o)&&(console.log(`Limpiando directorio de salida: ${o}`),Z(o,{recursive:!0,force:!0})),Y(o,{recursive:!0});let d=r.createDirectory(o);console.log(`Encontrados ${g.length} archivos de workflow para procesar.`);let s=[],S=[],m=!1;for(let p of g){console.log(`
3
+ Procesando archivo: ${p.getBaseName()}`);let u=p.getDescendantsOfKind(P.CallExpression).filter(y=>y.getExpression().getText()===ne);if(u.length!==0)for(let y of u){let f=y.getParentIfKind(P.VariableDeclaration);if(!f)continue;let b=f.getName();console.log(` -> Transformando workflow: ${b}`);let[v]=y.getArguments();if(!a.isObjectLiteralExpression(v))continue;let I=v.getProperty("workflow");if(!I||!a.isPropertyAssignment(I))continue;let $=I.getInitializer();if(!$||!a.isArrowFunction($))continue;let w=v.getProperty("version"),h="unknown";if(w&&a.isPropertyAssignment(w)){let R=w.getInitializer();R&&a.isStringLiteral(R)&&(h=R.getLiteralValue())}let x=p.getBaseName().replace(/\.ts$/,".compiled.mts"),E=N.join(d.getPath(),x),C=r.createSourceFile(E,"",{overwrite:!0});S.push(C),oe(b,$,y,C,n);let M=C.getFullText(),F=se(M),T=l[b]?.[h];if(T)if(T!==F){if(i==="prod")throw new Error(`
4
+ \u{1F6D1} ERROR DE INTEGRIDAD (PROD) \u{1F6D1}
5
+ El workflow '${b}' (v${h}) ha cambiado, pero el lockfile no se actualiz\xF3.
6
+ Hash esperado: ${T.substring(0,8)}...
7
+ Hash actual: ${F.substring(0,8)}...
8
+
9
+ Soluci\xF3n:
10
+ 1. Incrementa la versi\xF3n en tu c\xF3digo (ej: v${h} -> v${parseFloat(h)+.1}).
11
+ 2. O ejecuta en modo dev para actualizar el lockfile: 'b-durable-compiler dev ...'
12
+ `);console.log(` \u26A0\uFE0F v${h} modificada. Actualizando hash en lockfile.`),l[b]||(l[b]={}),l[b][h]=F,m=!0}else console.log(` \u2705 v${h} verificada.`);else console.log(` \u{1F195} v${h} registrada.`),l[b]||(l[b]={}),l[b][h]=F,m=!0;console.log(` -> Archivo generado: ${N.relative(process.cwd(),E)}`);let D=x;s.push({name:b,importPath:`./${D}`})}}if(m){if(i==="prod")throw new Error("El lockfile ha cambiado durante un build de PROD. Esto no est\xE1 permitido.");ee(c,JSON.stringify(l,null,2)),console.log(`
13
+ \u{1F512} durable.lock.json actualizado.`)}if(s.length>0){let p=N.join(d.getPath(),"index.mts"),u=r.createSourceFile(p,"",{overwrite:!0});S.push(u),u.addStatements(`// Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.
14
+ `),u.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:n,namedImports:["DurableFunction"]});for(let f of s)u.addImportDeclaration({moduleSpecifier:f.importPath,namedImports:[f.name]});u.addExportDeclaration({namedExports:s.map(f=>f.name)}),u.addStatements(`
15
+ `),u.addVariableStatement({declarationKind:_.Const,declarations:[{name:"durableFunctions",type:"Map<string, DurableFunction<any, any, any, any>>",initializer:"new Map()"}]});let y=s.map(f=>`durableFunctions.set(${f.name}.name, ${f.name});`);u.addStatements(y),u.addStatements(`
16
+ `),u.addExportAssignment({isExportEquals:!1,expression:"durableFunctions"}),console.log(`
17
+ -> Archivo de \xEDndice generado: ${N.basename(p)}`)}console.log(`
18
+ Formateando archivos generados con Prettier...`);for(let p of S)await re(p);await r.save(),console.log(`
19
+ Compilaci\xF3n completada exitosamente.`)}function oe(e,t,o,n,i){let c=t.getBody();if(!a.isBlock(c))throw new Error(`El cuerpo del workflow '${e}' debe ser un bloque {}.`);let[l]=o.getArguments();if(!a.isObjectLiteralExpression(l))throw new Error("El argumento de bDurable debe ser un objeto.");let r=l.getProperty("version");if(!r||!a.isPropertyAssignment(r))throw new Error(`El workflow '${e}' debe tener una propiedad 'version'.`);let g=r.getInitializer();if(!g||!a.isStringLiteral(g))throw new Error(`La versi\xF3n del workflow '${e}' debe ser un string literal.`);let d=l.getProperty("retryOptions"),s="undefined";d&&a.isPropertyAssignment(d)&&(s=d.getInitializer()?.getText()||"undefined");let{clauses:S}=A(c.getStatements(),{step:0,persistedVariables:new Map}),m=t.getReturnType();m.getSymbol()?.getName()==="Promise"&&m.isObject()&&(m=m.getTypeArguments()[0]||m);let p=m.getText(void 0,L),u=new Set,y=t.getSourceFile(),f=o.getTypeArguments(),b=f.length>0?f[0].getText():"unknown",v=f.length>2?f[2].getText():"Record<string, never>",I=f.length>3?f[3].getText():"Record<string, never>";y.getImportDeclarations().forEach(x=>{if(x.getModuleSpecifierValue()===i)return;let E=x.getModuleSpecifierValue();if(E.includes(".workflow")){let T=N.parse(E),D=N.join(T.dir,T.base+".compiled.mts");!D.startsWith(".")&&!N.isAbsolute(D)&&(D="./"+D),E=D.replace(/\\/g,"/")}else E.startsWith(".")&&N.extname(E)===""&&(E+=".mjs");let C=[],M=[];x.getNamedImports().forEach(T=>{let D=T.getName(),R=T.getAliasNode()?.getText(),W=R?`${D} as ${R}`:D,z=(T.getNameNode().getSymbol()?.getAliasedSymbol()??T.getNameNode().getSymbol())?.getDeclarations()??[],J=z.some(B=>a.isEnumDeclaration(B));T.isTypeOnly()||!J&&z.every(B=>a.isInterfaceDeclaration(B)||a.isTypeAliasDeclaration(B))?M.push(W):C.push(W)}),C.length>0&&n.addImportDeclaration({moduleSpecifier:E,namedImports:C}),M.length>0&&n.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:E,namedImports:M});let F=x.getDefaultImport();F&&n.addImportDeclaration({moduleSpecifier:E,defaultImport:F.getText()})}),y.getInterfaces().forEach(x=>{u.add(x.getText().startsWith("export")?x.getText():`export ${x.getText()}`)}),y.getTypeAliases().forEach(x=>{u.add(x.getText().startsWith("export")?x.getText():`export ${x.getText()}`)});let[$]=t.getParameters(),w="";if($){let x=$.getNameNode().getText();x!=="input"&&(w=`const ${x} = input;`)}n.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:i,namedImports:["DurableFunction","WorkflowContext","Instruction"]}),u.size>0&&(n.addStatements(`
20
+ `),n.addStatements(Array.from(u))),n.addStatements(`
11
21
  // Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.
12
- `);let P=l.getLiteralValue(),F=`{
22
+ `);let h=g.getLiteralValue(),V=`{
13
23
  __isDurable: true,
14
24
  name: '${e}',
15
- version: '${P}',
16
- retryOptions: ${t},
17
- async execute(context: WorkflowContext<${N}>): Promise<Instruction<${d}>> {
25
+ version: '${h}',
26
+ retryOptions: ${s},
27
+ async execute(context: WorkflowContext<${b}>): Promise<Instruction<${p}>> {
18
28
  const { input, state, result, log, workflowId } = context;
19
- ${E}
29
+ ${w}
20
30
  while (true) {
21
31
  switch (context.step) {
22
- ${m.join(`
32
+ ${S.join(`
23
33
  `)}
24
34
  default:
25
35
  throw new Error(\`Paso desconocido: \${context.step}\`);
26
36
  }
27
37
  }
28
38
  }
29
- }`;s.addVariableStatement({isExported:!0,declarationKind:z.Const,declarations:[{name:e,type:`DurableFunction<${N}, ${d}, ${D}, ${I}>`,initializer:F}]}),s.organizeImports()}function $(e,n){if(e.length===0){let f=[];if(n.pendingStateAssignment){let S=`case ${n.step}: {
30
- ${n.pendingStateAssignment}
39
+ }`;n.addVariableStatement({isExported:!0,declarationKind:_.Const,declarations:[{name:e,type:`DurableFunction<${b}, ${p}, ${v}, ${I}>`,initializer:V}]}),n.organizeImports()}function A(e,t){if(e.length===0){let u=[];if(t.pendingStateAssignment){let y=`case ${t.step}: {
40
+ ${t.pendingStateAssignment}
31
41
  return { type: 'COMPLETE', result: undefined };
32
- }`;f.push(S)}return{clauses:f,nextStep:n.step+1}}let{syncBlock:o,durableStatement:s,nextStatements:a}=le(e),{rewrittenSyncStatements:c,newlyPersistedVariables:g}=re(o,s?[s,...a]:[],n.persistedVariables);n.pendingStateAssignment&&c.unshift(n.pendingStateAssignment);let r=new Map([...n.persistedVariables,...g]);if(!s){let f=c.join(`
33
- `),x=o.length>0&&i.isReturnStatement(o[o.length-1])?"":`
34
- return { type: 'COMPLETE', result: undefined };`;return{clauses:[`case ${n.step}: {
35
- ${f}${x}
36
- }`],nextStep:n.step+1}}if(i.isIfStatement(s))return ne(s,a,{...n,persistedVariables:r},c);if(i.isTryStatement(s))return se(s,a,{...n,persistedVariables:r},c);let{instruction:l,nextPendingStateAssignment:u}=ae(s,r);c.push(l);let t=c.join(`
37
- `),m=`case ${n.step}: {
38
- ${t}
39
- }`,p={step:n.step+1,persistedVariables:r,pendingStateAssignment:u},d=$(a,p);return{clauses:[m,...d.clauses],nextStep:d.nextStep}}function ne(e,n,o,s){let a=k(e.getExpression(),o.persistedVariables),c=e.getThenStatement(),g=i.isBlock(c)?c.getStatements():[c],r=$(g,{step:o.step+1,persistedVariables:new Map(o.persistedVariables)}),l,u=e.getElseStatement();if(u){let S=i.isBlock(u)?u.getStatements():[u];l=$(S,{step:r.nextStep,persistedVariables:new Map(o.persistedVariables)})}let t=l?l.nextStep:r.nextStep,m=$(n,{step:t,persistedVariables:o.persistedVariables}),p=s.join(`
40
- `),d=r.nextStep;return{clauses:[`
42
+ }`;u.push(y)}return{clauses:u,nextStep:t.step+1}}let{syncBlock:o,durableStatement:n,nextStatements:i}=de(e),{rewrittenSyncStatements:c,newlyPersistedVariables:l}=ce(o,n?[n,...i]:[],t.persistedVariables);t.pendingStateAssignment&&c.unshift(t.pendingStateAssignment);let r=new Map([...t.persistedVariables,...l]);if(!n){let u=c.join(`
43
+ `),f=o.length>0&&a.isReturnStatement(o[o.length-1])?"":`
44
+ return { type: 'COMPLETE', result: undefined };`;return{clauses:[`case ${t.step}: {
45
+ ${u}${f}
46
+ }`],nextStep:t.step+1}}if(a.isIfStatement(n))return ae(n,i,{...t,persistedVariables:r},c);if(a.isTryStatement(n))return ie(n,i,{...t,persistedVariables:r},c);let{instruction:g,nextPendingStateAssignment:d}=pe(n,r);c.push(g);let s=c.join(`
47
+ `),S=`case ${t.step}: {
48
+ ${s}
49
+ }`,m={step:t.step+1,persistedVariables:r,pendingStateAssignment:d},p=A(i,m);return{clauses:[S,...p.clauses],nextStep:p.nextStep}}function ae(e,t,o,n){let i=k(e.getExpression(),o.persistedVariables),c=e.getThenStatement(),l=a.isBlock(c)?c.getStatements():[c],r=A(l,{step:o.step+1,persistedVariables:new Map(o.persistedVariables)}),g,d=e.getElseStatement();if(d){let y=a.isBlock(d)?d.getStatements():[d];g=A(y,{step:r.nextStep,persistedVariables:new Map(o.persistedVariables)})}let s=g?g.nextStep:r.nextStep,S=A(t,{step:s,persistedVariables:o.persistedVariables}),m=n.join(`
50
+ `),p=r.nextStep;return{clauses:[`
41
51
  case ${o.step}: {
42
- ${p}
43
- if (${a}) {
52
+ ${m}
53
+ if (${i}) {
44
54
  context.step = ${o.step+1};
45
55
  } else {
46
- ${u?`context.step = ${d};`:`context.step = ${t};`}
56
+ ${d?`context.step = ${p};`:`context.step = ${s};`}
47
57
  }
48
58
  break;
49
59
  }
50
- `,...r.clauses,...l?l.clauses:[],...m.clauses],nextStep:m.nextStep}}function se(e,n,o,s){let{step:a,persistedVariables:c}=o,g=e.getTryBlock(),r=e.getCatchClause(),l=e.getFinallyBlock(),u=$(g.getStatements(),{step:a+1,persistedVariables:new Map(c)}),t,m,p=u.nextStep;if(r){let E=r.getBlock(),P=r.getVariableDeclaration();P&&(m=P.getName()),t=$(E.getStatements(),{step:p,persistedVariables:new Map(c)})}let d,f=t?t.nextStep:p;l&&(d=$(l.getStatements(),{step:f,persistedVariables:new Map(c)}));let S=d?d.nextStep:f,x=$(n,{step:S,persistedVariables:c}),N=`{ catchStep: ${r?p:"undefined"}, finallyStep: ${l?f:"undefined"} }`,D=`
51
- case ${a}: {
52
- ${s.join(`
60
+ `,...r.clauses,...g?g.clauses:[],...S.clauses],nextStep:S.nextStep}}function ie(e,t,o,n){let{step:i,persistedVariables:c}=o,l=e.getTryBlock(),r=e.getCatchClause(),g=e.getFinallyBlock(),d=A(l.getStatements(),{step:i+1,persistedVariables:new Map(c)}),s,S,m=d.nextStep;if(r){let w=r.getBlock(),h=r.getVariableDeclaration();h&&(S=h.getName()),s=A(w.getStatements(),{step:m,persistedVariables:new Map(c)})}let p,u=s?s.nextStep:m;g&&(p=A(g.getStatements(),{step:u,persistedVariables:new Map(c)}));let y=p?p.nextStep:u,f=A(t,{step:y,persistedVariables:c}),b=`{ catchStep: ${r?m:"undefined"}, finallyStep: ${g?u:"undefined"} }`,v=`
61
+ case ${i}: {
62
+ ${n.join(`
53
63
  `)}
54
64
  state.tryCatchStack = state.tryCatchStack || [];
55
- state.tryCatchStack.push(${N});
56
- context.step = ${a+1}; // Salta al inicio del bloque try
65
+ state.tryCatchStack.push(${b});
66
+ context.step = ${i+1}; // Salta al inicio del bloque try
57
67
  break;
58
68
  }
59
- `,I=u.clauses.pop()||"",w=l?f:S;if(u.clauses.push(I.replace(/return { type: 'COMPLETE'.* };/,`context.step = ${w}; break;`)),t){if(m){let P=t.clauses[0]||`case ${p}: {}`;t.clauses[0]=P.replace("{",`{
60
- const ${m} = result as unknown;`)}let E=t.clauses.pop()||"";t.clauses.push(E.replace(/return { type: 'COMPLETE'.* };/,`context.step = ${w}; break;`))}if(d){let E=d.clauses.pop()||"";d.clauses.push(E.replace(/return { type: 'COMPLETE'.* };/,`state.tryCatchStack?.pop(); context.step = ${S}; break;`))}return{clauses:[D,...u.clauses,...t?t.clauses:[],...d?d.clauses:[],...x.clauses],nextStep:x.nextStep}}function re(e,n,o){let s=[],a=new Map,c=ie(n),g=new Map(o);for(let r of e){if(i.isVariableStatement(r))for(let u of r.getDeclarations()){let t=u.getInitializer();if(!t)continue;let m=oe(u),p=m.filter(d=>c.has(d.name));if(p.length>0){let d=k(t,o);for(let{name:f,type:S}of p){a.set(f,{type:S}),g.set(f,{type:S});let x=m.length>1?`${d}.${f}`:d;s.push(`state.${f} = ${x};`)}}}s.push(k(r,g))}return{rewrittenSyncStatements:s,newlyPersistedVariables:a}}function oe(e){let n=e.getNameNode(),o=[];if(i.isIdentifier(n)){let s=e.getType().getText(e,V);o.push({name:n.getText(),type:s})}else if(i.isObjectBindingPattern(n))for(let s of n.getElements()){let a=s.getName(),c=s.getType().getText(s,V);o.push({name:a,type:c})}return o}function ae(e,n){if(i.isReturnStatement(e))return{instruction:`return { type: 'COMPLETE', result: ${e.getExpression()?k(e.getExpressionOrThrow(),n):"undefined"} };`,nextPendingStateAssignment:void 0};if(e.getDescendantsOfKind(b.AwaitExpression).length>1)throw new Error(`[b-durable Compiler Error] Multiple 'await' expressions found in a single statement at line ${e.getStartLineNumber()}.
61
- Please split them into separate lines/variables to ensure safe state persistence.`);let s,a=e.getFirstDescendantByKind(b.VariableDeclaration);if(a){let g=a.getName(),r=a.getType().getText(a,V);n.set(g,{type:r}),s=`state.${g} = result;`}let c=e.getFirstDescendantByKind(b.AwaitExpression);if(c){let g=c.getParent();if(!(i.isExpressionStatement(g)||i.isVariableDeclaration(g)||i.isCallExpression(g)&&i.isExpressionStatement(g.getParent()))&&a&&a.getInitializer()!==c)throw new Error(`[b-durable Compiler Error] Complex 'await' usage detected at line ${e.getStartLineNumber()}.
69
+ `,I=d.clauses.pop()||"",$=g?u:y;if(d.clauses.push(I.replace(/return { type: 'COMPLETE'.* };/,`context.step = ${$}; break;`)),s){if(S){let h=s.clauses[0]||`case ${m}: {}`;s.clauses[0]=h.replace("{",`{
70
+ const ${S} = result as unknown;`)}let w=s.clauses.pop()||"";s.clauses.push(w.replace(/return { type: 'COMPLETE'.* };/,`context.step = ${$}; break;`))}if(p){let w=p.clauses.pop()||"";p.clauses.push(w.replace(/return { type: 'COMPLETE'.* };/,`state.tryCatchStack?.pop(); context.step = ${y}; break;`))}return{clauses:[v,...d.clauses,...s?s.clauses:[],...p?p.clauses:[],...f.clauses],nextStep:f.nextStep}}function ce(e,t,o){let n=[],i=new Map,c=ue(t),l=new Map(o);for(let r of e){if(a.isVariableStatement(r))for(let d of r.getDeclarations()){let s=d.getInitializer();if(!s)continue;let S=le(d),m=S.filter(p=>c.has(p.name));if(m.length>0){let p=k(s,o);for(let{name:u,type:y}of m){i.set(u,{type:y}),l.set(u,{type:y});let f=S.length>1?`${p}.${u}`:p;n.push(`state.${u} = ${f};`)}}}n.push(k(r,l))}return{rewrittenSyncStatements:n,newlyPersistedVariables:i}}function le(e){let t=e.getNameNode(),o=[];if(a.isIdentifier(t)){let n=e.getType().getText(e,L);o.push({name:t.getText(),type:n})}else if(a.isObjectBindingPattern(t))for(let n of t.getElements()){let i=n.getName(),c=n.getType().getText(n,L);o.push({name:i,type:c})}return o}function pe(e,t){if(a.isReturnStatement(e))return{instruction:`return { type: 'COMPLETE', result: ${e.getExpression()?k(e.getExpressionOrThrow(),t):"undefined"} };`,nextPendingStateAssignment:void 0};if(e.getDescendantsOfKind(P.AwaitExpression).length>1)throw new Error(`[b-durable Compiler Error] Multiple 'await' expressions found in a single statement at line ${e.getStartLineNumber()}.
71
+ Please split them into separate lines/variables to ensure safe state persistence.`);let n,i=e.getFirstDescendantByKind(P.VariableDeclaration);if(i){let l=i.getName(),r=i.getType().getText(i,L);t.set(l,{type:r}),n=`state.${l} = result;`}let c=e.getFirstDescendantByKind(P.AwaitExpression);if(c){let l=c.getParent();if(!(a.isExpressionStatement(l)||a.isVariableDeclaration(l)||a.isCallExpression(l)&&a.isExpressionStatement(l.getParent()))&&i&&i.getInitializer()!==c)throw new Error(`[b-durable Compiler Error] Complex 'await' usage detected at line ${e.getStartLineNumber()}.
62
72
  The 'await' keyword must be the direct value of the assignment.
63
73
  Invalid: const x = 1 + await foo();
64
- Valid: const temp = await foo(); const x = 1 + temp;`);let l=c.getExpression();if(i.isCallExpression(l))return{instruction:`return ${ce(l,n)};`,nextPendingStateAssignment:s}}return{instruction:k(e,n),nextPendingStateAssignment:s}}function ie(e){let n=new Set;for(let o of e)o.getDescendantsOfKind(b.Identifier).forEach(s=>{n.add(s.getText())});return n}function k(e,n){let o=e.getText(),s=e.getStart(),a=[],c=e.getDescendantsOfKind(b.Identifier);i.isIdentifier(e)&&c.push(e),c.forEach(r=>{let l=r.getText();if(!n.has(l))return;let u=r.getSymbol();if(u&&u.getDeclarations().some(y=>y.getStart()>=e.getStart()&&y.getEnd()<=e.getEnd()))return;let t=r.getParent(),m=i.isVariableDeclaration(t)&&t.getNameNode()===r,p=i.isPropertyAccessExpression(t)&&t.getNameNode()===r||i.isPropertyAssignment(t)&&t.getNameNode()===r,d=i.isBindingElement(t)&&t.getNameNode()===r,f=i.isShorthandPropertyAssignment(t)&&t.getNameNode()===r,S=i.isParameterDeclaration(t)&&t.getNameNode()===r,x=i.isFunctionDeclaration(t)&&t.getNameNode()===r,N=i.isClassDeclaration(t)&&t.getNameNode()===r,D=i.isInterfaceDeclaration(t)&&t.getNameNode()===r,I=i.isTypeAliasDeclaration(t)&&t.getNameNode()===r,w=i.isEnumDeclaration(t)&&t.getNameNode()===r,E=i.isMethodDeclaration(t)&&t.getNameNode()===r;if(!m&&!p&&!d&&!S&&!x&&!N&&!D&&!I&&!w&&!E){let P=n.get(l),F=r.getStart()-s,y=r.getEnd()-s,h=`(state.${l} as ${P.type})`;f&&(h=`${l}: ${h}`),a.push({start:F,end:y,text:h})}}),a.sort((r,l)=>l.start-r.start);let g=o;for(let{start:r,end:l,text:u}of a)g=g.substring(0,r)+u+g.substring(l);return g}function ce(e,n){let o=e.getExpression(),s,a=!1;i.isPropertyAccessExpression(o)?(o.getExpression().getText()==="context"&&(a=!0),s=o.getName()):s=o.getText();let c=e.getArguments().map(t=>k(t,n)).join(", ");if(a)switch(s){case"bSleep":return`{ type: 'SCHEDULE_SLEEP', duration: ${c} }`;case"bWaitForEvent":return`{ type: 'WAIT_FOR_SIGNAL', signalName: ${c} }`;case"bExecute":{let[t,m]=e.getArguments(),p=t.getText(),d=m?k(m,n):"undefined";return`{ type: 'EXECUTE_SUBWORKFLOW', workflowName: ${p}.name, input: ${d} }`}case"bSignal":{let[t,m]=e.getArguments().map(p=>k(p,n));return`{ type: 'EMIT_EVENT', eventName: ${t}, payload: ${m} }`}default:throw new Error(`Funci\xF3n de contexto durable desconocida: '${s}'.`)}let g=o.getSymbol();if(!g)throw new Error(`S\xEDmbolo no encontrado para '${s}'.`);let r=g.getDeclarations()[0]?.asKind(b.ImportSpecifier);if(!r)throw new Error(`'${s}' debe ser importada.`);let l=r.getImportDeclaration().getModuleSpecifierSourceFileOrThrow();return`{ type: 'SCHEDULE_TASK', modulePath: '${T.relative(process.cwd(),l.getFilePath()).replace(/\\/g,"/")}', exportName: '${s}', args: [${c}] }`}function v(e){for(let n of e.getDescendantsOfKind(b.AwaitExpression)){let o=n.getExpressionIfKind(b.CallExpression);if(o){let s=o.getExpression();if(i.isPropertyAccessExpression(s)){let a=s.getName();if(s.getExpression().getText()==="context"&&(a==="bSleep"||a==="bWaitForEvent"||a==="bExecute"||a==="bSignal")||s.getSymbol()?.getDeclarations()[0]?.isKind(b.ImportSpecifier))return!0}else if(s.getSymbol()?.getDeclarations()[0]?.isKind(b.ImportSpecifier))return!0}}if(i.isTryStatement(e)&&(v(e.getTryBlock())||e.getCatchClause()&&v(e.getCatchClause().getBlock())||e.getFinallyBlock()&&v(e.getFinallyBlock())))return!0;if(i.isIfStatement(e)){let n=v(e.getThenStatement()),o=e.getElseStatement()?v(e.getElseStatement()):!1;return n||o}return i.isBlock(e)?e.getStatements().some(v):!1}function le(e){for(let n=0;n<e.length;n++){let o=e[n];if(i.isReturnStatement(o)||v(o)||i.isTryStatement(o))return{syncBlock:e.slice(0,n),durableStatement:o,nextStatements:e.slice(n+1)}}return{syncBlock:e,durableStatement:null,nextStatements:[]}}var q=e=>{let n=process.argv.indexOf(e);if(n!==-1&&process.argv.length>n+1)return process.argv[n+1]};async function pe(){let e=q("--in"),n=q("--out");(!e||!n)&&(console.error("Uso: b-durable-compiler --in <directorio_entrada> --out <directorio_salida>"),process.exit(1));let o=H.resolve(process.cwd(),e),s=H.resolve(process.cwd(),n);await U({inputDir:o,outputDir:s,packageName:"@bobtail.software/b-durable"})}pe().catch(e=>{console.error("Error durante la compilaci\xF3n:",e),process.exit(1)});
74
+ Valid: const temp = await foo(); const x = 1 + temp;`);let g=c.getExpression();if(a.isCallExpression(g))return{instruction:`return ${ge(g,t)};`,nextPendingStateAssignment:n}}return{instruction:k(e,t),nextPendingStateAssignment:n}}function ue(e){let t=new Set;for(let o of e)o.getDescendantsOfKind(P.Identifier).forEach(n=>{t.add(n.getText())});return t}function k(e,t){let o=e.getText(),n=e.getStart(),i=[],c=e.getDescendantsOfKind(P.Identifier);a.isIdentifier(e)&&c.push(e),c.forEach(r=>{let g=r.getText();if(!t.has(g))return;let d=r.getSymbol();if(d&&d.getDeclarations().some(x=>x.getStart()>=e.getStart()&&x.getEnd()<=e.getEnd()))return;let s=r.getParent(),S=a.isVariableDeclaration(s)&&s.getNameNode()===r,m=a.isPropertyAccessExpression(s)&&s.getNameNode()===r||a.isPropertyAssignment(s)&&s.getNameNode()===r,p=a.isBindingElement(s)&&s.getNameNode()===r,u=a.isShorthandPropertyAssignment(s)&&s.getNameNode()===r,y=a.isParameterDeclaration(s)&&s.getNameNode()===r,f=a.isFunctionDeclaration(s)&&s.getNameNode()===r,b=a.isClassDeclaration(s)&&s.getNameNode()===r,v=a.isInterfaceDeclaration(s)&&s.getNameNode()===r,I=a.isTypeAliasDeclaration(s)&&s.getNameNode()===r,$=a.isEnumDeclaration(s)&&s.getNameNode()===r,w=a.isMethodDeclaration(s)&&s.getNameNode()===r;if(!S&&!m&&!p&&!y&&!f&&!b&&!v&&!I&&!$&&!w){let h=t.get(g),V=r.getStart()-n,x=r.getEnd()-n,E=`(state.${g} as ${h.type})`;u&&(E=`${g}: ${E}`),i.push({start:V,end:x,text:E})}}),i.sort((r,g)=>g.start-r.start);let l=o;for(let{start:r,end:g,text:d}of i)l=l.substring(0,r)+d+l.substring(g);return l}function ge(e,t){let o=e.getExpression(),n,i=!1;a.isPropertyAccessExpression(o)?(o.getExpression().getText()==="context"&&(i=!0),n=o.getName()):n=o.getText();let c=e.getArguments().map(s=>k(s,t)).join(", ");if(i)switch(n){case"bSleep":return`{ type: 'SCHEDULE_SLEEP', duration: ${c} }`;case"bWaitForEvent":return`{ type: 'WAIT_FOR_SIGNAL', signalName: ${c} }`;case"bExecute":{let[s,S]=e.getArguments(),m=s.getText(),p=S?k(S,t):"undefined";return`{ type: 'EXECUTE_SUBWORKFLOW', workflowName: ${m}.name, input: ${p} }`}case"bSignal":{let[s,S]=e.getArguments().map(m=>k(m,t));return`{ type: 'EMIT_EVENT', eventName: ${s}, payload: ${S} }`}default:throw new Error(`Funci\xF3n de contexto durable desconocida: '${n}'.`)}let l=o.getSymbol();if(!l)throw new Error(`S\xEDmbolo no encontrado para '${n}'.`);let r=l.getDeclarations()[0]?.asKind(P.ImportSpecifier);if(!r)throw new Error(`'${n}' debe ser importada.`);let g=r.getImportDeclaration().getModuleSpecifierSourceFileOrThrow();return`{ type: 'SCHEDULE_TASK', modulePath: '${N.relative(process.cwd(),g.getFilePath()).replace(/\\/g,"/")}', exportName: '${n}', args: [${c}] }`}function O(e){for(let t of e.getDescendantsOfKind(P.AwaitExpression)){let o=t.getExpressionIfKind(P.CallExpression);if(o){let n=o.getExpression();if(a.isPropertyAccessExpression(n)){let i=n.getName();if(n.getExpression().getText()==="context"&&(i==="bSleep"||i==="bWaitForEvent"||i==="bExecute"||i==="bSignal")||n.getSymbol()?.getDeclarations()[0]?.isKind(P.ImportSpecifier))return!0}else if(n.getSymbol()?.getDeclarations()[0]?.isKind(P.ImportSpecifier))return!0}}if(a.isTryStatement(e)&&(O(e.getTryBlock())||e.getCatchClause()&&O(e.getCatchClause().getBlock())||e.getFinallyBlock()&&O(e.getFinallyBlock())))return!0;if(a.isIfStatement(e)){let t=O(e.getThenStatement()),o=e.getElseStatement()?O(e.getElseStatement()):!1;return t||o}return a.isBlock(e)?e.getStatements().some(O):!1}function de(e){for(let t=0;t<e.length;t++){let o=e[t];if(a.isReturnStatement(o)||O(o)||a.isTryStatement(o))return{syncBlock:e.slice(0,t),durableStatement:o,nextStatements:e.slice(t+1)}}return{syncBlock:e,durableStatement:null,nextStatements:[]}}var G=e=>{let t=process.argv.indexOf(e);if(t!==-1&&process.argv.length>t+1)return process.argv[t+1]};async function me(){let e=G("--in"),t=G("--out"),n=process.argv.slice(2).includes("dev")?"dev":"prod";(!e||!t)&&(console.error("Uso: b-durable-compiler <dev|prod> --in <src> --out <generated>"),process.exit(1));let i=q.resolve(process.cwd(),e),c=q.resolve(process.cwd(),t);await H({inputDir:i,outputDir:c,packageName:"@bobtail.software/b-durable",mode:n})}me().catch(e=>{console.error("Error durante la compilaci\xF3n:",e),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobtail.software/b-durable",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "main": "dist/index.mjs",
5
5
  "types": "dist/index.d.mts",
6
6
  "description": "A system for creating durable, resilient, and type-safe workflows in JavaScript/TypeScript.",