UNPKG

durable-execution-orpc-utils

Version:

oRPC utilities for durable-execution to create a separate server process for durable execution

162 lines 4.99 kB
// src/index.ts import { safe, toORPCError } from "@orpc/client"; import { ORPCError } from "@orpc/contract"; import { type } from "@orpc/server"; import { DurableExecutionError, DurableExecutionNotFoundError } from "durable-execution"; import { getErrorMessage } from "@gpahal/std/errors"; function createEnqueueTaskProcedure(osBuilder, executor, tasks) { return osBuilder.input( type() ).output(type()).handler(async ({ input }) => { const task = tasks[input.taskId]; if (!task) { throw new ORPCError("NOT_FOUND", { message: `Task ${input.taskId} not found` }); } try { const handle = await executor.enqueueTask( task, input.input, input.options ); return handle.executionId; } catch (error) { if (error instanceof DurableExecutionError) { if (error instanceof DurableExecutionNotFoundError) { throw new ORPCError("NOT_FOUND", { message: error.message }); } throw new ORPCError(error.isInternal ? "INTERNAL_SERVER_ERROR" : "BAD_REQUEST", { message: error.message }); } throw new ORPCError("INTERNAL_SERVER_ERROR", { message: getErrorMessage(error) }); } }); } function createGetTaskExecutionProcedure(osBuilder, executor, tasks) { return osBuilder.input( type() ).output(type()).handler(async ({ input }) => { const task = tasks[input.taskId]; if (!task) { throw new ORPCError("NOT_FOUND", { message: `Task ${input.taskId} not found` }); } try { const handle = await executor.getTaskExecutionHandle(task, input.executionId); return await handle.getExecution(); } catch (error) { if (error instanceof DurableExecutionError) { if (error instanceof DurableExecutionNotFoundError) { throw new ORPCError("NOT_FOUND", { message: error.message }); } throw new ORPCError(error.isInternal ? "INTERNAL_SERVER_ERROR" : "BAD_REQUEST", { message: error.message }); } throw new ORPCError("INTERNAL_SERVER_ERROR", { message: getErrorMessage(error) }); } }); } function createWakeupSleepingTaskExecutionProcedure(osBuilder, executor, tasks) { return osBuilder.input( type() ).output(type()).handler(async ({ input }) => { const task = tasks[input.taskId]; if (!task) { throw new ORPCError("NOT_FOUND", { message: `Task ${input.taskId} not found` }); } if (task.taskType !== "sleepingTask") { throw new ORPCError("BAD_REQUEST", { message: `Task ${input.taskId} is not a sleeping task` }); } try { return await executor.wakeupSleepingTaskExecution( task, input.sleepingTaskUniqueId, input.options ); } catch (error) { if (error instanceof DurableExecutionError) { if (error instanceof DurableExecutionNotFoundError) { throw new ORPCError("NOT_FOUND", { message: error.message }); } throw new ORPCError(error.isInternal ? "INTERNAL_SERVER_ERROR" : "BAD_REQUEST", { message: error.message }); } throw new ORPCError("INTERNAL_SERVER_ERROR", { message: getErrorMessage(error) }); } }); } function createTasksRouter(osBuilder, executor, tasks) { return { enqueueTask: createEnqueueTaskProcedure(osBuilder, executor, tasks), getTaskExecution: createGetTaskExecutionProcedure(osBuilder, executor, tasks), wakeupSleepingTaskExecution: createWakeupSleepingTaskExecutionProcedure( osBuilder, executor, tasks ) }; } var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]); function convertProcedureClientToTask(executor, taskOptions, procedure, ...rest) { return executor.task({ ...taskOptions, run: async (_, input) => { const context = rest.length > 0 ? rest[0] : void 0; const procedureRest = [input, context]; const { error, data, isSuccess } = await safe(procedure(...procedureRest)); if (error) { const orpcError = toORPCError(error); if (orpcError.status === 404) { throw new DurableExecutionNotFoundError(orpcError.message); } let isRetryable = false; let isInternal = false; if (RETRYABLE_STATUSES.has(orpcError.status)) { isRetryable = true; } if (orpcError.status >= 500) { isInternal = true; } throw new DurableExecutionError(orpcError.message, { isRetryable, isInternal }); } else if (isSuccess) { return data; } else { throw DurableExecutionError.nonRetryable("Unknown error"); } } // eslint-disable-next-line @typescript-eslint/no-explicit-any }); } export { convertProcedureClientToTask, createTasksRouter }; //# sourceMappingURL=index.js.map