Skip to content

Commit 8786155

Browse files
committed
Wire up in fixture
1 parent c6c224d commit 8786155

File tree

4 files changed

+93
-19
lines changed

4 files changed

+93
-19
lines changed

fixtures/flight/server/global.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ async function renderApp(req, res, next) {
104104
if (req.headers['cache-control']) {
105105
proxiedHeaders['Cache-Control'] = req.get('cache-control');
106106
}
107+
if (req.get('rsc-request-id')) {
108+
proxiedHeaders['rsc-request-id'] = req.get('rsc-request-id');
109+
}
107110

108111
const requestsPrerender = req.path === '/prerender';
109112

fixtures/flight/server/region.js

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,27 @@ const {readFile} = require('fs').promises;
5050

5151
const React = require('react');
5252

53-
async function renderApp(res, returnValue, formState, noCache) {
53+
const activeDebugChannels =
54+
process.env.NODE_ENV === 'development' ? new Map() : null;
55+
56+
function getDebugChannel(req) {
57+
if (process.env.NODE_ENV !== 'development') {
58+
return undefined;
59+
}
60+
const requestId = req.get('rsc-request-id');
61+
if (!requestId) {
62+
return undefined;
63+
}
64+
return activeDebugChannels.get(requestId);
65+
}
66+
67+
async function renderApp(
68+
res,
69+
returnValue,
70+
formState,
71+
noCache,
72+
promiseForDebugChannel
73+
) {
5474
const {renderToPipeableStream} = await import(
5575
'react-server-dom-webpack/server'
5676
);
@@ -101,7 +121,9 @@ async function renderApp(res, returnValue, formState, noCache) {
101121
);
102122
// For client-invoked server actions we refresh the tree and return a return value.
103123
const payload = {root, returnValue, formState};
104-
const {pipe} = renderToPipeableStream(payload, moduleMap);
124+
const {pipe} = renderToPipeableStream(payload, moduleMap, {
125+
debugChannel: await promiseForDebugChannel,
126+
});
105127
pipe(res);
106128
}
107129

@@ -166,7 +188,7 @@ app.get('/', async function (req, res) {
166188
if ('prerender' in req.query) {
167189
await prerenderApp(res, null, null, noCache);
168190
} else {
169-
await renderApp(res, null, null, noCache);
191+
await renderApp(res, null, null, noCache, getDebugChannel(req));
170192
}
171193
});
172194

@@ -204,7 +226,7 @@ app.post('/', bodyParser.text(), async function (req, res) {
204226
// We handle the error on the client
205227
}
206228
// Refresh the client and return the value
207-
renderApp(res, result, null, noCache);
229+
renderApp(res, result, null, noCache, getDebugChannel(req));
208230
} else {
209231
// This is the progressive enhancement case
210232
const UndiciRequest = require('undici').Request;
@@ -220,11 +242,11 @@ app.post('/', bodyParser.text(), async function (req, res) {
220242
// Wait for any mutations
221243
const result = await action();
222244
const formState = decodeFormState(result, formData);
223-
renderApp(res, null, formState, noCache);
245+
renderApp(res, null, formState, noCache, undefined);
224246
} catch (x) {
225247
const {setServerState} = await import('../src/ServerState.js');
226248
setServerState('Error: ' + x.message);
227-
renderApp(res, null, null, noCache);
249+
renderApp(res, null, null, noCache, undefined);
228250
}
229251
}
230252
});
@@ -324,7 +346,7 @@ if (process.env.NODE_ENV === 'development') {
324346
});
325347
}
326348

327-
app.listen(3001, () => {
349+
const httpServer = app.listen(3001, () => {
328350
console.log('Regional Flight Server listening on port 3001...');
329351
});
330352

@@ -346,3 +368,27 @@ app.on('error', function (error) {
346368
throw error;
347369
}
348370
});
371+
372+
if (process.env.NODE_ENV === 'development') {
373+
// Open a websocket server for Debug information
374+
const WebSocket = require('ws');
375+
const webSocketServer = new WebSocket.Server({noServer: true});
376+
377+
httpServer.on('upgrade', (request, socket, head) => {
378+
const DEBUG_CHANNEL_PATH = '/debug-channel?';
379+
if (request.url.startsWith(DEBUG_CHANNEL_PATH)) {
380+
const requestId = request.url.slice(DEBUG_CHANNEL_PATH.length);
381+
const promiseForWs = new Promise(resolve => {
382+
webSocketServer.handleUpgrade(request, socket, head, ws => {
383+
ws.on('close', () => {
384+
activeDebugChannels.delete(requestId);
385+
});
386+
resolve(ws);
387+
});
388+
});
389+
activeDebugChannels.set(requestId, promiseForWs);
390+
} else {
391+
socket.destroy();
392+
}
393+
});
394+
}

fixtures/flight/src/App.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ async function ServerComponent({noCache}) {
123123
export default async function App({prerender, noCache}) {
124124
const res = await fetch('http://localhost:3001/todos');
125125
const todos = await res.json();
126-
console.log(res);
127126

128127
const dedupedChild = <ServerComponent noCache={noCache} />;
129128
const message = getServerState();

fixtures/flight/src/index.js

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,43 @@ function Shell({data}) {
4242
}
4343

4444
async function hydrateApp() {
45-
const {root, returnValue, formState} = await createFromFetch(
46-
fetch('/', {
47-
headers: {
48-
Accept: 'text/x-component',
49-
},
50-
}),
51-
{
52-
callServer,
53-
findSourceMapURL,
54-
}
55-
);
45+
let response;
46+
if (
47+
process.env.NODE_ENV === 'development' &&
48+
typeof WebSocketStream === 'function'
49+
) {
50+
const requestId = crypto.randomUUID();
51+
const wss = new WebSocketStream(
52+
'ws://localhost:3001/debug-channel?' + requestId
53+
);
54+
const debugChannel = await wss.opened;
55+
response = createFromFetch(
56+
fetch('/', {
57+
headers: {
58+
Accept: 'text/x-component',
59+
'rsc-request-id': requestId,
60+
},
61+
}),
62+
{
63+
callServer,
64+
debugChannel,
65+
findSourceMapURL,
66+
}
67+
);
68+
} else {
69+
response = createFromFetch(
70+
fetch('/', {
71+
headers: {
72+
Accept: 'text/x-component',
73+
},
74+
}),
75+
{
76+
callServer,
77+
findSourceMapURL,
78+
}
79+
);
80+
}
81+
const {root, returnValue, formState} = await response;
5682

5783
ReactDOM.hydrateRoot(
5884
document,

0 commit comments

Comments
 (0)