{"version":3,"file":"index.cjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface NavigateOptions {\n ignoreBlocker?: boolean\n}\n\ntype SubscriberHistoryAction =\n | {\n type: Exclude\n }\n | {\n type: 'GO'\n index: number\n }\n\ntype SubscriberArgs = {\n location: HistoryLocation\n action: SubscriberHistoryAction\n}\n\nexport interface RouterHistory {\n location: HistoryLocation\n length: number\n subscribers: Set<(opts: SubscriberArgs) => void>\n subscribe: (cb: (opts: SubscriberArgs) => void) => () => void\n push: (path: string, state?: any, navigateOpts?: NavigateOptions) => void\n replace: (path: string, state?: any, navigateOpts?: NavigateOptions) => void\n go: (index: number, navigateOpts?: NavigateOptions) => void\n back: (navigateOpts?: NavigateOptions) => void\n forward: (navigateOpts?: NavigateOptions) => void\n canGoBack: () => boolean\n createHref: (href: string) => string\n block: (blocker: NavigationBlocker) => () => void\n flush: () => void\n destroy: () => void\n notify: (action: SubscriberHistoryAction) => void\n _ignoreSubscribers?: boolean\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: ParsedHistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {}\n\nexport type ParsedHistoryState = HistoryState & {\n key?: string // TODO: Remove in v2 - use __TSR_key instead\n __TSR_key?: string\n __TSR_index: number\n}\n\ntype ShouldAllowNavigation = any\n\nexport type HistoryAction = 'PUSH' | 'REPLACE' | 'FORWARD' | 'BACK' | 'GO'\n\nexport type BlockerFnArgs = {\n currentLocation: HistoryLocation\n nextLocation: HistoryLocation\n action: HistoryAction\n}\n\nexport type BlockerFn = (\n args: BlockerFnArgs,\n) => Promise | ShouldAllowNavigation\n\nexport type NavigationBlocker = {\n blockerFn: BlockerFn\n enableBeforeUnload?: (() => boolean) | boolean\n}\n\ntype TryNavigateArgs = {\n task: () => void\n type: 'PUSH' | 'REPLACE' | 'BACK' | 'FORWARD' | 'GO'\n navigateOpts?: NavigateOptions\n} & (\n | {\n type: 'PUSH' | 'REPLACE'\n path: string\n state: any\n }\n | {\n type: 'BACK' | 'FORWARD' | 'GO'\n }\n)\n\nconst stateIndexKey = '__TSR_index'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nexport function createHistory(opts: {\n getLocation: () => HistoryLocation\n getLength: () => number\n pushState: (path: string, state: any) => void\n replaceState: (path: string, state: any) => void\n go: (n: number) => void\n back: (ignoreBlocker: boolean) => void\n forward: (ignoreBlocker: boolean) => void\n createHref: (path: string) => string\n flush?: () => void\n destroy?: () => void\n onBlocked?: () => void\n getBlockers?: () => Array\n setBlockers?: (blockers: Array) => void\n // Avoid notifying on forward/back/go, used for browser history as we already get notified by the popstate event\n notifyOnIndexChange?: boolean\n}): RouterHistory {\n let location = opts.getLocation()\n const subscribers = new Set<(opts: SubscriberArgs) => void>()\n\n const notify = (action: SubscriberHistoryAction) => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber({ location, action }))\n }\n\n const handleIndexChange = (action: SubscriberHistoryAction) => {\n if (opts.notifyOnIndexChange ?? true) notify(action)\n else location = opts.getLocation()\n }\n\n const tryNavigation = async ({\n task,\n navigateOpts,\n ...actionInfo\n }: TryNavigateArgs) => {\n const ignoreBlocker = navigateOpts?.ignoreBlocker ?? false\n if (ignoreBlocker) {\n task()\n return\n }\n\n const blockers = opts.getBlockers?.() ?? []\n const isPushOrReplace =\n actionInfo.type === 'PUSH' || actionInfo.type === 'REPLACE'\n if (typeof document !== 'undefined' && blockers.length && isPushOrReplace) {\n for (const blocker of blockers) {\n const nextLocation = parseHref(actionInfo.path, actionInfo.state)\n const isBlocked = await blocker.blockerFn({\n currentLocation: location,\n nextLocation,\n action: actionInfo.type,\n })\n if (isBlocked) {\n opts.onBlocked?.()\n return\n }\n }\n }\n\n task()\n }\n\n return {\n get location() {\n return location\n },\n get length() {\n return opts.getLength()\n },\n subscribers,\n subscribe: (cb: (opts: SubscriberArgs) => void) => {\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n }\n },\n push: (path, state, navigateOpts) => {\n const currentIndex = location.state[stateIndexKey]\n state = assignKeyAndIndex(currentIndex + 1, state)\n tryNavigation({\n task: () => {\n opts.pushState(path, state)\n notify({ type: 'PUSH' })\n },\n navigateOpts,\n type: 'PUSH',\n path,\n state,\n })\n },\n replace: (path, state, navigateOpts) => {\n const currentIndex = location.state[stateIndexKey]\n state = assignKeyAndIndex(currentIndex, state)\n tryNavigation({\n task: () => {\n opts.replaceState(path, state)\n notify({ type: 'REPLACE' })\n },\n navigateOpts,\n type: 'REPLACE',\n path,\n state,\n })\n },\n go: (index, navigateOpts) => {\n tryNavigation({\n task: () => {\n opts.go(index)\n handleIndexChange({ type: 'GO', index })\n },\n navigateOpts,\n type: 'GO',\n })\n },\n back: (navigateOpts) => {\n tryNavigation({\n task: () => {\n opts.back(navigateOpts?.ignoreBlocker ?? false)\n handleIndexChange({ type: 'BACK' })\n },\n navigateOpts,\n type: 'BACK',\n })\n },\n forward: (navigateOpts) => {\n tryNavigation({\n task: () => {\n opts.forward(navigateOpts?.ignoreBlocker ?? false)\n handleIndexChange({ type: 'FORWARD' })\n },\n navigateOpts,\n type: 'FORWARD',\n })\n },\n canGoBack: () => location.state[stateIndexKey] !== 0,\n createHref: (str) => opts.createHref(str),\n block: (blocker) => {\n if (!opts.setBlockers) return () => {}\n const blockers = opts.getBlockers?.() ?? []\n opts.setBlockers([...blockers, blocker])\n\n return () => {\n const blockers = opts.getBlockers?.() ?? []\n opts.setBlockers?.(blockers.filter((b) => b !== blocker))\n }\n },\n flush: () => opts.flush?.(),\n destroy: () => opts.destroy?.(),\n notify,\n }\n}\n\nfunction assignKeyAndIndex(index: number, state: HistoryState | undefined) {\n if (!state) {\n state = {}\n }\n const key = createRandomKey()\n return {\n ...state,\n key, // TODO: Remove in v2 - use __TSR_key instead\n __TSR_key: key,\n [stateIndexKey]: index,\n } as ParsedHistoryState\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n parseLocation?: () => HistoryLocation\n createHref?: (path: string) => string\n window?: any\n}): RouterHistory {\n const win =\n opts?.window ??\n (typeof document !== 'undefined' ? window : (undefined as any))\n\n const originalPushState = win.history.pushState\n const originalReplaceState = win.history.replaceState\n\n let blockers: Array = []\n const _getBlockers = () => blockers\n const _setBlockers = (newBlockers: Array) =>\n (blockers = newBlockers)\n\n const createHref = opts?.createHref ?? ((path) => path)\n const parseLocation =\n opts?.parseLocation ??\n (() =>\n parseHref(\n `${win.location.pathname}${win.location.search}${win.location.hash}`,\n win.history.state,\n ))\n\n // Ensure there is always a key to start\n if (!win.history.state?.__TSR_key && !win.history.state?.key) {\n const addedKey = createRandomKey()\n win.history.replaceState(\n {\n [stateIndexKey]: 0,\n key: addedKey, // TODO: Remove in v2 - use __TSR_key instead\n __TSR_key: addedKey,\n },\n '',\n )\n }\n\n let currentLocation = parseLocation()\n let rollbackLocation: HistoryLocation | undefined\n\n let nextPopIsGo = false\n let ignoreNextPop = false\n let skipBlockerNextPop = false\n let ignoreNextBeforeUnload = false\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise | undefined\n\n // This function flushes the next update to the browser history\n const flush = () => {\n if (!next) {\n return\n }\n\n // We need to ignore any updates to the subscribers while we update the browser history\n history._ignoreSubscribers = true\n\n // Update the browser history\n ;(next.isPush ? win.history.pushState : win.history.replaceState)(\n next.state,\n '',\n next.href,\n )\n\n // Stop ignoring subscriber updates\n history._ignoreSubscribers = false\n\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n rollbackLocation = undefined\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n destHref: string,\n state: any,\n ) => {\n const href = createHref(destHref)\n\n if (!scheduled) {\n rollbackLocation = currentLocation\n }\n\n // Update the location in memory\n currentLocation = parseHref(destHref, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n // NOTE: this function can probably be removed\n const onPushPop = (type: 'PUSH' | 'REPLACE') => {\n currentLocation = parseLocation()\n history.notify({ type })\n }\n\n const onPushPopEvent = async () => {\n if (ignoreNextPop) {\n ignoreNextPop = false\n return\n }\n\n const nextLocation = parseLocation()\n const delta =\n nextLocation.state[stateIndexKey] - currentLocation.state[stateIndexKey]\n const isForward = delta === 1\n const isBack = delta === -1\n const isGo = (!isForward && !isBack) || nextPopIsGo\n nextPopIsGo = false\n\n const action = isGo ? 'GO' : isBack ? 'BACK' : 'FORWARD'\n const notify: SubscriberHistoryAction = isGo\n ? {\n type: 'GO',\n index: delta,\n }\n : {\n type: isBack ? 'BACK' : 'FORWARD',\n }\n\n if (skipBlockerNextPop) {\n skipBlockerNextPop = false\n } else {\n const blockers = _getBlockers()\n if (typeof document !== 'undefined' && blockers.length) {\n for (const blocker of blockers) {\n const isBlocked = await blocker.blockerFn({\n currentLocation,\n nextLocation,\n action,\n })\n if (isBlocked) {\n ignoreNextPop = true\n win.history.go(1)\n history.notify(notify)\n return\n }\n }\n }\n }\n\n currentLocation = parseLocation()\n history.notify(notify)\n }\n\n const onBeforeUnload = (e: BeforeUnloadEvent) => {\n if (ignoreNextBeforeUnload) {\n ignoreNextBeforeUnload = false\n return\n }\n\n let shouldBlock = false\n\n // If one blocker has a non-disabled beforeUnload, we should block\n const blockers = _getBlockers()\n if (typeof document !== 'undefined' && blockers.length) {\n for (const blocker of blockers) {\n const shouldHaveBeforeUnload = blocker.enableBeforeUnload ?? true\n if (shouldHaveBeforeUnload === true) {\n shouldBlock = true\n break\n }\n\n if (\n typeof shouldHaveBeforeUnload === 'function' &&\n shouldHaveBeforeUnload() === true\n ) {\n shouldBlock = true\n break\n }\n }\n }\n\n if (shouldBlock) {\n e.preventDefault()\n return (e.returnValue = '')\n }\n return\n }\n\n const history = createHistory({\n getLocation,\n getLength: () => win.history.length,\n pushState: (href, state) => queueHistoryAction('push', href, state),\n replaceState: (href, state) => queueHistoryAction('replace', href, state),\n back: (ignoreBlocker) => {\n if (ignoreBlocker) skipBlockerNextPop = true\n ignoreNextBeforeUnload = true\n return win.history.back()\n },\n forward: (ignoreBlocker) => {\n if (ignoreBlocker) skipBlockerNextPop = true\n ignoreNextBeforeUnload = true\n win.history.forward()\n },\n go: (n) => {\n nextPopIsGo = true\n win.history.go(n)\n },\n createHref: (href) => createHref(href),\n flush,\n destroy: () => {\n win.history.pushState = originalPushState\n win.history.replaceState = originalReplaceState\n win.removeEventListener(beforeUnloadEvent, onBeforeUnload, {\n capture: true,\n })\n win.removeEventListener(popStateEvent, onPushPopEvent)\n },\n onBlocked: () => {\n // If a navigation is blocked, we need to rollback the location\n // that we optimistically updated in memory.\n if (rollbackLocation && currentLocation !== rollbackLocation) {\n currentLocation = rollbackLocation\n }\n },\n getBlockers: _getBlockers,\n setBlockers: _setBlockers,\n notifyOnIndexChange: false,\n })\n\n win.addEventListener(beforeUnloadEvent, onBeforeUnload, { capture: true })\n win.addEventListener(popStateEvent, onPushPopEvent)\n\n win.history.pushState = function (...args: Array) {\n const res = originalPushState.apply(win.history, args as any)\n if (!history._ignoreSubscribers) onPushPop('PUSH')\n return res\n }\n\n win.history.replaceState = function (...args: Array) {\n const res = originalReplaceState.apply(win.history, args as any)\n if (!history._ignoreSubscribers) onPushPop('REPLACE')\n return res\n }\n\n return history\n}\n\n/**\n * Create a hash-based history implementation.\n * Useful for static hosts or environments without server URL rewriting.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/history-types\n */\nexport function createHashHistory(opts?: { window?: any }): RouterHistory {\n const win =\n opts?.window ??\n (typeof document !== 'undefined' ? window : (undefined as any))\n return createBrowserHistory({\n window: win,\n parseLocation: () => {\n const hashSplit = win.location.hash.split('#').slice(1)\n const pathPart = hashSplit[0] ?? '/'\n const searchPart = win.location.search\n const hashEntries = hashSplit.slice(1)\n const hashPart =\n hashEntries.length === 0 ? '' : `#${hashEntries.join('#')}`\n const hashHref = `${pathPart}${searchPart}${hashPart}`\n return parseHref(hashHref, win.history.state)\n },\n createHref: (href) =>\n `${win.location.pathname}${win.location.search}#${href}`,\n })\n}\n\n/**\n * Create an in-memory history implementation.\n * Ideal for server rendering, tests, and non-DOM environments.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/history-types\n */\nexport function createMemoryHistory(\n opts: {\n initialEntries: Array\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex\n ? Math.min(Math.max(opts.initialIndex, 0), entries.length - 1)\n : entries.length - 1\n const states = entries.map((_entry, index) =>\n assignKeyAndIndex(index, undefined),\n )\n\n const getLocation = () => parseHref(entries[index]!, states[index])\n\n let blockers: Array = []\n const _getBlockers = () => blockers\n const _setBlockers = (newBlockers: Array) =>\n (blockers = newBlockers)\n\n return createHistory({\n getLocation,\n getLength: () => entries.length,\n pushState: (path, state) => {\n // Removes all subsequent entries after the current index to start a new branch\n if (index < entries.length - 1) {\n entries.splice(index + 1)\n states.splice(index + 1)\n }\n states.push(state)\n entries.push(path)\n index = Math.max(entries.length - 1, 0)\n },\n replaceState: (path, state) => {\n states[index] = state\n entries[index] = path\n },\n back: () => {\n index = Math.max(index - 1, 0)\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => {\n index = Math.min(Math.max(index + n, 0), entries.length - 1)\n },\n createHref: (path) => path,\n getBlockers: _getBlockers,\n setBlockers: _setBlockers,\n })\n}\n\n/**\n * Sanitize a path to prevent open redirect vulnerabilities.\n * Removes control characters and collapses leading double slashes.\n */\nfunction sanitizePath(path: string): string {\n // Remove ASCII control characters (0x00-0x1F) and DEL (0x7F)\n // These include CR (\\r = 0x0D), LF (\\n = 0x0A), and other potentially dangerous characters\n // eslint-disable-next-line no-control-regex\n let sanitized = path.replace(/[\\x00-\\x1f\\x7f]/g, '')\n\n // Prevent open redirect via protocol-relative URLs (e.g. \"//evil.com\")\n // Collapse leading double slashes to a single slash\n if (sanitized.startsWith('//')) {\n sanitized = '/' + sanitized.replace(/^\\/+/, '')\n }\n\n return sanitized\n}\n\nexport function parseHref(\n href: string,\n state: ParsedHistoryState | undefined,\n): HistoryLocation {\n const sanitizedHref = sanitizePath(href)\n const hashIndex = sanitizedHref.indexOf('#')\n const searchIndex = sanitizedHref.indexOf('?')\n\n const addedKey = createRandomKey()\n\n return {\n href: sanitizedHref,\n pathname: sanitizedHref.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : sanitizedHref.length,\n ),\n hash: hashIndex > -1 ? sanitizedHref.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? sanitizedHref.slice(\n searchIndex,\n hashIndex === -1 ? undefined : hashIndex,\n )\n : '',\n state: state || { [stateIndexKey]: 0, key: addedKey, __TSR_key: addedKey },\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"mappings":"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"}