// // PersistenceService.swift // Zyquo Router // // Author: Simon-Pierre Boucher // Mail: contact@spboucher.ai // // JSON persistence in ~/Library/Application Support/ZyquoRouter/: // aliases.json, chains.json, local-keys.json, usage.json, settings.json // Ported from Zyquo Cloud; conversation-specific storage dropped (the Router // keeps generic named-document load/save only). // import Foundation struct PersistenceService { static let shared = PersistenceService() let rootDirectory: URL private let encoder: JSONEncoder private let decoder: JSONDecoder init(rootDirectory: URL? = nil) { let base = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] self.rootDirectory = rootDirectory ?? base.appendingPathComponent("ZyquoRouter") encoder = JSONEncoder() encoder.outputFormatting = [.prettyPrinted, .sortedKeys] encoder.dateEncodingStrategy = .iso8601 decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 try? FileManager.default.createDirectory(at: self.rootDirectory, withIntermediateDirectories: true) } // MARK: - Generic documents (aliases, chains, keys, settings…) func load(_ type: T.Type, from fileName: String) -> T? { let url = rootDirectory.appendingPathComponent(fileName) guard let data = try? Data(contentsOf: url) else { return nil } return try? decoder.decode(type, from: data) } func save(_ value: T, to fileName: String) { let url = rootDirectory.appendingPathComponent(fileName) guard let data = try? encoder.encode(value) else { return } try? data.write(to: url, options: .atomic) } }