Closed AlCalzone closed 1 year ago
I was able to use the proxyDurable method withDurables uses. @AlCalzone see https://github.com/kwhitley/itty-durable/issues/31 for example
I got this working using withDurables
after all. It is a bit awkward though, since we have to individually wrap each loader
function and cannot hook this up in createRequestHandler
in the CF workers adapter, because Remix passes a new Request instance to each loader.
Wrap Remix loader function with the following function:
// in any route using a loader:
export const loader = loaderWithDurables(async (args) => {
// loader code
});
// Definition of loaderWithDurables:
export function loaderWithDurables(fn: LoaderFunctionWithDurables): LoaderFunction {
return (args) => {
withDurables({ parse: true })(args.request, args.context.env);
return fn(args as any);
};
}
The types are defined as follows:
export type LoaderFunctionArgs = Omit<DataFunctionArgs, "context"> & { context: Context };
export type LoaderFunction = (
args: LoaderFunctionArgs,
) => Response | null | Promise<Response | null>;
export type LoaderFunctionWithDurablesArgs = { request: RequestWithDurables } & Omit<DataFunctionArgs, "context" | "request"> & { context: Context };
export type LoaderFunctionWithDurables = (
args: LoaderFunctionWithDurablesArgs,
) => Response | null | Promise<Response | null>;
export interface CloudflareEnvironment {
// ... everything that should be available under `context.env`
}
export interface Context {
ctx: ExecutionContext;
env: CloudflareEnvironment;
}
The RequestWithDurables
mimicks what itty-durable
does to the request object:
export interface RequestWithDurables extends Request, TestProps /*, ... other DO props */ {}
Each XyzProps
typelooks like this:
export type TestProps = {
TEST: IttyDurableObjectNamespace<TestObj>;
}
where TEST
is the env
key, and TestObj
is the class name.
type PromisifyPublicFunctions<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any
? (...args: Parameters<T[K]>) => Promise<Awaited<ReturnType<T[K]>>>
: never;
};
interface IttyDurableObjectNamespace<T> {
get(id: string | DurableObjectId): PromisifyPublicFunctions<T>;
}
This library looks really cool and solves a pain point I've been having with DOs from the start. Unfortunately, I'm using https://remix.run in my project, which has a file-based routing convention, so I'm at a loss how I can hook the
withDurables
middleware in there.I should be able to modify the request context using
getLoadContext
, similar to https://remix.run/docs/en/v1/other-api/adapter, so a more "manual" version of this magic hook could help here. Is there something like that?