* refactor: migrate ssrLoadModule to moduleRunner.import
Replace all server.ssrLoadModule() calls in dev-server.ts and api-handler.ts
with runner.import() via the ModuleImporter interface, following the Vite
Module Runner migration guide. Remove ssrFixStacktrace calls which are not
needed with Module Runner APIs. Update call sites in index.ts to pass the
existing getPagesRunner() lazy factory as the runner argument. Update tests
to use ModuleImporter-shaped mocks instead of the old ViteDevServer mock.
* refactor: address bonk review comments
- Fix misleading stack trace comments: ssrFixStacktrace is not applicable
to ModuleRunner (not that it rewrites automatically)
- Update ALS-ARCHITECTURE.md to reference runner.import() instead of
server.ssrLoadModule()
- Add importModule() typed helper to instrumentation.ts to centralise
the Record<string, any> cast, removing 12 inline eslint-disable comments
- Remove dead ssrLoadModule mock from pages-router ISR test (createSSRHandler
no longer calls server.ssrLoadModule)
* chore: migrate to vite plus
* Disable typeAware and typeCheck
* Update CI
* Fix CI
* Fix test
* Clean
* Run test with vp
* Try revert
* react: false In test
* Fix test
* Revert "Try revert"
This reverts commit 009da10473.
* Update
* Update
* Try revert ci changes
* revert
* Run vp migrate
* Disable typeAware and typeCheck for now
* Better resolve for test
* Use vp dev instead of vite
* Update expect
* Fix NormalizeManifestModuleId
* Try increase timeout
* Update to use vp
* Try new check
* Bring back npx vp
* Migrate CI
* Make next-intl resolvable
* Update
* Update
* Update
* Fix Pages API parsing parity
* Fix Pages API body parsing parity
* Fix empty form body parity
* Regenerate entry-templates snapshots after merge
* fix: propagate statusText through prod server sendCompressed non-compressed path
The sendCompressed function had a statusText parameter but only used it in
the compressed response path. The non-compressed else branch called
res.writeHead directly without forwarding statusText, so short error
responses (like 'Invalid JSON' at 12 bytes, well below COMPRESS_THRESHOLD)
lost their custom reason phrase and fell back to the default 'Bad Request'.
Fix: replace the direct res.writeHead call in the else branch with the
writeHead closure that already handles the statusText conditional.
Also set statusText on the ApiBodyParseError response in the pages server
entry template so the value is present for prod-server to forward.
---------
Co-authored-by: James <james@eli.cx>
* Fix Buffer handling in Pages API res
* fix: skip reporting handled Pages API parse errors
* address review: blank line nit, content-length parity for Buffer, fix duplicate Content-Length in sendCompressed
* fix: set content-length for Buffer in production res.send() to match dev parity
---------
Co-authored-by: James <james@eli.cx>
* perf: pre-split route patterns and hoist URL split out of match loop
Route matching runs on every request and iterates all routes until a
match is found. Previously, matchPattern() re-split both the URL and
the pattern string on every iteration:
for (const route of routes) {
// url.split("/") — same URL, re-split every iteration
// pattern.split("/") — pattern never pre-computed
matchPattern(normalizedUrl, route.pattern);
}
For a 50-route app on a 404, that's 50 URL splits + 50 pattern splits
+ 50 Object.create(null) + 100 .filter(Boolean) calls.
Fix:
- Add `patternParts: string[]` to Route and AppRoute interfaces,
computed once at scan time
- Split the URL once in matchRoute/matchAppRoute before the loop
- Pass pre-split arrays to matchPattern instead of raw strings
- Apply the same optimization to generated production entries
(pages-server-entry.ts, app-rsc-entry.ts)
- Fix intercepting route lookup to use the new array-based API
* update entry-templates snapshots
---------
Co-authored-by: James <james@eli.cx>
* add oxfmt formatter: config, scripts, CI, editor setup, docs
* rebuild lockfile
* fix: add Format to required checks list, remove dead ignore pattern
* run fmt
* add format to agents.md again