diff --git a/_spec.ts b/_spec.ts index 4782eb3..e7908e0 100644 --- a/_spec.ts +++ b/_spec.ts @@ -154,10 +154,30 @@ export interface SpecObserver { * - Receives the subscription object as a parameter * - Runs before any other observer methods * - Allows the observer to store the subscription for later cancellation + * - Is intended for inspection or immediate cancellation, not for owning + * resources that need teardown * - Can throw exceptions, which are reported but don't prevent subscription * * If this method throws, the error is reported to the host environment * but the subscription is still established. + * + * Cleanup is sourced from the subscriber function's return value, not from + * `start()`. That means resources created in `start()` are outside the + * normal teardown path unless you arrange their cleanup elsewhere. + * + * In practice, that does not force this library to add new API surface. + * Callers that need to aggregate several cleanup steps can already return one + * function or one disposable object, including a `DisposableStack` or + * `AsyncDisposableStack`, from the subscriber body. That solves the cleanup + * aggregation problem. + * + * The nuance is that cleanup aggregation is not the same as cancellation + * propagation. A stack can collect teardown work to run when the + * subscription closes, but it does not replace a live cancellation channel + * like `AbortSignal`. The newer WICG Observable draft addresses both concerns + * together with a `Subscriber` object that exposes `signal` and + * `addTeardown()`. This library keeps the current return-a-teardown model + * rather than adopting that extra surface. * * @param subscription - The subscription object created by this subscribe call * @specref § 4.2 CreateSubscription diff --git a/_types.ts b/_types.ts index 52baada..26ce4b9 100644 --- a/_types.ts +++ b/_types.ts @@ -62,6 +62,15 @@ export interface Observer extends SpecObserver { * This override ensures the subscription passed to start() is our * enhanced Subscription type with additional properties and methods, * not just the minimal SpecSubscription. + * + * `start()` is best used for observing subscription setup or cancelling the + * subscription before the subscriber body runs. It is not a teardown + * registration point. Resources that need deterministic cleanup should be + * created in the subscriber body, where one returned teardown can already + * aggregate multiple cleanup steps, including disposable stacks when useful. + * That solves cleanup ownership, but it does not create a cancellation signal + * for in-flight async work, which is why this differs from the newer WICG + * `Subscriber` shape. * * @param subscription - Our enhanced Subscription object * @specref § 4.2 CreateSubscription