diff --git a/apps/macos/Sources/Clawdis/GatewayPayloadDecoding.swift b/apps/macos/Sources/Clawdis/GatewayPayloadDecoding.swift new file mode 100644 index 000000000..2087cd064 --- /dev/null +++ b/apps/macos/Sources/Clawdis/GatewayPayloadDecoding.swift @@ -0,0 +1,16 @@ +import ClawdisProtocol +import Foundation + +enum GatewayPayloadDecoding { + static func decode(_ payload: ClawdisProtocol.AnyCodable, as _: T.Type = T.self) throws -> T { + let data = try JSONEncoder().encode(payload) + return try JSONDecoder().decode(T.self, from: data) + } + + static func decodeIfPresent(_ payload: ClawdisProtocol.AnyCodable?, as _: T.Type = T.self) throws + -> T? + { + guard let payload else { return nil } + return try decode(payload, as: T.self) + } +} diff --git a/apps/macos/Sources/Clawdis/InstancesStore.swift b/apps/macos/Sources/Clawdis/InstancesStore.swift index d55423fa4..a7f82b9f2 100644 --- a/apps/macos/Sources/Clawdis/InstancesStore.swift +++ b/apps/macos/Sources/Clawdis/InstancesStore.swift @@ -92,11 +92,7 @@ final class InstancesStore: ObservableObject { case .seqGap: Task { await self.refresh() } case let .snapshot(hello): - if JSONSerialization.isValidJSONObject(hello.snapshot.presence), - let data = try? JSONEncoder().encode(hello.snapshot.presence) - { - self.decodeAndApplyPresenceData(data) - } + self.applyPresence(hello.snapshot.presence) default: break } @@ -264,8 +260,7 @@ final class InstancesStore: ObservableObject { func handlePresenceEventPayload(_ payload: ClawdisProtocol.AnyCodable) { do { - let payloadData = try JSONEncoder().encode(payload) - let wrapper = try JSONDecoder().decode(PresenceEventPayload.self, from: payloadData) + let wrapper = try GatewayPayloadDecoding.decode(payload, as: PresenceEventPayload.self) self.applyPresence(wrapper.presence) } catch { self.logger.error("presence event decode failed: \(error.localizedDescription, privacy: .public)") diff --git a/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift b/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift index 7913c5e42..92f72dda8 100644 --- a/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift +++ b/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift @@ -213,8 +213,7 @@ final class WebChatViewModel: ObservableObject { private func handleGatewayEvent(_ evt: EventFrame) { guard evt.event == "chat" else { return } guard let payload = evt.payload else { return } - guard let data = try? JSONEncoder().encode(payload) else { return } - guard let chat = try? JSONDecoder().decode(ChatEventPayload.self, from: data) else { return } + guard let chat = try? GatewayPayloadDecoding.decode(payload, as: ChatEventPayload.self) else { return } guard chat.sessionKey == nil || chat.sessionKey == self.sessionKey else { return } if let runId = chat.runId, !self.pendingRuns.contains(runId) {