Skip to content

Commit

Permalink
refactor(realtime): general realtime improvements (#426)
Browse files Browse the repository at this point in the history
  • Loading branch information
grdsdev authored Jun 27, 2024
1 parent 083c6c3 commit 7512be9
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 8 deletions.
1 change: 0 additions & 1 deletion Examples/Examples/AnyJSONView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ struct AnyJSONView: View {
}
}
}

case let .object(object):
let elements = Array(object).sorted(by: { $0.key < $1.key })
ForEach(elements, id: \.key) { element in
Expand Down
2 changes: 1 addition & 1 deletion Examples/UserManagement/AppView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct AppView: View {
}
}
.task {
for await state in await supabase.auth.authStateChanges {
for await state in supabase.auth.authStateChanges {
if [.initialSession, .signedIn, .signedOut].contains(state.event) {
isAuthenticated = state.session != nil
}
Expand Down
5 changes: 2 additions & 3 deletions Examples/UserManagement/ProfileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ struct ProfileView: View {
do {
let currentUser = try await supabase.auth.session.user

let profile: Profile = try await supabase.database
.from("profiles")
let profile: Profile = try await supabase.from("profiles")
.select()
.eq("id", value: currentUser.id)
.single()
Expand Down Expand Up @@ -138,7 +137,7 @@ struct ProfileView: View {
avatarURL: imageURL
)

try await supabase.database
try await supabase
.from("profiles")
.update(updatedProfile)
.eq("id", value: currentUser.id)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Realtime/V2/CallbackManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import ConcurrencyExtras
import Foundation
import Helpers

final class CallbackManager: @unchecked Sendable {
final class CallbackManager: Sendable {
struct MutableState {
var id = 0
var serverChanges: [PostgresJoinConfig] = []
Expand Down
8 changes: 8 additions & 0 deletions Sources/Realtime/V2/RealtimeChannelV2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,18 @@ public final class RealtimeChannelV2: Sendable {
)
}

/// Send a broadcast message with `event` and a `Codable` payload.
/// - Parameters:
/// - event: Broadcast message event.
/// - message: Message payload.
public func broadcast(event: String, message: some Codable) async throws {
try await broadcast(event: event, message: JSONObject(message))
}

/// Send a broadcast message with `event` and a raw `JSON` payload.
/// - Parameters:
/// - event: Broadcast message event.
/// - message: Message payload.
public func broadcast(event: String, message: JSONObject) async {
assert(
status == .subscribed,
Expand Down
8 changes: 7 additions & 1 deletion Sources/Realtime/V2/RealtimeMessageV2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@ public struct RealtimeMessageV2: Hashable, Codable, Sendable {
self.payload = payload
}

var status: PushStatus? {
payload["status"]
.flatMap(\.stringValue)
.flatMap(PushStatus.init(rawValue:))
}

public var eventType: EventType? {
switch event {
case ChannelEvent.system where payload["status"]?.stringValue == "ok": .system
case ChannelEvent.system where status == .ok: .system
case ChannelEvent.postgresChanges:
.postgresChanges
case ChannelEvent.broadcast:
Expand Down
1 change: 1 addition & 0 deletions Sources/Realtime/V2/WebSocketClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ final class WebSocket: NSObject, URLSessionWebSocketDelegate, WebSocketClient, @

case .data:
fallthrough

default:
throw RealtimeError("Unsupported message type.")
}
Expand Down
60 changes: 60 additions & 0 deletions Tests/RealtimeTests/RealtimeMessageV2Tests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// RealtimeMessageV2Tests.swift
//
//
// Created by Guilherme Souza on 26/06/24.
//

@testable import Realtime
import XCTest

final class RealtimeMessageV2Tests: XCTestCase {
func testStatus() {
var message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "ok"])
XCTAssertEqual(message.status, .ok)

message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "timeout"])
XCTAssertEqual(message.status, .timeout)

message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "error"])
XCTAssertEqual(message.status, .error)

message = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "heartbeat", event: "event", payload: ["status": "invalid"])
XCTAssertNil(message.status)
}

func testEventType() {
let payloadWithTokenExpiredMessage: JSONObject = ["message": "access token has expired"]
let payloadWithStatusOK: JSONObject = ["status": "ok"]
let payloadWithNoStatus: JSONObject = [:]

let systemEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.system, payload: payloadWithStatusOK)
let postgresChangesEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.postgresChanges, payload: payloadWithNoStatus)
let tokenExpiredEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.system, payload: payloadWithTokenExpiredMessage)

XCTAssertEqual(systemEventMessage.eventType, .system)
XCTAssertEqual(postgresChangesEventMessage.eventType, .postgresChanges)
XCTAssertEqual(tokenExpiredEventMessage.eventType, .tokenExpired)

let broadcastEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.broadcast, payload: payloadWithNoStatus)
XCTAssertEqual(broadcastEventMessage.eventType, .broadcast)

let closeEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.close, payload: payloadWithNoStatus)
XCTAssertEqual(closeEventMessage.eventType, .close)

let errorEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.error, payload: payloadWithNoStatus)
XCTAssertEqual(errorEventMessage.eventType, .error)

let presenceDiffEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.presenceDiff, payload: payloadWithNoStatus)
XCTAssertEqual(presenceDiffEventMessage.eventType, .presenceDiff)

let presenceStateEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.presenceState, payload: payloadWithNoStatus)
XCTAssertEqual(presenceStateEventMessage.eventType, .presenceState)

let replyEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: ChannelEvent.reply, payload: payloadWithNoStatus)
XCTAssertEqual(replyEventMessage.eventType, .reply)

let unknownEventMessage = RealtimeMessageV2(joinRef: nil, ref: nil, topic: "topic", event: "unknown_event", payload: payloadWithNoStatus)
XCTAssertNil(unknownEventMessage.eventType)
}
}
2 changes: 1 addition & 1 deletion Tests/RealtimeTests/RealtimeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class RealtimeTests: XCTestCase {

override func tearDown() {
sut.disconnect()

super.tearDown()
}

Expand Down

0 comments on commit 7512be9

Please sign in to comment.