Skip to content

Commit

Permalink
move AppSyncRTC back to API category package
Browse files Browse the repository at this point in the history
  • Loading branch information
5d committed Mar 28, 2024
1 parent f616f3b commit 6c99824
Show file tree
Hide file tree
Showing 13 changed files with 48 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Foundation
import Combine
import Amplify

@_spi(AppSyncRTC)
extension AppSyncRealTimeClient {
/**
Submit an AppSync request to real-time server.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import Foundation
import Combine
import Amplify
@_spi(WebSocket) import AmplifyNetwork

@_spi(AppSyncRTC)
public protocol AppSyncRealTimeClientProtocol {
protocol AppSyncRealTimeClientProtocol {
func connect() async throws
func disconnectWhenIdel() async
func disconnect() async
Expand All @@ -23,8 +23,7 @@ public protocol AppSyncRealTimeClientProtocol {
The AppSyncRealTimeClient conforms to the AppSync real-time WebSocket protocol.
ref: https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html
*/
@_spi(AppSyncRTC)
public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {
actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {

static let jsonEncoder = JSONEncoder()
static let jsonDecoder = JSONDecoder()
Expand Down Expand Up @@ -59,7 +58,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {
/// Writable data stream convert WebSocketEvent to AppSyncRealTimeResponse
internal let subject = PassthroughSubject<AppSyncRealTimeResponse, Never>()

public var isConnected: Bool {
var isConnected: Bool {
self.state.value == .connected
}

Expand All @@ -70,7 +69,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {
- requestInterceptor: Interceptor for decocating AppSyncRealTimeRequest
- webSocketClient: WebSocketClient for reading/writing to connection
*/
public init(
init(
endpoint: URL,
requestInterceptor: AppSyncRequestInterceptor,
webSocketClient: AppSyncWebSocketClientProtocol
Expand All @@ -93,7 +92,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {
/**
Connecting to remote AppSync real-time server.
*/
public func connect() async throws {
func connect() async throws {
switch self.state.value {
case .connecting, .connected:
log.debug("[AppSyncRealTimeClient] client is already connecting or connected")
Expand Down Expand Up @@ -125,7 +124,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {
/**
Disconnect only when there are no subscriptions exist.
*/
public func disconnectWhenIdel() async {
func disconnectWhenIdel() async {
if self.subscriptions.isEmpty {
log.debug("[AppSyncRealTimeClient] no subscription exist, client is trying to disconnect")
await disconnect()
Expand All @@ -137,7 +136,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {
/**
Disconnect from AppSync real-time server.
*/
public func disconnect() async {
func disconnect() async {
guard self.state.value != .disconnecting else {
log.debug("[AppSyncRealTimeClient] client already disconnecting")
return
Expand All @@ -161,7 +160,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol {
- Returns:
A never fail data stream for AppSyncSubscriptionEvent.
*/
public func subscribe(id: String, query: String) async throws -> AnyPublisher<AppSyncSubscriptionEvent, Never> {
func subscribe(id: String, query: String) async throws -> AnyPublisher<AppSyncSubscriptionEvent, Never> {
log.debug("[AppSyncRealTimeClient] Received subscription request id: \(id), query: \(query)")
let subscription = AppSyncRealTimeSubscription(id: id, query: query, appSyncRealTimeClient: self)
subscriptions[id] = subscription
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@
import Foundation
import Amplify

@_spi(AppSyncRTC)
public enum AppSyncRealTimeRequest {
enum AppSyncRealTimeRequest {
case connectionInit
case start(StartRequest)
case stop(String)

public struct StartRequest {
public let id: String
public let data: String
public let auth: AppSyncRealTimeRequestAuth?
struct StartRequest {
let id: String
let data: String
let auth: AppSyncRealTimeRequestAuth?

public init(id: String, data: String, auth: AppSyncRealTimeRequestAuth?) {
init(id: String, data: String, auth: AppSyncRealTimeRequestAuth?) {
self.id = id
self.data = data
self.auth = auth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,58 +8,57 @@

import Foundation

@_spi(AppSyncRTC)
public enum AppSyncRealTimeRequestAuth {
enum AppSyncRealTimeRequestAuth {
case authToken(AuthToken)
case apiKey(ApiKey)
case iam(IAM)

public struct AuthToken {
struct AuthToken {
let host: String
let authToken: String

public init(host: String, authToken: String) {
init(host: String, authToken: String) {
self.host = host
self.authToken = authToken
}
}

public struct ApiKey {
struct ApiKey {
let host: String
let apiKey: String
let amzDate: String

public init(host: String, apiKey: String, amzDate: String) {
init(host: String, apiKey: String, amzDate: String) {
self.host = host
self.apiKey = apiKey
self.amzDate = amzDate
}
}

public struct IAM {
struct IAM {
let host: String
let authToken: String
let securityToken: String
let amzDate: String

public init(host: String, authToken: String, securityToken: String, amzDate: String) {
init(host: String, authToken: String, securityToken: String, amzDate: String) {
self.host = host
self.authToken = authToken
self.securityToken = securityToken
self.amzDate = amzDate
}
}

public struct URLQuery {
struct URLQuery {
let header: AppSyncRealTimeRequestAuth
let payload: String

public init(header: AppSyncRealTimeRequestAuth, payload: String = "{}") {
init(header: AppSyncRealTimeRequestAuth, payload: String = "{}") {
self.header = header
self.payload = payload
}

public func withBaseURL(_ url: URL, encoder: JSONEncoder? = nil) -> URL {
func withBaseURL(_ url: URL, encoder: JSONEncoder? = nil) -> URL {
let jsonEncoder: JSONEncoder = encoder ?? JSONEncoder()
guard let headerJsonData = try? jsonEncoder.encode(header) else {
return url
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@
import Foundation
import Amplify

@_spi(AppSyncRTC)
public struct AppSyncRealTimeResponse {
struct AppSyncRealTimeResponse {

public let id: String?
public let payload: JSONValue?
public let type: EventType
let id: String?
let payload: JSONValue?
let type: EventType

public enum EventType: String, Codable {
enum EventType: String, Codable {
case connectionAck = "connection_ack"
case startAck = "start_ack"
case stopAck = "complete"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
import Foundation
import Combine
import Amplify
@_spi(WebSocket) import AmplifyNetwork

/**
AppSyncRealTimeSubscription reprensents one realtime subscription to AppSync realtime server.
*/
@_spi(AppSyncRTC)
public actor AppSyncRealTimeSubscription {
actor AppSyncRealTimeSubscription {
static let jsonEncoder = JSONEncoder()

public enum State {
enum State {
case none
case subscribing
case subscribed
Expand All @@ -36,8 +36,8 @@ public actor AppSyncRealTimeSubscription {

private weak var appSyncRealTimeClient: AppSyncRealTimeClient?

public let id: String
public let query: String
let id: String
let query: String


init(id: String, query: String, appSyncRealTimeClient: AppSyncRealTimeClient) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import Foundation

@_spi(AppSyncRTC)
public protocol AppSyncRequestInterceptor {
protocol AppSyncRequestInterceptor {
func interceptRequest(event: AppSyncRealTimeRequest, url: URL) async -> AppSyncRealTimeRequest
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
import Foundation
import Amplify

@_spi(AppSyncRTC)
public enum AppSyncSubscriptionEvent {
enum AppSyncSubscriptionEvent {
case subscribing
case subscribed
case data(JSONValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

import Foundation
import Combine
@_spi(WebSocket) import AmplifyNetwork

@_spi(AppSyncRTC)
public protocol AppSyncWebSocketClientProtocol: AnyObject {
protocol AppSyncWebSocketClientProtocol: AnyObject {
var isConnected: Bool { get async }
var publisher: AnyPublisher<WebSocketEvent, Never> { get async }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import XCTest
import Combine
@testable import Amplify
@testable import AWSAPIPlugin
@testable @_spi(WebSocket) import AWSPluginsCore
@testable import AWSPluginsCore
@testable @_spi(WebSocket) import AmplifyNetwork

class AppSyncRealTimeClientTests: XCTestCase {
let subscriptionRequest = """
Expand Down Expand Up @@ -154,10 +155,12 @@ class AppSyncRealTimeClientTests: XCTestCase {
maxSubscriptionReachedError.assertForOverFulfill = false
let retryTriggerredAndSucceed = expectation(description: "Retry on max subscription reached error and succeed")
cancellables.append(try await makeOneSubscription { event in
if case .error(let errors) = event {
XCTAssertTrue(errors.count == 1)
XCTAssertTrue(errors[0] is AppSyncRealTimeRequest.Error)
if case .maxSubscriptionsReached = errors[0] as! AppSyncRealTimeRequest.Error {
if case .error(let payload) = event,
let error = payload.errors {
let errors = error.asArray ?? [error]
let requestErrors = errors.compactMap(AppSyncRealTimeRequest.parseResponseError(error:))
XCTAssertTrue(requestErrors.count == 1)
if case .maxSubscriptionsReached = requestErrors[0] {
maxSubscriptionReachedError.fulfill()
cancellables.dropLast(10).forEach { $0?.cancel() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import XCTest
import Combine
import Amplify
@testable import AWSAPIPlugin
@_spi(WebSocket) import AmplifyNetwork

class AppSyncRealTimeClientTests: XCTestCase {

Expand Down

0 comments on commit 6c99824

Please sign in to comment.