You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ppr capture budget must be configurable — deferred shell material (async Meta / top-level handle pushes) beyond 5s makes a route uncapturable #715
The consumer pattern (explicit design requirement from a production storefront)
Handlers push DEFERRED shell material — ctx.use(Meta)(dataPromise.then(...)), top-level handle pushes carrying promises — and on the live path React 19 hoisting streams the resolved metas late while the body renders. Under PPR the intended semantic is: the capture awaits the deferred material and bakes the settled values (shell fully static afterward; TTL/SWR govern freshness). The bake-lane mechanism already does exactly this — top-level pushes are awaited at capture.
The gap
SHELL_CAPTURE_MAX_WAIT_MS is a hard-coded 5s. Deferred material slower than that makes the capture refuse forever (eternal MISS with backoff + the no-usable-shell warning). Routes fit today only when their upstreams happen to be fast; there is no way to DECLARE "this route's shell material takes ~8s to settle — wait for it". Capture is background work (waitUntil): a longer budget costs latency-to-HIT only, never a served response.
Fix shape
Per-route knob: ppr: { ttl, swr, captureTimeout?: number } (ms), default the current 5s; plumb into the descriptor → captureShellHTML maxWaitMs and the handle-encode barrier so BOTH the fizz deadline and the handle settle window honor it.
The workerd waitUntil lifetime is the physical ceiling — document that.
Producer B parity: build-time captures should honor the same knob (build has no waitUntil bound).
e2e: a route with deliberately slow (>5s) deferred Meta + top-level handle push, captureTimeout set — MISS→HIT, baked meta present in the stored prelude, values frozen across HITs until TTL; and the negative (no knob → documented refusal warning). Both apps, dev + production.
Found with # on the same route; the two together are what "adopt the app's async pattern to ppr" requires.
Activity
feat(ppr): captureTimeout route option + handle-settle capture gate; …
feat(ppr): captureTimeout route option + handle-settle capture gate; …