@sveltejs/kit
Version:
SvelteKit is the fastest way to build Svelte apps
70 lines (60 loc) • 2.09 kB
JavaScript
/** @import { RequestEvent } from '@sveltejs/kit' */
/** @import { RequestStore } from 'types' */
/** @import { AsyncLocalStorage } from 'node:async_hooks' */
import { IN_WEBCONTAINER } from '../../../constants.js';
import * as e from '../../../messages/server-errors.js';
/** @type {RequestStore | null} */
let sync_store = null;
/** @type {AsyncLocalStorage<RequestStore | null> | null} */
let als;
import('node:async_hooks')
.then((hooks) => (als = new hooks.AsyncLocalStorage()))
.catch(() => {
// can't use AsyncLocalStorage, but can still call getRequestEvent synchronously.
// this isn't behind `supports` because it's basically just StackBlitz (i.e.
// in-browser usage) that doesn't support it AFAICT
});
/**
* Returns the current `RequestEvent`. Can be used inside server hooks, server `load` functions, actions, and endpoints (and functions called by them).
*
* In environments without [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage), this must be called synchronously (i.e. not after an `await`).
* @since 2.20.0
*
* @returns {RequestEvent}
*/
export function getRequestEvent() {
const event = try_get_request_store()?.event;
if (!event) {
if (als) e.request_event_unavailable();
e.request_event_after_await();
}
return event;
}
export function get_request_store() {
const result = try_get_request_store();
if (!result) {
if (als) throw new Error('Could not get the request store. This is an internal error.');
e.request_store_after_await();
}
return result;
}
export function try_get_request_store() {
return sync_store ?? als?.getStore() ?? null;
}
/**
* @template T
* @param {RequestStore | null} store
* @param {() => T} fn
*/
export function with_request_store(store, fn) {
try {
sync_store = store;
return als ? als.run(store, fn) : fn();
} finally {
// Since AsyncLocalStorage is not working in webcontainers, we don't reset `sync_store`
// and handle only one request at a time in `src/runtime/server/index.js`.
if (!IN_WEBCONTAINER) {
sync_store = null;
}
}
}