From e89d2098041d265131915c4e006a51478ff664bb Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 6 Mar 2024 11:07:42 -0300 Subject: fix #8564 --- packages/web-util/src/hooks/useLocalStorage.ts | 51 ++++++++++++++++---------- packages/web-util/src/index.build.ts | 2 +- packages/web-util/src/utils/observable.ts | 10 ++--- 3 files changed, 37 insertions(+), 26 deletions(-) (limited to 'packages/web-util/src') diff --git a/packages/web-util/src/hooks/useLocalStorage.ts b/packages/web-util/src/hooks/useLocalStorage.ts index b460144a6..7c41f98be 100644 --- a/packages/web-util/src/hooks/useLocalStorage.ts +++ b/packages/web-util/src/hooks/useLocalStorage.ts @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { Codec, codecForString } from "@gnu-taler/taler-util"; +import { AbsoluteTime, Codec, codecForString } from "@gnu-taler/taler-util"; import { useEffect, useState } from "preact/hooks"; import { ObservableMap, @@ -61,12 +61,25 @@ const supportLocalStorage = typeof window !== "undefined"; const supportBrowserStorage = typeof chrome !== "undefined" && typeof chrome.storage !== "undefined"; + /** + * Build setting storage + */ const storage: ObservableMap = (function buildStorage() { if (supportBrowserStorage) { - return browserStorageMap(memoryMap()); + //browser storage is like local storage but + //with app sync. + //Works for almost every browser + if (supportLocalStorage) { + return browserStorageMap(localStorageMap()); + } else { + // service worker doesn't have local storage + return browserStorageMap(memoryMap()); + } } else if (supportLocalStorage) { + // fallback if browser is too old return localStorageMap(); } else { + // new need to save settings somewhere return memoryMap(); } })(); @@ -85,26 +98,14 @@ export function useLocalStorage( key: StorageKey, defaultValue?: Type, ): StorageState { - function convert(updated: string | undefined): Type | undefined { - if (updated === undefined) return defaultValue; //optional - try { - return key.codec.decode(JSON.parse(updated)); - } catch (e) { - //decode error - return defaultValue; - } - } - const [storedValue, setStoredValue] = useState( - (): Type | undefined => { - const prev = storage.get(key.id); - return convert(prev); - }, - ); + const current = convert(storage.get(key.id), key, defaultValue); + + const [_, setStoredValue] = useState(AbsoluteTime.now().t_ms); useEffect(() => { return storage.onUpdate(key.id, () => { - const newValue = storage.get(key.id); - setStoredValue(convert(newValue)); + // const newValue = storage.get(key.id); + setStoredValue(AbsoluteTime.now().t_ms); }); }, [key.id]); @@ -120,10 +121,20 @@ export function useLocalStorage( }; return { - value: storedValue, + value: current, update: setValue, reset: () => { setValue(defaultValue); }, }; } + +function convert(updated: string | undefined, key: StorageKey, defaultValue?: Type): Type | undefined { + if (updated === undefined) return defaultValue; //optional + try { + return key.codec.decode(JSON.parse(updated)); + } catch (e) { + //decode error + return defaultValue; + } +} diff --git a/packages/web-util/src/index.build.ts b/packages/web-util/src/index.build.ts index 4a52d1177..c0c5fc179 100644 --- a/packages/web-util/src/index.build.ts +++ b/packages/web-util/src/index.build.ts @@ -218,7 +218,7 @@ const defaultEsBuildConfig: esbuild.BuildOptions = { ".woff2": "file", ".eot": "file", }, - target: ["es6"], + target: ["es2020"], format: "esm", platform: "browser", jsxFactory: "h", diff --git a/packages/web-util/src/utils/observable.ts b/packages/web-util/src/utils/observable.ts index 01e655eaa..16a33ae72 100644 --- a/packages/web-util/src/utils/observable.ts +++ b/packages/web-util/src/utils/observable.ts @@ -118,6 +118,7 @@ export function localStorageMap(): ObservableMap { const total = localStorage.length; return { next() { + if (index === total) return { done: true, value: undefined }; const key = localStorage.key(index); if (key === null) { //we are going from 0 until last, this should not happen @@ -128,7 +129,6 @@ export function localStorageMap(): ObservableMap { //the key exist, this should not happen throw Error("value cant be null"); } - if (index == total) return { done: true, value: [key, item] }; index = index + 1; return { done: false, value: [key, item] }; }, @@ -165,12 +165,12 @@ export function localStorageMap(): ObservableMap { const total = localStorage.length; return { next() { + if (index === total) return { done: true, value: undefined }; const key = localStorage.key(index); if (key === null) { //we are going from 0 until last, this should not happen throw Error("key cant be null"); } - if (index == total) return { done: true, value: key }; index = index + 1; return { done: false, value: key }; }, @@ -185,6 +185,7 @@ export function localStorageMap(): ObservableMap { const total = localStorage.length; return { next() { + if (index === total) return { done: true, value: undefined }; const key = localStorage.key(index); if (key === null) { //we are going from 0 until last, this should not happen @@ -195,7 +196,6 @@ export function localStorageMap(): ObservableMap { //the key exist, this should not happen throw Error("value cant be null"); } - if (index == total) return { done: true, value: item }; index = index + 1; return { done: false, value: item }; }, @@ -247,11 +247,11 @@ function onBrowserStorageUpdate(cb: (changes: Changes) => void): void { export function browserStorageMap( backend: ObservableMap, ): ObservableMap { - getAllContent().then((content) => { + getAllContent().then(content => { Object.entries(content ?? {}).forEach(([k, v]) => { backend.set(k, v as string); }); - }); + }) backend.onAnyUpdate(async () => { const result: Record = {}; -- cgit v1.2.3