Skip to content

Commit f80745e

Browse files
committed
refactor(@angular/build): ensure deterministic locale ordering in cache checks
Resolve asynchronous cache checks on a per-file basis using Promise.all to ensure windowLocales ordering is preserved within uncachedByFile regardless of disk I/O resolution timing. Also avoids pre-populating and deleting empty arrays in uncachedByFile.
1 parent d329040 commit f80745e

1 file changed

Lines changed: 36 additions & 42 deletions

File tree

packages/angular/build/src/tools/esbuild/i18n-inliner.ts

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -286,58 +286,52 @@ export class I18nInliner {
286286
const uncachedByFile = new Map<string, UncachedLocaleEntry[]>();
287287

288288
if (this.#transformedFileCache) {
289+
const cache = this.#transformedFileCache;
289290
const cacheChecks: Promise<void>[] = [];
290291

291292
for (const filename of filenames) {
292293
const file = this.#localizeFiles.get(filename);
293294
assert(file !== undefined, 'Localize file must exist: ' + filename);
294295

295-
const fileEntries: UncachedLocaleEntry[] = [];
296-
297-
for (const { locale } of windowLocales) {
298-
const fileCacheKeyBase = localeCacheBases.get(locale);
299-
assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale);
300-
301-
const hasher = createContentHash();
302-
hasher.update(file.hash);
303-
hasher.update(filename);
304-
hasher.update(fileCacheKeyBase);
305-
const cacheKey = hasher.digest();
306-
307-
cacheChecks.push(
308-
this.#transformedFileCache
309-
.get(cacheKey)
310-
.then((result) => {
311-
if (result) {
312-
fileResultsByLocale.get(locale)?.set(filename, result);
313-
} else {
314-
fileEntries.push({
315-
locale,
316-
cacheKey,
317-
translation: localeBlobs.get(locale),
318-
});
319-
}
320-
})
321-
.catch(() => {
322-
fileEntries.push({
323-
locale,
324-
cacheKey,
325-
translation: localeBlobs.get(locale),
326-
});
327-
}),
328-
);
329-
}
296+
const fileEntriesPromises = windowLocales.map(
297+
async ({ locale }): Promise<UncachedLocaleEntry | undefined> => {
298+
const fileCacheKeyBase = localeCacheBases.get(locale);
299+
assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale);
300+
301+
const hasher = createContentHash();
302+
hasher.update(file.hash);
303+
hasher.update(filename);
304+
hasher.update(fileCacheKeyBase);
305+
const cacheKey = hasher.digest();
306+
307+
try {
308+
const result = await cache.get(cacheKey);
309+
if (result) {
310+
fileResultsByLocale.get(locale)?.set(filename, result);
311+
312+
return;
313+
}
314+
} catch {}
315+
316+
return {
317+
locale,
318+
cacheKey,
319+
translation: localeBlobs.get(locale),
320+
};
321+
},
322+
);
330323

331-
uncachedByFile.set(filename, fileEntries);
324+
cacheChecks.push(
325+
Promise.all(fileEntriesPromises).then((entries) => {
326+
const filtered = entries.filter((e): e is UncachedLocaleEntry => e !== undefined);
327+
if (filtered.length > 0) {
328+
uncachedByFile.set(filename, filtered);
329+
}
330+
}),
331+
);
332332
}
333333

334334
await Promise.all(cacheChecks);
335-
336-
for (const [filename, entries] of uncachedByFile) {
337-
if (entries.length === 0) {
338-
uncachedByFile.delete(filename);
339-
}
340-
}
341335
} else {
342336
for (const filename of filenames) {
343337
uncachedByFile.set(

0 commit comments

Comments
 (0)