• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / supabase-swift / 17238365990

26 Aug 2025 12:38PM UTC coverage: 48.936% (-28.5%) from 77.386%
17238365990

Pull #781

github

web-flow
Merge 95ac7642e into e4d8c3718
Pull Request #781: RFC: Migrate HTTP networking from URLSession to Alamofire

287 of 986 new or added lines in 26 files covered. (29.11%)

1397 existing lines in 30 files now uncovered.

3448 of 7046 relevant lines covered (48.94%)

5.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.57
/Sources/Realtime/CallbackManager.swift
1
import ConcurrencyExtras
2
import Foundation
3

4
final class CallbackManager: Sendable {
5
  struct MutableState {
6
    var id = 0
12✔
7
    var serverChanges: [PostgresJoinConfig] = []
12✔
8
    var callbacks: [RealtimeCallback] = []
12✔
9
  }
10

11
  private let mutableState = LockIsolated(MutableState())
6✔
12

13
  var serverChanges: [PostgresJoinConfig] {
1✔
14
    mutableState.serverChanges
1✔
15
  }
1✔
16

17
  var callbacks: [RealtimeCallback] {
3✔
18
    mutableState.callbacks
3✔
19
  }
3✔
20

21
  deinit {
6✔
22
    reset()
6✔
23
  }
6✔
24

25
  @discardableResult
26
  func addBroadcastCallback(
27
    event: String,
28
    callback: @escaping @Sendable (JSONObject) -> Void
29
  ) -> Int {
4✔
30
    mutableState.withValue {
4✔
31
      $0.id += 1
4✔
32
      $0.callbacks.append(
4✔
33
        .broadcast(
4✔
34
          BroadcastCallback(
4✔
35
            id: $0.id,
4✔
36
            event: event,
4✔
37
            callback: callback
4✔
38
          )
4✔
39
        )
4✔
40
      )
4✔
41
      return $0.id
4✔
42
    }
4✔
43
  }
4✔
44

45
  @discardableResult
46
  func addPostgresCallback(
47
    filter: PostgresJoinConfig,
48
    callback: @escaping @Sendable (AnyAction) -> Void
49
  ) -> Int {
5✔
50
    mutableState.withValue {
5✔
51
      $0.id += 1
5✔
52
      $0.callbacks.append(
5✔
53
        .postgres(
5✔
54
          PostgresCallback(
5✔
55
            id: $0.id,
5✔
56
            filter: filter,
5✔
57
            callback: callback
5✔
58
          )
5✔
59
        )
5✔
60
      )
5✔
61
      return $0.id
5✔
62
    }
5✔
63
  }
5✔
64

65
  @discardableResult
66
  func addPresenceCallback(callback: @escaping @Sendable (any PresenceAction) -> Void) -> Int {
2✔
67
    mutableState.withValue {
2✔
68
      $0.id += 1
2✔
69
      $0.callbacks.append(.presence(PresenceCallback(id: $0.id, callback: callback)))
2✔
70
      return $0.id
2✔
71
    }
2✔
72
  }
2✔
73

74
  @discardableResult
75
  func addSystemCallback(callback: @escaping @Sendable (RealtimeMessageV2) -> Void) -> Int {
1✔
76
    mutableState.withValue {
1✔
77
      $0.id += 1
1✔
78
      $0.callbacks.append(.system(SystemCallback(id: $0.id, callback: callback)))
1✔
79
      return $0.id
1✔
80
    }
1✔
81
  }
1✔
82

83
  func setServerChanges(changes: [PostgresJoinConfig]) {
2✔
84
    mutableState.withValue {
2✔
85
      $0.serverChanges = changes
2✔
86
    }
2✔
87
  }
2✔
88

89
  func removeCallback(id: Int) {
2✔
90
    mutableState.withValue {
2✔
91
      $0.callbacks.removeAll { $0.id == id }
5✔
92
    }
2✔
93
  }
2✔
94

95
  func triggerPostgresChanges(ids: [Int], data: AnyAction) {
4✔
96
    // Read mutableState at start to acquire lock once.
4✔
97
    let mutableState = mutableState.value
4✔
98

4✔
99
    let filters = mutableState.serverChanges.filter {
16✔
100
      ids.contains($0.id)
16✔
101
    }
16✔
102
    let postgresCallbacks = mutableState.callbacks.compactMap {
16✔
103
      if case let .postgres(callback) = $0 {
16✔
104
        return callback
16✔
105
      }
16✔
106
      return nil
×
107
    }
16✔
108

4✔
109
    let callbacks = postgresCallbacks.filter { cc in
16✔
110
      filters.contains { sc in
16✔
111
        cc.filter == sc
16✔
112
      }
16✔
113
    }
16✔
114

4✔
115
    for item in callbacks {
6✔
116
      item.callback(data)
6✔
117
    }
6✔
118
  }
4✔
119

120
  func triggerBroadcast(event: String, json: JSONObject) {
3✔
121
    let broadcastCallbacks = mutableState.callbacks.compactMap {
6✔
122
      if case let .broadcast(callback) = $0 {
6✔
123
        return callback
6✔
124
      }
6✔
125
      return nil
×
126
    }
6✔
127
    let callbacks = broadcastCallbacks.filter { $0.event == "*" || $0.event.lowercased() == event.lowercased() }
6✔
128
    callbacks.forEach { $0.callback(json) }
6✔
129
  }
3✔
130

131
  func triggerPresenceDiffs(
132
    joins: [String: PresenceV2],
133
    leaves: [String: PresenceV2],
134
    rawMessage: RealtimeMessageV2
135
  ) {
1✔
136
    let presenceCallbacks = mutableState.callbacks.compactMap {
1✔
137
      if case let .presence(callback) = $0 {
1✔
138
        return callback
1✔
139
      }
1✔
140
      return nil
×
141
    }
1✔
142
    for presenceCallback in presenceCallbacks {
1✔
143
      presenceCallback.callback(
1✔
144
        PresenceActionImpl(
1✔
145
          joins: joins,
1✔
146
          leaves: leaves,
1✔
147
          rawMessage: rawMessage
1✔
148
        )
1✔
149
      )
1✔
150
    }
1✔
151
  }
1✔
152

153
  func triggerSystem(message: RealtimeMessageV2) {
1✔
154
    let systemCallbacks = mutableState.callbacks.compactMap {
1✔
155
      if case .system(let callback) = $0 {
1✔
156
        return callback
1✔
157
      }
1✔
158
      return nil
×
159
    }
1✔
160

1✔
161
    for systemCallback in systemCallbacks {
1✔
162
      systemCallback.callback(message)
1✔
163
    }
1✔
164
  }
1✔
165

166
  func reset() {
6✔
167
    mutableState.setValue(MutableState())
6✔
168
  }
6✔
169
}
170

