@rangojs/router 0.0.0-experimental.bd6e11bc → 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 +296 -887
- package/dist/bin/rango.js +459 -91
- package/dist/testing/vitest.js +36 -2
- package/dist/vite/index.js +1708 -414
- package/package.json +35 -10
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +82 -5
- package/skills/bundle-analysis/SKILL.md +2 -2
- package/skills/cache-guide/SKILL.md +14 -9
- package/skills/caching/SKILL.md +221 -12
- 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 +83 -2
- 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 +11 -3
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +9 -9
- package/skills/hooks/SKILL.md +73 -900
- 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 +84 -7
- package/skills/i18n/SKILL.md +1 -1
- package/skills/intercept/SKILL.md +51 -17
- package/skills/layout/SKILL.md +38 -16
- package/skills/links/SKILL.md +1 -1
- package/skills/loader/SKILL.md +48 -20
- package/skills/middleware/SKILL.md +11 -5
- package/skills/migrate-nextjs/SKILL.md +203 -20
- package/skills/migrate-react-router/SKILL.md +59 -675
- 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 +3 -3
- package/skills/observability/SKILL.md +70 -5
- package/skills/parallel/SKILL.md +32 -8
- package/skills/ppr/SKILL.md +622 -0
- package/skills/prerender/SKILL.md +59 -28
- package/skills/rango/SKILL.md +124 -50
- package/skills/response-routes/SKILL.md +78 -46
- package/skills/route/SKILL.md +85 -6
- package/skills/router-setup/SKILL.md +41 -6
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +28 -3
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +1 -1
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +68 -654
- 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 -918
- 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 +47 -17
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +44 -1
- package/src/__augment-tests__/augmented.check.ts +2 -3
- package/src/__internal.ts +0 -65
- package/src/browser/action-coordinator.ts +1 -1
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +14 -27
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +178 -100
- 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 +81 -68
- package/src/browser/navigation-client.ts +115 -70
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +153 -88
- package/src/browser/navigation-transaction.ts +0 -32
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +157 -144
- package/src/browser/prefetch/cache.ts +148 -81
- package/src/browser/prefetch/fetch.ts +231 -51
- package/src/browser/prefetch/queue.ts +25 -7
- package/src/browser/rango-state.ts +157 -115
- package/src/browser/react/Link.tsx +40 -7
- package/src/browser/react/NavigationProvider.tsx +140 -99
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +17 -2
- package/src/browser/react/index.ts +0 -51
- package/src/browser/react/location-state-shared.ts +14 -15
- package/src/browser/react/location-state.ts +0 -1
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +0 -5
- 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 +10 -5
- package/src/browser/react/use-params.ts +0 -2
- package/src/browser/react/use-router.ts +6 -4
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +0 -13
- package/src/browser/response-adapter.ts +74 -8
- package/src/browser/rsc-router.tsx +97 -22
- package/src/browser/scroll-restoration.ts +15 -8
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/server-action-bridge.ts +216 -38
- package/src/browser/types.ts +94 -22
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/generate-manifest.ts +155 -131
- package/src/build/generate-route-types.ts +1 -1
- package/src/build/index.ts +11 -5
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -22
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +12 -1
- package/src/build/route-types/include-resolution.ts +455 -61
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +15 -2
- package/src/build/route-types/router-processing.ts +77 -41
- package/src/build/route-types/source-scan.ts +105 -7
- package/src/build/runtime-discovery.ts +4 -1
- 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 -101
- package/src/cache/cache-scope.ts +159 -54
- 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 +2170 -377
- 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 +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -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/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 +39 -22
- package/src/client.tsx +28 -58
- 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 +13 -1
- package/src/decode-loader-results.ts +18 -2
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +0 -3
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +57 -40
- 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 +7 -0
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +1 -65
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +6 -2
- package/src/href-client.ts +7 -12
- package/src/index.rsc.ts +88 -8
- package/src/index.ts +90 -16
- package/src/internal-debug.ts +11 -10
- package/src/loader.rsc.ts +19 -9
- package/src/loader.ts +12 -4
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +32 -37
- package/src/prerender.ts +75 -7
- 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 +25 -0
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +13 -49
- package/src/route-definition/dsl-helpers.ts +60 -53
- package/src/route-definition/helper-factories.ts +0 -2
- package/src/route-definition/helpers-types.ts +46 -46
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +6 -1
- package/src/route-definition/use-item-types.ts +3 -6
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +0 -5
- package/src/router/content-negotiation.ts +58 -23
- package/src/router/error-handling.ts +44 -17
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +6 -1
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +35 -2
- package/src/router/lazy-includes.ts +79 -56
- package/src/router/loader-resolution.ts +151 -73
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +76 -52
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +181 -178
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +115 -194
- package/src/router/match-middleware/cache-store.ts +61 -50
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +36 -67
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +0 -116
- package/src/router/middleware.ts +231 -120
- package/src/router/navigation-snapshot.ts +7 -56
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +99 -152
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +111 -66
- package/src/router/preview-match.ts +3 -1
- package/src/router/request-classification.ts +47 -42
- package/src/router/revalidation.ts +75 -81
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +70 -8
- package/src/router/router-options.ts +126 -4
- package/src/router/segment-resolution/fresh.ts +104 -80
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +155 -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 +215 -304
- 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 +35 -15
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +54 -35
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +9 -23
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -64
- package/src/router/types.ts +1 -63
- package/src/router/url-params.ts +13 -5
- package/src/router.ts +119 -48
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +1 -0
- package/src/rsc/handler.ts +267 -152
- package/src/rsc/helpers.ts +78 -4
- package/src/rsc/index.ts +1 -4
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +114 -38
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +11 -15
- package/src/rsc/progressive-enhancement.ts +120 -13
- 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 +58 -141
- package/src/rsc/rsc-rendering.ts +492 -49
- package/src/rsc/runtime-warnings.ts +14 -0
- package/src/rsc/server-action.ts +268 -82
- package/src/rsc/shell-capture.ts +1190 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +45 -3
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +31 -26
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +260 -95
- package/src/server/context.ts +99 -9
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +125 -2
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +379 -138
- package/src/ssr/index.tsx +491 -182
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +44 -48
- package/src/testing/collect-handle.ts +14 -31
- package/src/testing/dispatch.ts +533 -160
- package/src/testing/e2e/fixture.ts +45 -11
- package/src/testing/e2e/index.ts +1 -22
- package/src/testing/e2e/matchers.ts +0 -16
- package/src/testing/e2e/parity.ts +85 -4
- package/src/testing/e2e/server.ts +12 -0
- package/src/testing/flight-matchers.ts +7 -14
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +36 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +30 -0
- package/src/testing/flight.ts +145 -70
- package/src/testing/generated-routes.ts +26 -50
- package/src/testing/index.ts +18 -19
- package/src/testing/internal/context.ts +184 -68
- 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 +134 -115
- package/src/testing/run-loader.ts +140 -51
- package/src/testing/run-middleware.ts +59 -33
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +1 -1
- package/src/testing/vitest-stubs/cloudflare-workers.ts +1 -1
- package/src/testing/vitest.ts +138 -16
- 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 +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +15 -15
- package/src/types/handler-context.ts +45 -15
- package/src/types/index.ts +2 -10
- package/src/types/loader-types.ts +6 -3
- package/src/types/request-scope.ts +8 -22
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +100 -13
- package/src/urls/include-helper.ts +10 -12
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -8
- package/src/urls/path-helper-types.ts +52 -14
- package/src/urls/path-helper.ts +5 -54
- package/src/urls/pattern-types.ts +36 -0
- package/src/urls/type-extraction.ts +76 -42
- package/src/urls/urls-function.ts +0 -14
- package/src/use-loader.tsx +0 -186
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/discovery/bundle-postprocess.ts +2 -1
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +34 -43
- package/src/vite/discovery/discovery-errors.ts +61 -0
- package/src/vite/discovery/prerender-collection.ts +33 -46
- package/src/vite/discovery/state.ts +12 -1
- package/src/vite/discovery/virtual-module-codegen.ts +1 -11
- package/src/vite/index.ts +9 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +143 -10
- package/src/vite/plugins/cjs-to-esm.ts +8 -12
- package/src/vite/plugins/client-ref-dedup.ts +0 -11
- package/src/vite/plugins/client-ref-hashing.ts +0 -10
- package/src/vite/plugins/cloudflare-protocol-stub.ts +0 -20
- package/src/vite/plugins/expose-action-id.ts +2 -73
- package/src/vite/plugins/expose-id-utils.ts +85 -56
- package/src/vite/plugins/expose-ids/export-analysis.ts +30 -43
- package/src/vite/plugins/expose-ids/handler-transform.ts +5 -31
- package/src/vite/plugins/expose-ids/loader-transform.ts +12 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +98 -26
- package/src/vite/plugins/expose-internal-ids.ts +10 -1
- package/src/vite/plugins/performance-tracks.ts +0 -3
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +21 -46
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +22 -27
- package/src/vite/plugins/version-plugin.ts +6 -66
- package/src/vite/plugins/virtual-entries.ts +137 -26
- package/src/vite/rango.ts +146 -135
- package/src/vite/router-discovery.ts +189 -48
- package/src/vite/utils/ast-handler-extract.ts +11 -20
- package/src/vite/utils/bundle-analysis.ts +6 -13
- package/src/vite/utils/client-chunks.ts +0 -6
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +0 -22
- package/src/vite/utils/manifest-utils.ts +4 -75
- package/src/vite/utils/package-resolution.ts +1 -73
- package/src/vite/utils/prerender-utils.ts +71 -44
- package/src/vite/utils/shared-utils.ts +55 -37
- 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
|
@@ -17,7 +17,12 @@ import {
|
|
|
17
17
|
export interface FixtureOptions {
|
|
18
18
|
/** Absolute or cwd-relative path to the consumer app under test. */
|
|
19
19
|
root: string;
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Server mode. Required: omitting it would spawn no server in beforeAll and
|
|
22
|
+
* surface only as a bare "Invalid URL" from `url()` at first use, so we fail
|
|
23
|
+
* eagerly at useFixture time instead.
|
|
24
|
+
*/
|
|
25
|
+
mode: "dev" | "build";
|
|
21
26
|
/** Override the server command (default: `pnpm dev` for dev, `pnpm preview` for build). */
|
|
22
27
|
command?: string;
|
|
23
28
|
/** Override the build command (default: `pnpm build`). */
|
|
@@ -32,7 +37,7 @@ export interface FixtureOptions {
|
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
export interface Fixture {
|
|
35
|
-
mode: "dev" | "build"
|
|
40
|
+
mode: "dev" | "build";
|
|
36
41
|
root: string;
|
|
37
42
|
/** Resolve a path against the running server's base URL. */
|
|
38
43
|
url: (url?: string) => string;
|
|
@@ -49,6 +54,11 @@ export function createUseFixture(
|
|
|
49
54
|
test: TestType<any, any>,
|
|
50
55
|
): (options: FixtureOptions) => Fixture {
|
|
51
56
|
return function useFixture(options: FixtureOptions): Fixture {
|
|
57
|
+
if (options.mode !== "dev" && options.mode !== "build") {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`useFixture: mode is required: 'dev' | 'build' (got ${JSON.stringify(options.mode)}).`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
52
62
|
let cleanup: (() => Promise<void>) | undefined;
|
|
53
63
|
let baseURL!: string;
|
|
54
64
|
|
|
@@ -79,6 +89,14 @@ export function createUseFixture(
|
|
|
79
89
|
...options.cliOptions,
|
|
80
90
|
env: cliEnv,
|
|
81
91
|
});
|
|
92
|
+
// Assign cleanup immediately after spawn, before any await that can
|
|
93
|
+
// throw (findPort/waitForReady). Otherwise a beforeAll failure leaves
|
|
94
|
+
// afterAll's cleanup a no-op and orphans the dev server (plus workerd
|
|
95
|
+
// children) for the rest of the run.
|
|
96
|
+
cleanup = async () => {
|
|
97
|
+
proc!.kill();
|
|
98
|
+
await proc!.done;
|
|
99
|
+
};
|
|
82
100
|
const port = await proc.findPort();
|
|
83
101
|
baseURL = `http://localhost:${port}`;
|
|
84
102
|
const readyUrl = options.readyPath
|
|
@@ -96,10 +114,6 @@ export function createUseFixture(
|
|
|
96
114
|
if (options.isolatedServer) {
|
|
97
115
|
await warmupDevServer(readyUrl);
|
|
98
116
|
}
|
|
99
|
-
cleanup = async () => {
|
|
100
|
-
proc!.kill();
|
|
101
|
-
await proc!.done;
|
|
102
|
-
};
|
|
103
117
|
}
|
|
104
118
|
|
|
105
119
|
if (options.mode === "build") {
|
|
@@ -112,7 +126,25 @@ export function createUseFixture(
|
|
|
112
126
|
...options.cliOptions,
|
|
113
127
|
env: cliEnv,
|
|
114
128
|
});
|
|
115
|
-
await
|
|
129
|
+
// The build is a finite process, but assign cleanup before the await
|
|
130
|
+
// so a hung build is still killed if beforeAll is torn down.
|
|
131
|
+
cleanup = async () => {
|
|
132
|
+
buildProc.kill();
|
|
133
|
+
await buildProc.done;
|
|
134
|
+
};
|
|
135
|
+
// Fail loudly on a nonzero build exit. Without this a failed build is
|
|
136
|
+
// swallowed and preview serves the previous stale dist/ (green
|
|
137
|
+
// production tests against old code), or times out with "Server not
|
|
138
|
+
// ready" that never mentions the build failure. The captured build
|
|
139
|
+
// output (stdout/stderr above) precedes this throw.
|
|
140
|
+
const code = await buildProc.exitCode;
|
|
141
|
+
if (code !== 0) {
|
|
142
|
+
throw new Error(
|
|
143
|
+
`Build failed with exit code ${code} for "${options.root}" ` +
|
|
144
|
+
`(command: ${options.buildCommand ?? "pnpm build"}). ` +
|
|
145
|
+
`See the captured build output above for the cause.`,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
116
148
|
}
|
|
117
149
|
proc = runCli({
|
|
118
150
|
command: options.command ?? `pnpm preview`,
|
|
@@ -121,6 +153,12 @@ export function createUseFixture(
|
|
|
121
153
|
...options.cliOptions,
|
|
122
154
|
env: cliEnv,
|
|
123
155
|
});
|
|
156
|
+
// Switch cleanup to the preview process immediately after spawn, before
|
|
157
|
+
// findPort/waitForReady can throw and orphan it.
|
|
158
|
+
cleanup = async () => {
|
|
159
|
+
proc!.kill();
|
|
160
|
+
await proc!.done;
|
|
161
|
+
};
|
|
124
162
|
const port = await proc.findPort();
|
|
125
163
|
baseURL = `http://localhost:${port}`;
|
|
126
164
|
const buildReadyUrl = options.readyPath
|
|
@@ -130,10 +168,6 @@ export function createUseFixture(
|
|
|
130
168
|
stdout: proc!.stdout(),
|
|
131
169
|
stderr: proc!.stderr(),
|
|
132
170
|
}));
|
|
133
|
-
cleanup = async () => {
|
|
134
|
-
proc!.kill();
|
|
135
|
-
await proc!.done;
|
|
136
|
-
};
|
|
137
171
|
}
|
|
138
172
|
});
|
|
139
173
|
|
package/src/testing/e2e/index.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
// Public entry for the consumer e2e harness. `createRangoE2E({ test, expect })`
|
|
2
|
-
// wires the server fixture, page helpers, parity helpers, and matchers around
|
|
3
|
-
// the consumer's Playwright `test`/`expect` objects so this module never
|
|
4
|
-
// imports `@playwright/test` at runtime (type-only imports are erased).
|
|
5
|
-
|
|
6
1
|
import type { Expect, TestType } from "@playwright/test";
|
|
7
2
|
import {
|
|
8
3
|
createUseFixture,
|
|
@@ -35,14 +30,9 @@ import {
|
|
|
35
30
|
} from "./parity.js";
|
|
36
31
|
import { createRangoMatchers, type RangoMatchers } from "./matchers.js";
|
|
37
32
|
|
|
38
|
-
// Cache-status helpers are pure (cache-status.ts imports only TYPES), so they
|
|
39
|
-
// are safe to surface from this Playwright-runnable entry. Importing them from
|
|
40
|
-
// the `@rangojs/router/testing` barrel does NOT work in a plain Playwright
|
|
41
|
-
// runner — the barrel transitively pulls the build-only `@rangojs/router:version`
|
|
42
|
-
// virtual via the route-manifest path. Asserting cache status on a real
|
|
43
|
-
// response is an e2e activity, so this is their Playwright-safe home.
|
|
44
33
|
export {
|
|
45
34
|
assertCacheStatus,
|
|
35
|
+
assertCacheDecision,
|
|
46
36
|
parseCacheHeader,
|
|
47
37
|
createCacheSink,
|
|
48
38
|
filterCacheDecisions,
|
|
@@ -50,9 +40,6 @@ export {
|
|
|
50
40
|
type ExpectedCacheStatus,
|
|
51
41
|
type CacheStatusTarget,
|
|
52
42
|
} from "../cache-status.js";
|
|
53
|
-
|
|
54
|
-
// Re-export standalone helpers and all public types so the barrel can re-export
|
|
55
|
-
// them from a single module.
|
|
56
43
|
export {
|
|
57
44
|
testId,
|
|
58
45
|
waitForHydration,
|
|
@@ -87,7 +74,6 @@ export interface RangoE2E extends PageHelpers, Parity {
|
|
|
87
74
|
useFixture: (options: FixtureOptions) => Fixture;
|
|
88
75
|
testNoJs: TestType<any, any>;
|
|
89
76
|
rangoMatchers: RangoMatchers;
|
|
90
|
-
// Standalone helpers, re-surfaced for convenience.
|
|
91
77
|
testId: typeof testId;
|
|
92
78
|
waitForHydration: typeof waitForHydration;
|
|
93
79
|
waitForNavigation: typeof waitForNavigation;
|
|
@@ -102,12 +88,6 @@ export interface RangoE2E extends PageHelpers, Parity {
|
|
|
102
88
|
measureTime: typeof measureTime;
|
|
103
89
|
}
|
|
104
90
|
|
|
105
|
-
/**
|
|
106
|
-
* Wire the full e2e harness around a consumer's Playwright `test`/`expect`.
|
|
107
|
-
*
|
|
108
|
-
* @param defaultRoot - fallback app root for `parityDescribe` when a call omits
|
|
109
|
-
* `options.root`.
|
|
110
|
-
*/
|
|
111
91
|
export function createRangoE2E({
|
|
112
92
|
test,
|
|
113
93
|
expect,
|
|
@@ -132,7 +112,6 @@ export function createRangoE2E({
|
|
|
132
112
|
rangoMatchers,
|
|
133
113
|
...parity,
|
|
134
114
|
...pageHelpers,
|
|
135
|
-
// Standalone helpers.
|
|
136
115
|
testId,
|
|
137
116
|
waitForHydration,
|
|
138
117
|
waitForNavigation,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// Custom Playwright matchers for Rango assertions. Returned as an object
|
|
2
|
-
// suitable for `expect.extend(...)`. v1 ships only `toHaveRangoPathname`.
|
|
3
|
-
|
|
4
1
|
import type { Expect, Page } from "@playwright/test";
|
|
5
2
|
|
|
6
3
|
interface MatcherResult {
|
|
@@ -12,17 +9,6 @@ export interface RangoMatchers {
|
|
|
12
9
|
toHaveRangoPathname: (page: Page, expected: string) => MatcherResult;
|
|
13
10
|
}
|
|
14
11
|
|
|
15
|
-
/**
|
|
16
|
-
* Build the matcher object for `expect.extend(createRangoMatchers(expect))`.
|
|
17
|
-
*
|
|
18
|
-
* `toHaveRangoPathname(page, expected)` asserts that the pathname of the page's
|
|
19
|
-
* current URL equals `expected`.
|
|
20
|
-
*
|
|
21
|
-
* TODO: `toHaveSegments` / `toHaveParams` are intentionally not implemented.
|
|
22
|
-
* They require a client-emitted signal (the active segment chain / resolved
|
|
23
|
-
* params exposed on the page) that does not exist yet; implementing them by
|
|
24
|
-
* scraping the DOM would be a guess. Add them once the router emits that signal.
|
|
25
|
-
*/
|
|
26
12
|
export function createRangoMatchers(_expect: Expect): RangoMatchers {
|
|
27
13
|
return {
|
|
28
14
|
toHaveRangoPathname(page: Page, expected: string): MatcherResult {
|
|
@@ -39,8 +25,6 @@ export function createRangoMatchers(_expect: Expect): RangoMatchers {
|
|
|
39
25
|
};
|
|
40
26
|
}
|
|
41
27
|
|
|
42
|
-
// Type augmentation so consumers can call `await expect(page).toHaveRangoPathname("/x")`
|
|
43
|
-
// after `expect.extend(rangoMatchers)`, without re-declaring the matcher.
|
|
44
28
|
declare global {
|
|
45
29
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
46
30
|
namespace PlaywrightTest {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { Expect, Page, TestType } from "@playwright/test";
|
|
8
8
|
import type { Fixture, FixtureOptions } from "./fixture.js";
|
|
9
|
+
import { DEFAULT_STATE_COOKIE_PREFIX } from "../../browser/cookie-name.js";
|
|
9
10
|
|
|
10
11
|
export interface ParityDescribeOptions extends Partial<
|
|
11
12
|
Omit<FixtureOptions, "mode">
|
|
@@ -30,6 +31,15 @@ export interface ExpectParityOptions {
|
|
|
30
31
|
* transport being snapshotted.
|
|
31
32
|
*/
|
|
32
33
|
waitFor?: (page: Page) => Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Cookie NAMES to exclude from the JS-vs-no-JS jar comparison, matched exactly
|
|
36
|
+
* (string) or by pattern (RegExp). The rango state cookie (default prefix
|
|
37
|
+
* `rango-state`) is ALWAYS excluded — it is written/rotated only by the client
|
|
38
|
+
* runtime, so it is JS-only by design and never appears in the no-JS jar. Use
|
|
39
|
+
* this for a custom `stateCookiePrefix` (e.g. `[/^myapp-state_/]`) or any other
|
|
40
|
+
* volatile/JS-only cookie (analytics, CSRF) that should not break parity.
|
|
41
|
+
*/
|
|
42
|
+
ignoreCookies?: ReadonlyArray<string | RegExp>;
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
export interface Parity {
|
|
@@ -76,6 +86,31 @@ export interface Parity {
|
|
|
76
86
|
* are therefore NOT compared — a PE/JS divergence in an HttpOnly cookie will
|
|
77
87
|
* not be caught here. Assert on those via `read_network_requests` / response
|
|
78
88
|
* Set-Cookie headers in a dedicated test, not expectParity.
|
|
89
|
+
*
|
|
90
|
+
* Submit-intent requirements (the `submit` path runs the intent TWICE against
|
|
91
|
+
* the same server, and compares whole cookie jars from two contexts):
|
|
92
|
+
* - DOUBLE EXECUTION: the JS path submits, then the no-JS pass reloads the
|
|
93
|
+
* same `originUrl` in a fresh context and submits AGAIN. Both hit the one
|
|
94
|
+
* running server, so a non-idempotent action runs twice. The no-JS snapshot
|
|
95
|
+
* then observes BOTH mutations unless the mutated state is per-session /
|
|
96
|
+
* per-context — e.g. an add-to-cart count only reaches the same value on
|
|
97
|
+
* both transports if the cart is session-scoped (the JS context and the
|
|
98
|
+
* fresh no-JS context are distinct sessions). A globally-shared counter
|
|
99
|
+
* would read N after the JS submit and N+1 after the no-JS submit and
|
|
100
|
+
* false-mismatch. Make the action's observable state session/context-scoped,
|
|
101
|
+
* or assert the submit path some other way.
|
|
102
|
+
* - COOKIE JAR vs DELTA: the cookie check compares the WHOLE `document.cookie`
|
|
103
|
+
* of two different contexts. The JS context carries every cookie accumulated
|
|
104
|
+
* before the intent (consent, analytics, prior navigations); the fresh no-JS
|
|
105
|
+
* context starts empty. Unrelated pre-existing cookies therefore false-
|
|
106
|
+
* mismatch — expectParity compares jars, not the per-submit cookie delta.
|
|
107
|
+
* Keep the JS context's pre-intent cookie state minimal, or assert the
|
|
108
|
+
* specific Set-Cookie elsewhere.
|
|
109
|
+
* - RANGO STATE COOKIE: the rango state cookie (default prefix `rango-state`)
|
|
110
|
+
* is written/rotated only by the client runtime, so it is JS-only by design
|
|
111
|
+
* and would always diverge — it is excluded from the comparison
|
|
112
|
+
* automatically. A custom `stateCookiePrefix` (or any other volatile/JS-only
|
|
113
|
+
* cookie) is excluded via `opts.ignoreCookies`.
|
|
79
114
|
*/
|
|
80
115
|
expectParity: (
|
|
81
116
|
page: Page,
|
|
@@ -178,8 +213,16 @@ async function settleSubmit(
|
|
|
178
213
|
`\`observe\`, or pass \`waitFor\` to express the precise post-submit wait.`,
|
|
179
214
|
);
|
|
180
215
|
}
|
|
181
|
-
// Landed but never stabilized within the ceiling:
|
|
182
|
-
//
|
|
216
|
+
// Landed but never stabilized within the ceiling: warn (so a slow/flaky action
|
|
217
|
+
// is visible rather than silently snapshotting a mid-flight DOM), then fall
|
|
218
|
+
// through and snapshot the last-read state — the parity equality assertion
|
|
219
|
+
// still surfaces any JS-vs-no-JS mismatch. A throw here would risk failing a
|
|
220
|
+
// slow-but-correct submit, so this stays a warning.
|
|
221
|
+
console.warn(
|
|
222
|
+
`expectParity: the observed testids [${observe.join(", ")}] did not stabilize ` +
|
|
223
|
+
`within 5s; snapshotting the last-read state. If this is flaky, pass ` +
|
|
224
|
+
`\`waitFor\` to express the precise post-submit wait.`,
|
|
225
|
+
);
|
|
183
226
|
}
|
|
184
227
|
|
|
185
228
|
async function snapshot(
|
|
@@ -188,7 +231,13 @@ async function snapshot(
|
|
|
188
231
|
): Promise<ParitySnapshot> {
|
|
189
232
|
const testIds: Record<string, string | null> = {};
|
|
190
233
|
for (const id of observe) {
|
|
191
|
-
|
|
234
|
+
// Match readObserved: .first() (a testid may repeat) + .catch (a missing
|
|
235
|
+
// testid yields null, not an unhandled rejection).
|
|
236
|
+
testIds[id] = await page
|
|
237
|
+
.locator(`[data-testid="${id}"]`)
|
|
238
|
+
.first()
|
|
239
|
+
.textContent()
|
|
240
|
+
.catch(() => null);
|
|
192
241
|
}
|
|
193
242
|
return {
|
|
194
243
|
testIds,
|
|
@@ -197,6 +246,35 @@ async function snapshot(
|
|
|
197
246
|
};
|
|
198
247
|
}
|
|
199
248
|
|
|
249
|
+
// Reduce a `document.cookie` string to the cookies that should match across the
|
|
250
|
+
// JS and no-JS transports. The rango state cookie (default prefix `rango-state`)
|
|
251
|
+
// is always dropped — it is written/rotated only by the client runtime, so it
|
|
252
|
+
// exists in the JS jar but never the no-JS one. `ignore` drops additional names
|
|
253
|
+
// (a custom stateCookiePrefix, or other JS-only/volatile cookies) by exact
|
|
254
|
+
// string or RegExp match. Returns a normalized, sorted `name=value; ...` string.
|
|
255
|
+
function parityCookies(
|
|
256
|
+
cookieString: string,
|
|
257
|
+
ignore: ReadonlyArray<string | RegExp>,
|
|
258
|
+
): string {
|
|
259
|
+
const isIgnored = (name: string): boolean => {
|
|
260
|
+
if (name.startsWith(DEFAULT_STATE_COOKIE_PREFIX)) return true;
|
|
261
|
+
return ignore.some((m) =>
|
|
262
|
+
typeof m === "string" ? m === name : m.test(name),
|
|
263
|
+
);
|
|
264
|
+
};
|
|
265
|
+
return cookieString
|
|
266
|
+
.split(";")
|
|
267
|
+
.map((c) => c.trim())
|
|
268
|
+
.filter((c) => c.length > 0)
|
|
269
|
+
.filter((c) => {
|
|
270
|
+
const eq = c.indexOf("=");
|
|
271
|
+
const name = eq === -1 ? c : c.slice(0, eq);
|
|
272
|
+
return !isIgnored(name);
|
|
273
|
+
})
|
|
274
|
+
.sort()
|
|
275
|
+
.join("; ");
|
|
276
|
+
}
|
|
277
|
+
|
|
200
278
|
export function createParity({
|
|
201
279
|
test: _test,
|
|
202
280
|
expect,
|
|
@@ -296,7 +374,10 @@ export function createParity({
|
|
|
296
374
|
return url.pathname + url.search + url.hash;
|
|
297
375
|
};
|
|
298
376
|
expect(locationOf(noJsSnapshot.url)).toEqual(locationOf(jsSnapshot.url));
|
|
299
|
-
|
|
377
|
+
const ignore = opts.ignoreCookies ?? [];
|
|
378
|
+
expect(parityCookies(noJsSnapshot.cookies, ignore)).toEqual(
|
|
379
|
+
parityCookies(jsSnapshot.cookies, ignore),
|
|
380
|
+
);
|
|
300
381
|
} finally {
|
|
301
382
|
await noJsContext.close();
|
|
302
383
|
}
|
|
@@ -12,6 +12,12 @@ export type { SpawnOptions };
|
|
|
12
12
|
export interface RunCliHandle {
|
|
13
13
|
proc: ReturnType<typeof x>["process"];
|
|
14
14
|
done: Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolves with the process's exit code (null if killed by signal) when it
|
|
17
|
+
* exits. Unlike `done`, callers can branch on a nonzero code. Used to fail
|
|
18
|
+
* the build step loudly; the long-running serve processes never inspect it.
|
|
19
|
+
*/
|
|
20
|
+
exitCode: Promise<number | null>;
|
|
15
21
|
findPort: (timeoutMs?: number) => Promise<number>;
|
|
16
22
|
kill: () => void;
|
|
17
23
|
stdout: () => string;
|
|
@@ -49,11 +55,16 @@ export function runCli(
|
|
|
49
55
|
console.log(styleText("magenta", label), data.toString());
|
|
50
56
|
}
|
|
51
57
|
});
|
|
58
|
+
let resolveExitCode!: (code: number | null) => void;
|
|
59
|
+
const exitCode = new Promise<number | null>((resolve) => {
|
|
60
|
+
resolveExitCode = resolve;
|
|
61
|
+
});
|
|
52
62
|
const done = new Promise<void>((resolve) => {
|
|
53
63
|
child.on("exit", (code) => {
|
|
54
64
|
if (code !== 0 && code !== 143 && process.platform !== "win32") {
|
|
55
65
|
console.log(styleText("magenta", `${label}`), `exit code ${code}`);
|
|
56
66
|
}
|
|
67
|
+
resolveExitCode(code);
|
|
57
68
|
resolve();
|
|
58
69
|
});
|
|
59
70
|
});
|
|
@@ -106,6 +117,7 @@ export function runCli(
|
|
|
106
117
|
return {
|
|
107
118
|
proc: child,
|
|
108
119
|
done,
|
|
120
|
+
exitCode,
|
|
109
121
|
findPort,
|
|
110
122
|
kill,
|
|
111
123
|
stdout: () => stdout,
|
|
@@ -29,21 +29,19 @@
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
import { expect } from "vitest";
|
|
32
|
-
|
|
32
|
+
// Import from the serializer-free module, NOT ./flight.js: that module
|
|
33
|
+
// top-level imports the vendored react-server-dom serializer, which throws when
|
|
34
|
+
// loaded outside the `react-server` condition. flight-matchers must be
|
|
35
|
+
// importable under the plain node condition (a consumer's shared setupFiles
|
|
36
|
+
// does `expect.extend(flightMatchers)`), so it cannot transitively pull in the
|
|
37
|
+
// serializer.
|
|
38
|
+
import { normalizeFlight } from "./flight-normalize.js";
|
|
33
39
|
|
|
34
40
|
interface MatcherResult {
|
|
35
41
|
pass: boolean;
|
|
36
42
|
message: () => string;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
|
-
/**
|
|
40
|
-
* Matcher object for `expect.extend(flightMatchers)`.
|
|
41
|
-
*
|
|
42
|
-
* - `toMatchFlight(received, expected)` — `received` is a rendered Flight
|
|
43
|
-
* string; passes if its normalized form contains `expected`.
|
|
44
|
-
* - `toMatchFlightSnapshot(received)` — delegates to vitest's snapshot on the
|
|
45
|
-
* normalized Flight string.
|
|
46
|
-
*/
|
|
47
45
|
export const flightMatchers: {
|
|
48
46
|
toMatchFlight(received: string, expected: string): MatcherResult;
|
|
49
47
|
toMatchFlightSnapshot(received: string): MatcherResult;
|
|
@@ -72,12 +70,7 @@ export const flightMatchers: {
|
|
|
72
70
|
},
|
|
73
71
|
|
|
74
72
|
toMatchFlightSnapshot(received: string): MatcherResult {
|
|
75
|
-
// Delegate to vitest's snapshot engine on the normalized string. The
|
|
76
|
-
// snapshot is keyed by the current test file/title (vitest tracks this via
|
|
77
|
-
// the active test context), not by this call site, so delegating through a
|
|
78
|
-
// freshly imported `expect` is reliable.
|
|
79
73
|
expect(normalizeFlight(received)).toMatchSnapshot();
|
|
80
|
-
// toMatchSnapshot throws on mismatch; reaching here means it passed.
|
|
81
74
|
return {
|
|
82
75
|
pass: true,
|
|
83
76
|
message: () => "Flight snapshot matched.",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Volatile leading reference row: `:N<timestamp>` (dev only).
|
|
2
|
+
const REFERENCE_ROW_RE = /^:N[\d.]+\n/;
|
|
3
|
+
// Absolute file:// paths in dev stack rows. Pattern matches frames
|
|
4
|
+
// `["Component","file:///path",<line>,<col>...]` and scrubs the path only.
|
|
5
|
+
const FILE_URL_RE = /file:\/\/[^"\\]+(?=",\d+,\d+)/g;
|
|
6
|
+
|
|
7
|
+
export function normalizeFlight(flight: string): string {
|
|
8
|
+
return flight
|
|
9
|
+
.replace(REFERENCE_ROW_RE, "")
|
|
10
|
+
.replace(FILE_URL_RE, "file://<path>");
|
|
11
|
+
}
|
|
@@ -18,4 +18,40 @@ declare module "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge" {
|
|
|
18
18
|
clientManifest: unknown,
|
|
19
19
|
options?: { onError?: (error: unknown) => string | void },
|
|
20
20
|
): ReadableStream<Uint8Array>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Tag a value as a client reference. Mutates `impl` in place (defining
|
|
24
|
+
* `$$typeof`/`$$id`/`$$async`) and returns it, so a server tree that imports
|
|
25
|
+
* the same module binding renders it as a client boundary (an `I` row) rather
|
|
26
|
+
* than inlining it. `$$id` becomes `${id}#${exportName}`.
|
|
27
|
+
*/
|
|
28
|
+
export function registerClientReference<T>(
|
|
29
|
+
impl: T,
|
|
30
|
+
id: string,
|
|
31
|
+
exportName: string,
|
|
32
|
+
): T;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Vendored react-server-dom CLIENT deserializer wrappers shipped inside
|
|
37
|
+
* @vitejs/plugin-rsc. Used by renderServerTree to turn a Flight wire string
|
|
38
|
+
* back into an inspectable React element tree. These run in the same
|
|
39
|
+
* `react-server`-condition worker as the serializer (deserialize-only never
|
|
40
|
+
* renders, so the client React/react-dom imports they pull are inert).
|
|
41
|
+
*/
|
|
42
|
+
declare module "@vitejs/plugin-rsc/react/browser" {
|
|
43
|
+
export function createFromReadableStream<T = unknown>(
|
|
44
|
+
stream: ReadableStream<Uint8Array>,
|
|
45
|
+
options?: { temporaryReferences?: unknown },
|
|
46
|
+
): Promise<T>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
declare module "@vitejs/plugin-rsc/core/browser" {
|
|
50
|
+
/**
|
|
51
|
+
* Install the module loader the client deserializer resolves client
|
|
52
|
+
* references through. Init-once per worker (first call wins).
|
|
53
|
+
*/
|
|
54
|
+
export function setRequireModule(options: {
|
|
55
|
+
load: (id: string) => unknown;
|
|
56
|
+
}): void;
|
|
21
57
|
}
|