Skip to content

Commit d5d12c9

Browse files
committed
fix: reply encoding
1 parent 93fc52d commit d5d12c9

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@
3636
"dependencies": {
3737
"@swc/core": "1.3.39",
3838
"@vitejs/plugin-react": "^3.1.0",
39+
"busboy": "^1.6.0",
3940
"vite": "^4.1.4"
4041
},
4142
"devDependencies": {
4243
"@swc/cli": "^0.1.62",
4344
"@types/babel__core": "^7.20.0",
45+
"@types/busboy": "^1.5.0",
4446
"@types/node": "^18.15.0",
4547
"@types/react": "^18.0.28",
4648
"@types/react-dom": "^18.0.11",

pnpm-lock.yaml

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/client.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ReactNode } from "react";
22
import RSDWClient from "react-server-dom-webpack/client";
33

4-
const { createFromFetch } = RSDWClient;
4+
const { createFromFetch, encodeReply } = RSDWClient;
55

66
export function serve<Props>(rscId: string, render: (ele: ReactNode) => void) {
77
return async (props: Props) => {
@@ -10,7 +10,8 @@ export function serve<Props>(rscId: string, render: (ele: ReactNode) => void) {
1010
searchParams.set("rsc_id", rscId);
1111
searchParams.set("props", serializedProps);
1212
const options = {
13-
callServer(rsfId: string, args: unknown[]) {
13+
async callServer(rsfId: string, args: unknown[]) {
14+
const isMutating = !!mutationMode;
1415
const searchParams = new URLSearchParams();
1516
searchParams.set("rsf_id", rsfId);
1617
if (isMutating) {
@@ -19,7 +20,7 @@ export function serve<Props>(rscId: string, render: (ele: ReactNode) => void) {
1920
}
2021
const response = fetch(`/?${searchParams}`, {
2122
method: "POST",
22-
body: JSON.stringify(args),
23+
body: await encodeReply(args),
2324
});
2425
const data = createFromFetch(response, options);
2526
if (isMutating) {
@@ -38,13 +39,13 @@ export function serve<Props>(rscId: string, render: (ele: ReactNode) => void) {
3839
};
3940
}
4041

41-
let isMutating = 0;
42+
let mutationMode = 0;
4243

4344
export function mutate<Fn extends (...args: any[]) => any>(fn: Fn): Fn {
4445
return ((...args: unknown[]) => {
45-
++isMutating;
46+
++mutationMode;
4647
const result = fn(...args);
47-
--isMutating;
48+
--mutationMode;
4849
return result;
4950
}) as Fn;
5051
}

src/middleware/rscDev.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import url from "node:url";
55
import * as swc from "@swc/core";
66
import RSDWRegister from "react-server-dom-webpack/node-register";
77
import RSDWServer from "react-server-dom-webpack/server";
8+
import busboy from "busboy";
89

910
import type { MiddlewareCreator } from "./common.ts";
1011

11-
const { renderToPipeableStream } = RSDWServer;
12+
const { renderToPipeableStream, decodeReply, decodeReplyFromBusboy } =
13+
RSDWServer;
1214

1315
// TODO we would like a native solution without hacks
1416
// https://nodejs.org/api/esm.html#loaders
@@ -80,11 +82,21 @@ const rscDefault: MiddlewareCreator = (config) => {
8082
if (typeof rsfId === "string") {
8183
const [filePath, name] = rsfId.split("#");
8284
const fname = path.join(dir, filePath!);
83-
let body = "";
84-
for await (const chunk of req) {
85-
body += chunk;
85+
let args: unknown[] = [];
86+
if (req.headers["content-type"]?.startsWith("multipart/form-data")) {
87+
const bb = busboy({ headers: req.headers });
88+
const reply = decodeReplyFromBusboy(bb);
89+
req.pipe(bb);
90+
args = await reply;
91+
} else {
92+
let body = "";
93+
for await (const chunk of req) {
94+
body += chunk;
95+
}
96+
if (body) {
97+
args = await decodeReply(body);
98+
}
8699
}
87-
const args = body ? JSON.parse(body) : [];
88100
// TODO can we use node:vm?
89101
const mod = require(fname);
90102
const data = await (mod[name!] || mod)(...args);

0 commit comments

Comments
 (0)