171
struct PostgresCallback {
172
  var id: Int
173
  var filter: PostgresJoinConfig
174
  var callback: @Sendable (AnyAction) -> Void
175
}
176

177
struct BroadcastCallback {
178
  var id: Int
179
  var event: String
180
  var callback: @Sendable (JSONObject) -> Void
181
}
182

183
struct PresenceCallback {
184
  var id: Int
185
  var callback: @Sendable (any PresenceAction) -> Void
186
}
187

188
struct SystemCallback {
189
  var id: Int
190
  var callback: @Sendable (RealtimeMessageV2) -> Void
191
}
192

193
enum RealtimeCallback {
194
  case postgres(PostgresCallback)
195
  case broadcast(BroadcastCallback)
196
  case presence(PresenceCallback)
197
  case system(SystemCallback)
198

199
  var id: Int {
7✔
200
    switch self {
7✔
201
    case let .postgres(callback): callback.id
7✔
202
    case let .broadcast(callback): callback.id
7✔
203
    case let .presence(callback): callback.id
7✔
204
    case let .system(callback): callback.id
7✔
205
    }
7✔
206
  }
7✔
207

UNCOV
208
  var isPresence: Bool {
×
UNCOV
209
    if case .presence = self {
×
UNCOV
210
      return true
×
UNCOV
211
    } else {
×
UNCOV
212
      return false
×
UNCOV
213
    }
×
UNCOV
214
  }
×
215
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc