Repository navigation
test(Tokenizer): the SSR test loads Tokenizer at collection and finishes each case's sheet load - #8760
Conversation
…hes each case's sheet load Each case hydrates a fresh module graph (`vi.resetModules()`, then an import of Tokenizer's entry). The first case paid the graph's transform inside its 30 s budget, about 3.4 s alone and many times that on a busy machine, where it timed out. Its work then kept running, and a coarse-pointer case's on-demand sheet load resolved during the next case's hydration, which reported "This root received an early update". The entry and its sheet now load while the file is collected, which is untimed, so each fresh graph only runs the modules again. A coarse-pointer case finishes the sheet load its hydration starts before it unmounts, and a case that ends early has its hydration finish before the next case starts.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
There was a problem hiding this comment.
Recommending approval: loading Tokenizer's module graph at collection keeps the cold transform out of the first SSR case's budget, and the coarse-pointer cases still fail when the FR16 hydration path is broken. With every budget cut to 1 s, main times out both coarse-pointer cases, while this branch passes all three, each in 0.1 s or less. One optional hardening: wrap the afterEach cleanup in try/finally (lines 39–48), so a case that times out and then throws cannot leave its focused trigger and stubs for the next case. Also note that the description's 3 s recipe passes on main on a machine where the first case takes about 2.8 s; a 1 s cut reproduces the failure reliably.
[Automated review]
| if (hydrating != null) { | ||
| await hydrating; | ||
| } |
There was a problem hiding this comment.
Optional hardening: if hydrating rejects (a case that timed out and then failed), this await throws before the cleanup below, so the failed case's container, focus and stubs reach the next case. Putting the cleanup in a finally keeps the error on the timed-out case and still resets the DOM:
try {
if (hydrating != null) {
await hydrating;
}
} finally {
vi.restoreAllMocks();
vi.unstubAllGlobals();
document.body.replaceChildren();
}
Review only this PR's change: vjeux/astryx@6b96fc3...7b45858
Maintainer impact
On a busy machine,
Tokenizer.ssr.test.tsxfails in full test runs and passes alone, so it shows up as a red on pull requests that never touch Tokenizer. Its coarse-pointer case times out at its 30 s budget, and the fine-pointer case after it then reports "This root received an early update, before anything was able hydrate".What led here: the red appeared in our full runs after #7977 added the file. Each case hydrates a fresh module graph (
vi.resetModules(), then an import of the internal Tokenizer entry).vi.resetModules()only re-runs modules; their transforms stay cached. So the first case alone paid the cold transform of Tokenizer's graph inside its budget: 3.4 s of the file's 3.5 s alone, many times that under load. Its work then kept running, and its on-demand sheet load resolved during the next case's hydration.Intended invariant
A case's time goes to the hydration it checks, and none of its work reaches the next case.
Change
Options weighed:
vi.resetModules(): the cases would share one module graph, so a later case would no longer start from a fresh server process, which is what the test checks.So the Tokenizer entry and its sheet load at collection, a coarse-pointer case finishes the sheet load its hydration starts before it unmounts, and a case that ends early has its hydration finish before the next case starts.
Evidence
How to check: cut the three budgets to 3 s (
}, 3000);) and runpnpm vitest run packages/core/src/Tokenizer/Tokenizer.ssr.test.tsx.Scope
Testing
check:changesets.