From da6ca76304f61ba3c0d26f70a43f2c9addcd8199 Mon Sep 17 00:00:00 2001 From: Henrique Bruno Date: Sat, 26 Dec 2020 04:23:06 -0300 Subject: [PATCH] added reset() --- src/async.ts | 37 +++++++++++++++++++++++++++++++++++++ src/parse-store.ts | 41 ++++++++++++++++++++--------------------- 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/async.ts b/src/async.ts index 6b66731..ddcd953 100644 --- a/src/async.ts +++ b/src/async.ts @@ -48,6 +48,14 @@ export interface AsyncTrunkOptions { * @param error */ onError?: (error: any) => void; + + /** + * If the values of non-ignored properties before the trunk.init() should be + * volatilly saved so they can be later `reset()`ed. + * + * Defaults to `false`. + */ + saveDefaultValues?: boolean; } export class AsyncTrunk { @@ -58,6 +66,9 @@ export class AsyncTrunk { readonly delay: number; readonly onError: (error: any) => void; + readonly saveDefaultValues: boolean; + private defaultValues: any; + constructor( store: any, { @@ -65,6 +76,7 @@ export class AsyncTrunk { storageKey = KeyDefaultKey, delay = 0, onError = noop, + saveDefaultValues = false, }: AsyncTrunkOptions = {}, ) { this.store = store; @@ -72,6 +84,7 @@ export class AsyncTrunk { this.storageKey = storageKey; this.delay = delay; this.onError = onError; + this.saveDefaultValues = saveDefaultValues; } async persist() { @@ -104,8 +117,32 @@ export class AsyncTrunk { delay: this.delay, onError: this.onError, }); + // Save default values + if (this.saveDefaultValues) + parseStore(this.store, initialState, false, this.defaultValues); } + /** + * It will reset the store properties to their default values and also save on storage. + * + * You must have set the `saveDefaultValues` parameter in this trunk constructor. + */ + async reset() { + if (!this.saveDefaultValues) { + this.onError( + "mobx-sync reset() was called but saveDefaultValues parameter wasn't set on the trunk constructor.", + ); + return; + } + + parseStore( + this.store, + JSON.parse(JSON.stringify(this.defaultValues)), + false, + ); + return this.persist(); + } + /** Erases the data from the storage. */ async clear() { return this.storage.removeItem(this.storageKey); } diff --git a/src/parse-store.ts b/src/parse-store.ts index 31f2ebf..0b7c9b1 100644 --- a/src/parse-store.ts +++ b/src/parse-store.ts @@ -12,7 +12,13 @@ import { action, isObservableArray, isObservableMap, observable } from 'mobx'; import { KeyFormat, KeyNodeVersion, KeyVersions } from './keys'; import { isPrimitive } from './utils'; -let parseStore = (store: any, data: any, isFromServer: boolean) => { +/** Target allows saving the current data elsewhere than the store itself */ +let parseStore = ( + store: any, + data: any, + isFromServer: boolean, + target: any = store, +) => { // if store or data is empty, break it if (!store || !data) { return; @@ -21,10 +27,8 @@ let parseStore = (store: any, data: any, isFromServer: boolean) => { const storeVersions = store[KeyVersions] || {}; const deserializers = store[KeyFormat] || {}; // version control for node - if ((KeyNodeVersion in dataVersions) - || (KeyNodeVersion in storeVersions)) { - if (dataVersions[KeyNodeVersion] - !== storeVersions[KeyNodeVersion]) { + if (KeyNodeVersion in dataVersions || KeyNodeVersion in storeVersions) { + if (dataVersions[KeyNodeVersion] !== storeVersions[KeyNodeVersion]) { return; } } @@ -52,27 +56,22 @@ let parseStore = (store: any, data: any, isFromServer: boolean) => { const storeValue = store[key]; const dataValue = data[key]; if (deserializers[key] && deserializers[key].deserializer) { - store[key] = deserializers[key].deserializer(dataValue, storeValue); - } - else if (isObservableArray(storeValue)) { + target[key] = deserializers[key].deserializer(dataValue, storeValue); + } else if (isObservableArray(storeValue)) { // mobx array - store[key] = observable.array(dataValue); - } - else if (isObservableMap(storeValue)) { + target[key] = observable.array(dataValue); + } else if (isObservableMap(storeValue)) { // mobx map - store[key] = observable.map(dataValue); - } - else if (isPrimitive(dataValue)) { + target[key] = observable.map(dataValue); + } else if (isPrimitive(dataValue)) { // js/mobx primitive objects - store[key] = dataValue; - } - else if (!storeValue) { + target[key] = dataValue; + } else if (!storeValue) { // if store value is empty, assign persisted data to it directly - store[key] = dataValue; - } - else { + target[key] = dataValue; + } else { // nested pure js object or mobx observable object - parseStore(storeValue, dataValue, isFromServer); + parseStore(storeValue, dataValue, isFromServer, target[key]); } } }