-
Notifications
You must be signed in to change notification settings - Fork 49k
[Flight] Encode references to existing objects by property path #28996
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,7 +231,7 @@ describe('ReactFlightDOMEdge', () => { | |
const [stream1, stream2] = passThrough(stream).tee(); | ||
|
||
const serializedContent = await readResult(stream1); | ||
expect(serializedContent.length).toBeLessThan(400); | ||
expect(serializedContent.length).toBeLessThan(470); | ||
|
||
const result = await ReactServerDOMClient.createFromReadableStream( | ||
stream2, | ||
|
@@ -543,6 +543,55 @@ describe('ReactFlightDOMEdge', () => { | |
expect(await iterator.next()).toEqual({value: undefined, done: true}); | ||
}); | ||
|
||
// @gate enableFlightReadableStream | ||
it('should ideally dedupe objects inside async iterables but does not yet', async () => { | ||
const obj = { | ||
this: {is: 'a large objected'}, | ||
with: {many: 'properties in it'}, | ||
}; | ||
const iterable = { | ||
async *[Symbol.asyncIterator]() { | ||
for (let i = 0; i < 30; i++) { | ||
yield obj; | ||
} | ||
}, | ||
}; | ||
|
||
const stream = ReactServerDOMServer.renderToReadableStream({ | ||
iterable, | ||
}); | ||
const [stream1, stream2] = passThrough(stream).tee(); | ||
|
||
const serializedContent = await readResult(stream1); | ||
// TODO: Ideally streams should dedupe objects but because we never outline the objects | ||
// they end up not having a row to reference them nor any of its nested objects. | ||
// expect(serializedContent.length).toBeLessThan(400); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a test to show case this. This used to work by the second row getting outlined. Because every "chunk/entry" inside a stream has the same ID we can't refer to those objects. Only the stream object itself ( This means we can't dedupe the object at the root of a stream row. Since we don't have a reference to that object we also can't dedupe the nested object via the parent neither. Leading to duplicating all these objects. It seems unfortunate to outline every chunk/entry in a stream just in case it needs deduping. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potentially there could be a way to reach into the nth item inside the buffer of the stream to get the Chunk responsible for that and then reach into it. |
||
expect(serializedContent.length).toBeGreaterThan(400); | ||
|
||
const result = await ReactServerDOMClient.createFromReadableStream( | ||
stream2, | ||
{ | ||
ssrManifest: { | ||
moduleMap: null, | ||
moduleLoading: null, | ||
}, | ||
}, | ||
); | ||
|
||
const items = []; | ||
const iterator = result.iterable[Symbol.asyncIterator](); | ||
let entry; | ||
while (!(entry = await iterator.next()).done) { | ||
items.push(entry.value); | ||
} | ||
|
||
// Should still match the result when parsed | ||
expect(items.length).toBe(30); | ||
// TODO: These should be the same | ||
// expect(items[5]).toBe(items[10]); // two random items are the same instance | ||
expect(items[5]).toEqual(items[10]); | ||
}); | ||
|
||
it('warns if passing a this argument to bind() of a server reference', async () => { | ||
const ServerModule = serverExports({ | ||
greet: function () {}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: To avoid confusion, I would prefer if we called this
reference
and notref
(here, as well as in the other switch cases), since we also useref
in this file to refer to the actual element ref.getOutlinedModel
also calls the paramreference
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is mainly to avoid all of these calls turning into multi-line.