import { runDurableObjectAlarm, runInDurableObject } from "cloudflare:test"; import type { RepoDurableObject } from "@/worker/do"; export type RepoDOStub = DurableObjectStub; export type RepoDOStubFactory = () => RepoDOStub; /** * Run work against a Durable Object instance and reacquire the stub if workerd * invalidated the previous instance during local test execution. */ export async function runDOWithRetry( getStub: RepoDOStubFactory, fn: (instance: RepoDurableObject, state: DurableObjectState) => Promise | T ): Promise { const exec = async (stub: RepoDOStub): Promise => { return await runInDurableObject(stub, (instance, state) => fn(instance, state) ); }; try { return await exec(getStub()); } catch (error) { const message = String(error || ""); if (message.includes("invalidating this Durable Object")) { return await exec(getStub()); } throw error; } } /** * Call a stub method directly and retry once if the underlying instance was * invalidated between calls. */ export async function callStubWithRetry( getStub: RepoDOStubFactory, fn: (stub: RepoDOStub) => Promise ): Promise { try { return await fn(getStub()); } catch (error) { const message = String(error || ""); if (message.includes("invalidating this Durable Object")) { return await fn(getStub()); } throw error; } } /** * Fire a Durable Object alarm and reacquire the stub if workerd invalidated the * previous instance during local test execution. */ export async function runAlarmWithRetry(getStub: RepoDOStubFactory): Promise { try { return await runDurableObjectAlarm(getStub()); } catch (error) { const message = String(error || ""); if (message.includes("invalidating this Durable Object")) { return await runDurableObjectAlarm(getStub()); } throw error; } }