Skip to content

Instantly share code, notes, and snippets.

@stramel
Created February 7, 2024 18:48
Show Gist options
  • Save stramel/43e744a5eeff39c6a8c770856a93ca70 to your computer and use it in GitHub Desktop.
Save stramel/43e744a5eeff39c6a8c770856a93ca70 to your computer and use it in GitHub Desktop.
/**
* Checks if the specified Web Storage API exists and is accessible
* @param storage - Web Storage API
* @returns true, if the Web Storage API is accessible
*/
const isStorageEnabled = (storage?: Storage): storage is Storage => {
if (!storage) return false;
try {
const key = `__storage__test`;
storage.setItem(key, '');
storage.removeItem(key);
return true;
} catch {
return false;
}
};
/**
* Utilizes a `Map` cache backed Web Storage API when the specified Web Storage API isn't accessible
* @param storage - possible Web Storage API
* @returns a Web Storage API implementation
*/
const createStorage = (storage?: Storage): Storage => {
if (isStorageEnabled(storage)) {
return storage;
}
const storageFallbackCache = new Map<string, string>();
return {
clear(): void {
storageFallbackCache.clear();
},
getItem(key: string): string | null {
// eslint-disable-next-line unicorn/no-null
return storageFallbackCache.get(key) ?? null;
},
key(index: number): string | null {
// eslint-disable-next-line unicorn/no-null
return [...storageFallbackCache.values()][index] ?? null;
},
get length() {
return storageFallbackCache.size;
},
removeItem(key: string): void {
storageFallbackCache.delete(key);
},
setItem(key: string, value: string): void {
storageFallbackCache.set(key, value);
},
};
};
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
export const localStorage = createStorage(window?.localStorage);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
export const sessionStorage = createStorage(window?.sessionStorage);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment