Skip to content

Commit

Permalink
refactor(react-server): use official registerClientReference (#17)
Browse files Browse the repository at this point in the history
* refactor(react-server): use official `registerClientReference`

* chore: cleanup
  • Loading branch information
hi-ogawa authored Apr 12, 2024
1 parent 6367336 commit e421c9d
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 25 deletions.
32 changes: 14 additions & 18 deletions examples/react-server/src/features/use-client/react-server.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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;
Expand Down
11 changes: 6 additions & 5 deletions examples/react-server/src/types/react.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ declare module "react-server-dom-webpack/server.edge" {
},
): ReadableStream<Uint8Array>;

export function decodeReply(body: string | FormData): Promise<unknown>;
export function registerClientReference<T>(
proxy: T,
id: string,
name: string,
): T;
}

// https://github.com/facebook/react/blob/89021fb4ec9aa82194b0788566e736a4cedfc0e4/packages/react-server-dom-webpack/src/ReactFlightDOMClientEdge.js
Expand Down Expand Up @@ -42,11 +46,8 @@ declare module "react-server-dom-webpack/client.browser" {
callServer?: import(".").CallServerCallback;
},
): Promise<T>;

export function encodeReply(
v: unknown,
): Promise<string | URLSearchParams | FormData>;
}

declare module "react-dom/server.edge" {
export * from "react-dom/server";
}
4 changes: 2 additions & 2 deletions examples/react-server/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit e421c9d

Please sign in to comment.