You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As in 8be3aed. Cursor struggled a bit when porting the JS tests, not
considering some Swift concurrency subtleties (the fact that `async let`
or `Task` tasks do not have any "synchronous part" thus needing to be
careful about not missing events, same as in c75fa2a, and the lack of
any ordering guarantees when triggering `Task`s), so I introduced the
Subscription.addListener and MainActorStorage types to perform more work
synchronously to be in line with the JS tests.
@@ -39,13 +40,50 @@ final class Subscriber<each CallbackArg: Sendable>: Sendable {
39
40
guardlet self else{
40
41
return
41
42
}
42
-
mutex.withLock{
43
+
letcallListeners=mutex.withLock{
43
44
letinvocation=(repeateach arg)
44
45
invocations.append(invocation)
46
+
47
+
return{[listeners]in
48
+
forlistenerin listeners {
49
+
listener.callAsFunction(repeateach invocation)
50
+
}
51
+
}
45
52
}
46
53
iflet action {
47
54
action(repeateach arg)
48
55
}
56
+
callListeners()
49
57
}
50
58
}
59
+
60
+
/// A wrapper that allows us to store a callback that takes variadic args.
61
+
///
62
+
/// This allows us to avoid the error "Cannot fully abstract a value of variadic function type '@Sendable (repeat each CallbackArg) -> ()' because different contexts will not be able to reliably agree on a calling convention; try wrapping it in a struct" that we get if we try to directly store the callback in an array. Claude suggested this solution.
/// Adds a listener which replays all previously buffered and future invocations of any function previously created by ``createListener(_:)``.
72
+
///
73
+
/// This is useful for the scenario where you want to set up a subscription synchronously (so as not to miss any events) but then in an `async` context perform actions as a result of the invocation of the listener. (You could equally use the SDK's `AsyncSequence` interface but the approach here is a closer mapping of the ported JS integration tests that call `subscribe`.)
0 commit comments