@bobtail.software/b-durable 1.0.0 → 1.0.2
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/compiler/cli.mjs +51 -35
- package/dist/index.d.mts +16 -4
- package/dist/index.mjs +1 -1
- package/package.json +2 -4
package/dist/compiler/cli.mjs
CHANGED
|
@@ -1,37 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
Procesando archivo: ${
|
|
4
|
-
`),
|
|
5
|
-
`),
|
|
6
|
-
`),
|
|
7
|
-
-> Archivo de \xEDndice generado: ${
|
|
8
|
-
Compilaci\xF3n completada exitosamente.`)}function
|
|
9
|
-
|
|
10
|
-
${K}
|
|
11
|
-
return ${v};
|
|
12
|
-
}`,d++,e="";let D=i.getFirstDescendantByKind(F.VariableDeclaration);if(D){let y=D.getName(),b=D.getTypeNode()?.getText()??D.getInitializerOrThrow().getType().getText();l.set(y,{type:b}),e=`state.${y} = result;
|
|
13
|
-
`}}else if(m.isReturnStatement(i)){let u=A(e,l,n),h=I(i.getExpressionOrThrow(),l,n);g+=`
|
|
14
|
-
case ${d}: {
|
|
15
|
-
${u}
|
|
16
|
-
return { type: 'COMPLETE', result: ${h} };
|
|
17
|
-
}`,d++,e=""}else e+=i.getText()+`
|
|
18
|
-
`}if(e.trim()!==""){let i=A(e,l,n);g+=`
|
|
19
|
-
case ${d}: {
|
|
20
|
-
${i}
|
|
21
|
-
return { type: 'COMPLETE', result: undefined };
|
|
22
|
-
}`}let[w]=o.getParameters(),f=new Set,N="{}",S="unknown",E=o.getSourceFile();if(E.getInterfaces().forEach(i=>{f.add(i.getFullText())}),E.getTypeAliases().forEach(i=>{f.add(i.getFullText())}),w){N=w.getNameNode().getText();let i=w.getTypeNode();if(i){S=i.getText();let x=i.getType().getSymbol();if(x)for(let u of x.getDeclarations())m.isInterfaceDeclaration(u)||m.isTypeAliasDeclaration(u)?f.add(u.getFullText()):m.isImportSpecifier(u)&&f.add(u.getImportDeclaration().getFullText())}}s.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:c,namedImports:["DurableFunction","WorkflowContext","Instruction"]}),f.size>0&&(s.addStatements(`
|
|
23
|
-
`),s.addStatements(Array.from(f))),s.addStatements(`
|
|
2
|
+
import W from"path";import{existsSync as Z,mkdirSync as V,rmSync as ee}from"fs";import y from"path";import{Node as g,Project as te,SyntaxKind as $,VariableDeclarationKind as K}from"ts-morph";var ne="bDurable";async function j(e){console.log("Iniciando compilador de workflows duraderos...");let{inputDir:t,outputDir:n,packageName:o}=e,r=new te({tsConfigFilePath:y.resolve(process.cwd(),"tsconfig.json")}),a=r.addSourceFilesAtPaths(`${t}/**/*.ts`);Z(n)&&(console.log(`Limpiando directorio de salida: ${n}`),ee(n,{recursive:!0,force:!0})),V(n,{recursive:!0});let l=r.createDirectory(n);console.log(`Encontrados ${a.length} archivos de workflow para procesar.`);let i=[];for(let c of a){console.log(`
|
|
3
|
+
Procesando archivo: ${c.getBaseName()}`);let s=c.getDescendantsOfKind($.CallExpression).filter(d=>d.getExpression().getText()===ne);if(s.length!==0)for(let d of s){let u=d.getParentIfKind($.VariableDeclaration);if(!u)continue;let x=u.getName();console.log(` -> Transformando workflow: ${x}`);let[S]=d.getArguments();if(!g.isArrowFunction(S))continue;let m=c.getBaseName().replace(/\.ts$/,".compiled.mts"),p=y.join(l.getPath(),m),T=r.createSourceFile(p,"",{overwrite:!0});oe(x,S,r,o,T),console.log(` -> Archivo generado: ${y.relative(process.cwd(),p)}`);let f=m;i.push({name:x,importPath:`./${f}`})}}if(i.length>0){let c=y.join(l.getPath(),"index.mts"),s=r.createSourceFile(c,"",{overwrite:!0});s.addStatements(`// Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.
|
|
4
|
+
`),s.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:o,namedImports:["DurableFunction"]});for(let u of i)s.addImportDeclaration({moduleSpecifier:u.importPath,namedImports:[u.name]});s.addExportDeclaration({namedExports:i.map(u=>u.name)}),s.addStatements(`
|
|
5
|
+
`),s.addVariableStatement({declarationKind:K.Const,declarations:[{name:"durableFunctions",type:"Map<string, DurableFunction<any, any>>",initializer:"new Map()"}]});let d=i.map(u=>`durableFunctions.set(${u.name}.name, ${u.name});`);s.addStatements(d),s.addStatements(`
|
|
6
|
+
`),s.addExportAssignment({isExportEquals:!1,expression:"durableFunctions"}),console.log(`
|
|
7
|
+
-> Archivo de \xEDndice generado: ${y.basename(c)}`)}await r.save(),console.log(`
|
|
8
|
+
Compilaci\xF3n completada exitosamente.`)}function oe(e,t,n,o,r){let a=t.getBody();if(!g.isBlock(a))throw new Error(`El cuerpo del workflow '${e}' debe ser un bloque {}.`);let l=new Map,{clauses:i}=F(a.getStatements(),0,l,n,o,""),[c]=t.getParameters(),s=t.getParameters()[1],u=s&&s.getName()==="context"?"const { log, workflowId } = context;":"",x=`Awaited<${t.getReturnType().getText()}>`,S=new Set,w="{}",m="unknown",p=t.getSourceFile();if(p.getInterfaces().forEach(f=>{S.add(f.getFullText())}),p.getTypeAliases().forEach(f=>{S.add(f.getFullText())}),c){w=c.getNameNode().getText();let f=c.getTypeNode();f&&(m=f.getText())}r.addImportDeclaration({isTypeOnly:!0,moduleSpecifier:o,namedImports:["DurableFunction","WorkflowContext","Instruction"]}),S.size>0&&(r.addStatements(`
|
|
9
|
+
`),r.addStatements(Array.from(S))),r.addStatements(`
|
|
24
10
|
// Este archivo fue generado autom\xE1ticamente. NO EDITAR MANUALMENTE.
|
|
25
|
-
`);let
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
11
|
+
`);let T=`{
|
|
12
|
+
__isDurable: true,
|
|
13
|
+
name: '${e}',
|
|
14
|
+
async execute(context: WorkflowContext<${m}>): Promise<Instruction<${x}>> {
|
|
15
|
+
const { input, state, result } = context;
|
|
16
|
+
${u}
|
|
17
|
+
const ${w} = input;
|
|
18
|
+
switch (context.step) {
|
|
19
|
+
${i.join(`
|
|
20
|
+
`)}
|
|
21
|
+
default:
|
|
22
|
+
throw new Error(\`Paso desconocido: \${context.step}\`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}`;r.addVariableStatement({isExported:!0,declarationKind:K.Const,declarations:[{name:e,type:`DurableFunction<${m}, ${x}>`,initializer:T}]})}function F(e,t,n,o,r,a){if(e.length===0)return{clauses:[],nextStep:t};let{syncBlock:l,durableStatement:i,nextStatements:c}=v(e),s=a+l.map(m=>E(m,n,o)).join(`
|
|
26
|
+
`);if(!i)return{clauses:[`case ${t}: {
|
|
27
|
+
${s}
|
|
28
|
+
return { type: 'COMPLETE', result: undefined };
|
|
29
|
+
}`],nextStep:t+1};let d="",u=i.getFirstDescendantByKind($.VariableDeclaration);if(u){let m=u.getName(),p=u.getTypeNode()?.getText()??u.getInitializerOrThrow().getType().getText();n.set(m,{type:p}),d=`state.${m} = result;`}if(g.isIfStatement(i)){let m=E(i.getExpression(),n,o),p=`__branch_step_${t}`,T=L(i.getThenStatement()),f=i.getElseStatement(),I=f?L(f):[],{syncBlock:z,durableStatement:B,nextStatements:H}=v(T),{syncBlock:q,durableStatement:M,nextStatements:G}=v(I),J=z.map(D=>E(D,n,o)).join(`
|
|
30
|
+
`),Q=B?A(B,n,o,r):'return { type: "COMPLETE", result: undefined };',k=`if (${m}) {
|
|
31
|
+
${J}
|
|
32
|
+
state.${p} = 0;
|
|
33
|
+
${Q}
|
|
34
|
+
}`;if(I.length>0){let D=q.map(N=>E(N,n,o)).join(`
|
|
35
|
+
`),C=M?A(M,n,o,r):'return { type: "COMPLETE", result: undefined };';k+=` else {
|
|
36
|
+
${D}
|
|
37
|
+
state.${p} = 1;
|
|
38
|
+
${C}
|
|
39
|
+
}`}let X=`case ${t}: {
|
|
40
|
+
${s}
|
|
41
|
+
${k}
|
|
42
|
+
}`,O=F(H,t+1,new Map(n),o,r,d),_=F(G,t+1,new Map(n),o,r,d),b=[];if(O.clauses.length>0||_.clauses.length>0){let D=O.clauses.map(h=>h.replace(/^case \d+:\s*{/,"")).map(h=>h.replace(/}\s*$/,"")).join(`
|
|
43
|
+
`),C=_.clauses.map(h=>h.replace(/^case \d+:\s*{/,"")).map(h=>h.replace(/}\s*$/,"")).join(`
|
|
44
|
+
`),N=`case ${t+1}: {
|
|
45
|
+
if (state.${p} === 0) {
|
|
46
|
+
${D}
|
|
47
|
+
} else {
|
|
48
|
+
${C}
|
|
49
|
+
}
|
|
50
|
+
}`;b.push(N)}let Y=t+1+(b.length>0?1:0),R=F(c,Y,n,o,r,"");return{clauses:[X,...b,...R.clauses],nextStep:R.nextStep}}let x=A(i,n,o,r),S=`case ${t}: {
|
|
51
|
+
${s}
|
|
52
|
+
${x}
|
|
53
|
+
}`,w=F(c,t+1,n,o,r,d);return{clauses:[S,...w.clauses],nextStep:w.nextStep}}function P(e){if(e.getDescendantsOfKind($.AwaitExpression).length>0)return!0;if(g.isIfStatement(e)){let t=P(e.getThenStatement()),n=e.getElseStatement()?P(e.getElseStatement()):!1;return t||n}return g.isBlock(e)?e.getStatements().some(P):!1}function L(e){return g.isBlock(e)?e.getStatements():[e]}function v(e){for(let t=0;t<e.length;t++){let n=e[t];if(g.isReturnStatement(n)||P(n))return{syncBlock:e.slice(0,t),durableStatement:n,nextStatements:e.slice(t+1)}}return{syncBlock:e,durableStatement:null,nextStatements:[]}}function A(e,t,n,o){if(g.isReturnStatement(e))return`return { type: 'COMPLETE', result: ${e.getExpression()?E(e.getExpressionOrThrow(),t,n):"undefined"} };`;let r=e.getFirstDescendantByKind($.AwaitExpression);if(r){let a=r.getExpression();if(g.isCallExpression(a))return`return ${re(a,t,n,o)};`}throw new Error(`No se pudo generar una instrucci\xF3n para el statement: ${e.getText()}`)}function re(e,t,n,o){let r=e.getExpression(),a=r.getText(),l=e.getArguments().map(d=>E(d,t,n)).join(", "),i=r.getSymbol();if(!i)throw new Error(`S\xEDmbolo no encontrado para '${a}'.`);let c=i.getDeclarations()[0]?.asKind($.ImportSpecifier);if(!c)throw new Error(`'${a}' debe ser importada.`);if(c.getImportDeclaration().getModuleSpecifierValue()===o){if(a==="bSleep")return`{ type: 'SCHEDULE_SLEEP', duration: ${l} }`;if(a==="bWaitForEvent")return`{ type: 'WAIT_FOR_EVENT', eventName: ${l} }`;throw new Error(`Funci\xF3n desconocida '${a}' importada desde '${o}'.`)}else{let d=c.getImportDeclaration().getModuleSpecifierSourceFileOrThrow();return`{ type: 'SCHEDULE_TASK', modulePath: '${y.relative(process.cwd(),d.getFilePath()).replace(/\\/g,"/")}', exportName: '${a}', args: [${l}] }`}}function E(e,t,n){let o=e.getProject().createSourceFile("temp_rewrite.ts",e.getText(),{overwrite:!0}).getChildAtIndex(0),r=[o,...o.getDescendants()];for(let l of r.reverse())if(g.isIdentifier(l)&&!l.wasForgotten()){let i=l.getText();if(t.has(i)){let c=t.get(i);if(c){let s=l.getParent();if(s&&g.isPropertyAccessExpression(s)&&s.getNameNode()===l||s&&g.isPropertyAssignment(s)&&s.getNameNode()===l)continue;l.replaceWithText(`(state.${i} as ${c.type})`)}}}let a=o.getSourceFile().getFullText();return o.getSourceFile().forget(),a}var U=e=>{let t=process.argv.indexOf(e);if(t!==-1&&process.argv.length>t+1)return process.argv[t+1]};async function se(){let e=U("--in"),t=U("--out");(!e||!t)&&(console.error("Uso: b-durable-compiler --in <directorio_entrada> --out <directorio_salida>"),process.exit(1));let n=W.resolve(process.cwd(),e),o=W.resolve(process.cwd(),t);await j({inputDir:n,outputDir:o,packageName:"@bobtail.software/b-durable"})}se().catch(e=>{console.error("Error durante la compilaci\xF3n:",e),process.exit(1)});
|
package/dist/index.d.mts
CHANGED
|
@@ -17,6 +17,9 @@ type Instruction<TOutput = unknown> = {
|
|
|
17
17
|
} | {
|
|
18
18
|
type: 'SCHEDULE_SLEEP';
|
|
19
19
|
duration: ms.StringValue;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'WAIT_FOR_EVENT';
|
|
22
|
+
eventName: string;
|
|
20
23
|
} | {
|
|
21
24
|
type: 'COMPLETE';
|
|
22
25
|
result: TOutput;
|
|
@@ -36,9 +39,10 @@ declare class DurableRuntime {
|
|
|
36
39
|
constructor(options: {
|
|
37
40
|
sourceRoot: string;
|
|
38
41
|
});
|
|
39
|
-
start<TInput, TOutput>(durableFn: DurableFunction<TInput, TOutput>, input: TInput): Promise
|
|
42
|
+
start<TInput, TOutput>(durableFn: DurableFunction<TInput, TOutput>, input: TInput): Promise<`${string}-${string}-${string}-${string}-${string}`>;
|
|
40
43
|
private executeStep;
|
|
41
44
|
private handleInstruction;
|
|
45
|
+
sendEvent<T>(workflowId: string, eventName: string, payload: T): Promise<void>;
|
|
42
46
|
private startScheduler;
|
|
43
47
|
private startWorker;
|
|
44
48
|
run(durableFns: Map<string, DurableFunction<unknown>>): void;
|
|
@@ -59,12 +63,20 @@ declare const bDurable: <TInput, TOutput>(fn: DurableWorkflowFn<TInput, TOutput>
|
|
|
59
63
|
* en una instrucción para el runtime. No se ejecuta directamente.
|
|
60
64
|
* @param duration Una cadena de tiempo como '2 days', '10h', '7s'.
|
|
61
65
|
*/
|
|
62
|
-
declare function
|
|
66
|
+
declare function bSleep(duration: ms.StringValue): Promise<void>;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Pausa la ejecución del workflow hasta que se reciba un evento externo.
|
|
70
|
+
* @param eventName El nombre único del evento que se está esperando.
|
|
71
|
+
* @returns Una promesa que se resuelve con el payload del evento recibido.
|
|
72
|
+
*/
|
|
73
|
+
declare function bWaitForEvent<T>(eventName: string): Promise<T>;
|
|
63
74
|
|
|
64
75
|
interface BDurableAPI {
|
|
65
|
-
start: <TInput, TOutput>(durableFn: DurableFunction<TInput, TOutput>, input: TInput) => Promise<
|
|
76
|
+
start: <TInput, TOutput>(durableFn: DurableFunction<TInput, TOutput>, input: TInput) => Promise<string>;
|
|
66
77
|
stop: () => void;
|
|
67
78
|
runtime: DurableRuntime;
|
|
79
|
+
sendEvent: <T>(workflowId: string, eventName: string, payload: T) => Promise<void>;
|
|
68
80
|
}
|
|
69
81
|
interface InitializeOptions {
|
|
70
82
|
durableFunctions: Map<string, DurableFunction<unknown, unknown>>;
|
|
@@ -74,4 +86,4 @@ interface InitializeOptions {
|
|
|
74
86
|
}
|
|
75
87
|
declare function bDurableInitialize(options: InitializeOptions): BDurableAPI;
|
|
76
88
|
|
|
77
|
-
export { type BDurableAPI, type DurableFunction, type Instruction, type WorkflowContext, bDurable, bDurableInitialize,
|
|
89
|
+
export { type BDurableAPI, type DurableFunction, type Instruction, type WorkflowContext, bDurable, bDurableInitialize, bSleep, bWaitForEvent };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var r,c;function g(i){if(r||c){console.warn("[Persistence] Los clientes de Redis ya han sido configurados. Omitiendo.");return}r=i.commandClient,c=i.blockingClient}import{randomUUID as m}from"crypto";import I from"ms";import{resolve as h}from"path";var d="queue:tasks",w="durable:sleepers";var u={RUNNING:"RUNNING",SLEEPING:"SLEEPING",COMPLETED:"COMPLETED",FAILED:"FAILED",AWAITING_EVENT:"AWAITING_EVENT"};var p=class{durableFns=new Map;isWorkerRunning=!1;isSchedulerRunning=!1;schedulerInterval=null;sourceRoot;constructor(t){this.sourceRoot=t.sourceRoot}async start(t,a){let o=m();console.log(`[RUNTIME] Iniciando workflow '${t.name}' con ID: ${o}`);let e={workflowId:o,name:t.name,status:u.RUNNING,step:"0",input:JSON.stringify(a),state:JSON.stringify({})};return await r.hset(`workflow:${o}`,e),await this.executeStep(o,t),o}async executeStep(t,a,o){let e=await r.hgetall(`workflow:${t}`);if(!e||e.status!=="RUNNING")return;let n={workflowId:t,step:parseInt(e.step,10),input:JSON.parse(e.input),state:JSON.parse(e.state),result:o,log:s=>{console.log(`[WF:${t}] ${s}`)}};try{let s=await a.execute(n);await this.handleInstruction(s,n)}catch(s){console.error(`[RUNTIME] Error en workflow ${t} en el paso ${n.step}:`,s);let l={status:u.FAILED,error:s instanceof Error?s.message:String(s)};await r.hset(`workflow:${t}`,l)}}async handleInstruction(t,a){let{workflowId:o,state:e}=a;switch(await r.hset(`workflow:${o}`,"state",JSON.stringify(e)),t.type){case"SCHEDULE_TASK":{console.log(`[RUNTIME] Workflow ${o} agend\xF3 la tarea '${t.exportName}'.`);let n={workflowId:o,durableFunctionName:await r.hget(`workflow:${o}`,"name"),modulePath:t.modulePath,exportName:t.exportName,args:t.args};await r.lpush(d,JSON.stringify(n));break}case"SCHEDULE_SLEEP":{let n=I(t.duration),s=Date.now()+n;console.log(`[RUNTIME] Workflow ${o} en pausa por ${t.duration}. Despertar\xE1 en ${new Date(s).toISOString()}`),await r.hset(`workflow:${o}`,"status","SLEEPING"),await r.zadd(w,s.toString(),o);break}case"WAIT_FOR_EVENT":{console.log(`[RUNTIME] Workflow ${o} en pausa, esperando el evento '${t.eventName}'.`),await r.hset(`workflow:${o}`,{status:u.AWAITING_EVENT,awaitingEvent:t.eventName}),await r.sadd(`events:awaiting:${t.eventName}`,o);break}case"COMPLETE":{console.log(`[RUNTIME] Workflow ${o} completado.`);let n={status:"COMPLETED",result:JSON.stringify(t.result),step:(a.step+1).toString()};await r.hset(`workflow:${o}`,n);break}}}async sendEvent(t,a,o){let e=`workflow:${t}`,n=await r.hgetall(e);if(!n.status){console.warn(`[RUNTIME] Intento de enviar evento a un workflow no existente: ${t}`);return}if(n.status!==u.AWAITING_EVENT||n.awaitingEvent!==a){console.warn(`[RUNTIME] El workflow ${t} no est\xE1 esperando el evento '${a}'. Estado actual: ${n.status}.`);return}console.log(`[RUNTIME] Evento '${a}' recibido para el workflow ${t}. Reanudando...`);let s=n.name,l=this.durableFns.get(s);l&&(await r.hset(e,"status",u.RUNNING),await r.hdel(e,"awaitingEvent"),await r.srem(`events:awaiting:${a}`,t),await r.hincrby(e,"step",1),await this.executeStep(t,l,o))}startScheduler(){if(this.isSchedulerRunning)return;this.isSchedulerRunning=!0,console.log("[SCHEDULER] Scheduler iniciado.");let t=async()=>{let a=Date.now(),o=await r.zrangebyscore(w,0,a);if(o.length>0){console.log(`[SCHEDULER] Despertando ${o.length} workflow(s)...`),await r.zrem(w,...o);for(let e of o){let n=await r.hget(`workflow:${e}`,"name");if(!n){console.error(`[SCHEDULER] No se pudo encontrar el nombre del workflow para el ID ${e}. Saltando.`);continue}let s=this.durableFns.get(n);if(!s){console.error(`[SCHEDULER] El workflow '${n}' (ID: ${e}) no est\xE1 registrado en este worker. Saltando.`);continue}console.log(`[SCHEDULER] Reanudando workflow ${e}`),await r.hset(`workflow:${e}`,"status","RUNNING"),await r.hincrby(`workflow:${e}`,"step",1),await this.executeStep(e,s,null)}}};this.schedulerInterval=setInterval(t,2e3)}startWorker(){if(this.isWorkerRunning)return;this.isWorkerRunning=!0,console.log("[WORKER] Worker iniciado, esperando tareas..."),(async()=>{for(;this.isWorkerRunning;)try{let a=await c.brpop(d,0);if(a){let[,o]=a,e=JSON.parse(o);console.log(`[WORKER] Tarea recibida: ${e.exportName}`);try{let n=e.modulePath.startsWith("virtual:")?e.modulePath:h(this.sourceRoot,e.modulePath);console.log(`[WORKER] Importando m\xF3dulo desde: ${n}`);let l=(await import(n))[e.exportName];if(typeof l!="function")throw new Error(`La exportaci\xF3n '${e.exportName}' no es una funci\xF3n en '${e.modulePath}'.`);let E=await l(...e.args),k=`workflow:${e.workflowId}`;await r.hincrby(k,"step",1);let f=this.durableFns.get(e.durableFunctionName);f&&await this.executeStep(e.workflowId,f,E)}catch(n){console.error(`[WORKER] Falla en la tarea '${e.exportName}' para el workflow ${e.workflowId}. Marcando como FAILED.`);let s={status:u.FAILED,error:n instanceof Error?n.message:String(n)};await r.hset(`workflow:${e.workflowId}`,s)}}}catch(a){if(a instanceof Error&&a.message.includes("Connection is closed")){console.log("[WORKER] Conexi\xF3n de bloqueo cerrada.");break}console.error("[WORKER] Error de infraestructura:",a)}})()}run(t){this.durableFns=t,this.startWorker(),this.startScheduler()}stop(){this.isWorkerRunning=!1,this.isSchedulerRunning=!1,this.schedulerInterval&&clearInterval(this.schedulerInterval),console.log("[RUNTIME] Solicitando detenci\xF3n...")}};var b=i=>i;function T(i){throw new Error(`The "bSleep" function can only be called inside a "bDurable" workflow. ${i}`)}function R(i){throw new Error(`The "bWaitForEvent" function can only be called inside a "bDurable" workflow. Waiting for "${i}".`)}function L(i){console.log("--- Inicializando Sistema Durable ---"),g({commandClient:i.redisClient,blockingClient:i.blockingRedisClient});let t=new p({sourceRoot:i.sourceRoot});return t.run(i.durableFunctions),{start:t.start.bind(t),sendEvent:t.sendEvent.bind(t),stop:t.stop.bind(t),runtime:t}}export{b as bDurable,L as bDurableInitialize,T as bSleep,R as bWaitForEvent};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobtail.software/b-durable",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
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.",
|
|
@@ -23,13 +23,11 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"ioredis": "^5.8.2",
|
|
25
25
|
"ms": "^2.1.3",
|
|
26
|
-
"ts-morph": "^27.0.2"
|
|
27
|
-
"uuid": "^13.0.0"
|
|
26
|
+
"ts-morph": "^27.0.2"
|
|
28
27
|
},
|
|
29
28
|
"devDependencies": {
|
|
30
29
|
"@types/ms": "^2.1.0",
|
|
31
30
|
"@types/node": "^24.10.0",
|
|
32
|
-
"@types/uuid": "^11.0.0",
|
|
33
31
|
"tsup": "^8.5.0",
|
|
34
32
|
"typescript": "^5.9.3",
|
|
35
33
|
"vitest": "^4.0.7"
|