From b3765f13dad710bf64e938f547d7bb3ace13d744 Mon Sep 17 00:00:00 2001 From: tapframe <85391825+tapframe@users.noreply.github.com> Date: Mon, 19 Jan 2026 12:52:03 +0530 Subject: [PATCH] various simkl api call optimizations --- src/services/simklService.ts | 78 +++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/src/services/simklService.ts b/src/services/simklService.ts index 677664a8..b824a138 100644 --- a/src/services/simklService.ts +++ b/src/services/simklService.ts @@ -151,6 +151,16 @@ export class SimklService { // Default completion threshold (can't be configured on Simkl side essentially, but we use it for logic) private readonly COMPLETION_THRESHOLD = 80; + // Caching & Deduplication + private playbackStatusPromise: Promise | null = null; + private cachedPlaybackStatus: SimklPlaybackData[] = []; + private lastPlaybackStatusTime: number = 0; + private readonly PLAYBACK_CACHE_TTL = 10000; // 10 seconds + + private cachedUserSettings: SimklUserSettings | null = null; + private lastUserSettingsTime: number = 0; + private readonly USER_SETTINGS_CACHE_TTL = 300000; // 5 minutes (5 * 60 * 1000) + private constructor() { // Determine cleanup logic if needed AppState.addEventListener('change', this.handleAppStateChange); @@ -254,6 +264,16 @@ export class SimklService { await this.ensureInitialized(); this.accessToken = null; await mmkvStorage.removeItem(SIMKL_ACCESS_TOKEN_KEY); + + // Clear caches + this.cachedPlaybackStatus = []; + this.lastPlaybackStatusTime = 0; + this.playbackStatusPromise = null; + this.lastSyncTimes.clear(); + + this.cachedUserSettings = null; + this.lastUserSettingsTime = 0; + logger.log('[SimklService] Logged out'); } @@ -533,15 +553,40 @@ export class SimklService { return await this.apiRequest('/sync/history/remove', 'POST', items); } - public async getPlaybackStatus(): Promise { - const playback = await this.apiRequest('/sync/playback'); - const items = Array.isArray(playback) ? playback : []; - const sorted = items - .filter(Boolean) - .sort((a, b) => new Date(b.paused_at).getTime() - new Date(a.paused_at).getTime()); + public async getPlaybackStatus(forceRefresh: boolean = false): Promise { + await this.ensureInitialized(); - logger.log(`[SimklService] getPlaybackStatus: ${sorted.length} items`); - return sorted; + const now = Date.now(); + + // 1. Check cache (unless forced) + if (!forceRefresh && this.cachedPlaybackStatus.length > 0 && (now - this.lastPlaybackStatusTime < this.PLAYBACK_CACHE_TTL)) { + logger.log('[SimklService] getPlaybackStatus: Returning cached data'); + return this.cachedPlaybackStatus; + } + + // 2. Check in-flight request deduplication + if (this.playbackStatusPromise) { + logger.log('[SimklService] getPlaybackStatus: Returning in-flight promise'); + return this.playbackStatusPromise; + } + + // 3. Make new request + this.playbackStatusPromise = (async () => { + try { + const response = await this.apiRequest('/sync/playback'); + const data = response || []; + + // Update cache + this.cachedPlaybackStatus = data; + this.lastPlaybackStatusTime = Date.now(); + + return data; + } finally { + this.playbackStatusPromise = null; + } + })(); + + return this.playbackStatusPromise; } /** @@ -573,10 +618,22 @@ export class SimklService { /** * Get user settings/profile */ - public async getUserSettings(): Promise { + public async getUserSettings(forceRefresh: boolean = false): Promise { + const now = Date.now(); + if (!forceRefresh && this.cachedUserSettings && (now - this.lastUserSettingsTime < this.USER_SETTINGS_CACHE_TTL)) { + logger.log('[SimklService] getUserSettings: Returning cached data'); + return this.cachedUserSettings; + } + try { const response = await this.apiRequest('/users/settings', 'POST'); logger.log('[SimklService] getUserSettings:', JSON.stringify(response)); + + if (response) { + this.cachedUserSettings = response; + this.lastUserSettingsTime = Date.now(); + } + return response; } catch (error) { logger.error('[SimklService] Failed to get user settings:', error); @@ -606,4 +663,5 @@ export class SimklService { logger.error('[SimklService] Failed to get user stats:', error); return null; } - }} \ No newline at end of file + } +} \ No newline at end of file