UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

95 lines (94 loc) 3 kB
import { applySnapshot, getEnv, getSnapshot, onSnapshot, resolvePath, types, } from '@jbrowse/mobx-state-tree'; const MAX_HISTORY_LENGTH = 20; const TimeTraveller = types .model('TimeTraveller', { undoIdx: -1, targetPath: '', }) .volatile(() => ({ history: [], notTrackingUndo: false, })) .views(self => ({ get canUndo() { return self.undoIdx > 0 && !self.notTrackingUndo; }, get canRedo() { return self.undoIdx < self.history.length - 1 && !self.notTrackingUndo; }, })) .actions(self => { let targetStore; let snapshotDisposer; let skipNextUndoState = false; let debounceTimer; let pendingSnapshot; return { stopTrackingUndo() { self.notTrackingUndo = true; }, resumeTrackingUndo() { self.notTrackingUndo = false; }, addUndoState(snapshot) { if (self.notTrackingUndo) { return; } if (skipNextUndoState) { skipNextUndoState = false; return; } self.history.splice(self.undoIdx + 1); self.history.push(snapshot); if (self.history.length > MAX_HISTORY_LENGTH) { self.history.shift(); } self.undoIdx = self.history.length - 1; }, beforeDestroy() { snapshotDisposer(); if (debounceTimer) { clearTimeout(debounceTimer); } }, initialize() { targetStore = self.targetPath ? resolvePath(self, self.targetPath) : getEnv(self).targetStore; if (!targetStore) { throw new Error('Failed to find target store for TimeTraveller. Please provide `targetPath` property, or a `targetStore` in the environment'); } snapshotDisposer = onSnapshot(targetStore, snapshot => { if (self.notTrackingUndo || skipNextUndoState) { return; } pendingSnapshot = snapshot; if (debounceTimer) { clearTimeout(debounceTimer); } debounceTimer = setTimeout(() => { debounceTimer = undefined; this.addUndoState(pendingSnapshot); }, 300); }); if (self.history.length === 0) { this.addUndoState(getSnapshot(targetStore)); } }, undo() { self.undoIdx--; skipNextUndoState = true; if (targetStore) { applySnapshot(targetStore, self.history[self.undoIdx]); } }, redo() { self.undoIdx++; skipNextUndoState = true; if (targetStore) { applySnapshot(targetStore, self.history[self.undoIdx]); } }, }; }); export default TimeTraveller;