kex
Version:
Kex is a tiny library for state managenent in JavaScript projects
169 lines • 6.28 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const is_object_1 = require("../utils/is-object");
const apply_modifiers_1 = require("./apply-modifiers");
const resolve_modifier_1 = require("./resolve-modifier");
class KxStore {
constructor() {
this._reducers = [];
this._listeners = [];
this._state = {
cache: {},
actions: []
};
this._historyMaxSize = 10;
this._history = [];
}
_broadcastChange(change) {
this._history = [change, ...this._history];
while (this._history.length > this._historyMaxSize) {
this._history.pop();
}
for (let listener of this._listeners) {
listener(this._state, change);
}
}
history() {
return this._history;
}
getState() {
return this._state;
}
getCache(key, token) {
if (typeof key !== 'string') {
throw new Error('cache key should be string');
}
if (!is_object_1.isObject(this._state.cache)) {
return null;
}
const cache = this._state.cache[key];
if (cache === undefined) {
return null;
}
if (cache.token === token) {
return cache.value;
}
return null;
}
setCache(key, value, token) {
if (typeof key !== 'string') {
throw new Error('cache key should be string');
}
return this.update({ cache: { [key]: { token, value } } });
}
update(resolvedModifier) {
this._state = apply_modifiers_1.applyModifiers(this._state, resolvedModifier);
this._broadcastChange({
action: null,
changes: resolvedModifier
});
return this._state;
}
clear() {
const clearModifier = Object.create(null);
for (let key in this._state) {
if (!Object.prototype.hasOwnProperty.call(this._state, key)) {
continue;
}
if (key === 'actions') {
clearModifier[key] = [];
continue;
}
if (key === 'cache') {
for (let cacheKey in this._state.cache) {
if (!Object.prototype.hasOwnProperty.call(this._state.cache, cacheKey)) {
continue;
}
if (!is_object_1.isObject(clearModifier[key])) {
clearModifier[key] = {};
}
clearModifier[key][cacheKey] = undefined;
}
continue;
}
clearModifier[key] = undefined;
}
return this.update(clearModifier);
}
clearCache() {
const clearModifier = Object.create(null);
if (!is_object_1.isObject(this._state.cache)) {
clearModifier.cache = undefined;
}
else {
for (let cacheKey in this._state.cache) {
if (!Object.prototype.hasOwnProperty.call(this._state.cache, cacheKey)) {
continue;
}
if (!is_object_1.isObject(clearModifier.cache)) {
clearModifier.cache = {};
}
clearModifier.cache[cacheKey] = undefined;
}
}
return this.update(clearModifier);
}
replaceReducers(...nextReducers) {
for (let reducer of nextReducers) {
if (typeof reducer !== 'function') {
throw new Error('reducer should be a function');
}
}
this._reducers = nextReducers;
return this;
}
addStorageListener(listener) {
if (typeof listener !== 'function') {
throw new Error('storage listener should be a function');
}
this._listeners.push(listener);
return this;
}
removeStorageListener(listener) {
this._listeners = this._listeners.filter(l => l !== listener);
return this;
}
dispatch(action) {
return __awaiter(this, void 0, void 0, function* () {
if (!is_object_1.isObject(action)) {
throw new Error('action should be an object');
}
if (typeof action.type !== 'string') {
throw new Error('action type should be a string');
}
let changes = Object.create(null);
for (let reducer of this._reducers) {
const resolvedModifiers = yield resolve_modifier_1.resolveModifier(reducer(action));
this._state = apply_modifiers_1.applyModifiers(this._state, ...resolvedModifiers);
changes = apply_modifiers_1.applyModifiers(changes, ...resolvedModifiers);
}
if (!Array.isArray(this._state.actions)) {
throw new Error('field actions in state should be an array');
}
if (this._state.actions.length > 0) {
const nextAction = this._state.actions[0];
this._state.actions = this._state.actions.filter(action => action !== nextAction);
this._broadcastChange({ action: action.type, changes });
return yield this.dispatch(nextAction);
}
this._broadcastChange({ action: action.type, changes });
return this._state;
});
}
setHistoryMaxSize(size) {
if (typeof size !== 'number' || isNaN(size)) {
throw new Error('history size should be a number');
}
this._historyMaxSize = size;
}
}
exports.KxStore = KxStore;
//# sourceMappingURL=storage.js.map