@bleedingdev/modern-js-render 3.8.3-ultramodern.1 → 3.8.3-ultramodern.3
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/dist/esm/0~server.mjs +4 -2
- package/dist/esm/rsc.mjs +53 -4
- package/dist/esm/rscWorker.mjs +53 -4
- package/package.json +6 -5
package/dist/esm/0~server.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { injectRSCPayload } from "@modern-js/runtime-extensions/rsc-html-stream";
|
|
1
2
|
const encoder = new TextEncoder();
|
|
2
3
|
const closingTagsPattern = /<\/body>\s*<\/html>\s*$/i;
|
|
3
|
-
function
|
|
4
|
+
function server_injectRSCPayload(rscStream, { injectClosingTags = true }) {
|
|
5
|
+
if (injectClosingTags) return injectRSCPayload(rscStream);
|
|
4
6
|
const decoder = new TextDecoder();
|
|
5
7
|
let resolveFlightDataPromise;
|
|
6
8
|
const flightDataPromise = new Promise((resolve)=>resolveFlightDataPromise = resolve);
|
|
@@ -107,4 +109,4 @@ function injectCSS(cssFiles, { injectClosingTags = true } = {}) {
|
|
|
107
109
|
}
|
|
108
110
|
});
|
|
109
111
|
}
|
|
110
|
-
export { injectCSS, injectRSCPayload };
|
|
112
|
+
export { injectCSS, server_injectRSCPayload as injectRSCPayload };
|
package/dist/esm/rsc.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { injectRSCPayload } from "@modern-js/runtime-extensions/rsc-html-stream";
|
|
1
2
|
import { decodeReply as server_node_decodeReply, loadServerAction as server_node_loadServerAction, registerClientReference, registerServerReference, renderToReadableStream } from "react-server-dom-rspack/server.node";
|
|
2
3
|
const server_encoder = new TextEncoder();
|
|
3
4
|
const closingTagsPattern = /<\/body>\s*<\/html>\s*$/i;
|
|
4
|
-
function
|
|
5
|
+
function server_injectRSCPayload(rscStream, { injectClosingTags = true }) {
|
|
6
|
+
if (injectClosingTags) return injectRSCPayload(rscStream);
|
|
5
7
|
const decoder = new TextDecoder();
|
|
6
8
|
let resolveFlightDataPromise;
|
|
7
9
|
const flightDataPromise = new Promise((resolve)=>resolveFlightDataPromise = resolve);
|
|
@@ -123,7 +125,7 @@ const createRenderCSRWithRSC = (renderRsc)=>async (options)=>{
|
|
|
123
125
|
});
|
|
124
126
|
const stream = htmlStream.pipeThrough(injectCSS(cssFiles, {
|
|
125
127
|
injectClosingTags: false
|
|
126
|
-
})).pipeThrough(
|
|
128
|
+
})).pipeThrough(server_injectRSCPayload(rscPayloadStream, {
|
|
127
129
|
injectClosingTags: true
|
|
128
130
|
}));
|
|
129
131
|
return new Response(stream, {
|
|
@@ -133,12 +135,49 @@ const createRenderCSRWithRSC = (renderRsc)=>async (options)=>{
|
|
|
133
135
|
})
|
|
134
136
|
});
|
|
135
137
|
};
|
|
138
|
+
const MAX_ACTION_BODY_BYTES = 1048576;
|
|
139
|
+
const readBoundedBody = async (req)=>{
|
|
140
|
+
const reader = req.body?.getReader();
|
|
141
|
+
if (!reader) return new Uint8Array();
|
|
142
|
+
const bytes = new Uint8Array(MAX_ACTION_BODY_BYTES);
|
|
143
|
+
let size = 0;
|
|
144
|
+
try {
|
|
145
|
+
while(true){
|
|
146
|
+
const { done, value } = await reader.read();
|
|
147
|
+
if (done) return bytes.slice(0, size);
|
|
148
|
+
if (value.byteLength > MAX_ACTION_BODY_BYTES - size) {
|
|
149
|
+
reader.cancel().catch(()=>{});
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
bytes.set(value, size);
|
|
153
|
+
size += value.byteLength;
|
|
154
|
+
}
|
|
155
|
+
} finally{
|
|
156
|
+
reader.releaseLock();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
136
159
|
const createHandleAction = ({ decodeReply, loadServerAction, renderRsc })=>async (req)=>{
|
|
160
|
+
if ('POST' !== req.method) return new Response('Method not allowed', {
|
|
161
|
+
status: 405,
|
|
162
|
+
headers: {
|
|
163
|
+
Allow: 'POST'
|
|
164
|
+
}
|
|
165
|
+
});
|
|
137
166
|
try {
|
|
138
167
|
const serverReference = req.headers.get('x-rsc-action');
|
|
139
168
|
if (!serverReference) return new Response('Cannot find server reference', {
|
|
140
169
|
status: 404
|
|
141
170
|
});
|
|
171
|
+
const declaredLength = req.headers.get('content-length');
|
|
172
|
+
if (null !== declaredLength) {
|
|
173
|
+
const parsedLength = Number(declaredLength);
|
|
174
|
+
if (!/^\d+$/.test(declaredLength) || !Number.isSafeInteger(parsedLength)) return new Response('Invalid server action request', {
|
|
175
|
+
status: 400
|
|
176
|
+
});
|
|
177
|
+
if (parsedLength > MAX_ACTION_BODY_BYTES) return new Response('Server action payload too large', {
|
|
178
|
+
status: 413
|
|
179
|
+
});
|
|
180
|
+
}
|
|
142
181
|
const action = loadServerAction(serverReference);
|
|
143
182
|
if ('function' != typeof action) {
|
|
144
183
|
console.error('[RSC] Invalid action: server reference is not a function, serverReference:', serverReference);
|
|
@@ -149,11 +188,21 @@ const createHandleAction = ({ decodeReply, loadServerAction, renderRsc })=>async
|
|
|
149
188
|
const contentType = req.headers.get('content-type');
|
|
150
189
|
let args;
|
|
151
190
|
try {
|
|
191
|
+
const body = await readBoundedBody(req);
|
|
192
|
+
if (null === body) return new Response('Server action payload too large', {
|
|
193
|
+
status: 413
|
|
194
|
+
});
|
|
152
195
|
if (contentType?.includes('multipart/form-data')) {
|
|
153
|
-
const formData = await
|
|
196
|
+
const formData = await new Response(body, {
|
|
197
|
+
headers: {
|
|
198
|
+
'Content-Type': contentType
|
|
199
|
+
}
|
|
200
|
+
}).formData();
|
|
154
201
|
args = await decodeReply(formData);
|
|
155
202
|
} else {
|
|
156
|
-
const text =
|
|
203
|
+
const text = new TextDecoder('utf-8', {
|
|
204
|
+
fatal: true
|
|
205
|
+
}).decode(body);
|
|
157
206
|
args = await decodeReply(text);
|
|
158
207
|
}
|
|
159
208
|
} catch (error) {
|
package/dist/esm/rscWorker.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { decodeReply as server_edge_decodeReply, loadServerAction as server_edge_loadServerAction, registerClientReference, registerServerReference, renderToReadableStream } from "react-server-dom-rspack/server.edge";
|
|
2
|
+
import { injectRSCPayload } from "@modern-js/runtime-extensions/rsc-html-stream";
|
|
2
3
|
const server_encoder = new TextEncoder();
|
|
3
4
|
const closingTagsPattern = /<\/body>\s*<\/html>\s*$/i;
|
|
4
|
-
function
|
|
5
|
+
function server_injectRSCPayload(rscStream, { injectClosingTags = true }) {
|
|
6
|
+
if (injectClosingTags) return injectRSCPayload(rscStream);
|
|
5
7
|
const decoder = new TextDecoder();
|
|
6
8
|
let resolveFlightDataPromise;
|
|
7
9
|
const flightDataPromise = new Promise((resolve)=>resolveFlightDataPromise = resolve);
|
|
@@ -123,7 +125,7 @@ const createRenderCSRWithRSC = (renderRsc)=>async (options)=>{
|
|
|
123
125
|
});
|
|
124
126
|
const stream = htmlStream.pipeThrough(injectCSS(cssFiles, {
|
|
125
127
|
injectClosingTags: false
|
|
126
|
-
})).pipeThrough(
|
|
128
|
+
})).pipeThrough(server_injectRSCPayload(rscPayloadStream, {
|
|
127
129
|
injectClosingTags: true
|
|
128
130
|
}));
|
|
129
131
|
return new Response(stream, {
|
|
@@ -133,12 +135,49 @@ const createRenderCSRWithRSC = (renderRsc)=>async (options)=>{
|
|
|
133
135
|
})
|
|
134
136
|
});
|
|
135
137
|
};
|
|
138
|
+
const MAX_ACTION_BODY_BYTES = 1048576;
|
|
139
|
+
const readBoundedBody = async (req)=>{
|
|
140
|
+
const reader = req.body?.getReader();
|
|
141
|
+
if (!reader) return new Uint8Array();
|
|
142
|
+
const bytes = new Uint8Array(MAX_ACTION_BODY_BYTES);
|
|
143
|
+
let size = 0;
|
|
144
|
+
try {
|
|
145
|
+
while(true){
|
|
146
|
+
const { done, value } = await reader.read();
|
|
147
|
+
if (done) return bytes.slice(0, size);
|
|
148
|
+
if (value.byteLength > MAX_ACTION_BODY_BYTES - size) {
|
|
149
|
+
reader.cancel().catch(()=>{});
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
bytes.set(value, size);
|
|
153
|
+
size += value.byteLength;
|
|
154
|
+
}
|
|
155
|
+
} finally{
|
|
156
|
+
reader.releaseLock();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
136
159
|
const createHandleAction = ({ decodeReply, loadServerAction, renderRsc })=>async (req)=>{
|
|
160
|
+
if ('POST' !== req.method) return new Response('Method not allowed', {
|
|
161
|
+
status: 405,
|
|
162
|
+
headers: {
|
|
163
|
+
Allow: 'POST'
|
|
164
|
+
}
|
|
165
|
+
});
|
|
137
166
|
try {
|
|
138
167
|
const serverReference = req.headers.get('x-rsc-action');
|
|
139
168
|
if (!serverReference) return new Response('Cannot find server reference', {
|
|
140
169
|
status: 404
|
|
141
170
|
});
|
|
171
|
+
const declaredLength = req.headers.get('content-length');
|
|
172
|
+
if (null !== declaredLength) {
|
|
173
|
+
const parsedLength = Number(declaredLength);
|
|
174
|
+
if (!/^\d+$/.test(declaredLength) || !Number.isSafeInteger(parsedLength)) return new Response('Invalid server action request', {
|
|
175
|
+
status: 400
|
|
176
|
+
});
|
|
177
|
+
if (parsedLength > MAX_ACTION_BODY_BYTES) return new Response('Server action payload too large', {
|
|
178
|
+
status: 413
|
|
179
|
+
});
|
|
180
|
+
}
|
|
142
181
|
const action = loadServerAction(serverReference);
|
|
143
182
|
if ('function' != typeof action) {
|
|
144
183
|
console.error('[RSC] Invalid action: server reference is not a function, serverReference:', serverReference);
|
|
@@ -149,11 +188,21 @@ const createHandleAction = ({ decodeReply, loadServerAction, renderRsc })=>async
|
|
|
149
188
|
const contentType = req.headers.get('content-type');
|
|
150
189
|
let args;
|
|
151
190
|
try {
|
|
191
|
+
const body = await readBoundedBody(req);
|
|
192
|
+
if (null === body) return new Response('Server action payload too large', {
|
|
193
|
+
status: 413
|
|
194
|
+
});
|
|
152
195
|
if (contentType?.includes('multipart/form-data')) {
|
|
153
|
-
const formData = await
|
|
196
|
+
const formData = await new Response(body, {
|
|
197
|
+
headers: {
|
|
198
|
+
'Content-Type': contentType
|
|
199
|
+
}
|
|
200
|
+
}).formData();
|
|
154
201
|
args = await decodeReply(formData);
|
|
155
202
|
} else {
|
|
156
|
-
const text =
|
|
203
|
+
const text = new TextDecoder('utf-8', {
|
|
204
|
+
fatal: true
|
|
205
|
+
}).decode(body);
|
|
157
206
|
args = await decodeReply(text);
|
|
158
207
|
}
|
|
159
208
|
} catch (error) {
|
package/package.json
CHANGED
|
@@ -17,18 +17,19 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.8.3-ultramodern.
|
|
20
|
+
"version": "3.8.3-ultramodern.3",
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
23
|
"hook.d.ts"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@modern-js/
|
|
27
|
-
"@modern-js/
|
|
26
|
+
"@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.8.3-ultramodern.3",
|
|
27
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.8.3-ultramodern.3",
|
|
28
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.8.3-ultramodern.3",
|
|
28
29
|
"@swc/helpers": "^0.5.23"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
|
-
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.8.3-ultramodern.
|
|
32
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.8.3-ultramodern.3",
|
|
32
33
|
"@rslib/core": "0.23.2",
|
|
33
34
|
"@scripts/build": "2.66.0",
|
|
34
35
|
"@scripts/rstest-config": "2.66.0",
|
|
@@ -91,7 +92,7 @@
|
|
|
91
92
|
},
|
|
92
93
|
"scripts": {
|
|
93
94
|
"dev": "rslib build --watch",
|
|
94
|
-
"build": "rslib build
|
|
95
|
+
"build": "rslib build",
|
|
95
96
|
"test": "tsgo --noEmit -p tsconfig.json && rstest --passWithNoTests"
|
|
96
97
|
}
|
|
97
98
|
}
|