Skip to content

Instantly share code, notes, and snippets.

@jehna
Created August 30, 2024 20:16
Show Gist options
  • Save jehna/7613eeefd06df8e86bb7b4de3201e277 to your computer and use it in GitHub Desktop.
Save jehna/7613eeefd06df8e86bb7b4de3201e277 to your computer and use it in GitHub Desktop.
saga.ts
export type SideEffect<Result> = {
commit: () => Promise<Result>;
rollback: () => Promise<any>;
};
export async function saga<T>(
callback: (
run: <Result>(sideEffect: SideEffect<Result>) => Promise<Result>
) => Promise<T>
): Promise<T> {
const rollbacks: SideEffect<any>["rollback"][] = [];
async function run<Result>(sideEffect: SideEffect<Result>): Promise<Result> {
try {
const result = await sideEffect.commit();
rollbacks.unshift(sideEffect.rollback);
return result;
} catch (e) {
for (const rollback of rollbacks) {
await rollback();
}
throw e;
}
}
return await callback(run);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment