Files
CodeNomad/src/lib/storage.ts

107 lines
3.2 KiB
TypeScript

import type { Preferences, RecentFolder } from "../stores/preferences"
export interface ConfigData {
preferences: Preferences
recentFolders: RecentFolder[]
}
export interface InstanceData {
messageHistory: string[]
}
export class FileStorage {
private configPath: string
private instancesDir: string
private configChangeListeners: Set<() => void> = new Set()
constructor() {
this.configPath = window.electronAPI.getConfigPath()
this.instancesDir = window.electronAPI.getInstancesDir()
// Listen for config changes from other instances
window.electronAPI.onConfigChanged(() => {
this.configChangeListeners.forEach((listener) => listener())
})
}
// Config operations
async loadConfig(): Promise<ConfigData> {
try {
const content = await window.electronAPI.readConfigFile()
return JSON.parse(content)
} catch (error) {
console.warn("Failed to load config, using defaults:", error)
return {
preferences: {
showThinkingBlocks: false,
},
recentFolders: [],
}
}
}
async saveConfig(config: ConfigData): Promise<void> {
try {
await window.electronAPI.writeConfigFile(JSON.stringify(config, null, 2))
} catch (error) {
console.error("Failed to save config:", error)
throw error
}
}
// Instance operations
async loadInstanceData(instanceId: string): Promise<InstanceData> {
try {
const filename = this.instanceIdToFilename(instanceId)
const content = await window.electronAPI.readInstanceFile(filename)
return JSON.parse(content)
} catch (error) {
console.warn(`Failed to load instance data for ${instanceId}, using defaults:`, error)
return {
messageHistory: [],
}
}
}
async saveInstanceData(instanceId: string, data: InstanceData): Promise<void> {
try {
const filename = this.instanceIdToFilename(instanceId)
await window.electronAPI.writeInstanceFile(filename, JSON.stringify(data, null, 2))
} catch (error) {
console.error(`Failed to save instance data for ${instanceId}:`, error)
throw error
}
}
async deleteInstanceData(instanceId: string): Promise<void> {
try {
const filename = this.instanceIdToFilename(instanceId)
await window.electronAPI.deleteInstanceFile(filename)
} catch (error) {
console.error(`Failed to delete instance data for ${instanceId}:`, error)
throw error
}
}
// Convert folder path to safe filename
private instanceIdToFilename(instanceId: string): string {
// Convert folder path to safe filename
// Replace path separators and other invalid characters
return instanceId
.replace(/[\\/]/g, "_") // Replace path separators
.replace(/[^a-zA-Z0-9_.-]/g, "_") // Replace other invalid chars
.replace(/_{2,}/g, "_") // Replace multiple underscores with single
.replace(/^_|_$/g, "") // Remove leading/trailing underscores
.toLowerCase()
}
// Config change listeners
onConfigChanged(listener: () => void): () => void {
this.configChangeListeners.add(listener)
return () => this.configChangeListeners.delete(listener)
}
}
// Singleton instance
export const storage = new FileStorage()