import type { Locale } from "date-fns"; import type { AppDateFormat, AppLocale, AppRequestHeaders, AppTimeFormat, AppTimezone } from "./types.js"; /** * THE PER-REQUEST HOME OF EVERYTHING A NON-REACT CALLER READS (v32, gh#1219). * * Locale, timezone, the date/time formats and the request headers used to be three module-level * variables (`translate.ts`, `request-headers.ts`, `lib/datetime/sync.ts`). In a browser that is * one user and harmless. On a server it is every request at once: the last `AppProvider` to render * wrote them, so a `translateCurrent` / `formatDate` / `getAppRequestHeaders` call in request A * answered with request B's language and zone — measured in `ssr-request-isolation.test.tsx`. * * Now each of those modules keeps its slot in ONE `AppSettingsState` object, and which object is * "current" depends on where the call runs: * * 1. inside `runWithAppSettings(settings, fn)` → that call's own object. On a server it is carried * by `AsyncLocalStorage`, so it survives every `await` inside `fn`; where no AsyncLocalStorage * exists it covers the synchronous part of `fn` only. * 2. otherwise → one module-level object, which is the browser's single-user case. * * React components do not need this: they read `AppProvider`'s context, which is per tree by * construction. The scope is for code that has no React context to read. */ export type AppSettings = { locale: AppLocale; fallbackLocale: AppLocale; timezone: AppTimezone; timeFormat: AppTimeFormat; dateFormat: AppDateFormat; }; /** @internal Each module owns one slot; an unset slot means "nothing chose it — use the default". */ export type AppSettingsState = { i18n?: Partial>; datetime?: Partial> & { dateFnsLocale?: Locale; }; headers?: Partial; }; /** @internal The state object the current call belongs to. Mutated in place by the `sync*` writers. */ export declare function getAppSettingsState(): AppSettingsState; /** * Run `fn` with its own locale / timezone / format / header state — one call per server request. * * Everything `fn` reaches without a React context (`translateCurrent`, `formatDate` with no * options, `getAppRequestHeaders`, and an `AppProvider` rendered inside it syncing its values for * those callers) reads and writes THIS call's state, never another request's. Unset fields keep * the neutral defaults (``/`en`, UTC on a server, formats from `Intl`). * * ```ts * const html = await runWithAppSettings({ locale: "de", timezone: "Europe/Berlin" }, () => * renderToString(), * ); * ``` */ export declare function runWithAppSettings(settings: Partial, fn: () => R): R;