feat: persist circuit and components to localStorage
Auto-saves every 3 seconds and on page unload. Restores the full state (circuit, camera, custom components) on page load. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
12
js/app.js
12
js/app.js
@@ -2,9 +2,21 @@
|
|||||||
import { initRenderer } from './renderer.js';
|
import { initRenderer } from './renderer.js';
|
||||||
import { initEvents } from './events.js';
|
import { initEvents } from './events.js';
|
||||||
import { initPuzzleUI } from './puzzleUI.js';
|
import { initPuzzleUI } from './puzzleUI.js';
|
||||||
|
import { loadFromStorage, startAutoSave } from './saveLoad.js';
|
||||||
|
import { updateComponentButtons } from './components.js';
|
||||||
|
import { evaluateAll } from './gates.js';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
initRenderer();
|
initRenderer();
|
||||||
initEvents();
|
initEvents();
|
||||||
initPuzzleUI();
|
initPuzzleUI();
|
||||||
|
|
||||||
|
// Restore previous session from localStorage
|
||||||
|
if (loadFromStorage()) {
|
||||||
|
updateComponentButtons();
|
||||||
|
evaluateAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-save every 3 seconds + on page unload
|
||||||
|
startAutoSave(3000);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
import { state } from './state.js';
|
import { state } from './state.js';
|
||||||
import { progress } from './levels.js';
|
import { progress } from './levels.js';
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'logiclab_state';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save complete application state to JSON
|
* Save complete application state to JSON
|
||||||
*/
|
*/
|
||||||
@@ -147,3 +149,46 @@ export async function pasteFromClipboard() {
|
|||||||
return { success: false, error: e.message };
|
return { success: false, error: e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save state to localStorage
|
||||||
|
*/
|
||||||
|
export function saveToStorage() {
|
||||||
|
try {
|
||||||
|
const data = saveState();
|
||||||
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[storage] failed to save:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load state from localStorage (returns true if state was restored)
|
||||||
|
*/
|
||||||
|
export function loadFromStorage() {
|
||||||
|
try {
|
||||||
|
const json = localStorage.getItem(STORAGE_KEY);
|
||||||
|
if (!json) return false;
|
||||||
|
const data = JSON.parse(json);
|
||||||
|
const result = loadState(data);
|
||||||
|
if (result.success) {
|
||||||
|
console.log('[storage] restored state from localStorage');
|
||||||
|
}
|
||||||
|
return result.success;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[storage] failed to load:', e.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start auto-saving to localStorage on an interval
|
||||||
|
*/
|
||||||
|
let autoSaveInterval = null;
|
||||||
|
export function startAutoSave(intervalMs = 3000) {
|
||||||
|
if (autoSaveInterval) clearInterval(autoSaveInterval);
|
||||||
|
autoSaveInterval = setInterval(saveToStorage, intervalMs);
|
||||||
|
// Also save on page unload
|
||||||
|
window.addEventListener('beforeunload', saveToStorage);
|
||||||
|
console.log(`[storage] auto-save enabled (every ${intervalMs}ms)`);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user