34 lines
1.1 KiB
TypeScript
34 lines
1.1 KiB
TypeScript
import { AsyncLocalStorage } from "node:async_hooks";
|
|
import type { Context } from "./context.ts";
|
|
|
|
/**
|
|
* The request context for the currently executing server work.
|
|
*
|
|
* A server-side API call needs the request's cookies, session, and URL, but
|
|
* `ctx` is not in scope everywhere server code runs: load blocks have it,
|
|
* schema actions take it as a parameter, and plain actions and server
|
|
* functions have neither. Threading it through every signature would make the
|
|
* call site differ between server and browser, which defeats the point.
|
|
*/
|
|
const storage = new AsyncLocalStorage<Context>();
|
|
|
|
export function runWithRequestContext<T>(ctx: Context, fn: () => T): T {
|
|
return storage.run(ctx, fn);
|
|
}
|
|
|
|
export function getRequestContext(): Context | undefined {
|
|
return storage.getStore();
|
|
}
|
|
|
|
export function requireRequestContext(what: string): Context {
|
|
const ctx = storage.getStore();
|
|
|
|
if (!ctx) {
|
|
throw new Error(
|
|
`${what} needs a request context. It ran outside a request — server-side API calls are only available while handling one.`,
|
|
);
|
|
}
|
|
|
|
return ctx;
|
|
}
|