UNPKG

torotask

Version:

Task queue processing in NodeJS based on BullMQ and Redis

146 lines 13.1 kB
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