81 lines
2.2 KiB
JavaScript
81 lines
2.2 KiB
JavaScript
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 {
|
|
const storage = JSON.parse(this.storage.getItem(KEY)) ?? {};
|
|
Object.values(storage).forEach((entry) => {
|
|
if (entry.progress && !('message' in entry.progress)) {
|
|
// eslint-disable-next-line no-param-reassign
|
|
entry.progress.message = '';
|
|
}
|
|
});
|
|
return storage;
|
|
} 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);
|
|
}
|