Skip to content

Commit

Permalink
Fix data encoder and decoder to use stream in renderer (vercel#35936)
Browse files Browse the repository at this point in the history
There are several places where the decoder should have `stream: true`. Also changed the `encodeText(extraChunk + decodeText(chunk))` pattern to just emit two chunks.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
  • Loading branch information
shuding authored and colinhacks committed Apr 14, 2022
1 parent 853cee4 commit 57075cf
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 6 deletions.
2 changes: 1 addition & 1 deletion packages/next/client/index.tsx
Expand Up @@ -778,7 +778,7 @@ if (process.env.__NEXT_RSC) {
if (serialized) {
const readable = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(serialized))
controller.enqueue(encoder.encode(serialized))
controller.close()
},
})
Expand Down
11 changes: 7 additions & 4 deletions packages/next/server/node-web-streams-helper.ts
Expand Up @@ -94,6 +94,8 @@ export async function streamToString(
stream: ReadableStream<Uint8Array>
): Promise<string> {
const reader = stream.getReader()
const textDecoder = new TextDecoder()

let bufferedString = ''

while (true) {
Expand All @@ -103,7 +105,7 @@ export async function streamToString(
return bufferedString
}

bufferedString += decodeText(value)
bufferedString += decodeText(value, textDecoder)
}
}

Expand Down Expand Up @@ -230,9 +232,10 @@ export function createFlushEffectStream(
): TransformStream<Uint8Array, Uint8Array> {
return createTransformStream({
async transform(chunk, controller) {
const extraChunk = await handleFlushEffect()
// those should flush together at once
controller.enqueue(encodeText(extraChunk + decodeText(chunk)))
const flushedChunk = encodeText(await handleFlushEffect())

controller.enqueue(flushedChunk)
controller.enqueue(chunk)
},
})
}
Expand Down
6 changes: 5 additions & 1 deletion packages/next/server/render.tsx
Expand Up @@ -1461,15 +1461,19 @@ export async function renderToHTML(
// If it's a server component with the Node.js runtime, we also
// statically generate the page data.
let data = ''

const readable = serverComponentsPageDataTransformStream.readable
const reader = readable.getReader()
const textDecoder = new TextDecoder()

while (true) {
const { done, value } = await reader.read()
if (done) {
break
}
data += decodeText(value)
data += decodeText(value, textDecoder)
}

;(renderOpts as any).pageData = {
...(renderOpts as any).pageData,
__flight__: data,
Expand Down

0 comments on commit 57075cf

Please sign in to comment.