@timber-js/app 0.2.0-alpha.2 → 0.2.0-alpha.200
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/agent-skill.md +346 -0
- package/dist/_chunks/actions-d1hCqnU3.js +345 -0
- package/dist/_chunks/actions-d1hCqnU3.js.map +1 -0
- package/dist/_chunks/als-registry-C6kcfprT.js +41 -0
- package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js +26 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -0
- package/dist/_chunks/base-path-DaQrzbez.js +80 -0
- package/dist/_chunks/base-path-DaQrzbez.js.map +1 -0
- package/dist/_chunks/build-manifest-DTmSGLRz.js +135 -0
- package/dist/_chunks/build-manifest-DTmSGLRz.js.map +1 -0
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js +370 -0
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +1 -0
- package/dist/_chunks/cache-api-ByagcC-J.js +1149 -0
- package/dist/_chunks/cache-api-ByagcC-J.js.map +1 -0
- package/dist/_chunks/canonicalize-CgHoscYO.js +66 -0
- package/dist/_chunks/canonicalize-CgHoscYO.js.map +1 -0
- package/dist/_chunks/chains-Bpb0W4ax.js +412 -0
- package/dist/_chunks/chains-Bpb0W4ax.js.map +1 -0
- package/dist/_chunks/cli-check-D6VolrDV.js +293 -0
- package/dist/_chunks/cli-check-D6VolrDV.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-D6rO-VcS.js +299 -0
- package/dist/_chunks/cli-schema-sync-D6rO-VcS.js.map +1 -0
- package/dist/_chunks/cloudflare-BFb__LYG.js +1290 -0
- package/dist/_chunks/cloudflare-BFb__LYG.js.map +1 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
- package/dist/_chunks/convention-lint-fRkwVwEH.js +893 -0
- package/dist/_chunks/convention-lint-fRkwVwEH.js.map +1 -0
- package/dist/_chunks/dist-DtrJyBbw.js +386 -0
- package/dist/_chunks/dist-DtrJyBbw.js.map +1 -0
- package/dist/_chunks/error-boundary-BfPHZjm0.js +1050 -0
- package/dist/_chunks/error-boundary-BfPHZjm0.js.map +1 -0
- package/dist/_chunks/fast-hash-C-tVYrLb.js +41 -0
- package/dist/_chunks/fast-hash-C-tVYrLb.js.map +1 -0
- package/dist/_chunks/file-cache-Dw6BJPG7.js +458 -0
- package/dist/_chunks/file-cache-Dw6BJPG7.js.map +1 -0
- package/dist/_chunks/format-BKclgVbk.js +14 -0
- package/dist/_chunks/format-BKclgVbk.js.map +1 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js +208 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +1 -0
- package/dist/_chunks/graph-cache-CP4GEmf9.js +304 -0
- package/dist/_chunks/graph-cache-CP4GEmf9.js.map +1 -0
- package/dist/_chunks/href-validation-BIrxavIy.js +213 -0
- package/dist/_chunks/href-validation-BIrxavIy.js.map +1 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js +63 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +1 -0
- package/dist/_chunks/live-graph-D_2D32Ad.js +150 -0
- package/dist/_chunks/live-graph-D_2D32Ad.js.map +1 -0
- package/dist/_chunks/logger-uLBuGKDI.js +1484 -0
- package/dist/_chunks/logger-uLBuGKDI.js.map +1 -0
- package/dist/_chunks/navigation-context-D0TU0Jog.js +135 -0
- package/dist/_chunks/navigation-context-D0TU0Jog.js.map +1 -0
- package/dist/_chunks/navigation-root-mHSK9psY.js +126 -0
- package/dist/_chunks/navigation-root-mHSK9psY.js.map +1 -0
- package/dist/_chunks/param-value-C8TNYchQ.js +66 -0
- package/dist/_chunks/param-value-C8TNYchQ.js.map +1 -0
- package/dist/_chunks/plugin-context-8idfR3UZ.js +321 -0
- package/dist/_chunks/plugin-context-8idfR3UZ.js.map +1 -0
- package/dist/_chunks/poison-rules-DoEhbqaY.js +110 -0
- package/dist/_chunks/poison-rules-DoEhbqaY.js.map +1 -0
- package/dist/_chunks/poison-scan-Bm9Yyqk9.js +101 -0
- package/dist/_chunks/poison-scan-Bm9Yyqk9.js.map +1 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js +14 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js.map +1 -0
- package/dist/_chunks/resolve-schema-CBR6Lm4i.js +50 -0
- package/dist/_chunks/resolve-schema-CBR6Lm4i.js.map +1 -0
- package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/_chunks/rsc-cache-key-ClUiXQnK.js +243 -0
- package/dist/_chunks/rsc-cache-key-ClUiXQnK.js.map +1 -0
- package/dist/_chunks/rsc-media-type-DDc7duTD.js +61 -0
- package/dist/_chunks/rsc-media-type-DDc7duTD.js.map +1 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js +48 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js.map +1 -0
- package/dist/_chunks/scan-BoP17W3w.js +140 -0
- package/dist/_chunks/scan-BoP17W3w.js.map +1 -0
- package/dist/_chunks/scanner-AiazgH_f.js +1771 -0
- package/dist/_chunks/scanner-AiazgH_f.js.map +1 -0
- package/dist/_chunks/schema-bridge-C83xa9lT.js +199 -0
- package/dist/_chunks/schema-bridge-C83xa9lT.js.map +1 -0
- package/dist/_chunks/segment-classify-C539Pa2O.js +197 -0
- package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -0
- package/dist/_chunks/segment-context-D9_89u34.js +34 -0
- package/dist/_chunks/segment-context-D9_89u34.js.map +1 -0
- package/dist/_chunks/segment-keys-lqtdookO.js +256 -0
- package/dist/_chunks/segment-keys-lqtdookO.js.map +1 -0
- package/dist/_chunks/singleflight-2lUWfcAk.js +54 -0
- package/dist/_chunks/singleflight-2lUWfcAk.js.map +1 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js +35 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +1 -0
- package/dist/_chunks/{ssr-data-DLnbYpj1.js → ssr-data-D6T6Y3ef.js} +3 -31
- package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +1 -0
- package/dist/_chunks/state-FippDgxN.js +52 -0
- package/dist/_chunks/state-FippDgxN.js.map +1 -0
- package/dist/_chunks/status-page-marker-DwQBrLBz.js +496 -0
- package/dist/_chunks/status-page-marker-DwQBrLBz.js.map +1 -0
- package/dist/_chunks/use-query-states-I3JMng6J.js +226 -0
- package/dist/_chunks/use-query-states-I3JMng6J.js.map +1 -0
- package/dist/_chunks/walkers-B6XUtmqK.js +144 -0
- package/dist/_chunks/walkers-B6XUtmqK.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +72 -0
- package/dist/adapters/build-output-helper.d.ts.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 +74 -0
- package/dist/adapters/cloudflare-dev.js.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts +65 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +123 -0
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +200 -22
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -188
- package/dist/adapters/compress-module.d.ts +17 -4
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +64 -0
- package/dist/adapters/fs-identity.d.ts.map +1 -0
- package/dist/adapters/nitro-presets.d.ts +37 -0
- package/dist/adapters/nitro-presets.d.ts.map +1 -0
- package/dist/adapters/nitro-preview.d.ts +32 -0
- package/dist/adapters/nitro-preview.d.ts.map +1 -0
- package/dist/adapters/nitro.d.ts +82 -37
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +457 -288
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +62 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +28 -6
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/analyze/chains.d.ts +124 -0
- package/dist/analyze/chains.d.ts.map +1 -0
- package/dist/analyze/classify.d.ts +150 -0
- package/dist/analyze/classify.d.ts.map +1 -0
- package/dist/analyze/crawl-entry.d.ts +17 -0
- package/dist/analyze/crawl-entry.d.ts.map +1 -0
- package/dist/analyze/crawl-entry.js +313 -0
- package/dist/analyze/crawl-entry.js.map +1 -0
- package/dist/analyze/crawl.d.ts +134 -0
- package/dist/analyze/crawl.d.ts.map +1 -0
- package/dist/analyze/graph-cache.d.ts +104 -0
- package/dist/analyze/graph-cache.d.ts.map +1 -0
- package/dist/analyze/graph-command.d.ts +43 -0
- package/dist/analyze/graph-command.d.ts.map +1 -0
- package/dist/analyze/graph-command.js +472 -0
- package/dist/analyze/graph-command.js.map +1 -0
- package/dist/analyze/live-graph.d.ts +81 -0
- package/dist/analyze/live-graph.d.ts.map +1 -0
- package/dist/analyze/poison-rules.d.ts +72 -0
- package/dist/analyze/poison-rules.d.ts.map +1 -0
- package/dist/analyze/poison-scan.d.ts +48 -0
- package/dist/analyze/poison-scan.d.ts.map +1 -0
- package/dist/analyze/scan.d.ts +73 -0
- package/dist/analyze/scan.d.ts.map +1 -0
- package/dist/cache/cache-api.d.ts +48 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/fast-hash.d.ts +27 -0
- package/dist/cache/fast-hash.d.ts.map +1 -0
- package/dist/cache/handler-store.d.ts +33 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +32 -9
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +3 -284
- package/dist/cache/invalidation-epoch.d.ts +43 -0
- package/dist/cache/invalidation-epoch.d.ts.map +1 -0
- package/dist/cache/json-lossy-check.d.ts +11 -0
- package/dist/cache/json-lossy-check.d.ts.map +1 -0
- package/dist/cache/redis-handler.d.ts +141 -9
- package/dist/cache/redis-handler.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts +21 -2
- 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/stable-stringify.d.ts +9 -0
- package/dist/cache/stable-stringify.d.ts.map +1 -1
- package/dist/cache/store.d.ts +53 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.d.ts +38 -0
- package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.js +29 -0
- package/dist/cache/stores/cloudflare-kv.js.map +1 -0
- package/dist/cache/stores/memory.d.ts +42 -0
- package/dist/cache/stores/memory.d.ts.map +1 -0
- package/dist/cache/stores/memory.js +90 -0
- package/dist/cache/stores/memory.js.map +1 -0
- package/dist/cache/stores/redis.d.ts +69 -0
- package/dist/cache/stores/redis.d.ts.map +1 -0
- package/dist/cache/stores/redis.js +35 -0
- package/dist/cache/stores/redis.js.map +1 -0
- package/dist/cache/stores/vercel.d.ts +36 -0
- package/dist/cache/stores/vercel.d.ts.map +1 -0
- package/dist/cache/stores/vercel.js +33 -0
- package/dist/cache/stores/vercel.js.map +1 -0
- package/dist/cache/tag-aware-handler.d.ts +52 -0
- package/dist/cache/tag-aware-handler.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +21 -11
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cdn/cloudflare-purge.d.ts +23 -0
- package/dist/cdn/cloudflare-purge.d.ts.map +1 -0
- package/dist/cdn/cloudflare-purge.js +30 -0
- package/dist/cdn/cloudflare-purge.js.map +1 -0
- package/dist/cdn/fastly-purge.d.ts +25 -0
- package/dist/cdn/fastly-purge.d.ts.map +1 -0
- package/dist/cdn/fastly-purge.js +33 -0
- package/dist/cdn/fastly-purge.js.map +1 -0
- package/dist/cdn/headers.d.ts +97 -0
- package/dist/cdn/headers.d.ts.map +1 -0
- package/dist/cdn/index.d.ts +5 -0
- package/dist/cdn/index.d.ts.map +1 -0
- package/dist/cdn/index.js +94 -0
- package/dist/cdn/index.js.map +1 -0
- package/dist/cdn/purge-store.d.ts +23 -0
- package/dist/cdn/purge-store.d.ts.map +1 -0
- package/dist/cdn/workers-cache-purge.d.ts +20 -0
- package/dist/cdn/workers-cache-purge.d.ts.map +1 -0
- package/dist/cdn/workers-cache-purge.js +35 -0
- package/dist/cdn/workers-cache-purge.js.map +1 -0
- package/dist/cli-check.d.ts +163 -0
- package/dist/cli-check.d.ts.map +1 -0
- package/dist/cli-schema-sync.d.ts +59 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +75 -8
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +175 -47
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +37 -1
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts +19 -0
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
- package/dist/client/browser-entry/action-queue.d.ts +44 -0
- package/dist/client/browser-entry/action-queue.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 +63 -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 +29 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +46 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +32 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +28 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- package/dist/client/deny-last-resort.d.ts +29 -0
- package/dist/client/deny-last-resort.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +66 -6
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +2 -126
- package/dist/client/error-reconstituter.d.ts +61 -0
- package/dist/client/error-reconstituter.d.ts.map +1 -0
- package/dist/client/form.d.ts +16 -27
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/global-context.d.ts +15 -0
- package/dist/client/global-context.d.ts.map +1 -0
- package/dist/client/history.d.ts +50 -9
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +20 -33
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +323 -1148
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +20 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +818 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link.d.ts +63 -60
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/location-search.d.ts +12 -0
- package/dist/client/location-search.d.ts.map +1 -0
- package/dist/client/navigation-api.d.ts +121 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-commit.d.ts +98 -0
- package/dist/client/navigation-commit.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +51 -31
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/navigation-root.d.ts +98 -0
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/navigation-transition.d.ts +187 -0
- package/dist/client/navigation-transition.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts +1 -1
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/params-context.d.ts +81 -0
- package/dist/client/params-context.d.ts.map +1 -0
- package/dist/client/react-root.d.ts +44 -0
- package/dist/client/react-root.d.ts.map +1 -0
- package/dist/client/router-effects.d.ts +130 -0
- package/dist/client/router-effects.d.ts.map +1 -0
- package/dist/client/router-lifecycle.d.ts +98 -0
- package/dist/client/router-lifecycle.d.ts.map +1 -0
- package/dist/client/router-pipeline.d.ts +87 -0
- package/dist/client/router-pipeline.d.ts.map +1 -0
- package/dist/client/router-ref.d.ts +2 -2
- package/dist/client/router-ref.d.ts.map +1 -1
- package/dist/client/router-skew.d.ts +21 -0
- package/dist/client/router-skew.d.ts.map +1 -0
- package/dist/client/router-types.d.ts +272 -0
- package/dist/client/router-types.d.ts.map +1 -0
- package/dist/client/router.d.ts +1 -97
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +104 -26
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +161 -25
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-context.d.ts +1 -1
- package/dist/client/segment-context.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +68 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/segment-update-context.d.ts +15 -0
- package/dist/client/segment-update-context.d.ts.map +1 -0
- package/dist/client/shallow-url.d.ts +10 -0
- package/dist/client/shallow-url.d.ts.map +1 -0
- package/dist/client/slot-content-cache-context.d.ts +35 -0
- package/dist/client/slot-content-cache-context.d.ts.map +1 -0
- package/dist/client/slot-context.d.ts +31 -0
- package/dist/client/slot-context.d.ts.map +1 -0
- package/dist/client/slot-outlet.d.ts +16 -0
- package/dist/client/slot-outlet.d.ts.map +1 -0
- package/dist/client/slot-provider.d.ts +25 -0
- package/dist/client/slot-provider.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +29 -7
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-client.d.ts +69 -0
- package/dist/client/stale-client.d.ts.map +1 -0
- package/dist/client/state.d.ts +19 -8
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/status-page-marker.d.ts +25 -0
- package/dist/client/status-page-marker.d.ts.map +1 -0
- package/dist/client/top-loader.d.ts +7 -6
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/unload-guard.d.ts +5 -0
- package/dist/client/unload-guard.d.ts.map +1 -1
- package/dist/client/use-cookie.d.ts +12 -0
- package/dist/client/use-cookie.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-pathname.d.ts +13 -11
- package/dist/client/use-pathname.d.ts.map +1 -1
- package/dist/client/use-pending-navigation.d.ts +23 -0
- package/dist/client/use-pending-navigation.d.ts.map +1 -0
- package/dist/client/use-query-states.d.ts +10 -4
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +2 -2
- package/dist/client/use-router.d.ts.map +1 -1
- package/dist/client/use-search-params.d.ts +15 -8
- package/dist/client/use-search-params.d.ts.map +1 -1
- package/dist/client/use-segment-params.d.ts +55 -0
- package/dist/client/use-segment-params.d.ts.map +1 -0
- package/dist/codec.d.ts +69 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +76 -0
- package/dist/codec.js.map +1 -0
- package/dist/config-types.d.ts +322 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-validation.d.ts +51 -0
- package/dist/config-validation.d.ts.map +1 -0
- package/dist/cookies/define-cookie.d.ts +58 -25
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +3 -2
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/cookies/index.js +256 -36
- package/dist/cookies/index.js.map +1 -1
- package/dist/cookies/json-cookie.d.ts +64 -0
- package/dist/cookies/json-cookie.d.ts.map +1 -0
- package/dist/cookies/validation.d.ts +34 -0
- package/dist/cookies/validation.d.ts.map +1 -0
- package/dist/dev-tools/404-page.d.ts +50 -0
- package/dist/dev-tools/404-page.d.ts.map +1 -0
- package/dist/dev-tools/browser-logs.d.ts +40 -0
- package/dist/dev-tools/browser-logs.d.ts.map +1 -0
- package/dist/dev-tools/dev-page-shell.d.ts +78 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -0
- package/dist/dev-tools/error-page.d.ts +32 -0
- package/dist/dev-tools/error-page.d.ts.map +1 -0
- package/dist/dev-tools/holding-server.d.ts +46 -0
- package/dist/dev-tools/holding-server.d.ts.map +1 -0
- package/dist/dev-tools/hydration-overlay.d.ts +11 -0
- package/dist/dev-tools/hydration-overlay.d.ts.map +1 -0
- package/dist/dev-tools/index.d.ts +31 -0
- package/dist/dev-tools/index.d.ts.map +1 -0
- package/dist/dev-tools/instrumentation.d.ts +59 -0
- package/dist/dev-tools/instrumentation.d.ts.map +1 -0
- package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
- package/dist/dev-tools/logger.d.ts.map +1 -0
- package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +17 -3
- package/dist/dev-tools/logs.d.ts.map +1 -0
- package/dist/dev-tools/overlay.d.ts +91 -0
- package/dist/dev-tools/overlay.d.ts.map +1 -0
- package/dist/dev-tools/stack-classifier.d.ts +34 -0
- package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
- package/dist/dev-tools/terminal.d.ts +28 -0
- package/dist/dev-tools/terminal.d.ts.map +1 -0
- package/dist/fonts/ast-walk.d.ts +68 -0
- package/dist/fonts/ast-walk.d.ts.map +1 -0
- package/dist/fonts/ast.d.ts +112 -8
- package/dist/fonts/ast.d.ts.map +1 -1
- package/dist/fonts/bundle.d.ts +50 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/css.d.ts +2 -1
- package/dist/fonts/css.d.ts.map +1 -1
- package/dist/fonts/dev-middleware.d.ts +22 -0
- package/dist/fonts/dev-middleware.d.ts.map +1 -0
- package/dist/fonts/fallbacks.d.ts +0 -7
- package/dist/fonts/fallbacks.d.ts.map +1 -1
- package/dist/fonts/google.d.ts +5 -3
- package/dist/fonts/google.d.ts.map +1 -1
- package/dist/fonts/local.d.ts +6 -4
- package/dist/fonts/local.d.ts.map +1 -1
- package/dist/fonts/paths.d.ts +43 -0
- package/dist/fonts/paths.d.ts.map +1 -0
- package/dist/fonts/pipeline.d.ts +177 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +82 -0
- package/dist/fonts/transform.d.ts.map +1 -0
- package/dist/fonts/types.d.ts +47 -1
- package/dist/fonts/types.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts +77 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +35 -153
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10488 -13975
- package/dist/index.js.map +1 -1
- package/dist/params/codec-registry.d.ts +26 -0
- package/dist/params/codec-registry.d.ts.map +1 -0
- package/dist/params/define-schema.d.ts +81 -0
- package/dist/params/define-schema.d.ts.map +1 -0
- package/dist/params/index.d.ts +5 -0
- package/dist/params/index.d.ts.map +1 -0
- package/dist/params/index.js +34 -0
- package/dist/params/index.js.map +1 -0
- package/dist/params/resolve-schema.d.ts +34 -0
- package/dist/params/resolve-schema.d.ts.map +1 -0
- package/dist/plugin-context.d.ts +276 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +21 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +7 -3
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +54 -7
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/cache.d.ts +64 -0
- package/dist/plugins/cache.d.ts.map +1 -0
- package/dist/plugins/callsite-ast.d.ts +117 -0
- package/dist/plugins/callsite-ast.d.ts.map +1 -0
- package/dist/plugins/callsite-jsx.d.ts +35 -0
- package/dist/plugins/callsite-jsx.d.ts.map +1 -0
- package/dist/plugins/chunks.d.ts +11 -4
- package/dist/plugins/chunks.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +40 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/cloudflare-wasm.d.ts +21 -0
- package/dist/plugins/cloudflare-wasm.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-discovery.d.ts +123 -0
- package/dist/plugins/dev-discovery.d.ts.map +1 -0
- package/dist/plugins/dev-server.d.ts +17 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +32 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +16 -65
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/graph-endpoint.d.ts +112 -0
- package/dist/plugins/graph-endpoint.d.ts.map +1 -0
- package/dist/plugins/mdx.d.ts +24 -5
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/prebuilt-capture.d.ts +60 -0
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -0
- package/dist/plugins/prebuilt-options-analysis.d.ts +40 -0
- package/dist/plugins/prebuilt-options-analysis.d.ts.map +1 -0
- package/dist/plugins/prebuilt.d.ts +82 -0
- package/dist/plugins/prebuilt.d.ts.map +1 -0
- package/dist/plugins/prerender-sugar.d.ts +39 -0
- package/dist/plugins/prerender-sugar.d.ts.map +1 -0
- package/dist/plugins/request-dep/analysis.d.ts +106 -0
- package/dist/plugins/request-dep/analysis.d.ts.map +1 -0
- package/dist/plugins/request-dep/index.d.ts +75 -0
- package/dist/plugins/request-dep/index.d.ts.map +1 -0
- package/dist/plugins/request-dep/origin.d.ts +61 -0
- package/dist/plugins/request-dep/origin.d.ts.map +1 -0
- 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 +29 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +218 -21
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +26 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +61 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen-write.d.ts +51 -0
- package/dist/routing/codegen-write.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts +8 -3
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/collision-probe.d.ts +104 -0
- package/dist/routing/collision-probe.d.ts.map +1 -0
- package/dist/routing/collision-spaces.d.ts +26 -0
- package/dist/routing/collision-spaces.d.ts.map +1 -0
- package/dist/routing/convention-lint.d.ts +55 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/export-detect.d.ts +72 -0
- package/dist/routing/export-detect.d.ts.map +1 -0
- package/dist/routing/file-cache.d.ts +8 -0
- package/dist/routing/file-cache.d.ts.map +1 -0
- package/dist/routing/index.d.ts +13 -7
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +5 -2
- package/dist/routing/interception-overlap.d.ts +35 -0
- package/dist/routing/interception-overlap.d.ts.map +1 -0
- package/dist/routing/interception.d.ts +234 -10
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/routing/link-codegen.d.ts +105 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/manifest-codegen.d.ts +26 -0
- package/dist/routing/manifest-codegen.d.ts.map +1 -0
- package/dist/routing/scanner.d.ts +14 -10
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/schema-validation.d.ts +35 -0
- package/dist/routing/schema-validation.d.ts.map +1 -0
- package/dist/routing/segment-classify.d.ts +114 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/segment-codegen.d.ts +38 -0
- package/dist/routing/segment-codegen.d.ts.map +1 -0
- package/dist/routing/segment-keys.d.ts +118 -0
- package/dist/routing/segment-keys.d.ts.map +1 -0
- package/dist/routing/slot-placement.d.ts +48 -0
- package/dist/routing/slot-placement.d.ts.map +1 -0
- package/dist/routing/types.d.ts +74 -26
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +57 -0
- package/dist/routing/walkers.d.ts.map +1 -0
- 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 +14 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/rsc-runtime/transforms.d.ts +13 -0
- package/dist/rsc-runtime/transforms.d.ts.map +1 -0
- package/dist/schema-bridge.d.ts +145 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +262 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +3 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +179 -360
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/parse-total.d.ts +81 -0
- package/dist/search-params/parse-total.d.ts.map +1 -0
- package/dist/search-params/serialize-equal.d.ts +9 -0
- package/dist/search-params/serialize-equal.d.ts.map +1 -0
- package/dist/search-params/wrappers.d.ts +76 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/server/access-gate.d.ts +98 -10
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +42 -7
- 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 +39 -5
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +29 -35
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +117 -13
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/asset-headers.d.ts +8 -18
- package/dist/server/asset-headers.d.ts.map +1 -1
- package/dist/server/body-limits.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +25 -30
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/canonicalize.d.ts +10 -0
- package/dist/server/canonicalize.d.ts.map +1 -1
- package/dist/server/chain-url-parts.d.ts +82 -0
- package/dist/server/chain-url-parts.d.ts.map +1 -0
- package/dist/server/children-interception.d.ts +49 -0
- package/dist/server/children-interception.d.ts.map +1 -0
- package/dist/server/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- package/dist/server/compress.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts +170 -0
- package/dist/server/cookie-context.d.ts.map +1 -0
- package/dist/server/cookie-parsing.d.ts +65 -0
- package/dist/server/cookie-parsing.d.ts.map +1 -0
- package/dist/server/csp-nonce.d.ts +45 -0
- package/dist/server/csp-nonce.d.ts.map +1 -0
- package/dist/server/csrf.d.ts +3 -2
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/debug.d.ts +82 -0
- package/dist/server/debug.d.ts.map +1 -0
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/default-status-page.d.ts +45 -0
- package/dist/server/default-status-page.d.ts.map +1 -0
- package/dist/server/deny-boundary.d.ts +253 -0
- package/dist/server/deny-boundary.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts +20 -9
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/early-hints-sender.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +14 -12
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +101 -10
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/error-response-headers.d.ts +3 -0
- package/dist/server/error-response-headers.d.ts.map +1 -0
- package/dist/server/fallback-error.d.ts +12 -7
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/flight-injection-state.d.ts +66 -0
- package/dist/server/flight-injection-state.d.ts.map +1 -0
- package/dist/server/flight-scripts.d.ts +45 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/form-data.d.ts +41 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/form-flash.d.ts +1 -1
- package/dist/server/head-response.d.ts +35 -0
- package/dist/server/head-response.d.ts.map +1 -0
- package/dist/server/html-injector-core.d.ts +257 -0
- package/dist/server/html-injector-core.d.ts.map +1 -0
- package/dist/server/html-injectors.d.ts +84 -42
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +18 -54
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +212 -2930
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +1 -1
- package/dist/server/internal.d.ts +50 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +4034 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +39 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/metadata-collector.d.ts +71 -0
- package/dist/server/metadata-collector.d.ts.map +1 -0
- package/dist/server/metadata-platform.d.ts +2 -2
- package/dist/server/metadata-render.d.ts +2 -2
- package/dist/server/metadata-render.d.ts.map +1 -1
- package/dist/server/metadata-routes.d.ts +60 -11
- package/dist/server/metadata-routes.d.ts.map +1 -1
- package/dist/server/metadata-social.d.ts +2 -2
- package/dist/server/metadata.d.ts +10 -2
- package/dist/server/metadata.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +20 -5
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +105 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/nuqs-ssr-provider.d.ts +7 -3
- package/dist/server/nuqs-ssr-provider.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +78 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +77 -0
- package/dist/server/pipeline-helpers.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +59 -9
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-metadata.d.ts +7 -1
- package/dist/server/pipeline-metadata.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +49 -0
- package/dist/server/pipeline-outcome.d.ts.map +1 -0
- package/dist/server/pipeline-phases.d.ts +70 -0
- package/dist/server/pipeline-phases.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +160 -24
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/port-resolution.d.ts +31 -0
- package/dist/server/port-resolution.d.ts.map +1 -0
- package/dist/server/prebuilt/cache-key.d.ts +63 -0
- package/dist/server/prebuilt/cache-key.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +57 -0
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -0
- package/dist/server/prebuilt/key-discipline.d.ts +52 -0
- package/dist/server/prebuilt/key-discipline.d.ts.map +1 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts +27 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts.map +1 -0
- package/dist/server/prebuilt/overlay.d.ts +100 -0
- package/dist/server/prebuilt/overlay.d.ts.map +1 -0
- package/dist/server/prebuilt/payload-source.d.ts +79 -0
- package/dist/server/prebuilt/payload-source.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +99 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -0
- package/dist/server/prebuilt/synthetic-store.d.ts +67 -0
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -0
- package/dist/server/prebuilt-builder.d.ts +121 -0
- package/dist/server/prebuilt-builder.d.ts.map +1 -0
- package/dist/server/prebuilt-runtime.d.ts +111 -0
- package/dist/server/prebuilt-runtime.d.ts.map +1 -0
- package/dist/server/primitives.d.ts +129 -45
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/publish-params.d.ts +33 -0
- package/dist/server/publish-params.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/render-utils.d.ts +26 -0
- package/dist/server/render-utils.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +111 -107
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-dep.d.ts +15 -0
- package/dist/server/request-dep.d.ts.map +1 -0
- package/dist/server/response-cache-policy.d.ts +3 -0
- package/dist/server/response-cache-policy.d.ts.map +1 -0
- package/dist/server/route-element-builder.d.ts +57 -30
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-element-helpers.d.ts +12 -0
- package/dist/server/route-element-helpers.d.ts.map +1 -0
- package/dist/server/route-handler.d.ts +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +40 -38
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/route-module-loader.d.ts +37 -0
- package/dist/server/route-module-loader.d.ts.map +1 -0
- package/dist/server/rsc-cache-key-guard.d.ts +78 -0
- package/dist/server/rsc-cache-key-guard.d.ts.map +1 -0
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
- package/dist/server/rsc-entry/api-handler.d.ts +12 -3
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +29 -0
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -0
- package/dist/server/rsc-entry/error-renderer.d.ts +38 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +59 -42
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +40 -6
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +51 -0
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +108 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -0
- package/dist/server/rsc-entry/rsc-payload.d.ts +26 -6
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +39 -3
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +37 -5
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +89 -0
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
- package/dist/server/rsc-error-envelope.d.ts +11 -0
- package/dist/server/rsc-error-envelope.d.ts.map +1 -0
- package/dist/server/rsc-prop-warnings.d.ts.map +1 -1
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sensitive-fields.d.ts +74 -0
- package/dist/server/sensitive-fields.d.ts.map +1 -0
- package/dist/server/sitemap-generator.d.ts +130 -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/skippable-prefix.d.ts +29 -0
- package/dist/server/skippable-prefix.d.ts.map +1 -0
- package/dist/server/slot-interception.d.ts +80 -0
- package/dist/server/slot-interception.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +137 -7
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/slot-subtree-contain.d.ts +54 -0
- package/dist/server/slot-subtree-contain.d.ts.map +1 -0
- package/dist/server/ssr-bridge-types.d.ts +160 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -0
- package/dist/server/ssr-entry.d.ts +1 -43
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +69 -22
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +93 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/state-tree-diff.d.ts +44 -9
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/dist/server/static-generator.d.ts +112 -0
- package/dist/server/static-generator.d.ts.map +1 -0
- package/dist/server/static-not-found.d.ts +52 -0
- package/dist/server/static-not-found.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +26 -15
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +47 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +56 -11
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-match.d.ts +49 -0
- package/dist/server/tree-match.d.ts.map +1 -0
- package/dist/server/types.d.ts +88 -7
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils/element-type.d.ts +50 -0
- package/dist/server/utils/element-type.d.ts.map +1 -0
- package/dist/server/utils/escape-html.d.ts +14 -0
- package/dist/server/utils/escape-html.d.ts.map +1 -0
- package/dist/server/utils/mdx-file.d.ts +17 -0
- package/dist/server/utils/mdx-file.d.ts.map +1 -0
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/server/waituntil-bridge.d.ts.map +1 -1
- package/dist/server/workers-cache-bridge.d.ts +26 -0
- package/dist/server/workers-cache-bridge.d.ts.map +1 -0
- package/dist/shared/als-slots.d.ts +42 -0
- package/dist/shared/als-slots.d.ts.map +1 -0
- package/dist/shared/base-path.d.ts +56 -0
- package/dist/shared/base-path.d.ts.map +1 -0
- package/dist/shared/href-validation.d.ts +49 -0
- package/dist/shared/href-validation.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/shared/param-value.d.ts +104 -0
- package/dist/shared/param-value.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +109 -0
- package/dist/shared/payload-root.d.ts.map +1 -0
- package/dist/shared/redirect-type.d.ts +17 -0
- package/dist/shared/redirect-type.d.ts.map +1 -0
- package/dist/shared/rsc-cache-key.d.ts +163 -0
- package/dist/shared/rsc-cache-key.d.ts.map +1 -0
- package/dist/shared/rsc-error-envelope.d.ts +16 -0
- package/dist/shared/rsc-error-envelope.d.ts.map +1 -0
- package/dist/shared/rsc-manifest.d.ts +28 -0
- package/dist/shared/rsc-manifest.d.ts.map +1 -0
- package/dist/shared/rsc-media-type.d.ts +52 -0
- package/dist/shared/rsc-media-type.d.ts.map +1 -0
- package/dist/shared/rsc-payload-path.d.ts +42 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -0
- package/dist/shared/segment-info.d.ts +66 -0
- package/dist/shared/segment-info.d.ts.map +1 -0
- package/dist/shared/slot-params.d.ts +52 -0
- package/dist/shared/slot-params.d.ts.map +1 -0
- package/dist/shared/static-platform-files.d.ts +71 -0
- package/dist/shared/static-platform-files.d.ts.map +1 -0
- package/dist/shared/status-reason-phrase.d.ts +26 -0
- package/dist/shared/status-reason-phrase.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 +53 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/image.d.ts +120 -120
- package/dist/shims/image.d.ts.map +1 -1
- package/dist/shims/navigation-client.d.ts +25 -12
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation-rsc.d.ts +21 -0
- package/dist/shims/navigation-rsc.d.ts.map +1 -0
- package/dist/shims/navigation.d.ts +10 -5
- package/dist/shims/navigation.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/docs/api/30-api-server.mdx +236 -0
- package/docs/api/31-api-client.mdx +167 -0
- package/docs/api/32-api-cache.mdx +311 -0
- package/docs/api/33-api-search-params.mdx +176 -0
- package/docs/api/34-api-config.mdx +329 -0
- package/docs/api/35-api-typescript.mdx +91 -0
- package/docs/api/36-cli.mdx +192 -0
- package/docs/learn/00-introduction.mdx +109 -0
- package/docs/learn/01-quick-start.mdx +94 -0
- package/docs/learn/02-pages-and-layouts.mdx +147 -0
- package/docs/learn/03-fetching-data.mdx +211 -0
- package/docs/learn/04-access-control.mdx +115 -0
- package/docs/learn/05-the-flush-point.mdx +175 -0
- package/docs/learn/06-typed-params.mdx +275 -0
- package/docs/learn/07-typed-routes.mdx +108 -0
- package/docs/learn/08-forms-and-actions.mdx +146 -0
- package/docs/learn/09-streaming.mdx +140 -0
- package/docs/learn/10-caching.mdx +252 -0
- package/docs/learn/11-middleware.mdx +158 -0
- package/docs/learn/12-error-handling.mdx +188 -0
- package/docs/learn/13-deploying.mdx +287 -0
- package/llms.txt +55 -0
- package/package.json +117 -29
- package/src/adapters/build-output-helper.ts +351 -0
- package/src/adapters/cloudflare-dev.ts +183 -0
- package/src/adapters/cloudflare-kv-cache.ts +207 -0
- package/src/adapters/cloudflare.ts +747 -130
- package/src/adapters/compress-module.ts +101 -88
- package/src/adapters/fs-identity.ts +156 -0
- package/src/adapters/nitro-presets.ts +139 -0
- package/src/adapters/nitro-preview.ts +340 -0
- package/src/adapters/nitro.ts +279 -418
- package/src/adapters/raw-imports.d.ts +5 -0
- package/src/adapters/shared.ts +274 -0
- package/src/adapters/types.ts +28 -7
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/analyze/chains.ts +411 -0
- package/src/analyze/classify.ts +258 -0
- package/src/analyze/crawl-entry.ts +68 -0
- package/src/analyze/crawl.ts +500 -0
- package/src/analyze/graph-cache.ts +332 -0
- package/src/analyze/graph-command.ts +762 -0
- package/src/analyze/live-graph.ts +232 -0
- package/src/analyze/poison-rules.ts +165 -0
- package/src/analyze/poison-scan.ts +162 -0
- package/src/analyze/scan.ts +149 -0
- package/src/cache/cache-api.ts +107 -0
- package/src/cache/fast-hash.ts +39 -0
- package/src/cache/handler-store.ts +76 -0
- package/src/cache/index.ts +115 -22
- package/src/cache/invalidation-epoch.ts +93 -0
- package/src/cache/json-lossy-check.ts +75 -0
- package/src/cache/redis-handler.ts +198 -20
- package/src/cache/singleflight.ts +69 -6
- package/src/cache/sizeof.ts +33 -0
- package/src/cache/stable-stringify.ts +65 -2
- package/src/cache/store.ts +71 -0
- package/src/cache/stores/cloudflare-kv.ts +52 -0
- package/src/cache/stores/memory.ts +125 -0
- package/src/cache/stores/redis.ts +97 -0
- package/src/cache/stores/vercel.ts +59 -0
- package/src/cache/tag-aware-handler.ts +237 -0
- package/src/cache/timber-cache.ts +180 -48
- package/src/cdn/cloudflare-purge.ts +50 -0
- package/src/cdn/fastly-purge.ts +63 -0
- package/src/cdn/headers.ts +153 -0
- package/src/cdn/index.ts +23 -0
- package/src/cdn/purge-store.ts +34 -0
- package/src/cdn/workers-cache-purge.ts +34 -0
- package/src/cli-check.ts +507 -0
- package/src/cli-schema-sync.ts +401 -0
- package/src/cli.ts +262 -55
- package/src/client/browser-dev.ts +157 -2
- package/src/client/browser-entry/action-dispatch.ts +197 -0
- package/src/client/browser-entry/action-queue.ts +90 -0
- package/src/client/browser-entry/hmr.ts +70 -0
- package/src/client/browser-entry/hydrate.ts +148 -0
- package/src/client/browser-entry/index.ts +131 -0
- package/src/client/browser-entry/post-hydration.ts +123 -0
- package/src/client/browser-entry/router-init.ts +418 -0
- package/src/client/browser-entry/rsc-stream.ts +166 -0
- package/src/client/browser-entry/scroll.ts +50 -0
- package/src/client/deny-last-resort.tsx +54 -0
- package/src/client/error-boundary.tsx +316 -40
- package/src/client/error-reconstituter.tsx +79 -0
- package/src/client/form.tsx +36 -32
- package/src/client/global-context.ts +31 -0
- package/src/client/history.ts +81 -10
- package/src/client/index.ts +89 -53
- package/src/client/internal.ts +59 -0
- package/src/client/link.tsx +452 -159
- package/src/client/location-search.ts +15 -0
- package/src/client/navigation-api.ts +347 -0
- package/src/client/navigation-commit.ts +295 -0
- package/src/client/navigation-context.ts +67 -98
- package/src/client/navigation-root.tsx +224 -0
- package/src/client/navigation-transition.ts +327 -0
- package/src/client/nuqs-adapter.tsx +21 -9
- package/src/client/params-context.ts +187 -0
- package/src/client/react-root.ts +72 -0
- package/src/client/router-effects.ts +228 -0
- package/src/client/router-lifecycle.ts +354 -0
- package/src/client/router-pipeline.ts +490 -0
- package/src/client/router-ref.ts +3 -3
- package/src/client/router-skew.ts +30 -0
- package/src/client/router-types.ts +294 -0
- package/src/client/router.ts +436 -424
- package/src/client/rsc-fetch.ts +512 -73
- package/src/client/segment-cache.ts +327 -40
- package/src/client/segment-context.ts +13 -5
- package/src/client/segment-outlet.tsx +96 -0
- package/src/client/segment-update-context.ts +23 -0
- package/src/client/shallow-url.ts +22 -0
- package/src/client/slot-content-cache-context.ts +43 -0
- package/src/client/slot-context.ts +50 -0
- package/src/client/slot-outlet.tsx +22 -0
- package/src/client/slot-provider.tsx +32 -0
- package/src/client/ssr-data.ts +30 -9
- package/src/client/stale-client.ts +191 -0
- package/src/client/state.ts +29 -15
- package/src/client/status-page-marker.tsx +32 -0
- package/src/client/top-loader.tsx +36 -29
- package/src/client/unload-guard.ts +35 -3
- package/src/client/use-cookie.ts +70 -18
- package/src/client/use-link-status.ts +7 -7
- package/src/client/use-pathname.ts +22 -31
- package/src/client/use-pending-navigation.ts +40 -0
- package/src/client/use-query-states.ts +206 -36
- package/src/client/use-router.ts +6 -3
- package/src/client/use-search-params.ts +38 -49
- package/src/client/use-segment-params.ts +69 -0
- package/src/client/use-selected-layout-segment.ts +2 -2
- package/src/codec.ts +149 -0
- package/src/config-types.ts +322 -0
- package/src/config-validation.ts +347 -0
- package/src/cookies/define-cookie.ts +222 -53
- package/src/cookies/index.ts +13 -2
- package/src/cookies/json-cookie.ts +105 -0
- package/src/cookies/validation.ts +192 -0
- package/src/dev-tools/404-page.ts +286 -0
- package/src/dev-tools/browser-logs.ts +55 -0
- package/src/dev-tools/dev-page-shell.ts +260 -0
- package/src/dev-tools/error-page.ts +331 -0
- package/src/dev-tools/holding-server.ts +185 -0
- package/src/dev-tools/hydration-overlay.ts +158 -0
- package/src/dev-tools/index.ts +83 -0
- package/src/dev-tools/instrumentation.ts +213 -0
- package/src/{server/dev-logger.ts → dev-tools/logger.ts} +33 -51
- package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +122 -26
- package/src/dev-tools/overlay.ts +469 -0
- package/src/dev-tools/stack-classifier.ts +75 -0
- package/src/dev-tools/terminal.ts +182 -0
- package/src/fonts/ast-walk.ts +235 -0
- package/src/fonts/ast.ts +479 -128
- package/src/fonts/bundle.ts +138 -0
- package/src/fonts/css.ts +3 -2
- package/src/fonts/dev-middleware.ts +85 -0
- package/src/fonts/fallbacks.ts +0 -23
- package/src/fonts/google.ts +101 -19
- package/src/fonts/local.ts +13 -8
- package/src/fonts/paths.ts +58 -0
- package/src/fonts/pipeline.ts +348 -0
- package/src/fonts/transform.ts +311 -0
- package/src/fonts/types.ts +52 -1
- package/src/fonts/virtual-modules.ts +179 -0
- package/src/index.ts +486 -344
- package/src/params/codec-registry.ts +34 -0
- package/src/params/define-schema.ts +115 -0
- package/src/params/index.ts +17 -0
- package/src/params/resolve-schema.ts +84 -0
- package/src/plugin-context.ts +503 -0
- package/src/plugins/adapter-build.ts +229 -7
- package/src/plugins/build-manifest.ts +201 -26
- package/src/plugins/build-report.ts +275 -43
- package/src/plugins/cache.ts +243 -0
- package/src/plugins/callsite-ast.ts +472 -0
- package/src/plugins/callsite-jsx.ts +243 -0
- package/src/plugins/chunks.ts +74 -5
- package/src/plugins/client-chunks.ts +185 -0
- package/src/plugins/cloudflare-wasm.ts +141 -0
- package/src/plugins/content.ts +5 -1
- package/src/plugins/dev-discovery.ts +218 -0
- package/src/plugins/dev-server.ts +369 -96
- package/src/plugins/entries.ts +148 -18
- package/src/plugins/fonts.ts +251 -524
- package/src/plugins/graph-endpoint.ts +532 -0
- package/src/plugins/mdx.ts +116 -40
- package/src/plugins/prebuilt-capture.ts +217 -0
- package/src/plugins/prebuilt-options-analysis.ts +175 -0
- package/src/plugins/prebuilt.ts +655 -0
- package/src/plugins/prerender-sugar.ts +320 -0
- package/src/plugins/request-dep/analysis.ts +447 -0
- package/src/plugins/request-dep/index.ts +376 -0
- package/src/plugins/request-dep/origin.ts +310 -0
- package/src/plugins/routing.ts +273 -277
- package/src/plugins/server-bundle.ts +103 -14
- package/src/plugins/shims.ts +259 -97
- package/src/plugins/static-build.ts +708 -66
- package/src/react-canary.d.ts +2 -0
- package/src/routing/codegen-shared.ts +39 -0
- package/src/routing/codegen-types.ts +62 -0
- package/src/routing/codegen-write.ts +141 -0
- package/src/routing/codegen.ts +349 -232
- package/src/routing/collision-probe.ts +438 -0
- package/src/routing/collision-spaces.ts +281 -0
- package/src/routing/convention-lint.ts +623 -0
- package/src/routing/export-detect.ts +448 -0
- package/src/routing/file-cache.ts +23 -0
- package/src/routing/index.ts +16 -7
- package/src/routing/interception-overlap.ts +141 -0
- package/src/routing/interception.ts +1044 -67
- package/src/routing/link-codegen.ts +280 -0
- package/src/routing/manifest-codegen.ts +226 -0
- package/src/routing/scanner.ts +393 -219
- package/src/routing/schema-validation.ts +155 -0
- package/src/routing/segment-classify.ts +280 -0
- package/src/routing/segment-codegen.ts +98 -0
- package/src/routing/segment-keys.ts +186 -0
- package/src/routing/slot-placement.ts +97 -0
- package/src/routing/types.ts +75 -26
- package/src/routing/walkers.ts +98 -0
- package/src/rsc-runtime/rsc.ts +9 -0
- package/src/rsc-runtime/ssr.ts +51 -0
- package/src/rsc-runtime/transforms.ts +13 -0
- package/src/rsc-runtime/vendor-types.d.ts +19 -0
- package/src/schema-bridge.ts +380 -0
- package/src/search-params/define.ts +677 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/parse-total.ts +91 -0
- package/src/search-params/serialize-equal.ts +14 -0
- package/src/search-params/wrappers.ts +150 -0
- package/src/server/access-gate.tsx +196 -57
- package/src/server/action-client.ts +136 -35
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +256 -56
- package/src/server/actions.ts +112 -68
- package/src/server/als-registry.ts +160 -21
- package/src/server/asset-headers.ts +15 -37
- package/src/server/body-limits.ts +10 -2
- package/src/server/build-manifest.ts +33 -57
- package/src/server/canonicalize.ts +6 -3
- package/src/server/chain-url-parts.ts +163 -0
- package/src/server/children-interception.ts +115 -0
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/compress.ts +43 -8
- package/src/server/cookie-context.ts +484 -0
- package/src/server/cookie-parsing.ts +163 -0
- package/src/server/csp-nonce.ts +70 -0
- package/src/server/csrf.ts +39 -6
- package/src/server/debug.ts +137 -0
- package/src/server/default-logger.ts +99 -0
- package/src/server/default-status-page.ts +88 -0
- package/src/server/deny-boundary.ts +533 -0
- package/src/server/deny-renderer.ts +214 -112
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/early-hints-sender.ts +4 -3
- package/src/server/early-hints.ts +39 -29
- package/src/server/error-boundary-wrapper.ts +181 -44
- package/src/server/error-response-headers.ts +18 -0
- package/src/server/fallback-error.ts +79 -102
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +67 -0
- package/src/server/form-data.ts +124 -12
- package/src/server/form-flash.ts +2 -2
- package/src/server/head-response.ts +54 -0
- package/src/server/html-injector-core.ts +512 -0
- package/src/server/html-injectors.ts +272 -235
- package/src/server/index.ts +40 -192
- package/src/server/instrumentation.ts +1 -1
- package/src/server/internal.ts +173 -0
- package/src/server/logger.ts +73 -36
- package/src/server/metadata-collector.ts +174 -0
- package/src/server/metadata-platform.ts +2 -2
- package/src/server/metadata-render.ts +30 -8
- package/src/server/metadata-routes.ts +205 -24
- package/src/server/metadata-social.ts +2 -2
- package/src/server/metadata.ts +23 -2
- package/src/server/middleware-runner.ts +32 -5
- package/src/server/node-stream-transforms.ts +323 -0
- package/src/server/nuqs-ssr-provider.tsx +8 -7
- package/src/server/param-coercion.ts +198 -0
- package/src/server/pipeline-helpers.ts +159 -0
- package/src/server/pipeline-interception.ts +109 -33
- package/src/server/pipeline-metadata.ts +15 -1
- package/src/server/pipeline-outcome.ts +218 -0
- package/src/server/pipeline-phases.ts +606 -0
- package/src/server/pipeline.ts +343 -389
- package/src/server/port-resolution.ts +53 -0
- package/src/server/prebuilt/cache-key.ts +299 -0
- package/src/server/prebuilt/capture-state.ts +89 -0
- package/src/server/prebuilt/key-discipline.ts +122 -0
- package/src/server/prebuilt/manifest-tag-index.ts +46 -0
- package/src/server/prebuilt/overlay.ts +256 -0
- package/src/server/prebuilt/payload-source.ts +202 -0
- package/src/server/prebuilt/slots.ts +190 -0
- package/src/server/prebuilt/synthetic-store.ts +122 -0
- package/src/server/prebuilt-builder.ts +804 -0
- package/src/server/prebuilt-runtime.ts +817 -0
- package/src/server/primitives.ts +246 -97
- package/src/server/publish-params.ts +42 -0
- package/src/server/render-timeout.ts +108 -0
- package/src/server/render-utils.ts +35 -0
- package/src/server/request-context.ts +244 -333
- package/src/server/request-dep.ts +37 -0
- package/src/server/response-cache-policy.ts +45 -0
- package/src/server/route-element-builder.ts +508 -360
- package/src/server/route-element-helpers.ts +37 -0
- package/src/server/route-handler.ts +40 -13
- package/src/server/route-matcher.ts +165 -272
- package/src/server/route-module-loader.ts +161 -0
- package/src/server/rsc-cache-key-guard.ts +122 -0
- package/src/server/rsc-entry/action-middleware-runner.ts +174 -0
- package/src/server/rsc-entry/api-handler.ts +78 -34
- package/src/server/rsc-entry/deny-fallback.ts +93 -0
- package/src/server/rsc-entry/error-renderer.ts +373 -95
- package/src/server/rsc-entry/helpers.ts +226 -95
- package/src/server/rsc-entry/index.ts +405 -323
- package/src/server/rsc-entry/render-route.ts +304 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +350 -0
- package/src/server/rsc-entry/rsc-payload.ts +239 -50
- package/src/server/rsc-entry/rsc-stream.ts +160 -30
- package/src/server/rsc-entry/ssr-bridge.ts +18 -5
- package/src/server/rsc-entry/ssr-renderer.ts +315 -57
- package/src/server/rsc-entry/wrap-action-dispatch.ts +186 -0
- package/src/server/rsc-error-envelope.ts +18 -0
- package/src/server/rsc-prop-warnings.ts +3 -1
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/server-only-guard-noop.js +3 -0
- package/src/server/server-timing.ts +1 -1
- package/src/server/sitemap-generator.ts +337 -0
- package/src/server/sitemap-handler.ts +157 -0
- package/src/server/skippable-prefix.ts +172 -0
- package/src/server/slot-interception.ts +168 -0
- package/src/server/slot-resolver.ts +707 -300
- package/src/server/slot-subtree-contain.ts +255 -0
- package/src/server/ssr-bridge-types.ts +165 -0
- package/src/server/ssr-entry.ts +230 -85
- package/src/server/ssr-render.ts +357 -85
- package/src/server/ssr-wrappers.tsx +162 -0
- package/src/server/state-tree-diff.ts +85 -30
- package/src/server/static-generator.ts +715 -0
- package/src/server/static-not-found.ts +134 -0
- package/src/server/status-code-resolver.ts +107 -148
- package/src/server/stream-utils.ts +292 -0
- package/src/server/tracing.ts +151 -16
- package/src/server/tree-match.ts +262 -0
- package/src/server/types.ts +95 -10
- package/src/server/utils/element-type.ts +88 -0
- package/src/server/utils/escape-html.ts +20 -0
- package/src/server/utils/mdx-file.ts +22 -0
- package/src/server/version-skew.ts +104 -0
- package/src/server/waituntil-bridge.ts +5 -2
- package/src/server/workers-cache-bridge.ts +33 -0
- package/src/shared/als-slots.ts +74 -0
- package/src/shared/base-path.ts +80 -0
- package/src/shared/href-validation.ts +159 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shared/param-value.ts +281 -0
- package/src/shared/payload-root.ts +152 -0
- package/src/shared/redirect-type.ts +17 -0
- package/src/shared/rsc-cache-key.ts +269 -0
- package/src/shared/rsc-error-envelope.ts +16 -0
- package/src/shared/rsc-manifest.ts +29 -0
- package/src/shared/rsc-media-type.ts +59 -0
- package/src/shared/rsc-payload-path.ts +45 -0
- package/src/shared/segment-info.ts +67 -0
- package/src/shared/slot-params.ts +109 -0
- package/src/shared/static-platform-files.ts +75 -0
- package/src/shared/status-reason-phrase.ts +61 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/headers.ts +122 -1
- package/src/shims/navigation-client.ts +36 -32
- package/src/shims/navigation-rsc.ts +47 -0
- package/src/shims/navigation.ts +10 -7
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-k-AtAQ9R.js +0 -41
- package/dist/_chunks/als-registry-k-AtAQ9R.js.map +0 -1
- package/dist/_chunks/format-DNt20Kt8.js +0 -163
- package/dist/_chunks/format-DNt20Kt8.js.map +0 -1
- package/dist/_chunks/interception-DGDIjDbR.js +0 -676
- package/dist/_chunks/interception-DGDIjDbR.js.map +0 -1
- package/dist/_chunks/metadata-routes-CQCnF4VK.js +0 -153
- package/dist/_chunks/metadata-routes-CQCnF4VK.js.map +0 -1
- package/dist/_chunks/request-context-CRj2Zh1E.js +0 -329
- package/dist/_chunks/request-context-CRj2Zh1E.js.map +0 -1
- package/dist/_chunks/ssr-data-DLnbYpj1.js.map +0 -1
- package/dist/_chunks/tracing-DF0G3FB7.js +0 -173
- package/dist/_chunks/tracing-DF0G3FB7.js.map +0 -1
- package/dist/_chunks/use-cookie-dDbpCTx-.js +0 -91
- package/dist/_chunks/use-cookie-dDbpCTx-.js.map +0 -1
- package/dist/_chunks/use-query-states-DAhgj8Gx.js +0 -109
- package/dist/_chunks/use-query-states-DAhgj8Gx.js.map +0 -1
- package/dist/adapters/cloudflare.js.map +0 -1
- package/dist/cache/index.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/error-boundary.js.map +0 -1
- package/dist/client/head.d.ts +0 -16
- package/dist/client/head.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/segment-merger.d.ts +0 -119
- package/dist/client/segment-merger.d.ts.map +0 -1
- package/dist/client/stale-reload.d.ts +0 -44
- package/dist/client/stale-reload.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts +0 -74
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/client/use-navigation-pending.d.ts +0 -26
- package/dist/client/use-navigation-pending.d.ts.map +0 -1
- package/dist/client/use-params.d.ts +0 -92
- package/dist/client/use-params.d.ts.map +0 -1
- package/dist/content/index.d.ts +0 -11
- package/dist/content/index.d.ts.map +0 -1
- package/dist/content/index.js +0 -2
- package/dist/plugins/cache-transform.d.ts +0 -36
- package/dist/plugins/cache-transform.d.ts.map +0 -1
- package/dist/plugins/dev-error-overlay.d.ts +0 -60
- package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
- package/dist/plugins/dev-logs.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/plugins/server-action-exports.d.ts +0 -26
- package/dist/plugins/server-action-exports.d.ts.map +0 -1
- package/dist/routing/status-file-lint.d.ts +0 -33
- package/dist/routing/status-file-lint.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/registry.d.ts +0 -20
- package/dist/search-params/registry.d.ts.map +0 -1
- package/dist/server/client-module-map.d.ts +0 -47
- package/dist/server/client-module-map.d.ts.map +0 -1
- package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
- package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
- package/dist/server/dev-logger.d.ts.map +0 -1
- package/dist/server/dev-span-processor.d.ts +0 -29
- package/dist/server/dev-span-processor.d.ts.map +0 -1
- package/dist/server/dev-warnings.d.ts +0 -129
- package/dist/server/dev-warnings.d.ts.map +0 -1
- package/dist/server/flush.d.ts +0 -74
- package/dist/server/flush.d.ts.map +0 -1
- package/dist/server/manifest-status-resolver.d.ts +0 -58
- package/dist/server/manifest-status-resolver.d.ts.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/server/tree-builder.d.ts +0 -126
- package/dist/server/tree-builder.d.ts.map +0 -1
- package/dist/utils/directive-parser.d.ts +0 -70
- package/dist/utils/directive-parser.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -99
- package/src/client/browser-entry.ts +0 -674
- package/src/client/head.ts +0 -61
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/segment-merger.ts +0 -345
- package/src/client/stale-reload.ts +0 -89
- package/src/client/transition-root.tsx +0 -160
- package/src/client/use-navigation-pending.ts +0 -38
- package/src/client/use-params.ts +0 -141
- package/src/content/index.ts +0 -13
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dev-error-overlay.ts +0 -230
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/plugins/server-action-exports.ts +0 -220
- package/src/routing/status-file-lint.ts +0 -112
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/codecs.ts +0 -153
- package/src/search-params/create.ts +0 -321
- package/src/search-params/registry.ts +0 -31
- package/src/server/client-module-map.ts +0 -58
- package/src/server/dev-fetch-instrumentation.ts +0 -96
- package/src/server/dev-span-processor.ts +0 -78
- package/src/server/dev-warnings.ts +0 -282
- package/src/server/flush.ts +0 -182
- package/src/server/manifest-status-resolver.ts +0 -215
- package/src/server/prerender.ts +0 -139
- package/src/server/tree-builder.ts +0 -382
- package/src/shims/server-only-noop.js +0 -6
- package/src/utils/directive-parser.ts +0 -529
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-bridge-C83xa9lT.js","names":[],"sources":["../../src/schema-bridge.ts"],"sourcesContent":["/**\n * Standard Schema bridge — shared helpers for bridging Standard Schema-compatible\n * validation libraries (Zod, Valibot, ArkType) to the Codec<T> protocol.\n *\n * This module is the single source of truth for:\n * - StandardSchemaV1 interface (subset of the Standard Schema spec)\n * - validateSync() helper\n * - fromSchema() — search-param bridge; scalar shape first, array second\n * - fromArraySchema() — same loop, array shape first\n * - fromCookieSchema() — scalar shape only; a cookie has no array shape\n * - fromParamSchema() — route params; throws on failure (invalid param → 404)\n *\n * One parse loop, four candidate orders. Which shapes a bridge offers, and\n * in what order, is the ONLY thing that differs — see §\"Shape tolerance\"\n * below and in design/23-search-params.md. `serialize` is deliberately NOT\n * shared: `null` means \"omit the key\" for a search param and \"delete the\n * cookie\" for a cookie, so unifying it silently changed what\n * `cookie.set([])` did (TIM-1352).\n *\n * These are re-exported from @timber-js/app/search-params, @timber-js/app/segment-params,\n * and @timber-js/app/cookies for convenience. The canonical import is\n * @timber-js/app/codec.\n *\n * Design doc: design/23a-search-params-triage.md §\"Unify Codec<T> type\"\n */\n\nimport type { Codec } from './codec.ts';\n\n// ---------------------------------------------------------------------------\n// Standard Schema interface (subset)\n//\n// Standard Schema (https://github.com/standard-schema/standard-schema) defines\n// a minimal interface that Zod ≥3.24, Valibot ≥1.0, and ArkType all implement.\n// We depend only on `~standard.validate` to avoid coupling to any specific lib.\n// ---------------------------------------------------------------------------\n\n/** Minimal Standard Schema interface for auto-detection. */\nexport interface StandardSchemaV1<Output = unknown> {\n '~standard': {\n validate(value: unknown): StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;\n };\n}\n\nexport type StandardSchemaResult<Output> =\n | { value: Output; issues?: undefined }\n | { value?: undefined; issues: ReadonlyArray<{ message: string }> };\n\n// ---------------------------------------------------------------------------\n// Sync validate helper\n// ---------------------------------------------------------------------------\n\n/**\n * Run a Standard Schema's `~standard.validate()` synchronously.\n *\n * Zod v4's signature includes `Promise` in the return union to satisfy the\n * Standard Schema spec, but in practice Zod always validates synchronously\n * for the schema types we use. We assert the result is sync and throw if\n * it isn't — codec parsing must be synchronous.\n */\nexport function validateSync<Output>(\n schema: StandardSchemaV1<Output>,\n value: unknown\n): StandardSchemaResult<Output> {\n const result = schema['~standard'].validate(value);\n if (result instanceof Promise) {\n throw new Error(\n '[timber] fromSchema: schema returned a Promise — only sync schemas are supported.'\n );\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\n/** Check if a value is a Standard Schema object. */\nexport function isStandardSchema(value: unknown): value is StandardSchemaV1 {\n return (\n typeof value === 'object' &&\n value !== null &&\n '~standard' in value &&\n typeof (value as StandardSchemaV1)['~standard']?.validate === 'function'\n );\n}\n\n/** Check if a value is a Codec (has parse + serialize methods). */\nexport function isCodec(value: unknown): value is Codec<unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Codec<unknown>).parse === 'function' &&\n typeof (value as Codec<unknown>).serialize === 'function'\n );\n}\n\n// ---------------------------------------------------------------------------\n// fromParamSchema — bridge from Standard Schema to Codec<T> for route params\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge a Standard Schema to a Codec for route params.\n * Parse throws on failure (invalid param → 404). Serialize returns string.\n */\nexport function fromParamSchema<T>(fieldName: string, schema: StandardSchemaV1<T>): Codec<T> {\n return {\n parse(value: string | string[] | undefined): T {\n const result = validateSync(schema, value);\n if (!result.issues) {\n return result.value;\n }\n const messages = result.issues.map((i) => i.message).join(', ');\n throw new Error(`[timber] Param '${fieldName}' coercion failed: ${messages}`);\n },\n serialize(value: T): string | null {\n if (value === null || value === undefined) return null;\n if (Array.isArray(value)) return value.join('/');\n return String(value);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// resolveCodecOrSchema — generic resolver for any codec-or-schema field\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a field value to a Codec. Accepts Codec<T>, StandardSchemaV1<T>,\n * or (for route params) auto-wraps via fromParamSchema.\n *\n * @param fieldName - used in error messages\n * @param value - the codec or schema to resolve\n * @param mode - 'param' uses fromParamSchema (throws on parse failure),\n * 'search' uses fromSchema (falls back to default on failure,\n * tolerant of the repeated-key array shape),\n * 'cookie' uses fromCookieSchema (same, minus the array shape,\n * which a cookie value cannot have)\n */\nexport function resolveCodecOrSchema(\n fieldName: string,\n value: unknown,\n mode: 'param' | 'search' | 'cookie' = 'search'\n): Codec<unknown> {\n if (isCodec(value)) return value;\n if (isStandardSchema(value)) {\n if (mode === 'param') return fromParamSchema(fieldName, value);\n if (mode === 'cookie') return fromCookieSchema(value) as Codec<unknown>;\n return fromSchema(value) as Codec<unknown>;\n }\n throw new Error(\n `[timber] Field '${fieldName}' is not a valid codec or Standard Schema. ` +\n `Expected an object with { parse, serialize } methods, or a Standard Schema object ` +\n `(Zod, Valibot, ArkType).`\n );\n}\n\n// ---------------------------------------------------------------------------\n// fromSchema — bridge from Standard Schema to Codec<T>\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Shape tolerance — the shared parse loop for both bridges\n//\n// A URL value is `string | string[] | undefined`, but a schema is written\n// against ONE of those: `z.string()` wants `'a'`, `z.array(z.string())`\n// wants `['a']`. Nothing in Standard Schema says which — `~standard.types`\n// exists at the type level only, and probing at runtime is not reliable\n// (design/23-search-params.md §\"Shape tolerance\"). So a bridge tries BOTH\n// shapes rather than committing to one and discarding the value when it\n// guessed wrong.\n//\n// Each bridge only chooses WHICH candidates, and in what order. The first\n// candidate is always the shape that bridge already passed, so nothing that\n// parses today changes meaning; a later one is reached only where the old\n// code fell through to the default. `fromCookieSchema` offers ONE candidate,\n// because a cookie has no array shape at all.\n// ---------------------------------------------------------------------------\n\n/**\n * The scalar shape, and only it. A value that cannot be repeated — a cookie —\n * has no array shape to tolerate, so its bridge stays exactly where it was.\n */\nfunction scalarOnly(value: string | string[] | undefined): unknown[] {\n return [Array.isArray(value) ? value[0] : value];\n}\n\n/** Candidate inputs for the scalar bridge: scalar first, array second. */\nfunction scalarFirst(value: string | string[] | undefined): unknown[] {\n if (value === undefined) return [undefined];\n if (typeof value === 'string') return [value, [value]];\n // Repeated keys: `value[0]` matches URLSearchParams.get().\n //\n // A raw `[]` carries no value at all. `value[0]` is `undefined`, which is\n // the shape the scalar bridge has always passed for it, so `undefined`\n // stays FIRST — an empty array must keep meaning \"absent\" and land on the\n // schema's default. Only `defineSearchParams().parse({ tags: [] })`, the\n // record form, can produce one: URLSearchParams never yields an empty list.\n return value.length > 0 ? [value[0], value] : [undefined, value];\n}\n\n/** Candidate inputs for the array bridge: array first, scalar second. */\nfunction arrayFirst(value: string | string[] | undefined): unknown[] {\n if (value === undefined) return [undefined];\n if (typeof value === 'string') return [[value], value];\n // `[]` first here for the same reason, inverted: the array bridge has\n // always passed the empty array straight through.\n return value.length > 0 ? [value, value[0]] : [value, undefined];\n}\n\n/**\n * Validate `value` against `schema` in each candidate shape, then fall back\n * to the schema's default. Shared by every bridge — they differ only in\n * which candidates they offer, and in what order.\n */\nfunction parseThroughSchema<T>(\n schema: StandardSchemaV1<T>,\n candidates: (value: string | string[] | undefined) => unknown[],\n value: string | string[] | undefined\n): T {\n const inputs = candidates(value);\n for (let i = 0; i < inputs.length; i++) {\n // A throw from the FIRST candidate propagates, unchanged: that is the\n // shape the schema was written against, and a throw from it is the\n // deliberate signal design/23 protects — an app schema may `redirect()`\n // or `notFound()` on a value it refuses, and `validateSync` throws on\n // an async schema.\n //\n // A throw from a LATER candidate is ours, not the app's. We invented\n // that shape; the schema never agreed to receive it. A scalar-only\n // hand-written validator doing `value.toUpperCase()`, or a schema that\n // is async for the array shape only, would turn a field that used to\n // fall back to its default into a render-phase 500. Treat it as \"this\n // shape does not fit\" and keep going.\n let result: StandardSchemaResult<T>;\n try {\n result = validateSync(schema, inputs[i]);\n } catch (error) {\n if (i === 0) throw error;\n continue;\n }\n if (!result.issues) {\n return result.value;\n }\n }\n\n // No shape validated — try parsing undefined to get the default.\n // Re-validate each time so factory defaults (e.g. .default(() => []))\n // produce fresh values.\n const defaultResult = validateSync(schema, undefined);\n if (!defaultResult.issues) {\n return defaultResult.value;\n }\n\n // No default available — the field is implicitly optional. Return\n // undefined; defineSearchParams widens the field's inferred type to\n // T | undefined via InferField so this doesn't lie.\n // design/23-search-params.md §\"Implicit Optionality\"\n return undefined as T;\n}\n\n/**\n * Bridge a Standard Schema-compatible schema (Zod, Valibot, ArkType) to a\n * Codec<T>.\n *\n * Parse: coerces the raw URL value through the schema, trying the scalar\n * shape and then the array shape (see `scalarFirst`), so an array schema\n * works bare: `z.array(z.string()).default([])` yields `[]` when absent,\n * `['a']` for `?tags=a`, and `['a','b']` for `?tags=a&tags=b`. When no\n * shape validates, parses `undefined` to get the schema's default (the\n * schema should have a `.default()` call). If that also fails, returns\n * `undefined`.\n *\n * Serialize: `String()` for primitives, `null` for null/undefined. Note\n * that `String(['a','b'])` is `'a,b'` — the same string `fromArraySchema`\n * writes — so a bare array schema round-trips exactly as design/09\n * §\"Array params\" describes.\n *\n * This is the SEARCH-PARAM bridge. Cookies use `fromCookieSchema`; a\n * cookie has no array shape (see below).\n *\n * ```ts\n * import { z } from 'zod/v4'\n *\n * const pageCodec = fromSchema(z.coerce.number().int().min(1).default(1))\n * const tagsCodec = fromSchema(z.array(z.string()).default([]))\n * ```\n */\nexport function fromSchema<T>(schema: StandardSchemaV1<T>): Codec<T> {\n return {\n parse: (value: string | string[] | undefined): T =>\n parseThroughSchema(schema, scalarFirst, value),\n serialize(value: T): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n return String(value);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// fromCookieSchema — bridge for cookie values\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge a Standard Schema for a COOKIE value.\n *\n * Identical to `fromSchema` minus the array shape, because a cookie cannot\n * carry one: `Cookie:` headers and `document.cookie` yield a single string\n * per name, and there is no repeated-key concept to be tolerant of. Sharing\n * the search-param bridge here meant a cookie written by this very codec —\n * `serialize(['a','b'])` → `a,b` — read back as the one-element array\n * `['a,b']` instead of failing to its default: no repeated key in sight,\n * just a delimiter reinterpreted as data.\n *\n * The `serialize` contract also differs by domain and must not be unified:\n * for a search param `null` means \"omit the key\", for a cookie it means\n * **delete the cookie** (design/29-cookies.md).\n */\nexport function fromCookieSchema<T>(schema: StandardSchemaV1<T>): Codec<T> {\n return {\n parse: (value: string | string[] | undefined): T =>\n parseThroughSchema(schema, scalarOnly, value),\n serialize(value: T): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n return String(value);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// fromArraySchema — bridge for array-valued codecs\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge a Standard Schema for array values. Handles both single strings\n * and repeated query keys (`?tag=a&tag=b`).\n *\n * ```ts\n * import { fromArraySchema } from '@timber-js/app/codec'\n * import { z } from 'zod/v4'\n *\n * const tagsCodec = fromArraySchema(z.array(z.string()).default([]))\n * ```\n *\n * Since TIM-1352 a bare array schema works through `fromSchema` too, so\n * this is no longer required to make an array field parse. Two cases still\n * want it, both listed in design/23 §\"Shape tolerance\":\n *\n * 1. A **permissive** schema meant as an array — one that accepts a string\n * as readily as an array (`z.any()`, a hand-written coercing validator)\n * — where scalar-first ordering would settle on the scalar shape.\n * 2. An array schema wrapped in `.catch([])`, which swallows the failure\n * that would otherwise trigger the array attempt.\n *\n * It also serializes an empty array to `null` (omitting the key) where\n * `fromSchema` writes `''`.\n */\nexport function fromArraySchema<T>(schema: StandardSchemaV1<T>): {\n parse(value: string | string[] | undefined): T;\n serialize(value: T): string | string[] | null;\n} {\n return {\n parse: (value: string | string[] | undefined): T =>\n parseThroughSchema(schema, arrayFirst, value),\n serialize(value: T): string | string[] | null {\n if (value === null || value === undefined) {\n return null;\n }\n // TIM-1353: return string[] so buildSearchParams emits repeated keys\n // (?tag=a&tag=b) instead of comma-joining into one key (?tag=a%2Cb).\n if (Array.isArray(value)) {\n return value.length === 0 ? null : value.map(String);\n }\n return String(value);\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
//#region src/routing/types.ts
|
|
2
|
+
/** All recognized interception markers, ordered longest-first for parsing. */
|
|
3
|
+
var INTERCEPTION_MARKERS = [
|
|
4
|
+
"(..)(..)",
|
|
5
|
+
"(.)",
|
|
6
|
+
"(..)",
|
|
7
|
+
"(...)"
|
|
8
|
+
];
|
|
9
|
+
/** Default page extensions */
|
|
10
|
+
var DEFAULT_PAGE_EXTENSIONS = [
|
|
11
|
+
"tsx",
|
|
12
|
+
"ts",
|
|
13
|
+
"jsx",
|
|
14
|
+
"js"
|
|
15
|
+
];
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/routing/segment-classify.ts
|
|
18
|
+
/**
|
|
19
|
+
* Classify a URL path segment token.
|
|
20
|
+
*
|
|
21
|
+
* Walks the string left-to-right in one pass:
|
|
22
|
+
* 1. Find the first '[' — characters before it are the prefix.
|
|
23
|
+
* 2. Count opening brackets (1 or 2) to detect optional.
|
|
24
|
+
* 3. Check for '...' to detect catch-all.
|
|
25
|
+
* 4. Read the param name up to the closing bracket.
|
|
26
|
+
* 5. Validate the expected closing sequence (']' or ']]').
|
|
27
|
+
* 6. Characters after the close are the suffix.
|
|
28
|
+
* 7. Reject affixes on catch-all/optional-catch-all.
|
|
29
|
+
* 8. Reject affixes that contain '[' or ']' (no multi-param segments).
|
|
30
|
+
*
|
|
31
|
+
* Any structural violation → static (safe default).
|
|
32
|
+
*/
|
|
33
|
+
function classifyUrlSegment(token) {
|
|
34
|
+
const len = token.length;
|
|
35
|
+
if (len === 0) return {
|
|
36
|
+
kind: "static",
|
|
37
|
+
value: token
|
|
38
|
+
};
|
|
39
|
+
const bracketStart = token.indexOf("[");
|
|
40
|
+
if (bracketStart === -1) return {
|
|
41
|
+
kind: "static",
|
|
42
|
+
value: token
|
|
43
|
+
};
|
|
44
|
+
const prefix = token.slice(0, bracketStart);
|
|
45
|
+
let i = bracketStart + 1;
|
|
46
|
+
const optional = i < len && token[i] === "[";
|
|
47
|
+
if (optional) i++;
|
|
48
|
+
const catchAll = i + 2 < len && token[i] === "." && token[i + 1] === "." && token[i + 2] === ".";
|
|
49
|
+
if (catchAll) i += 3;
|
|
50
|
+
const nameStart = i;
|
|
51
|
+
while (i < len && token[i] !== "]") i++;
|
|
52
|
+
if (i >= len || i === nameStart) return {
|
|
53
|
+
kind: "static",
|
|
54
|
+
value: token
|
|
55
|
+
};
|
|
56
|
+
const name = token.slice(nameStart, i);
|
|
57
|
+
i++;
|
|
58
|
+
if (optional) {
|
|
59
|
+
if (i >= len || token[i] !== "]") return {
|
|
60
|
+
kind: "static",
|
|
61
|
+
value: token
|
|
62
|
+
};
|
|
63
|
+
i++;
|
|
64
|
+
}
|
|
65
|
+
const suffix = token.slice(i);
|
|
66
|
+
if (suffix.includes("[") || suffix.includes("]")) return {
|
|
67
|
+
kind: "static",
|
|
68
|
+
value: token
|
|
69
|
+
};
|
|
70
|
+
if (prefix.includes("]")) return {
|
|
71
|
+
kind: "static",
|
|
72
|
+
value: token
|
|
73
|
+
};
|
|
74
|
+
const hasAffixes = prefix.length > 0 || suffix.length > 0;
|
|
75
|
+
if (optional && catchAll) {
|
|
76
|
+
if (hasAffixes) return {
|
|
77
|
+
kind: "static",
|
|
78
|
+
value: token
|
|
79
|
+
};
|
|
80
|
+
return {
|
|
81
|
+
kind: "optional-catch-all",
|
|
82
|
+
name
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (catchAll) {
|
|
86
|
+
if (hasAffixes) return {
|
|
87
|
+
kind: "static",
|
|
88
|
+
value: token
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
kind: "catch-all",
|
|
92
|
+
name
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (optional) return {
|
|
96
|
+
kind: "static",
|
|
97
|
+
value: token
|
|
98
|
+
};
|
|
99
|
+
if (hasAffixes) return {
|
|
100
|
+
kind: "dynamic",
|
|
101
|
+
name,
|
|
102
|
+
prefix: prefix || void 0,
|
|
103
|
+
suffix: suffix || void 0
|
|
104
|
+
};
|
|
105
|
+
return {
|
|
106
|
+
kind: "dynamic",
|
|
107
|
+
name
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Classify a directory name into its segment type.
|
|
112
|
+
*
|
|
113
|
+
* Recognizes all timber file-system conventions in priority order:
|
|
114
|
+
* 1. Private folders: `_name` (excluded from routing)
|
|
115
|
+
* 2. Parallel route slots: `@name`
|
|
116
|
+
* 3. Intercepting routes: `(.)name`, `(..)name`, `(...)name`, `(..)(..)name`
|
|
117
|
+
* 4. Route groups: `(name)`
|
|
118
|
+
* 5. Bracket syntax: `[id]`, `[...slug]`, `[[...path]]` (delegated to
|
|
119
|
+
* `classifyUrlSegment`)
|
|
120
|
+
* 6. Static: anything else
|
|
121
|
+
*
|
|
122
|
+
* If you change the bracket syntax, update only `classifyUrlSegment`.
|
|
123
|
+
* If you change the directory-prefix conventions, update this function.
|
|
124
|
+
*/
|
|
125
|
+
function classifySegment(dirName) {
|
|
126
|
+
if (dirName.startsWith("_")) return { type: "private" };
|
|
127
|
+
if (dirName.startsWith("@")) return { type: "slot" };
|
|
128
|
+
const interception = parseInterceptionMarker(dirName);
|
|
129
|
+
if (interception) return {
|
|
130
|
+
type: "intercepting",
|
|
131
|
+
interceptionMarker: interception.marker,
|
|
132
|
+
interceptedSegmentName: interception.segmentName
|
|
133
|
+
};
|
|
134
|
+
if (dirName.startsWith("(") && dirName.endsWith(")")) return { type: "group" };
|
|
135
|
+
const urlSeg = classifyUrlSegment(dirName);
|
|
136
|
+
if (urlSeg.kind !== "static") {
|
|
137
|
+
const result = {
|
|
138
|
+
type: urlSeg.kind,
|
|
139
|
+
paramName: urlSeg.name
|
|
140
|
+
};
|
|
141
|
+
if (urlSeg.kind === "dynamic") {
|
|
142
|
+
if (urlSeg.prefix) result.paramPrefix = urlSeg.prefix;
|
|
143
|
+
if (urlSeg.suffix) result.paramSuffix = urlSeg.suffix;
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
return { type: "static" };
|
|
148
|
+
}
|
|
149
|
+
function effectiveUrlSegment(node) {
|
|
150
|
+
if (node.segmentType !== "intercepting" || !node.interceptedSegmentName) return {
|
|
151
|
+
segmentName: node.segmentName,
|
|
152
|
+
segmentType: node.segmentType,
|
|
153
|
+
paramName: node.paramName,
|
|
154
|
+
paramPrefix: node.paramPrefix,
|
|
155
|
+
paramSuffix: node.paramSuffix
|
|
156
|
+
};
|
|
157
|
+
const seg = classifyUrlSegment(node.interceptedSegmentName);
|
|
158
|
+
if (seg.kind === "static") return {
|
|
159
|
+
segmentName: seg.value,
|
|
160
|
+
segmentType: "static"
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
segmentName: node.interceptedSegmentName,
|
|
164
|
+
segmentType: seg.kind,
|
|
165
|
+
paramName: seg.name,
|
|
166
|
+
paramPrefix: seg.kind === "dynamic" ? seg.prefix : void 0,
|
|
167
|
+
paramSuffix: seg.kind === "dynamic" ? seg.suffix : void 0
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Parse an interception marker from a directory name.
|
|
172
|
+
*
|
|
173
|
+
* Returns the marker and the remaining segment name, or null if not an
|
|
174
|
+
* intercepting route. Markers are checked longest-first to avoid `(..)`
|
|
175
|
+
* matching before `(..)(..)`.
|
|
176
|
+
*
|
|
177
|
+
* Examples:
|
|
178
|
+
* "(.)photo" → { marker: "(.)", segmentName: "photo" }
|
|
179
|
+
* "(..)feed" → { marker: "(..)", segmentName: "feed" }
|
|
180
|
+
* "(...)photos" → { marker: "(...)", segmentName: "photos" }
|
|
181
|
+
* "(..)(..)admin" → { marker: "(..)(..)", segmentName: "admin" }
|
|
182
|
+
* "(marketing)" → null (route group, not interception)
|
|
183
|
+
*/
|
|
184
|
+
function parseInterceptionMarker(dirName) {
|
|
185
|
+
for (const marker of INTERCEPTION_MARKERS) if (dirName.startsWith(marker)) {
|
|
186
|
+
const rest = dirName.slice(marker.length);
|
|
187
|
+
if (rest.length > 0 && !rest.endsWith(")")) return {
|
|
188
|
+
marker,
|
|
189
|
+
segmentName: rest
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
export { INTERCEPTION_MARKERS as a, DEFAULT_PAGE_EXTENSIONS as i, classifyUrlSegment as n, effectiveUrlSegment as r, classifySegment as t };
|
|
196
|
+
|
|
197
|
+
//# sourceMappingURL=segment-classify-C539Pa2O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment-classify-C539Pa2O.js","names":[],"sources":["../../src/routing/types.ts","../../src/routing/segment-classify.ts"],"sourcesContent":["/**\n * Route tree types for timber.js file-system routing.\n *\n * The route tree is built by scanning the app/ directory and recognizing\n * file conventions (page.*, layout.*, middleware.ts, access.ts, route.ts, etc.).\n *\n * **Single shape, two specializations** (TIM-848):\n *\n * `SegmentNode<TFile>` is the one canonical in-memory shape for the\n * timber route tree. The same interface is used at build time (with\n * `TFile = RouteFile`) and at request time (with `TFile = ManifestFile`,\n * see `server/route-matcher.ts`). Walkers parameterized over `TFile`\n * work on either, eliminating the previous duplication between\n * `SegmentNode` (Map-based) and `ManifestSegmentNode` (object-based).\n *\n * Keyed groups (`slots`, `statusFiles`, `jsonStatusFiles`,\n * `metadataRoutes`) are plain `Record<string, …>`\n * objects rather than `Map`s so that the build-time tree can be\n * serialized into the virtual route manifest with no shape transform.\n *\n * See design/07-routing.md §\"Route Tree Shape\" and design/18-build-system.md\n * §\"Route Manifest Shape\".\n */\n\n/** Segment type classification */\nexport type SegmentType =\n | 'static' // e.g. \"dashboard\"\n | 'dynamic' // e.g. \"[id]\"\n | 'catch-all' // e.g. \"[...slug]\"\n | 'optional-catch-all' // e.g. \"[[...slug]]\"\n | 'group' // e.g. \"(marketing)\"\n | 'slot' // e.g. \"@sidebar\"\n | 'intercepting' // e.g. \"(.)photo\", \"(..)photo\", \"(...)photo\"\n | 'private'; // e.g. \"_components\", \"_lib\" — excluded from routing\n\n/**\n * Intercepting route marker — indicates how many levels up to resolve the\n * intercepted route from the intercepting route's location.\n *\n * See design/07-routing.md §\"Intercepting Routes\"\n */\nexport type InterceptionMarker = '(.)' | '(..)' | '(...)' | '(..)(..)';\n\n/** All recognized interception markers, ordered longest-first for parsing. */\nexport const INTERCEPTION_MARKERS: InterceptionMarker[] = ['(..)(..)', '(.)', '(..)', '(...)'];\n\n/**\n * A single file discovered in a route segment at build time.\n *\n * The runtime equivalent (`ManifestFile`, defined in\n * `server/route-matcher.ts`) replaces `extension` with a lazy `load`\n * function. Walkers that only need `filePath` are parameterized over\n * `TFile` and accept either.\n */\nexport interface RouteFile {\n /** Absolute path to the file */\n filePath: string;\n /** File extension without leading dot (e.g. \"tsx\", \"ts\", \"mdx\") */\n extension: string;\n}\n\n/**\n * A node in the segment tree.\n *\n * Generic over `TFile` so the same interface describes both the\n * build-time tree (`SegmentNode<RouteFile>`, the default) and the\n * runtime manifest tree (`SegmentNode<ManifestFile>`, aliased as\n * `ManifestSegmentNode`). All keyed groups use `Record` (not `Map`)\n * so the build-time tree serializes to the virtual route manifest\n * with no shape transform.\n */\nexport interface SegmentNode<TFile = RouteFile> {\n /** The raw directory name (e.g. \"dashboard\", \"[id]\", \"(auth)\", \"@sidebar\") */\n segmentName: string;\n /** Classified segment type */\n segmentType: SegmentType;\n /** The dynamic param name, if dynamic (e.g. \"id\" for \"[id]\", \"slug\" for \"[...slug]\") */\n paramName?: string;\n /** Literal prefix before the dynamic bracket (e.g. \"img-\" for \"img-[id].png\") */\n paramPrefix?: string;\n /** Literal suffix after the dynamic bracket (e.g. \".png\" for \"img-[id].png\") */\n paramSuffix?: string;\n /** The URL path prefix at this segment level (e.g. \"/dashboard\") */\n urlPath: string;\n /** For intercepting segments: the marker used, e.g. \"(.)\". */\n interceptionMarker?: InterceptionMarker;\n /**\n * For intercepting segments: the segment name after stripping the marker.\n * E.g., for \"(.)photo\" this is \"photo\".\n */\n interceptedSegmentName?: string;\n\n // --- File conventions ---\n page?: TFile;\n layout?: TFile;\n middleware?: TFile;\n access?: TFile;\n route?: TFile;\n error?: TFile;\n default?: TFile;\n /** Status-code files: 4xx.tsx, 5xx.tsx, {status}.tsx (component format) */\n statusFiles?: Record<string, TFile>;\n /** JSON status-code files: 4xx.json, 5xx.json, {status}.json */\n jsonStatusFiles?: Record<string, TFile>;\n /** denied.tsx — slot-only denial rendering */\n denied?: TFile;\n\n /** Metadata route files (sitemap.ts, robots.ts, icon.tsx, etc.) keyed by base name */\n metadataRoutes?: Record<string, TFile>;\n\n // --- Children ---\n children: SegmentNode<TFile>[];\n /** Parallel route slots (keyed by slot name without @) */\n slots: Record<string, SegmentNode<TFile>>;\n}\n\n/**\n * The full route tree output from the scanner (or the root of the\n * runtime route manifest, when `TFile = ManifestFile`).\n *\n * Generic so the same wrapper carries app-root metadata for both\n * shapes. The runtime manifest extends this with `viteRoot` (see\n * `ManifestRoot` in `server/route-matcher.ts`).\n */\nexport interface RouteTree<TFile = RouteFile> {\n /** The root segment node (representing app/) */\n root: SegmentNode<TFile>;\n /** All discovered proxy.ts files (should be at most one, in app/) */\n proxy?: TFile;\n /**\n * Global error page: app/global-error.{tsx,ts,jsx,js}\n *\n * Rendered as a standalone full-page replacement (no layout wrapping)\n * when no segment-level error file is found. SSR-only render path.\n * Must provide its own <html> and <body>.\n *\n * See design/10-error-handling.md §\"Tier 2 — Global Error Page\"\n */\n globalError?: TFile;\n}\n\n/** Configuration passed to the scanner */\nexport interface ScannerConfig {\n /** Recognized page/layout extensions (without dots). Default: ['tsx', 'ts', 'jsx', 'js'] */\n pageExtensions?: string[];\n}\n\n/** Default page extensions */\nexport const DEFAULT_PAGE_EXTENSIONS = ['tsx', 'ts', 'jsx', 'js'];\n","/**\n * Shared segment classifier — both URL tokens and filesystem directory names.\n *\n * `classifyUrlSegment(token)` is a pure single-pass character parser that\n * classifies a route segment token (e.g. \"dashboard\", \"[id]\", \"[...slug]\",\n * \"[[...path]]\") into a typed discriminated union. NO regex, NO Node.js-only\n * APIs — safe to import from browser code (used by `Link` interpolation).\n *\n * `classifySegment(dirName)` is the build-time directory-name classifier\n * used by the scanner. It recognizes timber-only conventions (private\n * `_*`, parallel `@*`, route groups `(name)`, intercepting routes\n * `(.)`/`(..)`/`(...)`/`(..)(..)`) and delegates bracket syntax to\n * `classifyUrlSegment`. It is the **single source of truth** for what\n * counts as a routing segment — there is no separate copy in the\n * scanner. (TIM-848.)\n *\n * Malformed input falls through to `{ kind: 'static' }` — the safe default.\n *\n * If you change the bracket syntax, update ONLY this file. Every\n * consumer imports from here.\n *\n * See design/07-routing.md §\"Route Segments\"\n */\n\nimport type { InterceptionMarker, SegmentType } from './types.ts';\nimport { INTERCEPTION_MARKERS } from './types.ts';\n\nexport type UrlSegment =\n | { kind: 'static'; value: string }\n | { kind: 'dynamic'; name: string; prefix?: string; suffix?: string }\n | { kind: 'catch-all'; name: string }\n | { kind: 'optional-catch-all'; name: string };\n\n/**\n * Classify a URL path segment token.\n *\n * Walks the string left-to-right in one pass:\n * 1. Find the first '[' — characters before it are the prefix.\n * 2. Count opening brackets (1 or 2) to detect optional.\n * 3. Check for '...' to detect catch-all.\n * 4. Read the param name up to the closing bracket.\n * 5. Validate the expected closing sequence (']' or ']]').\n * 6. Characters after the close are the suffix.\n * 7. Reject affixes on catch-all/optional-catch-all.\n * 8. Reject affixes that contain '[' or ']' (no multi-param segments).\n *\n * Any structural violation → static (safe default).\n */\nexport function classifyUrlSegment(token: string): UrlSegment {\n const len = token.length;\n if (len === 0) return { kind: 'static', value: token };\n\n // Find first '[' — characters before it are the prefix\n const bracketStart = token.indexOf('[');\n if (bracketStart === -1) return { kind: 'static', value: token };\n\n const prefix = token.slice(0, bracketStart);\n\n let i = bracketStart + 1;\n\n // Check for optional: '[[...'\n const optional = i < len && token[i] === '[';\n if (optional) i++;\n\n // Check for catch-all: '...'\n const catchAll = i + 2 < len && token[i] === '.' && token[i + 1] === '.' && token[i + 2] === '.';\n if (catchAll) i += 3;\n\n // Read param name — everything up to ']'\n const nameStart = i;\n while (i < len && token[i] !== ']') i++;\n\n // Must have found a ']' and name must be non-empty\n if (i >= len || i === nameStart) {\n return { kind: 'static', value: token };\n }\n\n const name = token.slice(nameStart, i);\n i++; // skip first ']'\n\n // Optional requires a second ']'\n if (optional) {\n if (i >= len || token[i] !== ']') {\n return { kind: 'static', value: token };\n }\n i++;\n }\n\n const suffix = token.slice(i);\n\n // Reject affixes containing brackets (no multi-param segments like [foo]-[bar])\n if (suffix.includes('[') || suffix.includes(']')) {\n return { kind: 'static', value: token };\n }\n if (prefix.includes(']')) {\n return { kind: 'static', value: token };\n }\n\n const hasAffixes = prefix.length > 0 || suffix.length > 0;\n\n if (optional && catchAll) {\n // No affixes on optional catch-all\n if (hasAffixes) return { kind: 'static', value: token };\n return { kind: 'optional-catch-all', name };\n }\n if (catchAll) {\n // No affixes on catch-all\n if (hasAffixes) return { kind: 'static', value: token };\n return { kind: 'catch-all', name };\n }\n if (optional) {\n // '[[name]]' without '...' is malformed — not a valid segment syntax\n return { kind: 'static', value: token };\n }\n\n if (hasAffixes) {\n return {\n kind: 'dynamic',\n name,\n prefix: prefix || undefined,\n suffix: suffix || undefined,\n };\n }\n return { kind: 'dynamic', name };\n}\n\n// ─── Directory-name classifier (build-time scanner) ─────────────────────────\n\n/** Result of classifying a filesystem directory name. */\nexport interface SegmentClassification {\n type: SegmentType;\n paramName?: string;\n paramPrefix?: string;\n paramSuffix?: string;\n interceptionMarker?: InterceptionMarker;\n interceptedSegmentName?: string;\n}\n\n/**\n * Classify a directory name into its segment type.\n *\n * Recognizes all timber file-system conventions in priority order:\n * 1. Private folders: `_name` (excluded from routing)\n * 2. Parallel route slots: `@name`\n * 3. Intercepting routes: `(.)name`, `(..)name`, `(...)name`, `(..)(..)name`\n * 4. Route groups: `(name)`\n * 5. Bracket syntax: `[id]`, `[...slug]`, `[[...path]]` (delegated to\n * `classifyUrlSegment`)\n * 6. Static: anything else\n *\n * If you change the bracket syntax, update only `classifyUrlSegment`.\n * If you change the directory-prefix conventions, update this function.\n */\nexport function classifySegment(dirName: string): SegmentClassification {\n // Private folder: _name (excluded from routing)\n if (dirName.startsWith('_')) {\n return { type: 'private' };\n }\n\n // Parallel route slot: @name\n if (dirName.startsWith('@')) {\n return { type: 'slot' };\n }\n\n // Intercepting routes: (.)name, (..)name, (...)name, (..)(..)name\n // Check before route groups since intercepting markers also start with (\n const interception = parseInterceptionMarker(dirName);\n if (interception) {\n return {\n type: 'intercepting',\n interceptionMarker: interception.marker,\n interceptedSegmentName: interception.segmentName,\n };\n }\n\n // Route group: (name)\n if (dirName.startsWith('(') && dirName.endsWith(')')) {\n return { type: 'group' };\n }\n\n // Bracket-syntax segments: [param], [...param], [[...param]]\n const urlSeg = classifyUrlSegment(dirName);\n if (urlSeg.kind !== 'static') {\n const result: SegmentClassification = { type: urlSeg.kind, paramName: urlSeg.name };\n if (urlSeg.kind === 'dynamic') {\n if (urlSeg.prefix) result.paramPrefix = urlSeg.prefix;\n if (urlSeg.suffix) result.paramSuffix = urlSeg.suffix;\n }\n return result;\n }\n\n return { type: 'static' };\n}\n\n/**\n * The URL-matching identity of a segment node.\n *\n * For every node except an intercepting one this is the node itself. An\n * intercepting node is different: its directory name carries a marker\n * (`(.)photo`, `(.)[id]`), so the node's own `segmentType` is\n * `'intercepting'` and the bracket syntax of the segment it intercepts was\n * never classified. Everything that has to reason about *the URL part this\n * node stands for* — matching it, and keying its param for codec coercion —\n * needs that classification.\n *\n * Deriving it here, from `interceptedSegmentName`, keeps interception out\n * of `classifySegment`'s output and out of the serialized manifest: there\n * is no second copy of the classification to drift from this one. The\n * returned `segmentName` is the intercepted name (`photo`, `[id]`), NOT the\n * node's directory name — callers that need the directory name for tree\n * paths must keep reading the node. See TIM-1281.\n */\nexport interface UrlSegmentIdentity {\n segmentName: string;\n segmentType: SegmentType;\n paramName?: string;\n paramPrefix?: string;\n paramSuffix?: string;\n}\n\nexport function effectiveUrlSegment(node: {\n segmentName: string;\n segmentType: SegmentType;\n paramName?: string;\n paramPrefix?: string;\n paramSuffix?: string;\n interceptedSegmentName?: string;\n}): UrlSegmentIdentity {\n if (node.segmentType !== 'intercepting' || !node.interceptedSegmentName) {\n return {\n segmentName: node.segmentName,\n segmentType: node.segmentType,\n paramName: node.paramName,\n paramPrefix: node.paramPrefix,\n paramSuffix: node.paramSuffix,\n };\n }\n\n const seg = classifyUrlSegment(node.interceptedSegmentName);\n if (seg.kind === 'static') {\n return { segmentName: seg.value, segmentType: 'static' };\n }\n return {\n segmentName: node.interceptedSegmentName,\n segmentType: seg.kind,\n paramName: seg.name,\n paramPrefix: seg.kind === 'dynamic' ? seg.prefix : undefined,\n paramSuffix: seg.kind === 'dynamic' ? seg.suffix : undefined,\n };\n}\n\n/**\n * Parse an interception marker from a directory name.\n *\n * Returns the marker and the remaining segment name, or null if not an\n * intercepting route. Markers are checked longest-first to avoid `(..)`\n * matching before `(..)(..)`.\n *\n * Examples:\n * \"(.)photo\" → { marker: \"(.)\", segmentName: \"photo\" }\n * \"(..)feed\" → { marker: \"(..)\", segmentName: \"feed\" }\n * \"(...)photos\" → { marker: \"(...)\", segmentName: \"photos\" }\n * \"(..)(..)admin\" → { marker: \"(..)(..)\", segmentName: \"admin\" }\n * \"(marketing)\" → null (route group, not interception)\n */\nfunction parseInterceptionMarker(\n dirName: string\n): { marker: InterceptionMarker; segmentName: string } | null {\n for (const marker of INTERCEPTION_MARKERS) {\n if (dirName.startsWith(marker)) {\n const rest = dirName.slice(marker.length);\n // Must have a segment name after the marker, and the rest must not\n // be empty or end with ) (which would be a route group like \"(auth)\")\n if (rest.length > 0 && !rest.endsWith(')')) {\n return { marker, segmentName: rest };\n }\n }\n }\n return null;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createContext, createElement, useContext, useMemo } from "react";
|
|
2
|
+
//#region src/client/segment-context.ts
|
|
3
|
+
/**
|
|
4
|
+
* Segment Context — provides layout segment position for useSelectedLayoutSegment hooks.
|
|
5
|
+
*
|
|
6
|
+
* Each layout in the segment tree is wrapped with a SegmentProvider that stores
|
|
7
|
+
* the URL segments from root to the current layout level. The hooks read this
|
|
8
|
+
* context to determine which child segments are active below the calling layout.
|
|
9
|
+
*
|
|
10
|
+
* The context value is intentionally minimal: just the segment path array and
|
|
11
|
+
* parallel route keys. No internal cache details are exposed.
|
|
12
|
+
*
|
|
13
|
+
* Design docs: design/19-client-navigation.md, design/14-ecosystem.md
|
|
14
|
+
*/
|
|
15
|
+
var SegmentContext = createContext(null);
|
|
16
|
+
/** Read the segment context. Returns null if no provider is above this component. */
|
|
17
|
+
function useSegmentContext() {
|
|
18
|
+
return useContext(SegmentContext);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Wraps each layout to provide segment position context.
|
|
22
|
+
* Injected by rsc-entry.ts during element tree construction.
|
|
23
|
+
*/
|
|
24
|
+
function SegmentProvider({ segments, segmentId: _segmentId, parallelRouteKeys, children }) {
|
|
25
|
+
const value = useMemo(() => ({
|
|
26
|
+
segments,
|
|
27
|
+
parallelRouteKeys
|
|
28
|
+
}), [segments, parallelRouteKeys]);
|
|
29
|
+
return createElement(SegmentContext.Provider, { value }, children);
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { useSegmentContext as n, SegmentProvider as t };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=segment-context-D9_89u34.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment-context-D9_89u34.js","names":[],"sources":["../../src/client/segment-context.ts"],"sourcesContent":["/**\n * Segment Context — provides layout segment position for useSelectedLayoutSegment hooks.\n *\n * Each layout in the segment tree is wrapped with a SegmentProvider that stores\n * the URL segments from root to the current layout level. The hooks read this\n * context to determine which child segments are active below the calling layout.\n *\n * The context value is intentionally minimal: just the segment path array and\n * parallel route keys. No internal cache details are exposed.\n *\n * Design docs: design/19-client-navigation.md, design/14-ecosystem.md\n */\n\n'use client';\n\nimport { createContext, useContext, createElement, useMemo } from 'react';\n\n// ─── Types ───────────────────────────────────────────────────────\n\nexport interface SegmentContextValue {\n /** URL segments from root to this layout (e.g. ['', 'dashboard', 'settings']) */\n segments: string[];\n /** Parallel route slot keys available at this layout level (e.g. ['sidebar', 'modal']) */\n parallelRouteKeys: string[];\n}\n\n// ─── Context ─────────────────────────────────────────────────────\n\nconst SegmentContext = createContext<SegmentContextValue | null>(null);\n\n/** Read the segment context. Returns null if no provider is above this component. */\nexport function useSegmentContext(): SegmentContextValue | null {\n return useContext(SegmentContext);\n}\n\n// ─── Provider ────────────────────────────────────────────────────\n\ninterface SegmentProviderProps {\n segments: string[];\n /**\n * Unique identifier for this segment, used by the client-side segment\n * merger for element caching. For route groups this includes the group\n * name (e.g., \"/(marketing)\") since groups share their parent's urlPath.\n * Falls back to the reconstructed path from `segments` if not provided.\n */\n segmentId?: string;\n parallelRouteKeys: string[];\n children: React.ReactNode;\n}\n\n/**\n * Wraps each layout to provide segment position context.\n * Injected by rsc-entry.ts during element tree construction.\n */\nexport function SegmentProvider({\n segments,\n segmentId: _segmentId,\n parallelRouteKeys,\n children,\n}: SegmentProviderProps) {\n const value = useMemo(\n () => ({ segments, parallelRouteKeys }),\n // segments and parallelRouteKeys are static per layout — the layout's\n // position in the tree is fixed. The arrays are used directly as deps\n // (React Compiler requires simple expressions here). Referential stability\n // of the context value doesn't matter: every consumer\n // (useSelectedLayoutSegment/useSelectedLayoutSegments) also calls\n // usePathname(), so it re-renders on every navigation regardless.\n [segments, parallelRouteKeys]\n );\n return createElement(SegmentContext.Provider, { value }, children);\n}\n"],"mappings":";;;;;;;;;;;;;;AA4BA,IAAM,iBAAiB,cAA0C,IAAI;;AAGrE,SAAgB,oBAAgD;CAC9D,OAAO,WAAW,cAAc;AAClC;;;;;AAqBA,SAAgB,gBAAgB,EAC9B,UACA,WAAW,YACX,mBACA,YACuB;CACvB,MAAM,QAAQ,eACL;EAAE;EAAU;CAAkB,IAOrC,CAAC,UAAU,iBAAiB,CAC9B;CACA,OAAO,cAAc,eAAe,UAAU,EAAE,MAAM,GAAG,QAAQ;AACnE"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import "node:crypto";
|
|
2
|
+
//#region src/server/metadata-routes.ts
|
|
3
|
+
/**
|
|
4
|
+
* All recognized metadata route file conventions.
|
|
5
|
+
*
|
|
6
|
+
* Each entry maps a base file name (without extension) to its route info.
|
|
7
|
+
* The extensions determine whether the file is static or dynamic.
|
|
8
|
+
*
|
|
9
|
+
* Static extensions: .xml, .txt, .json, .png, .jpg, .ico, .svg
|
|
10
|
+
* Dynamic extensions: .ts, .tsx
|
|
11
|
+
*/
|
|
12
|
+
var METADATA_ROUTE_CONVENTIONS = {
|
|
13
|
+
"sitemap": {
|
|
14
|
+
type: "sitemap",
|
|
15
|
+
contentType: "application/xml",
|
|
16
|
+
nestable: true,
|
|
17
|
+
staticExtensions: ["xml"],
|
|
18
|
+
dynamicExtensions: ["ts"],
|
|
19
|
+
servePath: "sitemap.xml"
|
|
20
|
+
},
|
|
21
|
+
"robots": {
|
|
22
|
+
type: "robots",
|
|
23
|
+
contentType: "text/plain",
|
|
24
|
+
nestable: false,
|
|
25
|
+
staticExtensions: ["txt"],
|
|
26
|
+
dynamicExtensions: ["ts"],
|
|
27
|
+
servePath: "robots.txt"
|
|
28
|
+
},
|
|
29
|
+
"manifest": {
|
|
30
|
+
type: "manifest",
|
|
31
|
+
contentType: "application/manifest+json",
|
|
32
|
+
nestable: false,
|
|
33
|
+
staticExtensions: ["json"],
|
|
34
|
+
dynamicExtensions: ["ts"],
|
|
35
|
+
servePath: "manifest.webmanifest"
|
|
36
|
+
},
|
|
37
|
+
"favicon": {
|
|
38
|
+
type: "favicon",
|
|
39
|
+
contentType: "image/x-icon",
|
|
40
|
+
nestable: false,
|
|
41
|
+
staticExtensions: ["ico"],
|
|
42
|
+
dynamicExtensions: ["ts", "tsx"],
|
|
43
|
+
servePath: "favicon.ico"
|
|
44
|
+
},
|
|
45
|
+
"icon": {
|
|
46
|
+
type: "icon",
|
|
47
|
+
contentType: "image/*",
|
|
48
|
+
nestable: true,
|
|
49
|
+
staticExtensions: [
|
|
50
|
+
"png",
|
|
51
|
+
"jpg",
|
|
52
|
+
"svg"
|
|
53
|
+
],
|
|
54
|
+
dynamicExtensions: ["ts", "tsx"],
|
|
55
|
+
servePath: "icon",
|
|
56
|
+
serveExtension: "png"
|
|
57
|
+
},
|
|
58
|
+
"opengraph-image": {
|
|
59
|
+
type: "opengraph-image",
|
|
60
|
+
contentType: "image/*",
|
|
61
|
+
nestable: true,
|
|
62
|
+
staticExtensions: ["png", "jpg"],
|
|
63
|
+
dynamicExtensions: ["ts", "tsx"],
|
|
64
|
+
servePath: "opengraph-image",
|
|
65
|
+
serveExtension: "png"
|
|
66
|
+
},
|
|
67
|
+
"apple-icon": {
|
|
68
|
+
type: "apple-icon",
|
|
69
|
+
contentType: "image/*",
|
|
70
|
+
nestable: true,
|
|
71
|
+
staticExtensions: ["png"],
|
|
72
|
+
dynamicExtensions: ["ts", "tsx"],
|
|
73
|
+
servePath: "apple-icon",
|
|
74
|
+
serveExtension: "png"
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Check if a file extension represents a static (non-code) metadata route file.
|
|
79
|
+
*
|
|
80
|
+
* @param baseName - The base file name without extension (e.g. "sitemap", "icon")
|
|
81
|
+
* @param extension - The file extension without leading dot (e.g. "xml", "png", "ts")
|
|
82
|
+
* @returns true if this is a static file, false if dynamic or unrecognized
|
|
83
|
+
*/
|
|
84
|
+
function isStaticMetadataExtension(baseName, extension) {
|
|
85
|
+
const convention = METADATA_ROUTE_CONVENTIONS[baseName];
|
|
86
|
+
if (!convention) return false;
|
|
87
|
+
return convention.staticExtensions.includes(extension);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if a file extension represents a dynamic (code) metadata route file.
|
|
91
|
+
*
|
|
92
|
+
* @param baseName - The base file name without extension (e.g. "sitemap", "icon")
|
|
93
|
+
* @param extension - The file extension without leading dot (e.g. "ts", "tsx")
|
|
94
|
+
* @returns true if this is a dynamic file, false if static or unrecognized
|
|
95
|
+
*/
|
|
96
|
+
function isDynamicMetadataExtension(baseName, extension) {
|
|
97
|
+
const convention = METADATA_ROUTE_CONVENTIONS[baseName];
|
|
98
|
+
if (!convention) return false;
|
|
99
|
+
return convention.dynamicExtensions.includes(extension);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Classify a file name as a metadata route, or return null if it's not one.
|
|
103
|
+
*
|
|
104
|
+
* @param fileName - The full file name including extension (e.g. "sitemap.xml", "icon.tsx")
|
|
105
|
+
* @returns Classification info, or null if not a metadata route
|
|
106
|
+
*/
|
|
107
|
+
function classifyMetadataRoute(fileName) {
|
|
108
|
+
const dotIndex = fileName.lastIndexOf(".");
|
|
109
|
+
if (dotIndex === -1) return null;
|
|
110
|
+
const baseName = fileName.slice(0, dotIndex);
|
|
111
|
+
const ext = fileName.slice(dotIndex + 1);
|
|
112
|
+
const convention = METADATA_ROUTE_CONVENTIONS[baseName];
|
|
113
|
+
if (!convention) return null;
|
|
114
|
+
const isStatic = convention.staticExtensions.includes(ext);
|
|
115
|
+
const isDynamic = convention.dynamicExtensions.includes(ext);
|
|
116
|
+
if (!isStatic && !isDynamic) return null;
|
|
117
|
+
return {
|
|
118
|
+
type: convention.type,
|
|
119
|
+
contentType: convention.contentType,
|
|
120
|
+
nestable: convention.nestable
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get the default serve path for a metadata route type (using default extension
|
|
125
|
+
* for image routes). Used for auto-link generation when only the type is known.
|
|
126
|
+
*/
|
|
127
|
+
function getMetadataRouteServePath(type) {
|
|
128
|
+
for (const convention of Object.values(METADATA_ROUTE_CONVENTIONS)) if (convention.type === type) {
|
|
129
|
+
if (convention.serveExtension) return `${convention.servePath}.${convention.serveExtension}`;
|
|
130
|
+
return convention.servePath;
|
|
131
|
+
}
|
|
132
|
+
throw new Error(`[timber] Unknown metadata route type: ${type}`);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* All possible serve path segments for metadata routes (includes extension
|
|
136
|
+
* variants for image routes).
|
|
137
|
+
*/
|
|
138
|
+
var METADATA_SERVE_PATHS = /* @__PURE__ */ new Set();
|
|
139
|
+
for (const convention of Object.values(METADATA_ROUTE_CONVENTIONS)) if (convention.serveExtension) for (const ext of [...convention.staticExtensions, convention.serveExtension]) METADATA_SERVE_PATHS.add(`${convention.servePath}.${ext}`);
|
|
140
|
+
else METADATA_SERVE_PATHS.add(convention.servePath);
|
|
141
|
+
function isMetadataRouteServePath(pathname) {
|
|
142
|
+
let lastSegment = pathname.slice(pathname.lastIndexOf("/") + 1);
|
|
143
|
+
const qIdx = lastSegment.indexOf("?");
|
|
144
|
+
let query = "";
|
|
145
|
+
if (qIdx !== -1) {
|
|
146
|
+
query = lastSegment.slice(qIdx + 1);
|
|
147
|
+
lastSegment = lastSegment.slice(0, qIdx);
|
|
148
|
+
}
|
|
149
|
+
if (!METADATA_SERVE_PATHS.has(lastSegment)) return false;
|
|
150
|
+
if (/(?:^|&)(?:import|url|raw|worker|inline)(?:&|$)/.test(query)) return false;
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get the auto-link tags to inject into <head> for metadata route files
|
|
155
|
+
* discovered in a segment.
|
|
156
|
+
*
|
|
157
|
+
* Returns link tags for icon/apple-icon/manifest, and meta tags for
|
|
158
|
+
* opengraph-image (emits both og:image and twitter:image). Returns null
|
|
159
|
+
* for types that don't auto-link (favicon, sitemap, robots).
|
|
160
|
+
*
|
|
161
|
+
* @param type - The metadata route type
|
|
162
|
+
* @param href - The resolved URL path to the metadata route
|
|
163
|
+
* @returns Tag descriptor(s) for the <head>, or null if no auto-link
|
|
164
|
+
*/
|
|
165
|
+
function getMetadataRouteAutoLink(type, href) {
|
|
166
|
+
switch (type) {
|
|
167
|
+
case "icon": return [{
|
|
168
|
+
tag: "link",
|
|
169
|
+
rel: "icon",
|
|
170
|
+
href
|
|
171
|
+
}];
|
|
172
|
+
case "apple-icon": return [{
|
|
173
|
+
tag: "link",
|
|
174
|
+
rel: "apple-touch-icon",
|
|
175
|
+
href
|
|
176
|
+
}];
|
|
177
|
+
case "manifest": return [{
|
|
178
|
+
tag: "link",
|
|
179
|
+
rel: "manifest",
|
|
180
|
+
href
|
|
181
|
+
}];
|
|
182
|
+
case "opengraph-image": return [{
|
|
183
|
+
tag: "meta",
|
|
184
|
+
property: "og:image",
|
|
185
|
+
content: href
|
|
186
|
+
}, {
|
|
187
|
+
tag: "meta",
|
|
188
|
+
name: "twitter:image",
|
|
189
|
+
content: href
|
|
190
|
+
}];
|
|
191
|
+
default: return [];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/routing/segment-keys.ts
|
|
196
|
+
/**
|
|
197
|
+
* Compute tree paths for a segment chain — the directory path of each segment
|
|
198
|
+
* with slots elided, e.g. `app/(browse)/feed` → `/(browse)/feed`.
|
|
199
|
+
*
|
|
200
|
+
* This is `computeSegmentKeys` with the group branch applied to *every*
|
|
201
|
+
* segment rather than only to groups. That one difference is the whole point:
|
|
202
|
+
* `computeSegmentKeys` resets to `urlPath` at each URL-visible segment, so
|
|
203
|
+
* `(browse)/feed` and `(landing)/feed` both key as `/feed`. Two directories
|
|
204
|
+
* that render different layouts must not share an identity.
|
|
205
|
+
*
|
|
206
|
+
* Used for interception scoping (`routing/interception.ts`), where the
|
|
207
|
+
* question is "does this route pass through *that* directory?" — not "does it
|
|
208
|
+
* render this URL?". Not interchangeable with `computeSegmentKeys`: the state
|
|
209
|
+
* tree is keyed by URL on purpose, because the client caches by URL.
|
|
210
|
+
*/
|
|
211
|
+
function computeSegmentTreePaths(segments) {
|
|
212
|
+
const paths = [];
|
|
213
|
+
let prev = "";
|
|
214
|
+
for (const segment of segments) {
|
|
215
|
+
const name = segment.segmentName ?? "";
|
|
216
|
+
if (!name) {
|
|
217
|
+
paths.push("/");
|
|
218
|
+
prev = "/";
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const path = `${prev === "/" ? "" : prev}/${name}`;
|
|
222
|
+
paths.push(path);
|
|
223
|
+
prev = path;
|
|
224
|
+
}
|
|
225
|
+
return paths;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The directory names a tree path is built from — `/` is none, `/feed/(a)` is
|
|
229
|
+
* `['feed', '(a)']`.
|
|
230
|
+
*
|
|
231
|
+
* The inverse of the walk above, and it lives beside it so the format is
|
|
232
|
+
* stated once: `findChainByTreePath` (`server/children-interception.ts`) walks
|
|
233
|
+
* these names back down the tree to the directory the path addresses, and
|
|
234
|
+
* `treePathDepth` counts them. Both are readings of the same string, and a
|
|
235
|
+
* reader that disagreed with the producer about what separates two names
|
|
236
|
+
* resolves an interception to the wrong node or to none.
|
|
237
|
+
*/
|
|
238
|
+
function treePathNames(treePath) {
|
|
239
|
+
return treePath === "/" ? [] : treePath.slice(1).split("/");
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* How many directories a tree path names — `/` is 0, `/feed` is 1,
|
|
243
|
+
* `/feed/(a)` is 2.
|
|
244
|
+
*
|
|
245
|
+
* Two tree paths on a single rendered chain are strictly nested, so on that
|
|
246
|
+
* chain depth orders them totally — which is what makes it usable as "the
|
|
247
|
+
* deeper of these two directories" wherever a route passes through both
|
|
248
|
+
* (`routing/interception.ts`).
|
|
249
|
+
*/
|
|
250
|
+
function treePathDepth(treePath) {
|
|
251
|
+
return treePathNames(treePath).length;
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
254
|
+
export { getMetadataRouteAutoLink as a, isMetadataRouteServePath as c, classifyMetadataRoute as i, isStaticMetadataExtension as l, treePathDepth as n, getMetadataRouteServePath as o, METADATA_ROUTE_CONVENTIONS as r, isDynamicMetadataExtension as s, computeSegmentTreePaths as t };
|
|
255
|
+
|
|
256
|
+
//# sourceMappingURL=segment-keys-lqtdookO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment-keys-lqtdookO.js","names":[],"sources":["../../src/server/metadata-routes.ts","../../src/routing/segment-keys.ts"],"sourcesContent":["/**\n * Metadata route classification for timber.js.\n *\n * Metadata routes are file-based endpoints that generate well-known URLs for\n * crawlers and browsers (sitemap.xml, robots.txt, OG images, etc.).\n *\n * These routes run through proxy.ts but NOT through middleware.ts or access.ts —\n * they are public endpoints by nature.\n *\n * See design/16-metadata.md §\"Metadata Routes\"\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { HeadElement } from './metadata.ts';\nimport type { Metadata } from './types.ts';\nimport type { ManifestSegmentNode } from './route-matcher.ts';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Classification of a metadata route file. */\nexport interface MetadataRouteInfo {\n /** The metadata route type. */\n type: MetadataRouteType;\n /** The content type to serve this route with. */\n contentType: string;\n /** Whether this route can appear in nested segments (not just app root). */\n nestable: boolean;\n}\n\nexport type MetadataRouteType =\n | 'sitemap'\n | 'robots'\n | 'manifest'\n | 'favicon'\n | 'icon'\n | 'opengraph-image'\n | 'apple-icon';\n\n// ─── Convention Table ────────────────────────────────────────────────────────\n\n/**\n * All recognized metadata route file conventions.\n *\n * Each entry maps a base file name (without extension) to its route info.\n * The extensions determine whether the file is static or dynamic.\n *\n * Static extensions: .xml, .txt, .json, .png, .jpg, .ico, .svg\n * Dynamic extensions: .ts, .tsx\n */\nexport const METADATA_ROUTE_CONVENTIONS: Record<\n string,\n {\n type: MetadataRouteType;\n contentType: string;\n nestable: boolean;\n staticExtensions: string[];\n dynamicExtensions: string[];\n /**\n * The URL path basename this file serves at (relative to segment).\n * For image routes, the full serve path includes an extension via\n * `resolveServePathForFile()`.\n */\n servePath: string;\n /**\n * When set, image routes append `.{serveExtension}` to the serve path.\n * Dynamic handlers (`.ts`/`.tsx`) use this as the default. Static files\n * use their own extension instead. Non-image routes leave this undefined.\n */\n serveExtension?: string;\n }\n> = {\n 'sitemap': {\n type: 'sitemap',\n contentType: 'application/xml',\n nestable: true,\n staticExtensions: ['xml'],\n dynamicExtensions: ['ts'],\n servePath: 'sitemap.xml',\n },\n 'robots': {\n type: 'robots',\n contentType: 'text/plain',\n nestable: false,\n staticExtensions: ['txt'],\n dynamicExtensions: ['ts'],\n servePath: 'robots.txt',\n },\n 'manifest': {\n type: 'manifest',\n contentType: 'application/manifest+json',\n nestable: false,\n staticExtensions: ['json'],\n dynamicExtensions: ['ts'],\n servePath: 'manifest.webmanifest',\n },\n 'favicon': {\n type: 'favicon',\n contentType: 'image/x-icon',\n nestable: false,\n staticExtensions: ['ico'],\n dynamicExtensions: ['ts', 'tsx'],\n servePath: 'favicon.ico',\n },\n 'icon': {\n type: 'icon',\n contentType: 'image/*',\n nestable: true,\n staticExtensions: ['png', 'jpg', 'svg'],\n dynamicExtensions: ['ts', 'tsx'],\n servePath: 'icon',\n serveExtension: 'png',\n },\n 'opengraph-image': {\n type: 'opengraph-image',\n contentType: 'image/*',\n nestable: true,\n staticExtensions: ['png', 'jpg'],\n dynamicExtensions: ['ts', 'tsx'],\n servePath: 'opengraph-image',\n serveExtension: 'png',\n },\n\n 'apple-icon': {\n type: 'apple-icon',\n contentType: 'image/*',\n nestable: true,\n staticExtensions: ['png'],\n dynamicExtensions: ['ts', 'tsx'],\n servePath: 'apple-icon',\n serveExtension: 'png',\n },\n};\n\n// ─── MIME Type Resolution ─────────────────────────────────────────────────────\n\n/**\n * Map of file extensions to MIME types for static metadata route files.\n * Used to resolve the generic `image/*` content type for static image files.\n */\nconst EXTENSION_MIME_TYPES: Record<string, string> = {\n xml: 'application/xml',\n txt: 'text/plain',\n json: 'application/json',\n ico: 'image/x-icon',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n};\n\n/**\n * Resolve the concrete MIME type for a static metadata route file.\n *\n * For generic content types like `image/*`, this resolves to the actual\n * MIME type based on the file extension (e.g. `image/png` for `.png`).\n *\n * @param conventionContentType - The content type from the convention table (may be generic like `image/*`)\n * @param extension - The file extension without leading dot (e.g. \"png\", \"xml\")\n * @returns The resolved MIME type\n */\nexport function resolveStaticContentType(conventionContentType: string, extension: string): string {\n if (conventionContentType.includes('*')) {\n return EXTENSION_MIME_TYPES[extension] ?? 'application/octet-stream';\n }\n return conventionContentType;\n}\n\n/**\n * Check if a file extension represents a static (non-code) metadata route file.\n *\n * @param baseName - The base file name without extension (e.g. \"sitemap\", \"icon\")\n * @param extension - The file extension without leading dot (e.g. \"xml\", \"png\", \"ts\")\n * @returns true if this is a static file, false if dynamic or unrecognized\n */\nexport function isStaticMetadataExtension(baseName: string, extension: string): boolean {\n const convention = METADATA_ROUTE_CONVENTIONS[baseName];\n if (!convention) return false;\n return convention.staticExtensions.includes(extension);\n}\n\n/**\n * Check if a file extension represents a dynamic (code) metadata route file.\n *\n * @param baseName - The base file name without extension (e.g. \"sitemap\", \"icon\")\n * @param extension - The file extension without leading dot (e.g. \"ts\", \"tsx\")\n * @returns true if this is a dynamic file, false if static or unrecognized\n */\nexport function isDynamicMetadataExtension(baseName: string, extension: string): boolean {\n const convention = METADATA_ROUTE_CONVENTIONS[baseName];\n if (!convention) return false;\n return convention.dynamicExtensions.includes(extension);\n}\n\n// ─── Classification ──────────────────────────────────────────────────────────\n\n/**\n * Classify a file name as a metadata route, or return null if it's not one.\n *\n * @param fileName - The full file name including extension (e.g. \"sitemap.xml\", \"icon.tsx\")\n * @returns Classification info, or null if not a metadata route\n */\nexport function classifyMetadataRoute(fileName: string): MetadataRouteInfo | null {\n const dotIndex = fileName.lastIndexOf('.');\n if (dotIndex === -1) return null;\n\n const baseName = fileName.slice(0, dotIndex);\n const ext = fileName.slice(dotIndex + 1);\n\n const convention = METADATA_ROUTE_CONVENTIONS[baseName];\n if (!convention) return null;\n\n const isStatic = convention.staticExtensions.includes(ext);\n const isDynamic = convention.dynamicExtensions.includes(ext);\n\n if (!isStatic && !isDynamic) return null;\n\n return {\n type: convention.type,\n contentType: convention.contentType,\n nestable: convention.nestable,\n };\n}\n\n/**\n * Resolve the serve path for a metadata route file.\n *\n * For image routes (icon, opengraph-image, apple-icon), the serve path includes\n * a file extension so CDNs cache correctly:\n * - Dynamic handlers (.ts/.tsx) use the convention's `serveExtension` (default: .png)\n * - Static files use their own extension (e.g., icon.svg → icon.svg)\n *\n * Non-image routes return the convention's `servePath` as-is (already includes\n * extension: sitemap.xml, robots.txt, etc.).\n */\nexport function resolveServePathForFile(baseName: string, filePath: string): string {\n const convention = METADATA_ROUTE_CONVENTIONS[baseName];\n if (!convention) return baseName;\n\n if (!convention.serveExtension) return convention.servePath;\n\n const ext = filePath.slice(filePath.lastIndexOf('.') + 1);\n if (convention.staticExtensions.includes(ext)) {\n return `${convention.servePath}.${ext}`;\n }\n return `${convention.servePath}.${convention.serveExtension}`;\n}\n\n/**\n * Get the default serve path for a metadata route type (using default extension\n * for image routes). Used for auto-link generation when only the type is known.\n */\nexport function getMetadataRouteServePath(type: MetadataRouteType): string {\n for (const convention of Object.values(METADATA_ROUTE_CONVENTIONS)) {\n if (convention.type === type) {\n if (convention.serveExtension) {\n return `${convention.servePath}.${convention.serveExtension}`;\n }\n return convention.servePath;\n }\n }\n throw new Error(`[timber] Unknown metadata route type: ${type}`);\n}\n\n/**\n * All possible serve path segments for metadata routes (includes extension\n * variants for image routes).\n */\nconst METADATA_SERVE_PATHS = new Set<string>();\nfor (const convention of Object.values(METADATA_ROUTE_CONVENTIONS)) {\n if (convention.serveExtension) {\n for (const ext of [...convention.staticExtensions, convention.serveExtension]) {\n METADATA_SERVE_PATHS.add(`${convention.servePath}.${ext}`);\n }\n } else {\n METADATA_SERVE_PATHS.add(convention.servePath);\n }\n}\n\nexport function isMetadataRouteServePath(pathname: string): boolean {\n let lastSegment = pathname.slice(pathname.lastIndexOf('/') + 1);\n const qIdx = lastSegment.indexOf('?');\n let query = '';\n if (qIdx !== -1) {\n query = lastSegment.slice(qIdx + 1);\n lastSegment = lastSegment.slice(0, qIdx);\n }\n if (!METADATA_SERVE_PATHS.has(lastSegment)) return false;\n // Vite module requests (e.g., /src/icon.svg?import) use special query params.\n // These are source assets, not metadata routes.\n if (/(?:^|&)(?:import|url|raw|worker|inline)(?:&|$)/.test(query)) return false;\n return true;\n}\n\n/** A <link> auto-link tag. */\nexport interface AutoLinkLink {\n tag: 'link';\n rel: string;\n href: string;\n type?: string;\n}\n\n/** A <meta> auto-link tag. */\nexport interface AutoLinkMeta {\n tag: 'meta';\n property?: string;\n name?: string;\n content: string;\n}\n\nexport type AutoLinkTag = AutoLinkLink | AutoLinkMeta;\n\n/**\n * Get the auto-link tags to inject into <head> for metadata route files\n * discovered in a segment.\n *\n * Returns link tags for icon/apple-icon/manifest, and meta tags for\n * opengraph-image (emits both og:image and twitter:image). Returns null\n * for types that don't auto-link (favicon, sitemap, robots).\n *\n * @param type - The metadata route type\n * @param href - The resolved URL path to the metadata route\n * @returns Tag descriptor(s) for the <head>, or null if no auto-link\n */\nexport function getMetadataRouteAutoLink(type: MetadataRouteType, href: string): AutoLinkTag[] {\n switch (type) {\n case 'icon':\n return [{ tag: 'link', rel: 'icon', href }];\n case 'apple-icon':\n return [{ tag: 'link', rel: 'apple-touch-icon', href }];\n case 'manifest':\n return [{ tag: 'link', rel: 'manifest', href }];\n case 'opengraph-image':\n return [\n { tag: 'meta', property: 'og:image', content: href },\n { tag: 'meta', name: 'twitter:image', content: href },\n ];\n default:\n return [];\n }\n}\n\n// ─── Auto-Linking ──────────────────────────────────────────────────────────\n\n// In dev mode, use a per-startup nonce for metadata route cache busting\n// instead of per-file content hashes (avoids rehashing on every request).\nlet _devNonce: string | undefined;\nfunction getDevNonce(): string {\n _devNonce ??= randomUUID().slice(0, 8);\n return _devNonce;\n}\n\n/**\n * Collect auto-linked head elements from metadata route files in the segment chain.\n *\n * Walks each segment's metadataRoutes, resolves serve paths and URLs, and\n * emits HeadElement descriptors for <link> and <meta> tags that React Float\n * hoists into <head>.\n *\n * See design/16-metadata.md §\"Auto-Linking\"\n */\nexport function collectMetadataRouteHeadElements(\n segments: ManifestSegmentNode[],\n firstDeniedIndex: number,\n resolvedMetadata: Metadata,\n requestUrl: URL,\n metadataRouteHashes?: Record<string, string>\n): HeadElement[] {\n const elements: HeadElement[] = [];\n const hasUserOgImage = Boolean(resolvedMetadata.openGraph?.images);\n const hasUserTwitterImage = Boolean(resolvedMetadata.twitter?.images);\n const requestPathname = requestUrl.pathname;\n // In dev mode, use the request origin so OG URLs resolve to localhost.\n // In production, use metadataBase (the canonical domain).\n const ogBase =\n process.env.NODE_ENV !== 'production'\n ? new URL(requestUrl.origin)\n : resolvedMetadata.metadataBase;\n\n for (let si = 0; si < segments.length; si++) {\n const segment = segments[si];\n if (!segment.metadataRoutes) continue;\n if (si >= firstDeniedIndex) continue;\n for (const baseName of Object.keys(segment.metadataRoutes)) {\n const convention = METADATA_ROUTE_CONVENTIONS[baseName];\n if (!convention) continue;\n if (!convention.nestable && segment.urlPath !== '/') continue;\n if (convention.type === 'opengraph-image' && hasUserOgImage) continue;\n const resolvedPrefix = convention.nestable\n ? requestPathname === '/'\n ? ''\n : requestPathname\n : '';\n const metaFile = segment.metadataRoutes[baseName];\n const fileServePath = metaFile?.filePath\n ? resolveServePathForFile(baseName, metaFile.filePath)\n : convention.serveExtension\n ? `${convention.servePath}.${convention.serveExtension}`\n : convention.servePath;\n let href = `${resolvedPrefix}/${fileServePath}`;\n if (convention.type === 'opengraph-image') {\n const fileHash = metaFile?.filePath ? metadataRouteHashes?.[metaFile.filePath] : undefined;\n const cacheBust = fileHash ?? getDevNonce();\n href = `${href}?${cacheBust}`;\n }\n if (ogBase && convention.type === 'opengraph-image') {\n href = new URL(href, ogBase).toString();\n }\n for (const autoLink of getMetadataRouteAutoLink(convention.type, href)) {\n if (\n hasUserTwitterImage &&\n autoLink.tag === 'meta' &&\n 'name' in autoLink &&\n autoLink.name === 'twitter:image'\n )\n continue;\n if (autoLink.tag === 'link') {\n const attrs: Record<string, string> = { rel: autoLink.rel, href: autoLink.href };\n if (autoLink.type) attrs.type = autoLink.type;\n elements.push({ tag: 'link', attrs });\n } else {\n const attrs: Record<string, string> = { content: autoLink.content };\n if (autoLink.property) attrs.property = autoLink.property;\n if (autoLink.name) attrs.name = autoLink.name;\n elements.push({ tag: 'meta', attrs });\n }\n }\n }\n }\n return elements;\n}\n","/**\n * Segment key computation — the stable identity of a segment in the route tree.\n *\n * A segment key is the string that names a segment across the RSC/SSR/client\n * boundary: it appears in the X-Timber-State-Tree header, the X-Timber-Segments\n * header, SegmentOutlet props, the client segment cache, and (since TIM-1279)\n * interception scoping.\n *\n * This module lives in `routing/` rather than `server/` because the keys are a\n * property of the route tree itself — both the build-time scanner tree and the\n * runtime manifest tree produce identical keys for the same directory, which is\n * what lets a build-time value (an interception scope) be compared against a\n * request-time matched chain.\n *\n * See design/19-client-navigation.md §\"X-Timber-State-Tree Header\"\n */\n\n/**\n * Segment node shape expected by computeSegmentKeys.\n *\n * Structurally satisfied by both `SegmentNode` (build time) and\n * `ManifestSegmentNode` (request time) — keys depend only on the\n * URL path and the segment classification, never on file payloads.\n */\n\nimport type { CoercedParams } from '../shared/param-value.ts';\n\nexport interface SegmentKeyInput {\n urlPath: string;\n segmentName?: string;\n segmentType?: string;\n}\n\n/**\n * Compute state-tree keys for a segment chain.\n *\n * Non-group segments use their urlPath as-is. Route groups accumulate\n * ancestor group names to produce globally unique keys:\n * app/(a)/(shared)/dashboard → keys: ['/', '/(a)', '/(a)/(shared)', '/dashboard']\n *\n * **An intercepting segment switches the chain to name accumulation for good.**\n * A children-path interception (TIM-1280) puts an intercepting node and its\n * descendants into the *main* rendered chain, and their `urlPath`s are not\n * URLs: interception adds no URL depth, so `app/(browse)/(...)[artistSlug]/[year]`\n * carries `/` and `/[year]`. Keyed by urlPath the intercepting node would\n * collide with its own owner, and `[year]` with any top-level `[year]` route —\n * so a client that had one mounted would reuse the wrong cached layout. The\n * switch is sticky rather than per-node because the *descendants* are where\n * the false URLs are; the intercepting node alone is not the problem.\n *\n * This is the single source of truth for segment keys — used by the\n * element builder (skip decisions, SegmentOutlet props), segment info\n * (X-Timber-Segments header), the client cache/state tree, and\n * interception scoping (`routing/interception.ts`).\n */\nexport function computeSegmentKeys(segments: SegmentKeyInput[]): string[] {\n const keys: string[] = [];\n let prevKey = '';\n let insideIntercepting = false;\n\n for (const segment of segments) {\n if (segment.segmentType === 'intercepting') insideIntercepting = true;\n if (segment.segmentType === 'group' || insideIntercepting) {\n const base = prevKey === '/' ? '' : prevKey;\n const key = `${base}/${segment.segmentName}`;\n keys.push(key);\n prevKey = key;\n } else {\n keys.push(segment.urlPath);\n prevKey = segment.urlPath;\n }\n }\n\n return keys;\n}\n\n/**\n * Compute tree paths for a segment chain — the directory path of each segment\n * with slots elided, e.g. `app/(browse)/feed` → `/(browse)/feed`.\n *\n * This is `computeSegmentKeys` with the group branch applied to *every*\n * segment rather than only to groups. That one difference is the whole point:\n * `computeSegmentKeys` resets to `urlPath` at each URL-visible segment, so\n * `(browse)/feed` and `(landing)/feed` both key as `/feed`. Two directories\n * that render different layouts must not share an identity.\n *\n * Used for interception scoping (`routing/interception.ts`), where the\n * question is \"does this route pass through *that* directory?\" — not \"does it\n * render this URL?\". Not interchangeable with `computeSegmentKeys`: the state\n * tree is keyed by URL on purpose, because the client caches by URL.\n */\nexport function computeSegmentTreePaths(segments: SegmentKeyInput[]): string[] {\n const paths: string[] = [];\n let prev = '';\n\n for (const segment of segments) {\n const name = segment.segmentName ?? '';\n if (!name) {\n // The app root — no directory name of its own.\n paths.push('/');\n prev = '/';\n continue;\n }\n const base = prev === '/' ? '' : prev;\n const path = `${base}/${name}`;\n paths.push(path);\n prev = path;\n }\n\n return paths;\n}\n\n/**\n * The directory names a tree path is built from — `/` is none, `/feed/(a)` is\n * `['feed', '(a)']`.\n *\n * The inverse of the walk above, and it lives beside it so the format is\n * stated once: `findChainByTreePath` (`server/children-interception.ts`) walks\n * these names back down the tree to the directory the path addresses, and\n * `treePathDepth` counts them. Both are readings of the same string, and a\n * reader that disagreed with the producer about what separates two names\n * resolves an interception to the wrong node or to none.\n */\nexport function treePathNames(treePath: string): string[] {\n return treePath === '/' ? [] : treePath.slice(1).split('/');\n}\n\n/**\n * How many directories a tree path names — `/` is 0, `/feed` is 1,\n * `/feed/(a)` is 2.\n *\n * Two tree paths on a single rendered chain are strictly nested, so on that\n * chain depth orders them totally — which is what makes it usable as \"the\n * deeper of these two directories\" wherever a route passes through both\n * (`routing/interception.ts`).\n */\nexport function treePathDepth(treePath: string): number {\n return treePathNames(treePath).length;\n}\n\n/**\n * Compute a unique key for a parallel route slot.\n * Format: `{parentSegmentId}/@{slotName}`, e.g. `/@sidebar` or `/dashboard/@modal`.\n */\nexport function computeSlotKey(parentSegmentId: string, slotName: string): string {\n const name = slotName.startsWith('@') ? slotName : `@${slotName}`;\n const prefix = parentSegmentId === '/' ? '' : parentSegmentId;\n return `${prefix}/${name}`;\n}\n\n/**\n * Compute a content key for a parallel route slot.\n *\n * The content key encodes everything that determines the slot's rendered\n * output for a given navigation: the slot key (which includes the owning\n * segment's identity and the slot name), the URL parts consumed by the\n * owning segment (which determine parent params the slot page might\n * read), the matched page file (or a sentinel for `default.tsx`), and\n * the slot's own extracted params.\n *\n * The slot key prevents cross-group collisions: two route groups at the\n * same URL level each owning a `@sidebar` slot produce different keys\n * even when both fall back to `default.tsx`.\n *\n * The key is opaque to the client — it stores whatever the server sent\n * and advertises it back. The server computes the destination key and\n * checks membership. This eliminates the need for the server to\n * reconstruct the client's state from a departing URL.\n *\n * See design/07-routing.md §\"Segment Tree Diffing on Navigation\"\n */\nexport function computeSlotContentKey(\n slotKey: string,\n ownerParts: string[],\n entryFile: string | null,\n slotParams: CoercedParams\n): string {\n const owner = ownerParts.join('/');\n const entry = entryFile ?? '\\x01';\n const paramKeys = Object.keys(slotParams).sort();\n const paramParts = paramKeys.map((k) => {\n const v = slotParams[k];\n return Array.isArray(v) ? `${k}=${v.map(String).join('\\x02')}` : `${k}=${String(v)}`;\n });\n return [slotKey, owner, entry, ...paramParts].join('\\0');\n}\n"],"mappings":"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"}
|