import { useStore } from '@tanstack/react-store' import { useRef } from 'react' import { replaceEqualDeep } from '@tanstack/router-core' import { useRouter } from './useRouter' import type { AnyRouter, RegisteredRouter, RouterState, } from '@tanstack/router-core' import type { StructuralSharingOption, ValidateSelected, } from './structuralSharing' export type UseRouterStateOptions< TRouter extends AnyRouter, TSelected, TStructuralSharing, > = { router?: TRouter select?: ( state: RouterState, ) => ValidateSelected } & StructuralSharingOption export type UseRouterStateResult< TRouter extends AnyRouter, TSelected, > = unknown extends TSelected ? RouterState : TSelected export function useRouterState< TRouter extends AnyRouter = RegisteredRouter, TSelected = unknown, TStructuralSharing extends boolean = boolean, >( opts?: UseRouterStateOptions, ): UseRouterStateResult { const contextRouter = useRouter({ warn: opts?.router === undefined, }) const router = opts?.router || contextRouter const previousResult = useRef>(undefined) return useStore(router.__store, (state) => { if (opts?.select) { if (opts.structuralSharing ?? router.options.defaultStructuralSharing) { const newSlice = replaceEqualDeep( previousResult.current, opts.select(state), ) previousResult.current = newSlice return newSlice } return opts.select(state) } return state }) as UseRouterStateResult }