@bobtail.software/b-durable 1.0.5 → 1.0.6
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/README.md +138 -163
- package/dist/compiler/cli.mjs +41 -703
- package/dist/index.d.mts +136 -18
- package/dist/index.mjs +1 -551
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
import Redis from 'ioredis';
|
|
2
2
|
import ms from 'ms';
|
|
3
3
|
|
|
4
|
+
interface Logger {
|
|
5
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
6
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
7
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
8
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
9
|
+
}
|
|
10
|
+
interface WorkflowStateInfo<TInput = unknown, TOutput = unknown> {
|
|
11
|
+
workflowId: string;
|
|
12
|
+
name: string;
|
|
13
|
+
version: string;
|
|
14
|
+
status: string;
|
|
15
|
+
step: number;
|
|
16
|
+
input: TInput;
|
|
17
|
+
output?: TOutput;
|
|
18
|
+
state: Record<string, unknown>;
|
|
19
|
+
error?: string;
|
|
20
|
+
createdAt?: number;
|
|
21
|
+
updatedAt?: number;
|
|
22
|
+
pendingTask?: {
|
|
23
|
+
name: string;
|
|
24
|
+
attempts: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
interface StartOptions<TInput, TSignals, TOutput> {
|
|
28
|
+
input: TInput;
|
|
29
|
+
workflowId?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Un callback opcional para recibir señales emitidas por el workflow en tiempo real.
|
|
32
|
+
* Se garantiza que la suscripción está activa antes de que se ejecute el primer paso.
|
|
33
|
+
*/
|
|
34
|
+
subscribe?: (signal: WorkflowSignal<TSignals, TOutput>) => void;
|
|
35
|
+
}
|
|
36
|
+
interface StartedWorkflowHandle {
|
|
37
|
+
workflowId: string;
|
|
38
|
+
/**
|
|
39
|
+
* Cierra la suscripción a las señales creada en `start`.
|
|
40
|
+
*/
|
|
41
|
+
unsubscribe: () => Promise<void>;
|
|
42
|
+
}
|
|
4
43
|
interface WorkflowState {
|
|
5
44
|
tryCatchStack?: {
|
|
6
45
|
catchStep?: number;
|
|
@@ -14,7 +53,7 @@ interface WorkflowContext<TInput = unknown> {
|
|
|
14
53
|
input: TInput;
|
|
15
54
|
state: WorkflowState;
|
|
16
55
|
result?: unknown;
|
|
17
|
-
log: (message: string) => void;
|
|
56
|
+
log: (message: string, meta?: Record<string, unknown>) => void;
|
|
18
57
|
}
|
|
19
58
|
type Instruction<TOutput = unknown> = {
|
|
20
59
|
type: 'SCHEDULE_TASK';
|
|
@@ -31,32 +70,79 @@ type Instruction<TOutput = unknown> = {
|
|
|
31
70
|
type: 'EXECUTE_SUBWORKFLOW';
|
|
32
71
|
workflowName: string;
|
|
33
72
|
input: unknown;
|
|
73
|
+
} | {
|
|
74
|
+
type: 'SEND_SIGNAL';
|
|
75
|
+
signalName: string;
|
|
76
|
+
payload: unknown;
|
|
34
77
|
} | {
|
|
35
78
|
type: 'COMPLETE';
|
|
36
79
|
result: TOutput;
|
|
37
80
|
};
|
|
38
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Representa una señal emitida por un workflow como una unión discriminada.
|
|
83
|
+
* Esto permite un estrechamiento de tipos seguro en el consumidor.
|
|
84
|
+
* Incluye las señales personalizadas (TSignals) y las señales del sistema.
|
|
85
|
+
*/
|
|
86
|
+
type WorkflowSignal<TSignals, TOutput> = {
|
|
87
|
+
[K in keyof TSignals]: {
|
|
88
|
+
name: K;
|
|
89
|
+
payload: TSignals[K];
|
|
90
|
+
};
|
|
91
|
+
}[keyof TSignals] | {
|
|
92
|
+
name: 'workflow:completed';
|
|
93
|
+
payload: TOutput;
|
|
94
|
+
} | {
|
|
95
|
+
name: 'workflow:failed';
|
|
96
|
+
payload: {
|
|
97
|
+
message: string;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Permite suscribirse a un workflow ya existente.
|
|
102
|
+
*/
|
|
103
|
+
interface WorkflowHandle<TSignals = unknown, TOutput = unknown> {
|
|
104
|
+
workflowId: string;
|
|
105
|
+
/**
|
|
106
|
+
* Se suscribe a las señales emitidas por esta instancia específica del workflow.
|
|
107
|
+
* @param onSignal Un callback fuertemente tipado que se ejecuta para cada señal.
|
|
108
|
+
* @returns Una promesa que se resuelve en un objeto con una función `unsubscribe`.
|
|
109
|
+
*/
|
|
110
|
+
subscribe: (onSignal: (signal: WorkflowSignal<TSignals, TOutput>, unsubscribe: () => void) => void) => Promise<{
|
|
111
|
+
unsubscribe: () => void;
|
|
112
|
+
}>;
|
|
113
|
+
}
|
|
114
|
+
declare class WorkflowCancellationError extends Error {
|
|
115
|
+
readonly isCancellation = true;
|
|
116
|
+
constructor(message: string);
|
|
117
|
+
}
|
|
118
|
+
interface DurableFunction<TInput = unknown, TOutput = unknown, TEvents = Record<string, never>, TSignals = Record<string, never>> {
|
|
39
119
|
__isDurable: true;
|
|
40
120
|
name: string;
|
|
121
|
+
version: string;
|
|
41
122
|
execute: (context: WorkflowContext<TInput>) => Promise<Instruction<TOutput>>;
|
|
42
123
|
_TEvents?: TEvents;
|
|
124
|
+
_TSignals?: TSignals;
|
|
43
125
|
}
|
|
44
126
|
|
|
45
|
-
interface StartOptions<TInput> {
|
|
46
|
-
input: TInput;
|
|
47
|
-
workflowId?: string;
|
|
48
|
-
}
|
|
49
127
|
declare class DurableRuntime {
|
|
50
128
|
private durableFns;
|
|
51
129
|
private repo;
|
|
52
130
|
private workerId;
|
|
53
131
|
private isRunning;
|
|
54
132
|
private schedulerInterval;
|
|
133
|
+
private heartbeatInterval;
|
|
55
134
|
private readonly sourceRoot;
|
|
135
|
+
private readonly pollingInterval;
|
|
136
|
+
private readonly logger;
|
|
137
|
+
private readonly maxTaskRetries;
|
|
56
138
|
constructor(options: {
|
|
57
139
|
sourceRoot: string;
|
|
140
|
+
retention?: ms.StringValue;
|
|
141
|
+
pollingInterval?: number;
|
|
142
|
+
logger?: Logger;
|
|
58
143
|
});
|
|
59
|
-
|
|
144
|
+
getState(workflowId: string): Promise<WorkflowStateInfo | null>;
|
|
145
|
+
start<TInput, TOutput, TEvents, TSignals>(durableFn: DurableFunction<TInput, TOutput, TEvents, TSignals>, options: StartOptions<TInput, TSignals, TOutput>, parentId?: string): Promise<StartedWorkflowHandle>;
|
|
60
146
|
private scheduleExecution;
|
|
61
147
|
private _executeStep;
|
|
62
148
|
private handleInstruction;
|
|
@@ -64,16 +150,20 @@ declare class DurableRuntime {
|
|
|
64
150
|
private resumeParentWorkflow;
|
|
65
151
|
private propagateFailureToParent;
|
|
66
152
|
sendEvent<T>(workflowId: string, eventName: string, payload: T): Promise<void>;
|
|
153
|
+
cancel(workflowId: string, reason: string): Promise<void>;
|
|
67
154
|
private startScheduler;
|
|
155
|
+
private checkSleepers;
|
|
156
|
+
private reapDeadWorkers;
|
|
157
|
+
private startHeartbeat;
|
|
68
158
|
private startWorker;
|
|
69
|
-
run(durableFns: Map<string, DurableFunction<unknown>>): void;
|
|
159
|
+
run(durableFns: Map<string, DurableFunction<unknown, unknown, any, any>>): void;
|
|
70
160
|
stop(): void;
|
|
71
161
|
}
|
|
72
162
|
|
|
73
163
|
/**
|
|
74
164
|
* El contexto de ejecución proporcionado a cada workflow, con métodos de durabilidad tipados.
|
|
75
165
|
*/
|
|
76
|
-
interface DurableContext<TEvents = Record<string, never>> extends Pick<WorkflowContext, 'log' | 'workflowId'> {
|
|
166
|
+
interface DurableContext<TEvents = Record<string, never>, TSignals = Record<string, never>> extends Pick<WorkflowContext, 'log' | 'workflowId'> {
|
|
77
167
|
/**
|
|
78
168
|
* Pausa la ejecución del workflow de manera duradera.
|
|
79
169
|
* @param duration Una cadena de tiempo como '2 days', '10h', '7s'.
|
|
@@ -92,25 +182,39 @@ interface DurableContext<TEvents = Record<string, never>> extends Pick<WorkflowC
|
|
|
92
182
|
* @param input La entrada para el sub-workflow.
|
|
93
183
|
* @returns Una promesa que se resuelve con el resultado del sub-workflow.
|
|
94
184
|
*/
|
|
95
|
-
bExecute<TInput, TOutput, TWorkflowEvents
|
|
185
|
+
bExecute<TInput, TOutput, TWorkflowEvents, TWorkflowSignals>(workflow: DurableFunction<TInput, TOutput, TWorkflowEvents, TWorkflowSignals>, input: TInput): Promise<TOutput>;
|
|
186
|
+
/**
|
|
187
|
+
* Emite una señal o notificación con un payload desde el workflow.
|
|
188
|
+
* Esta operación es duradera pero no bloquea la ejecución. El workflow continúa inmediatamente después.
|
|
189
|
+
* El nombre de la señal y el tipo del payload son validados contra el contrato de señales del workflow.
|
|
190
|
+
* @param signalName El nombre de la señal.
|
|
191
|
+
* @param payload Los datos a enviar con la señal.
|
|
192
|
+
*/
|
|
193
|
+
bSignal<K extends keyof TSignals>(signalName: K, payload: TSignals[K]): Promise<void>;
|
|
96
194
|
}
|
|
97
|
-
type DurableWorkflowFn<TInput, TOutput, TEvents = Record<string, never>> = (input: TInput, context: DurableContext<TEvents>) => Promise<TOutput>;
|
|
98
|
-
interface DurableWorkflowDef<TInput, TOutput, TEvents = Record<string, never>> {
|
|
195
|
+
type DurableWorkflowFn<TInput, TOutput, TEvents = Record<string, never>, TSignals = Record<string, never>> = (input: TInput, context: DurableContext<TEvents, TSignals>) => Promise<TOutput>;
|
|
196
|
+
interface DurableWorkflowDef<TInput, TOutput, TEvents = Record<string, never>, TSignals = Record<string, never>> {
|
|
99
197
|
/**
|
|
100
198
|
* La función async que contiene la lógica del workflow.
|
|
101
199
|
*/
|
|
102
|
-
workflow: DurableWorkflowFn<TInput, TOutput, TEvents>;
|
|
200
|
+
workflow: DurableWorkflowFn<TInput, TOutput, TEvents, TSignals>;
|
|
201
|
+
/**
|
|
202
|
+
* Versión del workflow. Se utiliza para identificar versiones de un workflow.
|
|
203
|
+
*/
|
|
204
|
+
version: string;
|
|
103
205
|
}
|
|
104
206
|
/**
|
|
105
207
|
* Marcador para que el compilador identifique y transforme una función en un workflow durable.
|
|
106
208
|
* Esta función es un passthrough en tiempo de ejecución, su único propósito es para el análisis estático.
|
|
107
209
|
*/
|
|
108
|
-
declare const bDurable: <TInput = any, TOutput = any, TEvents = Record<string, never>>(def: DurableWorkflowDef<TInput, TOutput, TEvents>) => DurableFunction<TInput, TOutput, TEvents>;
|
|
210
|
+
declare const bDurable: <TInput = any, TOutput = any, TEvents = Record<string, never>, TSignals = Record<string, never>>(def: DurableWorkflowDef<TInput, TOutput, TEvents, TSignals>) => DurableFunction<TInput, TOutput, TEvents, TSignals>;
|
|
109
211
|
|
|
110
212
|
interface BDurableAPI {
|
|
111
|
-
start: <TInput, TOutput>(durableFn: DurableFunction<TInput, TOutput>, options: StartOptions<TInput>) => Promise<
|
|
213
|
+
start: <TInput, TOutput, TEvents, TSignals>(durableFn: DurableFunction<TInput, TOutput, TEvents, TSignals>, options: StartOptions<TInput, TSignals, TOutput>) => Promise<StartedWorkflowHandle>;
|
|
112
214
|
stop: () => void;
|
|
113
215
|
runtime: DurableRuntime;
|
|
216
|
+
cancel: (workflowId: string, reason: string) => Promise<void>;
|
|
217
|
+
getState: (workflowId: string) => Promise<WorkflowStateInfo | null>;
|
|
114
218
|
/**
|
|
115
219
|
* Envía un evento a un workflow en ejecución que está en pausa esperando dicho evento.
|
|
116
220
|
* Esta función es estrictamente tipada basada en el tipo de eventos de la definición del workflow.
|
|
@@ -119,14 +223,28 @@ interface BDurableAPI {
|
|
|
119
223
|
* @param eventName El nombre del evento. Será autocompletado por el editor.
|
|
120
224
|
* @param payload La carga útil del evento. El tipo debe coincidir con el definido para `eventName`.
|
|
121
225
|
*/
|
|
122
|
-
sendEvent: <TInput, TOutput, TWorkflowEvents, K extends keyof TWorkflowEvents>(durableFn: DurableFunction<TInput, TOutput, TWorkflowEvents>, workflowId: string, eventName: K, payload: TWorkflowEvents[K]) => Promise<void>;
|
|
226
|
+
sendEvent: <TInput, TOutput, TWorkflowEvents, TSignals, K extends keyof TWorkflowEvents>(durableFn: DurableFunction<TInput, TOutput, TWorkflowEvents, TSignals>, workflowId: string, eventName: K, payload: TWorkflowEvents[K]) => Promise<void>;
|
|
227
|
+
/**
|
|
228
|
+
* Obtiene un "handle" para una instancia de workflow existente, permitiendo suscribirse a sus señales.
|
|
229
|
+
* @param durableFn La definición del workflow. Se usa para la inferencia de tipos de las señales.
|
|
230
|
+
* @param workflowId El ID de la instancia del workflow.
|
|
231
|
+
* @returns Un WorkflowHandle para la instancia especificada.
|
|
232
|
+
*/
|
|
233
|
+
getWorkflowHandle: <TInput, TOutput, TEvents, TSignals>(durableFn: DurableFunction<TInput, TOutput, TEvents, TSignals>, workflowId: string) => WorkflowHandle<TSignals, TOutput>;
|
|
123
234
|
}
|
|
124
235
|
interface InitializeOptions {
|
|
125
|
-
durableFunctions: Map<string, DurableFunction<unknown, unknown>>;
|
|
236
|
+
durableFunctions: Map<string, DurableFunction<unknown, unknown, unknown, unknown>>;
|
|
126
237
|
sourceRoot: string;
|
|
127
238
|
redisClient: Redis;
|
|
128
239
|
blockingRedisClient: Redis;
|
|
240
|
+
/**
|
|
241
|
+
* NUEVO: Período de retención para workflows completados/fallidos en Redis.
|
|
242
|
+
* Ejemplo: '7 days', '2h'. Si no se especifica, los workflows se guardan para siempre.
|
|
243
|
+
*/
|
|
244
|
+
retention?: ms.StringValue;
|
|
245
|
+
pollingInterval?: number;
|
|
246
|
+
logger?: Logger;
|
|
129
247
|
}
|
|
130
248
|
declare function bDurableInitialize(options: InitializeOptions): BDurableAPI;
|
|
131
249
|
|
|
132
|
-
export { type BDurableAPI, type DurableFunction, type Instruction, type StartOptions, type WorkflowContext, type WorkflowState, bDurable, bDurableInitialize };
|
|
250
|
+
export { type BDurableAPI, type DurableFunction, type Instruction, type Logger, type StartOptions, type StartedWorkflowHandle, WorkflowCancellationError, type WorkflowContext, type WorkflowHandle, type WorkflowSignal, type WorkflowState, type WorkflowStateInfo, bDurable, bDurableInitialize };
|