@timber-js/app 0.2.0-alpha.9 → 0.2.0-alpha.91
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/dist/_chunks/actions-DLnUaR65.js +421 -0
- package/dist/_chunks/actions-DLnUaR65.js.map +1 -0
- package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-HS0LGUl2.js} +1 -1
- package/dist/_chunks/als-registry-HS0LGUl2.js.map +1 -0
- package/dist/_chunks/chunk-BYIpzuS7.js +39 -0
- package/dist/_chunks/{debug-gwlJkDuf.js → debug-ECi_61pb.js} +2 -2
- package/dist/_chunks/debug-ECi_61pb.js.map +1 -0
- package/dist/_chunks/define-C77ScO0m.js +106 -0
- package/dist/_chunks/define-C77ScO0m.js.map +1 -0
- package/dist/_chunks/define-Itxvcd7F.js +199 -0
- package/dist/_chunks/define-Itxvcd7F.js.map +1 -0
- package/dist/_chunks/define-cookie-BowvzoP0.js +94 -0
- package/dist/_chunks/define-cookie-BowvzoP0.js.map +1 -0
- package/dist/_chunks/{format-DviM89f0.js → dev-warnings-DpGRGoDi.js} +5 -44
- package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +1 -0
- package/dist/_chunks/format-CYBGxKtc.js +14 -0
- package/dist/_chunks/format-CYBGxKtc.js.map +1 -0
- package/dist/_chunks/{interception-BOoWmLUA.js → interception-ErnB33JX.js} +301 -133
- package/dist/_chunks/interception-ErnB33JX.js.map +1 -0
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js +41 -0
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-DS3eKNmf.js} +1 -1
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-DS3eKNmf.js.map} +1 -1
- package/dist/_chunks/request-context-CK5tZqIP.js +478 -0
- package/dist/_chunks/request-context-CK5tZqIP.js.map +1 -0
- package/dist/_chunks/schema-bridge-C3xl_vfb.js +86 -0
- package/dist/_chunks/schema-bridge-C3xl_vfb.js.map +1 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js +65 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js.map +1 -0
- package/dist/_chunks/segment-context-fHFLF1PE.js +34 -0
- package/dist/_chunks/segment-context-fHFLF1PE.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-DzuI0bIV.js} +1 -1
- package/dist/_chunks/{ssr-data-MjmprTmO.js.map → ssr-data-DzuI0bIV.js.map} +1 -1
- package/dist/_chunks/stale-reload-BX5gL1r-.js +64 -0
- package/dist/_chunks/stale-reload-BX5gL1r-.js.map +1 -0
- package/dist/_chunks/{tracing-CemImE6h.js → tracing-CCYbKn5n.js} +60 -9
- package/dist/_chunks/tracing-CCYbKn5n.js.map +1 -0
- package/dist/_chunks/use-params-Br9YSUFV.js +295 -0
- package/dist/_chunks/use-params-Br9YSUFV.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-BiV5GJgm.js} +7 -4
- package/dist/_chunks/use-query-states-BiV5GJgm.js.map +1 -0
- package/dist/adapters/cloudflare-dev.d.ts +109 -0
- package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +73 -0
- package/dist/adapters/cloudflare-dev.js.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +95 -0
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +148 -12
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +135 -11
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +17 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +56 -13
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/cache/cache-api.d.ts +24 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/handler-store.d.ts +31 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +23 -7
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +142 -80
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/singleflight.d.ts +18 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts +22 -0
- package/dist/cache/sizeof.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cli.d.ts +6 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +27 -1
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
- package/dist/client/browser-entry/hmr.d.ts +21 -0
- package/dist/client/browser-entry/hmr.d.ts.map +1 -0
- package/dist/client/browser-entry/hydrate.d.ts +46 -0
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
- package/dist/client/browser-entry/index.d.ts +30 -0
- package/dist/client/browser-entry/index.d.ts.map +1 -0
- package/dist/client/browser-entry/post-hydration.d.ts +26 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +23 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +19 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +12 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +10 -4
- package/dist/client/error-boundary.js.map +1 -1
- package/dist/client/error-reconstituter.d.ts +54 -0
- package/dist/client/error-reconstituter.d.ts.map +1 -0
- package/dist/client/form.d.ts +6 -3
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/history.d.ts +19 -4
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +9 -21
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +229 -1018
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +18 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +890 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link-pending-store.d.ts +63 -0
- package/dist/client/link-pending-store.d.ts.map +1 -0
- package/dist/client/link.d.ts +62 -55
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/nav-link-store.d.ts +36 -0
- package/dist/client/nav-link-store.d.ts.map +1 -0
- package/dist/client/navigation-api-types.d.ts +90 -0
- package/dist/client/navigation-api-types.d.ts.map +1 -0
- package/dist/client/navigation-api.d.ts +115 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +13 -2
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/router-ref.d.ts +1 -1
- package/dist/client/router.d.ts +70 -4
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +38 -3
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +1 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +63 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +13 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-reload.d.ts +15 -0
- package/dist/client/stale-reload.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +5 -5
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/use-link-status.d.ts +5 -5
- package/dist/client/use-link-status.d.ts.map +1 -1
- package/dist/client/use-params.d.ts +6 -4
- package/dist/client/use-params.d.ts.map +1 -1
- package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
- package/dist/client/use-pending-navigation.d.ts.map +1 -0
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +1 -1
- package/dist/codec.d.ts +33 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +2 -0
- package/dist/config-types.d.ts +266 -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/content/index.d.ts +1 -10
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +0 -2
- package/dist/cookies/define-cookie.d.ts +35 -14
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -83
- package/dist/fonts/bundle.d.ts +48 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/css.d.ts +1 -0
- 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/pipeline.d.ts +138 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +72 -0
- package/dist/fonts/transform.d.ts.map +1 -0
- package/dist/fonts/types.d.ts +45 -1
- package/dist/fonts/types.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts +59 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +45 -190
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4294 -2453
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +107 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +1 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +2 -2
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +3 -3
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +32 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/content.d.ts +1 -1
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/dev-404-page.d.ts +56 -0
- package/dist/plugins/dev-404-page.d.ts.map +1 -0
- package/dist/plugins/dev-browser-logs.d.ts +84 -0
- package/dist/plugins/dev-browser-logs.d.ts.map +1 -0
- package/dist/plugins/dev-error-overlay.d.ts +49 -9
- package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
- package/dist/plugins/dev-error-page.d.ts +58 -0
- package/dist/plugins/dev-error-page.d.ts.map +1 -0
- package/dist/plugins/dev-logs.d.ts +1 -1
- package/dist/plugins/dev-logs.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/dev-terminal-error.d.ts +28 -0
- package/dist/plugins/dev-terminal-error.d.ts.map +1 -0
- package/dist/plugins/entries.d.ts +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +17 -73
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +1 -1
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts +6 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +4 -4
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +38 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +36 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts +2 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/convention-lint.d.ts +41 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/index.d.ts +2 -0
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +3 -2
- package/dist/routing/link-codegen.d.ts +90 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/segment-classify.d.ts +46 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/status-file-lint.d.ts +2 -1
- package/dist/routing/status-file-lint.d.ts.map +1 -1
- package/dist/routing/types.d.ts +16 -4
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +12 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/schema-bridge.d.ts +76 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +139 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +32 -441
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/registry.d.ts +2 -2
- package/dist/search-params/registry.d.ts.map +1 -1
- package/dist/search-params/wrappers.d.ts +53 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/segment-params/define.d.ts +78 -0
- package/dist/segment-params/define.d.ts.map +1 -0
- package/dist/segment-params/index.d.ts +3 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +2 -0
- package/dist/server/access-gate.d.ts +4 -0
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +41 -6
- 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 +7 -0
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +3 -6
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +32 -4
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +2 -2
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/debug.d.ts +1 -1
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/deny-page-resolver.d.ts +52 -0
- package/dist/server/deny-page-resolver.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-holding-server.d.ts +52 -0
- package/dist/server/dev-holding-server.d.ts.map +1 -0
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/dev-warnings.d.ts +1 -21
- package/dist/server/dev-warnings.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -5
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -1
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +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 +42 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/flush.d.ts.map +1 -1
- package/dist/server/form-data.d.ts +29 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/html-injectors.d.ts +51 -11
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -43
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +195 -2800
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +46 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +2900 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +25 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +19 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +113 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/page-deny-boundary.d.ts +31 -0
- package/dist/server/page-deny-boundary.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +1 -1
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-metadata.d.ts +6 -0
- package/dist/server/pipeline-metadata.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +52 -10
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +69 -18
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +112 -43
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +27 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +16 -2
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +2 -2
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +48 -5
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +20 -3
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +14 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sensitive-fields.d.ts +74 -0
- package/dist/server/sensitive-fields.d.ts.map +1 -0
- package/dist/server/sitemap-generator.d.ts +129 -0
- package/dist/server/sitemap-generator.d.ts.map +1 -0
- package/dist/server/sitemap-handler.d.ts +22 -0
- package/dist/server/sitemap-handler.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +1 -1
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +23 -0
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +39 -21
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +50 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +1 -1
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +36 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +4 -4
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +22 -19
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/shared/merge-search-params.d.ts +22 -0
- package/dist/shared/merge-search-params.d.ts.map +1 -0
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.js +42 -0
- package/dist/shims/font-google.js.map +1 -0
- package/dist/shims/font-local.d.ts +26 -0
- package/dist/shims/font-local.d.ts.map +1 -0
- package/dist/shims/font-local.js +20 -0
- package/dist/shims/font-local.js.map +1 -0
- package/dist/shims/headers.d.ts +2 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/navigation-client.d.ts +1 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +3 -2
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/directive-parser.d.ts +5 -2
- package/dist/utils/directive-parser.d.ts.map +1 -1
- package/dist/utils/state-machine.d.ts +80 -0
- package/dist/utils/state-machine.d.ts.map +1 -0
- package/package.json +51 -16
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +142 -0
- package/src/adapters/cloudflare.ts +342 -28
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +52 -8
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +38 -0
- package/src/cache/handler-store.ts +68 -0
- package/src/cache/index.ts +81 -18
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/sizeof.ts +31 -0
- package/src/cache/timber-cache.ts +24 -20
- package/src/cli.ts +16 -6
- package/src/client/browser-dev.ts +128 -1
- package/src/client/browser-entry/action-dispatch.ts +116 -0
- package/src/client/browser-entry/hmr.ts +81 -0
- package/src/client/browser-entry/hydrate.ts +145 -0
- package/src/client/browser-entry/index.ts +143 -0
- package/src/client/browser-entry/post-hydration.ts +119 -0
- package/src/client/browser-entry/router-init.ts +193 -0
- package/src/client/browser-entry/rsc-stream.ts +157 -0
- package/src/client/browser-entry/scroll.ts +27 -0
- package/src/client/error-boundary.tsx +48 -16
- package/src/client/error-reconstituter.tsx +65 -0
- package/src/client/form.tsx +14 -7
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +65 -38
- package/src/client/internal.ts +57 -0
- package/src/client/link-pending-store.ts +111 -0
- package/src/client/link.tsx +342 -113
- package/src/client/nav-link-store.ts +47 -0
- package/src/client/navigation-api-types.ts +112 -0
- package/src/client/navigation-api.ts +332 -0
- package/src/client/navigation-context.ts +31 -6
- package/src/client/navigation-root.tsx +342 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router-ref.ts +1 -1
- package/src/client/router.ts +299 -72
- package/src/client/rsc-fetch.ts +97 -8
- package/src/client/segment-cache.ts +1 -1
- package/src/client/segment-outlet.tsx +86 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/stale-reload.ts +72 -3
- package/src/client/top-loader.tsx +18 -6
- package/src/client/use-link-status.ts +7 -7
- package/src/client/use-params.ts +7 -5
- package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
- package/src/client/use-query-states.ts +9 -3
- package/src/client/use-router.ts +1 -1
- package/src/codec.ts +49 -0
- package/src/config-types.ts +264 -0
- package/src/config-validation.ts +303 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +78 -25
- package/src/cookies/index.ts +8 -0
- package/src/fonts/bundle.ts +142 -0
- package/src/fonts/css.ts +2 -1
- package/src/fonts/dev-middleware.ts +74 -0
- package/src/fonts/pipeline.ts +275 -0
- package/src/fonts/transform.ts +353 -0
- package/src/fonts/types.ts +50 -1
- package/src/fonts/virtual-modules.ts +159 -0
- package/src/index.ts +314 -355
- package/src/plugin-context.ts +240 -0
- package/src/plugins/adapter-build.ts +9 -3
- package/src/plugins/build-manifest.ts +13 -2
- package/src/plugins/build-report.ts +3 -3
- package/src/plugins/client-chunks.ts +65 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-404-page.ts +418 -0
- package/src/plugins/dev-browser-logs.ts +288 -0
- package/src/plugins/dev-error-overlay.ts +286 -42
- package/src/plugins/dev-error-page.ts +536 -0
- package/src/plugins/dev-logs.ts +1 -1
- package/src/plugins/dev-server.ts +146 -19
- package/src/plugins/dev-terminal-error.ts +217 -0
- package/src/plugins/entries.ts +111 -10
- package/src/plugins/fonts.ts +133 -638
- package/src/plugins/mdx.ts +1 -1
- package/src/plugins/routing.ts +213 -31
- package/src/plugins/server-action-exports.ts +1 -1
- package/src/plugins/server-bundle.ts +32 -1
- package/src/plugins/shims.ts +136 -35
- package/src/plugins/static-build.ts +17 -11
- package/src/routing/codegen-shared.ts +74 -0
- package/src/routing/codegen-types.ts +37 -0
- package/src/routing/codegen.ts +112 -173
- package/src/routing/convention-lint.ts +356 -0
- package/src/routing/index.ts +2 -0
- package/src/routing/link-codegen.ts +262 -0
- package/src/routing/scanner.ts +93 -23
- package/src/routing/segment-classify.ts +89 -0
- package/src/routing/status-file-lint.ts +3 -2
- package/src/routing/types.ts +17 -4
- package/src/rsc-runtime/rsc.ts +2 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
- package/src/search-params/define.ts +482 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/registry.ts +2 -2
- package/src/search-params/wrappers.ts +85 -0
- package/src/segment-params/define.ts +279 -0
- package/src/segment-params/index.ts +9 -0
- package/src/server/access-gate.tsx +70 -29
- package/src/server/action-client.ts +88 -15
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +53 -6
- package/src/server/actions.ts +10 -9
- package/src/server/als-registry.ts +34 -6
- package/src/server/build-manifest.ts +10 -4
- package/src/server/compress.ts +25 -7
- package/src/server/debug.ts +1 -1
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-page-resolver.ts +154 -0
- package/src/server/deny-renderer.ts +24 -38
- package/src/server/dev-holding-server.ts +185 -0
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/dev-warnings.ts +4 -49
- package/src/server/early-hints.ts +36 -15
- package/src/server/error-boundary-wrapper.ts +74 -22
- package/src/server/fallback-error.ts +74 -102
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +62 -0
- package/src/server/flush.ts +2 -1
- package/src/server/form-data.ts +76 -0
- package/src/server/html-injectors.ts +280 -120
- package/src/server/index.ts +25 -177
- package/src/server/internal.ts +169 -0
- package/src/server/logger.ts +44 -36
- package/src/server/middleware-runner.ts +31 -4
- package/src/server/node-stream-transforms.ts +509 -0
- package/src/server/page-deny-boundary.tsx +56 -0
- package/src/server/pipeline-interception.ts +17 -16
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline.ts +261 -66
- package/src/server/primitives.ts +111 -28
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +293 -132
- package/src/server/route-element-builder.ts +283 -191
- package/src/server/route-handler.ts +24 -4
- package/src/server/route-matcher.ts +31 -20
- package/src/server/rsc-entry/api-handler.ts +15 -16
- package/src/server/rsc-entry/error-renderer.ts +305 -89
- package/src/server/rsc-entry/helpers.ts +134 -5
- package/src/server/rsc-entry/index.ts +304 -111
- package/src/server/rsc-entry/rsc-payload.ts +65 -18
- package/src/server/rsc-entry/rsc-stream.ts +81 -13
- package/src/server/rsc-entry/ssr-bridge.ts +14 -5
- package/src/server/rsc-entry/ssr-renderer.ts +171 -38
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/sitemap-generator.ts +338 -0
- package/src/server/sitemap-handler.ts +126 -0
- package/src/server/slot-resolver.ts +244 -229
- package/src/server/ssr-entry.ts +215 -32
- package/src/server/ssr-render.ts +289 -67
- package/src/server/ssr-wrappers.tsx +139 -0
- package/src/server/status-code-resolver.ts +1 -1
- package/src/server/stream-utils.ts +213 -0
- package/src/server/tracing.ts +20 -9
- package/src/server/tree-builder.ts +92 -58
- package/src/server/types.ts +3 -6
- package/src/server/version-skew.ts +104 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/headers.ts +5 -1
- package/src/shims/navigation-client.ts +1 -1
- package/src/shims/navigation.ts +7 -2
- package/src/utils/directive-parser.ts +5 -2
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
- package/dist/_chunks/format-DviM89f0.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
- package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
- package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
- package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
- package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
- package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
- package/dist/cache/register-cached-function.d.ts +0 -17
- package/dist/cache/register-cached-function.d.ts.map +0 -1
- package/dist/client/browser-entry.d.ts +0 -21
- package/dist/client/browser-entry.d.ts.map +0 -1
- package/dist/client/link-status-provider.d.ts +0 -11
- package/dist/client/link-status-provider.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/client/use-navigation-pending.d.ts.map +0 -1
- package/dist/cookies/index.js.map +0 -1
- package/dist/plugins/cache-transform.d.ts +0 -36
- package/dist/plugins/cache-transform.d.ts.map +0 -1
- package/dist/plugins/dynamic-transform.d.ts +0 -72
- package/dist/plugins/dynamic-transform.d.ts.map +0 -1
- package/dist/search-params/analyze.d.ts +0 -54
- package/dist/search-params/analyze.d.ts.map +0 -1
- package/dist/search-params/builtin-codecs.d.ts +0 -105
- package/dist/search-params/builtin-codecs.d.ts.map +0 -1
- package/dist/search-params/codecs.d.ts +0 -53
- package/dist/search-params/codecs.d.ts.map +0 -1
- package/dist/search-params/create.d.ts +0 -106
- package/dist/search-params/create.d.ts.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/server/response-cache.d.ts +0 -54
- package/dist/server/response-cache.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -103
- package/src/client/browser-entry.ts +0 -678
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/transition-root.tsx +0 -166
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/create.ts +0 -321
- package/src/server/prerender.ts +0 -139
- package/src/server/response-cache.ts +0 -410
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev 404 page — self-contained HTML page for dev-mode route misses.
|
|
3
|
+
*
|
|
4
|
+
* When no route matches and the user has no 404.tsx, this page shows:
|
|
5
|
+
* - The requested path
|
|
6
|
+
* - All registered routes in the app
|
|
7
|
+
* - "Did you mean?" suggestions based on string similarity
|
|
8
|
+
* - Setup instructions for new projects with no routes
|
|
9
|
+
*
|
|
10
|
+
* Dev-only: this module is only imported in dev mode. It is never
|
|
11
|
+
* included in production builds.
|
|
12
|
+
*
|
|
13
|
+
* Design doc: 21-dev-server.md, 07-routing.md
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
interface RouteInfo {
|
|
19
|
+
/** URL path pattern (e.g., "/dashboard/[id]") */
|
|
20
|
+
path: string;
|
|
21
|
+
/** Whether this is a page route or API route handler */
|
|
22
|
+
type: 'page' | 'route';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Minimal segment node shape — matches ManifestSegmentNode. */
|
|
26
|
+
interface SegmentNode {
|
|
27
|
+
segmentName: string;
|
|
28
|
+
segmentType: string;
|
|
29
|
+
urlPath: string;
|
|
30
|
+
page?: { filePath: string };
|
|
31
|
+
route?: { filePath: string };
|
|
32
|
+
children: SegmentNode[];
|
|
33
|
+
slots: Record<string, SegmentNode> | Map<string, SegmentNode>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ─── Route Collection ───────────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Collect all routable paths from the manifest tree.
|
|
40
|
+
*
|
|
41
|
+
* Walks the segment tree and collects paths for segments that have
|
|
42
|
+
* a page or route handler.
|
|
43
|
+
*/
|
|
44
|
+
export function collectRoutes(root: SegmentNode): RouteInfo[] {
|
|
45
|
+
const routes: RouteInfo[] = [];
|
|
46
|
+
walkRoutes(root, routes);
|
|
47
|
+
return routes.sort((a, b) => a.path.localeCompare(b.path));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function walkRoutes(node: SegmentNode, routes: RouteInfo[]): void {
|
|
51
|
+
if (node.page) {
|
|
52
|
+
routes.push({ path: node.urlPath || '/', type: 'page' });
|
|
53
|
+
}
|
|
54
|
+
if (node.route) {
|
|
55
|
+
routes.push({ path: node.urlPath || '/', type: 'route' });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const child of node.children) {
|
|
59
|
+
walkRoutes(child, routes);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Handle both Map and plain object for slots
|
|
63
|
+
const slots = node.slots;
|
|
64
|
+
if (slots instanceof Map) {
|
|
65
|
+
for (const [, slotNode] of slots) {
|
|
66
|
+
walkRoutes(slotNode, routes);
|
|
67
|
+
}
|
|
68
|
+
} else if (slots && typeof slots === 'object') {
|
|
69
|
+
for (const key of Object.keys(slots)) {
|
|
70
|
+
walkRoutes((slots as Record<string, SegmentNode>)[key]!, routes);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ─── String Similarity ──────────────────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Compute Levenshtein distance between two strings.
|
|
79
|
+
*
|
|
80
|
+
* Used for "did you mean?" suggestions. Simple O(n*m) implementation
|
|
81
|
+
* — fine for short URL paths.
|
|
82
|
+
*/
|
|
83
|
+
function levenshtein(a: string, b: string): number {
|
|
84
|
+
const m = a.length;
|
|
85
|
+
const n = b.length;
|
|
86
|
+
|
|
87
|
+
// Optimization: use single-row DP
|
|
88
|
+
const row = Array.from({ length: n + 1 }, (_, i) => i);
|
|
89
|
+
|
|
90
|
+
for (let i = 1; i <= m; i++) {
|
|
91
|
+
let prev = i;
|
|
92
|
+
for (let j = 1; j <= n; j++) {
|
|
93
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
94
|
+
const val = Math.min(
|
|
95
|
+
row[j]! + 1, // deletion
|
|
96
|
+
prev + 1, // insertion
|
|
97
|
+
row[j - 1]! + cost // substitution
|
|
98
|
+
);
|
|
99
|
+
row[j - 1] = prev;
|
|
100
|
+
prev = val;
|
|
101
|
+
}
|
|
102
|
+
row[n] = prev;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return row[n]!;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Find routes similar to the requested path.
|
|
110
|
+
*
|
|
111
|
+
* Returns up to 3 suggestions, sorted by similarity.
|
|
112
|
+
* Only includes routes with distance ≤ 40% of the longer string.
|
|
113
|
+
*/
|
|
114
|
+
export function findSimilarRoutes(requestedPath: string, routes: RouteInfo[]): RouteInfo[] {
|
|
115
|
+
if (routes.length === 0) return [];
|
|
116
|
+
|
|
117
|
+
const scored = routes
|
|
118
|
+
.map((route) => ({
|
|
119
|
+
route,
|
|
120
|
+
distance: levenshtein(requestedPath.toLowerCase(), route.path.toLowerCase()),
|
|
121
|
+
}))
|
|
122
|
+
.filter((s) => {
|
|
123
|
+
const maxLen = Math.max(requestedPath.length, s.route.path.length);
|
|
124
|
+
return s.distance <= maxLen * 0.4;
|
|
125
|
+
})
|
|
126
|
+
.sort((a, b) => a.distance - b.distance);
|
|
127
|
+
|
|
128
|
+
return scored.slice(0, 3).map((s) => s.route);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ─── HTML Escaping ──────────────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
function esc(str: string): string {
|
|
134
|
+
return str
|
|
135
|
+
.replace(/&/g, '&')
|
|
136
|
+
.replace(/</g, '<')
|
|
137
|
+
.replace(/>/g, '>')
|
|
138
|
+
.replace(/"/g, '"');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ─── HTML Generation ────────────────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Generate a dev-mode 404 page with route listing and suggestions.
|
|
145
|
+
*
|
|
146
|
+
* Returns an HTML string for a self-contained error page.
|
|
147
|
+
*/
|
|
148
|
+
export function generateDev404Page(requestedPath: string, routes: RouteInfo[]): string {
|
|
149
|
+
const suggestions = findSimilarRoutes(requestedPath, routes);
|
|
150
|
+
const isEmpty = routes.length === 0;
|
|
151
|
+
|
|
152
|
+
return `<!DOCTYPE html>
|
|
153
|
+
<html lang="en">
|
|
154
|
+
<head>
|
|
155
|
+
<meta charset="utf-8">
|
|
156
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
157
|
+
<title>404 — ${esc(requestedPath)} | timber.js</title>
|
|
158
|
+
<style>${CSS}</style>
|
|
159
|
+
</head>
|
|
160
|
+
<body>
|
|
161
|
+
<div class="container">
|
|
162
|
+
<header class="header">
|
|
163
|
+
<div class="badge">404 Not Found</div>
|
|
164
|
+
<h1 class="message">No route matches <code>${esc(requestedPath)}</code></h1>
|
|
165
|
+
</header>
|
|
166
|
+
|
|
167
|
+
${
|
|
168
|
+
isEmpty
|
|
169
|
+
? `<div class="welcome">
|
|
170
|
+
<h2>Welcome to timber.js</h2>
|
|
171
|
+
<p>Your app has no pages yet. Create your first page to get started:</p>
|
|
172
|
+
<div class="code-block">
|
|
173
|
+
<div class="code-header">app/page.tsx</div>
|
|
174
|
+
<pre><code>export default function Home() {
|
|
175
|
+
return <h1>Hello, timber.js!</h1>;
|
|
176
|
+
}</code></pre>
|
|
177
|
+
</div>
|
|
178
|
+
<p class="hint">Save the file and this page will reload automatically.</p>
|
|
179
|
+
</div>`
|
|
180
|
+
: ''
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
${
|
|
184
|
+
suggestions.length > 0
|
|
185
|
+
? `<div class="section">
|
|
186
|
+
<div class="section-header">Did you mean?</div>
|
|
187
|
+
<ul class="route-list suggestions">
|
|
188
|
+
${suggestions.map((r) => `<li><a href="${esc(r.path)}">${esc(r.path)}</a> <span class="route-type">${r.type}</span></li>`).join('\n ')}
|
|
189
|
+
</ul>
|
|
190
|
+
</div>`
|
|
191
|
+
: ''
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
${
|
|
195
|
+
routes.length > 0
|
|
196
|
+
? `<div class="section">
|
|
197
|
+
<div class="section-header">Available Routes (${routes.length})</div>
|
|
198
|
+
<ul class="route-list">
|
|
199
|
+
${routes.map((r) => `<li><a href="${esc(r.path)}">${esc(r.path)}</a> <span class="route-type">${r.type}</span></li>`).join('\n ')}
|
|
200
|
+
</ul>
|
|
201
|
+
</div>`
|
|
202
|
+
: ''
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
<footer class="footer">
|
|
206
|
+
<span class="timber-logo">🪵 timber.js</span>
|
|
207
|
+
<span class="footer-hint">Add or edit routes and this page will reload automatically.</span>
|
|
208
|
+
</footer>
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<script>
|
|
212
|
+
// Auto-reload when Vite HMR fires (route added, file changed, etc.)
|
|
213
|
+
(function() {
|
|
214
|
+
try {
|
|
215
|
+
const ws = new WebSocket('ws://' + location.host, 'vite-hmr');
|
|
216
|
+
ws.addEventListener('message', function(e) {
|
|
217
|
+
try {
|
|
218
|
+
const data = JSON.parse(e.data);
|
|
219
|
+
if (data.type === 'full-reload' || data.type === 'update') {
|
|
220
|
+
location.reload();
|
|
221
|
+
}
|
|
222
|
+
} catch {}
|
|
223
|
+
});
|
|
224
|
+
} catch {}
|
|
225
|
+
})();
|
|
226
|
+
</script>
|
|
227
|
+
</body>
|
|
228
|
+
</html>`;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ─── CSS ────────────────────────────────────────────────────────────────────
|
|
232
|
+
|
|
233
|
+
const CSS = `
|
|
234
|
+
:root {
|
|
235
|
+
--bg: #fff;
|
|
236
|
+
--fg: #1a1a1a;
|
|
237
|
+
--fg-dim: #6b7280;
|
|
238
|
+
--border: #e5e7eb;
|
|
239
|
+
--badge-bg: #fefce8;
|
|
240
|
+
--badge-fg: #854d0e;
|
|
241
|
+
--badge-border: #fde68a;
|
|
242
|
+
--source-bg: #fafafa;
|
|
243
|
+
--link: #2563eb;
|
|
244
|
+
--code-bg: #f3f4f6;
|
|
245
|
+
--btn-bg: #f3f4f6;
|
|
246
|
+
--route-type-bg: #e0f2fe;
|
|
247
|
+
--route-type-fg: #0369a1;
|
|
248
|
+
--code-font: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
@media (prefers-color-scheme: dark) {
|
|
252
|
+
:root {
|
|
253
|
+
--bg: #0a0a0a;
|
|
254
|
+
--fg: #f5f5f5;
|
|
255
|
+
--fg-dim: #9ca3af;
|
|
256
|
+
--border: #27272a;
|
|
257
|
+
--badge-bg: #422006;
|
|
258
|
+
--badge-fg: #fde68a;
|
|
259
|
+
--badge-border: #854d0e;
|
|
260
|
+
--source-bg: #18181b;
|
|
261
|
+
--link: #60a5fa;
|
|
262
|
+
--code-bg: #27272a;
|
|
263
|
+
--btn-bg: #27272a;
|
|
264
|
+
--route-type-bg: #0c4a6e;
|
|
265
|
+
--route-type-fg: #bae6fd;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
270
|
+
|
|
271
|
+
body {
|
|
272
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
273
|
+
background: var(--bg);
|
|
274
|
+
color: var(--fg);
|
|
275
|
+
line-height: 1.6;
|
|
276
|
+
padding: 2rem;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.container { max-width: 56rem; margin: 0 auto; }
|
|
280
|
+
.header { margin-bottom: 1.5rem; }
|
|
281
|
+
|
|
282
|
+
.badge {
|
|
283
|
+
display: inline-block;
|
|
284
|
+
font-size: 0.75rem;
|
|
285
|
+
font-weight: 600;
|
|
286
|
+
text-transform: uppercase;
|
|
287
|
+
letter-spacing: 0.05em;
|
|
288
|
+
padding: 0.25rem 0.625rem;
|
|
289
|
+
border-radius: 0.375rem;
|
|
290
|
+
background: var(--badge-bg);
|
|
291
|
+
color: var(--badge-fg);
|
|
292
|
+
border: 1px solid var(--badge-border);
|
|
293
|
+
margin-bottom: 0.75rem;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.message {
|
|
297
|
+
font-size: 1.375rem;
|
|
298
|
+
font-weight: 600;
|
|
299
|
+
line-height: 1.3;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.message code {
|
|
303
|
+
font-family: var(--code-font);
|
|
304
|
+
background: var(--code-bg);
|
|
305
|
+
padding: 0.125rem 0.375rem;
|
|
306
|
+
border-radius: 0.25rem;
|
|
307
|
+
font-size: 1.125rem;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.welcome {
|
|
311
|
+
margin-bottom: 1.5rem;
|
|
312
|
+
padding: 1.5rem;
|
|
313
|
+
border: 1px solid var(--border);
|
|
314
|
+
border-radius: 0.5rem;
|
|
315
|
+
background: var(--source-bg);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.welcome h2 {
|
|
319
|
+
font-size: 1.125rem;
|
|
320
|
+
margin-bottom: 0.5rem;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.welcome p { color: var(--fg-dim); margin-bottom: 1rem; }
|
|
324
|
+
|
|
325
|
+
.code-block {
|
|
326
|
+
border: 1px solid var(--border);
|
|
327
|
+
border-radius: 0.5rem;
|
|
328
|
+
overflow: hidden;
|
|
329
|
+
margin-bottom: 1rem;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.code-header {
|
|
333
|
+
font-size: 0.75rem;
|
|
334
|
+
font-weight: 600;
|
|
335
|
+
padding: 0.5rem 0.75rem;
|
|
336
|
+
background: var(--code-bg);
|
|
337
|
+
border-bottom: 1px solid var(--border);
|
|
338
|
+
color: var(--fg-dim);
|
|
339
|
+
font-family: var(--code-font);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.code-block pre {
|
|
343
|
+
padding: 0.75rem;
|
|
344
|
+
font-family: var(--code-font);
|
|
345
|
+
font-size: 0.8125rem;
|
|
346
|
+
line-height: 1.7;
|
|
347
|
+
overflow-x: auto;
|
|
348
|
+
margin: 0;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.section {
|
|
352
|
+
margin-bottom: 1rem;
|
|
353
|
+
border: 1px solid var(--border);
|
|
354
|
+
border-radius: 0.5rem;
|
|
355
|
+
overflow: hidden;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.section-header {
|
|
359
|
+
font-size: 0.75rem;
|
|
360
|
+
font-weight: 600;
|
|
361
|
+
text-transform: uppercase;
|
|
362
|
+
letter-spacing: 0.05em;
|
|
363
|
+
padding: 0.5rem 0.75rem;
|
|
364
|
+
background: var(--source-bg);
|
|
365
|
+
border-bottom: 1px solid var(--border);
|
|
366
|
+
color: var(--fg-dim);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.route-list {
|
|
370
|
+
list-style: none;
|
|
371
|
+
padding: 0.5rem 0;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.route-list li {
|
|
375
|
+
padding: 0.375rem 0.75rem;
|
|
376
|
+
font-family: var(--code-font);
|
|
377
|
+
font-size: 0.8125rem;
|
|
378
|
+
display: flex;
|
|
379
|
+
align-items: center;
|
|
380
|
+
gap: 0.5rem;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.route-list li:hover { background: var(--source-bg); }
|
|
384
|
+
|
|
385
|
+
.route-list a {
|
|
386
|
+
color: var(--link);
|
|
387
|
+
text-decoration: none;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.route-list a:hover { text-decoration: underline; }
|
|
391
|
+
|
|
392
|
+
.route-type {
|
|
393
|
+
font-size: 0.625rem;
|
|
394
|
+
font-weight: 600;
|
|
395
|
+
text-transform: uppercase;
|
|
396
|
+
letter-spacing: 0.05em;
|
|
397
|
+
padding: 0.125rem 0.375rem;
|
|
398
|
+
border-radius: 0.25rem;
|
|
399
|
+
background: var(--route-type-bg);
|
|
400
|
+
color: var(--route-type-fg);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.suggestions { background: var(--source-bg); }
|
|
404
|
+
|
|
405
|
+
.hint { font-size: 0.875rem; color: var(--fg-dim); }
|
|
406
|
+
|
|
407
|
+
.footer {
|
|
408
|
+
display: flex;
|
|
409
|
+
align-items: center;
|
|
410
|
+
gap: 0.75rem;
|
|
411
|
+
padding-top: 1rem;
|
|
412
|
+
border-top: 1px solid var(--border);
|
|
413
|
+
font-size: 0.75rem;
|
|
414
|
+
color: var(--fg-dim);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.timber-logo { font-weight: 600; white-space: nowrap; }
|
|
418
|
+
`;
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* timber-dev-browser-logs — Forwards browser console output to the server terminal.
|
|
3
|
+
*
|
|
4
|
+
* Injects a small inline script in dev mode that intercepts browser
|
|
5
|
+
* `console.error`, `console.warn`, and `console.info`, then forwards
|
|
6
|
+
* messages to the server via Vite's HMR WebSocket.
|
|
7
|
+
*
|
|
8
|
+
* The server-side listener formats and prints the messages with color-coded
|
|
9
|
+
* prefixes: [browser:error], [browser:warn], [browser:info].
|
|
10
|
+
*
|
|
11
|
+
* Dev-only: this plugin only runs during `vite dev`.
|
|
12
|
+
* No runtime overhead in production.
|
|
13
|
+
*
|
|
14
|
+
* See TIM-513 for design context.
|
|
15
|
+
* See design/18-build-system.md §"Dev Server" for sub-plugin architecture.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { Plugin, ViteDevServer } from 'vite';
|
|
19
|
+
import type { PluginContext } from '../plugin-context.js';
|
|
20
|
+
|
|
21
|
+
// ─── Types ───────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
/** Log levels forwarded from the browser. */
|
|
24
|
+
export type BrowserLogLevel = 'error' | 'warn' | 'info';
|
|
25
|
+
|
|
26
|
+
/** Configuration value for devBrowserLogs in timber.config.ts. */
|
|
27
|
+
export type DevBrowserLogsConfig = BrowserLogLevel | 'none' | undefined;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Payload sent from browser to server via Vite's HMR WebSocket.
|
|
31
|
+
* Kept small — truncated before sending.
|
|
32
|
+
*/
|
|
33
|
+
export interface BrowserLogPayload {
|
|
34
|
+
level: BrowserLogLevel;
|
|
35
|
+
/** Serialized message string. */
|
|
36
|
+
message: string;
|
|
37
|
+
/** Error stack trace, if the first argument was an Error. */
|
|
38
|
+
stack: string | null;
|
|
39
|
+
/** Source URL and line number, if available. */
|
|
40
|
+
source: string | null;
|
|
41
|
+
/** Timestamp in ms (Date.now()) from the browser. */
|
|
42
|
+
timestamp: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ─── Constants ───────────────────────────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
/** Max message size in bytes before truncation. */
|
|
48
|
+
const MAX_MESSAGE_BYTES = 2048;
|
|
49
|
+
|
|
50
|
+
/** HMR event name for browser→server log forwarding. */
|
|
51
|
+
const HMR_EVENT = 'timber:browser-log';
|
|
52
|
+
|
|
53
|
+
/** ANSI color codes for terminal output. */
|
|
54
|
+
const COLORS = {
|
|
55
|
+
red: '\x1b[31m',
|
|
56
|
+
yellow: '\x1b[33m',
|
|
57
|
+
blue: '\x1b[34m',
|
|
58
|
+
dim: '\x1b[2m',
|
|
59
|
+
reset: '\x1b[0m',
|
|
60
|
+
} as const;
|
|
61
|
+
|
|
62
|
+
/** Level severity ordering for threshold comparison. */
|
|
63
|
+
const LEVEL_SEVERITY: Record<BrowserLogLevel | 'none', number> = {
|
|
64
|
+
none: 0,
|
|
65
|
+
info: 1,
|
|
66
|
+
warn: 2,
|
|
67
|
+
error: 3,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// ─── Formatting ──────────────────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Format a browser log payload for server terminal output.
|
|
74
|
+
*
|
|
75
|
+
* Produces color-coded output like:
|
|
76
|
+
* [browser:error] Uncaught TypeError: x is not a function
|
|
77
|
+
* at App (app.tsx:10:5)
|
|
78
|
+
* [browser:warn] Deprecation warning (app/page.tsx:42:12)
|
|
79
|
+
*/
|
|
80
|
+
export function formatBrowserLog(payload: BrowserLogPayload): string {
|
|
81
|
+
const { level, message, stack, source } = payload;
|
|
82
|
+
|
|
83
|
+
// Color-coded prefix
|
|
84
|
+
const color = level === 'error' ? COLORS.red : level === 'warn' ? COLORS.yellow : COLORS.blue;
|
|
85
|
+
const prefix = `${color}[browser:${level}]${COLORS.reset}`;
|
|
86
|
+
|
|
87
|
+
// Source suffix
|
|
88
|
+
const sourceSuffix = source ? ` ${COLORS.dim}(${source})${COLORS.reset}` : '';
|
|
89
|
+
|
|
90
|
+
let output = `${prefix} ${message}${sourceSuffix}`;
|
|
91
|
+
|
|
92
|
+
// Append stack trace indented
|
|
93
|
+
if (stack) {
|
|
94
|
+
const indented = stack
|
|
95
|
+
.split('\n')
|
|
96
|
+
.map((line) => ` ${COLORS.dim}${line}${COLORS.reset}`)
|
|
97
|
+
.join('\n');
|
|
98
|
+
output += `\n${indented}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return output;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ─── Level Filtering ─────────────────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Check if a log at `level` should be forwarded given the configured threshold.
|
|
108
|
+
*
|
|
109
|
+
* The threshold acts as a minimum severity:
|
|
110
|
+
* - 'error' → only errors
|
|
111
|
+
* - 'warn' → errors + warnings
|
|
112
|
+
* - 'info' → errors + warnings + info
|
|
113
|
+
* - 'none' → nothing
|
|
114
|
+
*/
|
|
115
|
+
export function shouldForwardLevel(
|
|
116
|
+
level: BrowserLogLevel,
|
|
117
|
+
threshold: BrowserLogLevel | 'none'
|
|
118
|
+
): boolean {
|
|
119
|
+
if (threshold === 'none') return false;
|
|
120
|
+
return LEVEL_SEVERITY[level] >= LEVEL_SEVERITY[threshold];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ─── Truncation ──────────────────────────────────────────────────────────
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Truncate a message to `maxBytes` to avoid flooding the terminal.
|
|
127
|
+
* Appends a suffix indicating how many bytes were dropped.
|
|
128
|
+
*/
|
|
129
|
+
export function truncateMessage(message: string, maxBytes: number): string {
|
|
130
|
+
if (message.length <= maxBytes) return message;
|
|
131
|
+
|
|
132
|
+
const truncated = message.slice(0, maxBytes);
|
|
133
|
+
const droppedBytes = message.length - maxBytes;
|
|
134
|
+
return `${truncated}… [truncated ${droppedBytes} bytes]`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ─── Client Injection Script ─────────────────────────────────────────────
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Generate the inline script injected into the browser in dev mode.
|
|
141
|
+
*
|
|
142
|
+
* This script:
|
|
143
|
+
* 1. Saves references to the original console methods
|
|
144
|
+
* 2. Wraps `console.error`, `console.warn`, `console.info`
|
|
145
|
+
* 3. Calls the original first (browser devtools still work)
|
|
146
|
+
* 4. Serializes and forwards via `import.meta.hot.send()`
|
|
147
|
+
* 5. Truncates messages to MAX_MESSAGE_BYTES
|
|
148
|
+
*
|
|
149
|
+
* The script is minimal and self-contained — no imports, no dependencies.
|
|
150
|
+
*/
|
|
151
|
+
export function generateClientScript(threshold: BrowserLogLevel | 'none'): string {
|
|
152
|
+
if (threshold === 'none') return '';
|
|
153
|
+
|
|
154
|
+
// Only intercept levels that meet the threshold
|
|
155
|
+
const levels: BrowserLogLevel[] = ['error', 'warn', 'info'].filter((l) =>
|
|
156
|
+
shouldForwardLevel(l as BrowserLogLevel, threshold)
|
|
157
|
+
) as BrowserLogLevel[];
|
|
158
|
+
|
|
159
|
+
if (levels.length === 0) return '';
|
|
160
|
+
|
|
161
|
+
return `
|
|
162
|
+
(function() {
|
|
163
|
+
if (!import.meta.hot) return;
|
|
164
|
+
var MAX_BYTES = ${MAX_MESSAGE_BYTES};
|
|
165
|
+
var levels = ${JSON.stringify(levels)};
|
|
166
|
+
var originals = {};
|
|
167
|
+
|
|
168
|
+
function serialize(arg) {
|
|
169
|
+
if (arg === null) return 'null';
|
|
170
|
+
if (arg === undefined) return 'undefined';
|
|
171
|
+
if (arg instanceof Error) return arg.stack || arg.message || String(arg);
|
|
172
|
+
if (typeof arg === 'object') {
|
|
173
|
+
try { return JSON.stringify(arg); } catch(e) { return String(arg); }
|
|
174
|
+
}
|
|
175
|
+
return String(arg);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function truncate(s) {
|
|
179
|
+
if (s.length <= MAX_BYTES) return s;
|
|
180
|
+
return s.slice(0, MAX_BYTES) + '... [truncated ' + (s.length - MAX_BYTES) + ' bytes]';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
levels.forEach(function(level) {
|
|
184
|
+
originals[level] = console[level];
|
|
185
|
+
console[level] = function() {
|
|
186
|
+
originals[level].apply(console, arguments);
|
|
187
|
+
try {
|
|
188
|
+
var args = Array.prototype.slice.call(arguments);
|
|
189
|
+
var firstArg = args[0];
|
|
190
|
+
var stack = null;
|
|
191
|
+
var source = null;
|
|
192
|
+
|
|
193
|
+
if (firstArg instanceof Error) {
|
|
194
|
+
stack = firstArg.stack || null;
|
|
195
|
+
source = null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
var message = args.map(serialize).join(' ');
|
|
199
|
+
message = truncate(message);
|
|
200
|
+
|
|
201
|
+
import.meta.hot.send('${HMR_EVENT}', {
|
|
202
|
+
level: level,
|
|
203
|
+
message: message,
|
|
204
|
+
stack: stack,
|
|
205
|
+
source: source,
|
|
206
|
+
timestamp: Date.now()
|
|
207
|
+
});
|
|
208
|
+
} catch(e) {
|
|
209
|
+
// Never let log forwarding break the page
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
})();
|
|
214
|
+
`.trim();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ─── Plugin ──────────────────────────────────────────────────────────────
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Create the timber-dev-browser-logs Vite plugin.
|
|
221
|
+
*
|
|
222
|
+
* - `configureServer`: Listens for HMR messages and prints them to the terminal
|
|
223
|
+
* - `transformIndexHtml`: Injects the client-side interception script
|
|
224
|
+
*
|
|
225
|
+
* Only active during `vite dev` (apply: 'serve').
|
|
226
|
+
*/
|
|
227
|
+
export function timberDevBrowserLogs(ctx: PluginContext): Plugin {
|
|
228
|
+
return {
|
|
229
|
+
name: 'timber-dev-browser-logs',
|
|
230
|
+
apply: 'serve',
|
|
231
|
+
|
|
232
|
+
configureServer(server: ViteDevServer) {
|
|
233
|
+
const threshold = ctx.config.devBrowserLogs ?? 'warn';
|
|
234
|
+
if (threshold === 'none') {
|
|
235
|
+
// Clear any stale script from a prior server instance (e.g. HMR reconfigure)
|
|
236
|
+
delete (globalThis as Record<string, unknown>).__timber_dev_browser_log_script;
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Register the client injection script on globalThis so the RSC entry
|
|
241
|
+
// can include it in headHtml for all Timber route responses.
|
|
242
|
+
// transformIndexHtml only runs for Vite's index.html fallback, not
|
|
243
|
+
// for responses served by createTimberMiddleware (TIM-575).
|
|
244
|
+
const script = generateClientScript(threshold);
|
|
245
|
+
if (script) {
|
|
246
|
+
(globalThis as Record<string, unknown>).__timber_dev_browser_log_script =
|
|
247
|
+
`<script type="module">${script}</script>`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Listen for browser log messages via HMR WebSocket
|
|
251
|
+
server.hot.on(HMR_EVENT, (payload: BrowserLogPayload) => {
|
|
252
|
+
try {
|
|
253
|
+
// Validate level
|
|
254
|
+
if (!shouldForwardLevel(payload.level, threshold)) return;
|
|
255
|
+
|
|
256
|
+
// Truncate server-side too (defense in depth)
|
|
257
|
+
payload.message = truncateMessage(payload.message, MAX_MESSAGE_BYTES);
|
|
258
|
+
|
|
259
|
+
const formatted = formatBrowserLog(payload);
|
|
260
|
+
|
|
261
|
+
// Use the correct console method for the log level
|
|
262
|
+
if (payload.level === 'error') {
|
|
263
|
+
process.stderr.write(formatted + '\n');
|
|
264
|
+
} else {
|
|
265
|
+
process.stdout.write(formatted + '\n');
|
|
266
|
+
}
|
|
267
|
+
} catch {
|
|
268
|
+
// Never let log forwarding crash the server
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
transformIndexHtml() {
|
|
274
|
+
const threshold = ctx.config.devBrowserLogs ?? 'warn';
|
|
275
|
+
const script = generateClientScript(threshold);
|
|
276
|
+
if (!script) return [];
|
|
277
|
+
|
|
278
|
+
return [
|
|
279
|
+
{
|
|
280
|
+
tag: 'script',
|
|
281
|
+
attrs: { type: 'module' },
|
|
282
|
+
children: script,
|
|
283
|
+
injectTo: 'head' as const,
|
|
284
|
+
},
|
|
285
|
+
];
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
}
|