import type { Router, State } from "@real-router/core"; export type ScrollRestorationMode = "restore" | "top" | "native"; export interface ScrollRestorationOptions { mode?: ScrollRestorationMode | undefined; anchorScrolling?: boolean | undefined; scrollContainer?: (() => HTMLElement | null) | undefined; /** * Scroll behavior passed to `scrollTo({ behavior })` and * `scrollIntoView({ behavior })`. * * - `"auto"` (default) — browser-defined, usually instant. * - `"instant"` — explicit instant jump (no animation). * - `"smooth"` — animated transition. Note: smooth restore on back/traverse * can feel disorienting if the user expects to land at the saved position * immediately. Recommended for `mode: "top"` or anchor scroll only. * * See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior). */ behavior?: ScrollBehavior | undefined; /** * sessionStorage key used to persist saved scroll positions. Default: * `"real-router:scroll"`. Override only when multiple independent * `RouterProvider` instances share the same document and you need to * isolate their scroll stores (e.g. micro-frontends, embedded widgets, * or testing). For a single app with one provider the default is fine. */ storageKey?: string | undefined; } export declare function createScrollRestoration(router: Router, options?: ScrollRestorationOptions): { destroy: () => void; }; export declare function keyOf(state: State): string; /** * Stable JSON serializer with sorted object keys. * * **Exported for testing only — not part of the public API** (intentionally * excluded from `index.ts` barrel). Adapter property tests import it via * the direct path to lock the key-order-insensitive property * (`canonicalJson({a:1,b:2}) === canonicalJson({b:2,a:1})`). * * ## Divergence from `@real-router/sources/canonicalJson` — by design * * Two independent implementations live in the monorepo: * * - **`shared/dom-utils/scroll-restore.canonicalJson`** (this file) — scroll * cache key builder. Uses `localeCompare` and a plain-object accumulator; * tolerates `__proto__`-keyed inputs only insofar as `JSON.stringify`'s * replacer happens to sort them; relies on `JSON.stringify`'s native cycle * detector. Designed to be cheap on the navigation hot path. The * surrounding [[safeKeyOf]] wrapper catches the two crash inputs (`BigInt`, * cyclic) and skips the offending capture/restore. * * - **`@real-router/sources/canonicalJson`** — sources cache key builder. * Uses byte-order compare (`< / >`) for locale-independence, a * `Object.create(null)` accumulator to prevent prototype pollution, and a * bespoke path-based cycle detector (the native one cannot see the cloned * graph). Throws eagerly on `Map`/`Set`/`RegExp`/cycles — the caller falls * back to a non-cached source. * * **They are intentionally NOT interchangeable.** Aligning them would either * regress scroll-restore performance (byte-order + recursive clone is heavier * per call) or weaken the sources cache (locale dependence breaks * deterministic cache keys across machines). No cross-package equivalence * test exists or should be added; the relationship is "different invariants, * different costs, different consumers." Audit-2 / audit-2026-05-17 §2 * documents the choice. */ export declare function canonicalJson(value: unknown): string;