From dbc525e8d8aef0eeb27aa770b082ab0db59bf462 Mon Sep 17 00:00:00 2001 From: Ralksta <16941050+ralksta@users.noreply.github.com> Date: Wed, 1 Apr 2026 12:46:12 +0200 Subject: [PATCH] feat(performance): Add promise deduplication for ImmichClient.getAlbum (#69) Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- lib/immich.ts | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lib/immich.ts b/lib/immich.ts index f1c7e5d..0766919 100644 --- a/lib/immich.ts +++ b/lib/immich.ts @@ -73,6 +73,7 @@ export interface SubpageSummary { class ImmichClient { private hasLoggedAlbums = false; private pendingAlbumsPromise: Promise | null = null; + private pendingAlbumPromises = new Map>(); private get config() { return getConfig(); @@ -281,18 +282,31 @@ class ImmichClient { const cached = cache.get(cacheKey); if (cached) return cached; - const album = await this.request(`/albums/${encodeURIComponent(albumId)}`); - if (!album) return null; + if (this.pendingAlbumPromises.has(albumId)) { + return this.pendingAlbumPromises.get(albumId)!; + } - // Filter out trashed assets - album.assets = (album.assets || []).filter((a) => !a.isTrashed); + const promise = (async () => { + try { + const album = await this.request(`/albums/${encodeURIComponent(albumId)}`); + if (!album) return null; - const name = this.config.albumOverrides[album.id] ?? album.albumName; - album.albumName = name; - album.slug = slugify(name); + // Filter out trashed assets + album.assets = (album.assets || []).filter((a) => !a.isTrashed); - cache.set(cacheKey, album, this.config.cacheTtl); - return album; + const name = this.config.albumOverrides[album.id] ?? album.albumName; + album.albumName = name; + album.slug = slugify(name); + + cache.set(cacheKey, album, this.config.cacheTtl); + return album; + } finally { + this.pendingAlbumPromises.delete(albumId); + } + })(); + + this.pendingAlbumPromises.set(albumId, promise); + return promise; } /**