mirror of
https://github.com/cloudflare/vinext.git
synced 2026-09-14 19:04:59 +08:00
vinext@0.2.1
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
00f0a684e0 | test(ppr): wait for fallback shell abort signal (#2072) | ||
|
|
930e03c449 |
fix(ppr): gate fallback shells until request-time resume is supported (#1716)
* fix(app-router): prerender cacheComponents root-param fallback shells PR 1 of 4: core model + build integration. Model: app-ppr-fallback-shell, pregenerated-concrete-paths, prerender-manifest Build: prerender/run-prerender fallback shell artifact generation Tests: createAppPprFallbackShells, pregenerated-concrete-paths core * feat(ppr): add fallback shell payload identity * feat(ppr): safely serve fallback shell cache entries * refactor(ppr): extract fallback shell render pipeline and dedupe getViteMajorVersion * fix(ppr): restore safe-serving CI checks The safe-serving branch failed CI because a client-side server-only guard rejected valid 'use server' action modules, a fallback-shell dependency cast no longer matched its helper type, apps/web lost the Cloudflare cache adapter source path during typecheck, and Knip could not resolve the documented Cloudflare cache adapter subpaths. The server-only guard now reads the directive prologue and skips top-level 'use server' modules, fallback-shell regeneration passes an explicit typed dependency object, apps/web gets the workspace Cloudflare cache path, the Cloudflare package exports explicit adapter subpaths, Knip uses a relative source import in the dispatch unit test, and the readiness test awaits the actual cache-ready promise. * fix(ppr): guard fallback shell reads for queries * fix(ppr): normalize pregenerated concrete paths * fix(ppr): address review comments on fallback shell serving and react runtime check * fix(ci): restore knip ignores for unlisted binaries and prune dependencies * fix(ppr): restrict bracket check in fallback detection to legacy manifests * fix(ppr): prefer stable ESM react-dom/static.edge before CJS fallback The loadStaticPrerender dev-mode path hard-codes react-dom's internal CJS file layout (cjs/react-dom-server.edge.development.js). A React upgrade could silently break fallback-shell rendering in dev without affecting production because the function never tried the stable ESM entry in development. Change the order so that react-dom/static.edge is attempted first in all environments. Only fall back to the CJS path when the ESM entry does not export prerender() and we are in a development runtime. This lets future React dev builds that expose prerender() from the ESM entry work automatically, and it surfaces the CJS-path failure only when the stable path is genuinely unavailable. Also handle the CJS default-export interop shape that Node.js ESM produces when dynamically importing a CommonJS module. * refactor(ppr): address four review cleanup items 1. Remove redundant double-normalization in seed-cache.ts addPregeneratedConcretePath already normalizes internally, so the call-site normalizePregeneratedPathname() was redundant. Dropping it gives a single source of truth for pathname normalization. 2. Lazily construct FallbackShellRenderDeps in tryServePprFallbackShell Extract the large FallbackShellRenderDeps object into a top-level buildFallbackShellRenderDeps helper. The closure in the probe loop now just delegates, so the heavy object is only created when a STALE entry actually triggers regeneration, not on every HIT probe. 3. Add dev-only warning for legacy bracket heuristic When isFallbackShellArtifactPath falls back to the bracket substring scan (route.fallback === undefined), emit a console.warn in dev so developers know a legacy manifest is being used and concrete URLs with literal brackets may be misclassified. 4. Update pregenerated-concrete-paths.test.ts to colon notation The production manifest writer uses colon notation (/:slug) for the route field, but the test fixtures used bracket notation (/[slug]). Update the fixtures so the test format matches production, exercising the real key format that the safe-serving guard depends on. * test(ppr): compact fallback shell dispatch fixtures * refactor(ppr): name fallback shell render phases * refactor(app-router): deduplicate PPR fallback shell and app page cache render paths * fix(ppr): avoid serving incomplete fallback shells * chore: drop redundant cloudflare cache aliases * fix(ppr): track fallback navigation hooks * test(ppr): render navigation hook probes * test(ppr): type navigation hook probes * refactor(ppr): remove unused shell regeneration path * refactor(ppr): remove unused shell result type * fix(ppr): safely gate fallback shell prerendering * fix(ppr): keep fallback shell gate internal * fix(ppr): mark generated dynamic fallback shells * test(ppr): align fallback fixture and search params --------- Co-authored-by: James <james@eli.cx> |
||
|
|
9e3cf90583 | test(e2e): disable hash fixture query prefetch (#1948) | ||
|
|
1c1744e0ea |
feat(ppr): add PPR fallback-shell render lifecycle tests (#1715)
* feat(ppr): add fallback shell render lifecycle * fix(ppr): address review feedback on PR #1715 - Make await params resolvable during fallback-shell prerendering by keeping the base promise as Promise.resolve(plain) and only throwing the hanging promise on sync fallback-key access. - Defer createPprFallbackShellSuspensePromise to first fallback-key access so hasDynamicBoundary and cache-task ignoring only fire when a fallback param is actually read, matching the suspend only on access contract. - Store and clear pendingAbortCleanup in preparePprFallbackShellFinalRender to avoid leaking uncancellable abort timers. - Add tests for await params resolving known params and for lazy dynamic-boundary marking when only non-fallback params are accessed. * fix(ppr): make awaited params preserve fallback-key suspension and getOwnPropertyDescriptor fully lazy - Promise now resolves to a Proxy (resolvedParams) instead of raw plain. The inner Proxy throws a hanging promise when a fallback param is accessed after await, so `const resolved = await params; resolved.slug` suspends. - Both outer and inner Proxy getOwnPropertyDescriptor traps return a getter that creates the hanging promise lazily. Object.keys(params) no longer triggers side effects merely by enumerating keys. - Added tests for awaited-params suspension and for enumeration not marking hasDynamicBoundary eagerly. * fix(ppr): restructure thenable-params with typed Proxy handlers and conditional observer semantics - Extract createResolvedParamsProxy with ProxyHandler<T> (no cast needed) - Extract createThenableParamsProxy with single as ThenableParams<T> boundary cast - Remove all as unknown as double casts - In fallback-shell mode, Promise continuations no longer observe all keys; let the resolved params proxy report actual property access lazily - Fix getOwnPropertyDescriptor to return throwing getter instead of throwing synchronously, preventing Object.keys from triggering suspension - Restructure awaited-params test to wrap entire async flow in ALS scope - Add test: awaiting params during fallback-shell observes only accessed known params * test(ppr): assert hasDynamicBoundary stays false after known-param access in fallback-shell observer test * fix(ppr): suspend escaped fallback params and settle warmup cache-ready without in-scope task Addresses bonk review on #1715: - Capture the originating fallback-shell state at params construction and create the suspense promise against it (via the new createPprFallbackShellSuspensePromiseForState), instead of re-reading the ALS store lazily. A params object that escapes the shell scope now still suspends on fallback-key access rather than leaking the raw `[slug]` placeholder, and the `get` / `getOwnPropertyDescriptor` traps no longer diverge on the out-of-scope path. - During warmup, always call scheduleCacheReadyIfSettled when a dynamic boundary is hit (not only in the final phase), so a bare headers()/cookies() access with an empty cache-task stack still re-schedules the warmup cache-ready settle. The call is a no-op while cache tasks are pending. Adds focused tests for both paths. * fix(ppr): keep cache-task counter and fallback suspension correct across phase transition Addresses follow-up bonk review on #1715: - Add a per-state cache epoch, bumped on the warmup->final transition. Cache tasks capture the epoch at creation; a task that settles in a later epoch no longer decrements the freshly-reset pendingCacheTasks counter below zero (which would permanently block resolveCacheReadyIfSettled). - Re-derive the memoized fallback-shell hanging promise when the live AbortController changes (preparePprFallbackShellFinalRender swaps it on the phase transition), so suspension always tracks the controller the lifecycle will actually abort instead of a stale warmup signal. Adds tests for the late warmup-task settle and the post-transition re-derive. --------- Co-authored-by: James Anderson <james@eli.cx> |