|
|
@@ -0,0 +1,58 @@ |
|
|
/** |
|
|
* 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); |