Async{Throwing}Stream reimplementation

Currently, the onCancel parameter on the unfolding initializer is only invoked when the consumer’s task is cancelled. This differs from the continuation-based initializer. Despite the documentation claiming otherwise, the onTermination closure is, currently, invoked when any of the following occur: the finish or finish(throwing:) method is called, the consumer’s task is cancelled, or the stream goes out of scope.

My question is whether there is any interest, or concern about, including in the pitch an additional unfolding initializer with an onTermination parameter that behaves like the continuation-based variant. For example, something like this:

init(
  unfolding produce: @escaping @Sendable () async -> Element?,
  onTermination: (@Sendable () -> Void)? = nil
)

I’m currently writing the pitch (sorry for the delay), but I can’t come up with a good motivation section for adding Hashable conformance other than that it makes testing simpler, and that AsyncStream.Continuation.Termination already conforms to Hashable, so why not extend this to AsyncThrowingStream.Continuation.Termination as well, alongside typed throws.

Is there any interest in this, or a compelling reason to do it? Otherwise, I will just drop it.

Same reasoning for making anything Hashable: to use it with APIs that require Hashable, such as storage in a hash map structure. Is it required to then make AsyncStream itself Hashable?

If that reasoning is good enough, I will incorporate it. Haven’t thought at all about making Async{Throwing}Stream Hashable yet, but off the top of my head, I wouldn’t see a reason why we can't do it. Their Continuation types already conform to Hashable anyway.