From e421c9dec4e74889905a83047a755241560eaae3 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 12 Apr 2024 16:57:34 +0900 Subject: [PATCH] refactor(react-server): use official `registerClientReference` (#17) * refactor(react-server): use official `registerClientReference` * chore: cleanup --- .../src/features/use-client/react-server.ts | 32 ++++++++----------- examples/react-server/src/types/react.d.ts | 11 ++++--- examples/react-server/vite.config.ts | 4 +-- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/examples/react-server/src/features/use-client/react-server.ts b/examples/react-server/src/features/use-client/react-server.ts index ecdab573..991e4dac 100644 --- a/examples/react-server/src/features/use-client/react-server.ts +++ b/examples/react-server/src/features/use-client/react-server.ts @@ -1,28 +1,24 @@ import { tinyassert } from "@hiogawa/utils"; import type { BundlerConfig, ImportManifestEntry } from "../../types"; +import reactServerDomWebpack from "react-server-dom-webpack/server.edge"; -// $$id: /src/components/counter.tsx::Counter +// https://github.com/facebook/react/blob/c8a035036d0f257c514b3628e927dd9dd26e5a09/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js#L43 + +// $$id: /src/components/counter.tsx#Counter // ⇕ // id: /src/components/counter.tsx // name: Counter -const REFERENCE_SEP = "::"; - -export function createClientReference(id: string, name: string) { - return Object.defineProperties(() => {}, { - $$typeof: { - value: Symbol.for("react.client.reference"), - enumerable: true, - }, - $$id: { - value: [id, name].join(REFERENCE_SEP), - enumerable: true, - }, - $$async: { - value: true, - enumerable: true, +export function registerClientReference(id: string, name: string) { + // reuse everything but $$async: true for simplicity + const reference = reactServerDomWebpack.registerClientReference({}, id, name); + return Object.defineProperties( + {}, + { + ...Object.getOwnPropertyDescriptors(reference), + $$async: { value: true }, }, - }) as any; + ); } export function createBundlerConfig(): BundlerConfig { @@ -31,7 +27,7 @@ export function createBundlerConfig(): BundlerConfig { { get(_target, $$id, _receiver) { tinyassert(typeof $$id === "string"); - let [id, name] = $$id.split(REFERENCE_SEP); + let [id, name] = $$id.split("#"); tinyassert(id); tinyassert(name); return { id, name, chunks: [] } satisfies ImportManifestEntry; diff --git a/examples/react-server/src/types/react.d.ts b/examples/react-server/src/types/react.d.ts index 9903ce9e..835950cb 100644 --- a/examples/react-server/src/types/react.d.ts +++ b/examples/react-server/src/types/react.d.ts @@ -12,7 +12,11 @@ declare module "react-server-dom-webpack/server.edge" { }, ): ReadableStream; - export function decodeReply(body: string | FormData): Promise; + export function registerClientReference( + proxy: T, + id: string, + name: string, + ): T; } // https://github.com/facebook/react/blob/89021fb4ec9aa82194b0788566e736a4cedfc0e4/packages/react-server-dom-webpack/src/ReactFlightDOMClientEdge.js @@ -42,11 +46,8 @@ declare module "react-server-dom-webpack/client.browser" { callServer?: import(".").CallServerCallback; }, ): Promise; - - export function encodeReply( - v: unknown, - ): Promise; } + declare module "react-dom/server.edge" { export * from "react-dom/server"; } diff --git a/examples/react-server/vite.config.ts b/examples/react-server/vite.config.ts index 39dbb2af..72081bb2 100644 --- a/examples/react-server/vite.config.ts +++ b/examples/react-server/vite.config.ts @@ -167,9 +167,9 @@ function vitePluginUseClient(): PluginOption { } } } - let result = `import { createClientReference } from "/src/features/use-client/react-server";\n`; + let result = `import { registerClientReference as $$register } from "/src/features/use-client/react-server";\n`; for (const name of exportNames) { - result += `export const ${name} = createClientReference("${id}", "${name}");\n`; + result += `export const ${name} = $$register("${id}", "${name}");\n`; } debug(`[${vitePluginUseClient.name}:transform]`, { id,