Release history
s2-streamstore/s2-sdk-typescript releases
Official MCP server for the S2.dev serverless stream platform.
All releases
27 shown
- CreateBasinInput.scope replaced by location
- EnsureBasinInput.scope replaced by location
- BasinInfo.scope replaced by location
- Adds `location` related RPCs
Full changelog
Minor Changes
-
5c0ed79: - refactor!: BasinScope now Location, and is free string instead of enum
- feat: adds
locationrelated RPCs
Breaking changes:
- CreateBasinInput.scope replaced by location
- EnsureBasinInput.scope replaced by location
- BasinInfo.scope replaced by location
- root export BasinScope removed and replaced by LocationName
- generated API.BasinScope no longer exists because the spec no longer has it
- feat: adds
- Adds `@s2-dev/resumable-stream/tanstack-ai` with `createResumableChat` for TanStack `StreamChunk` streams
- Adds `@s2-dev/resumable-stream/tanstack-ai/client` exposing `createS2Connection` for `useChat`
- Session mode stores TanStack stream chunks in S2, claims new turns from the tail, creates replay‑only in‑memory snapshots on first load, supports cursor resume, and provides opt‑in local generation stop via `enableStop`, `stopSession`, and `stopUrl`
Full changelog
Minor Changes
-
27806e1: Add TanStack AI helpers for S2-backed session replay:
@s2-dev/resumable-stream/tanstack-aiexposescreateResumableChatfor TanStackStreamChunkstreams.@s2-dev/resumable-stream/tanstack-ai/clientexposescreateS2ConnectionforuseChat.- Session mode stores TanStack stream chunks in S2, claims new turns from the stream tail, creates replay-only in-memory snapshots on first load, supports cursor resume, and provides opt-in local generation stop via
enableStop,stopSession, andstopUrl.
Minor fixes and improvements.
Changelog
Patch Changes
- 62698b8: Update readme
- Per‑stream encryption via `EncryptionKey`, `EncryptionAlgorithm`, and `EncryptionKeyInput` with basin-level `streamCipher` configuration
Full changelog
Minor Changes
- cdc822c: - Add stream encryption support to
@s2-dev/streamstore, including
EncryptionKey,EncryptionAlgorithm, andEncryptionKeyInput,
per-stream encryption keys viabasin.stream({ encryptionKey })andstream.withEncryptionKey(), and basin-levelstreamCipher
configuration.
Patch Changes
- e17c444: Treat truncated fetch SSE reads as retryable errors instead of silently ending the read session.
- makeResumable returns UIMessageChunk stream as SSE directly instead of JSON object
- replay no longer accepts fromSeqNum argument
- createS2Transport and S2TransportConfig removed; use DefaultChatTransport from ai package
Full changelog
Major Changes
-
7ea2cea: -
makeResumablenow returns theUIMessageChunkstream as SSE directly in the response body (previously returned JSON{ stream, fromSeqNum }). The source is teed: one branch streams to the client, the other persists to S2.replayno longer accepts afromSeqNumargument.createS2TransportandS2TransportConfigare removed. Usenew DefaultChatTransport({ api })fromai; the default reconnect URL (${api}/${chatId}/stream) matcheschat.replay(...). Customize viaprepareReconnectToStreamRequestif needed.- Error chunks no longer forward upstream error messages by default (previously leaked
err.messagedirectly). A newResumableChatConfig.onError?: (error: unknown) => stringlets callers opt into sanitized forwarding. Default emits the generic"An error occurred.". - Shared-mode streams now use a sliding liveness lease: if an active generation hasn't written any record (fence, data, or trim) for
leaseDurationMs(default 5 seconds), a new claim takes it over. Long-running generations that keep streaming are unaffected. The lease slides forward with every record, soleaseDurationMsis the maximum tolerated pause within a generation, not total generation duration. Previously, an abandoned non-terminal fence locked the stream forever. - Environment variable
S2_LINGER_DURATIONrenamed toS2_LINGER_DURATION_MS. Default dropped from 5000ms to 500ms on the genericcreateResumableStreamContextpath. The AI SDK path already defaults to 50ms. - Single-use streams now write a trim after the terminal fence at end-of-generation. Combined with
delete-on-emptyon the basin/stream config, completed single-use streams self-GC rather than piling up under the retention policy. Withoutdelete-on-empty, the stream is still emptied by the trim and will expire under the retention policy as before. - Single-use opening fences are appended with
matchSeqNum: 0, so a re-claim of the same stream name rejects with409even after the trim has propagated. The stream's tail seqnum stays above 0 until s2 GCs the stream entirely, which blocks accidental re-use of the same name. - Peer range for
airaised from>=4.0.0to>=5.0.0.
Migration:
// before const transport = createS2Transport({ api: "/api/chat", reconnectApi: "/api/chat/stream", }); // after import { DefaultChatTransport } from "ai"; const transport = new DefaultChatTransport({ api: "/api/chat" });The server-side
chat.makeResumable(...)andchat.replay(...)call sites are unchanged (both still return aResponse), but the GET reconnect route should be moved to/api/chat/[id]/streamto matchDefaultChatTransport's default shape.
Minor fixes and improvements.
Full changelog
Patch Changes
- 2d9d79c: misc bugfixes:
- Enforce 1 MiB minimum for maxInflightBytes (#129)
- Allow canSetUserAgentHeader in non-browser runtimes (#131)
- Respect backpressure in EventStream pull() (#161)
- Stop retry sessions promptly on cancel and abort (#162)
- Preserve non-plain objects in case conversion (#163)
- Skip command-only batches when ignoreCommandRecords enabled (#164)
- Propagate original Producer.close() errors instead of TypeError (#165)
- Cancel fetch transport iterators on early termination (#166)
- Reject endpoints with query strings or hash fragments (#167, #178)
- Fail blocked submits fast when close() races backpressure (#177)
- Wake idle RetryAppendSession pumps on abort() (#179)
- Release reader locks and cancel upstream on deserialize errors (#180)
- Validate S2S frame length to prevent parser desync (#182)
- Normalize deleteOnEmpty.minAgeSecs during reconfigure (#183)
- Allow iterator return()/throw() after stream exhaustion (#184)
- Fall back to manual S2S iterator when native async iteration throws (#184)
- Drop oversized framed records without crashing FrameAssembler (#192)
- Reject NaN and non-finite batch configuration values (#193)
- resumeStream returns null on session creation failure (#194)
- Validate fencing token length in AppendRecord.fence() (#195)
- Exclude path params from reconfigure request body (#196)
- Export BatchSubmitTicket as value, not type-only (#197)
Minor fixes and improvements.
Full changelog
Patch Changes
- 2d9d79c: misc bugfixes:
- Enforce 1 MiB minimum for maxInflightBytes (#129)
- Allow canSetUserAgentHeader in non-browser runtimes (#131)
- Respect backpressure in EventStream pull() (#161)
- Stop retry sessions promptly on cancel and abort (#162)
- Preserve non-plain objects in case conversion (#163)
- Skip command-only batches when ignoreCommandRecords enabled (#164)
- Propagate original Producer.close() errors instead of TypeError (#165)
- Cancel fetch transport iterators on early termination (#166)
- Reject endpoints with query strings or hash fragments (#167, #178)
- Fail blocked submits fast when close() races backpressure (#177)
- Wake idle RetryAppendSession pumps on abort() (#179)
- Release reader locks and cancel upstream on deserialize errors (#180)
- Validate S2S frame length to prevent parser desync (#182)
- Normalize deleteOnEmpty.minAgeSecs during reconfigure (#183)
- Allow iterator return()/throw() after stream exhaustion (#184)
- Fall back to manual S2S iterator when native async iteration throws (#184)
- Drop oversized framed records without crashing FrameAssembler (#192)
- Reject NaN and non-finite batch configuration values (#193)
- resumeStream returns null on session creation failure (#194)
- Validate fencing token length in AppendRecord.fence() (#195)
- Exclude path params from reconfigure request body (#196)
- Export BatchSubmitTicket as value, not type-only (#197)
Minor fixes and improvements.
Full changelog
Patch Changes
- 2d9d79c: misc bugfixes:
- Enforce 1 MiB minimum for maxInflightBytes (#129)
- Allow canSetUserAgentHeader in non-browser runtimes (#131)
- Respect backpressure in EventStream pull() (#161)
- Stop retry sessions promptly on cancel and abort (#162)
- Preserve non-plain objects in case conversion (#163)
- Skip command-only batches when ignoreCommandRecords enabled (#164)
- Propagate original Producer.close() errors instead of TypeError (#165)
- Cancel fetch transport iterators on early termination (#166)
- Reject endpoints with query strings or hash fragments (#167, #178)
- Fail blocked submits fast when close() races backpressure (#177)
- Wake idle RetryAppendSession pumps on abort() (#179)
- Release reader locks and cancel upstream on deserialize errors (#180)
- Validate S2S frame length to prevent parser desync (#182)
- Normalize deleteOnEmpty.minAgeSecs during reconfigure (#183)
- Allow iterator return()/throw() after stream exhaustion (#184)
- Fall back to manual S2S iterator when native async iteration throws (#184)
- Drop oversized framed records without crashing FrameAssembler (#192)
- Reject NaN and non-finite batch configuration values (#193)
- resumeStream returns null on session creation failure (#194)
- Validate fencing token length in AppendRecord.fence() (#195)
- Exclude path params from reconfigure request body (#196)
- Export BatchSubmitTicket as value, not type-only (#197)
- AI SDK durability support
Changelog
Patch Changes
- cb14923: feat: add AI SDK durability support
Fixed error propagation in BatchTransform.flush().
Changelog
Patch Changes
- af0ea65: bugfix: BatchTransform.flush() error propagation
- Added endpoint support for s2-lite
- Migrated internals to streamstore v2 SDK APIs
Full changelog
Patch Changes
- 362c138: Migrate internals to streamstore v2 SDK APIs and add endpoint support for s2-lite.
- Added Deno runtime support (fetch transports)
Changelog
Patch Changes
- bd3390f: Add Deno support (for fetch transports)
Fixed error message for status code 416.
Changelog
Patch Changes
- 843b6e4: Changes error message for 416 (#158)
Minor fixes and improvements.
Full changelog
Patch Changes
-
9f28893: - Improves decision tree for when to retry failed appends under
noSideEffectspolicy- Fixes a bug regarding duplicated acks after append session recovery
-
12f0903: Bug fixes:
- Fix
Producer.close()to be idempotent, preventing TypeError on concurrent calls (#90) - Freeze and unexport
Redactedprototype to prevent secret leakage (#91) - Re-check closed state after async transport creation in
readSession/appendSession(#96) - Check all pipelined entries for idempotency under
noSideEffectsretry policy (#135) - Fix
BatchTransformcancel hook, 0ms linger, controller init, and safe async flush (#136) - Use
AppendInput.createinSerializingAppendSession.writefor correctmeteredBytes(#137) - Await pending ack handlers before exiting
Producer.runPump(#138) - Prevent transport leak by caching creation promise in
S2Stream.getTransport(#140) - Use exact matching in
isConnectionErrorto prevent false positives (#141) - Clean up goaway and abort listeners in
S2SReadSessionto prevent memory leaks (#142) - Validate numeric inputs in
AppendRecord.trimandAppendInput.create(#143) - Fix
EventStreamfalsy value drops, missing return after done, and no-colon SSE parsing (#144) - Count connection failures toward
maxAttemptsinRetryAppendSession(#150) - Recompute
meteredBytesafter injecting dedupe headers (#151) - Add type guard before
inoperator to handle non-object error responses (#154)
- Fix
Fixed multiple reported bugs.
Changelog
Patch Changes
- d9a5707: bug fixes for #115, #114, #117, #116, #119, #118, #120
Fixed exclusion of Bun from HTTP/2 autodetection.
Changelog
Patch Changes
- 013dd0a: fix: exclude bun from http2 autodetection
Fixed ignoring of command records.
Changelog
Patch Changes
- fd5d960: fix: ignore command records
- Deprecated timeout settings under retry config; migrate to top-level connectionTimeoutMillis and requestTimeoutMillis.
- Default connection timeout reduced from 5000 ms to 3000 ms.
- basins.listAll() and streams.listAll() now accept includeDeleted via options object instead of as first positional argument
Full changelog
Patch Changes
- 792b99a: - Promote connectionTimeoutMillis and requestTimeoutMillis to top-level client options
- Deprecate timeout settings under retry config (backwards-compatible)
- Reduce default connection timeout from 5s to 3s
- Change basins.listAll() and streams.listAll() to accept includeDeleted in options object instead of as first positional argument
- Rename delay config options to clarify they apply to base delay
Minor fixes and improvements.
Changelog
Patch Changes
- 0105c3a: Bugfixes
Minor fixes and improvements.
Changelog
Patch Changes
- 0105c3a: Bugfixes
Fixed handling of HTTP 416 responses in the S2 read session.
Changelog
Minor Changes
- 1c13db6: Minor fix to handle 416 explicitly in s2s read session
- Public types are now SDK‑native (camelCase + Date); previously re‑exported generated snake_case wire types have been replaced.
- Wire‑format types moved behind the API: import from `@s2-dev/streamstore` rather than directly importing many snake_case types.
- Client endpoint configuration changed to use `S2ClientOptions.endpoints` / `S2Endpoints`; added `S2Environment.parse()` for env‑var config.
- Removed `retryBackoffDurationMillis` from retry config; replaced with `minDelayMillis`/`maxDelayMillis` and new `connectionTimeoutMillis`.
- Renamed and reshaped several public types: wire‑format snake_case imports are now behind the SDK's camelCase type layer (`import type { API } from "@s2-dev/streamstore"`).
- Stream append API changed from `S2Stream.append(records, {match_seq_num,fencing_token})` to `S2Stream.append(input: AppendInput)` with camelCase fields.
- Higher‑level Producer API with per‑record submit/ack interface using a configurable batcher over an append session.
- Protobuf content‑type used for unary data‑plane requests when appending or reading binary records (base64 still used for SSE read sessions).
- Explicit `S2Stream.close()` to trigger cleanup of shared transport and consolidated, documented SDK type layer including `AppendRecord` factories and `AppendInput.create(...)` validation.
Full changelog
Minor Changes
- 0d76a27: Adds a higher level Producer API which provides a per-record submit and ack interface (while using a configurable batcher over an append session)
- API standardization around append session, in particular by introducing a BatchSubmitTicket type
submit(batch)returnsPromise<BatchSubmitTicket>- this promise resolves only once a batch has been enqueued for submission in the session, and thus has received a deterministic ordering
- users can separately await the Promise returned by
BatchSubmitTicket.ack()to block on durability
- Switches to use of protobuf content-type for unary data plane requests when appending or reading binary records
- base64 is still used for SSE read sessions
- Allows explicit closing of an S2Stream, triggering cleanup of shared transport
- Introduces a consolidated, documented SDK type layer including
AppendRecordfactories andAppendInput.create(...)validation - Improves transport/mapping internals: dedicated case-conversion utilities, centralized mappers, and protobuf support for bytes paths
- Expanded docs/examples and test coverage (including retry/session and correctness-focused tests)
- API standardization around append session, in particular by introducing a BatchSubmitTicket type
Upgrade Notes
- Public types are now SDK-native (camelCase + Date): many previously re-exported generated (wire) types are replaced by new SDK types in
packages/streamstore/src/types.ts - Wire-format types moved behind API: instead of importing lots of snake_case types directly, use
import type { API } from "@s2-dev/streamstore" - Client endpoint config changed: use
S2ClientOptions.endpoints/S2Endpoints(andS2Environment.parse()was added for env var config) - Retry config renamed/changed:
retryBackoffDurationMillisis removed; replaced withminDelayMillis/maxDelayMillis(exponential backoff) and newconnectionTimeoutMillis(S2S transport only) - Stream append API changed:
S2Stream.append(records, { match_seq_num, fencing_token })→S2Stream.append(input: AppendInput)with camelCase fields- New validation helpers/constants:
AppendRecord.string/bytes(...),AppendInput.create(...) - String headers are no longer
Record<string,string>; use tuple arrays (ReadonlyArray<[string,string]>)
- Append session API changed:
AppendSession.submit(...)no longer returnsAppendAckdirectly; it returns aBatchSubmitTicketand you awaitticket.ack()to get the durableAppendAckAppendSession.writablenow acceptsAppendInput(notAppendArgs)
- Metrics API timestamps changed: start/end inputs accept Date or milliseconds; timeseries points in responses are now
[Date, number](not epoch seconds) - BatchTransform renamed/reshaped:
BatchTransformArgs→BatchTransformOptions,fencing_token/match_seq_num→ camelCase, and the transform output is now anAppendInput(not{ records, ... })
Minor fixes and improvements.
Changelog
Minor Changes
- Updated dependencies [0d76a27]
- @s2-dev/[email protected]