@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":"navigation-root-mHSK9psY.js","names":[],"sources":["../../src/client/router-ref.ts","../../src/client/use-pending-navigation.ts","../../src/client/top-loader.tsx","../../src/client/navigation-root.tsx"],"sourcesContent":["// Global router reference — shared between browser-entry and client hooks.\n//\n// Delegates to client/state.ts for the actual module-level variable.\n// This ensures singleton semantics regardless of import path — all\n// callers converge on the same state.ts instance via the barrel.\n//\n// See design/18-build-system.md §\"Module Singleton Strategy\"\n\nimport type { RouterInstance } from './router-types.ts';\nimport { globalRouter, _setGlobalRouter } from './state.ts';\n\n/**\n * Set the global router instance. Called once during bootstrap.\n */\nexport function setGlobalRouter(router: RouterInstance): void {\n _setGlobalRouter(router);\n}\n\n/**\n * Get the global router instance. Throws if called before bootstrap.\n * Used by client-side hooks (usePendingNavigation, etc.)\n */\nexport function getRouter(): RouterInstance {\n if (!globalRouter) {\n throw new Error('[timber] Router not initialized. getRouter() was called before bootstrap().');\n }\n return globalRouter;\n}\n\n/**\n * Get the global router instance or null if not yet initialized.\n * Used by useRouter() methods to avoid silent failures — callers\n * can log a meaningful warning instead of silently no-oping.\n */\nexport function getRouterOrNull(): RouterInstance | null {\n return globalRouter;\n}\n\n/**\n * Reset the global router to null. Used only in tests to isolate\n * module-level state between test cases.\n * @internal\n */\nexport function resetGlobalRouter(): void {\n _setGlobalRouter(null);\n}\n","import { useSyncExternalStore } from 'react';\nimport { getRouterOrNull } from './router-ref.ts';\n\nfunction subscribe(onStoreChange: () => void): () => void {\n const router = getRouterOrNull();\n if (!router) return () => {};\n return router.onPendingChange(onStoreChange);\n}\n\nfunction getSnapshot(): boolean {\n const router = getRouterOrNull();\n return router ? router.isPending() : false;\n}\n\nconst getServerSnapshot = getSnapshot;\n\n/**\n * Returns true while an RSC navigation is in flight.\n *\n * Reads from the router's external pending store via useSyncExternalStore.\n * Only components that call this hook re-render when pending state\n * changes — no full-tree re-render.\n *\n * ```tsx\n * 'use client'\n * import { usePendingNavigation } from '@timber-js/app/client'\n *\n * export function NavBar() {\n * const isPending = usePendingNavigation()\n * return (\n * <nav className={isPending ? 'opacity-50' : ''}>\n * <Link href=\"/dashboard\">Dashboard</Link>\n * </nav>\n * )\n * }\n * ```\n */\nexport function usePendingNavigation(): boolean {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","/**\n * TopLoader — Built-in progress bar for client navigations.\n *\n * Shows an animated progress bar at the top of the viewport while an RSC\n * navigation is in flight. Injected automatically by the framework into\n * NavigationRoot — users never render this component directly.\n *\n * Configuration is via timber.config.ts `topLoader` key. Enabled by default.\n * Users who want a fully custom progress indicator disable the built-in one\n * (`topLoader: { enabled: false }`) and use `usePendingNavigation()` directly.\n *\n * Animation approach: pure CSS @keyframes. The bar crawls from 0% to ~90%\n * width over ~30s using ease-out timing. When navigation completes, the bar\n * snaps to 100% and fades out over 200ms. No JS animation loops (RAF, setInterval).\n *\n * Phase transitions are derived synchronously during render (React's\n * getDerivedStateFromProps pattern) — no useEffect needed for state tracking.\n * The finishing → hidden cleanup uses onTransitionEnd from the CSS transition.\n *\n * When delay > 0, CSS animation-delay + a visibility keyframe ensure the bar\n * stays invisible during the delay period. If navigation finishes before the\n * delay, the bar was never visible so the finish transition is also invisible.\n *\n * See design/19-client-navigation.md §\"usePendingNavigation()\"\n * See LOCAL-336 for design decisions.\n */\n\n'use client';\n\nimport { useState, createElement } from 'react';\nimport { usePendingNavigation } from './use-pending-navigation.ts';\n\n// ─── Types ───────────────────────────────────────────────────────\n\nexport interface TopLoaderConfig {\n /** Whether the top-loader is enabled. Default: true. */\n enabled?: boolean;\n /** Bar color. Default: '#2299DD'. */\n color?: string;\n /** Bar height in pixels. Default: 3. */\n height?: number;\n /** Show subtle glow/shadow effect. Default: false. */\n shadow?: boolean;\n /** Delay in ms before showing the bar. Default: 0. */\n delay?: number;\n /** CSS z-index. Default: 1600. */\n zIndex?: number;\n}\n\n// ─── Defaults ────────────────────────────────────────────────────\n\nconst DEFAULT_COLOR = '#2299DD';\nconst DEFAULT_HEIGHT = 3;\nconst DEFAULT_SHADOW = false;\nconst DEFAULT_DELAY = 0;\nconst DEFAULT_Z_INDEX = 1600;\n\n// ─── Keyframes ───────────────────────────────────────────────────\n\n// Unique keyframes name to avoid collisions with user styles.\nconst CRAWL_KEYFRAMES = '__timber_top_loader_crawl';\nconst APPEAR_KEYFRAMES = '__timber_top_loader_appear';\nconst FINISH_KEYFRAMES = '__timber_top_loader_finish';\n\n// Track whether the @keyframes rules have been injected into the document.\nlet keyframesInjected = false;\n\n/**\n * Inject the @keyframes rules into the document head once.\n * Called during render (idempotent). Uses a <style> tag so the\n * animations are available for inline-styled elements.\n */\nfunction ensureKeyframes(): void {\n if (keyframesInjected) return;\n if (typeof document === 'undefined') return;\n\n const style = document.createElement('style');\n style.textContent = `\n@keyframes ${CRAWL_KEYFRAMES} {\n 0% { width: 0%; }\n 100% { width: 90%; }\n}\n@keyframes ${APPEAR_KEYFRAMES} {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n@keyframes ${FINISH_KEYFRAMES} {\n 0% { width: 90%; opacity: 1; }\n 50% { width: 100%; opacity: 1; }\n 100% { width: 100%; opacity: 0; }\n}\n`;\n document.head.appendChild(style);\n keyframesInjected = true;\n}\n\n// ─── Component ───────────────────────────────────────────────────\n\n/**\n * Internal top-loader component. Injected by NavigationRoot.\n *\n * Reads pending navigation state from the router's external store, via\n * usePendingNavigation() — the one pending representation (TIM-1307).\n * Phase transitions are derived synchronously during render:\n *\n * hidden → crawling: when isPending becomes true\n * crawling → finishing: when isPending becomes false\n * finishing → hidden: when CSS transition ends (onTransitionEnd)\n * finishing → crawling: when isPending becomes true again\n *\n * No useEffect — all state changes are either derived during render\n * (getDerivedStateFromProps pattern) or triggered by DOM events.\n */\nexport function TopLoader({ config }: { config?: TopLoaderConfig }): React.ReactElement | null {\n // Read pending state from the router's external store via\n // useSyncExternalStore (inside usePendingNavigation). Only this\n // component re-renders when pending changes — no full-tree re-render.\n const isPending = usePendingNavigation();\n\n const color = config?.color ?? DEFAULT_COLOR;\n const height = config?.height ?? DEFAULT_HEIGHT;\n const shadow = config?.shadow ?? DEFAULT_SHADOW;\n const delay = config?.delay ?? DEFAULT_DELAY;\n const zIndex = config?.zIndex ?? DEFAULT_Z_INDEX;\n\n const [phase, setPhase] = useState<'hidden' | 'crawling' | 'finishing'>('hidden');\n\n // ─── Synchronous phase derivation (getDerivedStateFromProps) ──\n // React allows setState during render if the value changes — it\n // immediately re-renders with the updated state before committing.\n\n if (isPending && (phase === 'hidden' || phase === 'finishing')) {\n setPhase('crawling');\n }\n if (!isPending && phase === 'crawling') {\n setPhase('finishing');\n }\n\n // Inject keyframes on first visible render (idempotent)\n if (phase !== 'hidden') {\n ensureKeyframes();\n }\n\n if (phase === 'hidden') return null;\n\n // ─── Styles ──────────────────────────────────────────────────\n\n const containerStyle: React.CSSProperties = {\n position: 'fixed',\n top: 0,\n left: 0,\n width: '100%',\n height: `${height}px`,\n zIndex,\n pointerEvents: 'none',\n };\n\n const barStyle: React.CSSProperties = {\n height: '100%',\n backgroundColor: color,\n ...(phase === 'crawling'\n ? {\n // Crawl from 0% to 90% over 30s. When delay > 0, both the crawl\n // and a visibility animation are delayed — the bar stays at width 0%\n // and opacity 0 during the delay, then appears and starts crawling.\n // With delay 0, the appear animation is instant (0s duration, no delay).\n animation: [\n `${CRAWL_KEYFRAMES} 30s ease-out ${delay}ms forwards`,\n `${APPEAR_KEYFRAMES} 0s ${delay}ms both`,\n ].join(', '),\n }\n : {\n // Finishing: fill to 100% then fade out via a keyframe animation.\n // We use a keyframe instead of a CSS transition because the\n // animation-to-transition handoff is unreliable — the browser\n // may not capture the animated width as the transition's \"from\"\n // value when both the animation removal and transition are\n // applied in the same render frame.\n animation: `${FINISH_KEYFRAMES} 400ms ease forwards`,\n }),\n ...(shadow\n ? {\n boxShadow: `0 0 10px ${color}, 0 0 5px ${color}`,\n }\n : {}),\n };\n\n // Clean up the finishing phase when the finish animation completes.\n const handleAnimationEnd =\n phase === 'finishing'\n ? (e: React.AnimationEvent) => {\n if (e.animationName === FINISH_KEYFRAMES) {\n setPhase('hidden');\n }\n }\n : undefined;\n\n return createElement(\n 'div',\n {\n 'style': containerStyle,\n 'aria-hidden': 'true',\n 'data-timber-top-loader': '',\n },\n createElement('div', { style: barStyle, onAnimationEnd: handleAnimationEnd })\n );\n}\n","/**\n * NavigationRoot — the component the router renders the page through.\n *\n * It is stateless. The router owns the displayed tree and drives React with\n * `root.render(<NavigationRoot rendered={{ element, publish }} />)` inside a\n * synchronous `startTransition` (see `client/react-root.ts`). A transition\n * update keeps the committed tree on screen while the incoming one resolves,\n * instead of replacing it with a Suspense fallback — the reason this\n * component exists (TIM-1306).\n *\n * It used to hold the tree in `useState` and register `setState` closures\n * into module globals during render so the router could reach into it, with a\n * second set of stand-in closures for the window before a root existed\n * (TIM-600). Inverting that — router calls React, not the reverse — deleted\n * all of it (TIM-1431). Next.js's `use-action-queue.ts` says it wants this\n * shape and cannot have it because it must decode Flight during render;\n * timber decodes in `router-pipeline.ts`, so nothing stands in the way.\n *\n * What this component does own is **the commit-time publish**: a navigation's\n * state (segment cache, address bar, history stack, pathname) is published\n * from a layout effect keyed on the tree object, so the event that puts a\n * route on screen is the event that makes it current (TIM-1301). Props work\n * for that exactly as state did.\n *\n * This component holds no pending state. The `TopLoader` it renders and the\n * public `usePendingNavigation()` both subscribe to the router's external\n * pending store; NavigationRoot's own `pendingUrl` was a second, unread\n * representation of the same fact and is gone (TIM-1307).\n *\n * Hard navigation guard: When a hard navigation is triggered (500 error,\n * version skew), the component throws an unresolved thenable AFTER all\n * hooks to suspend forever — preventing React from rendering children\n * during page teardown. The throw must come after hooks to satisfy\n * React's rules (same hook count every render) while still preventing\n * child renders that could hit hook count mismatches in components\n * whose positions shift during teardown. This pattern is borrowed from\n * Next.js (app-router.tsx pushRef.mpaNavigation — also after hooks).\n *\n * See design/05-streaming.md §\"deferSuspenseFor\"\n * See design/19-client-navigation.md §\"NavigationContext\"\n */\n\nimport { createElement, Fragment, useLayoutEffect, useRef, type ReactNode } from 'react';\nimport { TopLoader, type TopLoaderConfig } from './top-loader.tsx';\n\n// ─── Rendered Tree ──────────────────────────────────────────────\n\n/**\n * The tree the router has handed to React, and the state publish that belongs\n * to it. They travel as one object so React's commit of the tree is the event\n * that publishes — see the effect in NavigationRoot. Every `render` builds a\n * fresh one, which is what keys that effect: a tree is published once, however\n * many times React re-runs the effect for it.\n */\nexport interface RenderedTree {\n element: ReactNode;\n /**\n * Publishes the navigation's state — segment cache, pathname, address bar,\n * history stack, and the client's record of the mounted tree — and\n * announces it to listeners outside React. Runs when React commits\n * `element`, never before (TIM-1301). Null for a render that has nothing to\n * publish on commit (hydration, the shallow search re-wrap).\n */\n publish: (() => void) | null;\n}\n\n/**\n * Hand a tree to React in a transition. `publish` runs when React commits it.\n *\n * Every path that puts a page on screen goes through one of these — a\n * navigation, a revalidation, a popstate replay, a shallow search re-wrap —\n * and it is always a synchronous `startTransition` around `root.render`.\n * The production one is `createReactRoot().render`.\n */\nexport type NavigationRender = (element: ReactNode, publish: (() => void) | null) => void;\n\n// ─── Hard Navigation Guard ──────────────────────────────────────\n\n/**\n * Module-level flag indicating a hard (MPA) navigation is in progress.\n *\n * When true:\n * - NavigationRoot throws an unresolved thenable to suspend forever,\n * preventing React from rendering children during page teardown\n * (avoids \"Rendered more hooks\" crashes).\n * - The Navigation API handler skips interception, letting the browser\n * perform a full page load (prevents infinite loops where\n * window.location.href → navigate event → router.navigate → 500 →\n * window.location.href → ...).\n *\n * Uses globalThis for singleton guarantee across chunks (same pattern\n * as NavigationContext). See design/19-client-navigation.md §\"Singleton\n * Guarantee via globalThis\".\n */\nconst HARD_NAV_KEY = Symbol.for('__timber_hard_navigating');\n\nfunction getHardNavStore(): { value: boolean } {\n const g = globalThis as Record<symbol, unknown>;\n if (!g[HARD_NAV_KEY]) {\n g[HARD_NAV_KEY] = { value: false };\n }\n return g[HARD_NAV_KEY] as { value: boolean };\n}\n\n/**\n * Set the hard-navigating flag. Call this BEFORE setting\n * window.location.href or window.location.reload() to prevent:\n * 1. React from rendering children during page teardown\n * 2. Navigation API from intercepting the hard navigation\n */\nexport function setHardNavigating(value: boolean): void {\n getHardNavStore().value = value;\n}\n\n/**\n * Check if a hard navigation is in progress.\n * Used by NavigationRoot (throw unresolvedThenable) and by the\n * Navigation API handler (skip interception).\n */\nexport function isHardNavigating(): boolean {\n return getHardNavStore().value;\n}\n\n/**\n * A thenable that never resolves. When thrown during React render,\n * it causes the component to suspend forever — React keeps the\n * old committed tree visible and never attempts to render children.\n *\n * This is the same pattern Next.js uses in app-router.tsx for MPA\n * navigations (pushRef.mpaNavigation → throw unresolvedThenable).\n */\n// for React's Suspense mechanism. Same pattern as Next.js's unresolvedThenable.\n// eslint-disable-next-line unicorn/no-thenable -- Intentionally a never-resolving thenable\nconst unresolvedThenable = { then() {} } as PromiseLike<never>;\n\n// ─── Component ───────────────────────────────────────────────────\n\n/**\n * Root component the router renders the page through.\n *\n * Renders the TopLoader alongside the tree it is given. Neither adds a DOM\n * element on the hydration path, so the tree matches the server HTML.\n *\n * Rendered only by `createReactRoot` (client/react-root.ts): hydration passes\n * `{ element, publish: null }`, and every later render is a synchronous\n * `startTransition(() => root.render(...))` with a fresh `rendered` object.\n */\nexport function NavigationRoot({\n rendered,\n topLoaderConfig,\n}: {\n rendered: RenderedTree;\n topLoaderConfig?: TopLoaderConfig;\n}): ReactNode {\n // Publish the navigation's state when React commits its tree — not when the\n // tree is handed over. A tree React is still waiting on, or one a later\n // navigation replaces before React renders it, has been *given* to React\n // without being on screen; publishing then describes a route the user never\n // saw, which is the defect this ordering exists to prevent (TIM-1301).\n //\n // A **layout** effect, so the publish lands before the browser paints and,\n // more importantly, before every descendant's passive effect. A destination\n // component that navigates from a mount effect — a redirect guard, a\n // `refresh()` on mount — would otherwise start its navigation while the\n // segment cache, address bar and pathname still described the departing\n // route, and send an X-Timber-State-Tree for a tree that is no longer\n // mounted (codex on #998).\n //\n // Descendant *layout* effects still run first: React runs layout effects\n // child-before-parent, and the only way to precede them would be a fiber\n // rendered as an earlier sibling of the payload. That is not free here —\n // `server/ssr-wrappers.tsx` mirrors this component's fiber shape so `useId`\n // agrees across hydration, and an extra sibling shifts every id in the\n // payload subtree. A layout effect that navigates on mount is the price.\n //\n // Keyed on the tree object rather than on the effect run. A publish moves\n // the address bar, which is not idempotent, so any second invocation for the\n // same tree — an effect re-run React is entitled to perform, StrictMode's\n // double-invoke — must be a no-op rather than a second history entry.\n const publishedRef = useRef<RenderedTree | null>(null);\n useLayoutEffect(() => {\n if (publishedRef.current === rendered) return;\n publishedRef.current = rendered;\n rendered.publish?.();\n }, [rendered]);\n\n // ─── Hard navigation guard ─────────────────────────────────\n // When a hard navigation is in progress (500 error, version skew),\n // suspend forever to prevent React from rendering children during\n // page teardown. This avoids \"Rendered more hooks\" crashes in\n // CHILD components whose hook counts may shift during teardown.\n //\n // CRITICAL: This throw MUST come AFTER all hooks (the useRef and\n // useLayoutEffect above). React requires the same hooks to run on every\n // render. If we threw before hooks, React would see 0 hooks on the\n // re-render vs 2 on the initial render — triggering the exact \"Rendered\n // more hooks\" error we're trying to prevent.\n //\n // By placing it after hooks but before the return, all hooks\n // satisfy React's rules, but the thrown thenable prevents any\n // children from rendering. Same pattern as Next.js app-router.tsx\n // (pushRef.mpaNavigation — also placed after all hooks).\n if (isHardNavigating()) {\n throw unresolvedThenable;\n }\n\n // Inject TopLoader alongside the element tree. It subscribes to the router's\n // pending store itself, so it takes no props from here beyond its config,\n // and only it re-renders when a navigation starts or ends. Rendered only\n // when not explicitly disabled via config.\n //\n // This Fragment is a FORK — two children — so it advances React's tree\n // context and shifts every `useId` below it. `server/ssr-wrappers.tsx`\n // mirrors it for exactly that reason; a single-child wrapper would not need\n // a mirror. See tests/ssr-wrapper-parity.test.ts.\n const showTopLoader = topLoaderConfig?.enabled !== false;\n if (!showTopLoader) return rendered.element;\n return createElement(\n Fragment,\n null,\n createElement(TopLoader, { config: topLoaderConfig }),\n rendered.element\n );\n}\n"],"mappings":";;;;;;AAcA,SAAgB,gBAAgB,QAA8B;CAC5D,iBAAiB,MAAM;AACzB;;;;;AAMA,SAAgB,YAA4B;CAC1C,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,6EAA6E;CAE/F,OAAO;AACT;;;;;;AAOA,SAAgB,kBAAyC;CACvD,OAAO;AACT;;;ACjCA,SAAS,UAAU,eAAuC;CACxD,MAAM,SAAS,gBAAgB;CAC/B,IAAI,CAAC,QAAQ,aAAa,CAAC;CAC3B,OAAO,OAAO,gBAAgB,aAAa;AAC7C;AAEA,SAAS,cAAuB;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,OAAO,SAAS,OAAO,UAAU,IAAI;AACvC;AAEA,IAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;AAuB1B,SAAgB,uBAAgC;CAC9C,OAAO,qBAAqB,WAAW,aAAa,iBAAiB;AACvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEuDA,IAAM,eAAe,OAAO,IAAI,0BAA0B;AAE1D,SAAS,kBAAsC;CAC7C,MAAM,IAAI;CACV,IAAI,CAAC,EAAE,eACL,EAAE,gBAAgB,EAAE,OAAO,MAAM;CAEnC,OAAO,EAAE;AACX;;;;;;;AAQA,SAAgB,kBAAkB,OAAsB;CACtD,gBAAgB,CAAC,CAAC,QAAQ;AAC5B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/shared/param-value.ts
|
|
2
|
+
/** The domain, for error messages. Derived, never a second hand-written list. */
|
|
3
|
+
var DOMAIN = `a string, number, boolean, bigint, null, undefined, a plain object, an array, or ${[
|
|
4
|
+
"Date",
|
|
5
|
+
"Map",
|
|
6
|
+
"Set"
|
|
7
|
+
].join("/")}`;
|
|
8
|
+
function reject(path, was, hint) {
|
|
9
|
+
throw new Error(`[timber] Segment param "${path || "(root)"}" was coerced to ${was}, which cannot cross to the client. A param value may be ${DOMAIN}.\n ${hint}\n See design/41-global-params.md §"Transport".`);
|
|
10
|
+
}
|
|
11
|
+
function describe(value) {
|
|
12
|
+
return value.constructor?.name ?? "an object";
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Deep-clone a codec's output into the canonical form, or throw.
|
|
16
|
+
*
|
|
17
|
+
* `seen` accumulates every object the walk has entered, and a second encounter
|
|
18
|
+
* is rejected. That is one rule for two things — a shared reference and a cycle
|
|
19
|
+
* are both "this object again" — and it is what keeps the result a tree.
|
|
20
|
+
*/
|
|
21
|
+
function normalizeParamValue(value, path = "") {
|
|
22
|
+
return normalize(value, path, /* @__PURE__ */ new Set());
|
|
23
|
+
}
|
|
24
|
+
function normalize(value, path, seen) {
|
|
25
|
+
if (value === null) return null;
|
|
26
|
+
const kind = typeof value;
|
|
27
|
+
if (kind === "string" || kind === "number" || kind === "boolean" || kind === "bigint") return value;
|
|
28
|
+
if (kind === "undefined") return void 0;
|
|
29
|
+
if (kind === "function") reject(path, "a function", "Return the data it would produce, not the function.");
|
|
30
|
+
if (kind === "symbol") reject(path, "a symbol", "Return a string instead — a symbol has no wire representation.");
|
|
31
|
+
const object = value;
|
|
32
|
+
if (seen.has(object)) throw new Error(`[timber] Segment param "${path || "(root)"}" is a value that already appears elsewhere in the same param — a shared reference or a cycle. A param value is a tree: React Flight carries a repeated \`Date\` by value and a repeated object by reference, so sharing would survive for some types and not others.\n Return separate values, or move the shared part outside the params.\n See design/41-global-params.md §"Transport".`);
|
|
33
|
+
seen.add(object);
|
|
34
|
+
if (Array.isArray(object)) {
|
|
35
|
+
const out = [];
|
|
36
|
+
for (let index = 0; index < object.length; index++) out.push(normalize(object[index], `${path}[${index}]`, seen));
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
if (object instanceof Date) return new Date(object.getTime());
|
|
40
|
+
if (object instanceof Map) {
|
|
41
|
+
const out = /* @__PURE__ */ new Map();
|
|
42
|
+
for (const [key, entry] of object) out.set(normalize(key, `${path}<key>`, seen), normalize(entry, `${path}.get(${keyLabel(key)})`, seen));
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
if (object instanceof Set) {
|
|
46
|
+
const out = /* @__PURE__ */ new Set();
|
|
47
|
+
let index = 0;
|
|
48
|
+
for (const entry of object) out.add(normalize(entry, `${path}[${index++}]`, seen));
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
const prototype = Object.getPrototypeOf(object);
|
|
52
|
+
if (prototype !== null && prototype !== Object.prototype) reject(path, `a ${describe(object)} instance`, "Return a plain object with the fields you need.");
|
|
53
|
+
const out = Object.create(null);
|
|
54
|
+
for (const key of Object.keys(object)) {
|
|
55
|
+
if (key === "__proto__") continue;
|
|
56
|
+
out[key] = normalize(object[key], path ? `${path}.${key}` : key, seen);
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
function keyLabel(key) {
|
|
61
|
+
return typeof key === "string" ? JSON.stringify(key) : String(key);
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { normalizeParamValue as t };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=param-value-C8TNYchQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"param-value-C8TNYchQ.js","names":[],"sources":["../../src/shared/param-value.ts"],"sourcesContent":["/**\n * The canonical form of a segment param value.\n *\n * `getSegmentParams()` on the server and `useSegmentParams()` on the client\n * must return the same value — same prototype, same own properties. This\n * module is how that is guaranteed, and the mechanism matters:\n *\n * **Both sides are images of one normalizer.** A codec's output is deep-cloned\n * into a closed canonical domain at coercion time, and *that clone* is what the\n * server returns and what goes on the wire. Server and client agree by\n * construction, because neither holds the codec's original.\n *\n * That replaces predicting what React Flight would do to an arbitrary value.\n * Prediction is what the previous design attempted and it cannot be finished:\n * the question \"will Flight's decode output be observably identical to this\n * input?\" ranges over every way a JS object can carry state that is not in its\n * serialization — own keys, enumerability, symbols, holes, accessors,\n * subclassing, exotic objects — and a `Proxy` defeats it outright, since a\n * lying `getPrototypeOf` trap makes any static check unsound. Twelve review\n * findings on PR #992 were each one more case of that set, and the set does\n * not close.\n *\n * Normalizing closes it. The only remaining question is whether Flight\n * round-trips the normalizer's *output range* — a finite domain we defined,\n * covered by `tests/e2e/segment-params.test.ts` against the real serializer.\n *\n * ## The domain\n *\n * - `undefined`, `null`, `string`, `number`, `boolean`, `bigint`\n * - null-prototype objects, own enumerable string keys only\n * - dense arrays\n * - `Date`, `Map`, `Set` — rebuilt, never the codec's instance\n *\n * ...and it is a **tree**: no value appears twice, and nothing is cyclic.\n * That is not a simplification, it is the last prediction being removed.\n * Flight encodes a `Date` by value at each occurrence but tracks plain objects\n * for reference dedup, so preserving aliasing would carry it across for some\n * types and drop it for others — and knowing which is exactly the kind of\n * guess this design exists to stop making (codex, PR #992). A tree has no\n * sharing to preserve or lose, so what Flight does about it is unobservable.\n *\n * Anything else throws, naming the param and what it was. Note what is *not*\n * a rejection: a `Date` subclass normalizes to a `Date`, a decorated array to\n * a plain one, a sparse array to a dense one, a getter to the value it\n * returned. Those used to be twelve separate checks. They are not divergences\n * any more, because the normalization happens once and both sides see its\n * result — so they need no checks at all.\n *\n * Own properties that Flight would drop (non-enumerable, symbol-keyed) are\n * dropped here instead, symmetrically. Prototype pollution is handled by the\n * same pass: `__proto__` is never copied, and every object is\n * `Object.create(null)` (design/13-security.md #36b/#36c, TIM-873).\n *\n * ## The prototype flip\n *\n * Flight refuses to serialize a null-prototype object, so the canonical form\n * cannot go on the wire as-is. `toPlainRecord` and `toNullProtoRecord` flip\n * the prototype on the way out and back. They are exact inverses and both\n * total, because they only ever see canonical values — there is nothing to\n * validate and no shape to special-case.\n *\n * See design/41-global-params.md §\"Transport\".\n */\n\n// ─── Post-coercion param types ──────────────────────────────────────────\n\n/**\n * A single segment param value after codec coercion and normalization.\n *\n * Before coercion, every param is `string | string[]` (the raw URL part).\n * After `app/schema.ts` codecs run, a param can be any value in the\n * `normalizeParamValue` domain below. This type replaces the previous\n * `string | string[]` declaration, which was a lie whenever a codec\n * produced a non-string value (TIM-1347).\n *\n * The typed accessor `getSegmentParams(SEGMENT_PATH)` resolves through\n * the schema and returns the exact type the codec declares. This type\n * covers the untyped/no-argument form and internal plumbing.\n */\nexport type CoercedParamValue =\n | string\n | number\n | boolean\n | bigint\n | null\n | undefined\n | Date\n | Map<CoercedParamValue, CoercedParamValue>\n | Set<CoercedParamValue>\n | CoercedParamValue[]\n | { [key: string]: CoercedParamValue };\n\n/**\n * A record of coerced segment params, keyed by param name.\n *\n * This is the post-coercion type for `segmentParams` throughout the\n * framework. Before coercion (route matcher output, `rawSegmentParams`),\n * the type is `Record<string, string | string[]>`.\n */\nexport type CoercedParams = Record<string, CoercedParamValue>;\n\n/** Types the canonical form rebuilds rather than rejects. */\nconst REBUILT = ['Date', 'Map', 'Set'] as const;\n\n/** The domain, for error messages. Derived, never a second hand-written list. */\nconst DOMAIN = `a string, number, boolean, bigint, null, undefined, a plain object, an array, or ${REBUILT.join('/')}`;\n\nfunction reject(path: string, was: string, hint: string): never {\n throw new Error(\n `[timber] Segment param \"${path || '(root)'}\" was coerced to ${was}, which cannot ` +\n `cross to the client. A param value may be ${DOMAIN}.\\n` +\n ` ${hint}\\n` +\n ` See design/41-global-params.md §\"Transport\".`\n );\n}\n\nfunction describe(value: object): string {\n return (value as { constructor?: { name?: string } }).constructor?.name ?? 'an object';\n}\n\n/**\n * Deep-clone a codec's output into the canonical form, or throw.\n *\n * `seen` accumulates every object the walk has entered, and a second encounter\n * is rejected. That is one rule for two things — a shared reference and a cycle\n * are both \"this object again\" — and it is what keeps the result a tree.\n */\nexport function normalizeParamValue(value: unknown, path = ''): CoercedParamValue {\n return normalize(value, path, new Set());\n}\n\nfunction normalize(value: unknown, path: string, seen: Set<object>): CoercedParamValue {\n if (value === null) return null;\n\n const kind = typeof value;\n if (kind === 'string' || kind === 'number' || kind === 'boolean' || kind === 'bigint') {\n return value as string | number | boolean | bigint;\n }\n if (kind === 'undefined') return undefined;\n if (kind === 'function') {\n reject(path, 'a function', 'Return the data it would produce, not the function.');\n }\n if (kind === 'symbol') {\n reject(path, 'a symbol', 'Return a string instead — a symbol has no wire representation.');\n }\n\n const object = value as object;\n if (seen.has(object)) {\n throw new Error(\n `[timber] Segment param \"${path || '(root)'}\" is a value that already appears ` +\n `elsewhere in the same param — a shared reference or a cycle. A param value is a ` +\n `tree: React Flight carries a repeated \\`Date\\` by value and a repeated object by ` +\n `reference, so sharing would survive for some types and not others.\\n` +\n ` Return separate values, or move the shared part outside the params.\\n` +\n ` See design/41-global-params.md §\"Transport\".`\n );\n }\n seen.add(object);\n\n if (Array.isArray(object)) {\n // Read by index, so holes become `undefined` — on both sides, which is\n // the point. A subclass and any own properties are left behind for the\n // same reason: the clone is a plain, dense array either way.\n const out: CoercedParamValue[] = [];\n for (let index = 0; index < object.length; index++) {\n out.push(normalize((object as unknown[])[index], `${path}[${index}]`, seen));\n }\n return out;\n }\n\n if (object instanceof Date) {\n // A fresh Date, so a subclass or an attached property cannot travel half\n // way and be dropped by the wire.\n return new Date(object.getTime());\n }\n\n if (object instanceof Map) {\n const out = new Map<CoercedParamValue, CoercedParamValue>();\n for (const [key, entry] of object) {\n out.set(\n normalize(key, `${path}<key>`, seen),\n normalize(entry, `${path}.get(${keyLabel(key)})`, seen)\n );\n }\n return out;\n }\n\n if (object instanceof Set) {\n const out = new Set<CoercedParamValue>();\n let index = 0;\n for (const entry of object) out.add(normalize(entry, `${path}[${index++}]`, seen));\n return out;\n }\n\n // Everything else is judged by its prototype. A `Proxy` can lie here, and\n // that is fine: whatever it answers, the clone below reads through it once\n // and both sides see the same snapshot.\n const prototype = Object.getPrototypeOf(object);\n if (prototype !== null && prototype !== Object.prototype) {\n reject(\n path,\n `a ${describe(object)} instance`,\n 'Return a plain object with the fields you need.'\n );\n }\n\n // Own *enumerable string* keys only — the rest is what Flight would drop,\n // so dropping it here keeps the two sides identical. `__proto__` is skipped\n // rather than copied: it has a language-level setter that would change the\n // prototype chain of the copy (TIM-655, TIM-855, TIM-873).\n const out: Record<string, CoercedParamValue> = Object.create(null);\n for (const key of Object.keys(object)) {\n if (key === '__proto__') continue;\n out[key] = normalize(\n (object as Record<string, unknown>)[key],\n path ? `${path}.${key}` : key,\n seen\n );\n }\n return out;\n}\n\nfunction keyLabel(key: unknown): string {\n return typeof key === 'string' ? JSON.stringify(key) : String(key);\n}\n\n// ─── Prototype flip ──────────────────────────────────────────────\n\n/**\n * Canonical form → wire form. React Flight rejects a null prototype\n * (\"Classes or null prototypes are not supported\"), so objects cross as plain\n * ones and are restored on arrival.\n */\nexport function toPlainRecord<T>(value: T): T {\n return reproto(value, {}) as T;\n}\n\n/** Wire form → canonical form. The exact inverse of `toPlainRecord`. */\nexport function toNullProtoRecord<T>(value: T): T {\n return reproto(value, null) as T;\n}\n\n/**\n * Rebuild a canonical value with objects on `proto`.\n *\n * Total by construction: its input is always canonical, so the cases are the\n * domain and nothing else. No validation, no shape it might not have seen, and\n * no cycle to guard — a canonical value is a tree. That is what moving the\n * checking to `normalizeParamValue` bought.\n */\nfunction reproto(value: unknown, proto: object | null): unknown {\n if (value === null || typeof value !== 'object') return value;\n\n const object = value as object;\n\n // A Date carries no nested values, so it crosses as itself.\n if (object instanceof Date) return object;\n\n if (Array.isArray(object)) {\n return (object as unknown[]).map((item) => reproto(item, proto));\n }\n\n if (object instanceof Map) {\n const out = new Map<unknown, unknown>();\n for (const [key, entry] of object) out.set(reproto(key, proto), reproto(entry, proto));\n return out;\n }\n\n if (object instanceof Set) {\n const out = new Set<unknown>();\n for (const entry of object) out.add(reproto(entry, proto));\n return out;\n }\n\n const out: Record<string, unknown> = proto === null ? Object.create(null) : {};\n for (const key of Object.keys(object)) {\n if (key === '__proto__') continue;\n out[key] = reproto((object as Record<string, unknown>)[key], proto);\n }\n return out;\n}\n"],"mappings":";;AAyGA,IAAM,SAAS,oFAAoF;CAHlF;CAAQ;CAAO;AAGmE,CAAA,CAAQ,KAAK,GAAG;AAEnH,SAAS,OAAO,MAAc,KAAa,MAAqB;CAC9D,MAAM,IAAI,MACR,2BAA2B,QAAQ,SAAS,mBAAmB,IAAI,2DACpB,OAAO,OAC/C,KAAK,iDAEd;AACF;AAEA,SAAS,SAAS,OAAuB;CACvC,OAAQ,MAA8C,aAAa,QAAQ;AAC7E;;;;;;;;AASA,SAAgB,oBAAoB,OAAgB,OAAO,IAAuB;CAChF,OAAO,UAAU,OAAO,sBAAM,IAAI,IAAI,CAAC;AACzC;AAEA,SAAS,UAAU,OAAgB,MAAc,MAAsC;CACrF,IAAI,UAAU,MAAM,OAAO;CAE3B,MAAM,OAAO,OAAO;CACpB,IAAI,SAAS,YAAY,SAAS,YAAY,SAAS,aAAa,SAAS,UAC3E,OAAO;CAET,IAAI,SAAS,aAAa,OAAO,KAAA;CACjC,IAAI,SAAS,YACX,OAAO,MAAM,cAAc,qDAAqD;CAElF,IAAI,SAAS,UACX,OAAO,MAAM,YAAY,gEAAgE;CAG3F,MAAM,SAAS;CACf,IAAI,KAAK,IAAI,MAAM,GACjB,MAAM,IAAI,MACR,2BAA2B,QAAQ,SAAS,6XAM9C;CAEF,KAAK,IAAI,MAAM;CAEf,IAAI,MAAM,QAAQ,MAAM,GAAG;EAIzB,MAAM,MAA2B,CAAC;EAClC,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SACzC,IAAI,KAAK,UAAW,OAAqB,QAAQ,GAAG,KAAK,GAAG,MAAM,IAAI,IAAI,CAAC;EAE7E,OAAO;CACT;CAEA,IAAI,kBAAkB,MAGpB,OAAO,IAAI,KAAK,OAAO,QAAQ,CAAC;CAGlC,IAAI,kBAAkB,KAAK;EACzB,MAAM,sBAAM,IAAI,IAA0C;EAC1D,KAAK,MAAM,CAAC,KAAK,UAAU,QACzB,IAAI,IACF,UAAU,KAAK,GAAG,KAAK,QAAQ,IAAI,GACnC,UAAU,OAAO,GAAG,KAAK,OAAO,SAAS,GAAG,EAAE,IAAI,IAAI,CACxD;EAEF,OAAO;CACT;CAEA,IAAI,kBAAkB,KAAK;EACzB,MAAM,sBAAM,IAAI,IAAuB;EACvC,IAAI,QAAQ;EACZ,KAAK,MAAM,SAAS,QAAQ,IAAI,IAAI,UAAU,OAAO,GAAG,KAAK,GAAG,QAAQ,IAAI,IAAI,CAAC;EACjF,OAAO;CACT;CAKA,MAAM,YAAY,OAAO,eAAe,MAAM;CAC9C,IAAI,cAAc,QAAQ,cAAc,OAAO,WAC7C,OACE,MACA,KAAK,SAAS,MAAM,EAAE,YACtB,iDACF;CAOF,MAAM,MAAyC,OAAO,OAAO,IAAI;CACjE,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;EACrC,IAAI,QAAQ,aAAa;EACzB,IAAI,OAAO,UACR,OAAmC,MACpC,OAAO,GAAG,KAAK,GAAG,QAAQ,KAC1B,IACF;CACF;CACA,OAAO;AACT;AAEA,SAAS,SAAS,KAAsB;CACtC,OAAO,OAAO,QAAQ,WAAW,KAAK,UAAU,GAAG,IAAI,OAAO,GAAG;AACnE"}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
+
import { parseAst } from "vite";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { performance } from "node:perf_hooks";
|
|
7
|
+
//#region src/utils/startup-timer.ts
|
|
8
|
+
/**
|
|
9
|
+
* Startup timer — records named phases with their durations.
|
|
10
|
+
*
|
|
11
|
+
* Used by the plugin system to instrument cold start and report a
|
|
12
|
+
* timing breakdown in dev mode. Zero overhead in production (disabled).
|
|
13
|
+
*
|
|
14
|
+
* See design/18-build-system.md, TIM-155.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Create a startup timer that records phase durations.
|
|
18
|
+
*/
|
|
19
|
+
function createStartupTimer() {
|
|
20
|
+
const pending = /* @__PURE__ */ new Map();
|
|
21
|
+
const phases = [];
|
|
22
|
+
return {
|
|
23
|
+
start(phase) {
|
|
24
|
+
pending.set(phase, performance.now());
|
|
25
|
+
},
|
|
26
|
+
end(phase) {
|
|
27
|
+
const startMs = pending.get(phase);
|
|
28
|
+
if (startMs === void 0) return 0;
|
|
29
|
+
pending.delete(phase);
|
|
30
|
+
const durationMs = performance.now() - startMs;
|
|
31
|
+
phases.push({
|
|
32
|
+
name: phase,
|
|
33
|
+
startMs,
|
|
34
|
+
durationMs
|
|
35
|
+
});
|
|
36
|
+
return durationMs;
|
|
37
|
+
},
|
|
38
|
+
getPhases() {
|
|
39
|
+
return [...phases].sort((a, b) => a.startMs - b.startMs);
|
|
40
|
+
},
|
|
41
|
+
totalMs() {
|
|
42
|
+
if (phases.length === 0) return 0;
|
|
43
|
+
const sorted = this.getPhases();
|
|
44
|
+
const first = sorted[0];
|
|
45
|
+
const last = sorted[sorted.length - 1];
|
|
46
|
+
return last.startMs + last.durationMs - first.startMs;
|
|
47
|
+
},
|
|
48
|
+
formatSummary() {
|
|
49
|
+
const sorted = this.getPhases();
|
|
50
|
+
if (sorted.length === 0) return "No phases recorded.";
|
|
51
|
+
const lines = sorted.map((p) => {
|
|
52
|
+
const ms = p.durationMs.toFixed(1);
|
|
53
|
+
return ` ${p.name.padEnd(30)} ${ms.padStart(8)}ms`;
|
|
54
|
+
});
|
|
55
|
+
const total = this.totalMs().toFixed(1);
|
|
56
|
+
lines.push(` ${"total".padEnd(30)} ${total.padStart(8)}ms`);
|
|
57
|
+
return ["[timber] startup timing:", ...lines].join("\n");
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* No-op timer for production builds — all methods are empty.
|
|
63
|
+
*/
|
|
64
|
+
function createNoopTimer() {
|
|
65
|
+
return {
|
|
66
|
+
start() {},
|
|
67
|
+
end() {
|
|
68
|
+
return 0;
|
|
69
|
+
},
|
|
70
|
+
getPhases() {
|
|
71
|
+
return [];
|
|
72
|
+
},
|
|
73
|
+
totalMs() {
|
|
74
|
+
return 0;
|
|
75
|
+
},
|
|
76
|
+
formatSummary() {
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/plugin-context.ts
|
|
83
|
+
/**
|
|
84
|
+
* Plugin context — internal types and helpers for timber sub-plugins.
|
|
85
|
+
*
|
|
86
|
+
* These are NOT part of the user-facing API. They are consumed by
|
|
87
|
+
* sub-plugins (routing, entries, shims, etc.) via relative imports.
|
|
88
|
+
* The root entry point (index.ts) does not re-export them.
|
|
89
|
+
*
|
|
90
|
+
* Design doc: 18-build-system.md §"Shared Plugin Context"
|
|
91
|
+
*/
|
|
92
|
+
var plugin_context_exports = /* @__PURE__ */ __exportAll({
|
|
93
|
+
DEFAULT_BUILD_DIR: () => DEFAULT_BUILD_DIR,
|
|
94
|
+
ParseMemo: () => ParseMemo,
|
|
95
|
+
configLoadHint: () => configLoadHint,
|
|
96
|
+
createPluginContext: () => createPluginContext,
|
|
97
|
+
isTimberPluginApi: () => isTimberPluginApi,
|
|
98
|
+
loadTimberConfigFile: () => loadTimberConfigFile,
|
|
99
|
+
mergeFileConfig: () => mergeFileConfig,
|
|
100
|
+
resolveAppDir: () => resolveAppDir,
|
|
101
|
+
resolveBuildDir: () => resolveBuildDir,
|
|
102
|
+
resolveClientJavascript: () => resolveClientJavascript,
|
|
103
|
+
warnConfigConflicts: () => warnConfigConflicts
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* Resolve `clientJavascript` into a fully resolved config.
|
|
107
|
+
*/
|
|
108
|
+
function resolveClientJavascript(config) {
|
|
109
|
+
if (config.clientJavascript !== void 0) {
|
|
110
|
+
if (typeof config.clientJavascript === "boolean") return {
|
|
111
|
+
disabled: !config.clientJavascript,
|
|
112
|
+
enableHMRInDev: !config.clientJavascript
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
disabled: config.clientJavascript.disabled,
|
|
116
|
+
enableHMRInDev: config.clientJavascript.enableHMRInDev ?? config.clientJavascript.disabled
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
disabled: false,
|
|
121
|
+
enableHMRInDev: false
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
var PARSE_MEMO_CAPACITY = 32;
|
|
125
|
+
/**
|
|
126
|
+
* Content-keyed LRU memo for `parseAst`. Transforms for the same module run
|
|
127
|
+
* back-to-back across plugins and environments, so a tiny window captures the
|
|
128
|
+
* wins. The returned ProgramNode is shared — callers MUST NOT mutate it.
|
|
129
|
+
*/
|
|
130
|
+
var ParseMemo = class {
|
|
131
|
+
cache = /* @__PURE__ */ new Map();
|
|
132
|
+
/**
|
|
133
|
+
* Parse code, returning a cached ProgramNode if the same code was parsed
|
|
134
|
+
* before. The returned AST MUST NOT be mutated — it may be shared across
|
|
135
|
+
* multiple consumers.
|
|
136
|
+
*/
|
|
137
|
+
parse(code) {
|
|
138
|
+
const existing = this.cache.get(code);
|
|
139
|
+
if (existing) {
|
|
140
|
+
this.cache.delete(code);
|
|
141
|
+
this.cache.set(code, existing);
|
|
142
|
+
return existing;
|
|
143
|
+
}
|
|
144
|
+
const program = parseAst(code, { lang: "tsx" });
|
|
145
|
+
if (this.cache.size >= PARSE_MEMO_CAPACITY) {
|
|
146
|
+
const firstKey = this.cache.keys().next().value;
|
|
147
|
+
this.cache.delete(firstKey);
|
|
148
|
+
}
|
|
149
|
+
this.cache.set(code, program);
|
|
150
|
+
return program;
|
|
151
|
+
}
|
|
152
|
+
get size() {
|
|
153
|
+
return this.cache.size;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
/** Narrow an unknown Vite `plugin.api` to timber's. */
|
|
157
|
+
function isTimberPluginApi(api) {
|
|
158
|
+
return typeof api === "object" && api !== null && "getContext" in api && typeof api.getContext === "function";
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Resolve the app directory. Checks (in order):
|
|
162
|
+
* 1. Explicit `configAppDir` from timber.config.ts
|
|
163
|
+
* 2. `<root>/app`
|
|
164
|
+
* 3. `<root>/src/app`
|
|
165
|
+
*
|
|
166
|
+
* Throws if none exist.
|
|
167
|
+
*/
|
|
168
|
+
function resolveAppDir(root, configAppDir) {
|
|
169
|
+
if (configAppDir) {
|
|
170
|
+
const explicit = join(root, configAppDir);
|
|
171
|
+
if (!existsSync(explicit)) throw new Error(`[timber] Configured appDir "${configAppDir}" does not exist at ${explicit}`);
|
|
172
|
+
return explicit;
|
|
173
|
+
}
|
|
174
|
+
const rootApp = join(root, "app");
|
|
175
|
+
if (existsSync(rootApp)) return rootApp;
|
|
176
|
+
const srcApp = join(root, "src", "app");
|
|
177
|
+
if (existsSync(srcApp)) return srcApp;
|
|
178
|
+
throw new Error(`[timber] Could not find app directory. Expected "app/" or "src/app/" in ${root}. You can set appDir in timber.config.ts to specify a custom location.`);
|
|
179
|
+
}
|
|
180
|
+
function createPluginContext(config, root) {
|
|
181
|
+
const projectRoot = root ?? process.cwd();
|
|
182
|
+
const resolvedConfig = { ...config };
|
|
183
|
+
return {
|
|
184
|
+
config: resolvedConfig,
|
|
185
|
+
clientJavascript: resolveClientJavascript(resolvedConfig),
|
|
186
|
+
routeTree: null,
|
|
187
|
+
appDir: join(projectRoot, "app"),
|
|
188
|
+
root: projectRoot,
|
|
189
|
+
dev: false,
|
|
190
|
+
base: "/",
|
|
191
|
+
buildManifest: null,
|
|
192
|
+
deploymentId: null,
|
|
193
|
+
timer: createStartupTimer(),
|
|
194
|
+
holdingServer: null,
|
|
195
|
+
buildDir: resolveBuildDir(projectRoot, resolvedConfig.buildDir),
|
|
196
|
+
parseCached: new ParseMemo()
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/** Default build output directory (relative to root). */
|
|
200
|
+
var DEFAULT_BUILD_DIR = join(".timber", "dist");
|
|
201
|
+
/**
|
|
202
|
+
* Resolve the build output directory.
|
|
203
|
+
*
|
|
204
|
+
* Priority:
|
|
205
|
+
* 1. Explicit `timberBuildDir` from timber.config.ts
|
|
206
|
+
* 2. Explicit `viteBuildOutDir` from Vite's build.outDir (if not the default 'dist')
|
|
207
|
+
* 3. Default: `.timber/dist`
|
|
208
|
+
*
|
|
209
|
+
* Returns an absolute path.
|
|
210
|
+
*/
|
|
211
|
+
function resolveBuildDir(root, timberBuildDir, viteBuildOutDir) {
|
|
212
|
+
if (timberBuildDir) return resolve(root, timberBuildDir);
|
|
213
|
+
if (viteBuildOutDir && viteBuildOutDir !== "dist") return resolve(root, viteBuildOutDir);
|
|
214
|
+
return join(root, DEFAULT_BUILD_DIR);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Map known timber.config load failures to actionable hints (TIM-1040).
|
|
218
|
+
* Returns null when the error has no known remedy beyond its own message.
|
|
219
|
+
*
|
|
220
|
+
* Known failure modes of loading timber.config.ts via native require():
|
|
221
|
+
* - Node < 22.18 has no default type stripping → ERR_UNKNOWN_FILE_EXTENSION
|
|
222
|
+
* - Non-erasable TS syntax (enums, namespaces, parameter properties)
|
|
223
|
+
* → ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX / ERR_INVALID_TYPESCRIPT_SYNTAX
|
|
224
|
+
* - ESM syntax in a `"type": "commonjs"` package → the stripped .ts is
|
|
225
|
+
* parsed as CJS and throws SyntaxError: "Unexpected token 'export'"
|
|
226
|
+
* (export statements) or "Cannot use import statement outside a
|
|
227
|
+
* module" (import statements)
|
|
228
|
+
*/
|
|
229
|
+
function configLoadHint(configName, err) {
|
|
230
|
+
const code = err?.code;
|
|
231
|
+
const isTs = configName.endsWith(".ts");
|
|
232
|
+
if (isTs && code === "ERR_UNKNOWN_FILE_EXTENSION") return "Loading a TypeScript config requires Node.js 22.18+ (built-in type stripping). Upgrade Node.js or rewrite the config as timber.config.js.";
|
|
233
|
+
if (code === "ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX" || code === "ERR_INVALID_TYPESCRIPT_SYNTAX") return "Node.js loads the config with type stripping, which only supports erasable TypeScript syntax — replace enums, namespaces, and constructor parameter properties with plain objects and types.";
|
|
234
|
+
if (isTs && err instanceof SyntaxError && /Unexpected token '(export|import)'|Cannot use import statement outside a module/.test(err.message)) return "The config uses ESM syntax but Node.js parsed it as CommonJS — set \"type\": \"module\" in package.json, or use module.exports instead of export default.";
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Load timber.config.ts (or .js, .mjs) from the project root.
|
|
239
|
+
* Returns the config object or null if no config file is found.
|
|
240
|
+
* Throws a descriptive error naming the file when a config file exists
|
|
241
|
+
* but fails to load — a broken config must fail loudly, never silently
|
|
242
|
+
* degrade (see TIM-1066). Known failure modes get an actionable hint
|
|
243
|
+
* appended (see configLoadHint, TIM-1040).
|
|
244
|
+
*
|
|
245
|
+
* Uses require() — Node 22.12+ can require() ESM modules, and Node
|
|
246
|
+
* 22.18+ strips types from .ts files by default (hence the engines
|
|
247
|
+
* field requiring >=22.18.0). This keeps timber() synchronous — no
|
|
248
|
+
* async config loading needed.
|
|
249
|
+
* This is the single config loader — dev, build, and preview all use it.
|
|
250
|
+
*/
|
|
251
|
+
function loadTimberConfigFile(root) {
|
|
252
|
+
const configNames = [
|
|
253
|
+
"timber.config.ts",
|
|
254
|
+
"timber.config.js",
|
|
255
|
+
"timber.config.mjs"
|
|
256
|
+
];
|
|
257
|
+
const req = createRequire(join(root, "package.json"));
|
|
258
|
+
for (const name of configNames) {
|
|
259
|
+
const configPath = join(root, name);
|
|
260
|
+
if (existsSync(configPath)) try {
|
|
261
|
+
const mod = req(configPath);
|
|
262
|
+
return mod.default ?? mod;
|
|
263
|
+
} catch (err) {
|
|
264
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
265
|
+
const hint = configLoadHint(name, err);
|
|
266
|
+
throw new Error(`[timber] Failed to load ${configPath}: ${message}${hint ? `\n${hint}` : ""}`, { cause: err });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Detect config keys set in both inline (vite.config.ts) and file (timber.config.ts)
|
|
273
|
+
* and warn the user. The `output` key is excluded because it defaults to 'server'
|
|
274
|
+
* in createPluginContext and would always appear as an inline key.
|
|
275
|
+
*
|
|
276
|
+
* Returns the list of conflicting key names (for testing).
|
|
277
|
+
*/
|
|
278
|
+
function warnConfigConflicts(inline, fileConfig) {
|
|
279
|
+
const conflicts = [];
|
|
280
|
+
for (const key of Object.keys(fileConfig)) if (key in inline && inline[key] !== void 0) conflicts.push(key);
|
|
281
|
+
if (conflicts.length > 0) console.warn(`[timber] Config conflict: ${conflicts.map((k) => `"${k}"`).join(", ")} set in both vite.config.ts (inline) and timber.config.ts. Move all config to timber.config.ts to avoid confusion. The inline value from vite.config.ts will be used.`);
|
|
282
|
+
return conflicts;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Drop own keys whose value is `undefined` so they don't clobber file
|
|
286
|
+
* config during spread merging. `timber({ buildDir: process.env.BUILD_DIR })`
|
|
287
|
+
* with the var unset must not erase the timber.config.ts value.
|
|
288
|
+
*/
|
|
289
|
+
function stripUndefined(obj) {
|
|
290
|
+
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== void 0));
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Merge file-based config (timber.config.ts) with inline config (vite.config.ts).
|
|
294
|
+
* Inline config takes precedence — file config only fills in missing fields.
|
|
295
|
+
* Inline keys explicitly set to `undefined` are treated as absent, matching
|
|
296
|
+
* the `!== undefined` check in warnConfigConflicts.
|
|
297
|
+
*/
|
|
298
|
+
function mergeFileConfig(inline, fileConfig) {
|
|
299
|
+
warnConfigConflicts(inline, fileConfig);
|
|
300
|
+
const definedInline = stripUndefined(inline);
|
|
301
|
+
return {
|
|
302
|
+
...fileConfig,
|
|
303
|
+
...definedInline,
|
|
304
|
+
...fileConfig.limits && definedInline.limits ? { limits: {
|
|
305
|
+
...fileConfig.limits,
|
|
306
|
+
...stripUndefined(definedInline.limits)
|
|
307
|
+
} } : {},
|
|
308
|
+
...fileConfig.dev && definedInline.dev ? { dev: {
|
|
309
|
+
...fileConfig.dev,
|
|
310
|
+
...stripUndefined(definedInline.dev)
|
|
311
|
+
} } : {},
|
|
312
|
+
...fileConfig.mdx && definedInline.mdx ? { mdx: {
|
|
313
|
+
...fileConfig.mdx,
|
|
314
|
+
...stripUndefined(definedInline.mdx)
|
|
315
|
+
} } : {}
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
319
|
+
export { plugin_context_exports as a, resolveClientJavascript as c, mergeFileConfig as i, createNoopTimer as l, isTimberPluginApi as n, resolveAppDir as o, loadTimberConfigFile as r, resolveBuildDir as s, createPluginContext as t };
|
|
320
|
+
|
|
321
|
+
//# sourceMappingURL=plugin-context-8idfR3UZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-context-8idfR3UZ.js","names":[],"sources":["../../src/utils/startup-timer.ts","../../src/plugin-context.ts"],"sourcesContent":["/**\n * Startup timer — records named phases with their durations.\n *\n * Used by the plugin system to instrument cold start and report a\n * timing breakdown in dev mode. Zero overhead in production (disabled).\n *\n * See design/18-build-system.md, TIM-155.\n */\n\nimport { performance } from 'node:perf_hooks';\n\nexport interface PhaseRecord {\n name: string;\n startMs: number;\n durationMs: number;\n}\n\nexport interface StartupTimer {\n /** Mark the beginning of a named phase. */\n start(phase: string): void;\n /** Mark the end of a named phase. Returns duration in ms. */\n end(phase: string): number;\n /** Get all completed phase records, ordered by start time. */\n getPhases(): PhaseRecord[];\n /** Total elapsed time from first start() to last end(). */\n totalMs(): number;\n /** Format a human-readable summary string. */\n formatSummary(): string;\n}\n\n/**\n * Create a startup timer that records phase durations.\n */\nexport function createStartupTimer(): StartupTimer {\n const pending = new Map<string, number>();\n const phases: PhaseRecord[] = [];\n\n return {\n start(phase: string): void {\n pending.set(phase, performance.now());\n },\n\n end(phase: string): number {\n const startMs = pending.get(phase);\n if (startMs === undefined) {\n return 0;\n }\n pending.delete(phase);\n const durationMs = performance.now() - startMs;\n phases.push({ name: phase, startMs, durationMs });\n return durationMs;\n },\n\n getPhases(): PhaseRecord[] {\n return [...phases].sort((a, b) => a.startMs - b.startMs);\n },\n\n totalMs(): number {\n if (phases.length === 0) return 0;\n const sorted = this.getPhases();\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n return last.startMs + last.durationMs - first.startMs;\n },\n\n formatSummary(): string {\n const sorted = this.getPhases();\n if (sorted.length === 0) return 'No phases recorded.';\n\n const lines = sorted.map((p) => {\n const ms = p.durationMs.toFixed(1);\n return ` ${p.name.padEnd(30)} ${ms.padStart(8)}ms`;\n });\n\n const total = this.totalMs().toFixed(1);\n lines.push(` ${'total'.padEnd(30)} ${total.padStart(8)}ms`);\n\n return ['[timber] startup timing:', ...lines].join('\\n');\n },\n };\n}\n\n/**\n * No-op timer for production builds — all methods are empty.\n */\nexport function createNoopTimer(): StartupTimer {\n return {\n start() {},\n end() {\n return 0;\n },\n getPhases() {\n return [];\n },\n totalMs() {\n return 0;\n },\n formatSummary() {\n return '';\n },\n };\n}\n","/**\n * Plugin context — internal types and helpers for timber sub-plugins.\n *\n * These are NOT part of the user-facing API. They are consumed by\n * sub-plugins (routing, entries, shims, etc.) via relative imports.\n * The root entry point (index.ts) does not re-export them.\n *\n * Design doc: 18-build-system.md §\"Shared Plugin Context\"\n */\n\nimport { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport { parseAst } from 'vite';\nimport type { RouteTree } from './routing/types.ts';\nimport type { BuildManifest } from './server/build-manifest.ts';\nimport type { CaptureSummary } from './server/prebuilt-builder.ts';\nimport type { StartupTimer } from './utils/startup-timer.ts';\nimport { createStartupTimer } from './utils/startup-timer.ts';\nimport type { TimberUserConfig, ClientJavascriptConfig } from './config-types.ts';\nimport type { RscManifest } from './plugins/static-build.ts';\nimport type { HoldingServer } from './dev-tools/holding-server.ts';\nimport type { ProgramNode } from './plugins/callsite-ast.ts';\n\n// Re-export for sub-plugin convenience — they import from plugin-context.ts\nexport type { TimberUserConfig, ClientJavascriptConfig } from './config-types.ts';\n\n// ── Client JavaScript config ─────────────────────────────────────────────\n\n/** Fully resolved client JavaScript configuration (no optionals). */\nexport interface ResolvedClientJavascript {\n disabled: boolean;\n enableHMRInDev: boolean;\n}\n\n/**\n * Resolve `clientJavascript` into a fully resolved config.\n */\nexport function resolveClientJavascript(config: TimberUserConfig): ResolvedClientJavascript {\n if (config.clientJavascript !== undefined) {\n if (typeof config.clientJavascript === 'boolean') {\n return {\n disabled: !config.clientJavascript,\n enableHMRInDev: !config.clientJavascript,\n };\n }\n return {\n disabled: config.clientJavascript.disabled,\n enableHMRInDev: config.clientJavascript.enableHMRInDev ?? config.clientJavascript.disabled,\n };\n }\n return { disabled: false, enableHMRInDev: false };\n}\n\n// ── Plugin Context ────────────────────────────────────────────────────────\n\n/**\n * Shared context object passed to all sub-plugins via closure.\n *\n * Sub-plugins communicate through this context — not through Vite's\n * plugin API or global state.\n * See design/18-build-system.md §\"Shared Plugin Context\".\n */\nexport interface PluginContext {\n config: TimberUserConfig;\n /** Resolved client JavaScript configuration */\n clientJavascript: ResolvedClientJavascript;\n /** The scanned route tree (populated by timber-routing, consumed by timber-entries) */\n routeTree: RouteTree | null;\n /** Absolute path to the app/ directory */\n appDir: string;\n /** Absolute path to the project root */\n root: string;\n /** Whether the dev server is running (set by timber-root-sync in configResolved) */\n dev: boolean;\n /**\n * Vite's resolved `base` (set by timber-root-sync in configResolved).\n * Always has a trailing slash; `'/'` unless the app is deployed under a\n * sub-path. Every URL the framework emits — assets, fonts, RSC payloads —\n * carries this prefix. This is the single copy: sub-plugins read it here\n * rather than capturing `config.base` in their own configResolved.\n *\n * **Availability:** written by timber-root-sync, which has no `enforce`, so\n * it is populated from `buildStart`/`load`/`generateBundle`/`configureServer`\n * onward — but NOT during the `configResolved` of an `enforce: 'pre'`\n * plugin, which Vite runs first. A pre plugin that needs the base inside\n * its own `configResolved` must read `config.base` there (timber-fonts\n * does). See TIM-1261.\n */\n base: string;\n /** CSS build manifest (populated by adapter after client build, null in dev) */\n buildManifest: BuildManifest | null;\n /** Per-build deployment ID for version skew detection (null in dev) */\n deploymentId: string | null;\n /** Startup timer for profiling cold start phases (active in dev, no-op in prod) */\n timer: StartupTimer;\n /** Holding server that binds the port during dev startup (closed in timber-dev-server) */\n holdingServer?: HoldingServer | null;\n /**\n * Resolved absolute path to the build output directory.\n *\n * Defaults to `<root>/.timber/dist`. Can be overridden via\n * `timber.config.ts` `buildDir` or Vite's `build.outDir`.\n * Timber config takes precedence when both are set.\n *\n * Used by adapter-build and cli preview.\n */\n buildDir: string;\n /**\n * Per-route client reference keys captured during the RSC build.\n * Maps absolute route file paths to the set of client reference\n * hash keys they transitively import. Used by adapter-build to\n * populate per-route modulepreload entries from clientReferenceDeps.\n */\n routeClientRefKeys?: Map<string, Set<string>>;\n /**\n * Static request-dependency verdict per segment entry file, keyed by the\n * absolute `filePath` the route scanner produced. Computed once by\n * `timber-request-dep`'s RSC `buildEnd` and serialized into\n * `buildManifest.requestDep` by `timber-build-manifest` (build only — dev\n * answers the same question through the `Symbol.for('timber:request-dep')`\n * bridge instead).\n *\n * `undefined` and `{}` are different states and the difference is the whole\n * of TIM-1300: an empty object means the analysis ran and found no segments,\n * `undefined` means it never ran, and the runtime cannot tell them apart —\n * every key is absent either way, so every segment falls to the conservative\n * `true` and nothing is ever skipped. The build fails loudly on `undefined`\n * rather than shipping that silently.\n */\n requestDepMap?: Record<string, boolean>;\n /**\n * Maps absolute module IDs of client references in non-facade RSC\n * chunks to the absolute paths of their consuming facade modules.\n * Built during the RSC `generateBundle` phase by timber-chunks,\n * consumed by `clientChunkGroup` to reclassify `shared:` modules\n * that are only used by a single route boundary.\n * See design/27-chunking-strategy.md, TIM-1107.\n */\n sharedModuleFacades?: Map<string, string[]>;\n /**\n * Module ID → prebuilt component IDs declared in it. Recorded by the\n * timber-prebuilt transform (RSC environment, production builds only),\n * consumed by the RSC `generateBundle` module-graph walk that computes\n * `routePrebuiltComponents`. See design/44-render-at-build-time.md.\n */\n prebuiltModuleComponents?: Map<string, string[]>;\n /**\n * Module ID → mapping of variable name to component ID for the prebuilt\n * components declared in that module. Used at `generateBundle` time to\n * trace imports from other modules back to specific component IDs.\n */\n prebuiltBindingNames?: Map<string, Map<string, string>>;\n /**\n * Component ID → distinct static call-site prop objects captured from\n * JSX usage sites during the transform and generateBundle phases.\n * Consumed by the post-build capture pass to render with actual props\n * instead of empty `{}`. See design/44 §Props Derivation.\n */\n prebuiltCallSiteProps?: Map<string, Record<string, unknown>[]>;\n /**\n * Route file path (page or layout, absolute) → prebuilt component IDs\n * transitively reachable from it. Computed during RSC `generateBundle`,\n * consumed by the post-build capture pass (TIM-1119) to decide which\n * components to render under which route's param combos.\n */\n routePrebuiltComponents?: Map<string, string[]>;\n /**\n * Page file paths that were desugared from `export const prerender` by\n * timber-prerender-sugar. The prebuilt transform uses this to verify\n * the generated `cache.component(...)` call was picked up.\n */\n prerenderSugarPages?: Set<string>;\n /**\n * Component ID → built chunk file name for prebuilt-declaring modules\n * that are only reachable via dynamic imports (import.meta.glob, lazy\n * routes). The capture pass imports these chunks to trigger\n * cache.component() registration before rendering. Populated during\n * RSC generateBundle alongside routePrebuiltComponents.\n */\n prebuiltLazyChunks?: Map<string, string>;\n /** Post-build prebuilt capture summary (populated by timber-prebuilt, consumed by build-report). */\n captureSummary?: CaptureSummary;\n /**\n * Content-keyed AST parse memo shared across cache/prebuilt/prerender-sugar\n * transforms. Collapses both cross-plugin and cross-environment duplicate\n * parses: identical code hits, rewritten code misses (correct because Vite\n * transforms chain — a rewrite produces different code). Bounded LRU (32\n * entries) so it doesn't hold programs for the whole build.\n *\n * Consumers MUST treat the returned ProgramNode as read-only — they collect\n * ranges and rewrite CODE via MagicString; the AST itself is never mutated.\n */\n parseCached?: ParseMemo;\n /**\n * Content-Type mappings for extensionless static API route outputs.\n * Populated during static generation, consumed by adapter-build to\n * write per-path Content-Type rules in _headers. See TIM-1241.\n */\n staticContentTypes?: Record<string, string>;\n /**\n * RSC flight payload manifest mapping unhashed → hashed URLs.\n * Populated during static generation, consumed by adapters to set\n * immutable cache headers for `_rsc/` files. See TIM-1254.\n */\n rscManifest?: RscManifest;\n}\n\n// ── AST parse memo ───────────────────────────────────────────────────────\n\nconst PARSE_MEMO_CAPACITY = 32;\n\n/**\n * Content-keyed LRU memo for `parseAst`. Transforms for the same module run\n * back-to-back across plugins and environments, so a tiny window captures the\n * wins. The returned ProgramNode is shared — callers MUST NOT mutate it.\n */\nexport class ParseMemo {\n private cache = new Map<string, ProgramNode>();\n\n /**\n * Parse code, returning a cached ProgramNode if the same code was parsed\n * before. The returned AST MUST NOT be mutated — it may be shared across\n * multiple consumers.\n */\n parse(code: string): ProgramNode {\n const existing = this.cache.get(code);\n if (existing) {\n // LRU refresh: move to end\n this.cache.delete(code);\n this.cache.set(code, existing);\n return existing;\n }\n const program = parseAst(code, { lang: 'tsx' }) as unknown as ProgramNode;\n if (this.cache.size >= PARSE_MEMO_CAPACITY) {\n // Evict oldest (first inserted)\n const firstKey = this.cache.keys().next().value!;\n this.cache.delete(firstKey);\n }\n this.cache.set(code, program);\n return program;\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n\n// ── App directory resolution ──────────────────────────────────────────────\n\n// ── Plugin API (Vite `plugin.api`) ────────────────────────────────────────\n\n/**\n * What `timber-root-sync` publishes on its Vite `plugin.api`.\n *\n * The single supported way to read timber's *resolved* configuration from\n * outside the plugin pipeline. Re-reading `timber.config.ts` is not equivalent:\n * config passed inline as `timber({ ... })` in `vite.config.ts` exists only in\n * the plugin's closure, and `root`/`appDir` are resolved against Vite's root\n * rather than the caller's cwd.\n */\nexport interface TimberPluginApi {\n /** The live plugin context. Fully populated from `configResolved` onward. */\n getContext(): PluginContext;\n}\n\n/** Narrow an unknown Vite `plugin.api` to timber's. */\nexport function isTimberPluginApi(api: unknown): api is TimberPluginApi {\n return (\n typeof api === 'object' &&\n api !== null &&\n 'getContext' in api &&\n typeof api.getContext === 'function'\n );\n}\n\n/**\n * Resolve the app directory. Checks (in order):\n * 1. Explicit `configAppDir` from timber.config.ts\n * 2. `<root>/app`\n * 3. `<root>/src/app`\n *\n * Throws if none exist.\n */\nexport function resolveAppDir(root: string, configAppDir?: string): string {\n if (configAppDir) {\n const explicit = join(root, configAppDir);\n if (!existsSync(explicit)) {\n throw new Error(`[timber] Configured appDir \"${configAppDir}\" does not exist at ${explicit}`);\n }\n return explicit;\n }\n\n const rootApp = join(root, 'app');\n if (existsSync(rootApp)) return rootApp;\n\n const srcApp = join(root, 'src', 'app');\n if (existsSync(srcApp)) return srcApp;\n\n throw new Error(\n `[timber] Could not find app directory. Expected \"app/\" or \"src/app/\" in ${root}. ` +\n `You can set appDir in timber.config.ts to specify a custom location.`\n );\n}\n\n// ── Plugin context factory ────────────────────────────────────────────────\n\nexport function createPluginContext(config?: TimberUserConfig, root?: string): PluginContext {\n const projectRoot = root ?? process.cwd();\n const resolvedConfig: TimberUserConfig = { ...config };\n return {\n config: resolvedConfig,\n clientJavascript: resolveClientJavascript(resolvedConfig),\n routeTree: null,\n appDir: join(projectRoot, 'app'),\n root: projectRoot,\n dev: false,\n base: '/',\n buildManifest: null,\n deploymentId: null,\n timer: createStartupTimer(),\n holdingServer: null,\n buildDir: resolveBuildDir(projectRoot, resolvedConfig.buildDir),\n parseCached: new ParseMemo(),\n };\n}\n\n// ── Build directory resolution ────────────────────────────────────────────\n\n/** Default build output directory (relative to root). */\nexport const DEFAULT_BUILD_DIR = join('.timber', 'dist');\n\n/**\n * Resolve the build output directory.\n *\n * Priority:\n * 1. Explicit `timberBuildDir` from timber.config.ts\n * 2. Explicit `viteBuildOutDir` from Vite's build.outDir (if not the default 'dist')\n * 3. Default: `.timber/dist`\n *\n * Returns an absolute path.\n */\nexport function resolveBuildDir(\n root: string,\n timberBuildDir?: string,\n viteBuildOutDir?: string\n): string {\n if (timberBuildDir) {\n return resolve(root, timberBuildDir);\n }\n if (viteBuildOutDir && viteBuildOutDir !== 'dist') {\n return resolve(root, viteBuildOutDir);\n }\n return join(root, DEFAULT_BUILD_DIR);\n}\n\n// ── Config file loading ───────────────────────────────────────────────────\n\n/**\n * Map known timber.config load failures to actionable hints (TIM-1040).\n * Returns null when the error has no known remedy beyond its own message.\n *\n * Known failure modes of loading timber.config.ts via native require():\n * - Node < 22.18 has no default type stripping → ERR_UNKNOWN_FILE_EXTENSION\n * - Non-erasable TS syntax (enums, namespaces, parameter properties)\n * → ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX / ERR_INVALID_TYPESCRIPT_SYNTAX\n * - ESM syntax in a `\"type\": \"commonjs\"` package → the stripped .ts is\n * parsed as CJS and throws SyntaxError: \"Unexpected token 'export'\"\n * (export statements) or \"Cannot use import statement outside a\n * module\" (import statements)\n */\nexport function configLoadHint(configName: string, err: unknown): string | null {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n const isTs = configName.endsWith('.ts');\n\n if (isTs && code === 'ERR_UNKNOWN_FILE_EXTENSION') {\n return (\n 'Loading a TypeScript config requires Node.js 22.18+ (built-in type stripping). ' +\n 'Upgrade Node.js or rewrite the config as timber.config.js.'\n );\n }\n if (code === 'ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX' || code === 'ERR_INVALID_TYPESCRIPT_SYNTAX') {\n return (\n 'Node.js loads the config with type stripping, which only supports erasable TypeScript syntax — ' +\n 'replace enums, namespaces, and constructor parameter properties with plain objects and types.'\n );\n }\n if (\n isTs &&\n err instanceof SyntaxError &&\n /Unexpected token '(export|import)'|Cannot use import statement outside a module/.test(\n err.message\n )\n ) {\n return (\n 'The config uses ESM syntax but Node.js parsed it as CommonJS — ' +\n 'set \"type\": \"module\" in package.json, or use module.exports instead of export default.'\n );\n }\n return null;\n}\n\n/**\n * Load timber.config.ts (or .js, .mjs) from the project root.\n * Returns the config object or null if no config file is found.\n * Throws a descriptive error naming the file when a config file exists\n * but fails to load — a broken config must fail loudly, never silently\n * degrade (see TIM-1066). Known failure modes get an actionable hint\n * appended (see configLoadHint, TIM-1040).\n *\n * Uses require() — Node 22.12+ can require() ESM modules, and Node\n * 22.18+ strips types from .ts files by default (hence the engines\n * field requiring >=22.18.0). This keeps timber() synchronous — no\n * async config loading needed.\n * This is the single config loader — dev, build, and preview all use it.\n */\nexport function loadTimberConfigFile(root: string): TimberUserConfig | null {\n const configNames = ['timber.config.ts', 'timber.config.js', 'timber.config.mjs'];\n const req = createRequire(join(root, 'package.json'));\n\n for (const name of configNames) {\n const configPath = join(root, name);\n if (existsSync(configPath)) {\n try {\n const mod = req(configPath);\n return (mod.default ?? mod) as TimberUserConfig;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const hint = configLoadHint(name, err);\n throw new Error(\n `[timber] Failed to load ${configPath}: ${message}${hint ? `\\n${hint}` : ''}`,\n { cause: err }\n );\n }\n }\n }\n return null;\n}\n\n/**\n * Detect config keys set in both inline (vite.config.ts) and file (timber.config.ts)\n * and warn the user. The `output` key is excluded because it defaults to 'server'\n * in createPluginContext and would always appear as an inline key.\n *\n * Returns the list of conflicting key names (for testing).\n */\nexport function warnConfigConflicts(\n inline: TimberUserConfig,\n fileConfig: TimberUserConfig\n): string[] {\n const conflicts: string[] = [];\n for (const key of Object.keys(fileConfig) as (keyof TimberUserConfig)[]) {\n if (key in inline && inline[key] !== undefined) {\n conflicts.push(key);\n }\n }\n if (conflicts.length > 0) {\n console.warn(\n `[timber] Config conflict: ${conflicts.map((k) => `\"${k}\"`).join(', ')} set in both ` +\n `vite.config.ts (inline) and timber.config.ts. ` +\n `Move all config to timber.config.ts to avoid confusion. ` +\n `The inline value from vite.config.ts will be used.`\n );\n }\n return conflicts;\n}\n\n/**\n * Drop own keys whose value is `undefined` so they don't clobber file\n * config during spread merging. `timber({ buildDir: process.env.BUILD_DIR })`\n * with the var unset must not erase the timber.config.ts value.\n */\nfunction stripUndefined<T extends object>(obj: T): T {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as T;\n}\n\n/**\n * Merge file-based config (timber.config.ts) with inline config (vite.config.ts).\n * Inline config takes precedence — file config only fills in missing fields.\n * Inline keys explicitly set to `undefined` are treated as absent, matching\n * the `!== undefined` check in warnConfigConflicts.\n */\nexport function mergeFileConfig(\n inline: TimberUserConfig,\n fileConfig: TimberUserConfig\n): TimberUserConfig {\n warnConfigConflicts(inline, fileConfig);\n const definedInline = stripUndefined(inline);\n\n return {\n ...fileConfig,\n ...definedInline,\n ...(fileConfig.limits && definedInline.limits\n ? { limits: { ...fileConfig.limits, ...stripUndefined(definedInline.limits) } }\n : {}),\n ...(fileConfig.dev && definedInline.dev\n ? { dev: { ...fileConfig.dev, ...stripUndefined(definedInline.dev) } }\n : {}),\n ...(fileConfig.mdx && definedInline.mdx\n ? { mdx: { ...fileConfig.mdx, ...stripUndefined(definedInline.mdx) } }\n : {}),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiCA,SAAgB,qBAAmC;CACjD,MAAM,0BAAU,IAAI,IAAoB;CACxC,MAAM,SAAwB,CAAC;CAE/B,OAAO;EACL,MAAM,OAAqB;GACzB,QAAQ,IAAI,OAAO,YAAY,IAAI,CAAC;EACtC;EAEA,IAAI,OAAuB;GACzB,MAAM,UAAU,QAAQ,IAAI,KAAK;GACjC,IAAI,YAAY,KAAA,GACd,OAAO;GAET,QAAQ,OAAO,KAAK;GACpB,MAAM,aAAa,YAAY,IAAI,IAAI;GACvC,OAAO,KAAK;IAAE,MAAM;IAAO;IAAS;GAAW,CAAC;GAChD,OAAO;EACT;EAEA,YAA2B;GACzB,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;EACzD;EAEA,UAAkB;GAChB,IAAI,OAAO,WAAW,GAAG,OAAO;GAChC,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,QAAQ,OAAO;GACrB,MAAM,OAAO,OAAO,OAAO,SAAS;GACpC,OAAO,KAAK,UAAU,KAAK,aAAa,MAAM;EAChD;EAEA,gBAAwB;GACtB,MAAM,SAAS,KAAK,UAAU;GAC9B,IAAI,OAAO,WAAW,GAAG,OAAO;GAEhC,MAAM,QAAQ,OAAO,KAAK,MAAM;IAC9B,MAAM,KAAK,EAAE,WAAW,QAAQ,CAAC;IACjC,OAAO,KAAK,EAAE,KAAK,OAAO,EAAE,EAAE,GAAG,GAAG,SAAS,CAAC,EAAE;GAClD,CAAC;GAED,MAAM,QAAQ,KAAK,QAAQ,CAAC,CAAC,QAAQ,CAAC;GACtC,MAAM,KAAK,KAAK,QAAQ,OAAO,EAAE,EAAE,GAAG,MAAM,SAAS,CAAC,EAAE,GAAG;GAE3D,OAAO,CAAC,4BAA4B,GAAG,KAAK,CAAC,CAAC,KAAK,IAAI;EACzD;CACF;AACF;;;;AAKA,SAAgB,kBAAgC;CAC9C,OAAO;EACL,QAAQ,CAAC;EACT,MAAM;GACJ,OAAO;EACT;EACA,YAAY;GACV,OAAO,CAAC;EACV;EACA,UAAU;GACR,OAAO;EACT;EACA,gBAAgB;GACd,OAAO;EACT;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/DA,SAAgB,wBAAwB,QAAoD;CAC1F,IAAI,OAAO,qBAAqB,KAAA,GAAW;EACzC,IAAI,OAAO,OAAO,qBAAqB,WACrC,OAAO;GACL,UAAU,CAAC,OAAO;GAClB,gBAAgB,CAAC,OAAO;EAC1B;EAEF,OAAO;GACL,UAAU,OAAO,iBAAiB;GAClC,gBAAgB,OAAO,iBAAiB,kBAAkB,OAAO,iBAAiB;EACpF;CACF;CACA,OAAO;EAAE,UAAU;EAAO,gBAAgB;CAAM;AAClD;AA8JA,IAAM,sBAAsB;;;;;;AAO5B,IAAa,YAAb,MAAuB;CACrB,wBAAgB,IAAI,IAAyB;;;;;;CAO7C,MAAM,MAA2B;EAC/B,MAAM,WAAW,KAAK,MAAM,IAAI,IAAI;EACpC,IAAI,UAAU;GAEZ,KAAK,MAAM,OAAO,IAAI;GACtB,KAAK,MAAM,IAAI,MAAM,QAAQ;GAC7B,OAAO;EACT;EACA,MAAM,UAAU,SAAS,MAAM,EAAE,MAAM,MAAM,CAAC;EAC9C,IAAI,KAAK,MAAM,QAAQ,qBAAqB;GAE1C,MAAM,WAAW,KAAK,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;GAC1C,KAAK,MAAM,OAAO,QAAQ;EAC5B;EACA,KAAK,MAAM,IAAI,MAAM,OAAO;EAC5B,OAAO;CACT;CAEA,IAAI,OAAe;EACjB,OAAO,KAAK,MAAM;CACpB;AACF;;AAqBA,SAAgB,kBAAkB,KAAsC;CACtE,OACE,OAAO,QAAQ,YACf,QAAQ,QACR,gBAAgB,OAChB,OAAO,IAAI,eAAe;AAE9B;;;;;;;;;AAUA,SAAgB,cAAc,MAAc,cAA+B;CACzE,IAAI,cAAc;EAChB,MAAM,WAAW,KAAK,MAAM,YAAY;EACxC,IAAI,CAAC,WAAW,QAAQ,GACtB,MAAM,IAAI,MAAM,+BAA+B,aAAa,sBAAsB,UAAU;EAE9F,OAAO;CACT;CAEA,MAAM,UAAU,KAAK,MAAM,KAAK;CAChC,IAAI,WAAW,OAAO,GAAG,OAAO;CAEhC,MAAM,SAAS,KAAK,MAAM,OAAO,KAAK;CACtC,IAAI,WAAW,MAAM,GAAG,OAAO;CAE/B,MAAM,IAAI,MACR,2EAA2E,KAAK,uEAElF;AACF;AAIA,SAAgB,oBAAoB,QAA2B,MAA8B;CAC3F,MAAM,cAAc,QAAQ,QAAQ,IAAI;CACxC,MAAM,iBAAmC,EAAE,GAAG,OAAO;CACrD,OAAO;EACL,QAAQ;EACR,kBAAkB,wBAAwB,cAAc;EACxD,WAAW;EACX,QAAQ,KAAK,aAAa,KAAK;EAC/B,MAAM;EACN,KAAK;EACL,MAAM;EACN,eAAe;EACf,cAAc;EACd,OAAO,mBAAmB;EAC1B,eAAe;EACf,UAAU,gBAAgB,aAAa,eAAe,QAAQ;EAC9D,aAAa,IAAI,UAAU;CAC7B;AACF;;AAKA,IAAa,oBAAoB,KAAK,WAAW,MAAM;;;;;;;;;;;AAYvD,SAAgB,gBACd,MACA,gBACA,iBACQ;CACR,IAAI,gBACF,OAAO,QAAQ,MAAM,cAAc;CAErC,IAAI,mBAAmB,oBAAoB,QACzC,OAAO,QAAQ,MAAM,eAAe;CAEtC,OAAO,KAAK,MAAM,iBAAiB;AACrC;;;;;;;;;;;;;;AAiBA,SAAgB,eAAe,YAAoB,KAA6B;CAC9E,MAAM,OAAQ,KAAsC;CACpD,MAAM,OAAO,WAAW,SAAS,KAAK;CAEtC,IAAI,QAAQ,SAAS,8BACnB,OACE;CAIJ,IAAI,SAAS,uCAAuC,SAAS,iCAC3D,OACE;CAIJ,IACE,QACA,eAAe,eACf,kFAAkF,KAChF,IAAI,OACN,GAEA,OACE;CAIJ,OAAO;AACT;;;;;;;;;;;;;;;AAgBA,SAAgB,qBAAqB,MAAuC;CAC1E,MAAM,cAAc;EAAC;EAAoB;EAAoB;CAAmB;CAChF,MAAM,MAAM,cAAc,KAAK,MAAM,cAAc,CAAC;CAEpD,KAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,aAAa,KAAK,MAAM,IAAI;EAClC,IAAI,WAAW,UAAU,GACvB,IAAI;GACF,MAAM,MAAM,IAAI,UAAU;GAC1B,OAAQ,IAAI,WAAW;EACzB,SAAS,KAAK;GACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAC/D,MAAM,OAAO,eAAe,MAAM,GAAG;GACrC,MAAM,IAAI,MACR,2BAA2B,WAAW,IAAI,UAAU,OAAO,KAAK,SAAS,MACzE,EAAE,OAAO,IAAI,CACf;EACF;CAEJ;CACA,OAAO;AACT;;;;;;;;AASA,SAAgB,oBACd,QACA,YACU;CACV,MAAM,YAAsB,CAAC;CAC7B,KAAK,MAAM,OAAO,OAAO,KAAK,UAAU,GACtC,IAAI,OAAO,UAAU,OAAO,SAAS,KAAA,GACnC,UAAU,KAAK,GAAG;CAGtB,IAAI,UAAU,SAAS,GACrB,QAAQ,KACN,6BAA6B,UAAU,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,sKAIzE;CAEF,OAAO;AACT;;;;;;AAOA,SAAS,eAAiC,KAAW;CACnD,OAAO,OAAO,YAAY,OAAO,QAAQ,GAAG,CAAC,CAAC,QAAQ,GAAG,OAAO,MAAM,KAAA,CAAS,CAAC;AAClF;;;;;;;AAQA,SAAgB,gBACd,QACA,YACkB;CAClB,oBAAoB,QAAQ,UAAU;CACtC,MAAM,gBAAgB,eAAe,MAAM;CAE3C,OAAO;EACL,GAAG;EACH,GAAG;EACH,GAAI,WAAW,UAAU,cAAc,SACnC,EAAE,QAAQ;GAAE,GAAG,WAAW;GAAQ,GAAG,eAAe,cAAc,MAAM;EAAE,EAAE,IAC5E,CAAC;EACL,GAAI,WAAW,OAAO,cAAc,MAChC,EAAE,KAAK;GAAE,GAAG,WAAW;GAAK,GAAG,eAAe,cAAc,GAAG;EAAE,EAAE,IACnE,CAAC;EACL,GAAI,WAAW,OAAO,cAAc,MAChC,EAAE,KAAK;GAAE,GAAG,WAAW;GAAK,GAAG,eAAe,cAAc,GAAG;EAAE,EAAE,IACnE,CAAC;CACP;AACF"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { isBuiltin } from "node:module";
|
|
2
|
+
//#region src/analyze/poison-rules.ts
|
|
3
|
+
/**
|
|
4
|
+
* poison-rules — single source of truth for server-only / client-only
|
|
5
|
+
* module rules.
|
|
6
|
+
*
|
|
7
|
+
* Two tiers with different enforcement policies (design/47 §3):
|
|
8
|
+
*
|
|
9
|
+
* 1. **Explicit markers** (`server-only`, `client-only`) — evaluation-time
|
|
10
|
+
* poison pills. `plugins/shims.ts` resolves them to virtual modules
|
|
11
|
+
* whose body is a top-level `throw` in the wrong environment and a
|
|
12
|
+
* silent no-op in the right one. The error fires when the module is
|
|
13
|
+
* evaluated, not at resolve time.
|
|
14
|
+
*
|
|
15
|
+
* 2. **Inferred rules** (`node:*` imports, timber's ALS modules, browser
|
|
16
|
+
* globals) — report-only. They have legitimate false positives
|
|
17
|
+
* (`import.meta.env.SSR`-guarded `node:*` use, conditionally-imported
|
|
18
|
+
* packages), so erroring the build on them would refuse working apps.
|
|
19
|
+
* The `timber graph` reporter surfaces them as hints.
|
|
20
|
+
*
|
|
21
|
+
* Both shims.ts and the reporter consume this module so the two surfaces
|
|
22
|
+
* can never disagree. Promoting inferred rules to build errors is a
|
|
23
|
+
* policy flip on this list, never a new rule set.
|
|
24
|
+
*
|
|
25
|
+
* Design doc: 47-module-environment-tooling.md §3.
|
|
26
|
+
*/
|
|
27
|
+
var EXPLICIT_MARKERS = [{
|
|
28
|
+
specifier: "server-only",
|
|
29
|
+
virtualId: "\0timber:server-only",
|
|
30
|
+
violatesIn: (env) => env === "client",
|
|
31
|
+
errorMessage: "This module cannot be imported from a Client Component module. It should only be used from a Server Component.",
|
|
32
|
+
enforcement: "poison-pill"
|
|
33
|
+
}, {
|
|
34
|
+
specifier: "client-only",
|
|
35
|
+
virtualId: "\0timber:client-only",
|
|
36
|
+
violatesIn: (env) => env !== "client",
|
|
37
|
+
errorMessage: "This module cannot be imported from a Server Component module. It should only be used from a Client Component.",
|
|
38
|
+
enforcement: "poison-pill"
|
|
39
|
+
}];
|
|
40
|
+
/**
|
|
41
|
+
* Look up an explicit marker by its import specifier. Throws on an
|
|
42
|
+
* unknown specifier — callers reference rules that must exist, and a
|
|
43
|
+
* silent undefined would just defer the failure.
|
|
44
|
+
*/
|
|
45
|
+
function markerFor(specifier) {
|
|
46
|
+
const marker = EXPLICIT_MARKERS.find((m) => m.specifier === specifier);
|
|
47
|
+
if (!marker) throw new Error(`[timber] unknown poison marker: ${specifier}`);
|
|
48
|
+
return marker;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Generate the virtual module body for an explicit marker in `env`:
|
|
52
|
+
* a top-level throw in the wrong environment, a no-op otherwise.
|
|
53
|
+
*/
|
|
54
|
+
function poisonPillSource(marker, env) {
|
|
55
|
+
if (marker.violatesIn(env)) return `throw new Error(${JSON.stringify(marker.errorMessage)});`;
|
|
56
|
+
return "export {};";
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Timber modules that hold per-request AsyncLocalStorage state. Importing
|
|
60
|
+
* one from client-reachable code is a strong server-only signal — cf. the
|
|
61
|
+
* no-server-imports-in-isomorphic-define-modules rule.
|
|
62
|
+
*/
|
|
63
|
+
var ALS_MODULE_SPECIFIERS = /* @__PURE__ */ new Set([
|
|
64
|
+
"@timber-js/app/server",
|
|
65
|
+
"@timber-js/app/server/internal",
|
|
66
|
+
"#server-internal"
|
|
67
|
+
]);
|
|
68
|
+
/**
|
|
69
|
+
* The ALS registry module itself, as it appears in import sources.
|
|
70
|
+
* Framework code imports it ESM-style with a `.js` specifier — both
|
|
71
|
+
* `../server/als-registry.js` and sibling `./als-registry.js` forms
|
|
72
|
+
* exist throughout src/server — while resolved module ids carry `.ts`.
|
|
73
|
+
* Matching any path ending in the basename is deliberate: the rule is
|
|
74
|
+
* report-only, and a user file coincidentally named als-registry is a
|
|
75
|
+
* far rarer event than a missed hint on the real one.
|
|
76
|
+
*/
|
|
77
|
+
var ALS_REGISTRY_SUFFIX = /(?:^|\/)als-registry\.(?:ts|js)$/;
|
|
78
|
+
var INFERRED_RULES = [
|
|
79
|
+
{
|
|
80
|
+
id: "node-builtin-import",
|
|
81
|
+
implies: "server-only",
|
|
82
|
+
enforcement: "report-only",
|
|
83
|
+
description: "imports a node:* built-in module",
|
|
84
|
+
matchesImport: (specifier) => specifier.startsWith("node:") && isBuiltin(specifier)
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "timber-als-module",
|
|
88
|
+
implies: "server-only",
|
|
89
|
+
enforcement: "report-only",
|
|
90
|
+
description: "imports timber's per-request AsyncLocalStorage modules",
|
|
91
|
+
matchesImport: (specifier) => ALS_MODULE_SPECIFIERS.has(specifier) || ALS_REGISTRY_SUFFIX.test(specifier)
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "browser-global",
|
|
95
|
+
implies: "client-only",
|
|
96
|
+
enforcement: "report-only",
|
|
97
|
+
description: "references a browser-only global",
|
|
98
|
+
identifiers: [
|
|
99
|
+
"window",
|
|
100
|
+
"document",
|
|
101
|
+
"navigator",
|
|
102
|
+
"localStorage",
|
|
103
|
+
"sessionStorage"
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
];
|
|
107
|
+
//#endregion
|
|
108
|
+
export { poisonPillSource as i, INFERRED_RULES as n, markerFor as r, EXPLICIT_MARKERS as t };
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=poison-rules-DoEhbqaY.js.map
|