mirror of
https://github.com/cloudflare/vinext.git
synced 2026-09-14 19:04:59 +08:00
vinext@0.1.1
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3a1e56748f |
fix(app-router): match Pages navigation params in hybrid builds (#1741)
* fix(app-router): emit pages client entry for hybrid builds * fix pages router navigation params readiness * fix(pages-router): track hashed fallback client entry * fix(pages-router): honor navigation readiness in hooks * fix(pages-router): derive server router.isReady from SSR readiness Address review feedback on #1741: - getRouterSnapshot() now reads navigationIsReady from the SSR context on the server instead of unconditionally returning true. For pre-ready Pages routes (auto-export dynamic / query-string / rewrite-capable builds) this keeps useRouter().isReady consistent between SSR and client hydration, avoiding a hydration mismatch for components that read it in JSX. Mirrors Next.js render.tsx's server readiness rule. - Drop the redundant guard branch in getClientParamsSnapshot. - Add a regression test asserting server useRouter().isReady reflects the SSR navigationIsReady context. * fix(pages-router): align param resolution and dev/prod readiness parity Address review feedback (ask-bonk + self-review) on #1741: - Align client Pages navigation params to query-first, matching the server snapshot and Next.js's adaptForPathParams (derives path params from router.query). __NEXT_DATA__.query is kept current on client navigation, so the two snapshots are now provably identical and avoid a latent post- hydration mismatch. - Populate window.__VINEXT_PAGE_PATTERNS__ in the dev server (own script tag) so the next/navigation compat hooks can resolve a dynamic pattern from a resolved path in dev exactly as in production. Closes a dev/prod parity gap (prod set this via the client entry; dev never did). - Drop the redundant pre-readiness setSSRContext in dev; the single post- module-load call now publishes navigationIsReady before rendering, matching the prod handler. - Document that installPagesClientAssetGlobals is intentionally inert for App-only builds, and that getReadonlyPagesSearchParams' string-keyed cache is safe to share across concurrent SSR requests (immutable wrappers). - Add a dev regression test asserting __VINEXT_PAGE_PATTERNS__ exposure. * fix(pages-router): prefer URL params for client snapshots * fix(app-router): gate pages asset globals * test(app-router): add production test for hybrid basePath + assetPrefix * fix(navigation): widen usePathname return type to string | null * refactor(pages-router): dedupe navigation readiness modeling and cache pattern scan Addresses code-review cleanup findings on the Pages Router navigation readiness work: - Extract buildPagesReadinessNextData() so the dev SSR handler and the production Pages page handler derive the gssp/gsp/gip/appGip/autoExport __NEXT_DATA__ readiness flags from one place, instead of two hand-kept copies that could drift and produce a dev/prod hydration mismatch. - Extract resolvePagesNavigationPathname() shared by the client and SSR branches of getPagesNavigationContext, so the pathname null-ness rule (fallback / pre-ready auto-export dynamic) cannot diverge between them. - Memoize resolvePagesRoutePatternForPath()'s pattern scan, which ran an uncached O(routes) loop on every useSyncExternalStore snapshot read. - In getServerSearchParamsSnapshot, serialize the source only when the object-identity fast path misses, avoiding a toString() on every read. * refactor(pages-router): consistent ISR readiness data + robustness cleanups Addresses further code-review findings: - Thread the readiness flags (gssp/gsp/gip/appGip/autoExport) through the ISR background-regeneration path: renderPagesIsrHtml now serializes the same __NEXT_DATA__ readiness state the initial render emits, so a regenerated, re-cached page hydrates with the identical initial router.isReady the server computed. Previously these flags were dropped on that path — benign today (ISR-eligible getStaticProps routes never trigger the flag-gated early-ready branches) but a latent dev/prod hydration-readiness drift. Adds a shared PagesNextDataExtras type so every render path stays in lockstep. - readSsrManifest: degrade a malformed/unparseable SSR manifest to "no SSR manifest" with a warning instead of throwing and aborting server startup, restoring the previous tolerant behavior. - pages-readiness: project PagesReadinessNextData from the canonical VinextNextData and accept PagesPageModule, instead of bespoke types that could drift from the __NEXT_DATA__ shape. - getReadonlyPagesSearchParams: drop the redundant string-keyed cache slot; the per-object WeakMap is authoritative and concurrency-safe on its own. - isPagesRouterReady: drop the redundant server-side window check. * fix(pages-router): restore string-keyed readonly search-params cache Reverts the cache simplification from the previous commit. The string-keyed slot is load-bearing, not redundant: across the Pages Router pre-ready → ready transition the navigation context swaps in a new URLSearchParams instance even when the query string is unchanged, so the per-object WeakMap alone returns a fresh ReadonlyURLSearchParams wrapper and useSearchParams() loses Object.is stability — re-firing a [searchParams] effect. Caught by the rewrite-driven pre-ready static page e2e (search-params-snapshots saw ['',''] not ['']). Keeps the improved comment explaining why both cache levels are needed. --------- Co-authored-by: James <james@eli.cx> |
||
|
|
d9a5e63c32 |
refactor(pages): extract render orchestrator from codegen string (#1784) (#1805)
* refactor(pages): extract render orchestrator from codegen string (#1784) Move `_renderPage` (~260 lines) and `collectAssetTags` (~85 lines) out of the generated template string in `entries/pages-server-entry.ts` into typed, unit-testable server modules: - `server/pages-page-handler.ts` — `createPagesPageHandler` factory that owns the full Pages Router render lifecycle (i18n, route matching, 404/500 fallback recursion, _next/data envelope, 405 method check, ISR cache-key derivation, SSR-context setup). Mirrors how `server/app-rsc-handler.ts` is structured relative to `entries/app-rsc-entry.ts`. - `server/pages-asset-tags.ts` — `collectAssetTags` + manifest helpers, extracted from the template so they can be unit-tested directly. - `server/pages-data-route.ts` — adds `normalizePagesDataRequest` so both `renderPage` and `runMiddleware` share one implementation instead of duplicating the buildId-check logic in the template string. `entries/pages-server-entry.ts` is now thin wiring: route-table codegen, embedded config/i18n/buildId, and closures that delegate to the handler. `renderPage` keeps its exact exported signature; all callers are unaffected. No behavior change — pure code motion. Fixed a latent bug where the `isrCacheKey` wrapper in the handler was missing the `buildId` argument on non-i18n paths (causing a cache-key mismatch); caught by the existing ISR CSP-nonce test. * refactor(pages): tighten handler types and improve tests - Use ComponentType from react for AppComponent, DocumentComponent, and PageComponent closures instead of unknown — matches pages-page-response.ts which already uses ComponentType. Eliminates the DocumentComponent cast. - Widen isrCacheKey router param from literal union to string — the literal union forced as-casts everywhere it was used indirectly. All call sites pass 'pages' or 'app' string literals so the widening is safe. - Replace the shallow i18n redirect test (which just checked a route miss gave 404) with a test that actually exercises the 307 short-circuit: visiting / with Accept-Language: fr triggers resolvePagesI18nRequest to return redirectUrl and the handler returns 307 to /fr. - Add second i18n test: locale prefix already present → no redirect. - Tighten 'allows POST with gSSP' test: assert no Allow header (confirms the 405 guard was bypassed, not just that some non-405 came back). |