UNPKG

mobx-persist-store

Version:
174 lines (173 loc) 8.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PersistStore = void 0; const mobx_1 = require("mobx"); const PersistStoreMap_1 = require("./PersistStoreMap"); const StorageAdapter_1 = require("./StorageAdapter"); const configurePersistable_1 = require("./configurePersistable"); const serializableProperty_1 = require("./serializableProperty"); const utils_1 = require("./utils"); class PersistStore { constructor(target, options, reactionOptions = {}) { var _a, _b, _c, _d, _e, _f, _g, _h; this.cancelWatch = null; this.properties = []; this.reactionOptions = {}; this.storageAdapter = null; this.target = null; this.version = undefined; this.debugMode = false; this.isHydrated = false; this.isPersisting = false; this.storageName = ''; this.target = target; this.storageName = options.name; this.version = (_a = options.version) !== null && _a !== void 0 ? _a : configurePersistable_1.mpsConfig.version; this.properties = (0, serializableProperty_1.makeSerializableProperties)(options.properties); this.reactionOptions = Object.assign({ fireImmediately: true }, configurePersistable_1.mpsReactionOptions, reactionOptions); this.debugMode = (_c = (_b = options.debugMode) !== null && _b !== void 0 ? _b : configurePersistable_1.mpsConfig.debugMode) !== null && _c !== void 0 ? _c : false; this.storageAdapter = new StorageAdapter_1.StorageAdapter({ version: this.version, expireIn: (_d = options.expireIn) !== null && _d !== void 0 ? _d : configurePersistable_1.mpsConfig.expireIn, removeOnExpiration: (_f = (_e = options.removeOnExpiration) !== null && _e !== void 0 ? _e : configurePersistable_1.mpsConfig.removeOnExpiration) !== null && _f !== void 0 ? _f : true, stringify: (_h = (_g = options.stringify) !== null && _g !== void 0 ? _g : configurePersistable_1.mpsConfig.stringify) !== null && _h !== void 0 ? _h : true, storage: options.storage ? options.storage : configurePersistable_1.mpsConfig.storage, debugMode: this.debugMode, }); (0, mobx_1.makeObservable)(this, { clearPersistedStore: mobx_1.action, hydrateStore: mobx_1.action, isHydrated: mobx_1.observable, isPersisting: mobx_1.observable, pausePersisting: mobx_1.action, startPersisting: mobx_1.action, stopPersisting: mobx_1.action, }, { autoBind: true, deep: false }); (0, utils_1.invalidStorageAdaptorWarningIf)(this.storageAdapter.options.storage, this.storageName); (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - (makePersistable)`, { properties: this.properties, storageAdapter: this.storageAdapter, reactionOptions: this.reactionOptions, }); } async init() { await this.hydrateStore(); this.startPersisting(); return this; } async hydrateStore() { // If the user calls stopPersist and then rehydrateStore we don't want to automatically call startPersist below const isBeingWatched = Boolean(this.cancelWatch); if (this.isPersisting) { this.pausePersisting(); } (0, mobx_1.runInAction)(() => { this.isHydrated = false; (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - (hydrateStore) isHydrated:`, this.isHydrated); }); if (this.storageAdapter && this.target) { const data = await this.storageAdapter.getItem(this.storageName); // Reassigning so TypeScript doesn't complain (Object is possibly 'null') about this.target within forEach const target = this.target; if (data) { (0, mobx_1.runInAction)(() => { this.properties.forEach((property) => { const allowPropertyHydration = [ property.key in target, typeof data[property.key] !== 'undefined', ].every(Boolean); if (allowPropertyHydration) { const propertyData = data[property.key]; if (target[property.key] instanceof mobx_1.ObservableMap && (0, utils_1.isArrayForMap)(propertyData)) { target[property.key] = property.deserialize(new Map(propertyData)); } else if (target[property.key] instanceof mobx_1.ObservableSet && (0, utils_1.isArrayForSet)(propertyData)) { target[property.key] = property.deserialize(new Set(propertyData)); } else { target[property.key] = property.deserialize(propertyData); } } }); }); } } (0, mobx_1.runInAction)(() => { this.isHydrated = true; (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - isHydrated:`, this.isHydrated); }); if (isBeingWatched) { this.startPersisting(); } } startPersisting() { if (!this.storageAdapter || !this.target || this.cancelWatch) { return; } // Reassigning so TypeScript doesn't complain (Object is possibly 'null') about and this.target within reaction const target = this.target; this.cancelWatch = (0, mobx_1.reaction)(() => { const propertiesToWatch = {}; this.properties.forEach((property) => { const isComputedProperty = (0, mobx_1.isComputedProp)(target, property.key); const isActionProperty = (0, mobx_1.isAction)(target[property.key]); (0, utils_1.computedPersistWarningIf)(isComputedProperty, String(property.key)); (0, utils_1.actionPersistWarningIf)(isActionProperty, String(property.key)); if (!isComputedProperty && !isActionProperty) { let propertyData = property.serialize(target[property.key]); if (propertyData instanceof mobx_1.ObservableMap) { const mapArray = []; propertyData.forEach((v, k) => { mapArray.push([k, (0, mobx_1.toJS)(v)]); }); propertyData = mapArray; } else if (propertyData instanceof mobx_1.ObservableSet) { propertyData = Array.from(propertyData).map(mobx_1.toJS); } propertiesToWatch[property.key] = (0, mobx_1.toJS)(propertyData); } }); return propertiesToWatch; }, async (dataToSave) => { if (this.storageAdapter) { await this.storageAdapter.setItem(this.storageName, dataToSave); } }, this.reactionOptions); this.isPersisting = true; (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - (startPersisting) isPersisting:`, this.isPersisting); } pausePersisting() { this.isPersisting = false; (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - pausePersisting (isPersisting):`, this.isPersisting); if (this.cancelWatch) { this.cancelWatch(); this.cancelWatch = null; } } stopPersisting() { this.pausePersisting(); (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - (stopPersisting)`); PersistStoreMap_1.PersistStoreMap.delete(this.target); this.cancelWatch = null; this.properties = []; this.reactionOptions = {}; this.storageAdapter = null; this.target = null; } async clearPersistedStore() { if (this.storageAdapter) { (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - (clearPersistedStore)`); await this.storageAdapter.removeItem(this.storageName); } } async getPersistedStore() { if (this.storageAdapter) { (0, utils_1.consoleDebug)(this.debugMode, `${this.storageName} - (getPersistedStore)`); // @ts-ignore return this.storageAdapter.getItem(this.storageName); } return null; } } exports.PersistStore = PersistStore;