durable-execution-orpc-utils
Version:
oRPC utilities for durable-execution to create a separate server process for durable execution
100 lines • 3.15 kB
JavaScript
// src/server.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) {
return osBuilder.input(
type()
).output(type()).handler(async ({ input }) => {
try {
const handle = await executor.enqueueTask({ id: input.taskId }, input.input, input.options);
return handle.getExecutionId();
} 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) {
return osBuilder.input(
type()
).output(type()).handler(async ({ input }) => {
try {
const handle = await executor.getTaskHandle({ id: input.taskId }, 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 createTasksRouter(osBuilder, executor) {
return {
enqueueTask: createEnqueueTaskProcedure(osBuilder, executor),
getTaskExecution: createGetTaskExecutionProcedure(osBuilder, executor)
};
}
function convertClientProcedureToTask(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);
switch (orpcError.code) {
case "NOT_FOUND": {
throw new DurableExecutionNotFoundError(orpcError.message);
}
case "INTERNAL_SERVER_ERROR": {
throw new DurableExecutionError(orpcError.message, false, true);
}
default: {
throw new DurableExecutionError(orpcError.message, false);
}
}
} else if (isSuccess) {
return data;
} else {
throw new DurableExecutionError("Unknown error", false);
}
}
});
}
export {
convertClientProcedureToTask,
createTasksRouter
};
//# sourceMappingURL=server.js.map