Skip to content

fix(user): stop UserSync forcing an upstream bootstrap - #945

Draft
thostetler wants to merge 3 commits into
adsabs:masterfrom
thostetler:fix/usersync-drop-forced-bootstrap
Draft

thostetler wants to merge 3 commits into
adsabs:masterfrom
thostetler:fix/usersync-drop-forced-bootstrap

Conversation

@thostetler

Copy link
Copy Markdown
Member

UserSync sent a forced-refresh header on every client fetch of /api/user, so middleware discarded the session it had just minted for that page and made an upstream round trip to rebuild it. Expired sessions still recover through the api layer's forced refresh.

  • the redundant round trip happened three times per cold document load; in-app navigation never fetched /api/user, so only cold loads change.
  • a cache-shape mismatch had made the sync a no-op whenever the server seeded a valid token; now that it runs, a rejected token is no longer written back to the store, and after a 401 the store user stays null until the next navigation re-seeds it.

UserSync sent X-Refresh-Token on every client fetch of /api/user, which
middleware treats as forced session invalidation, so it bootstrapped
upstream even when the session was fresh. api.ts already owns expired-token
recovery through its plain -> forced -> bootstrap fallback.

Also corrects the ['user'] cache shape: ssr-utils and useUser write raw user
data, but UserSync read data.user off an envelope, so its store-sync effect
silently no-opped whenever the server seeded a valid token.
Api.invalidateUserData clears the store user to null on a 401 but leaves the
['user'] cache entry in place. With the cache shape corrected, UserSync's sync
effect saw a valid-looking cached token beside a cleared store user and wrote
the rejected one back. null is only ever written by that 401 path, so the
effect now treats it as a signal to stand down.

Also drops access_token from the sync debug log.
@thostetler
thostetler requested a review from shinyichen October 1, 2026 19:18
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

Bundle size

Shared by all pages: 629.6 kB (+0.0 kB) ⚪

No route changed by more than 1 kB. ✅

First load = polyfills + shared _app chunks + route chunks, gzipped.

@codecov

codecov Bot commented Oct 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.25000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.1%. Comparing base (ef57c7e) to head (e0c6dcb).

Files with missing lines Patch % Lines
src/components/UserSync/UserSync.tsx 81.3% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           master    #945     +/-   ##
========================================
+ Coverage    55.0%   55.1%   +0.1%     
========================================
  Files         374     375      +1     
  Lines       11462   11478     +16     
  Branches     2514    2517      +3     
========================================
+ Hits         6303    6320     +17     
+ Misses       4527    4526      -1     
  Partials      632     632             
Files with missing lines Coverage Δ
src/components/UserSync/UserSync.tsx 81.3% <81.3%> (ø)

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant