-
Notifications
You must be signed in to change notification settings - Fork 419
fix(tanstack-react-start): Fix navigation promise resolving too early #7463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@clerk/tanstack-react-start': patch | ||
| --- | ||
|
|
||
| Fix navigation edge case where the new auth state would sometimes be applied before the navigation finished. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,8 +1,8 @@ | ||||||
| import type { NavigateOptions } from '@tanstack/react-router'; | ||||||
| import { useLocation, useNavigate } from '@tanstack/react-router'; | ||||||
| import React, { useTransition } from 'react'; | ||||||
| import React from 'react'; | ||||||
|
|
||||||
| type Resolve = (value?: unknown) => void; | ||||||
| type Resolve = () => void; | ||||||
|
|
||||||
| export const useAwaitableNavigate = () => { | ||||||
| const navigate = useNavigate(); | ||||||
|
|
@@ -12,18 +12,21 @@ export const useAwaitableNavigate = () => { | |||||
| resolveFunctionsRef.current.forEach(resolve => resolve()); | ||||||
| resolveFunctionsRef.current.splice(0, resolveFunctionsRef.current.length); | ||||||
| }; | ||||||
| const [_, startTransition] = useTransition(); | ||||||
|
|
||||||
| React.useEffect(() => { | ||||||
| resolveAll(); | ||||||
| }, [location]); | ||||||
|
|
||||||
| return (options: NavigateOptions) => { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Add explicit return type annotation. Per coding guidelines, functions should have explicit return types, especially for public APIs. The returned function should explicitly declare its return type. As per coding guidelines: "Always define explicit return types for functions, especially public APIs." - return (options: NavigateOptions) => {
+ return (options: NavigateOptions): Promise<void> => {📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| return new Promise(res => { | ||||||
| startTransition(() => { | ||||||
| resolveFunctionsRef.current.push(res); | ||||||
| res(navigate(options)); | ||||||
| }); | ||||||
| return new Promise<void>(res => { | ||||||
| resolveFunctionsRef.current.push(res); | ||||||
| navigate(options) | ||||||
| .then(() => { | ||||||
| res(); | ||||||
| }) | ||||||
| .catch(() => { | ||||||
| res(); | ||||||
| }); | ||||||
| }); | ||||||
|
Comment on lines
20
to
30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Read the full file to understand the context
cat -n packages/tanstack-react-start/src/client/useAwaitableNavigate.tsRepository: clerk/javascript Length of output: 1146 🏁 Script executed: #!/bin/bash
# Search for tests related to useAwaitableNavigate
find . -type f \( -name "*.test.*" -o -name "*.spec.*" \) -exec rg -l "useAwaitableNavigate" {} \;Repository: clerk/javascript Length of output: 42 🏁 Script executed: #!/bin/bash
# Search for usage of useAwaitableNavigate in the codebase
rg -n "useAwaitableNavigate" --type=ts --type=tsx -B2 -A2 | head -100Repository: clerk/javascript Length of output: 87 🏁 Script executed: #!/bin/bash
# Search for usage patterns with broader search
rg "useAwaitableNavigate" -A 5 -B 5 --type=ts --type=js --type=jsxRepository: clerk/javascript Length of output: 87 🏁 Script executed: #!/bin/bash
# Look for any test files in the tanstack-react-start package
find packages/tanstack-react-start -type f \( -name "*.test.*" -o -name "*.spec.*" \) 2>/dev/null | head -20Repository: clerk/javascript Length of output: 198 🏁 Script executed: #!/bin/bash
# Check if there are any comments or git history that explains the design
rg -B 10 "useAwaitableNavigate" packages/tanstack-react-start/src/client/useAwaitableNavigate.ts | head -30Repository: clerk/javascript Length of output: 289 🏁 Script executed: #!/bin/bash
# Check the exports test file
cat packages/tanstack-react-start/src/__tests__/exports.test.tsRepository: clerk/javascript Length of output: 1115 🏁 Script executed: #!/bin/bash
# Search for actual usage in source files (avoiding test files)
rg "useAwaitableNavigate" packages/tanstack-react-start/src --type-add='tsx:*.tsx' --type=tsRepository: clerk/javascript Length of output: 579 🏁 Script executed: #!/bin/bash
# Check package index files for exports
cat packages/tanstack-react-start/src/client/index.tsRepository: clerk/javascript Length of output: 193 🏁 Script executed: #!/bin/bash
# Read ClerkProvider to understand how useAwaitableNavigate is used
cat -n packages/tanstack-react-start/src/client/ClerkProvider.tsxRepository: clerk/javascript Length of output: 2843 🏁 Script executed: #!/bin/bash
# Verify if navigate() actually triggers location change or if they're separate
rg -A 20 "navigate\(" packages/tanstack-react-start/src/client/useAwaitableNavigate.ts | head -30Repository: clerk/javascript Length of output: 201 🏁 Script executed: #!/bin/bash
# Check if there are any issues or PRs mentioning this hook
git log --oneline --all packages/tanstack-react-start/src/client/useAwaitableNavigate.ts 2>/dev/null | head -10Repository: clerk/javascript Length of output: 227 🏁 Script executed: #!/bin/bash
# Check the details of the commit that supposedly fixed this issue
git show 8b3574c5 --stat packages/tanstack-react-start/src/client/useAwaitableNavigate.tsRepository: clerk/javascript Length of output: 380 🏁 Script executed: #!/bin/bash
# Get full diff of that commit for the file
git show 8b3574c5 packages/tanstack-react-start/src/client/useAwaitableNavigate.tsRepository: clerk/javascript Length of output: 1454 Critical: Double resolution and memory leak in navigation promise logic. The promise resolution logic has a critical flaw:
return new Promise<void>(res => {
+ const index = resolveFunctionsRef.current.push(res) - 1;
- resolveFunctionsRef.current.push(res);
navigate(options)
.then(() => {
res();
+ resolveFunctionsRef.current.splice(index, 1);
})
.catch(() => {
res();
+ resolveFunctionsRef.current.splice(index, 1);
});
});Note: Option B assumes sequential resolution, which may not hold with concurrent navigations. 🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @wobsoriano @octoper I think this comment makes a lot of sense and articulates something I've been struggling with as well. Feels like we should either rely on the Because of #7411 I'm leaning towards the What do you think? I'll verify if removing the resolving on
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Turns out that wont work well either, because in TanStack Start,
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ff. thanks for checking this one out, frederik! |
||||||
| }; | ||||||
| }; | ||||||
Uh oh!
There was an error while loading. Please reload this page.