Created
March 18, 2021 17:54
-
-
Save codinronan/2753aaf472126009f2bc0f8b3b24d5ca to your computer and use it in GitHub Desktop.
Simple browser Storage abstraction to protect you from unavailable LocalStorage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From https://michalzalecki.com/why-using-localStorage-directly-is-a-bad-idea/ | |
// I always end up re-implementing this again every time I need it, so better to just put it here. | |
function isSupported(getStorage) { | |
try { | |
const key = "__some_random_key_you_are_not_going_to_use__"; | |
getStorage().setItem(key, key); | |
getStorage().removeItem(key); | |
return true; | |
} catch (e) { | |
return false; | |
} | |
} | |
isSupported(() => localStorage); // => true | false | |
/* ISC License (ISC). Copyright 2017 Michal Zalecki */ | |
export function storageFactory(getStorage: () => Storage): Storage { | |
let inMemoryStorage: { [key: string]: string } = {}; | |
function isSupported() { | |
try { | |
const testKey = "__some_random_key_you_are_not_going_to_use__"; | |
getStorage().setItem(testKey, testKey); | |
getStorage().removeItem(testKey); | |
return true; | |
} catch (e) { | |
return false; | |
} | |
} | |
function clear(): void { | |
if (isSupported()) { | |
getStorage().clear(); | |
} else { | |
inMemoryStorage = {}; | |
} | |
} | |
function getItem(name: string): string | null { | |
if (isSupported()) { | |
return getStorage().getItem(name); | |
} | |
if (inMemoryStorage.hasOwnProperty(name)) { | |
return inMemoryStorage[name]; | |
} | |
return null; | |
} | |
function key(index: number): string | null { | |
if (isSupported()) { | |
return getStorage().key(index); | |
} else { | |
return Object.keys(inMemoryStorage)[index] || null; | |
} | |
} | |
function removeItem(name: string): void { | |
if (isSupported()) { | |
getStorage().removeItem(name); | |
} else { | |
delete inMemoryStorage[name]; | |
} | |
} | |
function setItem(name: string, value: string): void { | |
if (isSupported()) { | |
getStorage().setItem(name, value); | |
} else { | |
inMemoryStorage[name] = String(value); // not everyone uses TypeScript | |
} | |
} | |
function length(): number { | |
if (isSupported()) { | |
return getStorage().length; | |
} else { | |
return Object.keys(inMemoryStorage).length; | |
} | |
} | |
return { | |
getItem, | |
setItem, | |
removeItem, | |
clear, | |
key, | |
get length() { | |
return length(); | |
}, | |
}; | |
} | |
export const localStore = storageFactory(() => localStorage); | |
export const sessionStore = storageFactory(() => sessionStorage); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment