ta
TanStack
GitHub
router
Workspace
GitHub
CI Pipeline Executions
Filtered
Runs
Demo
Insights
Compare tasks
Analytics
Sign in
Toggle sidebar
Overview
⌘K
router
Loading workspace stats
Loading workspace insights...
Statistics interval
7 days
30 days
Latest CI Pipeline Executions
Status
Fix filter
Filter
Fuzzy
Filter range
Sort by
Sort by
Start time
Sort ascending
Sort descending
Failed
7744
Fix ready
→
9e5200d0 test: rewrite PR 7744 internals assertions
by Sheraff
S
Failed
7744
Fix ready
→
4da6ecef bundle size improvements
by Sheraff
S
Canceled
7744
4da6ecef bundle size improvements
by Sheraff
S
Failed
7744
Fix ready
→
1f917616 perf: gzip shape alignment, dead solid scroll-restoration husk, single-use helper inlines Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Failed
7744
Fix ready
→
f4b56fe3 perf: recover gzip bytes in lane-model client code and match components Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Failed
7744
38470e34 docs: declare removed public API in the changeset and update RouterType docs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Canceled
7744
38470e34 docs: declare removed public API in the changeset and update RouterType docs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Succeeded
7744
bcc23d84 feat: navigations adopt in-flight preload loader runs (data-only) Restores the essential hover-preload contract — click during an in-flight preload executes the loader ONCE — without resurrecting the old join's bug classes: - Data only, never control flow: a donor preload that ends in redirect/ notFound/error is ignored and the navigation runs its own loader, so preload-computed redirects can no longer hijack navigations (the redirect regression test now pins non-leakage AND the retry). - The navigation always runs its own beforeLoad with preload:false semantics (the old join's context-mismatch class stays dead). - Private preload lanes register in router._preloadLanes; matchRoutes attaches a join handle; the loader phase adopts via the shared loadPromise. Joining is gated on the donor's loader being in flight — before that, the preload's serial phase may itself be waiting on this navigation through the borrow protocol, and joining would deadlock the pair (pinned by a serial-phase test). Concurrent sibling preloads of the same route also dedupe to one loader run. - No cache pollution: lanes stay private until success, unchanged. The adoption await is gated on the join handle so the synchronous loader-start contract is untouched for the no-preload case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Canceled
7744
bcc23d84 feat: navigations adopt in-flight preload loader runs (data-only) Restores the essential hover-preload contract — click during an in-flight preload executes the loader ONCE — without resurrecting the old join's bug classes: - Data only, never control flow: a donor preload that ends in redirect/ notFound/error is ignored and the navigation runs its own loader, so preload-computed redirects can no longer hijack navigations (the redirect regression test now pins non-leakage AND the retry). - The navigation always runs its own beforeLoad with preload:false semantics (the old join's context-mismatch class stays dead). - Private preload lanes register in router._preloadLanes; matchRoutes attaches a join handle; the loader phase adopts via the shared loadPromise. Joining is gated on the donor's loader being in flight — before that, the preload's serial phase may itself be waiting on this navigation through the borrow protocol, and joining would deadlock the pair (pinned by a serial-phase test). Concurrent sibling preloads of the same route also dedupe to one loader run. - No cache pollution: lanes stay private until success, unchanged. The adoption await is gated on the join handle so the synchronous loader-start contract is untouched for the no-preload case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Canceled
7744
bcc23d84 feat: navigations adopt in-flight preload loader runs (data-only) Restores the essential hover-preload contract — click during an in-flight preload executes the loader ONCE — without resurrecting the old join's bug classes: - Data only, never control flow: a donor preload that ends in redirect/ notFound/error is ignored and the navigation runs its own loader, so preload-computed redirects can no longer hijack navigations (the redirect regression test now pins non-leakage AND the retry). - The navigation always runs its own beforeLoad with preload:false semantics (the old join's context-mismatch class stays dead). - Private preload lanes register in router._preloadLanes; matchRoutes attaches a join handle; the loader phase adopts via the shared loadPromise. Joining is gated on the donor's loader being in flight — before that, the preload's serial phase may itself be waiting on this navigation through the borrow protocol, and joining would deadlock the pair (pinned by a serial-phase test). Concurrent sibling preloads of the same route also dedupe to one loader run. - No cache pollution: lanes stay private until success, unchanged. The adoption await is gated on the join handle so the synchronous loader-start contract is untouched for the no-preload case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Succeeded
7744
a70abdd5 refactor: delete hedges against invariants the model already guarantees (frameworks) Framework half of the trust-the-model sweep: - Vue's Transitioner adopts the single-emitter shape react uses: synchronous store subscriptions drive one emitEdges instead of three watch pipelines over usePrevious edges; the transition edge stays flush-coupled via nextTick for the onResolved event, while the idle/resolvedLocation commit happens on the first falling edge — joining the same reactive flush as the matches commit, so matchRoute/status consumers can never render one flush behind the committed lane. Navigations now produce one fewer store flush across the board (pinned counts updated downward). - Vue and Solid useMatch drop the hasPendingMatch throw-suppression guards and the pendingMatchContext/pendingRouteIds plumbing that fed them: atomic pending publication means a match the store publishes is always judgeable, matching react's semantics (changeset documents the Vue behavior change). Full suites green (router-core 1492, react 938, solid 818+server-mode, vue 789 incl. the conditional-Link regression this rework surfaced and fixed), react selective-ssr e2e green. Bundle: −30 to −218 B gzip on every measured target. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Canceled
7744
a70abdd5 refactor: delete hedges against invariants the model already guarantees (frameworks) Framework half of the trust-the-model sweep: - Vue's Transitioner adopts the single-emitter shape react uses: synchronous store subscriptions drive one emitEdges instead of three watch pipelines over usePrevious edges; the transition edge stays flush-coupled via nextTick for the onResolved event, while the idle/resolvedLocation commit happens on the first falling edge — joining the same reactive flush as the matches commit, so matchRoute/status consumers can never render one flush behind the committed lane. Navigations now produce one fewer store flush across the board (pinned counts updated downward). - Vue and Solid useMatch drop the hasPendingMatch throw-suppression guards and the pendingMatchContext/pendingRouteIds plumbing that fed them: atomic pending publication means a match the store publishes is always judgeable, matching react's semantics (changeset documents the Vue behavior change). Full suites green (router-core 1492, react 938, solid 818+server-mode, vue 789 incl. the conditional-Link regression this rework surfaced and fixed), react selective-ssr e2e green. Bundle: −30 to −218 B gzip on every measured target. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Failed
7744
022395e1 refactor(react-router): one deterministic emitter for the load lifecycle The Transitioner carried two emission pipelines: render-observed usePrevious edges (lossy by design — React batching can hide a flip inside one commit) and the mount-load repair, with a setTimeout(0) arbitrating between them. Both are replaced by a single emitter driven by synchronous store subscriptions (isLoading/hasPending), which cannot miss an edge, plus one render-coupled signal for onResolved: a commit tick bumped inside the transition and observed by a layout effect, so resolution still lands after React committed the transition render. A counter rather than a boolean so nested transitions (invalidate inside a user startTransition) can never coalesce into an unobservable no-change. No timer, no arbitration, no repair block, and the mount load reduces to a bare router.load() — its own isLoading toggle through the armed subscriptions is the deterministic signal even for loads that settled before mount (the memory-benchmark case, re-verified: no hang). Net smaller than the file it replaces. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Succeeded
7744
4d9e0e76 refactor: remove unnecessary mechanism across the match-loading pipeline Complexity sweep over the combined #7637+#7744 diff (23 verified simplifications; every candidate adversarially checked for behavior preservation against INTERNALS and the test suite): - One flag instead of two for pending publication (pendingPublished folded into rendered); serial failures live on inner.serialFailure instead of a local mirrored by a temporary background-null bracket (retained ancestors now gate background selection explicitly). - Provably-dead code deleted: finalizeRouteFailure's never-passed componentFailure parameter, an unreachable lane-shortening guard, the join's pre-wait aborted check, three sync-gap currentness re-checks in the background path, the server-side latestLoadPromise clear, two unreachable isServer branches in react Match, and the supersession drain loop's impossible-state guards (with a new multi-supersession pinning test). - One owner per rule: the serial-failure loader-prefix cap is a shared helper used by both client and server (new foreground-lane pinning test); matchRoutesInternal derives context through getMatchContext; invalidate() uses one parameterized updater; cancelMatches reads its known pool directly; the server reduction uses Promise.allSettled. - Vestigial indirection dropped: hydrate()'s follow-up load microtask deferral, solid's createResource microtask yield and armPending wrapper, ssr-client's duplicate route.options.ssr write, the loadedMatches/matches aliases, and stores.ts's initial-state object for five compile-time constants. Bundle: −95 to −150 B gzip (−300 to −494 B raw) on every measured target across react/solid/vue and vite/rsbuild. All suites green (router-core 1492, react 941, solid 821+server-mode, vue 791) plus react/solid selective-ssr e2e. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Canceled
7744
4d9e0e76 refactor: remove unnecessary mechanism across the match-loading pipeline Complexity sweep over the combined #7637+#7744 diff (23 verified simplifications; every candidate adversarially checked for behavior preservation against INTERNALS and the test suite): - One flag instead of two for pending publication (pendingPublished folded into rendered); serial failures live on inner.serialFailure instead of a local mirrored by a temporary background-null bracket (retained ancestors now gate background selection explicitly). - Provably-dead code deleted: finalizeRouteFailure's never-passed componentFailure parameter, an unreachable lane-shortening guard, the join's pre-wait aborted check, three sync-gap currentness re-checks in the background path, the server-side latestLoadPromise clear, two unreachable isServer branches in react Match, and the supersession drain loop's impossible-state guards (with a new multi-supersession pinning test). - One owner per rule: the serial-failure loader-prefix cap is a shared helper used by both client and server (new foreground-lane pinning test); matchRoutesInternal derives context through getMatchContext; invalidate() uses one parameterized updater; cancelMatches reads its known pool directly; the server reduction uses Promise.allSettled. - Vestigial indirection dropped: hydrate()'s follow-up load microtask deferral, solid's createResource microtask yield and armPending wrapper, ssr-client's duplicate route.options.ssr write, the loadedMatches/matches aliases, and stores.ts's initial-state object for five compile-time constants. Bundle: −95 to −150 B gzip (−300 to −494 B raw) on every measured target across react/solid/vue and vite/rsbuild. All suites green (router-core 1492, react 941, solid 821+server-mode, vue 791) plus react/solid selective-ssr e2e. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Succeeded
7744
c9efc460 refactor: single-shot foreground wait in the preload borrow protocol Replace the counter-capped wait loop with the deterministic contract the protocol originally had: if the borrowed owner is mid-navigation, await the current foreground load exactly once and re-read. An owner that still has not committed after that belongs to a newer navigation, and the speculative pass yields via the ownership sentinel. Zero or one await by construction — no arbitrary iteration bound. INTERNALS and the churn regression test updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Succeeded
7744
354d6593 fix: address delta-review findings - joinPreloadedActiveMatch's foreground wait is now bounded: a speculative preload drops its pass (ownership sentinel) instead of outwaiting sustained navigation churn, where every iteration picked up the replacement latestLoadPromise and awaiters never settled. Covered by a churn regression test with signal-aware loaders. - The react Transitioner stuck-pending repair now also emits onLoad/onBeforeRouteMount/onResolved — deferred one macrotask so the normal effect pipeline (which sets status idle) always wins arbitration and events cannot double-fire; only genuinely unobserved loads repair. - Server asset projection no longer abandons a pending async head()/ scripts() when a sync throw coincides with an async headers(): the response waits on headers regardless, so that case now flows through the generic per-kind branch and commits everything that settles. This also removes the duplicated commit+recurse continuation. - Restores solid-router's server-mode test suite ('vitest --mode server'), accidentally dropped from test:unit by a concurrent agent edit swept into an earlier commit; the suite passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Succeeded
7744
3867af17 fix: drop unnecessary type assertions in issue-7638 regression test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Canceled
7744
3867af17 fix: drop unnecessary type assertions in issue-7638 regression test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Failed
7744
Fix ready
→
39e8fe57 fix(solid-router): render hydration display pending through the shared ClientOnly slot The outer _displayPending branch made the hydrating client render the pending fallback at a different structural depth than the server (which renders it through ClientOnly's fallback), so Solid's dev runtime threw 'Hydration Mismatch' and cascaded into 'template is not a function' via the root CatchBoundary — dev-mode-only because prod silently falls back to client rendering. This regressed data-only+pendingComponent routes vs main and was also the mechanism behind the pre-existing #7283 (ssr:false+pendingComponent, broken on main too). _displayPending now renders inside MatchInner, which only mounts after ClientOnly hydrates — outside the hydration key sequence — fixing both cases. Adds a dev-server e2e spec covering both. Fixes #7283 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
by Sheraff
S
Previous
Next