@tanstack/react-router
Version:
Modern and scalable routing for React applications
1 lines • 6.75 kB
Source Map (JSON)
{"version":3,"file":"useMatch.cjs","names":["React","replaceEqualDeep","useRouter","dummyMatchContext","matchContext","isServer","useSelector"],"sources":["../../src/useMatch.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { useSelector } from '@tanstack/react-store'\nimport { invariant, replaceEqualDeep } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { dummyMatchContext, matchContext } from './matchContext'\nimport { useRouter } from './useRouter'\nimport type {\n StructuralSharingOption,\n ValidateSelected,\n} from './structuralSharing'\nimport type {\n AnyRouter,\n MakeRouteMatch,\n MakeRouteMatchUnion,\n RegisteredRouter,\n StrictOrFrom,\n ThrowConstraint,\n ThrowOrOptional,\n} from '@tanstack/router-core'\n\nconst dummyMatch = {}\n\nexport function useStructuralSharing<\n TRouter extends AnyRouter,\n TSelected,\n TStructuralSharing extends boolean,\n TStoreSlice,\n TSelectSlice = TStoreSlice,\n>(\n opts:\n | {\n select?: (\n slice: TSelectSlice,\n ) => ValidateSelected<TRouter, TSelected, TStructuralSharing>\n structuralSharing?: boolean\n }\n | undefined,\n router: TRouter,\n): (\n slice: TStoreSlice,\n) => ValidateSelected<TRouter, TSelected, TStructuralSharing> {\n const previousResult =\n // @ts-expect-error -- init to undefined, but without writing `undefined` to shave bytes\n React.useRef<ValidateSelected<TRouter, TSelected, TStructuralSharing>>()\n\n return (slice) => {\n const selected = opts?.select\n ? opts.select(slice as unknown as TSelectSlice)\n : (slice as ValidateSelected<TRouter, TSelected, TStructuralSharing>)\n\n if (opts?.structuralSharing ?? router.options.defaultStructuralSharing) {\n return (previousResult.current = replaceEqualDeep(\n previousResult.current,\n selected,\n ))\n }\n\n return selected\n }\n}\n\nexport interface UseMatchBaseOptions<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TThrow extends boolean,\n TSelected,\n TStructuralSharing extends boolean,\n> {\n select?: (\n match: MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>,\n ) => ValidateSelected<TRouter, TSelected, TStructuralSharing>\n shouldThrow?: TThrow\n}\n\nexport type UseMatchRoute<out TFrom> = <\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n TThrow extends boolean = true,\n>(\n opts?: UseMatchBaseOptions<\n TRouter,\n TFrom,\n true,\n TThrow,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,\n) => ThrowOrOptional<UseMatchResult<TRouter, TFrom, true, TSelected>, TThrow>\n\nexport type UseMatchOptions<\n TRouter extends AnyRouter,\n TFrom extends string | undefined,\n TStrict extends boolean,\n TThrow extends boolean,\n TSelected,\n TStructuralSharing extends boolean,\n> = StrictOrFrom<TRouter, TFrom, TStrict> &\n UseMatchBaseOptions<\n TRouter,\n TFrom,\n TStrict,\n TThrow,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>\n\nexport type UseMatchResult<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TSelected,\n> = unknown extends TSelected\n ? TStrict extends true\n ? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>\n : MakeRouteMatchUnion<TRouter>\n : TSelected\n\n/**\n * Read and select the nearest or targeted route match.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useMatchHook\n */\nexport function useMatch<\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string | undefined = undefined,\n TStrict extends boolean = true,\n TThrow extends boolean = true,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n>(\n opts: UseMatchOptions<\n TRouter,\n TFrom,\n TStrict,\n ThrowConstraint<TStrict, TThrow>,\n TSelected,\n TStructuralSharing\n >,\n): ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow> {\n const router = useRouter<TRouter>()\n const nearestRouteId = React.useContext(\n opts.from ? dummyMatchContext : matchContext,\n )\n\n const routeId = opts.from ?? nearestRouteId\n const matchStore = router.stores.getMatchStore(routeId!)\n\n if (isServer ?? router.isServer) {\n const match = matchStore.get()\n if (!match) {\n if (opts.shouldThrow ?? true) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `Invariant failed: Could not find ${opts.from ? `an active match from \"${opts.from}\"` : 'a nearest match!'}`,\n )\n }\n\n invariant()\n }\n\n return undefined as any\n }\n\n return (opts.select ? opts.select(match as any) : match) as any\n }\n\n const selector =\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n useStructuralSharing(opts, router)\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n const matchSelection = useSelector(matchStore, (match) =>\n match ? selector(match as any) : dummyMatch,\n )\n\n if (matchSelection !== dummyMatch) {\n return matchSelection as any\n }\n\n if (opts.shouldThrow ?? true) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `Invariant failed: Could not find ${opts.from ? `an active match from \"${opts.from}\"` : 'a nearest match!'}`,\n )\n }\n\n invariant()\n }\n\n return undefined as any\n}\n"],"mappings":";;;;;;;;;;AAsBA,IAAM,aAAa,CAAC;AAEpB,SAAgB,qBAOd,MAQA,QAG4D;CAC5D,MAAM,iBAEJA,MAAM,OAAiE;CAEzE,QAAQ,UAAU;EAChB,MAAM,WAAW,MAAM,SACnB,KAAK,OAAO,KAAgC,IAC3C;EAEL,IAAI,MAAM,qBAAqB,OAAO,QAAQ,0BAC5C,OAAQ,eAAe,WAAA,GAAUC,sBAAAA,iBAAAA,CAC/B,eAAe,SACf,QACF;EAGF,OAAO;CACT;AACF;;;;;AAkEA,SAAgB,SAQd,MAQ6E;CAC7E,MAAM,SAASC,kBAAAA,UAAmB;CAClC,MAAM,iBAAiBF,MAAM,WAC3B,KAAK,OAAOG,qBAAAA,oBAAoBC,qBAAAA,YAClC;CAEA,MAAM,UAAU,KAAK,QAAQ;CAC7B,MAAM,aAAa,OAAO,OAAO,cAAc,OAAQ;CAEvD,IAAIC,+BAAAA,YAAY,OAAO,UAAU;EAC/B,MAAM,QAAQ,WAAW,IAAI;EAC7B,IAAI,CAAC,OAAO;GACV,IAAI,KAAK,eAAe,MAAM;IAC5B,IAAA,QAAA,IAAA,aAA6B,cAC3B,MAAM,IAAI,MACR,oCAAoC,KAAK,OAAO,yBAAyB,KAAK,KAAK,KAAK,oBAC1F;IAGF,CAAA,GAAA,sBAAA,UAAA,CAAU;GACZ;GAEA;EACF;EAEA,OAAQ,KAAK,SAAS,KAAK,OAAO,KAAY,IAAI;CACpD;CAEA,MAAM,WAEJ,qBAAqB,MAAM,MAAM;CAGnC,MAAM,kBAAA,GAAiBC,sBAAAA,YAAAA,CAAY,aAAa,UAC9C,QAAQ,SAAS,KAAY,IAAI,UACnC;CAEA,IAAI,mBAAmB,YACrB,OAAO;CAGT,IAAI,KAAK,eAAe,MAAM;EAC5B,IAAA,QAAA,IAAA,aAA6B,cAC3B,MAAM,IAAI,MACR,oCAAoC,KAAK,OAAO,yBAAyB,KAAK,KAAK,KAAK,oBAC1F;EAGF,CAAA,GAAA,sBAAA,UAAA,CAAU;CACZ;AAGF"}