Created
July 13, 2021 20:01
-
-
Save braebo/75c478c6098245162727b1044c108077 to your computer and use it in GitHub Desktop.
asyncLocalStorageStore for Sveltekit
This file contains hidden or 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
import { writable } from 'svelte/store'; | |
import { browser } from '$app/env'; | |
const setAsync = async (key: string, value: any): Promise<void> => { | |
return Promise.resolve().then(() => { | |
typeof value != 'string' | |
? localStorage.setItem(key, JSON.stringify(value)) | |
: localStorage.setItem(key, value); | |
}); | |
} | |
const getAsync = async (key: string): Promise<JSON> => { | |
return Promise.resolve().then(() => { | |
let value = localStorage.getItem(key); | |
//? return object if valid json | |
try { | |
const object = JSON.parse(value); | |
if (object && typeof object === "object") { | |
return object; | |
} | |
} catch (e) {} //? discard error | |
//? make sure booleans aren't returned as strings | |
if (typeof value == 'string' && value == 'true' || value == 'false') return value === 'true' | |
return value; | |
}); | |
}; | |
// Adapted from https://svelte.dev/repl/7b4d6b448f8c4ed2b3d5a3c31260be2a?version=3.34.0 | |
export const localStorageStore = (key: string, value: any) => { | |
const { set: setStore, ...readableStore } = writable(value, () => { | |
if (!browser) return; | |
getAndSetFromLocalStorage(); | |
const updateFromStorageEvents = (event) => { | |
if (event.key === key) getAndSetFromLocalStorage(); | |
}; | |
window.addEventListener("storage", updateFromStorageEvents); | |
return () => window.removeEventListener("storage", updateFromStorageEvents); | |
}); | |
// Set both localStorage and this Svelte store | |
const set = async (value: any) => { | |
setStore(value); | |
try { | |
await setAsync(key, value); | |
} catch (error) { | |
console.error(`the \`${key}\` store's new value \`${value}\` could not be persisted to localStorage because of ${error}`); | |
} | |
}; | |
// Synchronize the Svelte store with localStorage | |
const getAndSetFromLocalStorage = async () => { | |
let localValue = null; | |
localValue = await getAsync(key).catch((error) => { | |
console.error(`the \`${key}\` store's value could not be restored from localStorage because of ${error}`); | |
}) | |
if (localValue === null) { | |
await setAsync(key, value); | |
} | |
else { | |
try { | |
// await setAsync(key, localValue); | |
setStore(localValue); | |
} catch (error) { | |
console.error(`the \`${key}\` store's value could not be added to localStorage because of ${error}`); | |
} | |
} | |
}; | |
return { ...readableStore, set }; | |
}; | |
export default localStorageStore |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use: