fix(v4): refresh the stale twoslash hovers, and stop them going stale - #870
Conversation
The docblock links added in #868 never reached the site: every twoslash overlay was serving hover data captured before those links existed. A cache is keyed on `sha256(shikiOptions:lang:code)` — the sample, not the types behind it. Changing a docblock in `src/` therefore invalidates nothing, and the tooltip stays frozen at whatever the types were when the cache was first written. Nothing warns you: the build passes, the page renders, only the hover is out of date. Same commit, same tree: committed caches -> 0 doc URLs in the hovers TWOSLASH_INLINE_CACHE_IGNORE -> 587 So this regenerates all 96 files' caches, and the deploy job now sets TWOSLASH_INLINE_CACHE_IGNORE so what is published is always generated against current types rather than trusted from the repo. The committed caches keep their real job, which is making `docs:v4:dev` fast locally. The cost is about 50s: a 32s docs build becomes 83s for ~200 samples. Folding a `dist` fingerprint into the twoslash options to auto-invalidate would be neater, but the options that feed the hash are shiki's, not the plugin's, so there is no clean seam for it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ioM9dGKVhexCv4NLUcbA7
Code ReviewRisk: Low — The workflow now regenerates v4 Twoslash caches during deployment, while the committed cache payloads refresh the visible examples; no blocking defect is evident in the reviewed diff. This change updates the generated hover data in several v4 documentation examples and sets Review usage: 52,273 in (3,056 cached) / 309 out tokens — $0.0318 (openrouter/openai/gpt-5.6-luna, thinking: low) Reviewed by @weareikko/code-review v0.9.5 for commit 3f81200. |
Export sizeBundled per export with peer dependencies left external, dynamic imports excluded and the output minified; sizes are gzipped. ✅ No export size changes. Unchanged (399)@studiometa/js-toolkit
@studiometa/js-toolkit-v4
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #870 +/- ##
=======================================
Coverage 97.06% 97.06%
=======================================
Files 176 176
Lines 4561 4561
Branches 1331 1331
=======================================
Hits 4427 4427
Misses 122 122
Partials 12 12
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
v4 mount benchmarksBase and head measured on this runner, alternating over 3 rounds each; every value is the median of the round medians. Running both sides on one machine is what removes cross-machine noise — a cached baseline from another runner would put it back. A move under 25%, or on a benchmark under 5 ms, is not reported as a change: it is inside the measured noise of a shared runner. No benchmark moved beyond the noise floor. Within noise (18)
|
The docblock links from #868 never reached the site. You spotted it as "missing links in the twoslash overlays" — the cause is one layer down.
The cache never invalidates on a type change
The key is the sample, not the types behind it. Change a docblock in
src/, rebuilddist, and every cache still matches — so the overlay keeps serving the hover data captured when it was first written.Nothing warns you. The build passes, the page renders, only the tooltip is out of date. Measured on the same commit and the same tree:
TWOSLASH_INLINE_CACHE_IGNORE=1Two fixes
Refresh now — all 96 files' caches regenerated, so a plain
npm run docs:v4:buildproduces all 587.Stop the drift — the
deploy-v4job setsTWOSLASH_INLINE_CACHE_IGNORE, so what gets published is always generated against current types instead of trusted from the repo. The committed caches keep their real job: makingdocs:v4:devfast locally.Cost: ~50s, a 32s build becoming 83s for ~200 samples.
What I considered and rejected
Folding a
distfingerprint into the twoslash options would auto-invalidate on any type change, which is neater in principle. But theoptionsthat feedgetOptionsHashare shiki'sCodeToHastOptions, not the plugin's own — there is no clean seam to inject a fingerprint, so it would mean patching the transformer.A
--checkguard asserting "regenerating changes nothing" was the other candidate. It keeps builds fast and the repo honest, but it pays the same ~50s in CI and adds a failure mode where the fix is "run a command and commit the diff". Regenerating at deploy time gets the property that matters — published output is never stale — without that friction.Note
deploy-v3has the same latent issue withpackages/docs, and I have not touched it: it would slow that build and it is not what this PR is about. Worth a look if v3 docblocks change.Checks
🤖 Generated with Claude Code
https://claude.ai/code/session_012ioM9dGKVhexCv4NLUcbA7