Skip to content

Commit

Permalink
Merge pull request #22 from ably-labs/implement-Subscription
Browse files Browse the repository at this point in the history
Implement the `Subscription` type
  • Loading branch information
lawrence-forooghian authored Aug 26, 2024
2 parents 20e7f5f + 721f10c commit 1089a3a
Show file tree
Hide file tree
Showing 15 changed files with 345 additions and 33 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
run: swift run BuildTool generate-matrices >> $GITHUB_OUTPUT

check-spm:
name: SPM (Xcode ${{ matrix.tooling.xcodeVersion }}, Swift ${{ matrix.tooling.swiftVersion }})
name: SPM (Xcode ${{ matrix.tooling.xcodeVersion }})
runs-on: macos-latest
needs: generate-matrices
strategy:
Expand All @@ -57,11 +57,11 @@ jobs:
xcode-version: ${{ matrix.tooling.xcodeVersion }}

# https://forums.swift.org/t/warnings-as-errors-for-libraries-frameworks/58393/2
- run: swift build -Xswiftc -warnings-as-errors -Xswiftc -swift-version -Xswiftc ${{ matrix.tooling.swiftVersion }}
- run: swift test -Xswiftc -warnings-as-errors -Xswiftc -swift-version -Xswiftc ${{ matrix.tooling.swiftVersion }}
- run: swift build -Xswiftc -warnings-as-errors
- run: swift test -Xswiftc -warnings-as-errors

check-xcode:
name: Xcode, ${{matrix.platform}} (Xcode ${{ matrix.tooling.xcodeVersion }}, Swift ${{ matrix.tooling.swiftVersion }})
name: Xcode, ${{matrix.platform}} (Xcode ${{ matrix.tooling.xcodeVersion }})
runs-on: macos-latest
needs: generate-matrices

Expand All @@ -76,7 +76,7 @@ jobs:
xcode-version: ${{ matrix.tooling.xcodeVersion }}

- name: Build and run tests
run: swift run BuildTool build-and-test-library --platform ${{ matrix.platform }} --swift-version ${{ matrix.tooling.swiftVersion }}
run: swift run BuildTool build-and-test-library --platform ${{ matrix.platform }}

check-example-app:
name: Example app, ${{matrix.platform}} (Xcode ${{ matrix.tooling.xcodeVersion }}, Swift ${{ matrix.tooling.swiftVersion }})
Expand Down
20 changes: 19 additions & 1 deletion AblyChat.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "f6b591fa76437494c2609ca1208b8583cbc3debe5e659be06bdcb7bc4bb5e457",
"originHash" : "fcc346d6fe86e610ac200cdbbf91c56204df67286546d5079bd9c610ee65953b",
"pins" : [
{
"identity" : "ably-cocoa",
Expand Down Expand Up @@ -36,6 +36,24 @@
"revision" : "41982a3656a71c768319979febd796c6fd111d5c",
"version" : "1.5.0"
}
},
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms",
"state" : {
"revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20",
"version" : "1.0.1"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d",
"version" : "1.1.2"
}
}
],
"version" : 3
Expand Down
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ And, actually more importantly, we want to be sure that the SDK can be integrate

### Multiple `Package.swift` files

