Skip to content

Instantly share code, notes, and snippets.

@codinronan
Created March 18, 2021 17:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codinronan/2753aaf472126009f2bc0f8b3b24d5ca to your computer and use it in GitHub Desktop.
Save codinronan/2753aaf472126009f2bc0f8b3b24d5ca to your computer and use it in GitHub Desktop.
Simple browser Storage abstraction to protect you from unavailable LocalStorage
// 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