@rangojs/router 0.0.0-experimental.b9cb8739 → 0.0.0-experimental.bdaf10aa
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/AGENTS.md +8 -4
- package/README.md +303 -741
- package/dist/bin/rango.js +730 -184
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +4344 -1335
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +86 -15
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +251 -24
- package/skills/caching/SKILL.md +375 -17
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +94 -18
- package/skills/layout/SKILL.md +62 -19
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +302 -54
- package/skills/middleware/SKILL.md +59 -16
- package/skills/migrate-nextjs/SKILL.md +745 -0
- package/skills/migrate-react-router/SKILL.md +153 -0
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +225 -10
- package/skills/ppr/SKILL.md +622 -0
- package/skills/prerender/SKILL.md +178 -124
- package/skills/rango/SKILL.md +318 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +172 -9
- package/skills/router-setup/SKILL.md +131 -11
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +45 -616
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +1 -66
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +257 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +132 -33
- package/src/browser/navigation-client.ts +218 -68
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +203 -80
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +241 -127
- package/src/browser/prefetch/cache.ts +271 -44
- package/src/browser/prefetch/fetch.ts +367 -40
- package/src/browser/prefetch/queue.ts +144 -23
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +121 -16
- package/src/browser/react/NavigationProvider.tsx +240 -122
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +46 -11
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +272 -80
- package/src/browser/scroll-restoration.ts +56 -22
- package/src/browser/segment-reconciler.ts +44 -7
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +244 -71
- package/src/browser/types.ts +136 -12
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +207 -158
- package/src/build/generate-route-types.ts +6 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +198 -41
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +464 -63
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +336 -110
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +454 -97
- package/src/cache/cache-scope.ts +235 -103
- package/src/cache/cache-tag.ts +149 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2446 -170
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +11 -17
- package/src/cache/document-cache.ts +144 -49
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +24 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +194 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1132 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +116 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +104 -34
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +100 -13
- package/src/index.ts +143 -19
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +215 -86
- package/src/redirect-origin.ts +114 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +485 -303
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +153 -77
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +53 -12
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +48 -21
- package/src/route-types.ts +37 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +164 -17
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +130 -29
- package/src/router/handler-context.ts +83 -39
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +50 -24
- package/src/router/lazy-includes.ts +89 -63
- package/src/router/loader-resolution.ts +286 -56
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +105 -56
- package/src/router/match-api.ts +178 -218
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +66 -22
- package/src/router/match-middleware/cache-lookup.ts +214 -263
- package/src/router/match-middleware/cache-store.ts +105 -50
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +128 -44
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +301 -177
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +203 -58
- package/src/router/preview-match.ts +35 -103
- package/src/router/request-classification.ts +291 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +256 -0
- package/src/router/router-context.ts +11 -29
- package/src/router/router-interfaces.ts +146 -35
- package/src/router/router-options.ts +202 -15
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +301 -78
- package/src/router/segment-resolution/helpers.ts +115 -30
- package/src/router/segment-resolution/loader-cache.ts +156 -39
- package/src/router/segment-resolution/loader-mask.ts +60 -0
- package/src/router/segment-resolution/loader-snapshot.ts +259 -0
- package/src/router/segment-resolution/mask-nested.ts +83 -0
- package/src/router/segment-resolution/revalidation.ts +477 -385
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +8 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +210 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +682 -508
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +127 -31
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +138 -15
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +509 -73
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +287 -113
- package/src/rsc/shell-capture.ts +1190 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +62 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +167 -0
- package/src/segment-system.tsx +449 -132
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +367 -61
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +38 -46
- package/src/server/request-context.ts +558 -173
- package/src/ssr/index.tsx +491 -174
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +234 -82
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +137 -14
- package/src/urls/include-helper.ts +40 -75
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +102 -23
- package/src/urls/path-helper.ts +62 -111
- package/src/urls/pattern-types.ts +84 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +346 -89
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +214 -132
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +57 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +15 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +234 -62
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/plugins/expose-action-id.ts +49 -98
- package/src/vite/plugins/expose-id-utils.ts +96 -51
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +553 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +46 -37
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +353 -303
- package/src/vite/router-discovery.ts +1090 -166
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +98 -38
- package/src/vite/utils/shared-utils.ts +144 -44
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type { Debugger } from "../debug.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Manifest-readiness gate + rediscovery scheduler.
|
|
5
|
+
*
|
|
6
|
+
* Owns the four pieces of state that cooperate to keep
|
|
7
|
+
* `s.discoveryDone` (the promise the manifest virtual module's `load()`
|
|
8
|
+
* hook awaits) consistent across HMR fan-out:
|
|
9
|
+
*
|
|
10
|
+
* - **gatePending**: a Promise has been issued and not yet resolved.
|
|
11
|
+
* Workerd's manifest virtual module load() is blocked on it.
|
|
12
|
+
* - **inProgress**: a refresh's work callback is currently executing.
|
|
13
|
+
* - **queued**: a refresh was attempted while one was already in
|
|
14
|
+
* flight; the active run consumes this in its `finally` and
|
|
15
|
+
* recurses.
|
|
16
|
+
* - **pendingEvents**: a route-file event has been received (gate
|
|
17
|
+
* already reset) but the corresponding refresh's work hasn't started
|
|
18
|
+
* yet — i.e. the debounce hasn't fired. Set in `noteRouteEvent`,
|
|
19
|
+
* cleared at the start of each refresh cycle. Refresh's finally MUST
|
|
20
|
+
* hold the gate if this is true even when `queued` is false,
|
|
21
|
+
* otherwise an event whose debounce fires AFTER the active refresh
|
|
22
|
+
* completes (the "tail-race" window) would observe a resolved gate.
|
|
23
|
+
*
|
|
24
|
+
* The HMR-event flow (cloudflare-stress repro):
|
|
25
|
+
*
|
|
26
|
+
* t=0 Touch 1 → noteRouteEvent → pendingEvents=true, beginGate
|
|
27
|
+
* (gate1 pending)
|
|
28
|
+
* → debounce 100ms
|
|
29
|
+
* t=100 runRefreshCycle(work) → clear pendingEvents, work starts
|
|
30
|
+
* t=750 Touch 2 → noteRouteEvent → pendingEvents=true (no-op gate)
|
|
31
|
+
* → debounce fires at t=850
|
|
32
|
+
* t=800 refresh A's finally → queued=false, pendingEvents=true
|
|
33
|
+
* → HOLD gate (don't resolve)
|
|
34
|
+
* t=850 runRefreshCycle (debounce) → clear pendingEvents, work starts
|
|
35
|
+
* t=1500 refresh B's finally → queued=false, pendingEvents=false
|
|
36
|
+
* → resolveGate (gate1 resolves)
|
|
37
|
+
*
|
|
38
|
+
* @internal Exported only for unit tests.
|
|
39
|
+
*/
|
|
40
|
+
export interface DiscoveryGate {
|
|
41
|
+
/**
|
|
42
|
+
* Reset the gate to a fresh pending Promise via `s.discoveryDone`.
|
|
43
|
+
* No-op when a gate is already pending — file watchers can fire
|
|
44
|
+
* multiple events for one save, and replacing the resolver would
|
|
45
|
+
* orphan the original promise (workerd's manifest load() would hang).
|
|
46
|
+
*/
|
|
47
|
+
beginGate(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the current pending gate. No-op when no gate is pending.
|
|
50
|
+
* Called at the tail of the last refresh cycle in a burst.
|
|
51
|
+
*/
|
|
52
|
+
resolveGate(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Record that a route-file event has arrived. Sets `pendingEvents`
|
|
55
|
+
* and begins the gate. Idempotent for both flags.
|
|
56
|
+
*/
|
|
57
|
+
noteRouteEvent(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Run one refresh cycle, managing queue + pending state around it.
|
|
60
|
+
* If a cycle is already in flight, sets `queued=true` and returns.
|
|
61
|
+
* Otherwise clears `pendingEvents`, runs `work`, and in `finally`:
|
|
62
|
+
*
|
|
63
|
+
* - queued → recurse, gate stays pending
|
|
64
|
+
* - pendingEvents → hold gate (next debounced cycle resolves)
|
|
65
|
+
* - neither → resolveGate
|
|
66
|
+
*/
|
|
67
|
+
runRefreshCycle(work: () => Promise<void>): Promise<void>;
|
|
68
|
+
/** Snapshot of internal state. Test-only. */
|
|
69
|
+
readonly state: () => Readonly<{
|
|
70
|
+
gatePending: boolean;
|
|
71
|
+
inProgress: boolean;
|
|
72
|
+
queued: boolean;
|
|
73
|
+
pendingEvents: boolean;
|
|
74
|
+
}>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** State container the gate writes `discoveryDone` into. */
|
|
78
|
+
export interface GateOwner {
|
|
79
|
+
discoveryDone: Promise<void> | null | undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function createDiscoveryGate(
|
|
83
|
+
s: GateOwner,
|
|
84
|
+
debug?: Debugger,
|
|
85
|
+
): DiscoveryGate {
|
|
86
|
+
let gatePending = false;
|
|
87
|
+
let gateResolver: () => void = () => {};
|
|
88
|
+
let inProgress = false;
|
|
89
|
+
let queued = false;
|
|
90
|
+
let pendingEvents = false;
|
|
91
|
+
|
|
92
|
+
const beginGate = (): void => {
|
|
93
|
+
if (gatePending) return;
|
|
94
|
+
s.discoveryDone = new Promise<void>((resolve) => {
|
|
95
|
+
gateResolver = resolve;
|
|
96
|
+
});
|
|
97
|
+
gatePending = true;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const resolveGate = (): void => {
|
|
101
|
+
if (!gatePending) return;
|
|
102
|
+
// Defer resolution while a refresh cycle is in flight or queued, or
|
|
103
|
+
// while an unprocessed route-file event is pending its debounce.
|
|
104
|
+
// Without this guard, cold-start's `discover().then(resolveGate)`
|
|
105
|
+
// could fire while an HMR-triggered runRefreshCycle is mid-flight,
|
|
106
|
+
// prematurely unblocking workerd's manifest load() against the
|
|
107
|
+
// stale cold-start gen. The active cycle's `finally` calls
|
|
108
|
+
// resolveGate again at the tail and finishes the resolution then.
|
|
109
|
+
if (inProgress || queued || pendingEvents) {
|
|
110
|
+
debug?.(
|
|
111
|
+
"hmr: resolveGate deferred — work in flight (inProgress=%s queued=%s pendingEvents=%s)",
|
|
112
|
+
inProgress,
|
|
113
|
+
queued,
|
|
114
|
+
pendingEvents,
|
|
115
|
+
);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
gatePending = false;
|
|
119
|
+
debug?.("hmr: discoveryDone resolved");
|
|
120
|
+
gateResolver();
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const noteRouteEvent = (): void => {
|
|
124
|
+
pendingEvents = true;
|
|
125
|
+
beginGate();
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const runRefreshCycle = async (work: () => Promise<void>): Promise<void> => {
|
|
129
|
+
if (inProgress) {
|
|
130
|
+
queued = true;
|
|
131
|
+
debug?.("hmr: rediscovery in flight — queued for a follow-up cycle");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Snapshot the current pendingEvents into "we're about to process";
|
|
135
|
+
// events arriving from now on re-set it.
|
|
136
|
+
pendingEvents = false;
|
|
137
|
+
inProgress = true;
|
|
138
|
+
try {
|
|
139
|
+
await work();
|
|
140
|
+
} finally {
|
|
141
|
+
inProgress = false;
|
|
142
|
+
if (queued) {
|
|
143
|
+
queued = false;
|
|
144
|
+
debug?.("hmr: consuming queued rediscovery");
|
|
145
|
+
runRefreshCycle(work).catch((err: unknown) => {
|
|
146
|
+
debug?.(
|
|
147
|
+
"hmr: queued cycle rejected — releasing gate (%s)",
|
|
148
|
+
err instanceof Error ? err.message : String(err),
|
|
149
|
+
);
|
|
150
|
+
// Belt-and-suspenders: even if the queued cycle's own try/catch
|
|
151
|
+
// missed something, ensure workerd doesn't hang.
|
|
152
|
+
resolveGate();
|
|
153
|
+
});
|
|
154
|
+
} else if (pendingEvents) {
|
|
155
|
+
debug?.(
|
|
156
|
+
"hmr: holding gate for pending events (debounce not yet fired)",
|
|
157
|
+
);
|
|
158
|
+
} else {
|
|
159
|
+
resolveGate();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
beginGate,
|
|
166
|
+
resolveGate,
|
|
167
|
+
noteRouteEvent,
|
|
168
|
+
runRefreshCycle,
|
|
169
|
+
state: () => ({ gatePending, inProgress, queued, pendingEvents }),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
@@ -6,16 +6,20 @@
|
|
|
6
6
|
* generation.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { contextSet } from "../../context-var.js";
|
|
9
|
+
import { contextSet, hasContextVars } from "../../context-var.js";
|
|
10
10
|
import {
|
|
11
11
|
encodePathParam,
|
|
12
12
|
substituteRouteParams,
|
|
13
13
|
runWithConcurrency,
|
|
14
14
|
groupByConcurrency,
|
|
15
15
|
notifyOnError,
|
|
16
|
+
resolvePrerenderError,
|
|
16
17
|
stageBuildAssetModule,
|
|
17
18
|
} from "../utils/prerender-utils.js";
|
|
18
19
|
import type { DiscoveryState } from "./state.js";
|
|
20
|
+
import { createRangoDebugger, NS } from "../debug.js";
|
|
21
|
+
|
|
22
|
+
const debug = createRangoDebugger(NS.prerender);
|
|
19
23
|
|
|
20
24
|
/**
|
|
21
25
|
* Expand prerender routes into concrete URLs and render them via the
|
|
@@ -30,6 +34,12 @@ export async function expandPrerenderRoutes(
|
|
|
30
34
|
): Promise<void> {
|
|
31
35
|
if (!state.opts?.enableBuildPrerender || !state.isBuildMode) return;
|
|
32
36
|
|
|
37
|
+
const overallStart = debug ? performance.now() : 0;
|
|
38
|
+
debug?.(
|
|
39
|
+
"expandPrerenderRoutes: start (%d router manifest(s))",
|
|
40
|
+
allManifests.length,
|
|
41
|
+
);
|
|
42
|
+
|
|
33
43
|
type PrerenderEntry = {
|
|
34
44
|
urlPath: string;
|
|
35
45
|
routeName: string;
|
|
@@ -51,103 +61,170 @@ export async function expandPrerenderRoutes(
|
|
|
51
61
|
return substituteRouteParams(pattern, params);
|
|
52
62
|
};
|
|
53
63
|
|
|
64
|
+
let resolvedRoutes = 0;
|
|
65
|
+
let totalDynamic = 0;
|
|
66
|
+
|
|
67
|
+
// Count dynamic routes upfront for progress reporting
|
|
54
68
|
for (const { manifest } of allManifests) {
|
|
55
69
|
if (!manifest.prerenderRoutes) continue;
|
|
56
|
-
const defs = manifest._prerenderDefs || {};
|
|
57
70
|
for (const routeName of manifest.prerenderRoutes) {
|
|
58
71
|
const pattern = manifest.routeManifest[routeName];
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
72
|
+
if (pattern && (pattern.includes(":") || pattern.includes("*"))) {
|
|
73
|
+
totalDynamic++;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Periodic progress log so long getParams() calls don't look stalled
|
|
79
|
+
const paramsStart = performance.now();
|
|
80
|
+
const progressInterval =
|
|
81
|
+
totalDynamic > 0
|
|
82
|
+
? setInterval(() => {
|
|
83
|
+
const elapsed = ((performance.now() - paramsStart) / 1000).toFixed(1);
|
|
84
|
+
console.log(
|
|
85
|
+
`[rango] Resolving prerender params... ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`,
|
|
86
|
+
);
|
|
87
|
+
}, 5000)
|
|
88
|
+
: undefined;
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
for (const { manifest } of allManifests) {
|
|
92
|
+
if (!manifest.prerenderRoutes) continue;
|
|
93
|
+
const defs = manifest._prerenderDefs || {};
|
|
94
|
+
const passthroughSet = new Set(manifest.passthroughRoutes || []);
|
|
95
|
+
for (const routeName of manifest.prerenderRoutes) {
|
|
96
|
+
const pattern = manifest.routeManifest[routeName];
|
|
97
|
+
if (!pattern) continue;
|
|
98
|
+
const def = defs[routeName];
|
|
99
|
+
const isPassthroughRoute = passthroughSet.has(routeName);
|
|
100
|
+
const hasDynamic = pattern.includes(":") || pattern.includes("*");
|
|
101
|
+
if (!hasDynamic) {
|
|
102
|
+
// Static route: use pattern directly (strip trailing slash for URL)
|
|
103
|
+
entries.push({
|
|
104
|
+
urlPath: pattern.replace(/\/$/, "") || "/",
|
|
105
|
+
routeName,
|
|
106
|
+
concurrency: 1,
|
|
107
|
+
isPassthroughRoute,
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
// Dynamic route: call getParams() to enumerate param combinations
|
|
111
|
+
if (def?.getParams) {
|
|
112
|
+
const getParamsStart = debug ? performance.now() : 0;
|
|
113
|
+
try {
|
|
114
|
+
const buildVars: Record<string, any> = {};
|
|
115
|
+
const buildEnv = state.resolvedBuildEnv;
|
|
116
|
+
const getParamsCtx = {
|
|
117
|
+
build: true as const,
|
|
118
|
+
dev: !state.isBuildMode,
|
|
119
|
+
set: ((keyOrVar: any, value: any) => {
|
|
120
|
+
contextSet(buildVars, keyOrVar, value);
|
|
121
|
+
}) as any,
|
|
122
|
+
reverse: getParamsReverse,
|
|
123
|
+
get env() {
|
|
124
|
+
if (buildEnv !== undefined) return buildEnv;
|
|
125
|
+
throw new Error(
|
|
126
|
+
"[rango] ctx.env is not available during build-time getParams(). " +
|
|
127
|
+
"Configure buildEnv in your rango() plugin options to enable build-time env access.",
|
|
128
|
+
);
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
const paramsList = await def.getParams(getParamsCtx);
|
|
132
|
+
debug?.(
|
|
133
|
+
"getParams %s -> %d params (%sms)",
|
|
134
|
+
routeName,
|
|
135
|
+
paramsList.length,
|
|
136
|
+
(performance.now() - getParamsStart).toFixed(1),
|
|
93
137
|
);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
138
|
+
const concurrency = def.options?.concurrency ?? 1;
|
|
139
|
+
const hasBuildVars = hasContextVars(buildVars);
|
|
140
|
+
for (const params of paramsList) {
|
|
141
|
+
let url = substituteRouteParams(
|
|
142
|
+
pattern,
|
|
143
|
+
params as Record<string, string>,
|
|
144
|
+
encodePathParam,
|
|
145
|
+
);
|
|
146
|
+
// Anonymous wildcard fallback: use conventional keys if provided
|
|
147
|
+
if (url.includes("*")) {
|
|
148
|
+
const wildcardValue =
|
|
149
|
+
(params as Record<string, string>)["*"] ??
|
|
150
|
+
(params as Record<string, string>).splat;
|
|
151
|
+
if (wildcardValue !== undefined) {
|
|
152
|
+
url = url.replace(
|
|
153
|
+
/\*[^/]*$/,
|
|
154
|
+
encodePathParam(wildcardValue),
|
|
155
|
+
);
|
|
156
|
+
}
|
|
101
157
|
}
|
|
158
|
+
entries.push({
|
|
159
|
+
urlPath: url.replace(/\/$/, "") || "/",
|
|
160
|
+
routeName,
|
|
161
|
+
concurrency,
|
|
162
|
+
...(hasBuildVars ? { buildVars } : {}),
|
|
163
|
+
isPassthroughRoute,
|
|
164
|
+
});
|
|
102
165
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
166
|
+
resolvedRoutes++;
|
|
167
|
+
} catch (err: any) {
|
|
168
|
+
resolvedRoutes++;
|
|
169
|
+
// Skip in getParams() skips the entire route
|
|
170
|
+
if (err.name === "Skip") {
|
|
171
|
+
console.log(
|
|
172
|
+
`[rango] SKIP route "${routeName}" - ${err.message}`,
|
|
173
|
+
);
|
|
174
|
+
notifyOnError(
|
|
175
|
+
registry,
|
|
176
|
+
err,
|
|
177
|
+
"prerender",
|
|
178
|
+
routeName,
|
|
179
|
+
undefined,
|
|
180
|
+
true,
|
|
181
|
+
);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
// Regular error: fail the build
|
|
185
|
+
console.error(
|
|
186
|
+
`[rango] Failed to get params for prerender route "${routeName}": ${err.message}`,
|
|
124
187
|
);
|
|
125
|
-
|
|
188
|
+
notifyOnError(registry, err, "prerender", routeName);
|
|
189
|
+
throw err;
|
|
126
190
|
}
|
|
127
|
-
|
|
128
|
-
console.
|
|
129
|
-
`[
|
|
191
|
+
} else {
|
|
192
|
+
console.warn(
|
|
193
|
+
`[rango] Dynamic prerender route "${routeName}" has no getParams(), skipping`,
|
|
130
194
|
);
|
|
131
|
-
notifyOnError(registry, err, "prerender", routeName);
|
|
132
|
-
throw err;
|
|
133
195
|
}
|
|
134
|
-
} else {
|
|
135
|
-
console.warn(
|
|
136
|
-
`[rsc-router] Dynamic prerender route "${routeName}" has no getParams(), skipping`,
|
|
137
|
-
);
|
|
138
196
|
}
|
|
139
197
|
}
|
|
140
198
|
}
|
|
199
|
+
} finally {
|
|
200
|
+
if (progressInterval) {
|
|
201
|
+
clearInterval(progressInterval);
|
|
202
|
+
const elapsed = ((performance.now() - paramsStart) / 1000).toFixed(1);
|
|
203
|
+
console.log(
|
|
204
|
+
`[rango] Resolved prerender params: ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
141
207
|
}
|
|
142
208
|
|
|
143
|
-
if (entries.length === 0)
|
|
209
|
+
if (entries.length === 0) {
|
|
210
|
+
debug?.(
|
|
211
|
+
"no prerender entries (done in %sms)",
|
|
212
|
+
(performance.now() - overallStart).toFixed(1),
|
|
213
|
+
);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
144
216
|
|
|
145
217
|
// Determine the max concurrency for the log header
|
|
146
218
|
const maxConcurrency = Math.max(...entries.map((e) => e.concurrency));
|
|
147
219
|
const concurrencyNote =
|
|
148
220
|
maxConcurrency > 1 ? ` (concurrency: ${maxConcurrency})` : "";
|
|
149
221
|
console.log(
|
|
150
|
-
`[
|
|
222
|
+
`[rango] Pre-rendering ${entries.length} URL(s)${concurrencyNote}...`,
|
|
223
|
+
);
|
|
224
|
+
debug?.(
|
|
225
|
+
"prerender loop: %d entries, max concurrency %d",
|
|
226
|
+
entries.length,
|
|
227
|
+
maxConcurrency,
|
|
151
228
|
);
|
|
152
229
|
|
|
153
230
|
const { hashParams } = await rscEnv.runner.import("@rangojs/router/build");
|
|
@@ -155,6 +232,10 @@ export async function expandPrerenderRoutes(
|
|
|
155
232
|
const manifestEntries: Record<string, string> = {};
|
|
156
233
|
let doneCount = 0;
|
|
157
234
|
let skipCount = 0;
|
|
235
|
+
// #587: a render error reaches here (matchForPrerender now re-throws it rather
|
|
236
|
+
// than baking the error boundary). Default "fail" fails the build; "warn" logs
|
|
237
|
+
// and skips baking the URL.
|
|
238
|
+
const prerenderOnError = state.opts?.prerenderOnError ?? "fail";
|
|
158
239
|
const startTotal = performance.now();
|
|
159
240
|
|
|
160
241
|
// Group entries by concurrency for batched rendering.
|
|
@@ -175,6 +256,7 @@ export async function expandPrerenderRoutes(
|
|
|
175
256
|
{},
|
|
176
257
|
entry.buildVars,
|
|
177
258
|
entry.isPassthroughRoute,
|
|
259
|
+
state.resolvedBuildEnv,
|
|
178
260
|
);
|
|
179
261
|
if (!result) continue;
|
|
180
262
|
|
|
@@ -182,7 +264,7 @@ export async function expandPrerenderRoutes(
|
|
|
182
264
|
if (result.passthrough) {
|
|
183
265
|
const elapsed = (performance.now() - startUrl).toFixed(0);
|
|
184
266
|
console.log(
|
|
185
|
-
`[
|
|
267
|
+
`[rango] PASS ${entry.urlPath.padEnd(40)} (${elapsed}ms) - live fallback`,
|
|
186
268
|
);
|
|
187
269
|
doneCount++;
|
|
188
270
|
break;
|
|
@@ -203,10 +285,9 @@ export async function expandPrerenderRoutes(
|
|
|
203
285
|
const interceptKey = `${result.routeName}/${paramHash}/i`;
|
|
204
286
|
const interceptValue = JSON.stringify({
|
|
205
287
|
segments: [...result.segments, ...result.interceptSegments],
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
},
|
|
288
|
+
// interceptHandles is the pre-encoded MERGED (main + intercept)
|
|
289
|
+
// handle string (the producer merged before encoding).
|
|
290
|
+
handles: result.interceptHandles ?? "",
|
|
210
291
|
});
|
|
211
292
|
manifestEntries[interceptKey] = stageBuildAssetModule(
|
|
212
293
|
state.projectRoot,
|
|
@@ -216,40 +297,27 @@ export async function expandPrerenderRoutes(
|
|
|
216
297
|
}
|
|
217
298
|
const elapsed = (performance.now() - startUrl).toFixed(0);
|
|
218
299
|
console.log(
|
|
219
|
-
`[
|
|
300
|
+
`[rango] OK ${entry.urlPath.padEnd(40)} (${elapsed}ms)`,
|
|
220
301
|
);
|
|
221
302
|
doneCount++;
|
|
222
303
|
break;
|
|
223
304
|
} catch (err: any) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
`[rsc-router] SKIP ${entry.urlPath.padEnd(40)} (${elapsed}ms) - ${err.message}`,
|
|
228
|
-
);
|
|
229
|
-
skipCount++;
|
|
230
|
-
notifyOnError(
|
|
231
|
-
registry,
|
|
232
|
-
err,
|
|
233
|
-
"prerender",
|
|
234
|
-
entry.routeName,
|
|
235
|
-
entry.urlPath,
|
|
236
|
-
true,
|
|
237
|
-
);
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
// Regular error: log, notify, and fail the build
|
|
305
|
+
// Skip, or a render error under prerender.onError "warn": skip the
|
|
306
|
+
// URL (never bake the error page, #587). A render error under the
|
|
307
|
+
// default "fail" re-throws below to fail the build.
|
|
241
308
|
const elapsed = (performance.now() - startUrl).toFixed(0);
|
|
242
|
-
|
|
243
|
-
`[rsc-router] FAIL ${entry.urlPath.padEnd(40)} (${elapsed}ms) - ${err.message}`,
|
|
244
|
-
);
|
|
245
|
-
notifyOnError(
|
|
309
|
+
resolvePrerenderError(
|
|
246
310
|
registry,
|
|
247
311
|
err,
|
|
312
|
+
prerenderOnError,
|
|
313
|
+
entry.urlPath.padEnd(40),
|
|
314
|
+
elapsed,
|
|
248
315
|
"prerender",
|
|
249
316
|
entry.routeName,
|
|
250
317
|
entry.urlPath,
|
|
251
318
|
);
|
|
252
|
-
|
|
319
|
+
skipCount++;
|
|
320
|
+
break;
|
|
253
321
|
}
|
|
254
322
|
}
|
|
255
323
|
},
|
|
@@ -263,7 +331,14 @@ export async function expandPrerenderRoutes(
|
|
|
263
331
|
const parts = [`${doneCount} done`];
|
|
264
332
|
if (skipCount > 0) parts.push(`${skipCount} skipped`);
|
|
265
333
|
console.log(
|
|
266
|
-
`[
|
|
334
|
+
`[rango] Pre-render complete: ${parts.join(", ")} (${totalElapsed}ms total)`,
|
|
335
|
+
);
|
|
336
|
+
debug?.(
|
|
337
|
+
"expandPrerenderRoutes done: %d done, %d skipped, %sms (overall %sms)",
|
|
338
|
+
doneCount,
|
|
339
|
+
skipCount,
|
|
340
|
+
totalElapsed,
|
|
341
|
+
(performance.now() - overallStart).toFixed(1),
|
|
267
342
|
);
|
|
268
343
|
}
|
|
269
344
|
|
|
@@ -285,19 +360,24 @@ export async function renderStaticHandlers(
|
|
|
285
360
|
)
|
|
286
361
|
return;
|
|
287
362
|
|
|
363
|
+
const overallStart = debug ? performance.now() : 0;
|
|
364
|
+
debug?.(
|
|
365
|
+
"renderStaticHandlers: start (%d static module(s))",
|
|
366
|
+
state.resolvedStaticModules.size,
|
|
367
|
+
);
|
|
368
|
+
|
|
288
369
|
const manifestEntries: Record<string, string> = {};
|
|
289
370
|
let staticDone = 0;
|
|
290
371
|
let staticSkip = 0;
|
|
291
372
|
let totalStaticCount = 0;
|
|
373
|
+
const prerenderOnError = state.opts?.prerenderOnError ?? "fail";
|
|
292
374
|
|
|
293
375
|
// Count handlers for the log header
|
|
294
376
|
for (const [, exportNames] of state.resolvedStaticModules) {
|
|
295
377
|
totalStaticCount += exportNames.length;
|
|
296
378
|
}
|
|
297
379
|
const startStatic = performance.now();
|
|
298
|
-
console.log(
|
|
299
|
-
`[rsc-router] Rendering ${totalStaticCount} static handler(s)...`,
|
|
300
|
-
);
|
|
380
|
+
console.log(`[rango] Rendering ${totalStaticCount} static handler(s)...`);
|
|
301
381
|
|
|
302
382
|
for (const [moduleId, exportNames] of state.resolvedStaticModules) {
|
|
303
383
|
let mod: any;
|
|
@@ -305,7 +385,7 @@ export async function renderStaticHandlers(
|
|
|
305
385
|
mod = await rscEnv!.runner.import(moduleId);
|
|
306
386
|
} catch (err: any) {
|
|
307
387
|
console.error(
|
|
308
|
-
`[
|
|
388
|
+
`[rango] Failed to import static module ${moduleId}: ${err.message}`,
|
|
309
389
|
);
|
|
310
390
|
notifyOnError(registry, err, "static");
|
|
311
391
|
throw err;
|
|
@@ -326,9 +406,12 @@ export async function renderStaticHandlers(
|
|
|
326
406
|
def.handler,
|
|
327
407
|
def.$$id,
|
|
328
408
|
(def as any).$$routePrefix,
|
|
409
|
+
state.resolvedBuildEnv,
|
|
410
|
+
!state.isBuildMode,
|
|
329
411
|
);
|
|
330
412
|
if (result) {
|
|
331
|
-
|
|
413
|
+
// result.handles is the pre-encoded handle string ("" when none).
|
|
414
|
+
const hasHandles = result.handles !== "";
|
|
332
415
|
const exportValue = hasHandles
|
|
333
416
|
? JSON.stringify(result)
|
|
334
417
|
: JSON.stringify(result.encoded);
|
|
@@ -338,37 +421,29 @@ export async function renderStaticHandlers(
|
|
|
338
421
|
exportValue,
|
|
339
422
|
);
|
|
340
423
|
const elapsed = (performance.now() - startHandler).toFixed(0);
|
|
341
|
-
console.log(
|
|
342
|
-
`[rsc-router] OK ${name.padEnd(40)} (${elapsed}ms)`,
|
|
343
|
-
);
|
|
424
|
+
console.log(`[rango] OK ${name.padEnd(40)} (${elapsed}ms)`);
|
|
344
425
|
staticDone++;
|
|
345
426
|
handled = true;
|
|
346
427
|
break;
|
|
347
428
|
}
|
|
348
429
|
} catch (err: any) {
|
|
349
|
-
|
|
350
|
-
const elapsed = (performance.now() - startHandler).toFixed(0);
|
|
351
|
-
console.log(
|
|
352
|
-
`[rsc-router] SKIP ${name.padEnd(40)} (${elapsed}ms) - ${err.message}`,
|
|
353
|
-
);
|
|
354
|
-
staticSkip++;
|
|
355
|
-
notifyOnError(registry, err, "static", undefined, undefined, true);
|
|
356
|
-
handled = true;
|
|
357
|
-
break;
|
|
358
|
-
}
|
|
359
|
-
// Regular error: log, notify, and fail the build
|
|
430
|
+
// Same Skip/warn/fail policy as the prerender loop (shared helper).
|
|
360
431
|
const elapsed = (performance.now() - startHandler).toFixed(0);
|
|
361
|
-
|
|
362
|
-
|
|
432
|
+
resolvePrerenderError(
|
|
433
|
+
registry,
|
|
434
|
+
err,
|
|
435
|
+
prerenderOnError,
|
|
436
|
+
name.padEnd(40),
|
|
437
|
+
elapsed,
|
|
438
|
+
"static",
|
|
363
439
|
);
|
|
364
|
-
|
|
365
|
-
|
|
440
|
+
staticSkip++;
|
|
441
|
+
handled = true;
|
|
442
|
+
break;
|
|
366
443
|
}
|
|
367
444
|
}
|
|
368
445
|
if (!handled) {
|
|
369
|
-
console.warn(
|
|
370
|
-
`[rsc-router] No router could render static handler "${name}"`,
|
|
371
|
-
);
|
|
446
|
+
console.warn(`[rango] No router could render static handler "${name}"`);
|
|
372
447
|
}
|
|
373
448
|
}
|
|
374
449
|
}
|
|
@@ -380,6 +455,13 @@ export async function renderStaticHandlers(
|
|
|
380
455
|
const staticParts = [`${staticDone} done`];
|
|
381
456
|
if (staticSkip > 0) staticParts.push(`${staticSkip} skipped`);
|
|
382
457
|
console.log(
|
|
383
|
-
`[
|
|
458
|
+
`[rango] Static render complete: ${staticParts.join(", ")} (${totalStaticElapsed}ms total)`,
|
|
459
|
+
);
|
|
460
|
+
debug?.(
|
|
461
|
+
"renderStaticHandlers done: %d done, %d skipped, %sms (overall %sms)",
|
|
462
|
+
staticDone,
|
|
463
|
+
staticSkip,
|
|
464
|
+
totalStaticElapsed,
|
|
465
|
+
(performance.now() - overallStart).toFixed(1),
|
|
384
466
|
);
|
|
385
467
|
}
|