@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
|
@@ -16,16 +16,132 @@
|
|
|
16
16
|
* See design/02-rendering-pipeline.md §"Parallel Slots"
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { TimberErrorBoundary } from '
|
|
20
|
-
import SlotErrorFallback from '
|
|
19
|
+
import { TimberErrorBoundary } from '../client/error-boundary.js';
|
|
20
|
+
import SlotErrorFallback from '../client/slot-error-fallback.js';
|
|
21
21
|
import { SlotAccessGate } from './access-gate.js';
|
|
22
22
|
import { wrapSegmentWithErrorBoundaries } from './error-boundary-wrapper.js';
|
|
23
|
+
import { isClientReference } from './route-element-builder.js';
|
|
24
|
+
import { loadModule } from './safe-load.js';
|
|
23
25
|
import type { InterceptionContext, RouteMatch } from './pipeline.js';
|
|
24
|
-
import { DenySignal } from './primitives.js';
|
|
26
|
+
import { DenySignal, RedirectSignal } from './primitives.js';
|
|
27
|
+
import { logRenderError } from './logger.js';
|
|
25
28
|
import type { ManifestSegmentNode } from './route-matcher.js';
|
|
26
29
|
|
|
27
30
|
type CreateElementFn = (...args: unknown[]) => React.ReactElement;
|
|
28
31
|
|
|
32
|
+
// ─── Module Loading Helpers ─────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Load a module and extract its default export as a component function.
|
|
36
|
+
* Returns undefined if no default export exists.
|
|
37
|
+
*/
|
|
38
|
+
async function loadComponent(loader: {
|
|
39
|
+
load: () => Promise<unknown>;
|
|
40
|
+
filePath: string;
|
|
41
|
+
}): Promise<((...args: unknown[]) => unknown) | undefined> {
|
|
42
|
+
const mod = await loadModule(loader);
|
|
43
|
+
return mod.default as ((...args: unknown[]) => unknown) | undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Load and render the default.tsx fallback for a slot node.
|
|
48
|
+
* Returns null if the slot has no default.tsx or it has no default export.
|
|
49
|
+
*/
|
|
50
|
+
async function renderDefaultFallback(
|
|
51
|
+
slotNode: ManifestSegmentNode,
|
|
52
|
+
h: CreateElementFn
|
|
53
|
+
): Promise<React.ReactElement | null> {
|
|
54
|
+
if (!slotNode.default) return null;
|
|
55
|
+
const DefaultComp = await loadComponent(slotNode.default);
|
|
56
|
+
if (!DefaultComp) return null;
|
|
57
|
+
return h(DefaultComp, {});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ─── Segment Tree Matching ──────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Find a matching child node for a URL segment name.
|
|
64
|
+
*
|
|
65
|
+
* Tries matches in priority order:
|
|
66
|
+
* 1. Static segment (exact name match)
|
|
67
|
+
* 2. Dynamic segment ([param])
|
|
68
|
+
* 3. Catch-all or optional-catch-all ([...param] / [[...param]])
|
|
69
|
+
* 4. Group children (transparent wrappers)
|
|
70
|
+
*
|
|
71
|
+
* Returns `{ node, consumesRest }` where `consumesRest` is true for catch-all
|
|
72
|
+
* segments that consume all remaining URL parts.
|
|
73
|
+
*/
|
|
74
|
+
function findMatchingChild(
|
|
75
|
+
children: ManifestSegmentNode[],
|
|
76
|
+
segmentName: string
|
|
77
|
+
): { node: ManifestSegmentNode; consumesRest: boolean } | null {
|
|
78
|
+
// 1. Static match
|
|
79
|
+
for (const child of children) {
|
|
80
|
+
if (child.segmentType === 'static' && child.segmentName === segmentName) {
|
|
81
|
+
return { node: child, consumesRest: false };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 2. Dynamic match
|
|
86
|
+
for (const child of children) {
|
|
87
|
+
if (child.segmentType === 'dynamic') {
|
|
88
|
+
return { node: child, consumesRest: false };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 3. Catch-all match — consumes all remaining segments
|
|
93
|
+
for (const child of children) {
|
|
94
|
+
if (child.segmentType === 'catch-all' || child.segmentType === 'optional-catch-all') {
|
|
95
|
+
return { node: child, consumesRest: true };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 4. Group children (transparent)
|
|
100
|
+
for (const child of children) {
|
|
101
|
+
if (child.segmentType === 'group') {
|
|
102
|
+
for (const groupChild of child.children ?? []) {
|
|
103
|
+
if (groupChild.segmentName === segmentName) {
|
|
104
|
+
return { node: groupChild, consumesRest: false };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Walk a segment tree from `startNode`, matching each part in `parts` against
|
|
115
|
+
* child nodes. Returns the chain of matched nodes (including startNode) and the
|
|
116
|
+
* final node, or null if any part fails to match.
|
|
117
|
+
*/
|
|
118
|
+
function walkSegmentTree(
|
|
119
|
+
startNode: ManifestSegmentNode,
|
|
120
|
+
parts: { segmentName: string }[] | string[],
|
|
121
|
+
initialChain: ManifestSegmentNode[] = [startNode]
|
|
122
|
+
): { chain: ManifestSegmentNode[]; leaf: ManifestSegmentNode } | null {
|
|
123
|
+
const chain = [...initialChain];
|
|
124
|
+
let currentNode = startNode;
|
|
125
|
+
|
|
126
|
+
for (const part of parts) {
|
|
127
|
+
const segName = typeof part === 'string' ? part : part.segmentName;
|
|
128
|
+
const directChildren = currentNode.children ?? [];
|
|
129
|
+
const match = findMatchingChild(directChildren, segName);
|
|
130
|
+
|
|
131
|
+
if (!match) return null;
|
|
132
|
+
|
|
133
|
+
chain.push(match.node);
|
|
134
|
+
currentNode = match.node;
|
|
135
|
+
|
|
136
|
+
// Catch-all segments consume all remaining parts
|
|
137
|
+
if (match.consumesRest) break;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return { chain, leaf: currentNode };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ─── Slot Element Resolution ────────────────────────────────────────────────
|
|
144
|
+
|
|
29
145
|
/**
|
|
30
146
|
* Resolve the element for a parallel slot.
|
|
31
147
|
*
|
|
@@ -40,7 +156,6 @@ type CreateElementFn = (...args: unknown[]) => React.ReactElement;
|
|
|
40
156
|
export async function resolveSlotElement(
|
|
41
157
|
slotNode: ManifestSegmentNode,
|
|
42
158
|
match: RouteMatch,
|
|
43
|
-
paramsPromise: Promise<Record<string, string | string[]>>,
|
|
44
159
|
h: CreateElementFn,
|
|
45
160
|
interception?: InterceptionContext
|
|
46
161
|
): Promise<React.ReactElement | null> {
|
|
@@ -54,125 +169,68 @@ export async function resolveSlotElement(
|
|
|
54
169
|
: findSlotMatch(slotNode, match);
|
|
55
170
|
|
|
56
171
|
if (slotMatch) {
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
const SlotPage = mod.default as (...args: unknown[]) => unknown;
|
|
60
|
-
|
|
172
|
+
const SlotPage = await loadComponent(slotMatch.page);
|
|
173
|
+
if (SlotPage) {
|
|
61
174
|
// Load default.tsx fallback for notFound() handling in the slot page.
|
|
62
175
|
// When a slot page calls notFound() or deny(), it should gracefully
|
|
63
176
|
// degrade to default.tsx or null — not crash the page. This matches
|
|
64
177
|
// Next.js behavior. See design/02-rendering-pipeline.md
|
|
65
178
|
// §"Slot Access Failure = Graceful Degradation"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
179
|
+
const denyFallback = await renderDefaultFallback(slotNode, h);
|
|
180
|
+
|
|
181
|
+
// Build the slot page element.
|
|
182
|
+
// Client references ('use client' pages) must NOT be called as functions —
|
|
183
|
+
// they are proxy objects that throw when invoked. For client references,
|
|
184
|
+
// use createElement directly. Error catching is unnecessary because client
|
|
185
|
+
// references are serialized as references in the RSC Flight stream — they
|
|
186
|
+
// don't execute on the server. See TIM-627.
|
|
187
|
+
//
|
|
188
|
+
// For server components, wrap in SafeSlotPage to catch ALL errors at the
|
|
189
|
+
// component level. This prevents errors from leaving unresolved Flight
|
|
190
|
+
// rows in the RSC stream — see TIM-524 for details.
|
|
191
|
+
let element: React.ReactElement;
|
|
192
|
+
if (isClientReference(SlotPage)) {
|
|
193
|
+
element = h(SlotPage, {});
|
|
194
|
+
} else {
|
|
195
|
+
const SafeSlotPage = async (props: Record<string, unknown>) => {
|
|
196
|
+
try {
|
|
197
|
+
return await (SlotPage as (props: Record<string, unknown>) => unknown)(props);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
// RedirectSignal must propagate — the pipeline handles redirects
|
|
200
|
+
// at the top level. Swallowing it here would silently return
|
|
201
|
+
// fallback content instead of redirecting. See TIM-554.
|
|
202
|
+
if (error instanceof RedirectSignal) {
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
if (error instanceof DenySignal) {
|
|
206
|
+
return denyFallback;
|
|
207
|
+
}
|
|
208
|
+
// Log the error but don't re-throw — returning fallback ensures
|
|
209
|
+
// the Flight row is resolved and the page hydrates correctly.
|
|
210
|
+
logRenderError({
|
|
211
|
+
method: '',
|
|
212
|
+
path: '',
|
|
213
|
+
error,
|
|
214
|
+
});
|
|
215
|
+
return denyFallback;
|
|
87
216
|
}
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
let element: React.ReactElement = h(SafeSlotPage, {
|
|
93
|
-
params: paramsPromise,
|
|
94
|
-
searchParams: {},
|
|
95
|
-
});
|
|
217
|
+
};
|
|
218
|
+
element = h(SafeSlotPage, {});
|
|
219
|
+
}
|
|
96
220
|
|
|
97
221
|
// Wrap with error boundaries and layouts from intermediate slot segments
|
|
98
222
|
// (everything between slot root and leaf). Process innermost-first, same
|
|
99
223
|
// order as route-element-builder.ts handles main segments. The slot root
|
|
100
224
|
// (index 0) is handled separately after the access gate below.
|
|
101
|
-
|
|
102
|
-
const seg = slotMatch.chain[i];
|
|
103
|
-
|
|
104
|
-
// Error boundaries from this segment
|
|
105
|
-
element = await wrapSegmentWithErrorBoundaries(seg, element, h);
|
|
106
|
-
|
|
107
|
-
// Layout from this segment
|
|
108
|
-
if (seg.layout) {
|
|
109
|
-
const layoutMod = (await seg.layout.load()) as Record<string, unknown>;
|
|
110
|
-
if (layoutMod.default) {
|
|
111
|
-
const Layout = layoutMod.default as (...args: unknown[]) => unknown;
|
|
112
|
-
element = h(Layout, {
|
|
113
|
-
params: paramsPromise,
|
|
114
|
-
searchParams: {},
|
|
115
|
-
children: element,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
225
|
+
element = await wrapWithIntermediateSegments(slotMatch.chain, element, h);
|
|
120
226
|
|
|
121
227
|
// Wrap in SlotAccessGate if slot root has access.ts.
|
|
122
228
|
// On denial: denied.tsx → default.tsx → null (graceful degradation).
|
|
123
229
|
// See design/04-authorization.md §"Slot-Level Auth".
|
|
124
|
-
|
|
125
|
-
const accessMod = (await slotNode.access.load()) as Record<string, unknown>;
|
|
126
|
-
const accessFn = accessMod.default as
|
|
127
|
-
| ((ctx: { params: Record<string, string | string[]>; searchParams: unknown }) => unknown)
|
|
128
|
-
| undefined;
|
|
129
|
-
if (accessFn) {
|
|
130
|
-
// Load denied.tsx fallback
|
|
131
|
-
let deniedFallback: React.ReactElement | null = null;
|
|
132
|
-
if (slotNode.denied) {
|
|
133
|
-
const deniedMod = (await slotNode.denied.load()) as Record<string, unknown>;
|
|
134
|
-
const DeniedComponent = deniedMod.default as
|
|
135
|
-
| ((...args: unknown[]) => unknown)
|
|
136
|
-
| undefined;
|
|
137
|
-
if (DeniedComponent) {
|
|
138
|
-
deniedFallback = h(DeniedComponent, {});
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Load default.tsx fallback
|
|
143
|
-
let defaultFallback: React.ReactElement | null = null;
|
|
144
|
-
if (slotNode.default) {
|
|
145
|
-
const defaultMod = (await slotNode.default.load()) as Record<string, unknown>;
|
|
146
|
-
const DefaultComp = defaultMod.default as ((...args: unknown[]) => unknown) | undefined;
|
|
147
|
-
if (DefaultComp) {
|
|
148
|
-
defaultFallback = h(DefaultComp, { params: paramsPromise, searchParams: {} });
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const params = await paramsPromise;
|
|
153
|
-
element = h(SlotAccessGate, {
|
|
154
|
-
accessFn,
|
|
155
|
-
params,
|
|
156
|
-
searchParams: {},
|
|
157
|
-
deniedFallback,
|
|
158
|
-
defaultFallback,
|
|
159
|
-
children: element,
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
230
|
+
element = await wrapWithAccessGate(slotNode, element, h);
|
|
163
231
|
|
|
164
232
|
// Wrap with slot root's layout (outermost, outside access gate)
|
|
165
|
-
|
|
166
|
-
const layoutMod = (await slotNode.layout.load()) as Record<string, unknown>;
|
|
167
|
-
if (layoutMod.default) {
|
|
168
|
-
const Layout = layoutMod.default as (...args: unknown[]) => unknown;
|
|
169
|
-
element = h(Layout, {
|
|
170
|
-
params: paramsPromise,
|
|
171
|
-
searchParams: {},
|
|
172
|
-
children: element,
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
233
|
+
element = await wrapWithLayout(slotNode, element, h);
|
|
176
234
|
|
|
177
235
|
// Wrap with slot root's error boundaries (outermost)
|
|
178
236
|
element = await wrapSegmentWithErrorBoundaries(slotNode, element, h);
|
|
@@ -180,7 +238,7 @@ export async function resolveSlotElement(
|
|
|
180
238
|
// Catch-all error boundary: ensures slot errors NEVER propagate to the
|
|
181
239
|
// parent layout. Without this, a slot without error.tsx that throws
|
|
182
240
|
// causes SSR's renderToReadableStream to reject, triggering renderDenyPage
|
|
183
|
-
// which re-executes all layout server components (including
|
|
241
|
+
// which re-executes all layout server components (including getHeaders() calls
|
|
184
242
|
// that fail in the SSR environment). The null fallback means the slot
|
|
185
243
|
// degrades to nothing — consistent with the slot access denial behavior.
|
|
186
244
|
// See design/02-rendering-pipeline.md §"Slot Access Failure = Graceful Degradation"
|
|
@@ -195,18 +253,81 @@ export async function resolveSlotElement(
|
|
|
195
253
|
}
|
|
196
254
|
|
|
197
255
|
// No matching page — render default.tsx fallback
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
256
|
+
return renderDefaultFallback(slotNode, h);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// ─── Element Wrapping Helpers ───────────────────────────────────────────────
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Wrap an element with error boundaries and layouts from intermediate
|
|
263
|
+
* slot segments (indices 1..n, skipping the slot root at index 0).
|
|
264
|
+
* Processes innermost-first to match route-element-builder.ts ordering.
|
|
265
|
+
*/
|
|
266
|
+
async function wrapWithIntermediateSegments(
|
|
267
|
+
chain: ManifestSegmentNode[],
|
|
268
|
+
element: React.ReactElement,
|
|
269
|
+
h: CreateElementFn
|
|
270
|
+
): Promise<React.ReactElement> {
|
|
271
|
+
for (let i = chain.length - 1; i > 0; i--) {
|
|
272
|
+
const seg = chain[i];
|
|
273
|
+
element = await wrapSegmentWithErrorBoundaries(seg, element, h);
|
|
274
|
+
element = await wrapWithLayout(seg, element, h);
|
|
204
275
|
}
|
|
276
|
+
return element;
|
|
277
|
+
}
|
|
205
278
|
|
|
206
|
-
|
|
207
|
-
|
|
279
|
+
/**
|
|
280
|
+
* Wrap an element with a segment's layout component, if present.
|
|
281
|
+
*/
|
|
282
|
+
async function wrapWithLayout(
|
|
283
|
+
node: ManifestSegmentNode,
|
|
284
|
+
element: React.ReactElement,
|
|
285
|
+
h: CreateElementFn
|
|
286
|
+
): Promise<React.ReactElement> {
|
|
287
|
+
if (!node.layout) return element;
|
|
288
|
+
const Layout = await loadComponent(node.layout);
|
|
289
|
+
if (!Layout) return element;
|
|
290
|
+
return h(Layout, { children: element });
|
|
208
291
|
}
|
|
209
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Wrap an element with a SlotAccessGate if the node has access.ts.
|
|
295
|
+
* On denial: denied.tsx → default.tsx → null (graceful degradation).
|
|
296
|
+
*/
|
|
297
|
+
async function wrapWithAccessGate(
|
|
298
|
+
slotNode: ManifestSegmentNode,
|
|
299
|
+
element: React.ReactElement,
|
|
300
|
+
h: CreateElementFn
|
|
301
|
+
): Promise<React.ReactElement> {
|
|
302
|
+
if (!slotNode.access) return element;
|
|
303
|
+
|
|
304
|
+
const accessFn = await loadComponent(slotNode.access);
|
|
305
|
+
if (!accessFn) return element;
|
|
306
|
+
|
|
307
|
+
// Pass the component (not pre-built element) so SlotAccessGate can
|
|
308
|
+
// forward DenySignal.data as dangerouslyPassData dynamically. See TIM-488.
|
|
309
|
+
let DeniedComponent: ((...args: unknown[]) => unknown) | null = null;
|
|
310
|
+
if (slotNode.denied) {
|
|
311
|
+
DeniedComponent = (await loadComponent(slotNode.denied)) ?? null;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Extract slot name from the directory name (strip @ prefix)
|
|
315
|
+
const slotName = slotNode.segmentName?.replace(/^@/, '') ?? '';
|
|
316
|
+
|
|
317
|
+
const defaultFallback = await renderDefaultFallback(slotNode, h);
|
|
318
|
+
|
|
319
|
+
return h(SlotAccessGate, {
|
|
320
|
+
accessFn,
|
|
321
|
+
DeniedComponent,
|
|
322
|
+
slotName,
|
|
323
|
+
createElement: h,
|
|
324
|
+
defaultFallback,
|
|
325
|
+
children: element,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ─── Slot Matching ──────────────────────────────────────────────────────────
|
|
330
|
+
|
|
210
331
|
/** Result of matching a slot's sub-tree against the current route. */
|
|
211
332
|
interface SlotMatchResult {
|
|
212
333
|
/** The page file at the matched leaf. */
|
|
@@ -267,74 +388,10 @@ function findSlotMatch(slotNode: ManifestSegmentNode, match: RouteMatch): SlotMa
|
|
|
267
388
|
return null;
|
|
268
389
|
}
|
|
269
390
|
|
|
270
|
-
// Walk the slot's children to match remaining URL segments
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
for (const seg of remainingSegments) {
|
|
275
|
-
const childName = seg.segmentName;
|
|
276
|
-
const directChildren = currentNode.children ?? [];
|
|
277
|
-
|
|
278
|
-
let found: ManifestSegmentNode | null = null;
|
|
279
|
-
for (const child of directChildren) {
|
|
280
|
-
// Exact static match
|
|
281
|
-
if (child.segmentType === 'static' && child.segmentName === childName) {
|
|
282
|
-
found = child;
|
|
283
|
-
break;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Try dynamic segments if no static match
|
|
288
|
-
if (!found) {
|
|
289
|
-
for (const child of directChildren) {
|
|
290
|
-
if (child.segmentType === 'dynamic') {
|
|
291
|
-
found = child;
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Try catch-all segments — these consume ALL remaining URL segments,
|
|
298
|
-
// so we break out of the outer loop immediately.
|
|
299
|
-
if (!found) {
|
|
300
|
-
for (const child of directChildren) {
|
|
301
|
-
if (child.segmentType === 'catch-all' || child.segmentType === 'optional-catch-all') {
|
|
302
|
-
found = child;
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
if (found) {
|
|
307
|
-
chain.push(found);
|
|
308
|
-
currentNode = found;
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Try group children (transparent)
|
|
314
|
-
if (!found) {
|
|
315
|
-
for (const child of directChildren) {
|
|
316
|
-
if (child.segmentType === 'group') {
|
|
317
|
-
for (const groupChild of child.children ?? []) {
|
|
318
|
-
if (groupChild.segmentName === childName) {
|
|
319
|
-
found = groupChild;
|
|
320
|
-
break;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
if (found) break;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (!found) {
|
|
329
|
-
// No matching child in slot tree — slot doesn't match this URL
|
|
330
|
-
return null;
|
|
331
|
-
}
|
|
332
|
-
chain.push(found);
|
|
333
|
-
currentNode = found;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
if (currentNode.page) {
|
|
337
|
-
return { page: currentNode.page, chain };
|
|
391
|
+
// Walk the slot's children to match remaining URL segments
|
|
392
|
+
const result = walkSegmentTree(slotNode, remainingSegments);
|
|
393
|
+
if (result && result.leaf.page) {
|
|
394
|
+
return { page: result.leaf.page, chain: result.chain };
|
|
338
395
|
}
|
|
339
396
|
return null;
|
|
340
397
|
}
|
|
@@ -374,59 +431,17 @@ function findInterceptingMatch(
|
|
|
374
431
|
|
|
375
432
|
// Walk the intercepting child's sub-tree to match remaining target parts
|
|
376
433
|
const remaining = targetParts.slice(matchIdx + 1);
|
|
377
|
-
const chain: ManifestSegmentNode[] = [slotNode, child];
|
|
378
434
|
|
|
379
435
|
if (remaining.length === 0) {
|
|
380
436
|
if (child.page) {
|
|
381
|
-
return { page: child.page, chain };
|
|
437
|
+
return { page: child.page, chain: [slotNode, child] };
|
|
382
438
|
}
|
|
383
439
|
continue;
|
|
384
440
|
}
|
|
385
441
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const children = currentNode.children ?? [];
|
|
390
|
-
let found: ManifestSegmentNode | null = null;
|
|
391
|
-
|
|
392
|
-
// Static match
|
|
393
|
-
for (const c of children) {
|
|
394
|
-
if (c.segmentType === 'static' && c.segmentName === part) {
|
|
395
|
-
found = c;
|
|
396
|
-
break;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Dynamic match
|
|
401
|
-
if (!found) {
|
|
402
|
-
for (const c of children) {
|
|
403
|
-
if (c.segmentType === 'dynamic') {
|
|
404
|
-
found = c;
|
|
405
|
-
break;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// Catch-all match
|
|
411
|
-
if (!found) {
|
|
412
|
-
for (const c of children) {
|
|
413
|
-
if (c.segmentType === 'catch-all' || c.segmentType === 'optional-catch-all') {
|
|
414
|
-
found = c;
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (!found) {
|
|
421
|
-
matched = false;
|
|
422
|
-
break;
|
|
423
|
-
}
|
|
424
|
-
chain.push(found);
|
|
425
|
-
currentNode = found;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
if (matched && currentNode.page) {
|
|
429
|
-
return { page: currentNode.page, chain };
|
|
442
|
+
const result = walkSegmentTree(child, remaining, [slotNode, child]);
|
|
443
|
+
if (result && result.leaf.page) {
|
|
444
|
+
return { page: result.leaf.page, chain: result.chain };
|
|
430
445
|
}
|
|
431
446
|
}
|
|
432
447
|
|