@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
|
@@ -58,15 +58,31 @@ export interface EarlyHint {
|
|
|
58
58
|
/**
|
|
59
59
|
* Format a single EarlyHint as a Link header value.
|
|
60
60
|
*
|
|
61
|
+
* Attribute order: `as` before `rel` to match Cloudflare CDN's cached
|
|
62
|
+
* Early Hints format. Cloudflare caches Link headers from 200 responses
|
|
63
|
+
* and re-emits them as 103 Early Hints on subsequent requests. If our
|
|
64
|
+
* attribute order differs from Cloudflare's cached copy, the browser
|
|
65
|
+
* sees two preload headers for the same URL (different attribute order)
|
|
66
|
+
* and warns "Preload was ignored." Matching the order ensures the
|
|
67
|
+
* browser deduplicates them correctly.
|
|
68
|
+
*
|
|
61
69
|
* Examples:
|
|
62
|
-
* `</styles/root.css>;
|
|
63
|
-
* `</fonts/inter.woff2>;
|
|
70
|
+
* `</styles/root.css>; as=style; rel=preload`
|
|
71
|
+
* `</fonts/inter.woff2>; as=font; rel=preload; crossorigin=anonymous`
|
|
64
72
|
* `</_timber/client.js>; rel=modulepreload`
|
|
65
73
|
* `<https://fonts.googleapis.com>; rel=preconnect`
|
|
66
74
|
*/
|
|
67
75
|
export function formatLinkHeader(hint: EarlyHint): string {
|
|
76
|
+
// For preload hints, emit `as` before `rel` to match Cloudflare's
|
|
77
|
+
// cached header format and avoid duplicate preload warnings.
|
|
78
|
+
if (hint.as !== undefined) {
|
|
79
|
+
let value = `<${hint.href}>; as=${hint.as}; rel=${hint.rel}`;
|
|
80
|
+
if (hint.crossOrigin !== undefined) value += `; crossorigin=${hint.crossOrigin}`;
|
|
81
|
+
if (hint.fetchPriority !== undefined) value += `; fetchpriority=${hint.fetchPriority}`;
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
// For modulepreload / preconnect (no `as`), emit rel first.
|
|
68
85
|
let value = `<${hint.href}>; rel=${hint.rel}`;
|
|
69
|
-
if (hint.as !== undefined) value += `; as=${hint.as}`;
|
|
70
86
|
if (hint.crossOrigin !== undefined) value += `; crossorigin=${hint.crossOrigin}`;
|
|
71
87
|
if (hint.fetchPriority !== undefined) value += `; fetchpriority=${hint.fetchPriority}`;
|
|
72
88
|
return value;
|
|
@@ -84,8 +100,8 @@ export interface EarlyHintOptions {
|
|
|
84
100
|
* Collect all Link header strings for a matched route's segment chain.
|
|
85
101
|
*
|
|
86
102
|
* Walks the build manifest to emit hints for:
|
|
87
|
-
* - CSS stylesheets (
|
|
88
|
-
* - Font assets (
|
|
103
|
+
* - CSS stylesheets (as=style; rel=preload)
|
|
104
|
+
* - Font assets (as=font; rel=preload; crossorigin)
|
|
89
105
|
* - JS modulepreload hints (rel=modulepreload) — unless skipJs is set
|
|
90
106
|
*
|
|
91
107
|
* Also emits global CSS from the `_global` manifest key. Route files
|
|
@@ -94,7 +110,7 @@ export interface EarlyHintOptions {
|
|
|
94
110
|
* key contains all CSS assets from the client build — fine for early
|
|
95
111
|
* hints since they're just prefetch signals.
|
|
96
112
|
*
|
|
97
|
-
* Returns formatted Link header strings, deduplicated, root → leaf order.
|
|
113
|
+
* Returns formatted Link header strings, deduplicated by URL, root → leaf order.
|
|
98
114
|
* Returns an empty array in dev mode (manifest is empty).
|
|
99
115
|
*/
|
|
100
116
|
export function collectEarlyHintHeaders(
|
|
@@ -103,30 +119,35 @@ export function collectEarlyHintHeaders(
|
|
|
103
119
|
options?: EarlyHintOptions
|
|
104
120
|
): string[] {
|
|
105
121
|
const result: string[] = [];
|
|
106
|
-
|
|
122
|
+
// Dedup by URL (href), not by full formatted header string.
|
|
123
|
+
// Different code paths can produce the same URL with different attribute
|
|
124
|
+
// ordering, which would bypass a full-string dedup and produce duplicate
|
|
125
|
+
// Link headers that trigger browser "preload was ignored" warnings.
|
|
126
|
+
const seenUrls = new Set<string>();
|
|
107
127
|
|
|
108
|
-
const add = (header: string) => {
|
|
109
|
-
if (!
|
|
110
|
-
|
|
128
|
+
const add = (url: string, header: string) => {
|
|
129
|
+
if (!seenUrls.has(url)) {
|
|
130
|
+
seenUrls.add(url);
|
|
111
131
|
result.push(header);
|
|
112
132
|
}
|
|
113
133
|
};
|
|
114
134
|
|
|
115
|
-
// Per-route CSS —
|
|
135
|
+
// Per-route CSS — as=style; rel=preload
|
|
116
136
|
for (const url of collectRouteCss(segments, manifest)) {
|
|
117
|
-
add(formatLinkHeader({ href: url, rel: 'preload', as: 'style' }));
|
|
137
|
+
add(url, formatLinkHeader({ href: url, rel: 'preload', as: 'style' }));
|
|
118
138
|
}
|
|
119
139
|
|
|
120
140
|
// Global CSS — all CSS assets from the client bundle.
|
|
121
141
|
// Covers CSS that the RSC plugin injects via data-rsc-css-href,
|
|
122
142
|
// which isn't keyed to route segments in our manifest.
|
|
123
143
|
for (const url of manifest.css['_global'] ?? []) {
|
|
124
|
-
add(formatLinkHeader({ href: url, rel: 'preload', as: 'style' }));
|
|
144
|
+
add(url, formatLinkHeader({ href: url, rel: 'preload', as: 'style' }));
|
|
125
145
|
}
|
|
126
146
|
|
|
127
|
-
// Fonts —
|
|
147
|
+
// Fonts — as=font; rel=preload; crossorigin (crossorigin required per spec)
|
|
128
148
|
for (const font of collectRouteFonts(segments, manifest)) {
|
|
129
149
|
add(
|
|
150
|
+
font.href,
|
|
130
151
|
formatLinkHeader({ href: font.href, rel: 'preload', as: 'font', crossOrigin: 'anonymous' })
|
|
131
152
|
);
|
|
132
153
|
}
|
|
@@ -134,7 +155,7 @@ export function collectEarlyHintHeaders(
|
|
|
134
155
|
// JS chunks — rel=modulepreload (skip when client JS is disabled)
|
|
135
156
|
if (!options?.skipJs) {
|
|
136
157
|
for (const url of collectRouteModulepreloads(segments, manifest)) {
|
|
137
|
-
add(formatLinkHeader({ href: url, rel: 'modulepreload' }));
|
|
158
|
+
add(url, formatLinkHeader({ href: url, rel: 'modulepreload' }));
|
|
138
159
|
}
|
|
139
160
|
}
|
|
140
161
|
|
|
@@ -5,8 +5,23 @@
|
|
|
5
5
|
* See design/10-error-handling.md.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { TimberErrorBoundary } from '
|
|
8
|
+
import { TimberErrorBoundary } from '../client/error-boundary.js';
|
|
9
9
|
import type { ManifestSegmentNode } from './route-matcher.js';
|
|
10
|
+
import { loadModule } from './safe-load.js';
|
|
11
|
+
|
|
12
|
+
/** MDX/markdown extensions — server components that cannot be passed as function props. */
|
|
13
|
+
const MDX_EXTENSIONS = new Set(['.mdx', '.md']);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if a manifest file path ends with an MDX/markdown extension.
|
|
17
|
+
* MDX components are server components and cannot cross the RSC→client
|
|
18
|
+
* boundary as function props to TimberErrorBoundary.
|
|
19
|
+
*/
|
|
20
|
+
function isMdxFilePath(filePath: string): boolean {
|
|
21
|
+
const dotIndex = filePath.lastIndexOf('.');
|
|
22
|
+
if (dotIndex === -1) return false;
|
|
23
|
+
return MDX_EXTENSIONS.has(filePath.slice(dotIndex));
|
|
24
|
+
}
|
|
10
25
|
|
|
11
26
|
/**
|
|
12
27
|
* Wrap an element in error boundaries defined by a route segment.
|
|
@@ -15,11 +30,17 @@ import type { ManifestSegmentNode } from './route-matcher.js';
|
|
|
15
30
|
* 1. Specific status files (e.g., 404.tsx, 500.tsx) — highest priority at runtime
|
|
16
31
|
* 2. Category catch-alls (4xx.tsx, 5xx.tsx)
|
|
17
32
|
* 3. error.tsx — catches anything not matched by status files
|
|
33
|
+
*
|
|
34
|
+
* MDX status files are server components and cannot be passed as function
|
|
35
|
+
* props to TimberErrorBoundary (a 'use client' component). Instead, they
|
|
36
|
+
* are pre-rendered as elements and passed as fallbackElement. See TIM-503.
|
|
18
37
|
*/
|
|
19
38
|
export async function wrapSegmentWithErrorBoundaries(
|
|
20
39
|
segment: ManifestSegmentNode,
|
|
21
40
|
element: React.ReactElement,
|
|
22
|
-
h: (...args: unknown[]) => React.ReactElement
|
|
41
|
+
h: (...args: unknown[]) => React.ReactElement,
|
|
42
|
+
/** When true, skip 4xx error boundaries — deny catching handles them in-tree. See TIM-666. */
|
|
43
|
+
skipDenyBoundaries = false
|
|
23
44
|
): Promise<React.ReactElement> {
|
|
24
45
|
// Specific status files (innermost — highest priority at runtime)
|
|
25
46
|
if (segment.statusFiles) {
|
|
@@ -27,13 +48,27 @@ export async function wrapSegmentWithErrorBoundaries(
|
|
|
27
48
|
if (key !== '4xx' && key !== '5xx') {
|
|
28
49
|
const status = parseInt(key, 10);
|
|
29
50
|
if (!isNaN(status)) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
51
|
+
// Skip 4xx boundaries when deny catching is active — the deny
|
|
52
|
+
// page is rendered by AccessGate/PageDenyBoundary instead.
|
|
53
|
+
if (skipDenyBoundaries && status >= 400 && status <= 499) continue;
|
|
54
|
+
// .catch: error boundary construction must not fail if the
|
|
55
|
+
// error page module has a syntax error — skip this boundary.
|
|
56
|
+
const mod = await loadModule(file).catch(() => null);
|
|
57
|
+
if (mod?.default) {
|
|
58
|
+
if (isMdxFilePath(file.filePath)) {
|
|
59
|
+
// MDX: pre-render as element (server component can't be a function prop)
|
|
60
|
+
element = h(TimberErrorBoundary, {
|
|
61
|
+
fallbackElement: h(mod.default as never, { status }),
|
|
62
|
+
status,
|
|
63
|
+
children: element,
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
element = h(TimberErrorBoundary, {
|
|
67
|
+
fallbackComponent: mod.default,
|
|
68
|
+
status,
|
|
69
|
+
children: element,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
37
72
|
}
|
|
38
73
|
}
|
|
39
74
|
}
|
|
@@ -41,14 +76,24 @@ export async function wrapSegmentWithErrorBoundaries(
|
|
|
41
76
|
|
|
42
77
|
// Category catch-alls (4xx.tsx, 5xx.tsx)
|
|
43
78
|
for (const [key, file] of Object.entries(segment.statusFiles)) {
|
|
79
|
+
if (skipDenyBoundaries && key === '4xx') continue;
|
|
44
80
|
if (key === '4xx' || key === '5xx') {
|
|
45
|
-
const mod =
|
|
46
|
-
if (mod
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
81
|
+
const mod = await loadModule(file).catch(() => null);
|
|
82
|
+
if (mod?.default) {
|
|
83
|
+
const categoryStatus = key === '4xx' ? 400 : 500;
|
|
84
|
+
if (isMdxFilePath(file.filePath)) {
|
|
85
|
+
element = h(TimberErrorBoundary, {
|
|
86
|
+
fallbackElement: h(mod.default as never, {}),
|
|
87
|
+
status: categoryStatus,
|
|
88
|
+
children: element,
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
element = h(TimberErrorBoundary, {
|
|
92
|
+
fallbackComponent: mod.default,
|
|
93
|
+
status: categoryStatus,
|
|
94
|
+
children: element,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
52
97
|
}
|
|
53
98
|
}
|
|
54
99
|
}
|
|
@@ -56,12 +101,19 @@ export async function wrapSegmentWithErrorBoundaries(
|
|
|
56
101
|
|
|
57
102
|
// error.tsx (outermost — catches anything not matched by status files)
|
|
58
103
|
if (segment.error) {
|
|
59
|
-
const mod =
|
|
60
|
-
if (mod
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
104
|
+
const mod = await loadModule(segment.error).catch(() => null);
|
|
105
|
+
if (mod?.default) {
|
|
106
|
+
if (isMdxFilePath(segment.error.filePath)) {
|
|
107
|
+
element = h(TimberErrorBoundary, {
|
|
108
|
+
fallbackElement: h(mod.default as never, {}),
|
|
109
|
+
children: element,
|
|
110
|
+
});
|
|
111
|
+
} else {
|
|
112
|
+
element = h(TimberErrorBoundary, {
|
|
113
|
+
fallbackComponent: mod.default,
|
|
114
|
+
children: element,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
65
117
|
}
|
|
66
118
|
}
|
|
67
119
|
|
|
@@ -10,10 +10,14 @@
|
|
|
10
10
|
* exposed to the client (design/13-security.md principle 4).
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { RouteMatch } from '
|
|
14
|
-
import type { ManifestSegmentNode } from '
|
|
15
|
-
import type { ClientBootstrapConfig } from '
|
|
16
|
-
import type { LayoutEntry } from '
|
|
13
|
+
import type { RouteMatch } from './pipeline.js';
|
|
14
|
+
import type { ManifestSegmentNode } from './route-matcher.js';
|
|
15
|
+
import type { ClientBootstrapConfig } from './html-injectors.js';
|
|
16
|
+
import type { LayoutEntry } from './deny-renderer.js';
|
|
17
|
+
import type { GlobalErrorFile } from './rsc-entry/error-renderer.js';
|
|
18
|
+
import { logRenderError } from './logger.js';
|
|
19
|
+
import { loadModule } from './safe-load.js';
|
|
20
|
+
import { sourceMapError } from './dev-source-map.js';
|
|
17
21
|
|
|
18
22
|
/**
|
|
19
23
|
* Render a fallback error page when the render pipeline throws.
|
|
@@ -27,25 +31,42 @@ export async function renderFallbackError(
|
|
|
27
31
|
responseHeaders: Headers,
|
|
28
32
|
isDev: boolean,
|
|
29
33
|
rootSegment: ManifestSegmentNode,
|
|
30
|
-
clientBootstrap: ClientBootstrapConfig
|
|
34
|
+
clientBootstrap: ClientBootstrapConfig,
|
|
35
|
+
globalError?: GlobalErrorFile,
|
|
36
|
+
projectRoot?: string
|
|
31
37
|
): Promise<Response> {
|
|
38
|
+
// Source-map the error's stack trace in dev mode so the error page
|
|
39
|
+
// shows original source positions. See TIM-811.
|
|
40
|
+
sourceMapError(error);
|
|
41
|
+
|
|
32
42
|
if (isDev) {
|
|
33
|
-
return renderDevErrorPage(error);
|
|
43
|
+
return renderDevErrorPage(error, projectRoot);
|
|
34
44
|
}
|
|
35
45
|
// Lazy import to avoid loading error-renderer in the pipeline module
|
|
36
|
-
const { renderErrorPage } = await import('
|
|
46
|
+
const { renderErrorPage } = await import('./rsc-entry/error-renderer.js');
|
|
37
47
|
const segments = [rootSegment];
|
|
38
48
|
const layoutComponents: LayoutEntry[] = [];
|
|
39
|
-
if
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
// Wrap layout loading in try/catch — if the root layout module itself
|
|
50
|
+
// crashes (evaluation failure, syntax error, etc.), we still want to
|
|
51
|
+
// reach renderErrorPage so it can fall through to global-error.tsx
|
|
52
|
+
// (Tier 2), which renders without any layout wrapping.
|
|
53
|
+
try {
|
|
54
|
+
if (rootSegment.layout) {
|
|
55
|
+
const mod = await loadModule(rootSegment.layout);
|
|
56
|
+
if (mod.default) {
|
|
57
|
+
layoutComponents.push({
|
|
58
|
+
component: mod.default as (...args: unknown[]) => unknown,
|
|
59
|
+
segment: rootSegment,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
46
62
|
}
|
|
63
|
+
} catch (layoutError) {
|
|
64
|
+
// Layout failed to load — proceed without it. renderErrorPage will
|
|
65
|
+
// attempt segment-level error pages (without layout wrapping) and
|
|
66
|
+
// then fall through to global-error.tsx if those also fail.
|
|
67
|
+
logRenderError({ method: req.method, path: new URL(req.url).pathname, error: layoutError });
|
|
47
68
|
}
|
|
48
|
-
const match: RouteMatch = { segments: segments as never,
|
|
69
|
+
const match: RouteMatch = { segments: segments as never, segmentParams: {}, middlewareChain: [] };
|
|
49
70
|
return renderErrorPage(
|
|
50
71
|
error,
|
|
51
72
|
500,
|
|
@@ -54,94 +75,41 @@ export async function renderFallbackError(
|
|
|
54
75
|
req,
|
|
55
76
|
match,
|
|
56
77
|
responseHeaders,
|
|
57
|
-
clientBootstrap
|
|
78
|
+
clientBootstrap,
|
|
79
|
+
globalError
|
|
58
80
|
);
|
|
59
81
|
}
|
|
60
82
|
|
|
61
83
|
/**
|
|
62
|
-
* Render a dev-mode 500 error page with error
|
|
84
|
+
* Render a dev-mode 500 error page with error details, source context,
|
|
85
|
+
* classified stack trace, and copy button.
|
|
86
|
+
*
|
|
87
|
+
* Dynamically imports the shared template from `plugins/dev-error-page.ts`
|
|
88
|
+
* so it is NOT pulled into production server bundles. The Vite client script
|
|
89
|
+
* is injected so the error overlay fires when the HMR WebSocket connects.
|
|
63
90
|
*
|
|
64
|
-
*
|
|
65
|
-
* The Vite HMR client script is included so the error overlay still fires.
|
|
91
|
+
* Dev-only — the dynamic import has zero production cost.
|
|
66
92
|
*/
|
|
67
|
-
export function renderDevErrorPage(error: unknown): Response {
|
|
93
|
+
export async function renderDevErrorPage(error: unknown, projectRoot?: string): Promise<Response> {
|
|
68
94
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
69
|
-
const
|
|
70
|
-
const message = escapeHtml(err.message);
|
|
71
|
-
const stack = err.stack ? escapeHtml(err.stack) : '';
|
|
95
|
+
const root = projectRoot ?? process.cwd();
|
|
72
96
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
.container { max-width: 800px; margin: 0 auto; }
|
|
90
|
-
.badge {
|
|
91
|
-
display: inline-block;
|
|
92
|
-
background: #e74c3c;
|
|
93
|
-
color: white;
|
|
94
|
-
font-size: 0.75rem;
|
|
95
|
-
font-weight: 700;
|
|
96
|
-
padding: 0.2rem 0.6rem;
|
|
97
|
-
border-radius: 4px;
|
|
98
|
-
text-transform: uppercase;
|
|
99
|
-
letter-spacing: 0.05em;
|
|
100
|
-
margin-bottom: 1rem;
|
|
101
|
-
}
|
|
102
|
-
h1 {
|
|
103
|
-
font-size: 1.5rem;
|
|
104
|
-
color: #ff6b6b;
|
|
105
|
-
margin-bottom: 0.5rem;
|
|
106
|
-
word-break: break-word;
|
|
107
|
-
}
|
|
108
|
-
.message {
|
|
109
|
-
font-size: 1.1rem;
|
|
110
|
-
color: #ccc;
|
|
111
|
-
margin-bottom: 1.5rem;
|
|
112
|
-
word-break: break-word;
|
|
113
|
-
}
|
|
114
|
-
.stack-container {
|
|
115
|
-
background: #16213e;
|
|
116
|
-
border: 1px solid #2a2a4a;
|
|
117
|
-
border-radius: 8px;
|
|
118
|
-
padding: 1rem;
|
|
119
|
-
overflow-x: auto;
|
|
120
|
-
}
|
|
121
|
-
.stack {
|
|
122
|
-
font-family: 'SF Mono', 'Fira Code', 'Fira Mono', Menlo, Consolas, monospace;
|
|
123
|
-
font-size: 0.8rem;
|
|
124
|
-
color: #a0a0c0;
|
|
125
|
-
white-space: pre-wrap;
|
|
126
|
-
word-break: break-all;
|
|
127
|
-
}
|
|
128
|
-
.hint {
|
|
129
|
-
margin-top: 1.5rem;
|
|
130
|
-
font-size: 0.85rem;
|
|
131
|
-
color: #666;
|
|
132
|
-
}
|
|
133
|
-
</style>
|
|
134
|
-
</head>
|
|
135
|
-
<body>
|
|
136
|
-
<div class="container">
|
|
137
|
-
<span class="badge">500 Internal Server Error</span>
|
|
138
|
-
<h1>${escapeHtml(title)}</h1>
|
|
139
|
-
<p class="message">${message}</p>
|
|
140
|
-
${stack ? `<div class="stack-container"><pre class="stack">${stack}</pre></div>` : ''}
|
|
141
|
-
<p class="hint">This error page is only shown in development.</p>
|
|
142
|
-
</div>
|
|
143
|
-
</body>
|
|
144
|
-
</html>`;
|
|
97
|
+
let html: string;
|
|
98
|
+
try {
|
|
99
|
+
// Dynamic import — keeps dev-error-page.ts and its transitive deps
|
|
100
|
+
// (dev-error-overlay.ts, @jridgewell/trace-mapping) out of production bundles.
|
|
101
|
+
const { generateDevErrorPage } = await import('../plugins/dev-error-page.js');
|
|
102
|
+
html = generateDevErrorPage(err, 'render', root);
|
|
103
|
+
// Inject Vite client script so the error overlay fires when HMR connects.
|
|
104
|
+
html = html.replace(
|
|
105
|
+
'</head>',
|
|
106
|
+
' <script type="module" src="/@vite/client"></script>\n</head>'
|
|
107
|
+
);
|
|
108
|
+
} catch {
|
|
109
|
+
// If the shared template fails (e.g., circular dep, missing module),
|
|
110
|
+
// fall back to a minimal error page.
|
|
111
|
+
html = minimalErrorPage(err);
|
|
112
|
+
}
|
|
145
113
|
|
|
146
114
|
return new Response(html, {
|
|
147
115
|
status: 500,
|
|
@@ -149,11 +117,15 @@ export function renderDevErrorPage(error: unknown): Response {
|
|
|
149
117
|
});
|
|
150
118
|
}
|
|
151
119
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Minimal fallback error page — used only if the shared template fails to load.
|
|
122
|
+
*/
|
|
123
|
+
function minimalErrorPage(err: Error): string {
|
|
124
|
+
const esc = (s: string) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
125
|
+
return `<!DOCTYPE html><html><head><meta charset="utf-8"><title>500</title>
|
|
126
|
+
<script type="module" src="/@vite/client"></script></head>
|
|
127
|
+
<body style="font-family:system-ui;padding:2rem;background:#1a1a2e;color:#e0e0e0">
|
|
128
|
+
<h1 style="color:#ff6b6b">500 Internal Server Error</h1>
|
|
129
|
+
<pre style="color:#a0a0c0;white-space:pre-wrap">${esc(err.stack ?? err.message)}</pre>
|
|
130
|
+
</body></html>`;
|
|
159
131
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared state machine types and transitions for RSC Flight injection.
|
|
3
|
+
*
|
|
4
|
+
* Both html-injectors.ts (Web Streams) and node-stream-transforms.ts
|
|
5
|
+
* (Node.js streams) implement identical state transitions — only the
|
|
6
|
+
* I/O primitives differ. This module defines the discriminated union
|
|
7
|
+
* states and the transition map once.
|
|
8
|
+
*
|
|
9
|
+
* Valid state flow:
|
|
10
|
+
* init → streaming → flushing → done
|
|
11
|
+
* (any) → error
|
|
12
|
+
*
|
|
13
|
+
* Suffix stripping (</body></html>) is handled by a separate
|
|
14
|
+
* createMoveSuffixStream / createNodeMoveSuffixTransform upstream
|
|
15
|
+
* in the pipeline (TIM-530). The flight injector only interleaves
|
|
16
|
+
* RSC scripts between HTML chunks — no suffix tracking needed.
|
|
17
|
+
*
|
|
18
|
+
* Design doc: 02-rendering-pipeline.md
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { TransitionMap } from '../utils/state-machine.js';
|
|
22
|
+
|
|
23
|
+
// ─── States ──────────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
/** Waiting for first HTML chunk. Pull loop not started. */
|
|
26
|
+
export interface InitState {
|
|
27
|
+
phase: 'init';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** HTML chunks flowing, pull loop running. */
|
|
31
|
+
export interface StreamingState {
|
|
32
|
+
phase: 'streaming';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** HTML stream done (flush fired). Draining remaining RSC chunks. */
|
|
36
|
+
export interface FlushingState {
|
|
37
|
+
phase: 'flushing';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** All streams consumed. Terminal state. */
|
|
41
|
+
export interface DoneState {
|
|
42
|
+
phase: 'done';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Pull loop failed. Terminal state with captured error. */
|
|
46
|
+
export interface ErrorState {
|
|
47
|
+
phase: 'error';
|
|
48
|
+
error: unknown;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type FlightInjectionState =
|
|
52
|
+
| InitState
|
|
53
|
+
| StreamingState
|
|
54
|
+
| FlushingState
|
|
55
|
+
| DoneState
|
|
56
|
+
| ErrorState;
|
|
57
|
+
|
|
58
|
+
// ─── Events ──────────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
/** First HTML chunk arrived — start the pull loop. */
|
|
61
|
+
export interface FirstChunkEvent {
|
|
62
|
+
type: 'FIRST_CHUNK';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** HTML stream finished (flush/end). */
|
|
66
|
+
export interface HtmlDoneEvent {
|
|
67
|
+
type: 'HTML_DONE';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** RSC pull loop completed (all chunks read or stream closed). */
|
|
71
|
+
export interface PullDoneEvent {
|
|
72
|
+
type: 'PULL_DONE';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** RSC pull loop encountered an error. */
|
|
76
|
+
export interface PullErrorEvent {
|
|
77
|
+
type: 'PULL_ERROR';
|
|
78
|
+
error: unknown;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export type FlightInjectionEvent = FirstChunkEvent | HtmlDoneEvent | PullDoneEvent | PullErrorEvent;
|
|
82
|
+
|
|
83
|
+
// ─── Transitions ─────────────────────────────────────────────────────────────
|
|
84
|
+
|
|
85
|
+
export const flightInjectionTransitions: TransitionMap<FlightInjectionState, FlightInjectionEvent> =
|
|
86
|
+
{
|
|
87
|
+
init: {
|
|
88
|
+
FIRST_CHUNK: (): StreamingState => ({ phase: 'streaming' }),
|
|
89
|
+
// Edge case: HTML stream ends immediately (empty body)
|
|
90
|
+
HTML_DONE: (): FlushingState => ({ phase: 'flushing' }),
|
|
91
|
+
},
|
|
92
|
+
streaming: {
|
|
93
|
+
HTML_DONE: (): FlushingState => ({ phase: 'flushing' }),
|
|
94
|
+
PULL_DONE: (): StreamingState => ({ phase: 'streaming' }),
|
|
95
|
+
PULL_ERROR: (_s, e): ErrorState => ({ phase: 'error', error: e.error }),
|
|
96
|
+
},
|
|
97
|
+
flushing: {
|
|
98
|
+
PULL_DONE: (): DoneState => ({ phase: 'done' }),
|
|
99
|
+
PULL_ERROR: (_s, e): ErrorState => ({ phase: 'error', error: e.error }),
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
/** Whether the HTML stream has finished (flush/end fired). */
|
|
106
|
+
export function isHtmlDone(state: FlightInjectionState): boolean {
|
|
107
|
+
return state.phase === 'flushing' || state.phase === 'done';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Whether the RSC pull loop has completed. */
|
|
111
|
+
export function isPullDone(state: FlightInjectionState): boolean {
|
|
112
|
+
return state.phase === 'done' || state.phase === 'error';
|
|
113
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Flight data script generation.
|
|
3
|
+
*
|
|
4
|
+
* Both html-injectors.ts (Web Streams / dev) and node-stream-transforms.ts
|
|
5
|
+
* (Node streams / production) use this module to generate inline `<script>`
|
|
6
|
+
* tags for RSC Flight data injection.
|
|
7
|
+
*
|
|
8
|
+
* The init script goes in `<head>` as part of the HTML shell (guaranteed
|
|
9
|
+
* to execute before any streaming chunk scripts). Push scripts are emitted
|
|
10
|
+
* as RSC chunks arrive during streaming.
|
|
11
|
+
*
|
|
12
|
+
* See design/02-rendering-pipeline.md, LOCAL-415
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// ─── JSON Escaping ────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Escape a JSON string for safe embedding inside an HTML `<script>` tag.
|
|
19
|
+
*
|
|
20
|
+
* Prevents XSS via `</script>` injection and handles Unicode line/paragraph
|
|
21
|
+
* separators that are valid JSON but invalid in JS string literals (pre-ES2019).
|
|
22
|
+
*/
|
|
23
|
+
export function htmlEscapeJsonString(str: string): string {
|
|
24
|
+
return str
|
|
25
|
+
.replace(/</g, '\\u003c')
|
|
26
|
+
.replace(/>/g, '\\u003e')
|
|
27
|
+
.replace(/\u2028/g, '\\u2028')
|
|
28
|
+
.replace(/\u2029/g, '\\u2029');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ─── Script Generation ────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
/** The global variable name used for Flight data on the client. */
|
|
34
|
+
const FLIGHT_VAR = 'self.__timber_f';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Generate the init script that creates the Flight data array.
|
|
38
|
+
*
|
|
39
|
+
* This MUST be included in `<head>` (via headHtml) so it executes before
|
|
40
|
+
* any streaming chunk scripts arrive in `<body>`. The array is created
|
|
41
|
+
* unconditionally — no `||[]` guard needed in push scripts.
|
|
42
|
+
*
|
|
43
|
+
* Also emits the bootstrap signal [0] which tells the client that
|
|
44
|
+
* Flight data is active for this page.
|
|
45
|
+
*/
|
|
46
|
+
export function flightInitScript(): string {
|
|
47
|
+
return `<script>${FLIGHT_VAR}=[${htmlEscapeJsonString(JSON.stringify([0]))}]</script>`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Generate a push script for a Flight data chunk.
|
|
52
|
+
*
|
|
53
|
+
* Normally the init script runs first (it's in `<head>`), so
|
|
54
|
+
* `self.__timber_f` already exists. However, shell-less status pages
|
|
55
|
+
* (e.g. standalone error pages) may have no `<head>` tag, so the init script
|
|
56
|
+
* never runs. The `||[]` guard ensures the array is created on first
|
|
57
|
+
* push if needed, preventing a TypeError. See TIM-559.
|
|
58
|
+
*/
|
|
59
|
+
export function flightChunkScript(data: string): string {
|
|
60
|
+
const escaped = htmlEscapeJsonString(JSON.stringify([1, data]));
|
|
61
|
+
return `<script>(${FLIGHT_VAR}=${FLIGHT_VAR}||[]).push(${escaped})</script>`;
|
|
62
|
+
}
|
package/src/server/flush.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { DenySignal, RedirectSignal, RenderError } from './primitives.js';
|
|
12
|
+
import { logRenderError } from './logger.js';
|
|
12
13
|
|
|
13
14
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
14
15
|
|
|
@@ -169,7 +170,7 @@ function handleSignal(error: unknown, responseHeaders: Headers): FlushResult {
|
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
// Unknown error → HTTP 500
|
|
172
|
-
|
|
173
|
+
logRenderError({ method: '', path: '', error });
|
|
173
174
|
return {
|
|
174
175
|
response: new Response(null, {
|
|
175
176
|
status: 500,
|