Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to debug hydration error #1295

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -5,7 +5,8 @@
"workspaces": [
"templates/*",
"packages/*",
"packages/playground/*"
"packages/playground/*",
"templates/*"
],
"engines": {
"node": ">=14"
Expand Down
2 changes: 1 addition & 1 deletion packages/hydrogen/graphql.schema.json

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions packages/hydrogen/src/entry-server.tsx
Expand Up @@ -428,12 +428,12 @@ async function stream(
}
);

const writingRSC = bufferReadableStream(
rscToScriptTagReadable.getReader(),
(scriptTag) => writable.write(encoder.encode(scriptTag))
);
// const writingRSC = bufferReadableStream(
// rscToScriptTagReadable.getReader(),
// (scriptTag) => writable.write(encoder.encode(scriptTag))
// );

Promise.all([writingSSR, writingRSC]).then(() => {
Promise.all([writingSSR]).then(() => {
// Last SSR write might be pending, delay closing the writable one tick
setTimeout(() => writable.close(), 0);
postRequestTasks(
Expand Down Expand Up @@ -495,10 +495,10 @@ async function stream(
pipe(response);
}, 0);

bufferReadableStream(rscToScriptTagReadable.getReader(), (chunk) => {
log.trace('rsc chunk');
return response.write(chunk);
});
// bufferReadableStream(rscToScriptTagReadable.getReader(), (chunk) => {
// log.trace('rsc chunk');
// return response.write(chunk);
// });
},
async onAllReady() {
log.trace('node complete stream');
Expand Down Expand Up @@ -533,14 +533,14 @@ async function stream(

startWritingHtmlToServerResponse(response, dev ? didError : undefined);

bufferReadableStream(rscToScriptTagReadable.getReader()).then(
(scriptTags) => {
// Piping ends the response so script tags
// must be written before that.
response.write(scriptTags);
pipe(response);
}
);
// bufferReadableStream(rscToScriptTagReadable.getReader()).then(
// (scriptTags) => {
// // Piping ends the response so script tags
// // must be written before that.
// response.write(scriptTags);
// pipe(response);
// }
// );
},
onShellError(error: any) {
log.error(error);
Expand Down
Expand Up @@ -198,17 +198,15 @@ function resolveModuleMetaData(config, moduleReference) {
}

// ATTENTION
// When adding new symbols to this file,
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
// The Symbol used to tag the ReactElement-like types.
var REACT_ELEMENT_TYPE = Symbol.for('react.element');
var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
var REACT_MEMO_TYPE = Symbol.for('react.memo');
var REACT_LAZY_TYPE = Symbol.for('react.lazy');
var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value');

var REACT_ELEMENT_TYPE = Symbol.for('react.element');
var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
var REACT_MEMO_TYPE = Symbol.for('react.memo');
var REACT_LAZY_TYPE = Symbol.for('react.lazy');
var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value');

// A reserved attribute.
// It is handled by React separately and shouldn't be written to the DOM.
Expand Down Expand Up @@ -506,7 +504,7 @@ var startInlineScript = stringToPrecomputedChunk('<script>');
var endInlineScript = stringToPrecomputedChunk('</script>');
var startScriptSrc = stringToPrecomputedChunk('<script src="');
var startModuleSrc = stringToPrecomputedChunk('<script type="module" src="');
var endAsyncScript = stringToPrecomputedChunk('" async=""></script>'); // Allows us to keep track of what we've already written so we can refer back to it.
var endAsyncScript = stringToPrecomputedChunk('" async=""></script>');

var textSeparator = stringToPrecomputedChunk('<!-- -->');

Expand Down
Expand Up @@ -15,6 +15,7 @@ if (process.env.NODE_ENV !== "production") {
'use strict';

var React = require('react');
var util = require('util');

var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;

Expand Down Expand Up @@ -67,31 +68,144 @@ function flushBuffered(destination) {
destination.flush();
}
}
var VIEW_SIZE = 2048;
var currentView = null;
var writtenBytes = 0;
var destinationHasCapacity = true;
function beginWriting(destination) {
// Older Node streams like http.createServer don't have this.
if (typeof destination.cork === 'function') {
destination.cork();
currentView = new Uint8Array(VIEW_SIZE);
writtenBytes = 0;
destinationHasCapacity = true;
}

function writeStringChunk(destination, stringChunk) {
if (stringChunk.length === 0) {
return;
} // maximum possible view needed to encode entire string


if (stringChunk.length * 3 > VIEW_SIZE) {
if (writtenBytes > 0) {
writeToDestination(destination, currentView.subarray(0, writtenBytes));
currentView = new Uint8Array(VIEW_SIZE);
writtenBytes = 0;
}

writeToDestination(destination, textEncoder.encode(stringChunk));
return;
}

var target = currentView;

if (writtenBytes > 0) {
target = currentView.subarray(writtenBytes);
}

var _textEncoder$encodeIn = textEncoder.encodeInto(stringChunk, target),
read = _textEncoder$encodeIn.read,
written = _textEncoder$encodeIn.written;

writtenBytes += written;

if (read < stringChunk.length) {
writeToDestination(destination, currentView);
currentView = new Uint8Array(VIEW_SIZE);
writtenBytes = textEncoder.encodeInto(stringChunk.slice(read), currentView).written;
}

if (writtenBytes === VIEW_SIZE) {
writeToDestination(destination, currentView);
currentView = new Uint8Array(VIEW_SIZE);
writtenBytes = 0;
}
}
function writeChunkAndReturn(destination, chunk) {
var nodeBuffer = chunk; // close enough

return destination.write(nodeBuffer);
function writeViewChunk(destination, chunk) {
if (chunk.byteLength === 0) {
return;
}

if (chunk.byteLength > VIEW_SIZE) {
// this chunk may overflow a single view which implies it was not
// one that is cached by the streaming renderer. We will enqueu
// it directly and expect it is not re-used
if (writtenBytes > 0) {
writeToDestination(destination, currentView.subarray(0, writtenBytes));
currentView = new Uint8Array(VIEW_SIZE);
writtenBytes = 0;
}

writeToDestination(destination, chunk);
return;
}

var bytesToWrite = chunk;
var allowableBytes = currentView.length - writtenBytes;

if (allowableBytes < bytesToWrite.byteLength) {
// this chunk would overflow the current view. We enqueue a full view
// and start a new view with the remaining chunk
if (allowableBytes === 0) {
// the current view is already full, send it
writeToDestination(destination, currentView);
} else {
// fill up the current view and apply the remaining chunk bytes
// to a new view.
currentView.set(bytesToWrite.subarray(0, allowableBytes), writtenBytes);
writtenBytes += allowableBytes;
writeToDestination(destination, currentView);
bytesToWrite = bytesToWrite.subarray(allowableBytes);
}

currentView = new Uint8Array(VIEW_SIZE);
writtenBytes = 0;
}

currentView.set(bytesToWrite, writtenBytes);
writtenBytes += bytesToWrite.byteLength;

if (writtenBytes === VIEW_SIZE) {
writeToDestination(destination, currentView);
currentView = new Uint8Array(VIEW_SIZE);
writtenBytes = 0;
}
}

function writeChunk(destination, chunk) {
if (typeof chunk === 'string') {
writeStringChunk(destination, chunk);
} else {
writeViewChunk(destination, chunk);
}
}

function writeToDestination(destination, view) {
var currentHasCapacity = destination.write(view);
destinationHasCapacity = destinationHasCapacity && currentHasCapacity;
}

function writeChunkAndReturn(destination, chunk) {
writeChunk(destination, chunk);
return destinationHasCapacity;
}
function completeWriting(destination) {
// Older Node streams like http.createServer don't have this.
if (typeof destination.uncork === 'function') {
destination.uncork();
if (currentView && writtenBytes > 0) {
destination.write(currentView.subarray(0, writtenBytes));
}

currentView = null;
writtenBytes = 0;
destinationHasCapacity = true;
}
function close(destination) {
destination.end();
}
var textEncoder = new util.TextEncoder();
function stringToChunk(content) {
return content;
}
function stringToPrecomputedChunk(content) {
return Buffer.from(content, 'utf8');
return textEncoder.encode(content);
}
function closeWithError(destination, error) {
// $FlowFixMe: This is an Error object or the destination accepts other types.
Expand Down Expand Up @@ -150,17 +264,15 @@ function resolveModuleMetaData(config, moduleReference) {
}

// ATTENTION
// When adding new symbols to this file,
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
// The Symbol used to tag the ReactElement-like types.
var REACT_ELEMENT_TYPE = Symbol.for('react.element');
var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
var REACT_MEMO_TYPE = Symbol.for('react.memo');
var REACT_LAZY_TYPE = Symbol.for('react.lazy');
var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value');

var REACT_ELEMENT_TYPE = Symbol.for('react.element');
var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
var REACT_MEMO_TYPE = Symbol.for('react.memo');
var REACT_LAZY_TYPE = Symbol.for('react.lazy');
var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value');

// A reserved attribute.
// It is handled by React separately and shouldn't be written to the DOM.
Expand Down Expand Up @@ -458,7 +570,7 @@ var startInlineScript = stringToPrecomputedChunk('<script>');
var endInlineScript = stringToPrecomputedChunk('</script>');
var startScriptSrc = stringToPrecomputedChunk('<script src="');
var startModuleSrc = stringToPrecomputedChunk('<script type="module" src="');
var endAsyncScript = stringToPrecomputedChunk('" async=""></script>'); // Allows us to keep track of what we've already written so we can refer back to it.
var endAsyncScript = stringToPrecomputedChunk('" async=""></script>');

var textSeparator = stringToPrecomputedChunk('<!-- -->');

Expand Down Expand Up @@ -1563,7 +1675,7 @@ function performWork(request) {
}

function flushCompletedChunks(request, destination) {
beginWriting(destination);
beginWriting();

try {
// We emit module chunks first in the stream so that
Expand Down