Skip to content

Commit 87a1799

Browse files
committed
Use lazy ID if referenced model chunk was not emitted yet
fixes #28595
1 parent 84a9438 commit 87a1799

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

packages/react-server/src/ReactFlightServer.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ export type Request = {
281281
writtenClientReferences: Map<ClientReferenceKey, number>,
282282
writtenServerReferences: Map<ServerReference<any>, number>,
283283
writtenObjects: WeakMap<Reference, number>, // -1 means "seen" but not outlined.
284+
emittedModelChunkIds: Set<number>,
284285
identifierPrefix: string,
285286
identifierCount: number,
286287
taintCleanupQueue: Array<string | bigint>,
@@ -379,6 +380,7 @@ export function createRequest(
379380
writtenClientReferences: new Map(),
380381
writtenServerReferences: new Map(),
381382
writtenObjects: new WeakMap(),
383+
emittedModelChunkIds: new Set(),
382384
identifierPrefix: identifierPrefix || '',
383385
identifierCount: 1,
384386
taintCleanupQueue: cleanupQueue,
@@ -1334,16 +1336,14 @@ function renderModelDestructive(
13341336
// but that is able to reuse the same task if we're already in one but then that
13351337
// will be a lazy future value rather than guaranteed to exist but maybe that's good.
13361338
const newId = outlineModel(request, (value: any));
1337-
return serializeByValueID(newId);
1339+
return request.emittedModelChunkIds.has(newId)
1340+
? serializeByValueID(newId)
1341+
: serializeLazyID(newId);
13381342
} else {
1339-
// We've already emitted this as an outlined object, so we can refer to that by its
1340-
// existing ID. TODO: We should use a lazy reference since, unlike plain objects,
1341-
// elements might suspend so it might not have emitted yet even if we have the ID for
1342-
// it. However, this creates an extra wrapper when it's not needed. We should really
1343-
// detect whether this already was emitted and synchronously available. In that
1344-
// case we can refer to it synchronously and only make it lazy otherwise.
1345-
// We currently don't have a data structure that lets us see that though.
1346-
return serializeByValueID(existingId);
1343+
// We've already outlined this model, so we can refer to that by its existing ID.
1344+
return request.emittedModelChunkIds.has(existingId)
1345+
? serializeByValueID(existingId)
1346+
: serializeLazyID(existingId);
13471347
}
13481348
} else {
13491349
// This is the first time we've seen this object. We may never see it again
@@ -1884,6 +1884,7 @@ function emitSymbolChunk(request: Request, id: number, name: string): void {
18841884
function emitModelChunk(request: Request, id: number, json: string): void {
18851885
const row = id.toString(16) + ':' + json + '\n';
18861886
const processedChunk = stringToChunk(row);
1887+
request.emittedModelChunkIds.add(id);
18871888
request.completedRegularChunks.push(processedChunk);
18881889
}
18891890

0 commit comments

Comments
 (0)