Actor Races

Try using AsyncStream as the queue (with for await in combineLatest on the streams of different typed elements) and the continuations as the operations, passing them to all the different potential call-sites.

Doing it this way around means it doesn't matter that AsyncSequence can only have one client, or that async funcs with multiple awaits suffer a re-entrency problem, or that streams aren't type erased.

This inversion reminds me of how we had to change our thinking when using values vs objects. Here is an example:

import SwiftUI
import AsyncAlgorithms
import ConcurrencyPlus

struct AsyncChannelTest {
    struct ContentView: View {
        @State var subject1 = AsyncSubject<Int>()
        @State var subject2 = AsyncSubject<String>()
        
        var body: some View {
            CounterView(subject: subject1)
            AppendView(subject: subject2)
                .task {
                    for await (i, s) in combineLatest(subject1, subject2) {
                        print("\(i) \(s)")
                    }
                }
        }
    }
    
    struct CounterView: View {
        @State var counter = 0
        let subject: AsyncSubject<Int>
        
        var body: some View {
            VStack {
                Button("Incrememnt \(counter)") {
                    counter += 1
                    subject.send(counter)
                }
            }
        }
    }
    
    struct AppendView: View {
        @State var text = ""
        let subject: AsyncSubject<String>
        
        var body: some View {
            VStack {
                Button("Append \(text)") {
                    text.append("a")
                    subject.send(text)
                }
            }
        }
    }
}

AsyncSubject is convenience for getting a continuation out of a stream's init closure, a workaround for this problem: `AsyncStream` constructor which also returns its Continuation