@timber-js/app 0.2.0-alpha.9 → 0.2.0-alpha.90
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-DRlhJWbu.js} +219 -97
- package/dist/_chunks/interception-DRlhJWbu.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.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/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.ts +273 -105
- package/src/routing/convention-lint.ts +356 -0
- package/src/routing/index.ts +2 -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
package/src/server/pipeline.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { canonicalize } from './canonicalize.js';
|
|
15
15
|
import { runProxy, type ProxyExport } from './proxy.js';
|
|
16
|
-
import {
|
|
16
|
+
import { runMiddlewareChain, type MiddlewareFn } from './middleware-runner.js';
|
|
17
17
|
import { runWithTimingCollector, withTiming, getServerTimingHeader } from './server-timing.js';
|
|
18
18
|
import {
|
|
19
19
|
runWithRequestContext,
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
setMutableCookieContext,
|
|
22
22
|
getSetCookieHeaders,
|
|
23
23
|
markResponseFlushed,
|
|
24
|
+
setSegmentParams,
|
|
24
25
|
} from './request-context.js';
|
|
25
26
|
import {
|
|
26
27
|
generateTraceId,
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
replaceTraceId,
|
|
30
31
|
withSpan,
|
|
31
32
|
setSpanAttribute,
|
|
32
|
-
|
|
33
|
+
getTraceId,
|
|
33
34
|
} from './tracing.js';
|
|
34
35
|
import {
|
|
35
36
|
logRequestReceived,
|
|
@@ -42,10 +43,35 @@ import {
|
|
|
42
43
|
} from './logger.js';
|
|
43
44
|
import { callOnRequestError } from './instrumentation.js';
|
|
44
45
|
import { RedirectSignal, DenySignal } from './primitives.js';
|
|
46
|
+
import { ParamCoercionError } from './route-element-builder.js';
|
|
47
|
+
import { checkVersionSkew, applyReloadHeaders } from './version-skew.js';
|
|
45
48
|
import { serveStaticMetadataFile, serializeSitemap } from './pipeline-metadata.js';
|
|
49
|
+
import { loadModule } from './safe-load.js';
|
|
46
50
|
import { findInterceptionMatch } from './pipeline-interception.js';
|
|
47
51
|
import type { MiddlewareContext } from './types.js';
|
|
48
|
-
import type { SegmentNode } from '
|
|
52
|
+
import type { SegmentNode } from '../routing/types.js';
|
|
53
|
+
|
|
54
|
+
// ─── Prototype-Pollution-Safe Merge ────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
/** Keys that must never be merged via Object.assign — they pollute Object.prototype. */
|
|
57
|
+
const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Shallow merge that skips prototype-polluting keys.
|
|
61
|
+
*
|
|
62
|
+
* Used instead of Object.assign when the source object comes from
|
|
63
|
+
* user-authored codec output (segmentParams.parse), which could
|
|
64
|
+
* contain __proto__, constructor, or prototype keys.
|
|
65
|
+
*
|
|
66
|
+
* See TIM-655, design/13-security.md
|
|
67
|
+
*/
|
|
68
|
+
export function safeMerge(target: Record<string, unknown>, source: Record<string, unknown>): void {
|
|
69
|
+
for (const key of Object.keys(source)) {
|
|
70
|
+
if (!DANGEROUS_KEYS.has(key)) {
|
|
71
|
+
target[key] = source[key];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
49
75
|
|
|
50
76
|
// ─── Route Match Result ────────────────────────────────────────────────────
|
|
51
77
|
|
|
@@ -53,10 +79,10 @@ import type { SegmentNode } from '#/routing/types.js';
|
|
|
53
79
|
export interface RouteMatch {
|
|
54
80
|
/** The matched segment chain from root to leaf. */
|
|
55
81
|
segments: SegmentNode[];
|
|
56
|
-
/** Extracted
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
|
|
82
|
+
/** Extracted segment params (catch-all segments produce string[]). */
|
|
83
|
+
segmentParams: Record<string, string | string[]>;
|
|
84
|
+
/** Middleware chain from the segment tree, ordered root-to-leaf. */
|
|
85
|
+
middlewareChain: MiddlewareFn[];
|
|
60
86
|
}
|
|
61
87
|
|
|
62
88
|
/** Function that matches a canonical pathname to a route. */
|
|
@@ -115,14 +141,25 @@ export interface PipelineConfig {
|
|
|
115
141
|
* Generated at build time from intercepting route directories.
|
|
116
142
|
* See design/07-routing.md §"Intercepting Routes"
|
|
117
143
|
*/
|
|
118
|
-
interceptionRewrites?: import('
|
|
144
|
+
interceptionRewrites?: import('../routing/interception.js').InterceptionRewrite[];
|
|
119
145
|
/**
|
|
120
|
-
*
|
|
121
|
-
* Only enable in dev mode — exposes internal timing data.
|
|
146
|
+
* Control Server-Timing header output.
|
|
122
147
|
*
|
|
123
|
-
*
|
|
148
|
+
* - `'detailed'` — per-phase breakdown (proxy, middleware, render).
|
|
149
|
+
* - `'total'` — single `total;dur=N` entry (production-safe).
|
|
150
|
+
* - `false` — no Server-Timing header at all.
|
|
151
|
+
*
|
|
152
|
+
* Default: `'total'`.
|
|
124
153
|
*/
|
|
125
|
-
|
|
154
|
+
serverTiming?: 'detailed' | 'total' | false;
|
|
155
|
+
/**
|
|
156
|
+
* Auto-generated sitemap handler. When provided, the pipeline intercepts
|
|
157
|
+
* `/sitemap.xml` and `/sitemap/N.xml` requests and delegates to this
|
|
158
|
+
* function. Returns a Response or null (pass-through to regular routing).
|
|
159
|
+
*
|
|
160
|
+
* See design/16-metadata.md §"Auto-generated Sitemap"
|
|
161
|
+
*/
|
|
162
|
+
autoSitemapHandler?: (pathname: string) => Promise<Response | null>;
|
|
126
163
|
/**
|
|
127
164
|
* Dev pipeline error callback — called when a pipeline phase (proxy,
|
|
128
165
|
* middleware, render) catches an unhandled error. Used to wire the error
|
|
@@ -131,6 +168,7 @@ export interface PipelineConfig {
|
|
|
131
168
|
* Undefined in production — zero overhead.
|
|
132
169
|
*/
|
|
133
170
|
onPipelineError?: (error: Error, phase: string) => void;
|
|
171
|
+
|
|
134
172
|
/**
|
|
135
173
|
* Fallback error renderer — called when a catastrophic error escapes the
|
|
136
174
|
* render phase. Produces an HTML Response instead of a bare empty 500.
|
|
@@ -147,6 +185,64 @@ export interface PipelineConfig {
|
|
|
147
185
|
req: Request,
|
|
148
186
|
responseHeaders: Headers
|
|
149
187
|
) => Response | Promise<Response>;
|
|
188
|
+
/**
|
|
189
|
+
* Fallback deny page renderer — called when a DenySignal escapes from
|
|
190
|
+
* middleware or the render phase. Renders the appropriate status-code
|
|
191
|
+
* page (403.tsx, 404.tsx, etc.) instead of returning a bare empty response.
|
|
192
|
+
*
|
|
193
|
+
* If this function throws, the pipeline falls back to a bare
|
|
194
|
+
* `new Response(null, { status: denyStatus })`.
|
|
195
|
+
*/
|
|
196
|
+
renderDenyFallback?: (
|
|
197
|
+
deny: DenySignal,
|
|
198
|
+
req: Request,
|
|
199
|
+
responseHeaders: Headers
|
|
200
|
+
) => Response | Promise<Response>;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ─── Param Coercion ────────────────────────────────────────────────────────
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Run segment param coercion on the matched route's segments.
|
|
207
|
+
*
|
|
208
|
+
* Loads params.ts modules from segments that have them, extracts the
|
|
209
|
+
* segmentParams definition, and coerces raw string params through codecs.
|
|
210
|
+
* Throws ParamCoercionError if any codec fails (→ 404).
|
|
211
|
+
*
|
|
212
|
+
* This runs BEFORE middleware, so ctx.segmentParams is already typed.
|
|
213
|
+
* See design/07-routing.md §"Where Coercion Runs"
|
|
214
|
+
*/
|
|
215
|
+
export async function coerceSegmentParams(match: RouteMatch): Promise<void> {
|
|
216
|
+
const segments = match.segments as unknown as import('./route-matcher.js').ManifestSegmentNode[];
|
|
217
|
+
|
|
218
|
+
for (const segment of segments) {
|
|
219
|
+
// Only process segments that have a params.ts convention file
|
|
220
|
+
if (!segment.params) continue;
|
|
221
|
+
|
|
222
|
+
let mod: Record<string, unknown>;
|
|
223
|
+
try {
|
|
224
|
+
mod = await loadModule(segment.params);
|
|
225
|
+
} catch (err) {
|
|
226
|
+
throw new ParamCoercionError(
|
|
227
|
+
`Failed to load params module for segment "${segment.segmentName}": ${err instanceof Error ? err.message : String(err)}`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const segmentParamsDef = mod.segmentParams as
|
|
232
|
+
| { parse(raw: Record<string, string | string[]>): Record<string, unknown> }
|
|
233
|
+
| undefined;
|
|
234
|
+
|
|
235
|
+
if (!segmentParamsDef || typeof segmentParamsDef.parse !== 'function') continue;
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const coerced = segmentParamsDef.parse(match.segmentParams);
|
|
239
|
+
// Merge coerced values back — use safeMerge to prevent prototype pollution
|
|
240
|
+
// from malicious/buggy codec output. See TIM-655.
|
|
241
|
+
safeMerge(match.segmentParams, coerced as Record<string, unknown>);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
throw new ParamCoercionError(err instanceof Error ? err.message : String(err));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
150
246
|
}
|
|
151
247
|
|
|
152
248
|
// ─── Pipeline ──────────────────────────────────────────────────────────────
|
|
@@ -165,7 +261,7 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
165
261
|
earlyHints,
|
|
166
262
|
stripTrailingSlash = true,
|
|
167
263
|
slowRequestMs = 3000,
|
|
168
|
-
|
|
264
|
+
serverTiming = 'total',
|
|
169
265
|
onPipelineError,
|
|
170
266
|
} = config;
|
|
171
267
|
|
|
@@ -186,7 +282,7 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
186
282
|
const traceIdValue = generateTraceId();
|
|
187
283
|
|
|
188
284
|
return runWithTraceId(traceIdValue, async () => {
|
|
189
|
-
// Establish request context ALS scope so
|
|
285
|
+
// Establish request context ALS scope so getHeaders() and getCookies() work
|
|
190
286
|
// throughout the entire request lifecycle (proxy, middleware, render).
|
|
191
287
|
return runWithRequestContext(req, async () => {
|
|
192
288
|
// In dev mode, wrap with timing collector for Server-Timing header.
|
|
@@ -216,25 +312,25 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
216
312
|
// DevSpanProcessor reads this for tree/summary output.
|
|
217
313
|
await setSpanAttribute('http.response.status_code', result.status);
|
|
218
314
|
|
|
219
|
-
// Append Server-Timing header.
|
|
220
|
-
// In dev mode: detailed per-phase breakdown (proxy, middleware, render).
|
|
221
|
-
// In production: single total duration — safe to expose, no phase names.
|
|
315
|
+
// Append Server-Timing header based on configured mode.
|
|
222
316
|
// Response.redirect() creates immutable headers, so we must
|
|
223
317
|
// ensure mutability before writing Server-Timing.
|
|
224
|
-
if (
|
|
225
|
-
|
|
226
|
-
|
|
318
|
+
if (serverTiming === 'detailed') {
|
|
319
|
+
// Detailed: per-phase breakdown (proxy, middleware, render).
|
|
320
|
+
const timingHeader = getServerTimingHeader();
|
|
321
|
+
if (timingHeader) {
|
|
227
322
|
result = ensureMutableResponse(result);
|
|
228
|
-
result.headers.set('Server-Timing',
|
|
323
|
+
result.headers.set('Server-Timing', timingHeader);
|
|
229
324
|
}
|
|
230
|
-
} else {
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
//
|
|
325
|
+
} else if (serverTiming === 'total') {
|
|
326
|
+
// Total only: single `total;dur=N` — no phase names.
|
|
327
|
+
// Prevents information disclosure while giving browser
|
|
328
|
+
// DevTools useful timing data.
|
|
234
329
|
const totalMs = Math.round(performance.now() - startTime);
|
|
235
330
|
result = ensureMutableResponse(result);
|
|
236
331
|
result.headers.set('Server-Timing', `total;dur=${totalMs}`);
|
|
237
332
|
}
|
|
333
|
+
// serverTiming === false: no header at all
|
|
238
334
|
|
|
239
335
|
return result;
|
|
240
336
|
}
|
|
@@ -254,7 +350,7 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
254
350
|
return response;
|
|
255
351
|
};
|
|
256
352
|
|
|
257
|
-
return
|
|
353
|
+
return serverTiming === 'detailed' ? runWithTimingCollector(runRequest) : runRequest();
|
|
258
354
|
});
|
|
259
355
|
});
|
|
260
356
|
};
|
|
@@ -272,7 +368,7 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
272
368
|
}
|
|
273
369
|
const proxyFn = () => runProxy(proxyExport, req, () => handleRequest(req, method, path));
|
|
274
370
|
return await withSpan('timber.proxy', {}, () =>
|
|
275
|
-
|
|
371
|
+
serverTiming === 'detailed' ? withTiming('proxy', 'proxy.ts', proxyFn) : proxyFn()
|
|
276
372
|
);
|
|
277
373
|
} catch (error) {
|
|
278
374
|
// Uncaught proxy.ts error → bare HTTP 500
|
|
@@ -283,6 +379,24 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
283
379
|
}
|
|
284
380
|
}
|
|
285
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Build a redirect Response from a RedirectSignal.
|
|
384
|
+
*
|
|
385
|
+
* For RSC payload requests (client navigation), returns 204 + X-Timber-Redirect
|
|
386
|
+
* so the client router can perform a soft SPA redirect. A raw 302 would be
|
|
387
|
+
* turned into an opaque redirect by fetch({redirect:'manual'}), crashing
|
|
388
|
+
* createFromFetch. See design/19-client-navigation.md.
|
|
389
|
+
*/
|
|
390
|
+
function buildRedirectResponse(signal: RedirectSignal, req: Request, headers: Headers): Response {
|
|
391
|
+
const isRsc = (req.headers.get('Accept') ?? '').includes('text/x-component');
|
|
392
|
+
if (isRsc) {
|
|
393
|
+
headers.set('X-Timber-Redirect', signal.location);
|
|
394
|
+
return new Response(null, { status: 204, headers });
|
|
395
|
+
}
|
|
396
|
+
headers.set('Location', signal.location);
|
|
397
|
+
return new Response(null, { status: signal.status, headers });
|
|
398
|
+
}
|
|
399
|
+
|
|
286
400
|
async function handleRequest(req: Request, method: string, path: string): Promise<Response> {
|
|
287
401
|
// Stage 1: URL canonicalization
|
|
288
402
|
const url = new URL(req.url);
|
|
@@ -306,7 +420,7 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
306
420
|
return await serveStaticMetadataFile(metaMatch);
|
|
307
421
|
}
|
|
308
422
|
|
|
309
|
-
const mod =
|
|
423
|
+
const mod = await loadModule<{ default?: Function }>(metaMatch.file);
|
|
310
424
|
if (typeof mod.default !== 'function') {
|
|
311
425
|
return new Response('Metadata route must export a default function', { status: 500 });
|
|
312
426
|
}
|
|
@@ -339,6 +453,36 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
339
453
|
}
|
|
340
454
|
}
|
|
341
455
|
|
|
456
|
+
// Stage 1b.2: Auto-generated sitemap — serves /sitemap.xml and /sitemap/N.xml
|
|
457
|
+
// when sitemap generation is enabled and no user-authored sitemap exists.
|
|
458
|
+
// Runs after metadata route matching so user sitemaps always take precedence.
|
|
459
|
+
// See design/16-metadata.md §"Auto-generated Sitemap"
|
|
460
|
+
if (config.autoSitemapHandler) {
|
|
461
|
+
try {
|
|
462
|
+
const sitemapResponse = await config.autoSitemapHandler(canonicalPathname);
|
|
463
|
+
if (sitemapResponse) return sitemapResponse;
|
|
464
|
+
} catch (error) {
|
|
465
|
+
logRenderError({ method, path, error });
|
|
466
|
+
if (onPipelineError && error instanceof Error) onPipelineError(error, 'auto-sitemap');
|
|
467
|
+
return new Response(null, { status: 500 });
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Stage 1c: Version skew detection (TIM-446).
|
|
472
|
+
// For RSC payload requests (client navigation), check if the client's
|
|
473
|
+
// deployment ID matches the current build. On mismatch, signal the
|
|
474
|
+
// client to do a full page reload instead of returning an RSC payload
|
|
475
|
+
// that references mismatched module IDs.
|
|
476
|
+
const isRscRequest = (req.headers.get('Accept') ?? '').includes('text/x-component');
|
|
477
|
+
if (isRscRequest) {
|
|
478
|
+
const skewCheck = checkVersionSkew(req);
|
|
479
|
+
if (!skewCheck.ok) {
|
|
480
|
+
const reloadHeaders = new Headers();
|
|
481
|
+
applyReloadHeaders(reloadHeaders);
|
|
482
|
+
return new Response(null, { status: 204, headers: reloadHeaders });
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
342
486
|
// Stage 2: Route matching
|
|
343
487
|
let match = matchRoute(canonicalPathname);
|
|
344
488
|
let interception: InterceptionContext | undefined;
|
|
@@ -397,18 +541,57 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
397
541
|
}
|
|
398
542
|
}
|
|
399
543
|
|
|
400
|
-
// Stage
|
|
401
|
-
|
|
544
|
+
// Stage 2c: Param coercion (before middleware)
|
|
545
|
+
// Load params.ts modules from matched segments and coerce raw string
|
|
546
|
+
// params through defineSegmentParams codecs. Coercion failure → 404
|
|
547
|
+
// (middleware never runs). See design/07-routing.md §"Where Coercion Runs"
|
|
548
|
+
try {
|
|
549
|
+
await coerceSegmentParams(match);
|
|
550
|
+
} catch (error) {
|
|
551
|
+
if (error instanceof ParamCoercionError) {
|
|
552
|
+
// For API routes (route.ts), return a bare 404 — not an HTML page.
|
|
553
|
+
// API consumers expect JSON/empty responses, not rendered HTML.
|
|
554
|
+
const leafSegment = match.segments[match.segments.length - 1];
|
|
555
|
+
if (
|
|
556
|
+
(leafSegment as { route?: unknown }).route &&
|
|
557
|
+
!(leafSegment as { page?: unknown }).page
|
|
558
|
+
) {
|
|
559
|
+
return new Response(null, { status: 404 });
|
|
560
|
+
}
|
|
561
|
+
// Route through the app's 404 page (404.tsx in root layout) instead of
|
|
562
|
+
// returning a bare empty 404 Response. Falls back to bare 404 only if
|
|
563
|
+
// no renderNoMatch renderer is configured.
|
|
564
|
+
if (config.renderNoMatch) {
|
|
565
|
+
return config.renderNoMatch(req, responseHeaders);
|
|
566
|
+
}
|
|
567
|
+
return new Response(null, { status: 404 });
|
|
568
|
+
}
|
|
569
|
+
throw error;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Store coerced segment params in ALS so components can access them
|
|
573
|
+
// via getSegmentParams() instead of receiving them as a prop.
|
|
574
|
+
// See design/07-routing.md §"params.ts — Convention File for Typed Params"
|
|
575
|
+
setSegmentParams(match.segmentParams);
|
|
576
|
+
|
|
577
|
+
// Stage 3: Middleware chain (root-to-leaf, short-circuits on first Response)
|
|
578
|
+
if (match.middlewareChain.length > 0) {
|
|
402
579
|
const ctx: MiddlewareContext = {
|
|
403
580
|
req,
|
|
404
581
|
requestHeaders: requestHeaderOverlay,
|
|
405
582
|
headers: responseHeaders,
|
|
406
|
-
|
|
407
|
-
searchParams: new URL(req.url).searchParams,
|
|
583
|
+
segmentParams: match.segmentParams,
|
|
408
584
|
earlyHints: (hints) => {
|
|
409
585
|
for (const hint of hints) {
|
|
410
|
-
|
|
411
|
-
|
|
586
|
+
// Match Cloudflare's cached Early Hints attribute order: `as` before `rel`.
|
|
587
|
+
// Cloudflare caches Link headers and re-emits them on subsequent 200s.
|
|
588
|
+
// If our order differs, the browser sees duplicate preloads and warns.
|
|
589
|
+
let value: string;
|
|
590
|
+
if (hint.as !== undefined) {
|
|
591
|
+
value = `<${hint.href}>; as=${hint.as}; rel=${hint.rel}`;
|
|
592
|
+
} else {
|
|
593
|
+
value = `<${hint.href}>; rel=${hint.rel}`;
|
|
594
|
+
}
|
|
412
595
|
if (hint.crossOrigin !== undefined) value += `; crossorigin=${hint.crossOrigin}`;
|
|
413
596
|
if (hint.fetchPriority !== undefined) value += `; fetchpriority=${hint.fetchPriority}`;
|
|
414
597
|
responseHeaders.append('Link', value);
|
|
@@ -419,9 +602,9 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
419
602
|
try {
|
|
420
603
|
// Enable cookie mutation during middleware (design/29-cookies.md §"Context Tracking")
|
|
421
604
|
setMutableCookieContext(true);
|
|
422
|
-
const
|
|
605
|
+
const chainFn = () => runMiddlewareChain(match.middlewareChain, ctx);
|
|
423
606
|
const middlewareResponse = await withSpan('timber.middleware', {}, () =>
|
|
424
|
-
|
|
607
|
+
serverTiming === 'detailed' ? withTiming('mw', 'middleware.ts', chainFn) : chainFn()
|
|
425
608
|
);
|
|
426
609
|
setMutableCookieContext(false);
|
|
427
610
|
if (middlewareResponse) {
|
|
@@ -430,32 +613,43 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
430
613
|
// mutability before appending Set-Cookie entries.
|
|
431
614
|
const finalResponse = ensureMutableResponse(middlewareResponse);
|
|
432
615
|
applyCookieJar(finalResponse.headers);
|
|
616
|
+
// Merge parent-set responseHeaders onto the short-circuit response.
|
|
617
|
+
// Child-set headers take precedence — only add headers not already present.
|
|
618
|
+
// Snapshot existing keys first so multi-value headers (Set-Cookie, Link)
|
|
619
|
+
// from the parent are all appended when the child didn't set that key.
|
|
620
|
+
const existingKeys = new Set(
|
|
621
|
+
[...finalResponse.headers.keys()].map((k) => k.toLowerCase())
|
|
622
|
+
);
|
|
623
|
+
for (const [key, value] of responseHeaders.entries()) {
|
|
624
|
+
if (!existingKeys.has(key.toLowerCase())) {
|
|
625
|
+
finalResponse.headers.append(key, value);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
433
628
|
logMiddlewareShortCircuit({ method, path, status: finalResponse.status });
|
|
434
629
|
return finalResponse;
|
|
435
630
|
}
|
|
436
|
-
// Middleware
|
|
437
|
-
// injected request headers so
|
|
631
|
+
// Middleware chain completed without short-circuiting — apply any
|
|
632
|
+
// injected request headers so getHeaders() returns them downstream.
|
|
438
633
|
applyRequestHeaderOverlay(requestHeaderOverlay);
|
|
439
634
|
} catch (error) {
|
|
440
635
|
setMutableCookieContext(false);
|
|
441
|
-
// RedirectSignal from middleware → HTTP redirect (not an error)
|
|
442
|
-
// For RSC payload requests (client navigation), return 204 + X-Timber-Redirect
|
|
443
|
-
// so the client router can perform a soft SPA redirect. A raw 302 would be
|
|
444
|
-
// turned into an opaque redirect by fetch({redirect:'manual'}), crashing
|
|
445
|
-
// createFromFetch. See design/19-client-navigation.md.
|
|
636
|
+
// RedirectSignal from middleware → HTTP redirect (not an error)
|
|
446
637
|
if (error instanceof RedirectSignal) {
|
|
447
638
|
applyCookieJar(responseHeaders);
|
|
448
|
-
|
|
449
|
-
if (isRsc) {
|
|
450
|
-
responseHeaders.set('X-Timber-Redirect', error.location);
|
|
451
|
-
return new Response(null, { status: 204, headers: responseHeaders });
|
|
452
|
-
}
|
|
453
|
-
responseHeaders.set('Location', error.location);
|
|
454
|
-
return new Response(null, { status: error.status, headers: responseHeaders });
|
|
639
|
+
return buildRedirectResponse(error, req, responseHeaders);
|
|
455
640
|
}
|
|
456
|
-
// DenySignal from middleware →
|
|
641
|
+
// DenySignal from middleware → render deny page with correct status code.
|
|
642
|
+
// Previously returned bare Response(null) — now renders 403.tsx etc.
|
|
457
643
|
if (error instanceof DenySignal) {
|
|
458
|
-
|
|
644
|
+
applyCookieJar(responseHeaders);
|
|
645
|
+
if (config.renderDenyFallback) {
|
|
646
|
+
try {
|
|
647
|
+
return await config.renderDenyFallback(error, req, responseHeaders);
|
|
648
|
+
} catch {
|
|
649
|
+
// Deny page rendering failed — fall through to bare response
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return new Response(null, { status: error.status, headers: responseHeaders });
|
|
459
653
|
}
|
|
460
654
|
// Middleware throw → HTTP 500 (middleware runs before rendering,
|
|
461
655
|
// no error boundary to catch it)
|
|
@@ -476,28 +670,29 @@ export function createPipeline(config: PipelineConfig): (req: Request) => Promis
|
|
|
476
670
|
const renderFn = () =>
|
|
477
671
|
render(req, match, responseHeaders, requestHeaderOverlay, interception);
|
|
478
672
|
const response = await withSpan('timber.render', { 'http.route': canonicalPathname }, () =>
|
|
479
|
-
|
|
673
|
+
serverTiming === 'detailed'
|
|
674
|
+
? withTiming('render', 'RSC + SSR render', renderFn)
|
|
675
|
+
: renderFn()
|
|
480
676
|
);
|
|
481
677
|
markResponseFlushed();
|
|
482
678
|
return response;
|
|
483
679
|
} catch (error) {
|
|
484
680
|
// DenySignal leaked from render (e.g. notFound() in metadata()).
|
|
485
|
-
//
|
|
681
|
+
// Render the deny page with the correct status code.
|
|
486
682
|
if (error instanceof DenySignal) {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
const isRsc = (req.headers.get('Accept') ?? '').includes('text/x-component');
|
|
494
|
-
if (isRsc) {
|
|
495
|
-
responseHeaders.set('X-Timber-Redirect', error.location);
|
|
496
|
-
return new Response(null, { status: 204, headers: responseHeaders });
|
|
683
|
+
if (config.renderDenyFallback) {
|
|
684
|
+
try {
|
|
685
|
+
return await config.renderDenyFallback(error, req, responseHeaders);
|
|
686
|
+
} catch {
|
|
687
|
+
// Deny page rendering failed — fall through to bare response
|
|
688
|
+
}
|
|
497
689
|
}
|
|
498
|
-
responseHeaders.set('Location', error.location);
|
|
499
690
|
return new Response(null, { status: error.status, headers: responseHeaders });
|
|
500
691
|
}
|
|
692
|
+
// RedirectSignal leaked from render — honour the redirect
|
|
693
|
+
if (error instanceof RedirectSignal) {
|
|
694
|
+
return buildRedirectResponse(error, req, responseHeaders);
|
|
695
|
+
}
|
|
501
696
|
logRenderError({ method, path, error });
|
|
502
697
|
await fireOnRequestError(error, req, 'render');
|
|
503
698
|
if (onPipelineError && error instanceof Error) onPipelineError(error, 'render');
|
|
@@ -532,7 +727,7 @@ async function fireOnRequestError(
|
|
|
532
727
|
await callOnRequestError(
|
|
533
728
|
error,
|
|
534
729
|
{ method: req.method, path: url.pathname, headers: headersObj },
|
|
535
|
-
{ phase, routePath: url.pathname, routeType: 'page', traceId:
|
|
730
|
+
{ phase, routePath: url.pathname, routeType: 'page', traceId: getTraceId() }
|
|
536
731
|
);
|
|
537
732
|
}
|
|
538
733
|
|