@timber-js/app 0.2.0-alpha.8 → 0.2.0-alpha.80
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/actions-Dg-ANYHb.js +421 -0
- package/dist/_chunks/actions-Dg-ANYHb.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-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-C77ScO0m.js +106 -0
- package/dist/_chunks/define-C77ScO0m.js.map +1 -0
- package/dist/_chunks/define-CZqDwhSu.js +199 -0
- package/dist/_chunks/define-CZqDwhSu.js.map +1 -0
- package/dist/_chunks/define-cookie-C2IkoFGN.js +94 -0
- package/dist/_chunks/define-cookie-C2IkoFGN.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-Dpn_UfAD.js} +171 -97
- package/dist/_chunks/interception-Dpn_UfAD.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-qMsWgy9C.js +478 -0
- package/dist/_chunks/request-context-qMsWgy9C.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-C2plcNtG.js +64 -0
- package/dist/_chunks/stale-reload-C2plcNtG.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-Lo_s_pw2.js} +4 -4
- package/dist/_chunks/use-query-states-Lo_s_pw2.js.map +1 -0
- package/dist/_chunks/wrappers-_DTmImGt.js +63 -0
- package/dist/_chunks/wrappers-_DTmImGt.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 +6 -1
- 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 +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 +7 -21
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +210 -1017
- 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 +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-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 +210 -0
- package/dist/config-types.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/css.d.ts +1 -0
- package/dist/fonts/css.d.ts.map +1 -1
- package/dist/index.d.ts +45 -192
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12296 -11901
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +84 -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-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 +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/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 +4 -474
- 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 +6 -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-holding-server.d.ts +52 -0
- package/dist/server/dev-holding-server.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 +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 +6 -43
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +38 -2798
- 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 +2883 -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 +42 -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 +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 +4 -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 +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 +53 -23
- 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 +6 -1
- 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 +138 -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 +2 -2
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +19 -38
- package/src/client/internal.ts +57 -0
- package/src/client/link-pending-store.ts +111 -0
- package/src/client/link.tsx +329 -97
- 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 +16 -8
- 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 +3 -3
- package/src/client/use-router.ts +1 -1
- package/src/codec.ts +49 -0
- package/src/config-types.ts +208 -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/css.ts +2 -1
- package/src/index.ts +258 -354
- package/src/plugin-context.ts +200 -0
- 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 +70 -9
- package/src/plugins/entries.ts +71 -10
- package/src/plugins/fonts.ts +168 -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 +135 -35
- package/src/plugins/static-build.ts +17 -11
- 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 +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 +29 -0
- package/src/server/access-gate.tsx +70 -29
- package/src/server/action-client.ts +21 -2
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +21 -4
- 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-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 +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 +280 -120
- package/src/server/index.ts +26 -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 +227 -62
- 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 +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 +200 -112
- package/src/server/rsc-entry/rsc-payload.ts +65 -18
- package/src/server/rsc-entry/rsc-stream.ts +65 -13
- package/src/server/rsc-entry/ssr-bridge.ts +14 -5
- package/src/server/rsc-entry/ssr-renderer.ts +168 -38
- 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 +244 -229
- 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 +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/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 -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
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream utilities for the RSC rendering pipeline.
|
|
3
|
+
*
|
|
4
|
+
* teeWithErrorPropagation — wraps native ReadableStream.tee() with:
|
|
5
|
+
* 1. Cross-branch error propagation (error on one branch cancels the other)
|
|
6
|
+
* 2. Buffer divergence monitoring (warns + cancels when threshold exceeded)
|
|
7
|
+
*
|
|
8
|
+
* This prevents two classes of bugs:
|
|
9
|
+
* - Silent stalls when one tee branch errors and the other hangs indefinitely
|
|
10
|
+
* - Unbounded memory growth when one consumer (SSR) is much slower than the other
|
|
11
|
+
*
|
|
12
|
+
* Design doc: 02-rendering-pipeline.md §"RSC → SSR → Client Hydration"
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Default maximum buffer divergence before cancellation (5MB). */
|
|
16
|
+
const DEFAULT_MAX_BUFFER_BYTES = 5 * 1024 * 1024;
|
|
17
|
+
|
|
18
|
+
export interface TeeOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Maximum byte divergence between the two branches before both are
|
|
21
|
+
* cancelled. When one branch has consumed this many more bytes than
|
|
22
|
+
* the other, the tee's internal buffer is at least this large.
|
|
23
|
+
*
|
|
24
|
+
* Default: 5MB.
|
|
25
|
+
*/
|
|
26
|
+
maxBufferBytes?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Tee a ReadableStream with error propagation and buffer monitoring.
|
|
31
|
+
*
|
|
32
|
+
* Delegates to the native `stream.tee()` for the actual forking, then wraps
|
|
33
|
+
* each branch in a ReadableStream that:
|
|
34
|
+
* - Tracks bytes consumed per branch
|
|
35
|
+
* - Cancels both branches if byte divergence exceeds `maxBufferBytes`
|
|
36
|
+
* - Cancels the other branch if either branch is cancelled or errors
|
|
37
|
+
*
|
|
38
|
+
* The returned streams are drop-in replacements for the native tee branches.
|
|
39
|
+
*/
|
|
40
|
+
export function teeWithErrorPropagation(
|
|
41
|
+
stream: ReadableStream<Uint8Array>,
|
|
42
|
+
options?: TeeOptions
|
|
43
|
+
): [ReadableStream<Uint8Array>, ReadableStream<Uint8Array>] {
|
|
44
|
+
const maxBuffer = options?.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES;
|
|
45
|
+
const [rawBranch1, rawBranch2] = stream.tee();
|
|
46
|
+
|
|
47
|
+
// Shared state for cross-branch coordination
|
|
48
|
+
let consumed1 = 0;
|
|
49
|
+
let consumed2 = 0;
|
|
50
|
+
let cancelled = false;
|
|
51
|
+
|
|
52
|
+
// Readers and controllers are assigned when wrapBranch creates the wrapped
|
|
53
|
+
// streams. We store them so cancelBoth can cancel raw tee branches AND
|
|
54
|
+
// error the wrapped stream controllers for cross-branch propagation.
|
|
55
|
+
let rawReader1: ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
56
|
+
let rawReader2: ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
57
|
+
let controller1: ReadableStreamDefaultController<Uint8Array> | undefined;
|
|
58
|
+
let controller2: ReadableStreamDefaultController<Uint8Array> | undefined;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Cancel both tee branches. `initiator` is the branch index (0 or 1)
|
|
62
|
+
* that triggered the cancellation — its controller is already being
|
|
63
|
+
* closed/errored by the pull/cancel that triggered this, so we skip it.
|
|
64
|
+
* Pass -1 to cancel+error both (e.g., from the buffer divergence guard).
|
|
65
|
+
*
|
|
66
|
+
* Both raw readers are always canceled regardless of initiator, because
|
|
67
|
+
* the tee source stream is only released when both branches are canceled.
|
|
68
|
+
* ReadableStreamDefaultReader.cancel() is idempotent, so double-cancel
|
|
69
|
+
* is safe.
|
|
70
|
+
*/
|
|
71
|
+
function cancelBoth(reason: unknown, initiator: number = -1): void {
|
|
72
|
+
if (cancelled) return;
|
|
73
|
+
cancelled = true;
|
|
74
|
+
// Cancel both raw readers — tee source requires both branches canceled.
|
|
75
|
+
rawReader1?.cancel(reason).catch(() => {});
|
|
76
|
+
rawReader2?.cancel(reason).catch(() => {});
|
|
77
|
+
// Error wrapped controllers so consumers see the failure.
|
|
78
|
+
// Skip the initiator's controller — it's already being closed/errored.
|
|
79
|
+
if (initiator !== 0) {
|
|
80
|
+
try {
|
|
81
|
+
controller1?.error(reason);
|
|
82
|
+
} catch {
|
|
83
|
+
/* already closed/errored */
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (initiator !== 1) {
|
|
87
|
+
try {
|
|
88
|
+
controller2?.error(reason);
|
|
89
|
+
} catch {
|
|
90
|
+
/* already closed/errored */
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function wrapBranch(
|
|
96
|
+
branchIndex: number,
|
|
97
|
+
rawBranch: ReadableStream<Uint8Array>,
|
|
98
|
+
assignReader: (r: ReadableStreamDefaultReader<Uint8Array>) => void,
|
|
99
|
+
assignController: (c: ReadableStreamDefaultController<Uint8Array>) => void,
|
|
100
|
+
addConsumed: (n: number) => void,
|
|
101
|
+
getSelfConsumed: () => number,
|
|
102
|
+
getOtherConsumed: () => number
|
|
103
|
+
): ReadableStream<Uint8Array> {
|
|
104
|
+
const reader = rawBranch.getReader();
|
|
105
|
+
assignReader(reader);
|
|
106
|
+
|
|
107
|
+
return new ReadableStream<Uint8Array>({
|
|
108
|
+
start(controller) {
|
|
109
|
+
assignController(controller);
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
async pull(controller) {
|
|
113
|
+
if (cancelled) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
const { done, value } = await reader.read();
|
|
119
|
+
|
|
120
|
+
// Re-check after await — cancelBoth may have fired while we
|
|
121
|
+
// were waiting on the raw reader.
|
|
122
|
+
if (cancelled) return;
|
|
123
|
+
|
|
124
|
+
if (done) {
|
|
125
|
+
try {
|
|
126
|
+
controller.close();
|
|
127
|
+
} catch {
|
|
128
|
+
/* controller already errored by cancelBoth */
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
addConsumed(value.byteLength);
|
|
134
|
+
|
|
135
|
+
// Check buffer divergence: the difference in consumed bytes
|
|
136
|
+
// approximates the tee's internal buffer size.
|
|
137
|
+
const divergence = getSelfConsumed() - getOtherConsumed();
|
|
138
|
+
if (divergence > maxBuffer) {
|
|
139
|
+
const error = new Error(
|
|
140
|
+
`RSC stream tee buffer exceeded ${formatBytes(maxBuffer)} ` +
|
|
141
|
+
`(divergence: ${formatBytes(divergence)}). ` +
|
|
142
|
+
`This usually means SSR is much slower than the inline stream consumer. ` +
|
|
143
|
+
`Consider reducing RSC payload size or increasing the tee buffer limit.`
|
|
144
|
+
);
|
|
145
|
+
console.warn(`[timber] ${error.message}`);
|
|
146
|
+
cancelBoth(error);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
controller.enqueue(value);
|
|
151
|
+
} catch (err) {
|
|
152
|
+
if (!cancelled) {
|
|
153
|
+
// Source stream errored — propagate to both branches.
|
|
154
|
+
// cancelBoth with initiator skips our own controller,
|
|
155
|
+
// so we error it explicitly here.
|
|
156
|
+
cancelBoth(err, branchIndex);
|
|
157
|
+
try {
|
|
158
|
+
controller.error(err);
|
|
159
|
+
} catch {
|
|
160
|
+
/* already closed/errored */
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
cancel(reason) {
|
|
167
|
+
// Consumer cancelled this branch — propagate to the other
|
|
168
|
+
cancelBoth(reason, branchIndex);
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const wrapped1 = wrapBranch(
|
|
174
|
+
0,
|
|
175
|
+
rawBranch1,
|
|
176
|
+
(r) => {
|
|
177
|
+
rawReader1 = r;
|
|
178
|
+
},
|
|
179
|
+
(c) => {
|
|
180
|
+
controller1 = c;
|
|
181
|
+
},
|
|
182
|
+
(n) => {
|
|
183
|
+
consumed1 += n;
|
|
184
|
+
},
|
|
185
|
+
() => consumed1,
|
|
186
|
+
() => consumed2
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const wrapped2 = wrapBranch(
|
|
190
|
+
1,
|
|
191
|
+
rawBranch2,
|
|
192
|
+
(r) => {
|
|
193
|
+
rawReader2 = r;
|
|
194
|
+
},
|
|
195
|
+
(c) => {
|
|
196
|
+
controller2 = c;
|
|
197
|
+
},
|
|
198
|
+
(n) => {
|
|
199
|
+
consumed2 += n;
|
|
200
|
+
},
|
|
201
|
+
() => consumed2,
|
|
202
|
+
() => consumed1
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
return [wrapped1, wrapped2];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Format bytes as human-readable string (e.g., "5.00 MB"). */
|
|
209
|
+
function formatBytes(bytes: number): string {
|
|
210
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
211
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;
|
|
212
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
213
|
+
}
|
package/src/server/tracing.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tracing — per-request trace ID via AsyncLocalStorage, OTEL span helpers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* getTraceId() is always available in server code (middleware, access, components, actions).
|
|
5
5
|
* Returns a 32-char lowercase hex string — the OTEL trace ID when an SDK is active,
|
|
6
6
|
* or a crypto.randomUUID()-derived fallback otherwise.
|
|
7
7
|
*
|
|
@@ -24,11 +24,11 @@ export type { TraceStore } from './als-registry.js';
|
|
|
24
24
|
*
|
|
25
25
|
* Throws if called outside a request context (no ALS store).
|
|
26
26
|
*/
|
|
27
|
-
export function
|
|
27
|
+
export function getTraceId(): string {
|
|
28
28
|
const store = traceAls.getStore();
|
|
29
29
|
if (!store) {
|
|
30
30
|
throw new Error(
|
|
31
|
-
'[timber]
|
|
31
|
+
'[timber] getTraceId() called outside of a request context. ' +
|
|
32
32
|
'It can only be used in middleware, access checks, server components, and server actions.'
|
|
33
33
|
);
|
|
34
34
|
}
|
|
@@ -38,7 +38,7 @@ export function traceId(): string {
|
|
|
38
38
|
/**
|
|
39
39
|
* Returns the current OTEL span ID if available, undefined otherwise.
|
|
40
40
|
*/
|
|
41
|
-
export function
|
|
41
|
+
export function getSpanId(): string | undefined {
|
|
42
42
|
return traceAls.getStore()?.spanId;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -86,7 +86,7 @@ export function updateSpanId(newSpanId: string | undefined): void {
|
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
88
|
* Get the current trace store, or undefined if outside a request context.
|
|
89
|
-
* Framework-internal — use
|
|
89
|
+
* Framework-internal — use getTraceId()/getSpanId() in user code.
|
|
90
90
|
*/
|
|
91
91
|
export function getTraceStore(): TraceStore | undefined {
|
|
92
92
|
return traceAls.getStore();
|
|
@@ -110,9 +110,20 @@ export async function initDevTracing(
|
|
|
110
110
|
const api = await getOtelApi();
|
|
111
111
|
if (!api) return;
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
let DevSpanProcessor: typeof import('./dev-span-processor.js').DevSpanProcessor;
|
|
114
|
+
let BasicTracerProvider: typeof import('@opentelemetry/sdk-trace-base').BasicTracerProvider;
|
|
115
|
+
let AsyncLocalStorageContextManager: typeof import('@opentelemetry/context-async-hooks').AsyncLocalStorageContextManager;
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
({ DevSpanProcessor } = await import('./dev-span-processor.js'));
|
|
119
|
+
({ BasicTracerProvider } = await import('@opentelemetry/sdk-trace-base'));
|
|
120
|
+
({ AsyncLocalStorageContextManager } = await import('@opentelemetry/context-async-hooks'));
|
|
121
|
+
} catch (err) {
|
|
122
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
123
|
+
console.warn(`[timber] Dev tracing disabled — failed to load OTEL packages:\n ${msg}`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
116
127
|
const processor = new DevSpanProcessor(config);
|
|
117
128
|
|
|
118
129
|
// Register a context manager so OTEL can propagate the active span
|
|
@@ -199,7 +210,7 @@ export async function withSpan<T>(
|
|
|
199
210
|
|
|
200
211
|
const api = (await getOtelApi())!;
|
|
201
212
|
return tracer.startActiveSpan(name, { attributes }, async (span) => {
|
|
202
|
-
const prevSpanId =
|
|
213
|
+
const prevSpanId = getSpanId();
|
|
203
214
|
updateSpanId(span.spanContext().spanId);
|
|
204
215
|
try {
|
|
205
216
|
const result = await fn();
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* See design/02-rendering-pipeline.md §"Element Tree Construction"
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { SegmentNode, RouteFile } from '
|
|
13
|
+
import type { SegmentNode, RouteFile } from '../routing/types.js';
|
|
14
14
|
|
|
15
15
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
16
16
|
|
|
@@ -46,10 +46,6 @@ export type SlotElements = Map<string, ReactElement>;
|
|
|
46
46
|
export interface TreeBuilderConfig {
|
|
47
47
|
/** The matched segment chain from root to leaf. */
|
|
48
48
|
segments: SegmentNode[];
|
|
49
|
-
/** Route params extracted by the matcher (catch-all segments produce string[]). */
|
|
50
|
-
params: Record<string, string | string[]>;
|
|
51
|
-
/** Parsed search params (typed or URLSearchParams). */
|
|
52
|
-
searchParams: unknown;
|
|
53
49
|
/** Loads a route file's module. */
|
|
54
50
|
loadModule: ModuleLoader;
|
|
55
51
|
/** React.createElement or equivalent. */
|
|
@@ -77,9 +73,7 @@ export interface TreeBuilderConfig {
|
|
|
77
73
|
* (backward compat for tree-builder.ts which doesn't run a pre-render pass).
|
|
78
74
|
*/
|
|
79
75
|
export interface AccessGateProps {
|
|
80
|
-
accessFn: (
|
|
81
|
-
params: Record<string, string | string[]>;
|
|
82
|
-
searchParams: unknown;
|
|
76
|
+
accessFn: () => unknown;
|
|
83
77
|
/** Segment name for dev logging (e.g. "authenticated", "dashboard"). */
|
|
84
78
|
segmentName?: string;
|
|
85
79
|
/**
|
|
@@ -92,18 +86,32 @@ export interface AccessGateProps {
|
|
|
92
86
|
| 'pass'
|
|
93
87
|
| import('./primitives.js').DenySignal
|
|
94
88
|
| import('./primitives.js').RedirectSignal;
|
|
89
|
+
/**
|
|
90
|
+
* Deny page fallback chain. When provided and a DenySignal is caught,
|
|
91
|
+
* AccessGate renders the matching deny page in-tree instead of throwing.
|
|
92
|
+
* This prevents the error from reaching React Flight, eliminating the
|
|
93
|
+
* second render pass. See TIM-666.
|
|
94
|
+
*/
|
|
95
|
+
denyPages?: import('./deny-page-resolver.js').DenyPageEntry[];
|
|
95
96
|
children: ReactElement;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
/**
|
|
99
100
|
* Framework-injected slot access gate component.
|
|
100
101
|
* On denial, renders denied.tsx → default.tsx → null instead of failing the page.
|
|
102
|
+
*
|
|
103
|
+
* DeniedComponent is passed instead of a pre-built element so that
|
|
104
|
+
* SlotAccessGate can forward DenySignal.data as dangerouslyPassData
|
|
105
|
+
* and slotName as the slot prop after catching the signal.
|
|
101
106
|
*/
|
|
102
107
|
export interface SlotAccessGateProps {
|
|
103
|
-
accessFn: (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
accessFn: () => unknown;
|
|
109
|
+
/** The denied.tsx component (not a pre-built element). null if no denied.tsx exists. */
|
|
110
|
+
DeniedComponent: ((...args: unknown[]) => unknown) | null;
|
|
111
|
+
/** Slot directory name without @ prefix (e.g. "admin", "sidebar"). */
|
|
112
|
+
slotName: string;
|
|
113
|
+
/** createElement function for building elements dynamically. */
|
|
114
|
+
createElement: CreateElement;
|
|
107
115
|
defaultFallback: ReactElement | null;
|
|
108
116
|
children: ReactElement;
|
|
109
117
|
}
|
|
@@ -113,7 +121,8 @@ export interface SlotAccessGateProps {
|
|
|
113
121
|
* Wraps content with status-code error boundary handling.
|
|
114
122
|
*/
|
|
115
123
|
export interface ErrorBoundaryProps {
|
|
116
|
-
fallbackComponent
|
|
124
|
+
fallbackComponent?: ReactElement | null;
|
|
125
|
+
fallbackElement?: ReactElement | null;
|
|
117
126
|
status?: number;
|
|
118
127
|
children: ReactElement;
|
|
119
128
|
}
|
|
@@ -143,8 +152,7 @@ export interface TreeBuildResult {
|
|
|
143
152
|
* Parallel slots are resolved at each layout level and composed as named props.
|
|
144
153
|
*/
|
|
145
154
|
export async function buildElementTree(config: TreeBuilderConfig): Promise<TreeBuildResult> {
|
|
146
|
-
const { segments,
|
|
147
|
-
config;
|
|
155
|
+
const { segments, loadModule, createElement, errorBoundaryComponent } = config;
|
|
148
156
|
|
|
149
157
|
if (segments.length === 0) {
|
|
150
158
|
throw new Error('[timber] buildElementTree: empty segment chain');
|
|
@@ -168,8 +176,8 @@ export async function buildElementTree(config: TreeBuilderConfig): Promise<TreeB
|
|
|
168
176
|
);
|
|
169
177
|
}
|
|
170
178
|
|
|
171
|
-
// Build the page element
|
|
172
|
-
let element: ReactElement = createElement(PageComponent, {
|
|
179
|
+
// Build the page element — params are accessed via getSegmentParams() from ALS
|
|
180
|
+
let element: ReactElement = createElement(PageComponent, {});
|
|
173
181
|
|
|
174
182
|
// Build tree bottom-up: wrap page, then walk segments from leaf to root
|
|
175
183
|
for (let i = segments.length - 1; i >= 0; i--) {
|
|
@@ -190,8 +198,6 @@ export async function buildElementTree(config: TreeBuilderConfig): Promise<TreeB
|
|
|
190
198
|
const accessFn = accessModule.default as AccessGateProps['accessFn'];
|
|
191
199
|
element = createElement('timber:access-gate', {
|
|
192
200
|
accessFn,
|
|
193
|
-
params,
|
|
194
|
-
searchParams,
|
|
195
201
|
segmentName: segment.segmentName,
|
|
196
202
|
children: element,
|
|
197
203
|
} satisfies AccessGateProps);
|
|
@@ -211,8 +217,6 @@ export async function buildElementTree(config: TreeBuilderConfig): Promise<TreeB
|
|
|
211
217
|
for (const [slotName, slotNode] of segment.slots) {
|
|
212
218
|
slotProps[slotName] = await buildSlotElement(
|
|
213
219
|
slotNode,
|
|
214
|
-
params,
|
|
215
|
-
searchParams,
|
|
216
220
|
loadModule,
|
|
217
221
|
createElement,
|
|
218
222
|
errorBoundaryComponent
|
|
@@ -222,8 +226,6 @@ export async function buildElementTree(config: TreeBuilderConfig): Promise<TreeB
|
|
|
222
226
|
|
|
223
227
|
element = createElement(LayoutComponent, {
|
|
224
228
|
...slotProps,
|
|
225
|
-
params,
|
|
226
|
-
searchParams,
|
|
227
229
|
children: element,
|
|
228
230
|
});
|
|
229
231
|
}
|
|
@@ -243,8 +245,6 @@ export async function buildElementTree(config: TreeBuilderConfig): Promise<TreeB
|
|
|
243
245
|
*/
|
|
244
246
|
async function buildSlotElement(
|
|
245
247
|
slotNode: SegmentNode,
|
|
246
|
-
params: Record<string, string | string[]>,
|
|
247
|
-
searchParams: unknown,
|
|
248
248
|
loadModule: ModuleLoader,
|
|
249
249
|
createElement: CreateElement,
|
|
250
250
|
errorBoundaryComponent: unknown
|
|
@@ -261,10 +261,10 @@ async function buildSlotElement(
|
|
|
261
261
|
|
|
262
262
|
// If no page, render default.tsx or null
|
|
263
263
|
if (!PageComponent) {
|
|
264
|
-
return DefaultComponent ? createElement(DefaultComponent, {
|
|
264
|
+
return DefaultComponent ? createElement(DefaultComponent, {}) : null;
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
let element: ReactElement = createElement(PageComponent, {
|
|
267
|
+
let element: ReactElement = createElement(PageComponent, {});
|
|
268
268
|
|
|
269
269
|
// Wrap in error boundaries
|
|
270
270
|
element = await wrapWithErrorBoundaries(
|
|
@@ -280,27 +280,19 @@ async function buildSlotElement(
|
|
|
280
280
|
const accessModule = await loadModule(slotNode.access);
|
|
281
281
|
const accessFn = accessModule.default as SlotAccessGateProps['accessFn'];
|
|
282
282
|
|
|
283
|
-
// Load denied.tsx
|
|
283
|
+
// Load denied.tsx — pass component (not pre-built element) so
|
|
284
|
+
// SlotAccessGate can forward DenySignal.data dynamically. See TIM-488.
|
|
284
285
|
const deniedModule = slotNode.denied ? await loadModule(slotNode.denied) : null;
|
|
285
|
-
const DeniedComponent =
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const deniedFallback = DeniedComponent
|
|
290
|
-
? createElement(DeniedComponent, {
|
|
291
|
-
slot: slotNode.segmentName.replace(/^@/, ''),
|
|
292
|
-
dangerouslyPassData: undefined,
|
|
293
|
-
})
|
|
294
|
-
: null;
|
|
295
|
-
const defaultFallback = DefaultComponent
|
|
296
|
-
? createElement(DefaultComponent, { params, searchParams })
|
|
297
|
-
: null;
|
|
286
|
+
const DeniedComponent =
|
|
287
|
+
(deniedModule?.default as ((...args: unknown[]) => ReactElement) | undefined) ?? null;
|
|
288
|
+
|
|
289
|
+
const defaultFallback = DefaultComponent ? createElement(DefaultComponent, {}) : null;
|
|
298
290
|
|
|
299
291
|
element = createElement('timber:slot-access-gate', {
|
|
300
292
|
accessFn,
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
293
|
+
DeniedComponent,
|
|
294
|
+
slotName: slotNode.segmentName.replace(/^@/, ''),
|
|
295
|
+
createElement,
|
|
304
296
|
defaultFallback,
|
|
305
297
|
children: element,
|
|
306
298
|
} satisfies SlotAccessGateProps);
|
|
@@ -311,6 +303,19 @@ async function buildSlotElement(
|
|
|
311
303
|
|
|
312
304
|
// ─── Error Boundary Wrapping ─────────────────────────────────────────────────
|
|
313
305
|
|
|
306
|
+
/** MDX/markdown extensions — these are server components that cannot be passed as function props. */
|
|
307
|
+
const MDX_EXTENSIONS = new Set(['mdx', 'md']);
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Check if a route file is an MDX/markdown file based on its extension.
|
|
311
|
+
* MDX components are server components by default and cannot cross the
|
|
312
|
+
* RSC→client boundary as function props. They must be pre-rendered as
|
|
313
|
+
* elements and passed as fallbackElement instead of fallbackComponent.
|
|
314
|
+
*/
|
|
315
|
+
function isMdxFile(file: RouteFile): boolean {
|
|
316
|
+
return MDX_EXTENSIONS.has(file.extension);
|
|
317
|
+
}
|
|
318
|
+
|
|
314
319
|
/**
|
|
315
320
|
* Wrap an element with error boundaries from a segment's status-code files.
|
|
316
321
|
*
|
|
@@ -320,6 +325,12 @@ async function buildSlotElement(
|
|
|
320
325
|
* 3. error.tsx (general error boundary)
|
|
321
326
|
*
|
|
322
327
|
* This creates the fallback chain described in design/10-error-handling.md.
|
|
328
|
+
*
|
|
329
|
+
* MDX status files are server components and cannot be passed as function
|
|
330
|
+
* props to TimberErrorBoundary (a 'use client' component). Instead, they
|
|
331
|
+
* are pre-rendered as elements and passed as fallbackElement. The error
|
|
332
|
+
* boundary renders the element directly when an error is caught.
|
|
333
|
+
* See TIM-503.
|
|
323
334
|
*/
|
|
324
335
|
async function wrapWithErrorBoundaries(
|
|
325
336
|
segment: SegmentNode,
|
|
@@ -340,11 +351,18 @@ async function wrapWithErrorBoundaries(
|
|
|
340
351
|
const mod = await loadModule(file);
|
|
341
352
|
const Component = mod.default;
|
|
342
353
|
if (Component) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
354
|
+
const boundaryProps = isMdxFile(file)
|
|
355
|
+
? ({
|
|
356
|
+
fallbackElement: createElement(Component, { status }),
|
|
357
|
+
status,
|
|
358
|
+
children: element,
|
|
359
|
+
} satisfies ErrorBoundaryProps)
|
|
360
|
+
: ({
|
|
361
|
+
fallbackComponent: Component,
|
|
362
|
+
status,
|
|
363
|
+
children: element,
|
|
364
|
+
} satisfies ErrorBoundaryProps);
|
|
365
|
+
element = createElement(errorBoundaryComponent, boundaryProps);
|
|
348
366
|
}
|
|
349
367
|
}
|
|
350
368
|
}
|
|
@@ -356,25 +374,41 @@ async function wrapWithErrorBoundaries(
|
|
|
356
374
|
const mod = await loadModule(file);
|
|
357
375
|
const Component = mod.default;
|
|
358
376
|
if (Component) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
377
|
+
const categoryStatus = key === '4xx' ? 400 : 500;
|
|
378
|
+
const boundaryProps = isMdxFile(file)
|
|
379
|
+
? ({
|
|
380
|
+
fallbackElement: createElement(Component, {}),
|
|
381
|
+
status: categoryStatus,
|
|
382
|
+
children: element,
|
|
383
|
+
} satisfies ErrorBoundaryProps)
|
|
384
|
+
: ({
|
|
385
|
+
fallbackComponent: Component,
|
|
386
|
+
status: categoryStatus,
|
|
387
|
+
children: element,
|
|
388
|
+
} satisfies ErrorBoundaryProps);
|
|
389
|
+
element = createElement(errorBoundaryComponent, boundaryProps);
|
|
364
390
|
}
|
|
365
391
|
}
|
|
366
392
|
}
|
|
367
393
|
}
|
|
368
394
|
|
|
369
395
|
// Wrap with error.tsx (outermost — catches anything not matched by status files)
|
|
396
|
+
// Note: error.tsx/error.mdx receives { error, digest, reset } props.
|
|
397
|
+
// MDX error files are pre-rendered without those props (they're static content).
|
|
370
398
|
if (segment.error) {
|
|
371
399
|
const errorModule = await loadModule(segment.error);
|
|
372
400
|
const ErrorComponent = errorModule.default;
|
|
373
401
|
if (ErrorComponent) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
402
|
+
const boundaryProps = isMdxFile(segment.error)
|
|
403
|
+
? ({
|
|
404
|
+
fallbackElement: createElement(ErrorComponent, {}),
|
|
405
|
+
children: element,
|
|
406
|
+
} satisfies ErrorBoundaryProps)
|
|
407
|
+
: ({
|
|
408
|
+
fallbackComponent: ErrorComponent,
|
|
409
|
+
children: element,
|
|
410
|
+
} satisfies ErrorBoundaryProps);
|
|
411
|
+
element = createElement(errorBoundaryComponent, boundaryProps);
|
|
378
412
|
}
|
|
379
413
|
}
|
|
380
414
|
|
package/src/server/types.ts
CHANGED
|
@@ -22,8 +22,7 @@ export interface MiddlewareContext {
|
|
|
22
22
|
req: Request;
|
|
23
23
|
requestHeaders: Headers;
|
|
24
24
|
headers: Headers;
|
|
25
|
-
|
|
26
|
-
searchParams: unknown;
|
|
25
|
+
segmentParams: Record<string, string | string[]>;
|
|
27
26
|
/** Declare early hints for critical resources. Appends Link headers. */
|
|
28
27
|
earlyHints: (hints: EarlyHint[]) => void;
|
|
29
28
|
}
|
|
@@ -35,10 +34,8 @@ export interface RouteContext {
|
|
|
35
34
|
headers: Headers;
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
searchParams: unknown;
|
|
41
|
-
}
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
38
|
+
export interface AccessContext {}
|
|
42
39
|
|
|
43
40
|
export interface Metadata {
|
|
44
41
|
title?: string | { default?: string; template?: string; absolute?: string };
|