Skip to content

Instantly share code, notes, and snippets.

@xantiagoma
Last active February 5, 2025 05:44
Show Gist options
  • Save xantiagoma/d319048986041eba7c66d13eeee0b5c3 to your computer and use it in GitHub Desktop.
Save xantiagoma/d319048986041eba7c66d13eeee0b5c3 to your computer and use it in GitHub Desktop.
Wraps a resource to use new TypeScript / JavaScript (await) using keyword
import redis from "redis";
const { REDIS_PASSWORD } = process.env;
async function makeDisposable<T extends object>(
resource: T,
{
onDispose,
onInit,
}: {
onDispose?: (resource: T) => Promise<void>;
onInit?: (resource: T) => Promise<void>;
} = {},
): Promise<T & { [Symbol.asyncDispose]: () => Promise<void> }> {
const handler: ProxyHandler<T> = {
get(target: T, prop: string | symbol, receiver: unknown): unknown {
if (prop === Symbol.asyncDispose) {
return async () => {
await onDispose?.(target);
};
}
const value = Reflect.get(target, prop, target);
return typeof value === "function" ? value.bind(target) : value;
},
};
const proxy = new Proxy(resource, handler) as T & {
[Symbol.asyncDispose]: () => Promise<void>;
};
await onInit?.(resource);
return proxy;
}
async function main() {
await using client = await makeDisposable(
redis.createClient({
password: REDIS_PASSWORD,
}),
{
onInit: async (resource) => {
// console.log("Initializing Redis client");
await resource.connect();
},
onDispose: async (resource) => {
// console.log("Disposing Redis client");
await resource.disconnect();
},
},
);
const test = await client.get("test");
console.log({ test });
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment