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.
- Any change: minor changeset for
@dexpace/rx.
Part of the audit remediation umbrella #67. Milestone 3. Severity: MEDIUM (decision). Requirement: ASYNC-21.
Current SDK behavior
sseEvents$andtypedSse$(packages/rx/src/sse.ts:35,57-59) pass() => stream.close()as the
releaseargument offromAsyncIterable.from-async-iterable.ts:103-108runsreleaseon every termination: unsubscribe, end of source, and source error. ASYNC-21 saysthe adapter "MUST NOT close the caller-owned source on any termination".
pageItems$andpages$pass norelease. The Phase 8b checklist (:67) marks ASYNC-21 done with that clausedropped from the gist. Neither §10 nor
docs/deviations.mditem 16 records the departure.Expected behavior
One of the two, written down and tested:
SseStream. The caller who built the stream callsclose().Unsubscribing stops delivery but does not release the socket; the documentation says so.
deliberate deviation from ASYNC-21 in the Phase 8b ledger section and in
docs/deviations.md.Notes and leads
resource-leak risk onto the caller; document it in
docs/sdk-documentation/beside thefor awaitguidance.today. The cost is a ledger row and a corrected checklist gist.
asserting
stream.close()call count.@dexpace/rx.