@timber-js/app 0.2.0-alpha.9 → 0.2.0-alpha.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/actions-DLnUaR65.js +421 -0
- package/dist/_chunks/actions-DLnUaR65.js.map +1 -0
- package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-HS0LGUl2.js} +1 -1
- package/dist/_chunks/als-registry-HS0LGUl2.js.map +1 -0
- package/dist/_chunks/chunk-BYIpzuS7.js +39 -0
- package/dist/_chunks/{debug-gwlJkDuf.js → debug-ECi_61pb.js} +2 -2
- package/dist/_chunks/debug-ECi_61pb.js.map +1 -0
- package/dist/_chunks/define-C77ScO0m.js +106 -0
- package/dist/_chunks/define-C77ScO0m.js.map +1 -0
- package/dist/_chunks/define-Itxvcd7F.js +199 -0
- package/dist/_chunks/define-Itxvcd7F.js.map +1 -0
- package/dist/_chunks/define-cookie-BowvzoP0.js +94 -0
- package/dist/_chunks/define-cookie-BowvzoP0.js.map +1 -0
- package/dist/_chunks/{format-DviM89f0.js → dev-warnings-DpGRGoDi.js} +5 -44
- package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +1 -0
- package/dist/_chunks/format-CYBGxKtc.js +14 -0
- package/dist/_chunks/format-CYBGxKtc.js.map +1 -0
- package/dist/_chunks/{interception-BOoWmLUA.js → interception-ErnB33JX.js} +301 -133
- package/dist/_chunks/interception-ErnB33JX.js.map +1 -0
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js +41 -0
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-DS3eKNmf.js} +1 -1
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-DS3eKNmf.js.map} +1 -1
- package/dist/_chunks/request-context-CK5tZqIP.js +478 -0
- package/dist/_chunks/request-context-CK5tZqIP.js.map +1 -0
- package/dist/_chunks/schema-bridge-C3xl_vfb.js +86 -0
- package/dist/_chunks/schema-bridge-C3xl_vfb.js.map +1 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js +65 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js.map +1 -0
- package/dist/_chunks/segment-context-fHFLF1PE.js +34 -0
- package/dist/_chunks/segment-context-fHFLF1PE.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-DzuI0bIV.js} +1 -1
- package/dist/_chunks/{ssr-data-MjmprTmO.js.map → ssr-data-DzuI0bIV.js.map} +1 -1
- package/dist/_chunks/stale-reload-BX5gL1r-.js +64 -0
- package/dist/_chunks/stale-reload-BX5gL1r-.js.map +1 -0
- package/dist/_chunks/{tracing-CemImE6h.js → tracing-CCYbKn5n.js} +60 -9
- package/dist/_chunks/tracing-CCYbKn5n.js.map +1 -0
- package/dist/_chunks/use-params-Br9YSUFV.js +295 -0
- package/dist/_chunks/use-params-Br9YSUFV.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-BiV5GJgm.js} +7 -4
- package/dist/_chunks/use-query-states-BiV5GJgm.js.map +1 -0
- package/dist/adapters/cloudflare-dev.d.ts +109 -0
- package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +73 -0
- package/dist/adapters/cloudflare-dev.js.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +95 -0
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +148 -12
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +135 -11
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +17 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +56 -13
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/cache/cache-api.d.ts +24 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/handler-store.d.ts +31 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +23 -7
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +142 -80
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/singleflight.d.ts +18 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts +22 -0
- package/dist/cache/sizeof.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cli.d.ts +6 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +27 -1
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
- package/dist/client/browser-entry/hmr.d.ts +21 -0
- package/dist/client/browser-entry/hmr.d.ts.map +1 -0
- package/dist/client/browser-entry/hydrate.d.ts +46 -0
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
- package/dist/client/browser-entry/index.d.ts +30 -0
- package/dist/client/browser-entry/index.d.ts.map +1 -0
- package/dist/client/browser-entry/post-hydration.d.ts +26 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +23 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +19 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +12 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +10 -4
- package/dist/client/error-boundary.js.map +1 -1
- package/dist/client/error-reconstituter.d.ts +54 -0
- package/dist/client/error-reconstituter.d.ts.map +1 -0
- package/dist/client/form.d.ts +6 -3
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/history.d.ts +19 -4
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +9 -21
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +229 -1018
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +18 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +890 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link-pending-store.d.ts +63 -0
- package/dist/client/link-pending-store.d.ts.map +1 -0
- package/dist/client/link.d.ts +62 -55
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/nav-link-store.d.ts +36 -0
- package/dist/client/nav-link-store.d.ts.map +1 -0
- package/dist/client/navigation-api-types.d.ts +90 -0
- package/dist/client/navigation-api-types.d.ts.map +1 -0
- package/dist/client/navigation-api.d.ts +115 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +13 -2
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/router-ref.d.ts +1 -1
- package/dist/client/router.d.ts +70 -4
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +38 -3
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +1 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +63 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +13 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-reload.d.ts +15 -0
- package/dist/client/stale-reload.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +5 -5
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/use-link-status.d.ts +5 -5
- package/dist/client/use-link-status.d.ts.map +1 -1
- package/dist/client/use-params.d.ts +6 -4
- package/dist/client/use-params.d.ts.map +1 -1
- package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
- package/dist/client/use-pending-navigation.d.ts.map +1 -0
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +1 -1
- package/dist/codec.d.ts +33 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +2 -0
- package/dist/config-types.d.ts +266 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-validation.d.ts +51 -0
- package/dist/config-validation.d.ts.map +1 -0
- package/dist/content/index.d.ts +1 -10
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +0 -2
- package/dist/cookies/define-cookie.d.ts +35 -14
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -83
- package/dist/fonts/bundle.d.ts +48 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/css.d.ts +1 -0
- package/dist/fonts/css.d.ts.map +1 -1
- package/dist/fonts/dev-middleware.d.ts +22 -0
- package/dist/fonts/dev-middleware.d.ts.map +1 -0
- package/dist/fonts/pipeline.d.ts +138 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +72 -0
- package/dist/fonts/transform.d.ts.map +1 -0
- package/dist/fonts/types.d.ts +45 -1
- package/dist/fonts/types.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts +59 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +45 -190
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4294 -2453
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +107 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +1 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +2 -2
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +3 -3
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +32 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/content.d.ts +1 -1
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/dev-404-page.d.ts +56 -0
- package/dist/plugins/dev-404-page.d.ts.map +1 -0
- package/dist/plugins/dev-browser-logs.d.ts +84 -0
- package/dist/plugins/dev-browser-logs.d.ts.map +1 -0
- package/dist/plugins/dev-error-overlay.d.ts +49 -9
- package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
- package/dist/plugins/dev-error-page.d.ts +58 -0
- package/dist/plugins/dev-error-page.d.ts.map +1 -0
- package/dist/plugins/dev-logs.d.ts +1 -1
- package/dist/plugins/dev-logs.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/dev-terminal-error.d.ts +28 -0
- package/dist/plugins/dev-terminal-error.d.ts.map +1 -0
- package/dist/plugins/entries.d.ts +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +17 -73
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +1 -1
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts +6 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +4 -4
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +38 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +36 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts +2 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/convention-lint.d.ts +41 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/index.d.ts +2 -0
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +3 -2
- package/dist/routing/link-codegen.d.ts +90 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/segment-classify.d.ts +46 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/status-file-lint.d.ts +2 -1
- package/dist/routing/status-file-lint.d.ts.map +1 -1
- package/dist/routing/types.d.ts +16 -4
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +12 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/schema-bridge.d.ts +76 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +139 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +32 -441
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/registry.d.ts +2 -2
- package/dist/search-params/registry.d.ts.map +1 -1
- package/dist/search-params/wrappers.d.ts +53 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/segment-params/define.d.ts +78 -0
- package/dist/segment-params/define.d.ts.map +1 -0
- package/dist/segment-params/index.d.ts +3 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +2 -0
- package/dist/server/access-gate.d.ts +4 -0
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +41 -6
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/action-encryption.d.ts +76 -0
- package/dist/server/action-encryption.d.ts.map +1 -0
- package/dist/server/action-handler.d.ts +7 -0
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +3 -6
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +32 -4
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +2 -2
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/debug.d.ts +1 -1
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/deny-page-resolver.d.ts +52 -0
- package/dist/server/deny-page-resolver.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-holding-server.d.ts +52 -0
- package/dist/server/dev-holding-server.d.ts.map +1 -0
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/dev-warnings.d.ts +1 -21
- package/dist/server/dev-warnings.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -5
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -1
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +12 -7
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/flight-injection-state.d.ts +66 -0
- package/dist/server/flight-injection-state.d.ts.map +1 -0
- package/dist/server/flight-scripts.d.ts +42 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/flush.d.ts.map +1 -1
- package/dist/server/form-data.d.ts +29 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/html-injectors.d.ts +51 -11
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -43
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +195 -2800
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +46 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +2900 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +25 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +19 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +113 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/page-deny-boundary.d.ts +31 -0
- package/dist/server/page-deny-boundary.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +1 -1
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-metadata.d.ts +6 -0
- package/dist/server/pipeline-metadata.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +52 -10
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +69 -18
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +112 -43
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +27 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +16 -2
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +2 -2
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +48 -5
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +20 -3
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +14 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sensitive-fields.d.ts +74 -0
- package/dist/server/sensitive-fields.d.ts.map +1 -0
- package/dist/server/sitemap-generator.d.ts +129 -0
- package/dist/server/sitemap-generator.d.ts.map +1 -0
- package/dist/server/sitemap-handler.d.ts +22 -0
- package/dist/server/sitemap-handler.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +1 -1
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +23 -0
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +39 -21
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +50 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +1 -1
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +36 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +4 -4
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +22 -19
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/shared/merge-search-params.d.ts +22 -0
- package/dist/shared/merge-search-params.d.ts.map +1 -0
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.js +42 -0
- package/dist/shims/font-google.js.map +1 -0
- package/dist/shims/font-local.d.ts +26 -0
- package/dist/shims/font-local.d.ts.map +1 -0
- package/dist/shims/font-local.js +20 -0
- package/dist/shims/font-local.js.map +1 -0
- package/dist/shims/headers.d.ts +2 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/navigation-client.d.ts +1 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +3 -2
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/directive-parser.d.ts +5 -2
- package/dist/utils/directive-parser.d.ts.map +1 -1
- package/dist/utils/state-machine.d.ts +80 -0
- package/dist/utils/state-machine.d.ts.map +1 -0
- package/package.json +51 -16
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +142 -0
- package/src/adapters/cloudflare.ts +342 -28
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +52 -8
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +38 -0
- package/src/cache/handler-store.ts +68 -0
- package/src/cache/index.ts +81 -18
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/sizeof.ts +31 -0
- package/src/cache/timber-cache.ts +24 -20
- package/src/cli.ts +16 -6
- package/src/client/browser-dev.ts +128 -1
- package/src/client/browser-entry/action-dispatch.ts +116 -0
- package/src/client/browser-entry/hmr.ts +81 -0
- package/src/client/browser-entry/hydrate.ts +145 -0
- package/src/client/browser-entry/index.ts +143 -0
- package/src/client/browser-entry/post-hydration.ts +119 -0
- package/src/client/browser-entry/router-init.ts +193 -0
- package/src/client/browser-entry/rsc-stream.ts +157 -0
- package/src/client/browser-entry/scroll.ts +27 -0
- package/src/client/error-boundary.tsx +48 -16
- package/src/client/error-reconstituter.tsx +65 -0
- package/src/client/form.tsx +14 -7
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +65 -38
- package/src/client/internal.ts +57 -0
- package/src/client/link-pending-store.ts +111 -0
- package/src/client/link.tsx +342 -113
- package/src/client/nav-link-store.ts +47 -0
- package/src/client/navigation-api-types.ts +112 -0
- package/src/client/navigation-api.ts +332 -0
- package/src/client/navigation-context.ts +31 -6
- package/src/client/navigation-root.tsx +342 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router-ref.ts +1 -1
- package/src/client/router.ts +299 -72
- package/src/client/rsc-fetch.ts +97 -8
- package/src/client/segment-cache.ts +1 -1
- package/src/client/segment-outlet.tsx +86 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/stale-reload.ts +72 -3
- package/src/client/top-loader.tsx +18 -6
- package/src/client/use-link-status.ts +7 -7
- package/src/client/use-params.ts +7 -5
- package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
- package/src/client/use-query-states.ts +9 -3
- package/src/client/use-router.ts +1 -1
- package/src/codec.ts +49 -0
- package/src/config-types.ts +264 -0
- package/src/config-validation.ts +303 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +78 -25
- package/src/cookies/index.ts +8 -0
- package/src/fonts/bundle.ts +142 -0
- package/src/fonts/css.ts +2 -1
- package/src/fonts/dev-middleware.ts +74 -0
- package/src/fonts/pipeline.ts +275 -0
- package/src/fonts/transform.ts +353 -0
- package/src/fonts/types.ts +50 -1
- package/src/fonts/virtual-modules.ts +159 -0
- package/src/index.ts +314 -355
- package/src/plugin-context.ts +240 -0
- package/src/plugins/adapter-build.ts +9 -3
- package/src/plugins/build-manifest.ts +13 -2
- package/src/plugins/build-report.ts +3 -3
- package/src/plugins/client-chunks.ts +65 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-404-page.ts +418 -0
- package/src/plugins/dev-browser-logs.ts +288 -0
- package/src/plugins/dev-error-overlay.ts +286 -42
- package/src/plugins/dev-error-page.ts +536 -0
- package/src/plugins/dev-logs.ts +1 -1
- package/src/plugins/dev-server.ts +146 -19
- package/src/plugins/dev-terminal-error.ts +217 -0
- package/src/plugins/entries.ts +111 -10
- package/src/plugins/fonts.ts +133 -638
- package/src/plugins/mdx.ts +1 -1
- package/src/plugins/routing.ts +213 -31
- package/src/plugins/server-action-exports.ts +1 -1
- package/src/plugins/server-bundle.ts +32 -1
- package/src/plugins/shims.ts +136 -35
- package/src/plugins/static-build.ts +17 -11
- package/src/routing/codegen-shared.ts +74 -0
- package/src/routing/codegen-types.ts +37 -0
- package/src/routing/codegen.ts +112 -173
- package/src/routing/convention-lint.ts +356 -0
- package/src/routing/index.ts +2 -0
- package/src/routing/link-codegen.ts +262 -0
- package/src/routing/scanner.ts +93 -23
- package/src/routing/segment-classify.ts +89 -0
- package/src/routing/status-file-lint.ts +3 -2
- package/src/routing/types.ts +17 -4
- package/src/rsc-runtime/rsc.ts +2 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
- package/src/search-params/define.ts +482 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/registry.ts +2 -2
- package/src/search-params/wrappers.ts +85 -0
- package/src/segment-params/define.ts +279 -0
- package/src/segment-params/index.ts +9 -0
- package/src/server/access-gate.tsx +70 -29
- package/src/server/action-client.ts +88 -15
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +53 -6
- package/src/server/actions.ts +10 -9
- package/src/server/als-registry.ts +34 -6
- package/src/server/build-manifest.ts +10 -4
- package/src/server/compress.ts +25 -7
- package/src/server/debug.ts +1 -1
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-page-resolver.ts +154 -0
- package/src/server/deny-renderer.ts +24 -38
- package/src/server/dev-holding-server.ts +185 -0
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/dev-warnings.ts +4 -49
- package/src/server/early-hints.ts +36 -15
- package/src/server/error-boundary-wrapper.ts +74 -22
- package/src/server/fallback-error.ts +74 -102
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +62 -0
- package/src/server/flush.ts +2 -1
- package/src/server/form-data.ts +76 -0
- package/src/server/html-injectors.ts +280 -120
- package/src/server/index.ts +25 -177
- package/src/server/internal.ts +169 -0
- package/src/server/logger.ts +44 -36
- package/src/server/middleware-runner.ts +31 -4
- package/src/server/node-stream-transforms.ts +509 -0
- package/src/server/page-deny-boundary.tsx +56 -0
- package/src/server/pipeline-interception.ts +17 -16
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline.ts +261 -66
- package/src/server/primitives.ts +111 -28
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +293 -132
- package/src/server/route-element-builder.ts +283 -191
- package/src/server/route-handler.ts +24 -4
- package/src/server/route-matcher.ts +31 -20
- package/src/server/rsc-entry/api-handler.ts +15 -16
- package/src/server/rsc-entry/error-renderer.ts +305 -89
- package/src/server/rsc-entry/helpers.ts +134 -5
- package/src/server/rsc-entry/index.ts +304 -111
- package/src/server/rsc-entry/rsc-payload.ts +65 -18
- package/src/server/rsc-entry/rsc-stream.ts +81 -13
- package/src/server/rsc-entry/ssr-bridge.ts +14 -5
- package/src/server/rsc-entry/ssr-renderer.ts +171 -38
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/sitemap-generator.ts +338 -0
- package/src/server/sitemap-handler.ts +126 -0
- package/src/server/slot-resolver.ts +244 -229
- package/src/server/ssr-entry.ts +215 -32
- package/src/server/ssr-render.ts +289 -67
- package/src/server/ssr-wrappers.tsx +139 -0
- package/src/server/status-code-resolver.ts +1 -1
- package/src/server/stream-utils.ts +213 -0
- package/src/server/tracing.ts +20 -9
- package/src/server/tree-builder.ts +92 -58
- package/src/server/types.ts +3 -6
- package/src/server/version-skew.ts +104 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/headers.ts +5 -1
- package/src/shims/navigation-client.ts +1 -1
- package/src/shims/navigation.ts +7 -2
- package/src/utils/directive-parser.ts +5 -2
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
- package/dist/_chunks/format-DviM89f0.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
- package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
- package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
- package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
- package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
- package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
- package/dist/cache/register-cached-function.d.ts +0 -17
- package/dist/cache/register-cached-function.d.ts.map +0 -1
- package/dist/client/browser-entry.d.ts +0 -21
- package/dist/client/browser-entry.d.ts.map +0 -1
- package/dist/client/link-status-provider.d.ts +0 -11
- package/dist/client/link-status-provider.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/client/use-navigation-pending.d.ts.map +0 -1
- package/dist/cookies/index.js.map +0 -1
- package/dist/plugins/cache-transform.d.ts +0 -36
- package/dist/plugins/cache-transform.d.ts.map +0 -1
- package/dist/plugins/dynamic-transform.d.ts +0 -72
- package/dist/plugins/dynamic-transform.d.ts.map +0 -1
- package/dist/search-params/analyze.d.ts +0 -54
- package/dist/search-params/analyze.d.ts.map +0 -1
- package/dist/search-params/builtin-codecs.d.ts +0 -105
- package/dist/search-params/builtin-codecs.d.ts.map +0 -1
- package/dist/search-params/codecs.d.ts +0 -53
- package/dist/search-params/codecs.d.ts.map +0 -1
- package/dist/search-params/create.d.ts +0 -106
- package/dist/search-params/create.d.ts.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/server/response-cache.d.ts +0 -54
- package/dist/server/response-cache.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -103
- package/src/client/browser-entry.ts +0 -678
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/transition-root.tsx +0 -166
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/create.ts +0 -321
- package/src/server/prerender.ts +0 -139
- package/src/server/response-cache.ts +0 -410
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
* 16-metadata.md §"Head Elements"
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import type { LayoutEntry } from '
|
|
13
|
-
import { renderDenyPageAsRsc } from '
|
|
14
|
-
import type { RouteMatch } from '
|
|
15
|
-
import type { RedirectSignal } from '
|
|
16
|
-
import type { HeadElement, LayoutComponentEntry } from '
|
|
17
|
-
import type { ManifestSegmentNode } from '
|
|
12
|
+
import type { LayoutEntry } from '../deny-renderer.js';
|
|
13
|
+
import { renderDenyPageAsRsc } from '../deny-renderer.js';
|
|
14
|
+
import type { RouteMatch } from '../pipeline.js';
|
|
15
|
+
import type { RedirectSignal } from '../primitives.js';
|
|
16
|
+
import type { HeadElement, LayoutComponentEntry } from '../route-element-builder.js';
|
|
17
|
+
import type { ManifestSegmentNode } from '../route-matcher.js';
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
20
|
buildRedirectResponse,
|
|
@@ -69,10 +69,25 @@ export async function buildRscPayloadResponse(
|
|
|
69
69
|
| { type: 'data'; chunk: ReadableStreamReadResult<Uint8Array> }
|
|
70
70
|
| { type: 'signal' };
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
let first: RaceResult;
|
|
73
|
+
try {
|
|
74
|
+
first = await Promise.race([
|
|
75
|
+
reader.read().then((chunk) => ({ type: 'data' as const, chunk })),
|
|
76
|
+
signalDetected.then(() => ({ type: 'signal' as const })),
|
|
77
|
+
]);
|
|
78
|
+
} catch (_readError) {
|
|
79
|
+
// RSC stream failed on first read — unhandled error in the page component.
|
|
80
|
+
// Return an error response so the client can hard-navigate for the
|
|
81
|
+
// SSR-rendered error page. See design/10-error-handling.md.
|
|
82
|
+
reader.cancel().catch(() => {});
|
|
83
|
+
signals.onSignal = undefined;
|
|
84
|
+
responseHeaders.set('X-Timber-Error', '1');
|
|
85
|
+
responseHeaders.set('content-type', 'application/json; charset=utf-8');
|
|
86
|
+
return new Response(JSON.stringify({ error: true, status: 500 }), {
|
|
87
|
+
status: 500,
|
|
88
|
+
headers: responseHeaders,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
76
91
|
|
|
77
92
|
// If data arrived first, still check signals — they may have fired
|
|
78
93
|
// concurrently. Also do a final ceiling timeout check for edge cases
|
|
@@ -102,10 +117,36 @@ export async function buildRscPayloadResponse(
|
|
|
102
117
|
);
|
|
103
118
|
}
|
|
104
119
|
|
|
120
|
+
// Check for unhandled errors (RenderError or plain Error).
|
|
121
|
+
// These aren't redirect/deny signals but the RSC stream will be broken.
|
|
122
|
+
// Return an error response so the client can hard-navigate for the
|
|
123
|
+
// SSR-rendered error page. See design/10-error-handling.md
|
|
124
|
+
// §"Error Page Rendering for Client Navigation".
|
|
125
|
+
if (signals.renderError) {
|
|
126
|
+
reader.cancel().catch(() => {});
|
|
127
|
+
responseHeaders.set('X-Timber-Error', '1');
|
|
128
|
+
responseHeaders.set('content-type', 'application/json; charset=utf-8');
|
|
129
|
+
return new Response(
|
|
130
|
+
JSON.stringify({
|
|
131
|
+
error: true,
|
|
132
|
+
status: signals.renderError.status,
|
|
133
|
+
}),
|
|
134
|
+
{ status: signals.renderError.status, headers: responseHeaders }
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
105
138
|
// Extract the first chunk from the race result.
|
|
106
|
-
// If the signal won the race
|
|
107
|
-
//
|
|
108
|
-
|
|
139
|
+
// If the signal won the race but neither redirect nor deny was detected
|
|
140
|
+
// (edge case), cancel the reader immediately rather than issuing a bare
|
|
141
|
+
// read() that could hang forever if the RSC stream has stalled.
|
|
142
|
+
// See TIM-519.
|
|
143
|
+
let firstRead: ReadableStreamReadResult<Uint8Array>;
|
|
144
|
+
if (first.type === 'data') {
|
|
145
|
+
firstRead = first.chunk;
|
|
146
|
+
} else {
|
|
147
|
+
await reader.cancel();
|
|
148
|
+
firstRead = { done: true, value: undefined };
|
|
149
|
+
}
|
|
109
150
|
|
|
110
151
|
// Reconstruct the stream: prepend the buffered first chunk,
|
|
111
152
|
// then continue piping from the original reader.
|
|
@@ -155,14 +196,20 @@ export async function buildRscPayloadResponse(
|
|
|
155
196
|
responseHeaders.set('X-Timber-Skipped-Segments', JSON.stringify(skippedSegments));
|
|
156
197
|
}
|
|
157
198
|
|
|
158
|
-
// Send route params so the client can populate
|
|
159
|
-
// SPA navigation. Without this,
|
|
160
|
-
if (Object.keys(match.
|
|
161
|
-
responseHeaders.set('X-Timber-Params', JSON.stringify(match.
|
|
199
|
+
// Send route params so the client can populate useSegmentParams() after
|
|
200
|
+
// SPA navigation. Without this, useSegmentParams() returns {}.
|
|
201
|
+
if (Object.keys(match.segmentParams).length > 0) {
|
|
202
|
+
responseHeaders.set('X-Timber-Params', JSON.stringify(match.segmentParams));
|
|
162
203
|
}
|
|
163
204
|
|
|
205
|
+
// Check if a DenySignal was caught in-tree by AccessGate or
|
|
206
|
+
// PageDenyBoundary. The deny page is in the Flight stream as a normal
|
|
207
|
+
// element — use the deny status for the HTTP response. See TIM-666.
|
|
208
|
+
const { getDenyStatus } = await import('../deny-page-resolver.js');
|
|
209
|
+
const denyStatus = getDenyStatus();
|
|
210
|
+
|
|
164
211
|
return new Response(patchedStream, {
|
|
165
|
-
status: 200,
|
|
212
|
+
status: denyStatus ?? 200,
|
|
166
213
|
headers: responseHeaders,
|
|
167
214
|
});
|
|
168
215
|
}
|
|
@@ -10,14 +10,22 @@
|
|
|
10
10
|
* 13-security.md §"Errors don't leak"
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { renderToReadableStream } from '
|
|
13
|
+
import { renderToReadableStream } from '../../rsc-runtime/rsc.js';
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
import { DenySignal, RedirectSignal, RenderError } from '#/server/primitives.js';
|
|
17
|
-
import { checkAndWarnRscPropError } from '#/server/rsc-prop-warnings.js';
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
18
16
|
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
17
|
+
import { logRenderError } from '../logger.js';
|
|
18
|
+
import { DenySignal, RedirectSignal, RenderError } from '../primitives.js';
|
|
19
|
+
import { checkAndWarnRscPropError } from '../rsc-prop-warnings.js';
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
createDebugChannelSink,
|
|
23
|
+
createDebugChannelCollector,
|
|
24
|
+
isAbortError,
|
|
25
|
+
type DebugComponentEntry,
|
|
26
|
+
} from './helpers.js';
|
|
27
|
+
import { isDebug } from '../debug.js';
|
|
28
|
+
import { isDevMode } from '../debug.js';
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
31
|
* Mutable signal state captured during RSC rendering.
|
|
@@ -33,6 +41,16 @@ export interface RenderSignals {
|
|
|
33
41
|
denySignal: DenySignal | null;
|
|
34
42
|
redirectSignal: RedirectSignal | null;
|
|
35
43
|
renderError: { error: unknown; status: number } | null;
|
|
44
|
+
/**
|
|
45
|
+
* The last unhandled error seen by RSC onError that isn't a signal.
|
|
46
|
+
* Used as a fallback when SSR fails (SsrStreamError) but no structured
|
|
47
|
+
* signal was captured — provides the original error for the error page
|
|
48
|
+
* instead of relying on SsrStreamError.cause extraction.
|
|
49
|
+
*
|
|
50
|
+
* NOT used for page-level error detection (that would break Suspense
|
|
51
|
+
* error isolation). Only consumed when SSR actually fails.
|
|
52
|
+
*/
|
|
53
|
+
lastUnhandledError: unknown | null;
|
|
36
54
|
/** Callback fired when a redirect or deny signal is captured in onError. */
|
|
37
55
|
onSignal?: () => void;
|
|
38
56
|
}
|
|
@@ -40,6 +58,8 @@ export interface RenderSignals {
|
|
|
40
58
|
export interface RscStreamResult {
|
|
41
59
|
rscStream: ReadableStream<Uint8Array> | undefined;
|
|
42
60
|
signals: RenderSignals;
|
|
61
|
+
/** Dev-only: server component debug info from the Flight debug channel. */
|
|
62
|
+
getDebugComponents?: () => DebugComponentEntry[];
|
|
43
63
|
}
|
|
44
64
|
|
|
45
65
|
/**
|
|
@@ -58,10 +78,15 @@ export function renderRscStream(element: React.ReactElement, req: Request): RscS
|
|
|
58
78
|
denySignal: null,
|
|
59
79
|
redirectSignal: null,
|
|
60
80
|
renderError: null,
|
|
81
|
+
lastUnhandledError: null,
|
|
61
82
|
};
|
|
62
83
|
|
|
63
84
|
let rscStream: ReadableStream<Uint8Array> | undefined;
|
|
64
85
|
|
|
86
|
+
// In dev mode, collect debug channel data for the error overlay.
|
|
87
|
+
// In production, use the discard sink (no overhead).
|
|
88
|
+
const debugChannel = isDevMode() ? createDebugChannelCollector() : createDebugChannelSink();
|
|
89
|
+
|
|
65
90
|
try {
|
|
66
91
|
rscStream = renderToReadableStream(
|
|
67
92
|
element,
|
|
@@ -126,13 +151,47 @@ export function renderRscStream(element: React.ReactElement, req: Request): RscS
|
|
|
126
151
|
checkAndWarnRscPropError(error, new URL(req.url).pathname);
|
|
127
152
|
}
|
|
128
153
|
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
// Log the error but do NOT track it as a page-level render error.
|
|
155
|
+
// If this error is inside a <Suspense> boundary, React will emit
|
|
156
|
+
// an error row in the Flight stream and the Suspense fallback will
|
|
157
|
+
// render on the client. Tracking it as signals.renderError would
|
|
158
|
+
// cause the pipeline to treat the entire page as a 500, even though
|
|
159
|
+
// the shell rendered successfully. See TIM-524.
|
|
160
|
+
//
|
|
161
|
+
// Only track as renderError if no Suspense boundary contains it —
|
|
162
|
+
// React will call onShellError for truly unrecoverable errors.
|
|
163
|
+
|
|
164
|
+
// Track the last unhandled error so the pipeline can use it
|
|
165
|
+
// if SSR fails (SsrStreamError). This is NOT used for page-level
|
|
166
|
+
// error detection — only as a fallback when SSR actually fails.
|
|
167
|
+
signals.lastUnhandledError = error;
|
|
168
|
+
|
|
169
|
+
// Return a digest so React emits a per-row error in the Flight
|
|
170
|
+
// stream instead of leaving the lazy reference unresolved.
|
|
171
|
+
//
|
|
172
|
+
// SECURITY: Never include error.message in the digest — it may
|
|
173
|
+
// contain SQL queries, filesystem paths, secret fragments, or
|
|
174
|
+
// internal IDs. Use a generic message with a correlation ID so
|
|
175
|
+
// the error can be matched to server logs.
|
|
176
|
+
// See design/13-security.md §"Errors don't leak".
|
|
177
|
+
const errorId = randomUUID();
|
|
178
|
+
logRenderError({
|
|
179
|
+
method: req.method,
|
|
180
|
+
path: new URL(req.url).pathname,
|
|
181
|
+
error,
|
|
182
|
+
errorId,
|
|
183
|
+
});
|
|
184
|
+
return JSON.stringify({
|
|
185
|
+
type: 'error',
|
|
186
|
+
message: isDevMode()
|
|
187
|
+
? error instanceof Error
|
|
188
|
+
? error.message
|
|
189
|
+
: String(error)
|
|
190
|
+
: 'An unexpected error occurred.',
|
|
191
|
+
errorId,
|
|
192
|
+
});
|
|
134
193
|
},
|
|
135
|
-
debugChannel
|
|
194
|
+
debugChannel,
|
|
136
195
|
},
|
|
137
196
|
{
|
|
138
197
|
onClientReference(info: { id: string; name: string; deps: unknown }) {
|
|
@@ -160,5 +219,14 @@ export function renderRscStream(element: React.ReactElement, req: Request): RscS
|
|
|
160
219
|
}
|
|
161
220
|
}
|
|
162
221
|
|
|
163
|
-
return {
|
|
222
|
+
return {
|
|
223
|
+
rscStream,
|
|
224
|
+
signals,
|
|
225
|
+
// Expose the debug channel collector's getComponents in dev mode.
|
|
226
|
+
// The caller can retrieve component tree info when handling errors.
|
|
227
|
+
getDebugComponents:
|
|
228
|
+
'getComponents' in debugChannel
|
|
229
|
+
? (debugChannel as { getComponents: () => DebugComponentEntry[] }).getComponents
|
|
230
|
+
: undefined,
|
|
231
|
+
};
|
|
164
232
|
}
|
|
@@ -4,15 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
/// <reference types="@vitejs/plugin-rsc/types" />
|
|
6
6
|
|
|
7
|
-
import type { NavContext } from '
|
|
7
|
+
import type { NavContext } from '../ssr-entry.js';
|
|
8
8
|
|
|
9
9
|
export async function callSsr(
|
|
10
10
|
rscStream: ReadableStream<Uint8Array>,
|
|
11
11
|
navContext: NavContext
|
|
12
12
|
): Promise<Response> {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
let ssrEntry: typeof import('../ssr-entry.js');
|
|
14
|
+
try {
|
|
15
|
+
ssrEntry = await import.meta.viteRsc.import<typeof import('../ssr-entry.js')>(
|
|
16
|
+
'../ssr-entry.js',
|
|
17
|
+
{ environment: 'ssr' }
|
|
18
|
+
);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
const original = error instanceof Error ? error.message : String(error);
|
|
21
|
+
throw new Error(
|
|
22
|
+
`[timber] Failed to load SSR entry from RSC environment.\n ${original}\n This usually means a module evaluation error in the SSR bundle.`,
|
|
23
|
+
{ cause: error }
|
|
24
|
+
);
|
|
25
|
+
}
|
|
17
26
|
return ssrEntry.handleSsr(rscStream, navContext);
|
|
18
27
|
}
|
|
@@ -12,25 +12,49 @@
|
|
|
12
12
|
* 05-streaming.md §"deferSuspenseFor and the Hold Window"
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import type { ClientBootstrapConfig } from '
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import
|
|
21
|
-
import type {
|
|
22
|
-
import type {
|
|
15
|
+
import type { ClientBootstrapConfig } from '../html-injectors.js';
|
|
16
|
+
import { flightInitScript } from '../flight-scripts.js';
|
|
17
|
+
import type { LayoutEntry } from '../deny-renderer.js';
|
|
18
|
+
import { renderDenyPage } from '../deny-renderer.js';
|
|
19
|
+
import type { RouteMatch } from '../pipeline.js';
|
|
20
|
+
import { SsrStreamError } from '../primitives.js';
|
|
21
|
+
import type { LayoutComponentEntry } from '../route-element-builder.js';
|
|
22
|
+
import type { ManifestSegmentNode } from '../route-matcher.js';
|
|
23
|
+
import type { NavContext } from '../ssr-entry.js';
|
|
23
24
|
|
|
24
25
|
import {
|
|
25
26
|
buildRedirectResponse,
|
|
26
27
|
buildSegmentInfo,
|
|
27
28
|
createDebugChannelSink,
|
|
28
29
|
isAbortError,
|
|
29
|
-
parseCookiesFromHeader,
|
|
30
30
|
} from './helpers.js';
|
|
31
|
-
import {
|
|
31
|
+
import { getCookiesForSsr } from '../request-context.js';
|
|
32
|
+
import { getDenyStatus } from '../deny-page-resolver.js';
|
|
33
|
+
import { renderErrorPage, type GlobalErrorFile } from './error-renderer.js';
|
|
32
34
|
import { callSsr } from './ssr-bridge.js';
|
|
33
35
|
import type { RenderSignals } from './rsc-stream.js';
|
|
36
|
+
import { recordTiming } from '../server-timing.js';
|
|
37
|
+
import { teeWithErrorPropagation } from '../stream-utils.js';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Maximum number of queueMicrotask yields during signal promotion.
|
|
41
|
+
* The known rejection chain depth for a withSpan-wrapped component is 3+
|
|
42
|
+
* microtasks. We use 5 to tolerate additional async wrappers or React
|
|
43
|
+
* Flight internals adding extra microtask hops. Do not increase beyond 8 —
|
|
44
|
+
* a deeper chain indicates a structural problem.
|
|
45
|
+
*/
|
|
46
|
+
const SIGNAL_PROMOTION_MAX_YIELDS = 5;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Test-only observable: records how many microtask yields were consumed
|
|
50
|
+
* during the last signal promotion check. Import this in tests to assert
|
|
51
|
+
* the actual rejection chain depth and detect regressions if wrappers
|
|
52
|
+
* add more async hops.
|
|
53
|
+
*
|
|
54
|
+
* Only populated when the object is imported and exists — production
|
|
55
|
+
* bundles that don't import it pay zero cost (the typeof check is free).
|
|
56
|
+
*/
|
|
57
|
+
export const __test_only_signalPromotionDepth: { value: number } = { value: 0 };
|
|
34
58
|
|
|
35
59
|
interface SsrRenderOptions {
|
|
36
60
|
req: Request;
|
|
@@ -44,6 +68,8 @@ interface SsrRenderOptions {
|
|
|
44
68
|
clientJsDisabled: boolean;
|
|
45
69
|
headHtml: string;
|
|
46
70
|
deferSuspenseFor: number;
|
|
71
|
+
/** Tier 2 global-error.tsx file, if present in app/. */
|
|
72
|
+
globalError?: GlobalErrorFile;
|
|
47
73
|
}
|
|
48
74
|
|
|
49
75
|
/**
|
|
@@ -77,11 +103,26 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
77
103
|
clientJsDisabled,
|
|
78
104
|
headHtml,
|
|
79
105
|
deferSuspenseFor,
|
|
106
|
+
globalError,
|
|
80
107
|
} = opts;
|
|
81
108
|
|
|
82
109
|
// Tee the RSC stream — one copy goes to SSR for HTML rendering,
|
|
83
110
|
// the other is inlined in the HTML for client-side hydration.
|
|
84
|
-
|
|
111
|
+
// Uses teeWithErrorPropagation to ensure errors on either branch
|
|
112
|
+
// cancel the other (preventing hung responses) and to monitor
|
|
113
|
+
// buffer divergence between SSR and inline consumers.
|
|
114
|
+
//
|
|
115
|
+
// When client JS is disabled, skip the tee — the inline stream would
|
|
116
|
+
// never be consumed, causing monotonic buffer divergence that eventually
|
|
117
|
+
// triggers the 5MB guard and cancels the SSR stream.
|
|
118
|
+
let ssrStream: ReadableStream<Uint8Array>;
|
|
119
|
+
let inlineStream: ReadableStream<Uint8Array> | undefined;
|
|
120
|
+
if (clientJsDisabled) {
|
|
121
|
+
ssrStream = rscStream;
|
|
122
|
+
inlineStream = undefined;
|
|
123
|
+
} else {
|
|
124
|
+
[ssrStream, inlineStream] = teeWithErrorPropagation(rscStream);
|
|
125
|
+
}
|
|
85
126
|
|
|
86
127
|
// Embed segment metadata in HTML for initial hydration.
|
|
87
128
|
// The client reads this to populate its segment cache before the
|
|
@@ -91,26 +132,33 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
91
132
|
? ''
|
|
92
133
|
: `<script>self.__timber_segments=${JSON.stringify(buildSegmentInfo(segments, layoutComponents))}</script>`;
|
|
93
134
|
|
|
94
|
-
// Embed route params in HTML so
|
|
95
|
-
// Without this,
|
|
135
|
+
// Embed route params in HTML so useSegmentParams() works on initial hydration.
|
|
136
|
+
// Without this, useSegmentParams() returns {} until the first client navigation.
|
|
96
137
|
const paramsScript =
|
|
97
|
-
clientJsDisabled || Object.keys(match.
|
|
138
|
+
clientJsDisabled || Object.keys(match.segmentParams).length === 0
|
|
98
139
|
? ''
|
|
99
|
-
: `<script>self.__timber_params=${JSON.stringify(match.
|
|
140
|
+
: `<script>self.__timber_params=${JSON.stringify(match.segmentParams)}</script>`;
|
|
100
141
|
|
|
101
142
|
const navContext: NavContext = {
|
|
102
143
|
pathname: new URL(req.url).pathname,
|
|
103
|
-
params: match.
|
|
144
|
+
params: match.segmentParams,
|
|
104
145
|
searchParams: Object.fromEntries(new URL(req.url).searchParams),
|
|
105
146
|
statusCode: 200,
|
|
106
147
|
responseHeaders,
|
|
107
|
-
headHtml:
|
|
148
|
+
headHtml:
|
|
149
|
+
headHtml +
|
|
150
|
+
clientBootstrap.preloadLinks +
|
|
151
|
+
segmentScript +
|
|
152
|
+
paramsScript +
|
|
153
|
+
// Initialize __timber_f in <head> so it exists before any streaming
|
|
154
|
+
// chunk scripts arrive in <body>. See flight-scripts.ts, LOCAL-415.
|
|
155
|
+
(clientJsDisabled ? '' : flightInitScript()),
|
|
108
156
|
bootstrapScriptContent: clientBootstrap.bootstrapScriptContent,
|
|
109
157
|
// Skip RSC inline stream when client JS is disabled — no client to hydrate.
|
|
110
158
|
rscStream: clientJsDisabled ? undefined : inlineStream,
|
|
111
159
|
deferSuspenseFor: deferSuspenseFor > 0 ? deferSuspenseFor : undefined,
|
|
112
160
|
signal: req.signal,
|
|
113
|
-
cookies:
|
|
161
|
+
cookies: getCookiesForSsr(),
|
|
114
162
|
};
|
|
115
163
|
|
|
116
164
|
// Helper: check if render-phase signals were captured and return the
|
|
@@ -118,14 +166,19 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
118
166
|
// promotion from Suspense) and failed SSR (signal outside Suspense).
|
|
119
167
|
//
|
|
120
168
|
// When `skipHandledDeny` is true (SSR success path), skip DenySignal
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
169
|
+
// re-render if the denial was already handled by a TimberErrorBoundary.
|
|
170
|
+
// The boundary renders the deny page as its fallback AND sets the correct
|
|
171
|
+
// HTTP status code on navContext — no redundant renderDenyPage() needed.
|
|
172
|
+
// See TIM-664, LOCAL-298.
|
|
124
173
|
function checkCapturedSignals(skipHandledDeny = false): Response | Promise<Response> | null {
|
|
125
174
|
if (signals.redirectSignal) {
|
|
126
175
|
return buildRedirectResponse(req, signals.redirectSignal, responseHeaders);
|
|
127
176
|
}
|
|
128
177
|
if (signals.denySignal && !(skipHandledDeny && navContext._denyHandledByBoundary)) {
|
|
178
|
+
// Deny was not handled by an in-tree error boundary.
|
|
179
|
+
// Fall back to renderDenyPage (separate React.cache scope).
|
|
180
|
+
// For single-render behavior, add a 'use client' status-code file
|
|
181
|
+
// (e.g., 4xx.tsx) — the error boundary handles it in-tree.
|
|
129
182
|
return renderDenyPage(
|
|
130
183
|
signals.denySignal,
|
|
131
184
|
segments,
|
|
@@ -147,7 +200,8 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
147
200
|
req,
|
|
148
201
|
match,
|
|
149
202
|
responseHeaders,
|
|
150
|
-
clientBootstrap
|
|
203
|
+
clientBootstrap,
|
|
204
|
+
globalError
|
|
151
205
|
);
|
|
152
206
|
}
|
|
153
207
|
return null;
|
|
@@ -156,18 +210,51 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
156
210
|
try {
|
|
157
211
|
const ssrResponse = await callSsr(ssrStream, navContext);
|
|
158
212
|
|
|
213
|
+
// Record SSR sub-phase timings for Server-Timing header (detailed mode).
|
|
214
|
+
// These are populated by handleSsr() in the SSR environment and passed
|
|
215
|
+
// back via navContext._ssrTimings across the RSC→SSR boundary.
|
|
216
|
+
if (navContext._ssrTimings) {
|
|
217
|
+
const t = navContext._ssrTimings;
|
|
218
|
+
recordTiming({ name: 'ssr-decode', dur: t.decodeMs, desc: 'RSC Flight decode' });
|
|
219
|
+
recordTiming({ name: 'ssr-shell', dur: t.shellMs, desc: 'Fizz onShellReady' });
|
|
220
|
+
recordTiming({ name: 'ssr-pipeline', dur: t.pipelineMs, desc: 'stream transforms' });
|
|
221
|
+
recordTiming({
|
|
222
|
+
name: 'ssr-total',
|
|
223
|
+
dur: t.totalMs,
|
|
224
|
+
desc: t.nodeStreams ? 'SSR (Node streams)' : 'SSR (Web Streams)',
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
159
228
|
// Signal promotion: check if any signals were captured during rendering
|
|
160
|
-
// inside Suspense boundaries. If no signals are present yet, yield
|
|
161
|
-
//
|
|
162
|
-
//
|
|
229
|
+
// inside Suspense boundaries. If no signals are present yet, yield
|
|
230
|
+
// multiple microtasks so async component rejections propagate through
|
|
231
|
+
// the full rejection chain to the RSC onError callback before we
|
|
232
|
+
// commit the response.
|
|
233
|
+
//
|
|
234
|
+
// The known rejection chain depth for a withSpan-wrapped page:
|
|
235
|
+
// 1. PageComponent throws DenySignal/RedirectSignal
|
|
236
|
+
// 2. withSpan catches and re-throws (microtask 1)
|
|
237
|
+
// 3. TracedPage promise rejects (microtask 2)
|
|
238
|
+
// 4. React Flight rejection handler → onError (microtask 3+)
|
|
239
|
+
//
|
|
240
|
+
// A single queueMicrotask only advances the queue by one step, which
|
|
241
|
+
// is insufficient for chains deeper than 1. We retry up to
|
|
242
|
+
// SIGNAL_PROMOTION_MAX_YIELDS (5) times, exiting early as soon as a
|
|
243
|
+
// signal is detected. This tolerates future wrappers adding depth
|
|
244
|
+
// without requiring code changes.
|
|
163
245
|
//
|
|
164
246
|
// When signals are already captured (onSignal already fired), skip the
|
|
165
247
|
// yield entirely — react immediately. Uses queueMicrotask instead of
|
|
166
|
-
// setTimeout(0)
|
|
167
|
-
// loop (timers phase).
|
|
248
|
+
// setTimeout(0) to avoid yielding to the full event loop (timers phase).
|
|
168
249
|
// See design/05-streaming.md §"deferSuspenseFor and the Hold Window"
|
|
169
250
|
if (!signals.redirectSignal && !signals.denySignal && !signals.renderError) {
|
|
170
|
-
|
|
251
|
+
let yieldsConsumed = 0;
|
|
252
|
+
for (let i = 0; i < SIGNAL_PROMOTION_MAX_YIELDS; i++) {
|
|
253
|
+
await new Promise<void>((r) => queueMicrotask(r));
|
|
254
|
+
yieldsConsumed++;
|
|
255
|
+
if (signals.redirectSignal || signals.denySignal || signals.renderError) break;
|
|
256
|
+
}
|
|
257
|
+
__test_only_signalPromotionDepth.value = yieldsConsumed;
|
|
171
258
|
}
|
|
172
259
|
|
|
173
260
|
const promoted = checkCapturedSignals(/* skipHandledDeny */ true);
|
|
@@ -175,6 +262,19 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
175
262
|
ssrResponse.body?.cancel();
|
|
176
263
|
return promoted;
|
|
177
264
|
}
|
|
265
|
+
|
|
266
|
+
// Check if a DenySignal was caught in-tree by AccessGate or
|
|
267
|
+
// PageDenyBoundary. The deny page was rendered as a normal element
|
|
268
|
+
// (no error in the Flight stream), so SSR succeeded with status 200.
|
|
269
|
+
// Override the status code from the ALS-stored deny status. See TIM-666.
|
|
270
|
+
const denyStatus = getDenyStatus();
|
|
271
|
+
if (denyStatus) {
|
|
272
|
+
return new Response(ssrResponse.body, {
|
|
273
|
+
status: denyStatus,
|
|
274
|
+
headers: ssrResponse.headers,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
178
278
|
return ssrResponse;
|
|
179
279
|
} catch (ssrError) {
|
|
180
280
|
// Connection abort — the client disconnected (page refresh, navigation
|
|
@@ -185,19 +285,34 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
185
285
|
|
|
186
286
|
// SsrStreamError: SSR's renderToReadableStream failed because the RSC
|
|
187
287
|
// stream contained an uncontained error (e.g., slot without error boundary).
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
|
|
288
|
+
//
|
|
289
|
+
// Error pages now use SSR-only rendering (Fizz directly, no RSC Flight),
|
|
290
|
+
// which imports layouts in the SSR environment where ALS is active. This
|
|
291
|
+
// means we CAN include layouts — they'll call getHeaders()/getCookies() correctly.
|
|
292
|
+
//
|
|
293
|
+
// Deny pages still go through RSC → SSR (plain props), so they pass empty
|
|
294
|
+
// layouts to avoid re-executing server components in the RSC environment's
|
|
295
|
+
// stale ALS scope. See LOCAL-293.
|
|
296
|
+
// Name-based check: SsrStreamError is thrown in the SSR environment
|
|
297
|
+
// but caught in the RSC environment. Since RSC and SSR are separate
|
|
298
|
+
// Vite module graphs, `instanceof` fails (different class identities).
|
|
299
|
+
// Use error.name instead. See design/18-build-system.md §"Virtual Module
|
|
300
|
+
// Resolution Quirks".
|
|
301
|
+
const isSsrStreamError =
|
|
302
|
+
ssrError instanceof SsrStreamError ||
|
|
303
|
+
(ssrError instanceof Error && ssrError.name === 'SsrStreamError');
|
|
304
|
+
if (isSsrStreamError) {
|
|
192
305
|
if (signals.redirectSignal) {
|
|
193
306
|
return buildRedirectResponse(req, signals.redirectSignal, responseHeaders);
|
|
194
307
|
}
|
|
195
308
|
if (signals.denySignal) {
|
|
196
|
-
//
|
|
309
|
+
// SSR failed (SsrStreamError) — the deny was in the shell and
|
|
310
|
+
// the error boundary didn't catch it during Fizz rendering.
|
|
311
|
+
// Fall back to renderDenyPage (separate render). See TIM-664.
|
|
197
312
|
return renderDenyPage(
|
|
198
313
|
signals.denySignal,
|
|
199
314
|
segments,
|
|
200
|
-
|
|
315
|
+
layoutComponents as LayoutEntry[],
|
|
201
316
|
req,
|
|
202
317
|
match,
|
|
203
318
|
responseHeaders,
|
|
@@ -207,19 +322,37 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
|
|
|
207
322
|
);
|
|
208
323
|
}
|
|
209
324
|
if (signals.renderError) {
|
|
325
|
+
// RenderError: TSX error pages use SSR-only path (layouts OK),
|
|
326
|
+
// MDX error pages use RSC path (plain props, no Error object).
|
|
210
327
|
return renderErrorPage(
|
|
211
328
|
signals.renderError.error,
|
|
212
329
|
signals.renderError.status,
|
|
213
330
|
segments,
|
|
214
|
-
|
|
331
|
+
layoutComponents as LayoutEntry[],
|
|
215
332
|
req,
|
|
216
333
|
match,
|
|
217
334
|
responseHeaders,
|
|
218
|
-
clientBootstrap
|
|
335
|
+
clientBootstrap,
|
|
336
|
+
globalError
|
|
219
337
|
);
|
|
220
338
|
}
|
|
221
|
-
// No captured signal —
|
|
222
|
-
|
|
339
|
+
// No captured signal — unhandled error in the RSC stream.
|
|
340
|
+
// Use the lastUnhandledError from RSC onError if available (more
|
|
341
|
+
// reliable than extracting SsrStreamError.cause). Falls back to
|
|
342
|
+
// cause extraction for backward compatibility.
|
|
343
|
+
const originalError =
|
|
344
|
+
signals.lastUnhandledError ?? (ssrError as { cause?: unknown }).cause ?? ssrError;
|
|
345
|
+
return renderErrorPage(
|
|
346
|
+
originalError,
|
|
347
|
+
500,
|
|
348
|
+
segments,
|
|
349
|
+
layoutComponents as LayoutEntry[],
|
|
350
|
+
req,
|
|
351
|
+
match,
|
|
352
|
+
responseHeaders,
|
|
353
|
+
clientBootstrap,
|
|
354
|
+
globalError
|
|
355
|
+
);
|
|
223
356
|
}
|
|
224
357
|
|
|
225
358
|
// SSR shell rendering failed — the error was outside Suspense.
|