Skip to content

Commit d85ec5f

Browse files
authored
[Flight] Assume __turbopack_load_by_url__ returns a cached Promise (facebook#33792)
1 parent fe81314 commit d85ec5f

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,6 @@ export function resolveServerReference<T>(
132132
return [resolvedModuleData.id, resolvedModuleData.chunks, name];
133133
}
134134

135-
// The chunk cache contains all the chunks we've preloaded so far.
136-
// If they're still pending they're a thenable. This map also exists
137-
// in Turbopack but unfortunately it's not exposed so we have to
138-
// replicate it in user space. null means that it has already loaded.
139-
const chunkCache: Map<string, null | Promise<any>> = new Map();
140-
141135
function requireAsyncModule(id: string): null | Thenable<any> {
142136
// We've already loaded all the chunks. We can require the module.
143137
const promise = __turbopack_require__(id);
@@ -165,6 +159,13 @@ function requireAsyncModule(id: string): null | Thenable<any> {
165159
}
166160
}
167161

162+
// Turbopack will return cached promises for the same chunk.
163+
// We still want to keep track of which chunks we have already instrumented
164+
// and which chunks have already been loaded until Turbopack returns instrumented
165+
// thenables directly.
166+
const instrumentedChunks: WeakSet<Thenable<any>> = new WeakSet();
167+
const loadedChunks: WeakSet<Thenable<any>> = new WeakSet();
168+
168169
function ignoreReject() {
169170
// We rely on rejected promises to be handled by another listener.
170171
}
@@ -174,19 +175,19 @@ export function preloadModule<T>(
174175
metadata: ClientReference<T>,
175176
): null | Thenable<any> {
176177
const chunks = metadata[CHUNKS];
177-
const promises = [];
178+
const promises: Promise<any>[] = [];
178179
for (let i = 0; i < chunks.length; i++) {
179180
const chunkFilename = chunks[i];
180-
const entry = chunkCache.get(chunkFilename);
181-
if (entry === undefined) {
182-
const thenable = loadChunk(chunkFilename);
181+
const thenable = loadChunk(chunkFilename);
182+
if (!loadedChunks.has(thenable)) {
183183
promises.push(thenable);
184+
}
185+
186+
if (!instrumentedChunks.has(thenable)) {
184187
// $FlowFixMe[method-unbinding]
185-
const resolve = chunkCache.set.bind(chunkCache, chunkFilename, null);
188+
const resolve = loadedChunks.add.bind(loadedChunks, thenable);
186189
thenable.then(resolve, ignoreReject);
187-
chunkCache.set(chunkFilename, thenable);
188-
} else if (entry !== null) {
189-
promises.push(entry);
190+
instrumentedChunks.add(thenable);
190191
}
191192
}
192193
if (isAsyncImport(metadata)) {

0 commit comments

Comments
 (0)