feat: streaming client methods + types [AMB-3016] - #46
Draft
bufo24 wants to merge 1 commit into
Draft
Conversation
This was referenced Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
transactions.watch(id)andwallets.watchEvents(id)to@ambosstech/payments: mint a short-lived stream token via GraphQL, then open a plainfetch-basedtext/event-streamreader (noEventSource— works in Node and browsers), yielding the samePaymentEventshape webhooks already use.Transactions.watch(id, options?)→AsyncIterable<PaymentEvent>forGET /payments/stream/transactions/:id.Wallets.watchEvents(id, options?)→AsyncIterable<PaymentEvent>forGET /payments/stream/wallets/:id.watchPaymentEventStream(src/resources/streaming.ts) does mint → fetch → SSE-parse → yield for both;src/resources/sseParser.tsis a standalone, unit-testedtext/event-streamline parser (manualgetReader()/TextDecoderloop, portable to browsers).Authorization: Bearer <token>(not?token=) since afetch-based client can set headers, unlike browserEventSource— lower exposure than a query string per the design doc's own reasoning.ApiError(401/404 pre-stream HTTP rejection) /NetworkError(transport failure, malformed payload, or an abortedoptions.signal) — no new error type.stream_closedcontrol event (sent before the server closes a stream for a reason other than transaction-terminal state) ends iteration without being yielded as aPaymentEvent.Two unmerged cross-repo dependencies
amboss-rails-api#565(unmerged) — addspayment.mutation.stream_token.mint(input: MintStreamTokenInput!): StreamToken!to the live schema. This SDK's GraphQL codegen generates typed operations from a static checked-in schema snapshot refreshed only against live production, so it genuinely cannot generate types for a mutation that isn't deployed yet. The mint call is therefore hand-authored as a plain query string insrc/resources/streamToken.ts, with hand-written types insrc/resources/streamToken.types.ts— verified field-for-field againstschema.gqlin PR #565 (StreamTokenMutations.mint(input): StreamToken!,StreamToken { token, expires_at }, flat, not wrapped). Names match the eventual generated types exactly.pnpm --filter @ambosstech/core run refresh-schema && pnpm --filter @ambosstech/payments run codegen, then deletestreamToken.ts+streamToken.types.tsin favor of the generatedMintStreamTokenoperation. Both files carry aTODO(AMB-3016)marking this.amboss-rails-api#564(unmerged, design doc) — specifies the SSE endpoint contract this PR implements against:GET /payments/stream/{transactions,wallets}/:id?token=..., thetext/event-streamshape (mirrorsPaymentEventverbatim, no parallel type), 15s heartbeats, 60s token TTL / 30-minute max stream lifetime, and how each stream ends (transaction stream closes after a terminal status; wallet/environment stream has no terminal state and stays open until lifetime expiry or disconnect).Scope
Client methods + types only, per AMB-3016. Not included (separate tickets):
Test plan
pnpm build— passes (core then payments)pnpm typecheck— passespnpm test— passes, including new unit tests:src/resources/sseParser.test.ts— SSE line-parsing (id/event/data fields, multi-line data, heartbeat comments, chunk reassembly, multiple events, no-trailing-blank-line)src/resources/streaming.test.ts—Transactions.watch/Wallets.watchEventsend-to-end (mint → fetch → yield),stream_closedhandling, pre-stream 401 →ApiError, abortedsignal→NetworkErrorpnpm format:check— passes