diff options
Diffstat (limited to 'app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js')
-rw-r--r-- | app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js new file mode 100644 index 00000000000..09bc7b33692 --- /dev/null +++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js @@ -0,0 +1,74 @@ +import { debounce, merge } from 'lodash'; +import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; + +const OLD_KEY = 'gl-bulk-imports-import-state'; +export const KEY = 'gl-bulk-imports-import-state-v2'; +export const DEBOUNCE_INTERVAL = DEFAULT_DEBOUNCE_AND_THROTTLE_MS; + +export class LocalStorageCache { + constructor({ storage = window.localStorage } = {}) { + this.storage = storage; + this.cache = this.loadCacheFromStorage(); + try { + // remove old storage data + this.storage.removeItem(OLD_KEY); + } catch { + // empty catch intended + } + + // cache for searching data by jobid + this.jobsLookupCache = {}; + } + + loadCacheFromStorage() { + try { + return JSON.parse(this.storage.getItem(KEY)) ?? {}; + } catch { + return {}; + } + } + + set(webUrl, data) { + this.cache[webUrl] = data; + this.saveCacheToStorage(); + // There are changes to jobIds, drop cache + this.jobsLookupCache = {}; + } + + get(webUrl) { + return this.cache[webUrl]; + } + + getCacheKeysByJobId(jobId) { + // this is invoked by polling, so we would like to cache results + if (!this.jobsLookupCache[jobId]) { + this.jobsLookupCache[jobId] = Object.keys(this.cache).filter( + (url) => this.cache[url]?.progress.id === jobId, + ); + } + + return this.jobsLookupCache[jobId]; + } + + updateStatusByJobId(jobId, status) { + this.getCacheKeysByJobId(jobId).forEach((webUrl) => + this.set(webUrl, { + ...(this.get(webUrl) ?? {}), + progress: { + id: jobId, + status, + }, + }), + ); + this.saveCacheToStorage(); + } + + saveCacheToStorage = debounce(() => { + try { + // storage might be changed in other tab so fetch first + this.storage.setItem(KEY, JSON.stringify(merge({}, this.loadCacheFromStorage(), this.cache))); + } catch { + // empty catch intentional: storage might be unavailable or full + } + }, DEBOUNCE_INTERVAL); +} |