4.7 KiB
DASH-001B-1: Electron-Store Migration
Overview
Migrate ProjectOrganizationService from localStorage to electron-store for persistent, disk-based storage that survives editor restarts, reinstalls, and npm run dev:clean.
Problem
Current implementation uses localStorage:
private loadData(): ProjectOrganizationData {
const stored = localStorage.getItem(this.storageKey);
// ...
}
private saveData(): void {
localStorage.setItem(this.storageKey, JSON.stringify(this.data));
}
Issues:
- Data cleared during
npm run dev:clean - Lost on editor reinstall/update
- Stored in Electron session cache (temporary)
Solution
Use electron-store like GitStore does:
import Store from 'electron-store';
const store = new Store<ProjectOrganizationData>({
name: 'project_organization',
encryptionKey: 'unique-key-here' // Optional
});
Implementation Steps
1. Update ProjectOrganizationService.ts
File: packages/noodl-editor/src/editor/src/services/ProjectOrganizationService.ts
Replace localStorage with electron-store:
import Store from 'electron-store';
import { EventDispatcher } from '../../../shared/utils/EventDispatcher';
// ... (keep existing interfaces)
export class ProjectOrganizationService extends EventDispatcher {
private static _instance: ProjectOrganizationService;
private store: Store<ProjectOrganizationData>;
private data: ProjectOrganizationData;
private constructor() {
super();
// Initialize electron-store
this.store = new Store<ProjectOrganizationData>({
name: 'project_organization',
defaults: {
version: 1,
folders: [],
tags: [],
projectMeta: {}
}
});
this.data = this.loadData();
}
private loadData(): ProjectOrganizationData {
try {
return this.store.store; // Get all data from store
} catch (error) {
console.error('[ProjectOrganizationService] Failed to load data:', error);
return {
version: 1,
folders: [],
tags: [],
projectMeta: {}
};
}
}
private saveData(): void {
try {
this.store.store = this.data; // Save all data to store
this.notifyListeners('dataChanged', this.data);
} catch (error) {
console.error('[ProjectOrganizationService] Failed to save data:', error);
}
}
// ... (rest of the methods remain the same)
}
2. Remove localStorage references
Remove the storageKey property as it's no longer needed:
// DELETE THIS:
private storageKey = 'projectOrganization';
3. Test persistence
After implementation:
- Create a folder in the launcher
- Run
npm run dev:clean - Restart the editor
- Verify the folder still exists
Files to Modify
packages/noodl-editor/src/editor/src/services/ProjectOrganizationService.ts
Changes Summary
Before:
- Used
localStorage.getItem()andlocalStorage.setItem() - Data stored in Electron session
- Cleared on dev mode restart
After:
- Uses
electron-storewith disk persistence - Data stored in OS-appropriate app data folder:
- macOS:
~/Library/Application Support/Noodl/project_organization.json - Windows:
%APPDATA%\Noodl\project_organization.json - Linux:
~/.config/Noodl/project_organization.json
- macOS:
- Survives all restarts and reinstalls
Testing Checklist
- Import
electron-storesuccessfully - Service initializes without errors
- Can create folders
- Can rename folders
- Can delete folders
- Can move projects to folders
- Data persists after
npm run dev:clean - Data persists after editor restart
- No console errors
Edge Cases
If electron-store fails to initialize
The service should gracefully fall back:
private loadData(): ProjectOrganizationData {
try {
return this.store.store;
} catch (error) {
console.error('[ProjectOrganizationService] Failed to load data:', error);
// Return empty structure - don't crash the app
return {
version: 1,
folders: [],
tags: [],
projectMeta: {}
};
}
}
Data corruption
If the stored JSON is corrupted, electron-store will throw an error. The loadData method catches this and returns empty defaults.
Benefits
- Persistent storage - Data survives restarts
- Proper location - Stored in OS app data folder
- Consistent pattern - Matches GitStore implementation
- Type safety - Generic
Store<ProjectOrganizationData>provides type checking - Atomic writes - electron-store handles file write safety
Follow-up
After this subtask, proceed to DASH-001B-2 (Service Integration) to connect the service to the UI.
Estimated Time: 1-2 hours Status: Not Started