@samitouri / QOS-React-2 / commits / d85ec5f5bd

[Flight] Assume `__turbopack_load_by_url__ ` returns a cached Promise (#33792)

Sebastian "Sebbie" Silbermann committed Jul 16, 2025 at 13:20 UTC d85ec5f5bd778d09214e3429e7fd043c4a152242
1 file changed +15 -14
packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack.js
+15 -14
@@ -132,12 +132,6 @@ export function resolveServerReference<T>(
132 return [resolvedModuleData.id, resolvedModuleData.chunks, name];
133 }
134
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 -
135 function requireAsyncModule(id: string): null | Thenable<any> {
136 // We've already loaded all the chunks. We can require the module.
137 const promise = __turbopack_require__(id);
@@ -165,6 +159,13 @@ function requireAsyncModule(id: string): null | Thenable<any> {
159 }
160 }
161
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 +
169 function ignoreReject() {
170 // We rely on rejected promises to be handled by another listener.
171 }
@@ -174,19 +175,19 @@ export function preloadModule<T>(
175 metadata: ClientReference<T>,
176 ): null | Thenable<any> {
177 const chunks = metadata[CHUNKS];
177 - const promises = [];
178 + const promises: Promise<any>[] = [];
179 for (let i = 0; i < chunks.length; i++) {
180 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)) {
183 promises.push(thenable);
184 + }
185 +
186 + if (!instrumentedChunks.has(thenable)) {
187 // $FlowFixMe[method-unbinding]
185 - const resolve = chunkCache.set.bind(chunkCache, chunkFilename, null);
188 + const resolve = loadedChunks.add.bind(loadedChunks, thenable);
189 thenable.then(resolve, ignoreReject);
187 - chunkCache.set(chunkFilename, thenable);
188 - } else if (entry !== null) {
189 - promises.push(entry);
190 + instrumentedChunks.add(thenable);
191 }
192 }
193 if (isAsyncImport(metadata)) {