@ima/core
Version:
IMA.js framework for isomorphic javascript application
126 lines (125 loc) • 3.78 kB
JavaScript
import { PageStateManager } from './PageStateManager';
import { StateEvents } from './StateEvents';
import { Dispatcher } from '../../event/Dispatcher';
const MAX_HISTORY_LIMIT = 10;
/**
* The implementation of the {@link PageStateManager} interface.
*/ export class PageStateManagerImpl extends PageStateManager {
_cursor = -1;
_dispatcher;
_ongoingTransaction = false;
_statePatchQueue = [];
_states = [];
static get $dependencies() {
return [
Dispatcher
];
}
/**
* Initializes the page state manager.
*
* @param {Dispatcher} dispatcher Dispatcher fires events to app.
*/ constructor(dispatcher){
super();
this._dispatcher = dispatcher;
}
/**
* @inheritDoc
*/ clear() {
this._states = [];
this._cursor = -1;
this.cancelTransaction();
}
/**
* @inheritDoc
*/ setState(patchState) {
if (this._ongoingTransaction) {
return this._statePatchQueue.push(patchState);
}
const oldState = this.getState();
const newState = Object.assign({}, this.getState(), patchState);
if (this._dispatcher) {
this._dispatcher.fire(StateEvents.BEFORE_CHANGE_STATE, {
newState,
oldState,
patchState
});
}
this._eraseExcessHistory();
this._pushToHistory(newState);
this._callOnChangeCallback(newState);
}
/**
* @inheritDoc
*/ getState() {
return this._states[this._cursor] || {};
}
/**
* @inheritDoc
*/ getAllStates() {
return this._states;
}
/**
* @inheritDoc
*/ getTransactionStatePatches() {
return this._statePatchQueue;
}
/**
* @inheritDoc
*/ beginTransaction() {
if ($Debug && this._ongoingTransaction) {
console.warn('ima.core.page.state.PageStateManagerImpl.beginTransaction():' + 'Another state transaction is already in progress. Check you workflow.' + 'These uncommitted state changes will be lost:', this._statePatchQueue);
}
this._ongoingTransaction = true;
this._statePatchQueue = [];
}
/**
* @inheritDoc
*/ commitTransaction() {
if ($Debug && !this._ongoingTransaction) {
console.warn('ima.core.page.state.PageStateManagerImpl.commitTransaction():' + 'No transaction is in progress. Check you workflow.');
}
if (this._statePatchQueue.length === 0) {
this._ongoingTransaction = false;
return;
}
const finalPatch = Object.assign({}, ...this._statePatchQueue);
this._ongoingTransaction = false;
this._statePatchQueue = [];
this.setState(finalPatch);
}
/**
* @inheritDoc
*/ cancelTransaction() {
this._ongoingTransaction = false;
this._statePatchQueue = [];
}
/**
* Erase the oldest state from storage only if it exceed max
* defined size of history.
*/ _eraseExcessHistory() {
if (this._states.length > MAX_HISTORY_LIMIT) {
this._states.shift();
this._cursor -= 1;
}
}
/**
* Push new state to history storage.
*/ _pushToHistory(newState) {
this._states.push(newState);
this._cursor += 1;
}
/**
* Call registered callback function on (@link onChange) with newState.
*/ _callOnChangeCallback(newState) {
if (this.onChange && typeof this.onChange === 'function') {
this.onChange(newState);
}
if (this._dispatcher) {
this._dispatcher.fire(StateEvents.AFTER_CHANGE_STATE, {
newState
});
}
}
}
//# sourceMappingURL=PageStateManagerImpl.js.map