Makes me think perhaps moving to async sequences was not the right call. It's an inherited limitation. A simple callback-based observer would have solved the problem:
await object.values(for: \.someProperty) { value in
// Really important processing of the value
}
// guaranteed to have at least one observer from here on
Prepending the initial value to the async sequence does (indirectly) solve it too, but also complicates other matters. Since it needs to be an opt-in behavior, it will push the decision of getting the initial value to the user, which is error prone for multiple reasons (and also not what we want to achieve in the first place).
I guess another way to approach this and keep async sequences would be to have an explicit sendable observer:
let observer = await object.observe(\.someProperty)
// guaranteed to have at least one observer from here on
Task {
for await value in observer.values {
// Really important processing of the value
// Would receive the last value wrt to the point were observation started (possibly no value)
}
}
Needless to say both of these complicate the API, but I think the issue you described is valid and covering it should be at least considered for the initial iteration.