We have a separate manifest file, `[email protected]`, which a Swift compiler supporting Swift 6 will use instead of `Package.swift` (see [documentation of this SPM feature](https://github.com/swiftlang/swift-package-manager/blob/74f06f8a7fd6b4c729e474dee34db66319d90759/Documentation/Usage.md#version-specific-manifest-selection)). This file only exists because if you try to use `.enableUpcomingFeature` for a feature that is enabled by default in Swift 6, you’ll get an error `error: upcoming feature 'BareSlashRegexLiterals' is already enabled as of Swift version 6`. (I don’t know if there’s a better way of handling this.)
We have a separate manifest file, `[email protected]`, which a Swift compiler supporting Swift 6 will use instead of `Package.swift` (see [documentation of this SPM feature](https://github.com/swiftlang/swift-package-manager/blob/74f06f8a7fd6b4c729e474dee34db66319d90759/Documentation/Usage.md#version-specific-manifest-selection)). This file exists for two reasons:

1. To tell the compiler “use the Swift 6 language mode to compile this package if the compiler supports Swift 6, else use the Swift 5 language mode” (I previously tried passing `-Xswiftc -swift-version -Xswiftc 6` to `swift build` but this seems to then use Swift 6 language mode for compiling not just our own package, but all of our dependencies, which is likely to fail.)
2. If you try to use `.enableUpcomingFeature` for a feature that is enabled by default in Swift 6, you’ll get an error `error: upcoming feature 'BareSlashRegexLiterals' is already enabled as of Swift version 6`. (I don’t know if there’s a better way of handling this.)

So, we need to make sure we keep `Package.swift` and `[email protected]` in sync manually.
6 changes: 4 additions & 2 deletions Example/AblyChatExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

/* Begin PBXFileReference section */
212F95A62C6CAD9300420287 /* MockRealtime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRealtime.swift; sourceTree = "<group>"; };
214AA9262C778FB70068FD0A /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
21F09A9C2C60CAF00025AF73 /* AblyChatExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AblyChatExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
21F09A9F2C60CAF00025AF73 /* AblyChatExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AblyChatExampleApp.swift; sourceTree = "<group>"; };
21F09AA12C60CAF00025AF73 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -75,6 +76,7 @@
212F95A52C6CAD7E00420287 /* Mocks */,
21F09A9F2C60CAF00025AF73 /* AblyChatExampleApp.swift */,
21F09AA12C60CAF00025AF73 /* ContentView.swift */,
214AA9262C778FB70068FD0A /* Config.xcconfig */,
21F09AA32C60CAF20025AF73 /* Assets.xcassets */,
21F09AA52C60CAF20025AF73 /* AblyChatExample.entitlements */,
21F09AA62C60CAF20025AF73 /* Preview Content */,
Expand Down Expand Up @@ -174,6 +176,7 @@
/* Begin XCBuildConfiguration section */
21F09AA92C60CAF20025AF73 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 214AA9262C778FB70068FD0A /* Config.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
Expand Down Expand Up @@ -238,6 +241,7 @@
};
21F09AAA2C60CAF20025AF73 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 214AA9262C778FB70068FD0A /* Config.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
Expand Down Expand Up @@ -326,7 +330,6 @@
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,3";
TVOS_DEPLOYMENT_TARGET = 17.0;
};
Expand Down Expand Up @@ -366,7 +369,6 @@
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,3";
TVOS_DEPLOYMENT_TARGET = 17.0;
};
Expand Down
3 changes: 3 additions & 0 deletions Example/AblyChatExample/Config.xcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This allows us to specify the Swift version on the command line without affecting the Swift version used for our dependencies (which it appears that specifying SWIFT_VERSION on the command line does).
EXAMPLE_APP_SWIFT_VERSION = 5.0
SWIFT_VERSION = $(EXAMPLE_APP_SWIFT_VERSION)
20 changes: 19 additions & 1 deletion Package.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "f6b591fa76437494c2609ca1208b8583cbc3debe5e659be06bdcb7bc4bb5e457",
"originHash" : "fcc346d6fe86e610ac200cdbbf91c56204df67286546d5079bd9c610ee65953b",
"pins" : [
{
"identity" : "ably-cocoa",
Expand Down Expand Up @@ -36,6 +36,24 @@
"revision" : "41982a3656a71c768319979febd796c6fd111d5c",
"version" : "1.5.0"
}
},
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms",
"state" : {
"revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20",
"version" : "1.0.1"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d",
"version" : "1.1.2"
}
}
],
"version" : 3
Expand Down
12 changes: 12 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ let package = Package(
url: "https://github.com/apple/swift-argument-parser",
from: "1.5.0"
),
.package(
url: "https://github.com/apple/swift-async-algorithms",
from: "1.0.1"
),
],
targets: [
.target(
Expand Down Expand Up @@ -55,6 +59,10 @@ let package = Package(
name: "AblyChatTests",
dependencies: [
"AblyChat",
.product(
name: "AsyncAlgorithms",
package: "swift-async-algorithms"
),
]
),
.executableTarget(
Expand All @@ -64,6 +72,10 @@ let package = Package(
name: "ArgumentParser",
package: "swift-argument-parser"
),
.product(
name: "AsyncAlgorithms",
package: "swift-async-algorithms"
),
],
swiftSettings: [
// See justification above.
Expand Down
12 changes: 12 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ let package = Package(
url: "https://github.com/apple/swift-argument-parser",
from: "1.5.0"
),
.package(
url: "https://github.com/apple/swift-async-algorithms",
from: "1.0.1"
),
],
targets: [
.target(
Expand All @@ -41,6 +45,10 @@ let package = Package(
name: "AblyChatTests",
dependencies: [
"AblyChat",
.product(
name: "AsyncAlgorithms",
package: "swift-async-algorithms"
),
]
),
.executableTarget(
Expand All @@ -50,6 +58,10 @@ let package = Package(
name: "ArgumentParser",
package: "swift-argument-parser"
),
.product(
name: "AsyncAlgorithms",
package: "swift-async-algorithms"
),
]
),
]
Expand Down
11 changes: 11 additions & 0 deletions Sources/AblyChat/BufferingPolicy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,15 @@ public enum BufferingPolicy: Sendable {
case unbounded
case bufferingOldest(Int)
case bufferingNewest(Int)

internal func asAsyncStreamBufferingPolicy<T>() -> AsyncStream<T>.Continuation.BufferingPolicy {
switch self {
case let .bufferingNewest(count):
.bufferingNewest(count)
case let .bufferingOldest(count):
.bufferingOldest(count)
case .unbounded:
.unbounded
}
}
}
34 changes: 28 additions & 6 deletions Sources/AblyChat/Messages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,43 @@ public struct QueryOptionsWithoutDirection: Sendable {
public struct MessageSubscription: Sendable, AsyncSequence {
public typealias Element = Message

public init<T: AsyncSequence>(mockAsyncSequence _: T) where T.Element == Element {
fatalError("Not yet implemented")
private var subscription: Subscription<Element>

private var mockGetPreviousMessages: (@Sendable (QueryOptionsWithoutDirection) async throws -> any PaginatedResult<Message>)?

internal init(bufferingPolicy: BufferingPolicy) {
subscription = .init(bufferingPolicy: bufferingPolicy)
}

public init<T: AsyncSequence & Sendable>(mockAsyncSequence: T, mockGetPreviousMessages: @escaping @Sendable (QueryOptionsWithoutDirection) async throws -> any PaginatedResult<Message>) where T.Element == Element {
subscription = .init(mockAsyncSequence: mockAsyncSequence)
self.mockGetPreviousMessages = mockGetPreviousMessages
}

internal func emit(_ element: Element) {
subscription.emit(element)
}

public func getPreviousMessages(params _: QueryOptionsWithoutDirection) async throws -> any PaginatedResult<Message> {
fatalError("Not yet implemented")
public func getPreviousMessages(params: QueryOptionsWithoutDirection) async throws -> any PaginatedResult<Message> {
guard let mockImplementation = mockGetPreviousMessages else {
fatalError("Not yet implemented")
}
return try await mockImplementation(params)
}

public struct AsyncIterator: AsyncIteratorProtocol {
private var subscriptionIterator: Subscription<Element>.AsyncIterator

fileprivate init(subscriptionIterator: Subscription<Element>.AsyncIterator) {
self.subscriptionIterator = subscriptionIterator
}

public mutating func next() async -> Element? {
fatalError("Not implemented")
await subscriptionIterator.next()
}
}

public func makeAsyncIterator() -> AsyncIterator {
fatalError("Not implemented")
.init(subscriptionIterator: subscription.makeAsyncIterator())
}
}
Loading

0 comments on commit 1089a3a

Please sign in to comment.