@huds0n/shared-state-store-rn
Version:
Share States React Native store creator
130 lines (129 loc) • 5.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SharedStateStore = void 0;
const tslib_1 = require("tslib");
const error_1 = tslib_1.__importDefault(require("@huds0n/error"));
const async_storage_1 = tslib_1.__importDefault(require("@react-native-async-storage/async-storage"));
const crypto_es_1 = tslib_1.__importDefault(require("crypto-es"));
const react_native_1 = require("react-native");
class SharedStateStore {
constructor(sharedState, options) {
const { load = true, saveAutomatically, saveOnBackground } = options;
this._options = options;
this._sharedState = sharedState;
if (saveAutomatically) {
const trigger = options.excludeKeys
? Object.keys(sharedState).filter((k) => options.excludeKeys.includes(k))
: options.includeKeys;
sharedState.addListener(() => {
this.save();
}, trigger);
}
if (saveOnBackground) {
react_native_1.AppState.addEventListener('change', (nextAppState) => {
if (nextAppState === 'background') {
this.save();
}
});
}
if (load) {
this.load();
}
this.delete = this.delete.bind(this);
this.load = this.load.bind(this);
this.save = this.save.bind(this);
}
get name() {
return this._options.storeName;
}
get sharedState() {
return this._sharedState;
}
save(state = this._sharedState.state) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { encryptionKey, excludeKeys, includeKeys, replacer, storeName } = this._options;
try {
let saveState = state;
if (includeKeys || excludeKeys) {
const saveEntries = Object.entries(saveState).filter(([key]) => includeKeys
? includeKeys.includes(key)
: !(excludeKeys === null || excludeKeys === void 0 ? void 0 : excludeKeys.includes(key)));
if (!saveEntries.length) {
return false;
}
saveState = Object.fromEntries(saveEntries);
}
let stateString = JSON.stringify(saveState, replacer);
if (encryptionKey) {
stateString = crypto_es_1.default.AES.encrypt(stateString, encryptionKey).toString();
}
yield async_storage_1.default.setItem(storeName, stateString);
return true;
}
catch (error) {
error_1.default.create({
name: 'State Error',
code: 'STORAGE_SAVE_ERROR',
message: 'Unable to save state',
info: { storeName },
severity: 'ERROR',
from: error,
});
return false;
}
});
}
load() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { encryptionKey, excludeKeys, includeKeys, reviver, storeName } = this._options;
try {
let stateString = (yield async_storage_1.default.getItem(storeName));
if (!stateString) {
yield this.save();
return undefined;
}
if (encryptionKey && stateString) {
stateString = crypto_es_1.default.AES.decrypt(stateString, encryptionKey).toString();
}
let retrievedState = JSON.parse(stateString, reviver);
if (includeKeys) {
retrievedState = Object.assign(Object.assign({}, this._sharedState.state), retrievedState);
}
else if (excludeKeys) {
const currentState = this._sharedState.state;
excludeKeys.forEach((key) => (retrievedState[key] = currentState[key]));
}
this._sharedState.setState(retrievedState);
return retrievedState;
}
catch (error) {
throw error_1.default.create({
name: 'State Error',
code: 'STORAGE_ERROR',
message: 'Error loading from storage',
severity: 'ERROR',
from: error,
});
}
});
}
delete() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { storeName } = this._options;
try {
yield async_storage_1.default.removeItem(storeName);
}
catch (error) {
throw error_1.default.create({
name: 'State Error',
code: 'STORAGE_DELETE_ERROR',
message: 'Unable to delete state',
info: { storeName },
severity: 'ERROR',
from: error,
});
}
});
}
}
exports.SharedStateStore = SharedStateStore;