UNPKG

@datorama/akita

Version:

State Management Tailored-Made for JS Applications

266 lines 19.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { pairwise } from 'rxjs/operators'; import { AkitaPlugin } from '../plugin'; import { logAction } from '../../actions'; import { isFunction } from '../../isFunction'; /** * @record */ export function StateHistoryParams() { } if (false) { /** @type {?|undefined} */ StateHistoryParams.prototype.maxAge; /** @type {?|undefined} */ StateHistoryParams.prototype.comparator; } /** * @template State */ export class StateHistoryPlugin extends AkitaPlugin { /** * @param {?} query * @param {?=} params * @param {?=} _entityId */ constructor(query, params = {}, _entityId) { super(query, { resetFn: (/** * @return {?} */ () => this.clear()) }); this.query = query; this.params = params; this._entityId = _entityId; /** * Allow skipping an update from outside */ this.skip = false; this.history = { past: [], present: null, future: [] }; /** * Skip the update when redo/undo */ this.skipUpdate = false; params.maxAge = !!params.maxAge ? params.maxAge : 10; params.comparator = params.comparator || ((/** * @return {?} */ () => true)); this.activate(); } /** * @return {?} */ get hasPast() { return this.history.past.length > 0; } /** * @return {?} */ get hasFuture() { return this.history.future.length > 0; } /** * @return {?} */ activate() { this.history.present = this.getSource(this._entityId); this.subscription = ((/** @type {?} */ (this))).selectSource(this._entityId).pipe(pairwise()) .subscribe((/** * @param {?} __0 * @return {?} */ ([past, present]) => { if (this.skip) { this.skip = false; return; } /** * comparator: (prev, current) => isEqual(prev, current) === false * @type {?} */ const shouldUpdate = this.params.comparator(past, present); if (!this.skipUpdate && shouldUpdate) { if (this.history.past.length === this.params.maxAge) { this.history.past = this.history.past.slice(1); } this.history.past = [...this.history.past, past]; this.history.present = present; } })); } /** * @return {?} */ undo() { if (this.history.past.length > 0) { const { past, present } = this.history; /** @type {?} */ const previous = past[past.length - 1]; this.history.past = past.slice(0, past.length - 1); this.history.present = previous; this.history.future = [present, ...this.history.future]; this.update(); } } /** * @return {?} */ redo() { if (this.history.future.length > 0) { const { past, present } = this.history; /** @type {?} */ const next = this.history.future[0]; /** @type {?} */ const newFuture = this.history.future.slice(1); this.history.past = [...past, present]; this.history.present = next; this.history.future = newFuture; this.update('Redo'); } } /** * @param {?} index * @return {?} */ jumpToPast(index) { if (index < 0 || index >= this.history.past.length) return; const { past, future } = this.history; /** * * const past = [1, 2, 3, 4, 5]; * * newPast = past.slice(0, 2) = [1, 2]; * present = past[index] = 3; * [...past.slice(2 + 1), ...future] = [4, 5]; * * @type {?} */ const newPast = past.slice(0, index); /** @type {?} */ const newFuture = [...past.slice(index + 1), ...future]; /** @type {?} */ const newPresent = past[index]; this.history.past = newPast; this.history.present = newPresent; this.history.future = newFuture; this.update(); } /** * @param {?} index * @return {?} */ jumpToFuture(index) { if (index < 0 || index >= this.history.future.length) return; const { past, future } = this.history; /** @type {?} */ const newPast = [...past, ...future.slice(0, index)]; /** @type {?} */ const newPresent = future[index]; /** @type {?} */ const newFuture = future.slice(index + 1); this.history.past = newPast; this.history.present = newPresent; this.history.future = newFuture; this.update('Redo'); } /** * Clear the history * * \@example * * stateHistory.clear((history) => { * return { * past: history.past, * present: history.present, * future: [] * }; * }); * @param {?=} customUpdateFn Callback function for only clearing part of the history * * @return {?} */ clear(customUpdateFn) { this.history = isFunction(customUpdateFn) ? customUpdateFn(this.history) : { past: [], present: null, future: [] }; } /** * @param {?=} clearHistory * @return {?} */ destroy(clearHistory = false) { if (clearHistory) { this.clear(); } this.subscription.unsubscribe(); } /** * @return {?} */ ignoreNext() { this.skip = true; } /** * @private * @param {?=} action * @return {?} */ update(action = 'Undo') { this.skipUpdate = true; logAction(`@StateHistory - ${action}`); this.updateStore(this.history.present, this._entityId); this.skipUpdate = false; } } if (false) { /** * Allow skipping an update from outside * @type {?} * @private */ StateHistoryPlugin.prototype.skip; /** * @type {?} * @private */ StateHistoryPlugin.prototype.history; /** * Skip the update when redo/undo * @type {?} * @private */ StateHistoryPlugin.prototype.skipUpdate; /** * @type {?} * @private */ StateHistoryPlugin.prototype.subscription; /** * @type {?} * @protected */ StateHistoryPlugin.prototype.query; /** * @type {?} * @private */ StateHistoryPlugin.prototype.params; /** * @type {?} * @private */ StateHistoryPlugin.prototype._entityId; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGVIaXN0b3J5UGx1Z2luLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGRhdG9yYW1hL2FraXRhLyIsInNvdXJjZXMiOlsic3JjL3BsdWdpbnMvc3RhdGVIaXN0b3J5L3N0YXRlSGlzdG9yeVBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxXQUFXLEVBQVcsTUFBTSxXQUFXLENBQUM7QUFDakQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7Ozs7QUFFOUMsd0NBR0M7OztJQUZDLG9DQUFnQjs7SUFDaEIsd0NBQWtEOzs7OztBQVNwRCxNQUFNLE9BQU8sa0JBQWdDLFNBQVEsV0FBa0I7Ozs7OztJQWNyRSxZQUFzQixLQUFxQixFQUFVLFNBQTZCLEVBQUUsRUFBVSxTQUFlO1FBQzNHLEtBQUssQ0FBQyxLQUFLLEVBQUU7WUFDWCxPQUFPOzs7WUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUE7U0FDNUIsQ0FBQyxDQUFDO1FBSGlCLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBeUI7UUFBVSxjQUFTLEdBQVQsU0FBUyxDQUFNOzs7O1FBWnJHLFNBQUksR0FBRyxLQUFLLENBQUM7UUFFYixZQUFPLEdBQUc7WUFDaEIsSUFBSSxFQUFFLEVBQUU7WUFDUixPQUFPLEVBQUUsSUFBSTtZQUNiLE1BQU0sRUFBRSxFQUFFO1NBQ1gsQ0FBQzs7OztRQUdNLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFPekIsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3JELE1B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LEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLFNBQVMsQ0FBQyxtQkFBbUIsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztJQUMxQixDQUFDO0NBQ0Y7Ozs7Ozs7SUF4SkMsa0NBQXFCOzs7OztJQUVyQixxQ0FJRTs7Ozs7O0lBR0Ysd0NBQTJCOzs7OztJQUMzQiwwQ0FBcUI7Ozs7O0lBRVQsbUNBQStCOzs7OztJQUFFLG9DQUF1Qzs7Ozs7SUFBRSx1Q0FBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwYWlyd2lzZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEFraXRhUGx1Z2luLCBRdWVyaWVzIH0gZnJvbSAnLi4vcGx1Z2luJztcbmltcG9ydCB7IGxvZ0FjdGlvbiB9IGZyb20gJy4uLy4uL2FjdGlvbnMnO1xuaW1wb3J0IHsgaXNGdW5jdGlvbiB9IGZyb20gJy4uLy4uL2lzRnVuY3Rpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlSGlzdG9yeVBhcmFtcyB7XG4gIG1heEFnZT86IG51bWJlcjtcbiAgY29tcGFyYXRvcj86IChwcmV2U3RhdGUsIGN1cnJlbnRTdGF0ZSkgPT4gYm9vbGVhbjtcbn1cblxuZXhwb3J0IHR5cGUgSGlzdG9yeTxTdGF0ZT4gPSB7XG4gIHBhc3Q6IFN0YXRlW10sXG4gIHByZXNlbnQ6IFN0YXRlIHwgbnVsbCxcbiAgZnV0dXJlOiBTdGF0ZVtdXG59XG5cbmV4cG9ydCBjbGFzcyBTdGF0ZUhpc3RvcnlQbHVnaW48U3RhdGUgPSBhbnk+IGV4dGVuZHMgQWtpdGFQbHVnaW48U3RhdGU+IHtcbiAgLyoqIEFsbG93IHNraXBwaW5nIGFuIHVwZGF0ZSBmcm9tIG91dHNpZGUgKi9cbiAgcHJpdmF0ZSBza2lwID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBoaXN0b3J5ID0ge1xuICAgIHBhc3Q6IFtdLFxuICAgIHByZXNlbnQ6IG51bGwsXG4gICAgZnV0dXJlOiBbXVxuICB9O1xuXG4gIC8qKiBTa2lwIHRoZSB1cGRhdGUgd2hlbiByZWRvL3VuZG8gKi9cbiAgcHJpdmF0ZSBza2lwVXBkYXRlID0gZmFsc2U7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBxdWVyeTogUXVlcmllczxTdGF0ZT4sIHByaXZhdGUgcGFyYW1zOiBTdGF0ZUhpc3RvcnlQYXJhbXMgPSB7fSwgcHJpdmF0ZSBfZW50aXR5SWQ/OiBhbnkpIHtcbiAgICBzdXBlcihxdWVyeSwge1xuICAgICAgcmVzZXRGbjogKCkgPT4gdGhpcy5jbGVhcigpXG4gICAgfSk7XG4gICAgcGFyYW1zLm1heEFnZSA9ICEhcGFyYW1zLm1heEFnZSA/IHBhcmFtcy5tYXhBZ2UgOiAxMDtcbiAgICBwYXJhbXMuY29tcGFyYXRvciA9IHBhcmFtcy5jb21wYXJhdG9yIHx8ICgoKSA9PiB0cnVlKTtcbiAgICB0aGlzLmFjdGl2YXRlKCk7XG4gIH1cblxuICBnZXQgaGFzUGFzdCgpIHtcbiAgICByZXR1cm4gdGhpcy5oaXN0b3J5LnBhc3QubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGdldCBoYXNGdXR1cmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGlzdG9yeS5mdXR1cmUubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGFjdGl2YXRlKCkge1xuICAgIHRoaXMuaGlzdG9yeS5wcmVzZW50ID0gdGhpcy5nZXRTb3VyY2UodGhpcy5fZW50aXR5SWQpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gKHRoaXMgYXMgYW55KS5zZWxlY3RTb3VyY2UodGhpcy5fZW50aXR5SWQpLnBpcGUocGFpcndpc2UoKSlcbiAgICAgIC5zdWJzY3JpYmUoKFtwYXN0LCBwcmVzZW50XSkgPT4ge1xuICAgICAgICBpZih0aGlzLnNraXApIHtcbiAgICAgICAgICB0aGlzLnNraXAgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqICBjb21wYXJhdG9yOiAocHJldiwgY3VycmVudCkgPT4gaXNFcXVhbChwcmV2LCBjdXJyZW50KSA9PT0gZmFsc2VcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IHNob3VsZFVwZGF0ZSA9IHRoaXMucGFyYW1zLmNvbXBhcmF0b3IocGFzdCwgcHJlc2VudCk7XG5cbiAgICAgICAgaWYoIXRoaXMuc2tpcFVwZGF0ZSAmJiBzaG91bGRVcGRhdGUpIHtcbiAgICAgICAgICBpZih0aGlzLmhpc3RvcnkucGFzdC5sZW5ndGggPT09IHRoaXMucGFyYW1zLm1heEFnZSkge1xuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnBhc3QgPSB0aGlzLmhpc3RvcnkucGFzdC5zbGljZSgxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnBhc3QgPSBbLi4udGhpcy5oaXN0b3J5LnBhc3QsIHBhc3RdO1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5wcmVzZW50ID0gcHJlc2VudDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICB1bmRvKCkge1xuICAgIGlmKHRoaXMuaGlzdG9yeS5wYXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHsgcGFzdCwgcHJlc2VudCB9ID0gdGhpcy5oaXN0b3J5O1xuICAgICAgY29uc3QgcHJldmlvdXMgPSBwYXN0W3Bhc3QubGVuZ3RoIC0gMV07XG4gICAgICB0aGlzLmhpc3RvcnkucGFzdCA9IHBhc3Quc2xpY2UoMCwgcGFzdC5sZW5ndGggLSAxKTtcbiAgICAgIHRoaXMuaGlzdG9yeS5wcmVzZW50ID0gcHJldmlvdXM7XG4gICAgICB0aGlzLmhpc3RvcnkuZnV0dXJlID0gW3ByZXNlbnQsIC4uLnRoaXMuaGlzdG9yeS5mdXR1cmVdO1xuICAgICAgdGhpcy51cGRhdGUoKTtcbiAgICB9XG4gIH1cblxuICByZWRvKCkge1xuICAgIGlmKHRoaXMuaGlzdG9yeS5mdXR1cmUubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgeyBwYXN0LCBwcmVzZW50IH0gPSB0aGlzLmhpc3Rvcnk7XG4gICAgICBjb25zdCBuZXh0ID0gdGhpcy5oaXN0b3J5LmZ1dHVyZVswXTtcbiAgICAgIGNvbnN0IG5ld0Z1dHVyZSA9IHRoaXMuaGlzdG9yeS5mdXR1cmUuc2xpY2UoMSk7XG4gICAgICB0aGlzLmhpc3RvcnkucGFzdCA9IFsuLi5wYXN0LCBwcmVzZW50XTtcbiAgICAgIHRoaXMuaGlzdG9yeS5wcmVzZW50ID0gbmV4dDtcbiAgICAgIHRoaXMuaGlzdG9yeS5mdXR1cmUgPSBuZXdGdXR1cmU7XG4gICAgICB0aGlzLnVwZGF0ZSgnUmVkbycpO1xuICAgIH1cbiAgfVxuXG4gIGp1bXBUb1Bhc3QoaW5kZXg6IG51bWJlcikge1xuICAgIGlmKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLmhpc3RvcnkucGFzdC5sZW5ndGgpIHJldHVybjtcblxuICAgIGNvbnN0IHsgcGFzdCwgZnV0dXJlIH0gPSB0aGlzLmhpc3Rvcnk7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBjb25zdCBwYXN0ID0gWzEsIDIsIDMsIDQsIDVdO1xuICAgICAqXG4gICAgICogbmV3UGFzdCA9IHBhc3Quc2xpY2UoMCwgMikgPSBbMSwgMl07XG4gICAgICogcHJlc2VudCA9IHBhc3RbaW5kZXhdID0gMztcbiAgICAgKiBbLi4ucGFzdC5zbGljZSgyICsgMSksIC4uLmZ1dHVyZV0gPSBbNCwgNV07XG4gICAgICpcbiAgICAgKi9cbiAgICBjb25zdCBuZXdQYXN0ID0gcGFzdC5zbGljZSgwLCBpbmRleCk7XG4gICAgY29uc3QgbmV3RnV0dXJlID0gWy4uLnBhc3Quc2xpY2UoaW5kZXggKyAxKSwgLi4uZnV0dXJlXTtcbiAgICBjb25zdCBuZXdQcmVzZW50ID0gcGFzdFtpbmRleF07XG4gICAgdGhpcy5oaXN0b3J5LnBhc3QgPSBuZXdQYXN0O1xuICAgIHRoaXMuaGlzdG9yeS5wcmVzZW50ID0gbmV3UHJlc2VudDtcbiAgICB0aGlzLmhpc3RvcnkuZnV0dXJlID0gbmV3RnV0dXJlO1xuICAgIHRoaXMudXBkYXRlKCk7XG4gIH1cblxuICBqdW1wVG9GdXR1cmUoaW5kZXg6IG51bWJlcikge1xuICAgIGlmKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLmhpc3RvcnkuZnV0dXJlLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3QgeyBwYXN0LCBmdXR1cmUgfSA9IHRoaXMuaGlzdG9yeTtcblxuICAgIGNvbnN0IG5ld1Bhc3QgPSBbLi4ucGFzdCwgLi4uZnV0dXJlLnNsaWNlKDAsIGluZGV4KV07XG4gICAgY29uc3QgbmV3UHJlc2VudCA9IGZ1dHVyZVtpbmRleF07XG4gICAgY29uc3QgbmV3RnV0dXJlID0gZnV0dXJlLnNsaWNlKGluZGV4ICsgMSk7XG5cbiAgICB0aGlzLmhpc3RvcnkucGFzdCA9IG5ld1Bhc3Q7XG4gICAgdGhpcy5oaXN0b3J5LnByZXNlbnQgPSBuZXdQcmVzZW50O1xuICAgIHRoaXMuaGlzdG9yeS5mdXR1cmUgPSBuZXdGdXR1cmU7XG4gICAgdGhpcy51cGRhdGUoJ1JlZG8nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciB0aGUgaGlzdG9yeVxuICAgKlxuICAgKiBAcGFyYW0gY3VzdG9tVXBkYXRlRm4gQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIG9ubHkgY2xlYXJpbmcgcGFydCBvZiB0aGUgaGlzdG9yeVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBzdGF0ZUhpc3RvcnkuY2xlYXIoKGhpc3RvcnkpID0+IHtcbiAgICogIHJldHVybiB7XG4gICAqICAgIHBhc3Q6IGhpc3RvcnkucGFzdCxcbiAgICogICAgcHJlc2VudDogaGlzdG9yeS5wcmVzZW50LFxuICAgKiAgICBmdXR1cmU6IFtdXG4gICAqICB9O1xuICAgKiB9KTtcbiAgICovXG4gIGNsZWFyKGN1c3RvbVVwZGF0ZUZuPzogKGhpc3Rvcnk6IEhpc3Rvcnk8U3RhdGU+KSA9PiBIaXN0b3J5PFN0YXRlPikge1xuICAgIHRoaXMuaGlzdG9yeSA9IGlzRnVuY3Rpb24oY3VzdG9tVXBkYXRlRm4pID8gY3VzdG9tVXBkYXRlRm4odGhpcy5oaXN0b3J5KSA6IHtcbiAgICAgIHBhc3Q6IFtdLFxuICAgICAgcHJlc2VudDogbnVsbCxcbiAgICAgIGZ1dHVyZTogW11cbiAgICB9O1xuICB9XG5cbiAgZGVzdHJveShjbGVhckhpc3RvcnkgPSBmYWxzZSkge1xuICAgIGlmKGNsZWFySGlzdG9yeSkge1xuICAgICAgdGhpcy5jbGVhcigpO1xuICAgIH1cbiAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgaWdub3JlTmV4dCgpIHtcbiAgICB0aGlzLnNraXAgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGUoYWN0aW9uID0gJ1VuZG8nKSB7XG4gICAgdGhpcy5za2lwVXBkYXRlID0gdHJ1ZTtcbiAgICBsb2dBY3Rpb24oYEBTdGF0ZUhpc3RvcnkgLSAke2FjdGlvbn1gKTtcbiAgICB0aGlzLnVwZGF0ZVN0b3JlKHRoaXMuaGlzdG9yeS5wcmVzZW50LCB0aGlzLl9lbnRpdHlJZCk7XG4gICAgdGhpcy5za2lwVXBkYXRlID0gZmFsc2U7XG4gIH1cbn1cbiJdfQ==