Skip to content

Instantly share code, notes, and snippets.

@cyco130
Last active October 1, 2021 14:40
Show Gist options
  • Save cyco130/280154c6e2c4b5ae390ea7cd0d4efbaf to your computer and use it in GitHub Desktop.
Save cyco130/280154c6e2c4b5ae390ea7cd0d4efbaf to your computer and use it in GitHub Desktop.
interface RpcModules {
"example-remote-module": MapReturnTypesToPromise<
typeof import("example-remote-module")
>;
}
export function importRemote<S extends keyof RpcModules>(
module: S
): RpcModules[S] {
return new Proxy({} as any, {
get(_t, func) {
return async (...args: unknown[]) => {
return fetch("/api/rpc", {
method: "POST",
// TODO: Use a more powerful serializer
body: JSON.stringify({ module, func, args }),
headers: { "content-type": "application/json" },
})
.then((r) => r.json())
.then((j) => {
if (j.error) {
// TODO: Standardize error format
throw j.error.message;
}
return j.result;
});
};
},
});
}
type MapReturnTypesToPromise<T extends Record<string, any>> = {
[k in keyof T]: MapReturnTypeToPromise<T[k]>;
};
type Promisify<T> = T extends Promise<any> ? T : Promise<T>;
type MapReturnTypeToPromise<T> = T extends (
ctx: any,
...args: infer A
) => infer R
? (...args: A) => Promisify<R>
: never;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment