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
{{ message }}
Repository navigation
RxJS SSE ownership: sseEvents$ and the caller-owned stream #75
Part of the audit remediation umbrella #67. Milestone 3. Severity: MEDIUM (decision). Requirement: ASYNC-21.
Current SDK behavior
sseEvents$ and typedSse$ (packages/rx/src/sse.ts:35,57-59) pass () => stream.close()
as the release argument of fromAsyncIterable. from-async-iterable.ts:103-108 runs release on every termination: unsubscribe, end of source, and source error. ASYNC-21 says
the adapter "MUST NOT close the caller-owned source on any termination". pageItems$ and pages$ pass no release. The Phase 8b checklist (:67) marks ASYNC-21 done with that clause
dropped from the gist. Neither §10 nor docs/deviations.md item 16 records the departure.
Expected behavior
One of the two, written down and tested:
The adapter does not close the SseStream. The caller who built the stream calls close().
Unsubscribing stops delivery but does not release the socket; the documentation says so.
The adapter takes ownership and closes on every termination, and this is recorded as a
deliberate deviation from ASYNC-21 in the Phase 8b ledger section and in docs/deviations.md.
Notes and leads
The spec-faithful option is a one-line change and makes SSE match pagination. It moves a
resource-leak risk onto the caller; document it in docs/sdk-documentation/ beside the for await guidance.
The ownership-transfer option is more convenient for RxJS users and is what the code does
today. The cost is a ledger row and a corrected checklist gist.
Test either outcome: a subscription that is unsubscribed early, and a source that errors,
asserting stream.close() call count.
Activity
test(node): the retry trail case moves from "same wrapper" to "no wra…
Wahbeh-Mohammad commentedon Sep 5, 2026
Addressed in PR #87, merged into
audit/remediation-67; reachesmvpthrough PR #98. Decision record:docs/audit-67-decisions.md.