https://github.com/adam-zethraeus/swift-async-broadcaster
Swift async sequences supporting multiple subscribers
https://github.com/adam-zethraeus/swift-async-broadcaster
async-sequence broadcast multicast swift
Last synced: about 1 month ago
JSON representation
Swift async sequences supporting multiple subscribers
- Host: GitHub
- URL: https://github.com/adam-zethraeus/swift-async-broadcaster
- Owner: adam-zethraeus
- License: mit
- Created: 2025-03-31T16:21:27.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2025-04-01T18:45:44.000Z (about 2 months ago)
- Last Synced: 2025-04-01T19:33:13.653Z (about 2 months ago)
- Topics: async-sequence, broadcast, multicast, swift
- Language: Swift
- Homepage:
- Size: 20.5 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# AsyncBroadcaster
Broadcasting/Multicasting for Swift's AsyncSequences
Swift's `AsyncSequence` protocol backs the `for await value in stream { /* ... */ }` syntax.
This is an execllent pattern with an inexplicable flaw: multiple subscribers are unsupported by default.
It's up to the author of the async sequence's data source to ensure each consumer receives its own `AsyncIteratorProtocol` to iterate on — and neither the Swift language nor the official AsyncAlgorithms package provide operators which 'broadcast' an existing AsyncSequence.Async sequences created with `AsyncStream.makeStream(of:)` or with any of the operators from AsyncAlgorithms **can not emit to multiple subscribers**.
Instance of `AsyncBroadcaster`, whether created directly or through a call to `.broadcast()`, **can**.
## Features
- **Broadcast**: make an AsyncSequence safe for multiple subscribers.
- **Yield**: synchronously yield values to an AsyncBroadcaster.
- **Replay behavior**: Control how new subscribers receive past values
- `.none`: No replay
- `.latest(n)`: Replay up to n most recent values
- `.unbounded`: Replay all historical values## Installation
### Swift Package Manager
Add the following to your `Package.swift` file:
```swift
dependencies: [
.package(url: "https://github.com/adam-zethraeus/AsyncBroadcaster.git", from: "0.0.1")
]
```## Usage
### Basic Example
```swift
let stream = [1,2,3].async.broadcast()
let one = Task {
var result: [Int] = []
for await i in stream {
result.append(i)
}
return result
}await #expect(one.value == [1,2,3])
```### Synchronously emitting to a Broadcaster's Continuation
```swift
let channel = AsyncBroadcaster.makeAsyncBroadcaster(of: Int.self, replaying: .latest(3))let task1 = Task {
var results: [Int] = []
for await value in channel.stream {
results.append(value)
}
return results
}let task2 = Task {
var results: [Int] = []
for await value in channel.stream {
results.append(value)
}
return results
}try await Task.sleep(for: .milliseconds(100))
channel.continuation.yield(1)
channel.continuation.yield(2)
channel.continuation.yield(3)
channel.continuation.finish()
let results1 = await task1.value
let results2 = await task2.value#expect(results1 == [1, 2, 3])
#expect(results2 == [1, 2, 3])
```## License
MIT