From 6249631a722da0222a689ae2e595d85371f0b7a5 Mon Sep 17 00:00:00 2001 From: Kaspars Date: Tue, 7 May 2024 11:40:09 +0200 Subject: [PATCH] implement sessionAtom function (same api as persistenAtom, just used sessionStorage instead of localStorage) --- website/src/user_pattern_utils.mjs | 60 ++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/website/src/user_pattern_utils.mjs b/website/src/user_pattern_utils.mjs index b0a19e6a..4ce1e7d9 100644 --- a/website/src/user_pattern_utils.mjs +++ b/website/src/user_pattern_utils.mjs @@ -1,5 +1,5 @@ -import { atom } from 'nanostores'; -import { persistentAtom, setPersistentEngine, windowPersistentEvents } from '@nanostores/persistent'; +import {atom, onMount} from 'nanostores'; +import { persistentAtom, windowPersistentEvents } from '@nanostores/persistent'; import { useStore } from '@nanostores/react'; import { logger } from '@strudel/core'; import { nanoid } from 'nanoid'; @@ -21,14 +21,58 @@ export const patternFilterName = { user: 'user', }; +export let sessionAtom = persistentAtom; + if (typeof sessionStorage !== 'undefined') { - // NB: this switches storageEngine of all persistent atoms - // ideally we would switch the engine per atom - // (like in this abandoned pr: https://github.com/nanostores/persistent/pull/30) - setPersistentEngine(sessionStorage, windowPersistentEvents); + const identity = a => a; + const eventsEngine = windowPersistentEvents; + sessionAtom = (name, initial = undefined, opts = {}) => { + let encode = opts.encode || identity + let decode = opts.decode || identity + + let store = atom(initial) + + let set = store.set + store.set = newValue => { + if (typeof newValue === 'undefined') { + delete sessionStorage[name] + } else { + sessionStorage[name] = encode(newValue) + } + set(newValue) + } + + function listener(e) { + if (e.key === name) { + if (e.newValue === null) { + set(undefined) + } else { + set(decode(e.newValue)) + } + } else if (!sessionStorage[name]) { + set(undefined) + } + } + + function restore() { + store.set(sessionStorage[name] ? decode(sessionStorage[name]) : initial) + } + + onMount(store, () => { + restore() + if (opts.listen !== false) { + eventsEngine.addEventListener(name, listener, restore) + return () => { + eventsEngine.removeEventListener(name, listener, restore) + } + } + }) + + return store + } } -export let $viewingPatternData = persistentAtom( +export let $viewingPatternData = sessionAtom( 'viewingPatternData', { id: '', @@ -75,7 +119,7 @@ export async function loadDBPatterns() { } // reason: https://github.com/tidalcycles/strudel/issues/857 -const $activePattern = persistentAtom('activePattern', '', { listen: false }); +const $activePattern = sessionAtom('activePattern', '', { listen: false }); export function setActivePattern(key) { $activePattern.set(key);