import Combine import Foundation import GRDB @MainActor final class ClientsStore: ObservableObject { static let shared = ClientsStore() @Published private(set) var ready = false @Published private(set) var clients: [Client] = [] func startFetching() { Task { let observation = ValueObservation.tracking(Credentials.fetchAll) do { for try await credentials in observation.values(in: Database.shared.dbQueue) { processCredentials(credentials) ready = true print("Fetched \(credentials.count) credentials") } } catch {} } } func addNewClient(_ client: Client) { clients.append(client) Task(priority: .background) { try? await client.credentials.save() } } private func processCredentials(_ credentials: [Credentials]) { let existsJids = clients.map { $0.credentials.bareJid } let forAdd = credentials.filter { !existsJids.contains($0.bareJid) } let forRemove = existsJids.filter { !credentials.map { $0.bareJid }.contains($0) } var newClients = clients.filter { !forRemove.contains($0.credentials.bareJid) } newClients.append(contentsOf: forAdd.map { Client(credentials: $0) }) clients = newClients } }