diff --git a/src/StaticConfiguration.ts b/src/StaticConfiguration.ts index 2ea9d5a78..f8394a427 100644 --- a/src/StaticConfiguration.ts +++ b/src/StaticConfiguration.ts @@ -133,5 +133,7 @@ class StaticConfiguration { }; public static readonly knnNeighbourCount = 3; + + public static readonly localStorageVersion = 2; } export default StaticConfiguration; diff --git a/src/script/ControlledStorage.ts b/src/script/ControlledStorage.ts index d16d7c82b..fa92c8405 100644 --- a/src/script/ControlledStorage.ts +++ b/src/script/ControlledStorage.ts @@ -1,3 +1,5 @@ +import StaticConfiguration from "../StaticConfiguration"; + /** * (c) 2023, Center for Computational Thinking and Design at Aarhus University and contributors * @@ -9,10 +11,19 @@ type StoredValue = { }; class ControlledStorage { + + public static readonly localStorageVersion = 2; + public static get(key: string): T { const storedValue = this.getStoredItem(key); - const parsedValue = this.parseItem(storedValue); - return parsedValue.value; + try { + const parsedValue = this.parseItem(storedValue); + return parsedValue.value; + } catch (error) { + console.log(`An error occurred while parsing the stored value with key ${key}. The stored value will be deleted`, error) + localStorage.removeItem(key); + } + throw new Error(`Could not parse value '${storedValue}'`); } public static set(key: string, value: T): void { @@ -21,7 +32,14 @@ class ControlledStorage { localStorage.setItem(key, stringified); } - public static has(key: string): boolean { + public static hasValid(key: string): boolean { + try { + this.parseItem(this.getStoredItem(key)); + } catch (error) { + console.log(`An error occurred while parsing the stored value with key ${key}. The stored value will be deleted`, error) + localStorage.removeItem(key); + return false; + } return !!localStorage.getItem(key); } @@ -46,12 +64,17 @@ class ControlledStorage { if (!('value' in parsed)) { throw new Error(`Could not parse value '${storedValue}'. It did not contain value`); } + if (parsed.version !== ControlledStorage.localStorageVersion) { + throw new Error( + `Could not parse value '${storedValue}'. Version mismatch. Expected version ${ControlledStorage.localStorageVersion}, found version ${parsed.version}`, + ); + } return parsed; } private static encapsulateItem(value: T): StoredValue { return { - version: 1, // todo move this magic constant + version: ControlledStorage.localStorageVersion, value, }; } diff --git a/src/script/repository/LocalStorageGestureRepository.ts b/src/script/repository/LocalStorageGestureRepository.ts index 48608bae2..b108f75f9 100644 --- a/src/script/repository/LocalStorageGestureRepository.ts +++ b/src/script/repository/LocalStorageGestureRepository.ts @@ -95,7 +95,10 @@ class LocalStorageGestureRepository implements GestureRepository { private getPersistedGestures(): Gesture[] { const resultFromFetch: PersistantGestureData[] = this.getPersistedData(); - return resultFromFetch.map(persistedData => this.buildGesture(persistedData)); + return resultFromFetch.map((persistedData, index) => { + const gesture = this.buildGesture(persistedData); + return gesture; + }); } private buildGesture(persistedData: PersistantGestureData) { @@ -110,11 +113,11 @@ class LocalStorageGestureRepository implements GestureRepository { } private getPersistedData(): PersistantGestureData[] { - const result = localStorage.getItem(this.LOCAL_STORAGE_KEY); - if (!result) { + if (!ControlledStorage.hasValid(this.LOCAL_STORAGE_KEY)) { return []; } - return ControlledStorage.get(this.LOCAL_STORAGE_KEY); + const storedData = ControlledStorage.get(this.LOCAL_STORAGE_KEY) + return storedData; } } diff --git a/src/script/repository/PersistantWritable.ts b/src/script/repository/PersistantWritable.ts index 6b34a8fdb..d21df2326 100644 --- a/src/script/repository/PersistantWritable.ts +++ b/src/script/repository/PersistantWritable.ts @@ -21,7 +21,7 @@ class PersistantWritable implements Writable { initialValue: T, private key: string, ) { - if (ControlledStorage.has(key)) { + if (ControlledStorage.hasValid(key)) { const storedValue = ControlledStorage.get(key); this.store = writable(storedValue); } else {