| 53 | : TSelected |
| 54 | |
| 55 | export function useMatch< |
| 56 | TRouter extends AnyRouter = RegisteredRouter, |
| 57 | const TFrom extends string | undefined = undefined, |
| 58 | TStrict extends boolean = true, |
| 59 | TThrow extends boolean = true, |
| 60 | TSelected = unknown, |
| 61 | >( |
| 62 | opts: UseMatchOptions< |
| 63 | TRouter, |
| 64 | TFrom, |
| 65 | TStrict, |
| 66 | ThrowConstraint<TStrict, TThrow>, |
| 67 | TSelected |
| 68 | >, |
| 69 | ): Solid.Accessor< |
| 70 | ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow> |
| 71 | > { |
| 72 | const nearestMatchId = Solid.useContext( |
| 73 | opts.from ? dummyMatchContext : matchContext, |
| 74 | ) |
| 75 | |
| 76 | // Create a signal to track error state separately from the match |
| 77 | const matchState: Solid.Accessor<{ |
| 78 | match: any |
| 79 | shouldThrowError: boolean |
| 80 | }> = useRouterState({ |
| 81 | select: (state: any) => { |
| 82 | const match = state.matches.find((d: any) => |
| 83 | opts.from ? opts.from === d.routeId : d.id === nearestMatchId(), |
| 84 | ) |
| 85 | |
| 86 | if (match === undefined) { |
| 87 | // During navigation transitions, check if the match exists in pendingMatches |
| 88 | const pendingMatch = state.pendingMatches?.find((d: any) => |
| 89 | opts.from ? opts.from === d.routeId : d.id === nearestMatchId(), |
| 90 | ) |
| 91 | |
| 92 | // Determine if we should throw an error |
| 93 | const shouldThrowError = |
| 94 | !pendingMatch && !state.isTransitioning && (opts.shouldThrow ?? true) |
| 95 | |
| 96 | return { match: undefined, shouldThrowError } |
| 97 | } |
| 98 | |
| 99 | return { |
| 100 | match: opts.select ? opts.select(match) : match, |
| 101 | shouldThrowError: false, |
| 102 | } |
| 103 | }, |
| 104 | } as any) |
| 105 | |
| 106 | // Use createEffect to throw errors outside the reactive selector context |
| 107 | // This allows error boundaries to properly catch the errors |
| 108 | Solid.createEffect(() => { |
| 109 | const state = matchState() |
| 110 | if (state.shouldThrowError) { |
| 111 | invariant( |
| 112 | false, |