spb/zyquo-router Public MIT
One local endpoint, every AI provider — a private OpenAI-compatible LLM gateway for your Mac (170 models, 12 providers).
Swift 95.7%
Python 2.3%
Shell 1.2%
Makefile 0.9%
1//2// PersistenceService.swift3// Zyquo Router4//5// Author: Simon-Pierre Boucher6// Mail: contact@spboucher.ai7//8// JSON persistence in ~/Library/Application Support/ZyquoRouter/:9// aliases.json, chains.json, local-keys.json, usage.json, settings.json10// Ported from Zyquo Cloud; conversation-specific storage dropped (the Router11// keeps generic named-document load/save only).12//1314import Foundation1516struct PersistenceService {17 static let shared = PersistenceService()1819 let rootDirectory: URL2021 private let encoder: JSONEncoder22 private let decoder: JSONDecoder2324 init(rootDirectory: URL? = nil) {25 let base = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]26 self.rootDirectory = rootDirectory ?? base.appendingPathComponent("ZyquoRouter")27 encoder = JSONEncoder()28 encoder.outputFormatting = [.prettyPrinted, .sortedKeys]29 encoder.dateEncodingStrategy = .iso860130 decoder = JSONDecoder()31 decoder.dateDecodingStrategy = .iso860132 try? FileManager.default.createDirectory(at: self.rootDirectory, withIntermediateDirectories: true)33 }3435 // MARK: - Generic documents (aliases, chains, keys, settings…)3637 func load<T: Decodable>(_ type: T.Type, from fileName: String) -> T? {38 let url = rootDirectory.appendingPathComponent(fileName)39 guard let data = try? Data(contentsOf: url) else { return nil }40 return try? decoder.decode(type, from: data)41 }4243 func save<T: Encodable>(_ value: T, to fileName: String) {44 let url = rootDirectory.appendingPathComponent(fileName)45 guard let data = try? encoder.encode(value) else { return }46 try? data.write(to: url, options: .atomic)47 }48}49