torotask
Version:
Task queue processing in NodeJS based on BullMQ and Redis
146 lines • 13.1 kB
TypeScript
import type { StringValue } from 'ms';
import type { Task } from './task.js';
import type { StepInnerString, StepTaskJobOptions, TaskDefForGroup, TaskFlowRun, TaskFlowRunNode, TaskGroupDefinitionRegistry, TaskKeysForGroup, TaskPayloadFromDef, TaskResultFromDef } from './types/index.js';
import { TaskJob } from './job.js';
export declare class StepExecutor<JobType extends TaskJob = TaskJob, TAllTaskGroupsDefs extends TaskGroupDefinitionRegistry = TaskGroupDefinitionRegistry, TCurrentJobGroup extends keyof TAllTaskGroupsDefs = never, TJobPayload = JobType extends TaskJob<infer P, any, any> ? P : unknown, TJobResult = JobType extends TaskJob<any, infer R, any> ? R : unknown> {
private job;
private parentTask;
private logger;
private stepCounts;
private client;
constructor(job: JobType, parentTask: Task<TJobPayload, TJobResult, any>);
private persistState;
/**
* Process step result before storing it in the job state.
* This method automatically prepares TaskJob instances ready for serialization.
* Recursively processes arrays and objects to find and serialize any TaskJob instances.
*
* @param result The result from a step's core logic
* @param stepKind The kind of step that produced this result
* @returns A processed version of the result suitable for storage
*/
protected memoizeStepResult<T>(result: T, stepKind: string): Promise<any>;
/**
* Checks if the memoized data is a job that needs to be reconstructed.
* Recursively processes arrays and objects to find and reconstruct any serialized jobs.
*
* @param memoizedData The data from the memoized result
* @param userStepId The ID of the step for logging purposes
* @returns The original data or a reconstructed job
*/
protected reconstructJobIfNeeded<T>(memoizedData: any, userStepId: string): Promise<T>;
/**
* Handles recovery for steps that were waiting for a child job.
* Checks the actual child job state and returns result or throws error.
*/
private _handleChildJobRecovery;
/**
* Centralized method to execute a step, handling memoization, state persistence, and errors.
* @param userStepId User-defined ID for the step.
* @param stepKind A string identifier for the kind of step (e.g., 'do', 'sleep').
* @param coreLogic The async function that performs the actual work of the step.
* If it initiates a pending state (e.g., sleep, wait), it should:
* 1. Update \`this.job.state.stepState\` with the new status (e.g., 'sleeping').
* 2. Call \`await this.persistState()\`.
* 3. Throw a \`WorkflowPendingError\` (e.g., \`DelayedError\`).
* If it completes successfully, it returns the result.
* If it fails with an unexpected error, it throws that error.
* @param handleMemoizedState Optional handler for memoized states that are not 'completed' or 'errored'.
* Used for re-evaluating pending states (e.g., checking if sleep duration has passed).
* If it handles the state, it should return \`{ processed: true, ... }\`.
* If the step completes, it must update state and persist.
* @param memoizeStepResult Optional function to customize how the step result is serialized before storage.
* If not provided, the default memoizeStepResult method will be used.
*/
private _executeStep;
do<T>(userStepId: string, handler: () => Promise<T>): Promise<T>;
sleep(userStepId: string, duration: number | StringValue): Promise<void>;
sleepUntil(userStepId: string, datetime: Date | string | number): Promise<void>;
_runGroupTask<TPayload, TJob>(taskName: StepInnerString, payload: TPayload, options?: StepTaskJobOptions): Promise<TJob>;
runGroupTask<TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, TCurrentJobGroup>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>, TJob extends TaskJob<TaskPayloadFromDef<TDef>, Result> = TaskJob<TaskPayloadFromDef<TDef>, Result>>(userStepId: string, taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<TJob>;
runGroupTaskStateless<TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, TCurrentJobGroup>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>, TJob extends TaskJob<TaskPayloadFromDef<TDef>, Result> = TaskJob<TaskPayloadFromDef<TDef>, Result>>(taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<TJob>;
_runGroupTaskAndWait<TPayload, TResult>(taskName: StepInnerString, payload: TPayload, options?: StepTaskJobOptions): Promise<{
job: TaskJob<TPayload, TResult>;
result: TResult;
}>;
/**
* Helper to start a group task without waiting - used for recovery scenarios
*/
_startGroupTask<TPayload, TResult>(taskName: StepInnerString, payload: TPayload, options?: StepTaskJobOptions): Promise<TaskJob<TPayload, TResult>>;
runGroupTaskAndWait<TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, TCurrentJobGroup>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>>(userStepId: string, taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<Result>;
runGroupTaskAndWaitStateless<TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, TCurrentJobGroup>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, TCurrentJobGroup, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>>(taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<Result>;
_runTask<Payload, TJob>(groupName: StepInnerString, taskName: StepInnerString, payload: Payload, options?: StepTaskJobOptions): Promise<TJob>;
runTask<GroupName extends keyof TAllTaskGroupsDefs, TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, GroupName>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>, TJob extends TaskJob<TaskPayloadFromDef<TDef>, Result> = TaskJob<TaskPayloadFromDef<TDef>, Result>>(userStepId: string, groupName: GroupName, taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<TJob>;
runTaskStateless<GroupName extends keyof TAllTaskGroupsDefs, TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, GroupName>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>, TJob extends TaskJob<TaskPayloadFromDef<TDef>, Result> = TaskJob<TaskPayloadFromDef<TDef>, Result>>(groupName: GroupName, taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<TJob>;
/**
* Helper to start a cross-group task without waiting - used for recovery scenarios
*/
_startTask<Payload, Result>(groupName: StepInnerString, taskName: StepInnerString, payload: Payload, options?: StepTaskJobOptions): Promise<TaskJob<Payload, Result>>;
/**
* Helper for stateless runTaskAndWait - starts job and waits
*/
_runTaskAndWait<Payload, Result>(groupName: StepInnerString, taskName: StepInnerString, payload: Payload, options?: StepTaskJobOptions): Promise<{
job: TaskJob<Payload, Result>;
result: Result;
}>;
runTaskAndWait<GroupName extends keyof TAllTaskGroupsDefs, TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, GroupName>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>>(userStepId: string, groupName: GroupName, taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<Result>;
runTaskAndWaitStateless<GroupName extends keyof TAllTaskGroupsDefs, TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, GroupName>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>>(groupName: GroupName, taskName: TaskName, payload: TaskPayloadFromDef<TDef>, options?: StepTaskJobOptions): Promise<Result>;
_runTasks<ActualPayload, TJob>(groupName: StepInnerString, taskName: StepInnerString, tasks: Array<{
name?: string;
payload?: ActualPayload;
options?: StepTaskJobOptions;
}>, options?: StepTaskJobOptions): Promise<TJob[]>;
runTasks<GroupName extends keyof TAllTaskGroupsDefs, TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, GroupName>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>, TJob extends TaskJob<TaskPayloadFromDef<TDef>, Result> = TaskJob<TaskPayloadFromDef<TDef>, Result>>(userStepId: string, groupName: GroupName, taskName: TaskName, tasks: Array<{
name?: string;
payload?: TaskPayloadFromDef<TDef>;
options?: StepTaskJobOptions;
}>, options?: StepTaskJobOptions): Promise<TJob[]>;
runTasksStateless<GroupName extends keyof TAllTaskGroupsDefs, TaskName extends TaskKeysForGroup<TAllTaskGroupsDefs, GroupName>, TDef extends TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName> = TaskDefForGroup<TAllTaskGroupsDefs, GroupName, TaskName>, Result extends TaskResultFromDef<TDef> = TaskResultFromDef<TDef>, TJob extends TaskJob<TaskPayloadFromDef<TDef>, Result> = TaskJob<TaskPayloadFromDef<TDef>, Result>>(groupName: GroupName, taskName: TaskName, tasks: Array<{
name?: string;
payload?: TaskPayloadFromDef<TDef>;
options?: StepTaskJobOptions;
}>, options?: StepTaskJobOptions): Promise<TJob[]>;
_runFlow(task: TaskFlowRun<TAllTaskGroupsDefs>, options?: StepTaskJobOptions): Promise<TaskFlowRunNode>;
runFlow(userStepId: string, task: TaskFlowRun<TAllTaskGroupsDefs>, options?: StepTaskJobOptions): Promise<TaskFlowRunNode>;
runFlowStateless(task: TaskFlowRun<TAllTaskGroupsDefs>, options?: StepTaskJobOptions): Promise<TaskFlowRunNode>;
_runFlows(tasks: TaskFlowRun<TAllTaskGroupsDefs>[], options?: StepTaskJobOptions): Promise<TaskFlowRunNode[]>;
runFlows(userStepId: string, tasks: TaskFlowRun<TAllTaskGroupsDefs>[], options?: StepTaskJobOptions): Promise<TaskFlowRunNode[]>;
runFlowsStateless(tasks: TaskFlowRun<TAllTaskGroupsDefs>[], options?: StepTaskJobOptions): Promise<TaskFlowRunNode[]>;
waitForChildTasks(userStepId: string): Promise<any[]>;
_sendEvent(eventName: string, eventData: any): Promise<void>;
sendEvent(userStepId: string, eventName: string, eventData: any): Promise<void>;
sendEventStateless(eventName: string, eventData: any): Promise<void>;
/**
* Gets the typed result of a completed child task.
* Returns undefined if the job hasn't completed yet.
*
* Use this after `waitForChildTasks()` to retrieve the return value from a job
* that was started with `runTask()`.
*
* @param job The TaskJob returned from runTask()
* @returns The typed return value, or undefined if the job hasn't completed
*
* @example
* ```ts
* const childJob = await step.runTask('start-child', 'groupName', 'taskName', payload);
* await step.waitForChildTasks('wait-for-children');
* const result = await step.getTaskResult(childJob); // string | undefined
* ```
*/
getTaskResult<TResult>(job: TaskJob<any, TResult>): Promise<TResult | undefined>;
/**
* Waits for a child task to complete and returns its typed result.
* Use this when you want to wait for a specific child task without using `waitForChildTasks()`.
*
* @param job The TaskJob returned from runTask()
* @returns The typed return value
*
* @example
* ```ts
* const childJob = await step.runTask('start-child', 'groupName', 'taskName', payload);
* const result = await step.waitForTaskResult(childJob); // Waits and returns string
* ```
*/
waitForTaskResult<TResult>(job: TaskJob<any, TResult>): Promise<TResult>;
}
//# sourceMappingURL=step-executor.d.ts.map