UNPKG

resig.js

Version:

Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.

385 lines 31.3 kB
"use strict"; /** * Undo/Redo System * Uses Memento<State> with coalgebraic time-travel patterns */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createArrayCommand = exports.createTextCommand = exports.createCommand = exports.createUndoRedoManager = exports.UndoRedoManager = void 0; const signal_1 = require("../core/signal"); // Coalgebraic time-travel manager class UndoRedoManager { constructor(initialState, config = {}) { this.config = config; this.lastCommand = null; this.mergeTimer = null; this.history = (0, signal_1.signal)([this.createMemento(initialState, 'initial')]); this.future = (0, signal_1.signal)([]); this.currentIndex = (0, signal_1.signal)(0); this.currentState = (0, signal_1.signal)(initialState); this.commands = (0, signal_1.signal)([]); this.setupAutoMerge(); this.loadPersistedHistory(); } // Create memento snapshot (coalgebraic unfold) createMemento(state, id, metadata) { return { state: this.deepClone(state), timestamp: Date.now(), id, metadata, }; } // Deep clone state for immutability deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Date) return new Date(obj.getTime()); if (obj instanceof Array) return obj.map((item) => this.deepClone(item)); if (typeof obj === 'object') { const cloned = {}; Object.keys(obj).forEach((key) => { cloned[key] = this.deepClone(obj[key]); }); return cloned; } return obj; } // Setup automatic command merging setupAutoMerge() { if (!this.config.autoMerge) return; const mergeTimeout = this.config.mergeTimeout || 1000; this.commands.subscribe((commands) => { if (commands.length === 0) return; // const _lastCommand = commands[commands.length - 1]; // Unused for now if (this.mergeTimer) { clearTimeout(this.mergeTimer); } this.mergeTimer = window.setTimeout(() => { this.lastCommand = null; }, mergeTimeout); }); } // Load persisted history loadPersistedHistory() { if (!this.config.persistKey) return; try { const saved = localStorage.getItem(this.config.persistKey); if (saved) { const data = JSON.parse(saved); this.history._set(data.history || []); this.currentIndex._set(data.currentIndex || 0); const currentMemento = this.history.value()[this.currentIndex.value()]; if (currentMemento) { this.currentState._set(currentMemento.state); } } } catch (error) { console.warn('Failed to load persisted undo/redo history:', error); } } // Persist history persistHistory() { if (!this.config.persistKey) return; try { const data = { history: this.history.value(), currentIndex: this.currentIndex.value(), }; localStorage.setItem(this.config.persistKey, JSON.stringify(data)); } catch (error) { console.warn('Failed to persist undo/redo history:', error); } } // Compress history by removing intermediate states compressHistory() { if (!this.config.compressHistory) return; const maxSize = this.config.maxHistorySize || 50; const history = this.history.value(); if (history.length <= maxSize) return; // Keep first, last, and evenly distributed intermediate states const compressed = []; const step = Math.floor(history.length / maxSize); for (let i = 0; i < history.length; i += step) { compressed.push(history[i]); } // Always keep the last state if (compressed[compressed.length - 1] !== history[history.length - 1]) { compressed.push(history[history.length - 1]); } this.history._set(compressed); this.currentIndex._set(Math.min(this.currentIndex.value(), compressed.length - 1)); } // Execute command with coalgebraic time-travel execute(command) { const currentState = this.currentState.value(); // Try to merge with last command if auto-merge is enabled if (this.config.autoMerge && this.lastCommand) { if (command.canMerge?.(this.lastCommand)) { const mergedCommand = command.merge(this.lastCommand); this.executeInternal(mergedCommand, currentState); return; } } this.executeInternal(command, currentState); this.lastCommand = command; } // Internal command execution executeInternal(command, currentState) { try { const newState = command.execute(currentState); const memento = this.createMemento(newState, command.id, { commandName: command.name, commandId: command.id, }); // Clear future history (branching timeline) this.future._set([]); // Add to history const history = this.history.value(); const newHistory = [ ...history.slice(0, this.currentIndex.value() + 1), memento, ]; // Limit history size const maxSize = this.config.maxHistorySize || 50; if (newHistory.length > maxSize) { newHistory.splice(0, newHistory.length - maxSize); } this.history._set(newHistory); this.currentIndex._set(newHistory.length - 1); this.currentState._set(newState); // Add command to command history this.commands._set([...this.commands.value(), command]); // Compress history if needed this.compressHistory(); // Persist changes this.persistHistory(); } catch (error) { console.error('Failed to execute command:', error); } } // Undo operation (coalgebraic time-travel backward) undo() { const currentIdx = this.currentIndex.value(); const history = this.history.value(); if (currentIdx <= 0) return false; const previousMemento = history[currentIdx - 1]; const currentMemento = history[currentIdx]; // Move current state to future this.future._set([currentMemento, ...this.future.value()]); // Update current state this.currentIndex._set(currentIdx - 1); this.currentState._set(previousMemento.state); this.persistHistory(); return true; } // Redo operation (coalgebraic time-travel forward) redo() { const future = this.future.value(); if (future.length === 0) return false; const nextMemento = future[0]; const remainingFuture = future.slice(1); // Move state from future to history this.future._set(remainingFuture); this.currentIndex._set(this.currentIndex.value() + 1); this.currentState._set(nextMemento.state); this.persistHistory(); return true; } // Jump to specific point in history (coalgebraic time-travel to index) jumpTo(index) { const history = this.history.value(); if (index < 0 || index >= history.length) return false; const currentIdx = this.currentIndex.value(); const targetMemento = history[index]; if (index < currentIdx) { // Moving backward - add states to future const statesToFuture = history.slice(index + 1, currentIdx + 1).reverse(); this.future._set([...statesToFuture, ...this.future.value()]); } else if (index > currentIdx) { // Moving forward - remove states from future const statesToRemove = index - currentIdx; this.future._set(this.future.value().slice(statesToRemove)); } this.currentIndex._set(index); this.currentState._set(targetMemento.state); this.persistHistory(); return true; } // Create snapshot manually createSnapshot(id) { const currentState = this.currentState.value(); const memento = this.createMemento(currentState, id || `snapshot-${Date.now()}`, { type: 'manual-snapshot' }); const history = this.history.value(); const newHistory = [ ...history.slice(0, this.currentIndex.value() + 1), memento, ]; this.history._set(newHistory); this.currentIndex._set(newHistory.length - 1); this.future._set([]); this.persistHistory(); } // Get time-travel state getTimeTravel() { return (0, signal_1.computed)(() => ({ currentIndex: this.currentIndex.value(), history: this.history.value(), future: this.future.value(), canUndo: this.currentIndex.value() > 0, canRedo: this.future.value().length > 0, totalStates: this.history.value().length + this.future.value().length, })); } // Get current state signal getCurrentState() { return this.currentState; } // Get history signal getHistory() { return this.history; } // Get commands signal getCommands() { return this.commands; } // Clear all history clearHistory() { const currentState = this.currentState.value(); const initialMemento = this.createMemento(currentState, 'reset'); this.history._set([initialMemento]); this.future._set([]); this.currentIndex._set(0); this.commands._set([]); this.persistHistory(); } // Get state at specific index getStateAt(index) { const history = this.history.value(); return history[index]?.state || null; } // Check if can undo/redo canUndo() { return this.currentIndex.value() > 0; } canRedo() { return this.future.value().length > 0; } // Cleanup destroy() { if (this.mergeTimer) { clearTimeout(this.mergeTimer); } } } exports.UndoRedoManager = UndoRedoManager; // Factory function for creating undo/redo manager const createUndoRedoManager = (initialState, config) => { return new UndoRedoManager(initialState, config); }; exports.createUndoRedoManager = createUndoRedoManager; // Command builders const createCommand = (id, name, execute, undo, options) => ({ id, name, timestamp: Date.now(), execute, undo, canMerge: options?.canMerge, merge: options?.merge, }); exports.createCommand = createCommand; // Mergeable command for text editing const createTextCommand = (id, type, position, text, previousText) => ({ id, name: `text-${type}`, timestamp: Date.now(), execute: (state) => { switch (type) { case 'insert': return state.slice(0, position) + text + state.slice(position); case 'delete': return state.slice(0, position) + state.slice(position + text.length); case 'replace': return (state.slice(0, position) + text + state.slice(position + (previousText?.length || 0))); default: return state; } }, undo: (state) => { switch (type) { case 'insert': return state.slice(0, position) + state.slice(position + text.length); case 'delete': return state.slice(0, position) + text + state.slice(position); case 'replace': return (state.slice(0, position) + (previousText || '') + state.slice(position + text.length)); default: return state; } }, canMerge: (other) => { return (other.name.startsWith('text-') && Math.abs(other.timestamp - Date.now()) < 1000); }, merge: (other) => { // Simplified merge logic - in production, implement proper text merging return (0, exports.createTextCommand)(`${id}-${other.id}`, type, position, text, previousText); }, }); exports.createTextCommand = createTextCommand; // Array manipulation commands const createArrayCommand = (type, ...args) => ({ id: `array-${type}-${Date.now()}`, name: `array-${type}`, timestamp: Date.now(), execute: (state) => { const newState = [...state]; newState[type](...args); return newState; }, undo: (state) => { const newState = [...state]; // Implement reverse operations switch (type) { case 'push': newState.pop(); break; case 'pop': newState.push(args[0]); break; case 'shift': newState.unshift(args[0]); break; case 'unshift': newState.shift(); break; case 'splice': // Reverse splice operation const [start, deleteCount, ...items] = args; newState.splice(start, items.length, ...new Array(deleteCount)); break; } return newState; }, }); exports.createArrayCommand = createArrayCommand; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5kby1yZWRvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2V4dGVuc2lvbnMvdW5kby1yZWRvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7OztBQUVILDJDQUEwRDtBQXlDMUQsa0NBQWtDO0FBQ2xDLE1BQWEsZUFBZTtJQVMxQixZQUNFLFlBQWUsRUFDUCxTQUF5QixFQUFFO1FBQTNCLFdBQU0sR0FBTixNQUFNLENBQXFCO1FBTDdCLGdCQUFXLEdBQXNCLElBQUksQ0FBQztRQUN0QyxlQUFVLEdBQWtCLElBQUksQ0FBQztRQU12QyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUEsZUFBTSxFQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBQSxlQUFNLEVBQUMsRUFBRSxDQUFDLENBQUM7UUFDekIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFBLGVBQU0sRUFBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUEsZUFBTSxFQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBQSxlQUFNLEVBQUMsRUFBRSxDQUFDLENBQUM7UUFFM0IsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRCwrQ0FBK0M7SUFDdkMsYUFBYSxDQUNuQixLQUFRLEVBQ1IsRUFBVSxFQUNWLFFBQThCO1FBRTlCLE9BQU87WUFDTCxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7WUFDNUIsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDckIsRUFBRTtZQUNGLFFBQVE7U0FDVCxDQUFDO0lBQ0osQ0FBQztJQUVELG9DQUFvQztJQUM1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