@timber-js/app 0.2.0-alpha.7 → 0.2.0-alpha.71
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/LICENSE +8 -0
- package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-BJARkOcu.js} +1 -1
- package/dist/_chunks/als-registry-BJARkOcu.js.map +1 -0
- package/dist/_chunks/chunk-DYhsFzuS.js +33 -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-CGuYoRHU.js +199 -0
- package/dist/_chunks/define-CGuYoRHU.js.map +1 -0
- package/dist/_chunks/define-Dz1bqwaS.js +106 -0
- package/dist/_chunks/define-Dz1bqwaS.js.map +1 -0
- package/dist/_chunks/define-cookie-B5mewxwM.js +93 -0
- package/dist/_chunks/define-cookie-B5mewxwM.js.map +1 -0
- package/dist/_chunks/error-boundary-D9hzsveV.js +216 -0
- package/dist/_chunks/error-boundary-D9hzsveV.js.map +1 -0
- package/dist/_chunks/{format-DviM89f0.js → format-Rn922VH2.js} +3 -20
- package/dist/_chunks/format-Rn922VH2.js.map +1 -0
- package/dist/_chunks/{tracing-Cwn7697K.js → handler-store-BVePM7hp.js} +68 -3
- package/dist/_chunks/handler-store-BVePM7hp.js.map +1 -0
- package/dist/_chunks/{interception-BOoWmLUA.js → interception-CEdHHviP.js} +171 -97
- package/dist/_chunks/interception-CEdHHviP.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-DIkVh_jG.js → request-context-CywiO4jV.js} +181 -69
- package/dist/_chunks/request-context-CywiO4jV.js.map +1 -0
- package/dist/_chunks/schema-bridge-C4SwjCQD.js +86 -0
- package/dist/_chunks/schema-bridge-C4SwjCQD.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-hzuJ048X.js +72 -0
- package/dist/_chunks/segment-context-hzuJ048X.js.map +1 -0
- package/dist/_chunks/stale-reload-BLUC_Pl_.js +64 -0
- package/dist/_chunks/stale-reload-BLUC_Pl_.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-DAhgj8Gx.js} +1 -1
- package/dist/_chunks/use-query-states-DAhgj8Gx.js.map +1 -0
- package/dist/_chunks/wrappers-LZbghvn0.js +63 -0
- package/dist/_chunks/wrappers-LZbghvn0.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.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/fast-hash.d.ts +22 -0
- package/dist/cache/fast-hash.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 +7 -5
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +111 -73
- 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/timber-cache.d.ts +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- 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 +1 -125
- 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 +2 -2
- 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 +6 -5
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +537 -166
- package/dist/client/index.js.map +1 -1
- package/dist/client/link-pending-store.d.ts +78 -0
- package/dist/client/link-pending-store.d.ts.map +1 -0
- package/dist/client/link.d.ts +90 -32
- 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.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-context.d.ts +1 -1
- package/dist/client/segment-context.d.ts.map +1 -1
- package/dist/client/segment-merger.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 +3 -3
- package/dist/client/top-loader.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-query-states.d.ts +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/codec.d.ts +23 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +2 -0
- package/dist/cookies/define-cookie.d.ts +35 -14
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +2 -0
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/cookies/index.js +3 -84
- package/dist/fonts/css.d.ts +1 -0
- package/dist/fonts/css.d.ts.map +1 -1
- package/dist/index.d.ts +154 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12092 -11916
- package/dist/index.js.map +1 -1
- 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-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 +26 -1
- package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
- 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/entries.d.ts +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +19 -5
- 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 +1 -1
- 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/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 -6
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +4 -474
- package/dist/search-params/registry.d.ts +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 +7 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +4 -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 +12 -1
- 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.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-warnings.d.ts +0 -14
- 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 +4 -3
- 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 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2176 -1663
- package/dist/server/index.js.map +1 -1
- 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 +32 -10
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +30 -3
- 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 +76 -37
- 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 +9 -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 +8 -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 +10 -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/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 +22 -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 +10 -0
- 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/server/waituntil-bridge.d.ts.map +1 -1
- 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/navigation-client.d.ts +1 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +1 -1
- 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 +37 -17
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare.ts +342 -28
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +58 -9
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +38 -0
- package/src/cache/fast-hash.ts +34 -0
- package/src/cache/handler-store.ts +68 -0
- package/src/cache/index.ts +9 -5
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/timber-cache.ts +40 -29
- package/src/cli.ts +0 -0
- package/src/client/browser-entry.ts +314 -142
- package/src/client/error-boundary.tsx +48 -16
- package/src/client/error-reconstituter.tsx +65 -0
- package/src/client/form.tsx +2 -2
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +13 -4
- package/src/client/link-pending-store.ts +136 -0
- package/src/client/link.tsx +346 -105
- 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 +27 -6
- package/src/client/navigation-root.tsx +346 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router.ts +302 -77
- package/src/client/rsc-fetch.ts +93 -5
- package/src/client/segment-cache.ts +1 -1
- package/src/client/segment-context.ts +6 -1
- package/src/client/segment-merger.ts +2 -8
- package/src/client/segment-outlet.tsx +86 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/stale-reload.ts +73 -6
- package/src/client/top-loader.tsx +22 -13
- package/src/client/use-navigation-pending.ts +1 -1
- package/src/client/use-params.ts +7 -5
- package/src/client/use-query-states.ts +2 -2
- package/src/codec.ts +34 -0
- package/src/cookies/define-cookie.ts +72 -21
- package/src/cookies/index.ts +7 -0
- package/src/fonts/css.ts +2 -1
- package/src/index.ts +328 -92
- package/src/plugins/adapter-build.ts +8 -2
- 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-browser-logs.ts +288 -0
- package/src/plugins/dev-error-overlay.ts +70 -1
- package/src/plugins/dev-logs.ts +1 -1
- package/src/plugins/dev-server.ts +55 -9
- package/src/plugins/entries.ts +70 -9
- package/src/plugins/fonts.ts +167 -61
- package/src/plugins/mdx.ts +1 -1
- package/src/plugins/routing.ts +57 -17
- package/src/plugins/server-action-exports.ts +1 -1
- package/src/plugins/server-bundle.ts +32 -1
- package/src/plugins/shims.ts +76 -33
- package/src/plugins/static-build.ts +10 -6
- package/src/routing/codegen.ts +165 -105
- 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 +13 -19
- package/src/search-params/registry.ts +1 -1
- package/src/search-params/wrappers.ts +85 -0
- package/src/segment-params/define.ts +279 -0
- package/src/segment-params/index.ts +28 -0
- package/src/server/access-gate.tsx +70 -29
- package/src/server/action-client.ts +28 -3
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +20 -3
- package/src/server/actions.ts +10 -9
- package/src/server/als-registry.ts +32 -4
- 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-warnings.ts +2 -28
- package/src/server/early-hints.ts +36 -15
- package/src/server/error-boundary-wrapper.ts +74 -22
- package/src/server/fallback-error.ts +31 -15
- 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 +277 -117
- package/src/server/index.ts +9 -5
- 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 +195 -51
- package/src/server/primitives.ts +47 -5
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +240 -117
- package/src/server/route-element-builder.ts +284 -197
- package/src/server/route-handler.ts +24 -4
- package/src/server/route-matcher.ts +24 -20
- package/src/server/rsc-entry/api-handler.ts +15 -16
- package/src/server/rsc-entry/error-renderer.ts +300 -89
- package/src/server/rsc-entry/helpers.ts +134 -5
- package/src/server/rsc-entry/index.ts +202 -113
- package/src/server/rsc-entry/rsc-payload.ts +100 -21
- package/src/server/rsc-entry/rsc-stream.ts +74 -18
- package/src/server/rsc-entry/ssr-bridge.ts +14 -5
- package/src/server/rsc-entry/ssr-renderer.ts +173 -40
- package/src/server/safe-load.ts +60 -0
- package/src/server/sitemap-generator.ts +338 -0
- package/src/server/sitemap-handler.ts +126 -0
- package/src/server/slot-resolver.ts +243 -228
- package/src/server/ssr-entry.ts +211 -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 +37 -3
- 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/server/waituntil-bridge.ts +4 -1
- 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/navigation-client.ts +1 -1
- package/src/shims/navigation.ts +2 -1
- 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.map +0 -1
- package/dist/_chunks/ssr-data-MjmprTmO.js +0 -88
- package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
- package/dist/_chunks/tracing-Cwn7697K.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/error-boundary.js.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/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/search-params/index.js.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 -53
- package/dist/server/response-cache.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -99
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/transition-root.tsx +0 -160
- 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 -277
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Small, stateless functions used across the RSC entry modules.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { ManifestSegmentNode } from '
|
|
8
|
-
import { RedirectSignal } from '
|
|
7
|
+
import type { ManifestSegmentNode } from '../route-matcher.js';
|
|
8
|
+
import { RedirectSignal } from '../primitives.js';
|
|
9
9
|
|
|
10
10
|
/** RSC content type for client navigation payload requests. */
|
|
11
11
|
export const RSC_CONTENT_TYPE = 'text/x-component';
|
|
@@ -20,9 +20,6 @@ export const RSC_CONTENT_TYPE = 'text/x-component';
|
|
|
20
20
|
* stream that we drain and discard.
|
|
21
21
|
*
|
|
22
22
|
* See design/13-security.md §"Server component source leak"
|
|
23
|
-
*
|
|
24
|
-
* TODO: In the future, expose this debug data to the browser in dev mode
|
|
25
|
-
* for inline error overlays (e.g. component stack traces).
|
|
26
23
|
*/
|
|
27
24
|
export function createDebugChannelSink(): { readable: ReadableStream; writable: WritableStream } {
|
|
28
25
|
const sink = new TransformStream();
|
|
@@ -34,6 +31,138 @@ export function createDebugChannelSink(): { readable: ReadableStream; writable:
|
|
|
34
31
|
};
|
|
35
32
|
}
|
|
36
33
|
|
|
34
|
+
// ─── Debug Channel Collector (dev mode only) ────────────────────────────
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Parsed component debug info extracted from the Flight debug channel.
|
|
38
|
+
*
|
|
39
|
+
* Contains only component names, environment labels, and stack frames —
|
|
40
|
+
* never source code or props. See design/13-security.md §"Server source
|
|
41
|
+
* never reaches the client".
|
|
42
|
+
*/
|
|
43
|
+
export interface DebugComponentEntry {
|
|
44
|
+
name: string;
|
|
45
|
+
env: string | null;
|
|
46
|
+
key: string | null;
|
|
47
|
+
stack: unknown[] | null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A debug channel that collects Flight debug rows instead of discarding them.
|
|
52
|
+
*
|
|
53
|
+
* Used in dev mode to capture server component tree information for the
|
|
54
|
+
* Vite error overlay. The collector provides the same `{ readable, writable }`
|
|
55
|
+
* shape as the discard sink, plus methods to retrieve collected data.
|
|
56
|
+
*
|
|
57
|
+
* Security: only component names, environments, and stack frames are
|
|
58
|
+
* extracted — props and source code are stripped. In production builds,
|
|
59
|
+
* use `createDebugChannelSink()` instead (this function is never called).
|
|
60
|
+
*/
|
|
61
|
+
export interface DebugChannelCollector {
|
|
62
|
+
readable: ReadableStream;
|
|
63
|
+
writable: WritableStream;
|
|
64
|
+
/** Get the raw collected text from the debug channel. */
|
|
65
|
+
getCollectedText(): string;
|
|
66
|
+
/** Get parsed component entries (names, stacks — no props or source). */
|
|
67
|
+
getComponents(): DebugComponentEntry[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function createDebugChannelCollector(): DebugChannelCollector {
|
|
71
|
+
const chunks: string[] = [];
|
|
72
|
+
const decoder = new TextDecoder();
|
|
73
|
+
|
|
74
|
+
const sink = new TransformStream();
|
|
75
|
+
|
|
76
|
+
// Collect chunks from the readable side instead of discarding them.
|
|
77
|
+
sink.readable
|
|
78
|
+
.pipeTo(
|
|
79
|
+
new WritableStream({
|
|
80
|
+
write(chunk: Uint8Array) {
|
|
81
|
+
chunks.push(decoder.decode(chunk, { stream: true }));
|
|
82
|
+
},
|
|
83
|
+
close() {
|
|
84
|
+
// Flush any remaining bytes in the decoder
|
|
85
|
+
const remaining = decoder.decode();
|
|
86
|
+
if (remaining) chunks.push(remaining);
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
.catch(() => {
|
|
91
|
+
// Stream abort — request cancelled. Not an error.
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
readable: new ReadableStream(), // no commands to send to Flight
|
|
96
|
+
writable: sink.writable,
|
|
97
|
+
getCollectedText() {
|
|
98
|
+
return chunks.join('');
|
|
99
|
+
},
|
|
100
|
+
getComponents() {
|
|
101
|
+
return parseDebugRows(chunks.join(''));
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Parse React Flight debug rows into component entries.
|
|
108
|
+
*
|
|
109
|
+
* The Flight debug channel writes rows in `hexId:json\n` format. Each row
|
|
110
|
+
* with a JSON object containing a `name` field is a component debug info
|
|
111
|
+
* entry. Rows without `name` (timing rows, reference rows like `D"$id"`)
|
|
112
|
+
* are skipped.
|
|
113
|
+
*
|
|
114
|
+
* Security: `props` are explicitly stripped from parsed entries — they may
|
|
115
|
+
* contain rendered output or user data. Only `name`, `env`, `key`, and
|
|
116
|
+
* `stack` are retained.
|
|
117
|
+
*/
|
|
118
|
+
export function parseDebugRows(text: string): DebugComponentEntry[] {
|
|
119
|
+
if (!text) return [];
|
|
120
|
+
|
|
121
|
+
const entries: DebugComponentEntry[] = [];
|
|
122
|
+
const lines = text.split('\n');
|
|
123
|
+
|
|
124
|
+
for (const line of lines) {
|
|
125
|
+
if (!line) continue;
|
|
126
|
+
|
|
127
|
+
// Flight row format: hexId:payload
|
|
128
|
+
const colonIdx = line.indexOf(':');
|
|
129
|
+
if (colonIdx === -1) continue;
|
|
130
|
+
|
|
131
|
+
let payload = line.slice(colonIdx + 1);
|
|
132
|
+
|
|
133
|
+
// React Flight debug rows may have a type-tag prefix before the JSON
|
|
134
|
+
// object (e.g., "D{...}" for debug info rows). Strip the single-char
|
|
135
|
+
// tag so the JSON parser sees the object. Non-JSON payloads like
|
|
136
|
+
// D"$a" reference rows are caught by the JSON.parse try/catch below.
|
|
137
|
+
// See TIM-556.
|
|
138
|
+
if (payload.length > 0 && payload[0] !== '{' && payload[0] !== '[' && payload[0] !== '"') {
|
|
139
|
+
payload = payload.slice(1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Skip payloads that still aren't JSON objects after tag stripping
|
|
143
|
+
if (!payload.startsWith('{')) continue;
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const parsed = JSON.parse(payload);
|
|
147
|
+
if (typeof parsed !== 'object' || parsed === null) continue;
|
|
148
|
+
if (typeof parsed.name !== 'string') continue;
|
|
149
|
+
|
|
150
|
+
// Strip props — may contain source-derived data or user data.
|
|
151
|
+
// Only retain: name, env, key, stack.
|
|
152
|
+
entries.push({
|
|
153
|
+
name: parsed.name,
|
|
154
|
+
env: parsed.env ?? null,
|
|
155
|
+
key: parsed.key ?? null,
|
|
156
|
+
stack: Array.isArray(parsed.stack) ? parsed.stack : null,
|
|
157
|
+
});
|
|
158
|
+
} catch {
|
|
159
|
+
// Malformed JSON — skip this row
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return entries;
|
|
164
|
+
}
|
|
165
|
+
|
|
37
166
|
/**
|
|
38
167
|
* Build segment metadata for the X-Timber-Segments response header.
|
|
39
168
|
* Describes the rendered segment chain with async status, enabling
|
|
@@ -23,37 +23,37 @@ import config from 'virtual:timber-config';
|
|
|
23
23
|
import buildManifest from 'virtual:timber-build-manifest';
|
|
24
24
|
// @ts-expect-error — virtual module provided by timber-entries plugin
|
|
25
25
|
import loadUserInstrumentation from 'virtual:timber-instrumentation';
|
|
26
|
+
// @ts-expect-error — virtual module provided by timber-entries plugin
|
|
27
|
+
import loadCacheHandler from 'virtual:timber-cache-handler';
|
|
26
28
|
|
|
27
|
-
import type { FormRerender } from '
|
|
28
|
-
import { handleActionRequest, isActionRequest } from '
|
|
29
|
-
import type { BodyLimitsConfig } from '
|
|
30
|
-
import type { BuildManifest } from '
|
|
29
|
+
import type { FormRerender } from '../action-handler.js';
|
|
30
|
+
import { handleActionRequest, isActionRequest } from '../action-handler.js';
|
|
31
|
+
import type { BodyLimitsConfig } from '../body-limits.js';
|
|
32
|
+
import type { BuildManifest } from '../build-manifest.js';
|
|
31
33
|
import {
|
|
32
|
-
buildCssLinkTags,
|
|
33
34
|
buildFontPreloadTags,
|
|
34
35
|
buildModulepreloadTags,
|
|
35
|
-
collectRouteCss,
|
|
36
36
|
collectRouteFonts,
|
|
37
37
|
collectRouteModulepreloads,
|
|
38
|
-
} from '
|
|
39
|
-
import type { LayoutEntry } from '
|
|
40
|
-
import { renderDenyPage, renderDenyPageAsRsc } from '
|
|
41
|
-
import { resolveLogMode } from '
|
|
42
|
-
import { sendEarlyHints103 } from '
|
|
43
|
-
import { collectEarlyHintHeaders } from '
|
|
44
|
-
import { runWithFormFlash } from '
|
|
45
|
-
import type { ClientBootstrapConfig } from '
|
|
46
|
-
import { buildClientScripts } from '
|
|
47
|
-
import type { InterceptionContext, PipelineConfig, RouteMatch } from '
|
|
48
|
-
import { createPipeline } from '
|
|
49
|
-
import {
|
|
50
|
-
import { buildRouteElement,
|
|
51
|
-
import type { ManifestSegmentNode } from '
|
|
52
|
-
import { createMetadataRouteMatcher, createRouteMatcher } from '
|
|
53
|
-
import { initDevTracing } from '
|
|
54
|
-
|
|
55
|
-
import { renderFallbackError as renderFallback } from '
|
|
56
|
-
import { loadInstrumentation } from '
|
|
38
|
+
} from '../build-manifest.js';
|
|
39
|
+
import type { LayoutEntry } from '../deny-renderer.js';
|
|
40
|
+
import { renderDenyPage, renderDenyPageAsRsc } from '../deny-renderer.js';
|
|
41
|
+
import { resolveLogMode } from '../dev-logger.js';
|
|
42
|
+
import { sendEarlyHints103 } from '../early-hints-sender.js';
|
|
43
|
+
import { collectEarlyHintHeaders } from '../early-hints.js';
|
|
44
|
+
import { runWithFormFlash } from '../form-flash.js';
|
|
45
|
+
import type { ClientBootstrapConfig } from '../html-injectors.js';
|
|
46
|
+
import { buildClientScripts } from '../html-injectors.js';
|
|
47
|
+
import type { InterceptionContext, PipelineConfig, RouteMatch } from '../pipeline.js';
|
|
48
|
+
import { createPipeline, coerceSegmentParams } from '../pipeline.js';
|
|
49
|
+
import { setSegmentParams } from '../request-context.js';
|
|
50
|
+
import { buildRouteElement, ParamCoercionError } from '../route-element-builder.js';
|
|
51
|
+
import type { ManifestSegmentNode } from '../route-matcher.js';
|
|
52
|
+
import { createMetadataRouteMatcher, createRouteMatcher } from '../route-matcher.js';
|
|
53
|
+
import { initDevTracing } from '../tracing.js';
|
|
54
|
+
|
|
55
|
+
import { renderFallbackError as renderFallback } from '../fallback-error.js';
|
|
56
|
+
import { loadInstrumentation } from '../instrumentation.js';
|
|
57
57
|
import { handleApiRoute } from './api-handler.js';
|
|
58
58
|
import { renderErrorPage, renderNoMatchPage } from './error-renderer.js';
|
|
59
59
|
import {
|
|
@@ -61,33 +61,62 @@ import {
|
|
|
61
61
|
createDebugChannelSink,
|
|
62
62
|
escapeHtml,
|
|
63
63
|
isRscPayloadRequest,
|
|
64
|
+
type DebugComponentEntry,
|
|
64
65
|
} from './helpers.js';
|
|
65
|
-
import { parseClientStateTree } from '
|
|
66
|
-
import {
|
|
67
|
-
createResponseCache,
|
|
68
|
-
resolveResponseCacheConfig,
|
|
69
|
-
type ResponseCache,
|
|
70
|
-
} from '#/server/response-cache.js';
|
|
66
|
+
import { parseClientStateTree } from '../state-tree-diff.js';
|
|
71
67
|
import { buildRscPayloadResponse } from './rsc-payload.js';
|
|
72
68
|
import { renderRscStream } from './rsc-stream.js';
|
|
73
69
|
import { renderSsrResponse } from './ssr-renderer.js';
|
|
74
70
|
import { callSsr } from './ssr-bridge.js';
|
|
75
|
-
import { isDebug, isDevMode, setDebugFromConfig } from '
|
|
71
|
+
import { isDebug, isDevMode, setDebugFromConfig } from '../debug.js';
|
|
72
|
+
import { recordTiming } from '../server-timing.js';
|
|
73
|
+
import { requestContextAls } from '../als-registry.js';
|
|
74
|
+
import { createAutoSitemapHandler } from '../sitemap-handler.js';
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Resolve the Server-Timing mode from timber.config.ts.
|
|
78
|
+
*
|
|
79
|
+
* If the user set `serverTiming` explicitly, use that value.
|
|
80
|
+
* Otherwise: `'detailed'` in dev, `'total'` in production.
|
|
81
|
+
*/
|
|
82
|
+
function resolveServerTimingMode(
|
|
83
|
+
config: Record<string, unknown>,
|
|
84
|
+
isDev: boolean
|
|
85
|
+
): 'detailed' | 'total' | false {
|
|
86
|
+
const userValue = config.serverTiming as 'detailed' | 'total' | false | undefined;
|
|
87
|
+
if (userValue !== undefined) return userValue;
|
|
88
|
+
return isDev ? 'detailed' : 'total';
|
|
89
|
+
}
|
|
76
90
|
|
|
77
91
|
// Dev-only pipeline error handler, set by the dev server after import.
|
|
78
92
|
// In production this is always undefined — no overhead.
|
|
79
|
-
|
|
93
|
+
// The third argument provides RSC debug component data (from the Flight
|
|
94
|
+
// debug channel) when available — used by the error overlay to show the
|
|
95
|
+
// server component tree context for render errors.
|
|
96
|
+
let _devPipelineErrorHandler:
|
|
97
|
+
| ((error: Error, phase: string, debugComponents?: DebugComponentEntry[]) => void)
|
|
98
|
+
| undefined;
|
|
80
99
|
|
|
81
100
|
/**
|
|
82
101
|
* Set the dev pipeline error handler.
|
|
83
102
|
*
|
|
84
103
|
* Called by the dev server after importing this module to wire pipeline
|
|
85
104
|
* errors into the Vite browser error overlay. No-op in production.
|
|
105
|
+
*
|
|
106
|
+
* The handler receives an optional third argument with RSC debug component
|
|
107
|
+
* info — component names, environments, and stack frames from the Flight
|
|
108
|
+
* debug channel. This is only populated for render-phase errors.
|
|
86
109
|
*/
|
|
87
|
-
export function setDevPipelineErrorHandler(
|
|
110
|
+
export function setDevPipelineErrorHandler(
|
|
111
|
+
handler: (error: Error, phase: string, debugComponents?: DebugComponentEntry[]) => void
|
|
112
|
+
): void {
|
|
88
113
|
_devPipelineErrorHandler = handler;
|
|
89
114
|
}
|
|
90
115
|
|
|
116
|
+
// Dev-only: debug components getter is stored per-request in ALS
|
|
117
|
+
// (RequestContextStore.debugComponentsGetter) to avoid cross-request
|
|
118
|
+
// race conditions. See TIM-557.
|
|
119
|
+
|
|
91
120
|
/**
|
|
92
121
|
* Create the RSC request handler from the route manifest.
|
|
93
122
|
*
|
|
@@ -101,13 +130,25 @@ async function createRequestHandler(manifest: typeof routeManifest, runtimeConfi
|
|
|
101
130
|
// See design/17-logging.md §"register() — Server Startup"
|
|
102
131
|
await loadInstrumentation(loadUserInstrumentation);
|
|
103
132
|
|
|
104
|
-
// Initialize
|
|
105
|
-
|
|
106
|
-
|
|
133
|
+
// Initialize deployment ID for version skew detection (TIM-446).
|
|
134
|
+
// The manifest init module sets globalThis.__TIMBER_DEPLOYMENT_ID__ at startup.
|
|
135
|
+
// In dev mode this is undefined — skew checks are skipped.
|
|
136
|
+
const deploymentId = (globalThis as Record<string, unknown>).__TIMBER_DEPLOYMENT_ID__ as
|
|
137
|
+
| string
|
|
107
138
|
| undefined;
|
|
108
|
-
if (
|
|
109
|
-
const {
|
|
110
|
-
|
|
139
|
+
if (deploymentId) {
|
|
140
|
+
const { setDeploymentId } = await import('../version-skew.js');
|
|
141
|
+
setDeploymentId(deploymentId);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Wire the configured cache handler into the module-level singleton (TIM-599).
|
|
145
|
+
// The cacheHandler is a class instance (e.g. RedisCacheHandler) that can't be
|
|
146
|
+
// JSON-serialized into virtual:timber-config. Instead, virtual:timber-cache-handler
|
|
147
|
+
// dynamically imports the user's timber.config.ts and extracts the handler.
|
|
148
|
+
const userCacheHandler = await loadCacheHandler();
|
|
149
|
+
if (userCacheHandler) {
|
|
150
|
+
const { setCacheHandler } = await import('../../cache/handler-store.js');
|
|
151
|
+
setCacheHandler(userCacheHandler as Parameters<typeof setCacheHandler>[0]);
|
|
111
152
|
}
|
|
112
153
|
|
|
113
154
|
const matchRoute = createRouteMatcher(manifest);
|
|
@@ -164,17 +205,6 @@ async function createRequestHandler(manifest: typeof routeManifest, runtimeConfi
|
|
|
164
205
|
|
|
165
206
|
const typedBuildManifest = buildManifest as BuildManifest;
|
|
166
207
|
|
|
167
|
-
// Initialize response-level caching and singleflight deduplication.
|
|
168
|
-
// See design/31-benchmarking.md for performance motivation.
|
|
169
|
-
const responseCacheRaw = (runtimeConfig as Record<string, unknown>).responseCache as
|
|
170
|
-
| { maxSize?: number; ttlMs?: number; publicOnly?: boolean }
|
|
171
|
-
| false
|
|
172
|
-
| undefined;
|
|
173
|
-
const responseCacheConfig = resolveResponseCacheConfig(responseCacheRaw);
|
|
174
|
-
const responseCache: ResponseCache | null = responseCacheConfig
|
|
175
|
-
? createResponseCache(responseCacheConfig)
|
|
176
|
-
: null;
|
|
177
|
-
|
|
178
208
|
const pipelineConfig: PipelineConfig = {
|
|
179
209
|
proxyLoader: manifest.proxy?.load,
|
|
180
210
|
matchRoute,
|
|
@@ -205,17 +235,16 @@ async function createRequestHandler(manifest: typeof routeManifest, runtimeConfi
|
|
|
205
235
|
_requestHeaderOverlay: Headers,
|
|
206
236
|
interception?: InterceptionContext
|
|
207
237
|
) => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return doRender();
|
|
238
|
+
return renderRoute(
|
|
239
|
+
req,
|
|
240
|
+
match,
|
|
241
|
+
responseHeaders,
|
|
242
|
+
clientBootstrap,
|
|
243
|
+
clientJsDisabled,
|
|
244
|
+
interception,
|
|
245
|
+
manifest.root,
|
|
246
|
+
manifest.globalError
|
|
247
|
+
);
|
|
219
248
|
},
|
|
220
249
|
renderNoMatch: async (req: Request, responseHeaders: Headers) => {
|
|
221
250
|
return renderNoMatchPage(req, manifest.root, responseHeaders, clientBootstrap);
|
|
@@ -224,14 +253,35 @@ async function createRequestHandler(manifest: typeof routeManifest, runtimeConfi
|
|
|
224
253
|
// Slow request threshold from timber.config.ts. Default 3000ms, 0 to disable.
|
|
225
254
|
// See design/17-logging.md §"slowRequestMs"
|
|
226
255
|
slowRequestMs: (runtimeConfig as Record<string, unknown>).slowRequestMs as number | undefined,
|
|
227
|
-
|
|
256
|
+
serverTiming: resolveServerTimingMode(runtimeConfig, isDev),
|
|
228
257
|
onPipelineError: isDev
|
|
229
258
|
? (error: Error, phase: string) => {
|
|
230
|
-
if (_devPipelineErrorHandler)
|
|
259
|
+
if (_devPipelineErrorHandler) {
|
|
260
|
+
// For render-phase errors, include RSC debug component data
|
|
261
|
+
// from the Flight debug channel (if available from the current request).
|
|
262
|
+
const store = requestContextAls.getStore();
|
|
263
|
+
const debugComponents =
|
|
264
|
+
phase === 'render' && store?.debugComponentsGetter
|
|
265
|
+
? store.debugComponentsGetter()
|
|
266
|
+
: undefined;
|
|
267
|
+
_devPipelineErrorHandler(error, phase, debugComponents);
|
|
268
|
+
}
|
|
231
269
|
}
|
|
232
270
|
: undefined,
|
|
233
271
|
renderFallbackError: (error, req, responseHeaders) =>
|
|
234
|
-
renderFallback(
|
|
272
|
+
renderFallback(
|
|
273
|
+
error,
|
|
274
|
+
req,
|
|
275
|
+
responseHeaders,
|
|
276
|
+
isDev,
|
|
277
|
+
manifest.root,
|
|
278
|
+
clientBootstrap,
|
|
279
|
+
manifest.globalError
|
|
280
|
+
),
|
|
281
|
+
// Auto-generated sitemap handler — enabled when sitemap.enabled is true
|
|
282
|
+
// and no user-authored sitemap exists at the app root.
|
|
283
|
+
// See design/16-metadata.md §"Auto-generated Sitemap"
|
|
284
|
+
autoSitemapHandler: createAutoSitemapHandler(manifest.root, runtimeConfig),
|
|
235
285
|
};
|
|
236
286
|
|
|
237
287
|
const pipeline = createPipeline(pipelineConfig);
|
|
@@ -267,6 +317,14 @@ async function createRequestHandler(manifest: typeof routeManifest, runtimeConfi
|
|
|
267
317
|
if (!revalidateMatch) {
|
|
268
318
|
throw new Error(`revalidatePath('${path}') — no matching route`);
|
|
269
319
|
}
|
|
320
|
+
// Coerce segment params (params.ts) before building the element tree.
|
|
321
|
+
// Without this, components receive raw strings instead of typed values.
|
|
322
|
+
await coerceSegmentParams(revalidateMatch);
|
|
323
|
+
// Set coerced params in ALS so rawSegmentParams() works during
|
|
324
|
+
// the revalidation render (AccessGate reads params via ALS).
|
|
325
|
+
// Without this, AccessGate → rawSegmentParams() throws because
|
|
326
|
+
// segmentParamsPromise is never set. See TIM-667.
|
|
327
|
+
setSegmentParams(revalidateMatch.segmentParams);
|
|
270
328
|
const routeResult = await buildRouteElement(revalidateReq, revalidateMatch);
|
|
271
329
|
return {
|
|
272
330
|
element: routeResult.element,
|
|
@@ -307,7 +365,9 @@ async function renderRoute(
|
|
|
307
365
|
responseHeaders: Headers,
|
|
308
366
|
clientBootstrap: ClientBootstrapConfig,
|
|
309
367
|
clientJsDisabled: boolean,
|
|
310
|
-
interception?: InterceptionContext
|
|
368
|
+
interception?: InterceptionContext,
|
|
369
|
+
rootSegment?: ManifestSegmentNode,
|
|
370
|
+
globalError?: { load: () => Promise<unknown>; filePath: string }
|
|
311
371
|
): Promise<Response> {
|
|
312
372
|
const segments = match.segments as unknown as ManifestSegmentNode[];
|
|
313
373
|
const leaf = segments[segments.length - 1];
|
|
@@ -326,49 +386,42 @@ async function renderRoute(
|
|
|
326
386
|
// See design/19-client-navigation.md §"X-Timber-State-Tree Header"
|
|
327
387
|
const clientStateTree = isRscPayloadRequest(_req) ? parseClientStateTree(_req) : null;
|
|
328
388
|
|
|
329
|
-
// Build the React element tree — loads modules,
|
|
330
|
-
// resolves metadata.
|
|
389
|
+
// Build the React element tree — loads modules, collects access checks,
|
|
390
|
+
// resolves metadata. Access checks are NOT run here — they run inside
|
|
391
|
+
// AccessPreRunner during renderToReadableStream so that access.ts and
|
|
392
|
+
// render components share the same React.cache scope (TIM-662).
|
|
393
|
+
//
|
|
394
|
+
// DenySignal/RedirectSignal from access checks are caught by onError
|
|
395
|
+
// during stream consumption and handled by renderSsrResponse /
|
|
396
|
+
// buildRscPayloadResponse.
|
|
331
397
|
let routeResult;
|
|
398
|
+
const _buildStart = performance.now();
|
|
332
399
|
try {
|
|
333
400
|
routeResult = await buildRouteElement(_req, match, interception, clientStateTree);
|
|
334
401
|
} catch (error) {
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
signal,
|
|
342
|
-
segs,
|
|
343
|
-
lc as LayoutEntry[],
|
|
344
|
-
responseHeaders,
|
|
345
|
-
createDebugChannelSink
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
return renderDenyPage(
|
|
349
|
-
signal,
|
|
350
|
-
segs,
|
|
351
|
-
lc as LayoutEntry[],
|
|
352
|
-
_req,
|
|
353
|
-
match,
|
|
354
|
-
responseHeaders,
|
|
355
|
-
clientBootstrap,
|
|
356
|
-
createDebugChannelSink,
|
|
357
|
-
callSsr
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
if (signal instanceof RedirectSignal) {
|
|
361
|
-
return buildRedirectResponse(_req, signal, responseHeaders);
|
|
362
|
-
}
|
|
402
|
+
// Param coercion failed — render the custom 404 page (status files / not-found).
|
|
403
|
+
// Previously returned a bare Response(null, { status: 404 }) which bypassed
|
|
404
|
+
// custom not-found pages. Now routes through renderNoMatchPage so apps with
|
|
405
|
+
// 404.tsx / not-found status files render their custom page.
|
|
406
|
+
if (error instanceof ParamCoercionError) {
|
|
407
|
+
return renderNoMatchPage(_req, rootSegment!, responseHeaders, clientBootstrap);
|
|
363
408
|
}
|
|
364
|
-
// No PageComponent found
|
|
409
|
+
// No PageComponent found — same treatment as param coercion: render custom 404.
|
|
365
410
|
if (error instanceof Error && error.message.startsWith('No page component')) {
|
|
366
|
-
return
|
|
411
|
+
return renderNoMatchPage(_req, rootSegment!, responseHeaders, clientBootstrap);
|
|
367
412
|
}
|
|
368
413
|
throw error;
|
|
369
414
|
}
|
|
370
415
|
|
|
371
|
-
const
|
|
416
|
+
const _buildEnd = performance.now();
|
|
417
|
+
recordTiming({
|
|
418
|
+
name: 'build',
|
|
419
|
+
dur: Math.round(_buildEnd - _buildStart),
|
|
420
|
+
desc: 'build element tree',
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
const { element, headElements, layoutComponents, deferSuspenseFor, skippedSegments } =
|
|
424
|
+
routeResult;
|
|
372
425
|
|
|
373
426
|
// Build head HTML for injection into the SSR output.
|
|
374
427
|
// Collects CSS, fonts, and modulepreload from the build manifest for matched segments.
|
|
@@ -380,16 +433,24 @@ async function renderRoute(
|
|
|
380
433
|
const typedManifest = buildManifest as BuildManifest;
|
|
381
434
|
let headHtml = '';
|
|
382
435
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
436
|
+
// CSS is handled by the RSC plugin via ReactDOM.preinit() with
|
|
437
|
+
// data-precedence attributes. This injects <link rel="stylesheet">
|
|
438
|
+
// tags during the RSC render phase — before our headHtml injection.
|
|
439
|
+
// We do NOT emit additional <link rel="stylesheet"> tags here because:
|
|
440
|
+
// 1. React's Float system deduplicates them, making ours redundant
|
|
441
|
+
// 2. The duplicate reference confuses React's client-side preload
|
|
442
|
+
// deduplication, causing "preload ignored" browser warnings
|
|
443
|
+
//
|
|
444
|
+
// CSS URLs are still collected for Early Hints (Link headers) in
|
|
445
|
+
// buildEarlyHintsHeaders() — those are HTTP headers, not DOM elements,
|
|
446
|
+
// so they don't conflict with Float.
|
|
447
|
+
|
|
448
|
+
// Inline font CSS as a <style> tag — @font-face rules and scoped classes.
|
|
449
|
+
// The font CSS is set on globalThis by the transformed font file's
|
|
450
|
+
// side-effect import of virtual:timber-font-css-register.
|
|
451
|
+
const fontCss = (globalThis as Record<string, unknown>).__timber_font_css as string | undefined;
|
|
452
|
+
if (fontCss) {
|
|
453
|
+
headHtml += `<style data-timber-fonts>${fontCss}</style>`;
|
|
393
454
|
}
|
|
394
455
|
|
|
395
456
|
const fontEntries = collectRouteFonts(segments, typedManifest);
|
|
@@ -417,8 +478,34 @@ async function renderRoute(
|
|
|
417
478
|
}
|
|
418
479
|
}
|
|
419
480
|
|
|
481
|
+
// In dev mode, inject the browser log forwarding script so console
|
|
482
|
+
// errors/warnings from the browser appear in the server terminal.
|
|
483
|
+
// Set by timber-dev-browser-logs plugin via globalThis (TIM-575).
|
|
484
|
+
if (isDevMode()) {
|
|
485
|
+
const devLogScript = (globalThis as Record<string, unknown>).__timber_dev_browser_log_script as
|
|
486
|
+
| string
|
|
487
|
+
| undefined;
|
|
488
|
+
if (devLogScript) {
|
|
489
|
+
headHtml += devLogScript;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
420
493
|
// Render to RSC Flight stream with signal tracking.
|
|
421
|
-
const
|
|
494
|
+
const _rscStart = performance.now();
|
|
495
|
+
const { rscStream, signals, getDebugComponents } = renderRscStream(element, _req);
|
|
496
|
+
|
|
497
|
+
// Store the debug components getter in ALS so onPipelineError can
|
|
498
|
+
// include component tree context for render-phase errors (dev mode only).
|
|
499
|
+
// Per-request via ALS — no cross-request race. See TIM-557.
|
|
500
|
+
const alsStore = requestContextAls.getStore();
|
|
501
|
+
if (alsStore) {
|
|
502
|
+
alsStore.debugComponentsGetter = getDebugComponents;
|
|
503
|
+
}
|
|
504
|
+
recordTiming({
|
|
505
|
+
name: 'rsc-init',
|
|
506
|
+
dur: Math.round(performance.now() - _rscStart),
|
|
507
|
+
desc: 'RSC stream init',
|
|
508
|
+
});
|
|
422
509
|
|
|
423
510
|
// Synchronous redirect — redirect() in access.ts or a non-async component
|
|
424
511
|
// throws during renderToReadableStream creation. Return HTTP redirect.
|
|
@@ -463,7 +550,8 @@ async function renderRoute(
|
|
|
463
550
|
_req,
|
|
464
551
|
match,
|
|
465
552
|
responseHeaders,
|
|
466
|
-
clientBootstrap
|
|
553
|
+
clientBootstrap,
|
|
554
|
+
globalError
|
|
467
555
|
);
|
|
468
556
|
}
|
|
469
557
|
|
|
@@ -497,15 +585,16 @@ async function renderRoute(
|
|
|
497
585
|
clientJsDisabled,
|
|
498
586
|
headHtml,
|
|
499
587
|
deferSuspenseFor,
|
|
588
|
+
globalError,
|
|
500
589
|
});
|
|
501
590
|
}
|
|
502
591
|
|
|
503
592
|
// Re-export for generated entry points (e.g., Nitro node-server/bun) to wrap
|
|
504
593
|
// the handler with per-request 103 Early Hints sender via ALS.
|
|
505
|
-
export { runWithEarlyHintsSender } from '
|
|
594
|
+
export { runWithEarlyHintsSender } from '../early-hints-sender.js';
|
|
506
595
|
|
|
507
596
|
// Re-export for generated entry points to wrap the handler with per-request
|
|
508
597
|
// waitUntil support via ALS. See design/11-platform.md §"waitUntil()".
|
|
509
|
-
export { runWithWaitUntil } from '
|
|
598
|
+
export { runWithWaitUntil } from '../waituntil-bridge.js';
|
|
510
599
|
|
|
511
600
|
export default await createRequestHandler(routeManifest, config);
|