Skip to content

Commit

Permalink
Choose lazy or value ID based on whether model chunk was emitted
Browse files Browse the repository at this point in the history
fixes #28595
  • Loading branch information
unstubbable committed Mar 23, 2024
1 parent 4baed31 commit d29a0dc
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions packages/react-server/src/ReactFlightServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ export type Request = {
writtenClientReferences: Map<ClientReferenceKey, number>,
writtenServerReferences: Map<ServerReference<any>, number>,
writtenObjects: WeakMap<Reference, number>, // -1 means "seen" but not outlined.
emittedModelChunkIds: Set<number>,
identifierPrefix: string,
identifierCount: number,
taintCleanupQueue: Array<string | bigint>,
Expand Down Expand Up @@ -379,6 +380,7 @@ export function createRequest(
writtenClientReferences: new Map(),
writtenServerReferences: new Map(),
writtenObjects: new WeakMap(),
emittedModelChunkIds: new Set(),
identifierPrefix: identifierPrefix || '',
identifierCount: 1,
taintCleanupQueue: cleanupQueue,
Expand Down Expand Up @@ -1334,16 +1336,14 @@ function renderModelDestructive(
// but that is able to reuse the same task if we're already in one but then that
// will be a lazy future value rather than guaranteed to exist but maybe that's good.
const newId = outlineModel(request, (value: any));
return serializeByValueID(newId);
return request.emittedModelChunkIds.has(newId)
? serializeByValueID(newId)
: serializeLazyID(newId);
} else {
// We've already emitted this as an outlined object, so we can refer to that by its
// existing ID. TODO: We should use a lazy reference since, unlike plain objects,
// elements might suspend so it might not have emitted yet even if we have the ID for
// it. However, this creates an extra wrapper when it's not needed. We should really
// detect whether this already was emitted and synchronously available. In that
// case we can refer to it synchronously and only make it lazy otherwise.
// We currently don't have a data structure that lets us see that though.
return serializeByValueID(existingId);
// We've already outlined this model, so we can refer to that by its existing ID.
return request.emittedModelChunkIds.has(existingId)
? serializeByValueID(existingId)
: serializeLazyID(existingId);
}
} else {
// This is the first time we've seen this object. We may never see it again
Expand Down Expand Up @@ -1884,6 +1884,7 @@ function emitSymbolChunk(request: Request, id: number, name: string): void {
function emitModelChunk(request: Request, id: number, json: string): void {
const row = id.toString(16) + ':' + json + '\n';
const processedChunk = stringToChunk(row);
request.emittedModelChunkIds.add(id);
request.completedRegularChunks.push(processedChunk);
}

Expand Down

0 comments on commit d29a0dc

Please sign in to comment.