@bleedingdev/modern-js-render 3.8.3-ultramodern.6 → 3.9.0-ultramodern.10
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/client.mjs +1 -1
- package/dist/esm/rsc.mjs +100 -68
- package/dist/esm/rscWorker.mjs +104 -72
- package/dist/esm/server~0.mjs +100 -0
- package/dist/esm/ssr.mjs +9 -8
- package/dist/types/client/index.d.ts +2 -2
- package/dist/types/client.d.ts +1 -1
- package/dist/types/rsc.d.ts +1 -1
- package/dist/types/rsc.worker.d.ts +1 -1
- package/dist/types/server/rsc/index.d.ts +2 -2
- package/dist/types/server/ssr/index.d.ts +1 -1
- package/dist/types/server/ssr/ssr.d.ts +3 -1
- package/dist/types/ssr.d.ts +1 -1
- package/package.json +7 -8
- package/dist/esm/0~server.mjs +0 -112
- package/dist/types/server/rsc/rsc.worker.d.ts +0 -12
- /package/dist/esm/{341.mjs → 341~0.mjs} +0 -0
package/dist/esm/client.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { ElementsContext, RSCServerSlot, ResetRootContext, RscClientRoot, ServerElementsProvider, callServer, createFromFetch, createFromReadableStream, createServerReference, rscStream, setServerCallback } from "./341.mjs";
|
|
1
|
+
export { ElementsContext, RSCServerSlot, ResetRootContext, RscClientRoot, ServerElementsProvider, callServer, createFromFetch, createFromReadableStream, createServerReference, rscStream, setServerCallback } from "./341~0.mjs";
|
package/dist/esm/rsc.mjs
CHANGED
|
@@ -1,63 +1,96 @@
|
|
|
1
|
-
import { injectRSCPayload } from "@modern-js/runtime-extensions/rsc-html-stream";
|
|
2
1
|
import { decodeReply as server_node_decodeReply, loadServerAction as server_node_loadServerAction, registerClientReference, registerServerReference, renderToReadableStream } from "react-server-dom-rspack/server.node";
|
|
3
2
|
const server_encoder = new TextEncoder();
|
|
4
3
|
const closingTagsPattern = /<\/body>\s*<\/html>\s*$/i;
|
|
5
|
-
function
|
|
6
|
-
if (injectClosingTags) return injectRSCPayload(rscStream);
|
|
4
|
+
function injectRSCPayload(rscStream, { injectClosingTags = true }) {
|
|
7
5
|
const decoder = new TextDecoder();
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
let pendingHtml = '';
|
|
7
|
+
let closingBody = false;
|
|
8
|
+
let closingHtml = false;
|
|
9
|
+
let closingProbe = '';
|
|
10
|
+
let flightReader;
|
|
11
|
+
let flightPromise;
|
|
12
|
+
function startFlight(controller) {
|
|
13
|
+
if (!flightPromise) {
|
|
14
|
+
flightReader = rscStream.getReader();
|
|
15
|
+
flightPromise = writeRSCStream(flightReader, controller).finally(()=>{
|
|
16
|
+
flightReader = void 0;
|
|
17
|
+
});
|
|
18
|
+
flightPromise.catch((error)=>controller.error(error));
|
|
19
|
+
}
|
|
20
|
+
return flightPromise;
|
|
22
21
|
}
|
|
23
|
-
|
|
22
|
+
async function writeHtml(value, controller) {
|
|
23
|
+
let html = pendingHtml + value;
|
|
24
|
+
pendingHtml = '';
|
|
25
|
+
if (!closingBody) {
|
|
26
|
+
const bodyIndex = html.search(/<\/body>\s*(?:<\/html>\s*|<\/h(?:t(?:m(?:l>?)?)?)?|<\/?|<)?$/i);
|
|
27
|
+
if (-1 !== bodyIndex) {
|
|
28
|
+
controller.enqueue(server_encoder.encode(html.slice(0, bodyIndex)));
|
|
29
|
+
await startFlight(controller);
|
|
30
|
+
closingBody = true;
|
|
31
|
+
html = html.slice(bodyIndex);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (closingBody) {
|
|
35
|
+
if (!injectClosingTags) {
|
|
36
|
+
pendingHtml = html;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
closingHtml ||= /<\/html>/i.test(closingProbe + html);
|
|
40
|
+
closingProbe = (closingProbe + html).slice(-6);
|
|
41
|
+
} else {
|
|
42
|
+
const tagIndex = html.lastIndexOf('<');
|
|
43
|
+
if (tagIndex > html.lastIndexOf('>')) {
|
|
44
|
+
pendingHtml = html.slice(tagIndex);
|
|
45
|
+
html = html.slice(0, tagIndex);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (html) {
|
|
49
|
+
controller.enqueue(server_encoder.encode(html));
|
|
50
|
+
startFlight(controller);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const transformer = {
|
|
24
54
|
transform (chunk, controller) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
flushBufferedChunks(controller);
|
|
29
|
-
if (!startedRSC) {
|
|
30
|
-
startedRSC = true;
|
|
31
|
-
writeRSCStream(rscStream, controller).catch((err)=>controller.error(err)).then(()=>resolveFlightDataPromise());
|
|
32
|
-
}
|
|
33
|
-
}, 0);
|
|
55
|
+
return writeHtml(decoder.decode(chunk, {
|
|
56
|
+
stream: true
|
|
57
|
+
}), controller);
|
|
34
58
|
},
|
|
35
59
|
async flush (controller) {
|
|
36
|
-
await
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
await writeHtml(decoder.decode(), controller);
|
|
61
|
+
await startFlight(controller);
|
|
62
|
+
const tail = injectClosingTags ? pendingHtml : pendingHtml.replace(closingTagsPattern, '');
|
|
63
|
+
if (tail) controller.enqueue(server_encoder.encode(tail));
|
|
64
|
+
if (injectClosingTags && !closingHtml) controller.enqueue(server_encoder.encode(closingBody ? '</html>' : '</body></html>'));
|
|
65
|
+
},
|
|
66
|
+
cancel (reason) {
|
|
67
|
+
return flightReader ? flightReader.cancel(reason) : rscStream.cancel(reason);
|
|
44
68
|
}
|
|
45
|
-
}
|
|
69
|
+
};
|
|
70
|
+
return new TransformStream(transformer);
|
|
46
71
|
}
|
|
47
|
-
async function writeRSCStream(
|
|
72
|
+
async function writeRSCStream(reader, controller) {
|
|
48
73
|
const decoder = new TextDecoder('utf-8', {
|
|
49
|
-
fatal: true
|
|
74
|
+
fatal: true,
|
|
75
|
+
ignoreBOM: true
|
|
50
76
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
77
|
+
try {
|
|
78
|
+
while(true){
|
|
79
|
+
const { done, value } = await reader.read();
|
|
80
|
+
if (done) return;
|
|
81
|
+
let chunk;
|
|
82
|
+
try {
|
|
83
|
+
chunk = JSON.stringify(decoder.decode(value));
|
|
84
|
+
} catch {
|
|
85
|
+
let binary = '';
|
|
86
|
+
for (const byte of value)binary += String.fromCharCode(byte);
|
|
87
|
+
chunk = `Uint8Array.from(atob(${JSON.stringify(btoa(binary))}), m => m.codePointAt(0))`;
|
|
88
|
+
}
|
|
89
|
+
writeChunk(chunk, controller);
|
|
90
|
+
}
|
|
91
|
+
} finally{
|
|
92
|
+
reader.releaseLock();
|
|
58
93
|
}
|
|
59
|
-
const remaining = decoder.decode();
|
|
60
|
-
if (remaining.length) writeChunk(JSON.stringify(remaining), controller);
|
|
61
94
|
}
|
|
62
95
|
function writeChunk(chunk, controller) {
|
|
63
96
|
controller.enqueue(server_encoder.encode(`<script>${escapeScript(`(self.__FLIGHT_DATA||=[]).push(${chunk})`)}</script>`));
|
|
@@ -76,35 +109,34 @@ function injectCSS(cssFiles, { injectClosingTags = true } = {}) {
|
|
|
76
109
|
});
|
|
77
110
|
const decoder = new TextDecoder();
|
|
78
111
|
const headTrailer = '</head>';
|
|
79
|
-
|
|
80
|
-
let timeout = null;
|
|
112
|
+
let pendingHtml = '';
|
|
81
113
|
let cssInjected = false;
|
|
82
114
|
const cssLinks = cssFiles.map((css)=>`<link href="${css}" rel="stylesheet" />`).join('');
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
115
|
+
function writeHtml(value, controller, final = false) {
|
|
116
|
+
let html = pendingHtml + value;
|
|
117
|
+
pendingHtml = '';
|
|
118
|
+
if (!cssInjected) {
|
|
119
|
+
const headIndex = html.toLowerCase().indexOf(headTrailer);
|
|
120
|
+
if (-1 !== headIndex) {
|
|
121
|
+
html = html.slice(0, headIndex) + cssLinks + html.slice(headIndex);
|
|
88
122
|
cssInjected = true;
|
|
123
|
+
} else if (!final) {
|
|
124
|
+
let retain = Math.min(headTrailer.length - 1, html.length);
|
|
125
|
+
while(retain && !html.toLowerCase().endsWith(headTrailer.slice(0, retain)))retain--;
|
|
126
|
+
pendingHtml = html.slice(html.length - retain);
|
|
127
|
+
html = html.slice(0, html.length - retain);
|
|
89
128
|
}
|
|
90
|
-
controller.enqueue(server_encoder.encode(buf));
|
|
91
129
|
}
|
|
92
|
-
|
|
93
|
-
timeout = null;
|
|
130
|
+
if (html) controller.enqueue(server_encoder.encode(html));
|
|
94
131
|
}
|
|
95
132
|
return new TransformStream({
|
|
96
133
|
transform (chunk, controller) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
flushBufferedChunks(controller);
|
|
101
|
-
}, 0);
|
|
134
|
+
writeHtml(decoder.decode(chunk, {
|
|
135
|
+
stream: true
|
|
136
|
+
}), controller);
|
|
102
137
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
clearTimeout(timeout);
|
|
106
|
-
flushBufferedChunks(controller);
|
|
107
|
-
}
|
|
138
|
+
flush (controller) {
|
|
139
|
+
writeHtml(decoder.decode(), controller, true);
|
|
108
140
|
if (!cssInjected) controller.enqueue(server_encoder.encode(cssLinks));
|
|
109
141
|
if (injectClosingTags) controller.enqueue(server_encoder.encode('</body></html>'));
|
|
110
142
|
}
|
|
@@ -125,7 +157,7 @@ const createRenderCSRWithRSC = (renderRsc)=>async (options)=>{
|
|
|
125
157
|
});
|
|
126
158
|
const stream = htmlStream.pipeThrough(injectCSS(cssFiles, {
|
|
127
159
|
injectClosingTags: false
|
|
128
|
-
})).pipeThrough(
|
|
160
|
+
})).pipeThrough(injectRSCPayload(rscPayloadStream, {
|
|
129
161
|
injectClosingTags: true
|
|
130
162
|
}));
|
|
131
163
|
return new Response(stream, {
|
package/dist/esm/rscWorker.mjs
CHANGED
|
@@ -1,63 +1,96 @@
|
|
|
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";
|
|
3
2
|
const server_encoder = new TextEncoder();
|
|
4
3
|
const closingTagsPattern = /<\/body>\s*<\/html>\s*$/i;
|
|
5
|
-
function
|
|
6
|
-
if (injectClosingTags) return injectRSCPayload(rscStream);
|
|
4
|
+
function injectRSCPayload(rscStream, { injectClosingTags = true }) {
|
|
7
5
|
const decoder = new TextDecoder();
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
let pendingHtml = '';
|
|
7
|
+
let closingBody = false;
|
|
8
|
+
let closingHtml = false;
|
|
9
|
+
let closingProbe = '';
|
|
10
|
+
let flightReader;
|
|
11
|
+
let flightPromise;
|
|
12
|
+
function startFlight(controller) {
|
|
13
|
+
if (!flightPromise) {
|
|
14
|
+
flightReader = rscStream.getReader();
|
|
15
|
+
flightPromise = writeRSCStream(flightReader, controller).finally(()=>{
|
|
16
|
+
flightReader = void 0;
|
|
17
|
+
});
|
|
18
|
+
flightPromise.catch((error)=>controller.error(error));
|
|
19
|
+
}
|
|
20
|
+
return flightPromise;
|
|
22
21
|
}
|
|
23
|
-
|
|
22
|
+
async function writeHtml(value, controller) {
|
|
23
|
+
let html = pendingHtml + value;
|
|
24
|
+
pendingHtml = '';
|
|
25
|
+
if (!closingBody) {
|
|
26
|
+
const bodyIndex = html.search(/<\/body>\s*(?:<\/html>\s*|<\/h(?:t(?:m(?:l>?)?)?)?|<\/?|<)?$/i);
|
|
27
|
+
if (-1 !== bodyIndex) {
|
|
28
|
+
controller.enqueue(server_encoder.encode(html.slice(0, bodyIndex)));
|
|
29
|
+
await startFlight(controller);
|
|
30
|
+
closingBody = true;
|
|
31
|
+
html = html.slice(bodyIndex);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (closingBody) {
|
|
35
|
+
if (!injectClosingTags) {
|
|
36
|
+
pendingHtml = html;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
closingHtml ||= /<\/html>/i.test(closingProbe + html);
|
|
40
|
+
closingProbe = (closingProbe + html).slice(-6);
|
|
41
|
+
} else {
|
|
42
|
+
const tagIndex = html.lastIndexOf('<');
|
|
43
|
+
if (tagIndex > html.lastIndexOf('>')) {
|
|
44
|
+
pendingHtml = html.slice(tagIndex);
|
|
45
|
+
html = html.slice(0, tagIndex);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (html) {
|
|
49
|
+
controller.enqueue(server_encoder.encode(html));
|
|
50
|
+
startFlight(controller);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const transformer = {
|
|
24
54
|
transform (chunk, controller) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
flushBufferedChunks(controller);
|
|
29
|
-
if (!startedRSC) {
|
|
30
|
-
startedRSC = true;
|
|
31
|
-
writeRSCStream(rscStream, controller).catch((err)=>controller.error(err)).then(()=>resolveFlightDataPromise());
|
|
32
|
-
}
|
|
33
|
-
}, 0);
|
|
55
|
+
return writeHtml(decoder.decode(chunk, {
|
|
56
|
+
stream: true
|
|
57
|
+
}), controller);
|
|
34
58
|
},
|
|
35
59
|
async flush (controller) {
|
|
36
|
-
await
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
await writeHtml(decoder.decode(), controller);
|
|
61
|
+
await startFlight(controller);
|
|
62
|
+
const tail = injectClosingTags ? pendingHtml : pendingHtml.replace(closingTagsPattern, '');
|
|
63
|
+
if (tail) controller.enqueue(server_encoder.encode(tail));
|
|
64
|
+
if (injectClosingTags && !closingHtml) controller.enqueue(server_encoder.encode(closingBody ? '</html>' : '</body></html>'));
|
|
65
|
+
},
|
|
66
|
+
cancel (reason) {
|
|
67
|
+
return flightReader ? flightReader.cancel(reason) : rscStream.cancel(reason);
|
|
44
68
|
}
|
|
45
|
-
}
|
|
69
|
+
};
|
|
70
|
+
return new TransformStream(transformer);
|
|
46
71
|
}
|
|
47
|
-
async function writeRSCStream(
|
|
72
|
+
async function writeRSCStream(reader, controller) {
|
|
48
73
|
const decoder = new TextDecoder('utf-8', {
|
|
49
|
-
fatal: true
|
|
74
|
+
fatal: true,
|
|
75
|
+
ignoreBOM: true
|
|
50
76
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
77
|
+
try {
|
|
78
|
+
while(true){
|
|
79
|
+
const { done, value } = await reader.read();
|
|
80
|
+
if (done) return;
|
|
81
|
+
let chunk;
|
|
82
|
+
try {
|
|
83
|
+
chunk = JSON.stringify(decoder.decode(value));
|
|
84
|
+
} catch {
|
|
85
|
+
let binary = '';
|
|
86
|
+
for (const byte of value)binary += String.fromCharCode(byte);
|
|
87
|
+
chunk = `Uint8Array.from(atob(${JSON.stringify(btoa(binary))}), m => m.codePointAt(0))`;
|
|
88
|
+
}
|
|
89
|
+
writeChunk(chunk, controller);
|
|
90
|
+
}
|
|
91
|
+
} finally{
|
|
92
|
+
reader.releaseLock();
|
|
58
93
|
}
|
|
59
|
-
const remaining = decoder.decode();
|
|
60
|
-
if (remaining.length) writeChunk(JSON.stringify(remaining), controller);
|
|
61
94
|
}
|
|
62
95
|
function writeChunk(chunk, controller) {
|
|
63
96
|
controller.enqueue(server_encoder.encode(`<script>${escapeScript(`(self.__FLIGHT_DATA||=[]).push(${chunk})`)}</script>`));
|
|
@@ -76,35 +109,34 @@ function injectCSS(cssFiles, { injectClosingTags = true } = {}) {
|
|
|
76
109
|
});
|
|
77
110
|
const decoder = new TextDecoder();
|
|
78
111
|
const headTrailer = '</head>';
|
|
79
|
-
|
|
80
|
-
let timeout = null;
|
|
112
|
+
let pendingHtml = '';
|
|
81
113
|
let cssInjected = false;
|
|
82
114
|
const cssLinks = cssFiles.map((css)=>`<link href="${css}" rel="stylesheet" />`).join('');
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
115
|
+
function writeHtml(value, controller, final = false) {
|
|
116
|
+
let html = pendingHtml + value;
|
|
117
|
+
pendingHtml = '';
|
|
118
|
+
if (!cssInjected) {
|
|
119
|
+
const headIndex = html.toLowerCase().indexOf(headTrailer);
|
|
120
|
+
if (-1 !== headIndex) {
|
|
121
|
+
html = html.slice(0, headIndex) + cssLinks + html.slice(headIndex);
|
|
88
122
|
cssInjected = true;
|
|
123
|
+
} else if (!final) {
|
|
124
|
+
let retain = Math.min(headTrailer.length - 1, html.length);
|
|
125
|
+
while(retain && !html.toLowerCase().endsWith(headTrailer.slice(0, retain)))retain--;
|
|
126
|
+
pendingHtml = html.slice(html.length - retain);
|
|
127
|
+
html = html.slice(0, html.length - retain);
|
|
89
128
|
}
|
|
90
|
-
controller.enqueue(server_encoder.encode(buf));
|
|
91
129
|
}
|
|
92
|
-
|
|
93
|
-
timeout = null;
|
|
130
|
+
if (html) controller.enqueue(server_encoder.encode(html));
|
|
94
131
|
}
|
|
95
132
|
return new TransformStream({
|
|
96
133
|
transform (chunk, controller) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
flushBufferedChunks(controller);
|
|
101
|
-
}, 0);
|
|
134
|
+
writeHtml(decoder.decode(chunk, {
|
|
135
|
+
stream: true
|
|
136
|
+
}), controller);
|
|
102
137
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
clearTimeout(timeout);
|
|
106
|
-
flushBufferedChunks(controller);
|
|
107
|
-
}
|
|
138
|
+
flush (controller) {
|
|
139
|
+
writeHtml(decoder.decode(), controller, true);
|
|
108
140
|
if (!cssInjected) controller.enqueue(server_encoder.encode(cssLinks));
|
|
109
141
|
if (injectClosingTags) controller.enqueue(server_encoder.encode('</body></html>'));
|
|
110
142
|
}
|
|
@@ -125,7 +157,7 @@ const createRenderCSRWithRSC = (renderRsc)=>async (options)=>{
|
|
|
125
157
|
});
|
|
126
158
|
const stream = htmlStream.pipeThrough(injectCSS(cssFiles, {
|
|
127
159
|
injectClosingTags: false
|
|
128
|
-
})).pipeThrough(
|
|
160
|
+
})).pipeThrough(injectRSCPayload(rscPayloadStream, {
|
|
129
161
|
injectClosingTags: true
|
|
130
162
|
}));
|
|
131
163
|
return new Response(stream, {
|
|
@@ -231,15 +263,15 @@ const createHandleAction = ({ decodeReply, loadServerAction, renderRsc })=>async
|
|
|
231
263
|
});
|
|
232
264
|
}
|
|
233
265
|
};
|
|
234
|
-
const
|
|
266
|
+
const rsc_renderRsc = (options)=>{
|
|
235
267
|
const readable = renderToReadableStream(options.element);
|
|
236
268
|
return readable;
|
|
237
269
|
};
|
|
238
|
-
const renderCSRWithRSC = createRenderCSRWithRSC(rsc_worker_renderRsc);
|
|
239
270
|
const handleAction = createHandleAction({
|
|
240
271
|
decodeReply: server_edge_decodeReply,
|
|
241
272
|
loadServerAction: server_edge_loadServerAction,
|
|
242
|
-
renderRsc:
|
|
273
|
+
renderRsc: rsc_renderRsc
|
|
243
274
|
});
|
|
275
|
+
const renderCSRWithRSC = createRenderCSRWithRSC(rsc_renderRsc);
|
|
244
276
|
export { createFromReadableStream } from "react-server-dom-rspack/client.edge";
|
|
245
|
-
export { handleAction, registerClientReference, registerServerReference, renderCSRWithRSC, renderToReadableStream,
|
|
277
|
+
export { handleAction, registerClientReference, registerServerReference, renderCSRWithRSC, renderToReadableStream, rsc_renderRsc as renderRsc };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const encoder = new TextEncoder();
|
|
2
|
+
const closingTagsPattern = /<\/body>\s*<\/html>\s*$/i;
|
|
3
|
+
function injectRSCPayload(rscStream, { injectClosingTags = true }) {
|
|
4
|
+
const decoder = new TextDecoder();
|
|
5
|
+
let pendingHtml = '';
|
|
6
|
+
let closingBody = false;
|
|
7
|
+
let closingHtml = false;
|
|
8
|
+
let closingProbe = '';
|
|
9
|
+
let flightReader;
|
|
10
|
+
let flightPromise;
|
|
11
|
+
function startFlight(controller) {
|
|
12
|
+
if (!flightPromise) {
|
|
13
|
+
flightReader = rscStream.getReader();
|
|
14
|
+
flightPromise = writeRSCStream(flightReader, controller).finally(()=>{
|
|
15
|
+
flightReader = void 0;
|
|
16
|
+
});
|
|
17
|
+
flightPromise.catch((error)=>controller.error(error));
|
|
18
|
+
}
|
|
19
|
+
return flightPromise;
|
|
20
|
+
}
|
|
21
|
+
async function writeHtml(value, controller) {
|
|
22
|
+
let html = pendingHtml + value;
|
|
23
|
+
pendingHtml = '';
|
|
24
|
+
if (!closingBody) {
|
|
25
|
+
const bodyIndex = html.search(/<\/body>\s*(?:<\/html>\s*|<\/h(?:t(?:m(?:l>?)?)?)?|<\/?|<)?$/i);
|
|
26
|
+
if (-1 !== bodyIndex) {
|
|
27
|
+
controller.enqueue(encoder.encode(html.slice(0, bodyIndex)));
|
|
28
|
+
await startFlight(controller);
|
|
29
|
+
closingBody = true;
|
|
30
|
+
html = html.slice(bodyIndex);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (closingBody) {
|
|
34
|
+
if (!injectClosingTags) {
|
|
35
|
+
pendingHtml = html;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
closingHtml ||= /<\/html>/i.test(closingProbe + html);
|
|
39
|
+
closingProbe = (closingProbe + html).slice(-6);
|
|
40
|
+
} else {
|
|
41
|
+
const tagIndex = html.lastIndexOf('<');
|
|
42
|
+
if (tagIndex > html.lastIndexOf('>')) {
|
|
43
|
+
pendingHtml = html.slice(tagIndex);
|
|
44
|
+
html = html.slice(0, tagIndex);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (html) {
|
|
48
|
+
controller.enqueue(encoder.encode(html));
|
|
49
|
+
startFlight(controller);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const transformer = {
|
|
53
|
+
transform (chunk, controller) {
|
|
54
|
+
return writeHtml(decoder.decode(chunk, {
|
|
55
|
+
stream: true
|
|
56
|
+
}), controller);
|
|
57
|
+
},
|
|
58
|
+
async flush (controller) {
|
|
59
|
+
await writeHtml(decoder.decode(), controller);
|
|
60
|
+
await startFlight(controller);
|
|
61
|
+
const tail = injectClosingTags ? pendingHtml : pendingHtml.replace(closingTagsPattern, '');
|
|
62
|
+
if (tail) controller.enqueue(encoder.encode(tail));
|
|
63
|
+
if (injectClosingTags && !closingHtml) controller.enqueue(encoder.encode(closingBody ? '</html>' : '</body></html>'));
|
|
64
|
+
},
|
|
65
|
+
cancel (reason) {
|
|
66
|
+
return flightReader ? flightReader.cancel(reason) : rscStream.cancel(reason);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
return new TransformStream(transformer);
|
|
70
|
+
}
|
|
71
|
+
async function writeRSCStream(reader, controller) {
|
|
72
|
+
const decoder = new TextDecoder('utf-8', {
|
|
73
|
+
fatal: true,
|
|
74
|
+
ignoreBOM: true
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
while(true){
|
|
78
|
+
const { done, value } = await reader.read();
|
|
79
|
+
if (done) return;
|
|
80
|
+
let chunk;
|
|
81
|
+
try {
|
|
82
|
+
chunk = JSON.stringify(decoder.decode(value));
|
|
83
|
+
} catch {
|
|
84
|
+
let binary = '';
|
|
85
|
+
for (const byte of value)binary += String.fromCharCode(byte);
|
|
86
|
+
chunk = `Uint8Array.from(atob(${JSON.stringify(btoa(binary))}), m => m.codePointAt(0))`;
|
|
87
|
+
}
|
|
88
|
+
writeChunk(chunk, controller);
|
|
89
|
+
}
|
|
90
|
+
} finally{
|
|
91
|
+
reader.releaseLock();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function writeChunk(chunk, controller) {
|
|
95
|
+
controller.enqueue(encoder.encode(`<script>${escapeScript(`(self.__FLIGHT_DATA||=[]).push(${chunk})`)}</script>`));
|
|
96
|
+
}
|
|
97
|
+
function escapeScript(script) {
|
|
98
|
+
return script.replace(/<!--/g, '<\\!--').replace(/<\/(script)/gi, '</\\$1');
|
|
99
|
+
}
|
|
100
|
+
export { injectRSCPayload };
|
package/dist/esm/ssr.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
|
|
2
2
|
import react from "react";
|
|
3
3
|
import { renderToReadableStream } from "react-dom/server.edge";
|
|
4
|
-
import { ServerElementsProvider } from "./341.mjs";
|
|
4
|
+
import { ServerElementsProvider } from "./341~0.mjs";
|
|
5
5
|
function CSSLinks({ cssFiles }) {
|
|
6
6
|
if (0 === cssFiles.length) return null;
|
|
7
7
|
return /*#__PURE__*/ react.createElement(react.Fragment, null, cssFiles.map((css)=>/*#__PURE__*/ react.createElement("link", {
|
|
@@ -16,13 +16,13 @@ function wrapStream(stream, originalStream) {
|
|
|
16
16
|
return wrappedStream;
|
|
17
17
|
}
|
|
18
18
|
const renderSSRStream = async (children, options)=>{
|
|
19
|
-
const { rscManifest, rscRoot, routes } = options;
|
|
19
|
+
const { rscManifest, rscRoot, routes, wrapHtmlRoot, ...reactOptions } = options;
|
|
20
20
|
const clientManifest = rscManifest?.clientManifest;
|
|
21
21
|
const serverConsumerModuleMap = rscManifest?.serverConsumerModuleMap;
|
|
22
22
|
const entryCssFiles = rscManifest?.entryCssFiles;
|
|
23
23
|
const hasRoutes = Boolean(routes && routes.length > 0);
|
|
24
|
-
if (!clientManifest || !serverConsumerModuleMap) return renderToReadableStream(children, {
|
|
25
|
-
...
|
|
24
|
+
if (!clientManifest || !serverConsumerModuleMap) return renderToReadableStream(wrapHtmlRoot ? wrapHtmlRoot(children) : children, {
|
|
25
|
+
...reactOptions,
|
|
26
26
|
identifierPrefix: SSR_HYDRATION_ID_PREFIX
|
|
27
27
|
});
|
|
28
28
|
try {
|
|
@@ -30,7 +30,7 @@ const renderSSRStream = async (children, options)=>{
|
|
|
30
30
|
const [{ renderRsc }, { createFromReadableStream }, { injectRSCPayload }] = await Promise.all([
|
|
31
31
|
rscRuntime,
|
|
32
32
|
import("react-server-dom-rspack/client.edge"),
|
|
33
|
-
import("./0
|
|
33
|
+
import("./server~0.mjs")
|
|
34
34
|
]);
|
|
35
35
|
const rscStream = await renderRsc({
|
|
36
36
|
element: rscRoot || children
|
|
@@ -39,12 +39,13 @@ const renderSSRStream = async (children, options)=>{
|
|
|
39
39
|
const elements = createFromReadableStream(rscElementStream);
|
|
40
40
|
let cssFiles = [];
|
|
41
41
|
if (!hasRoutes && entryCssFiles) cssFiles = Object.values(entryCssFiles).flat();
|
|
42
|
-
const
|
|
42
|
+
const htmlRoot = /*#__PURE__*/ react.createElement(ServerElementsProvider, {
|
|
43
43
|
elements: elements
|
|
44
44
|
}, /*#__PURE__*/ react.createElement(CSSLinks, {
|
|
45
45
|
cssFiles: cssFiles
|
|
46
|
-
}), children)
|
|
47
|
-
|
|
46
|
+
}), children);
|
|
47
|
+
const htmlStream = await renderToReadableStream(wrapHtmlRoot ? wrapHtmlRoot(htmlRoot) : htmlRoot, {
|
|
48
|
+
...reactOptions,
|
|
48
49
|
identifierPrefix: SSR_HYDRATION_ID_PREFIX
|
|
49
50
|
});
|
|
50
51
|
const stream = htmlStream.pipeThrough(injectRSCPayload(rscPayloadStream, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { type ReactNode } from 'react';
|
|
2
2
|
import { createFromFetch, createFromReadableStream, createServerReference, setServerCallback } from 'react-server-dom-rspack/client.browser';
|
|
3
|
-
export { rscStream } from '../rsc-html-stream/client';
|
|
4
|
-
export { callServer } from './callServer';
|
|
3
|
+
export { rscStream } from '../rsc-html-stream/client.js';
|
|
4
|
+
export { callServer } from './callServer.js';
|
|
5
5
|
export { createFromFetch, createFromReadableStream, createServerReference };
|
|
6
6
|
declare global {
|
|
7
7
|
interface Window {
|
package/dist/types/client.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './client/index';
|
|
1
|
+
export * from './client/index.js';
|
package/dist/types/rsc.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './server/rsc';
|
|
1
|
+
export * from './server/rsc/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './server/rsc/
|
|
1
|
+
export * from './server/rsc/index.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './csr';
|
|
2
|
-
export * from './rsc';
|
|
1
|
+
export * from './csr.js';
|
|
2
|
+
export * from './rsc.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './ssr';
|
|
1
|
+
export * from './ssr.js';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { ClientManifest } from '@modern-js/types/server';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { type ReactNode } from 'react';
|
|
3
3
|
import { renderToReadableStream } from 'react-dom/server.edge';
|
|
4
4
|
type Options = {
|
|
5
5
|
request: Request;
|
|
6
6
|
routes?: unknown[];
|
|
7
|
+
/** Wrap only the HTML render tree, never the input serialized by Flight. */
|
|
8
|
+
wrapHtmlRoot?: (root: ReactNode) => ReactNode;
|
|
7
9
|
rscManifest?: {
|
|
8
10
|
clientManifest?: ClientManifest;
|
|
9
11
|
serverConsumerModuleMap?: unknown;
|
package/dist/types/ssr.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './server/ssr';
|
|
1
|
+
export * from './server/ssr/index.js';
|
package/package.json
CHANGED
|
@@ -17,25 +17,24 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.
|
|
20
|
+
"version": "3.9.0-ultramodern.10",
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
23
|
"hook.d.ts"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@modern-js/
|
|
27
|
-
"@modern-js/
|
|
28
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.8.3-ultramodern.6",
|
|
26
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.10",
|
|
27
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.10",
|
|
29
28
|
"@swc/helpers": "^0.5.23"
|
|
30
29
|
},
|
|
31
30
|
"devDependencies": {
|
|
32
|
-
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.
|
|
33
|
-
"@rslib/core": "0.
|
|
31
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.10",
|
|
32
|
+
"@rslib/core": "1.0.0",
|
|
34
33
|
"@scripts/build": "2.66.0",
|
|
35
34
|
"@scripts/rstest-config": "2.66.0",
|
|
36
|
-
"@types/node": "^26.
|
|
35
|
+
"@types/node": "^26.4.1",
|
|
37
36
|
"@types/react": "^19.2.18",
|
|
38
|
-
"@types/react-dom": "^19.2.
|
|
37
|
+
"@types/react-dom": "^19.2.7",
|
|
39
38
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
40
39
|
"react": "^19.2.8",
|
|
41
40
|
"react-dom": "^19.2.8",
|
package/dist/esm/0~server.mjs
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { injectRSCPayload } from "@modern-js/runtime-extensions/rsc-html-stream";
|
|
2
|
-
const encoder = new TextEncoder();
|
|
3
|
-
const closingTagsPattern = /<\/body>\s*<\/html>\s*$/i;
|
|
4
|
-
function server_injectRSCPayload(rscStream, { injectClosingTags = true }) {
|
|
5
|
-
if (injectClosingTags) return injectRSCPayload(rscStream);
|
|
6
|
-
const decoder = new TextDecoder();
|
|
7
|
-
let resolveFlightDataPromise;
|
|
8
|
-
const flightDataPromise = new Promise((resolve)=>resolveFlightDataPromise = resolve);
|
|
9
|
-
let startedRSC = false;
|
|
10
|
-
const buffered = [];
|
|
11
|
-
let timeout = null;
|
|
12
|
-
function flushBufferedChunks(controller) {
|
|
13
|
-
let buf = '';
|
|
14
|
-
for (const chunk of buffered)buf += decoder.decode(chunk, {
|
|
15
|
-
stream: true
|
|
16
|
-
});
|
|
17
|
-
if (closingTagsPattern.test(buf)) buf = buf.replace(closingTagsPattern, '');
|
|
18
|
-
if (buf) controller.enqueue(encoder.encode(buf));
|
|
19
|
-
buffered.length = 0;
|
|
20
|
-
timeout = null;
|
|
21
|
-
}
|
|
22
|
-
return new TransformStream({
|
|
23
|
-
transform (chunk, controller) {
|
|
24
|
-
buffered.push(chunk);
|
|
25
|
-
if (timeout) return;
|
|
26
|
-
timeout = setTimeout(async ()=>{
|
|
27
|
-
flushBufferedChunks(controller);
|
|
28
|
-
if (!startedRSC) {
|
|
29
|
-
startedRSC = true;
|
|
30
|
-
writeRSCStream(rscStream, controller).catch((err)=>controller.error(err)).then(()=>resolveFlightDataPromise());
|
|
31
|
-
}
|
|
32
|
-
}, 0);
|
|
33
|
-
},
|
|
34
|
-
async flush (controller) {
|
|
35
|
-
await flightDataPromise;
|
|
36
|
-
if (timeout) {
|
|
37
|
-
clearTimeout(timeout);
|
|
38
|
-
flushBufferedChunks(controller);
|
|
39
|
-
}
|
|
40
|
-
const remaining = decoder.decode();
|
|
41
|
-
if (remaining) controller.enqueue(encoder.encode(remaining));
|
|
42
|
-
if (injectClosingTags) controller.enqueue(encoder.encode('</body></html>'));
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
async function writeRSCStream(rscStream, controller) {
|
|
47
|
-
const decoder = new TextDecoder('utf-8', {
|
|
48
|
-
fatal: true
|
|
49
|
-
});
|
|
50
|
-
for await (const chunk of rscStream)try {
|
|
51
|
-
writeChunk(JSON.stringify(decoder.decode(chunk, {
|
|
52
|
-
stream: true
|
|
53
|
-
})), controller);
|
|
54
|
-
} catch (err) {
|
|
55
|
-
const base64 = JSON.stringify(btoa(String.fromCodePoint(...chunk)));
|
|
56
|
-
writeChunk(`Uint8Array.from(atob(${base64}), m => m.codePointAt(0))`, controller);
|
|
57
|
-
}
|
|
58
|
-
const remaining = decoder.decode();
|
|
59
|
-
if (remaining.length) writeChunk(JSON.stringify(remaining), controller);
|
|
60
|
-
}
|
|
61
|
-
function writeChunk(chunk, controller) {
|
|
62
|
-
controller.enqueue(encoder.encode(`<script>${escapeScript(`(self.__FLIGHT_DATA||=[]).push(${chunk})`)}</script>`));
|
|
63
|
-
}
|
|
64
|
-
function escapeScript(script) {
|
|
65
|
-
return script.replace(/<!--/g, '<\\!--').replace(/<\/(script)/gi, '</\\$1');
|
|
66
|
-
}
|
|
67
|
-
function injectCSS(cssFiles, { injectClosingTags = true } = {}) {
|
|
68
|
-
if (0 === cssFiles.length) return new TransformStream({
|
|
69
|
-
transform (chunk, controller) {
|
|
70
|
-
controller.enqueue(chunk);
|
|
71
|
-
},
|
|
72
|
-
flush (controller) {
|
|
73
|
-
if (injectClosingTags) controller.enqueue(encoder.encode('</body></html>'));
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
const decoder = new TextDecoder();
|
|
77
|
-
const headTrailer = '</head>';
|
|
78
|
-
const buffered = [];
|
|
79
|
-
let timeout = null;
|
|
80
|
-
let cssInjected = false;
|
|
81
|
-
const cssLinks = cssFiles.map((css)=>`<link href="${css}" rel="stylesheet" />`).join('');
|
|
82
|
-
function flushBufferedChunks(controller) {
|
|
83
|
-
for (const chunk of buffered){
|
|
84
|
-
let buf = decoder.decode(chunk);
|
|
85
|
-
if (!cssInjected && buf.includes(headTrailer)) {
|
|
86
|
-
buf = buf.replace(headTrailer, `${cssLinks}${headTrailer}`);
|
|
87
|
-
cssInjected = true;
|
|
88
|
-
}
|
|
89
|
-
controller.enqueue(encoder.encode(buf));
|
|
90
|
-
}
|
|
91
|
-
buffered.length = 0;
|
|
92
|
-
timeout = null;
|
|
93
|
-
}
|
|
94
|
-
return new TransformStream({
|
|
95
|
-
transform (chunk, controller) {
|
|
96
|
-
buffered.push(chunk);
|
|
97
|
-
if (timeout) return;
|
|
98
|
-
timeout = setTimeout(()=>{
|
|
99
|
-
flushBufferedChunks(controller);
|
|
100
|
-
}, 0);
|
|
101
|
-
},
|
|
102
|
-
async flush (controller) {
|
|
103
|
-
if (timeout) {
|
|
104
|
-
clearTimeout(timeout);
|
|
105
|
-
flushBufferedChunks(controller);
|
|
106
|
-
}
|
|
107
|
-
if (!cssInjected) controller.enqueue(encoder.encode(cssLinks));
|
|
108
|
-
if (injectClosingTags) controller.enqueue(encoder.encode('</body></html>'));
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
export { injectCSS, server_injectRSCPayload as injectRSCPayload };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export { renderToReadableStream } from 'react-server-dom-rspack/server.edge';
|
|
2
|
-
export { createFromReadableStream } from 'react-server-dom-rspack/client.edge';
|
|
3
|
-
export { registerClientReference, registerServerReference, } from 'react-server-dom-rspack/server.edge';
|
|
4
|
-
type RenderRscOptions = {
|
|
5
|
-
element: React.ReactElement;
|
|
6
|
-
};
|
|
7
|
-
export declare const renderRsc: (options: RenderRscOptions) => ReadableStream<Uint8Array<ArrayBufferLike>>;
|
|
8
|
-
export declare const renderCSRWithRSC: (options: {
|
|
9
|
-
html: string;
|
|
10
|
-
rscRoot: import("react").ReactElement;
|
|
11
|
-
}) => Promise<Response>;
|
|
12
|
-
export declare const handleAction: (req: Request) => Promise<Response>;
|
|
File without changes
|