Skip to content
This repository was archived by the owner on Oct 23, 2025. It is now read-only.

Commit 229f925

Browse files
feat: read session resumption
1 parent ada0af9 commit 229f925

File tree

8 files changed

+51
-20
lines changed

8 files changed

+51
-20
lines changed

.speakeasy/gen.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ management:
55
docVersion: 1.0.0
66
speakeasyVersion: 1.487.0
77
generationVersion: 2.506.0
8-
releaseVersion: 0.3.7
9-
configChecksum: cf61e0b559919d1742f2d4b5043ee292
8+
releaseVersion: 0.3.8
9+
configChecksum: f1f08ec2a1fe81cf49886a5f8d670405
1010
repoURL: https://github.com/s2-streamstore/s2-sdk-typescript.git
1111
installationURL: https://github.com/s2-streamstore/s2-sdk-typescript
1212
published: true

.speakeasy/gen.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ generation:
1616
oAuth2ClientCredentialsEnabled: true
1717
oAuth2PasswordEnabled: true
1818
typescript:
19-
version: 0.3.7
19+
version: 0.3.8
2020
additionalDependencies:
2121
dependencies:
2222
uuid: ^9.0.1

.speakeasy/workflow.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ speakeasyVersion: 1.487.0
22
sources:
33
S2 API:
44
sourceNamespace: s-2-api
5-
sourceRevisionDigest: sha256:2f76d85136855c3f3c58d4d97488242b1e51bfc3412801901f1d0cc127b8df6c
5+
sourceRevisionDigest: sha256:66a149fc312cb9f820ffd854f9309c69612ee8620c5dbde3c29c73dab3f04d36
66
sourceBlobDigest: sha256:eda67f586b78ceb1300a3662669e008175f0667b68ff804d4de23fcab20998d1
77
tags:
88
- latest
@@ -11,10 +11,10 @@ targets:
1111
streamstore:
1212
source: S2 API
1313
sourceNamespace: s-2-api
14-
sourceRevisionDigest: sha256:2f76d85136855c3f3c58d4d97488242b1e51bfc3412801901f1d0cc127b8df6c
14+
sourceRevisionDigest: sha256:66a149fc312cb9f820ffd854f9309c69612ee8620c5dbde3c29c73dab3f04d36
1515
sourceBlobDigest: sha256:eda67f586b78ceb1300a3662669e008175f0667b68ff804d4de23fcab20998d1
1616
codeSamplesNamespace: s-2-api-typescript-code-samples
17-
codeSamplesRevisionDigest: sha256:e1de59eedebdbc0f1ff721f1eb03212012f8b9e44ef4df4600cec80183b42221
17+
codeSamplesRevisionDigest: sha256:363ebcc961d9681148a7bae02a1f0173fc1642cbfd957e6ad6006636443da852
1818
workflow:
1919
workflowVersion: 1.0.0
2020
speakeasyVersion: latest

jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
{
44
"name": "@s2-dev/streamstore",
5-
"version": "0.3.7",
5+
"version": "0.3.8",
66
"exports": {
77
".": "./src/index.ts",
88
"./models/errors": "./src/models/errors/index.ts",

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@s2-dev/streamstore",
3-
"version": "0.3.7",
3+
"version": "0.3.8",
44
"author": "Speakeasy",
55
"main": "./index.js",
66
"sideEffects": false,

src/index.extras.ts

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import {
99
Output,
1010
ReadResponse,
1111
ReadResponseOutput,
12+
SequencedRecord,
13+
SequencedRecordBatch,
1214
StreamConfig,
1315
StreamInfo,
1416
} from "./models/components";
15-
import { NotFoundError } from "./models/errors";
17+
import { ErrorResponse, NotFoundError } from "./models/errors";
1618
import {
1719
GetBasinConfigRequest,
1820
ListBasinsRequest,
@@ -263,16 +265,20 @@ class Stream {
263265

264266
async *readStream(request: ReadRequest): AsyncGenerator<ReadResponse, void, undefined> {
265267
let currentRequest: ReadRequest = { ...request };
268+
let backoffMs = 100;
269+
const maxBackoffMs = 5000;
270+
const maxRetries = 5;
271+
let retryCount = 0;
266272

267273
while (true) {
268274
let stream: EventStream<ReadResponse> | undefined;
269275
try {
270276
const response = await this._stream.read(
271277
{ ...currentRequest, stream: this.streamName },
272-
{
273-
serverURL: this.basinURL,
274-
timeoutMs: -1, // disable only for streaming
275-
acceptHeaderOverride: ReadAcceptEnum.textEventStream
278+
{
279+
serverURL: this.basinURL,
280+
timeoutMs: -1, // disable only for streaming
281+
acceptHeaderOverride: ReadAcceptEnum.textEventStream
276282
}
277283
);
278284
stream = response.readResponse;
@@ -281,7 +287,7 @@ class Stream {
281287
for await (const event of stream) {
282288
yield event;
283289

284-
if (event.event === 'output') {
290+
if (event.event === 'message') {
285291
const output = event as ReadResponseOutput;
286292
if ('batch' in output.data) {
287293
const batch = output.data.batch;
@@ -291,18 +297,43 @@ class Stream {
291297
currentRequest = { ...currentRequest, startSeqNum: lastRecord.seqNum + 1 };
292298
}
293299
}
300+
if (currentRequest.limit) {
301+
if (currentRequest.limit.count != null) {
302+
currentRequest.limit.count = Math.max(0, currentRequest.limit.count - batch.records.length);
303+
}
304+
if (currentRequest.limit.bytes != null) {
305+
currentRequest.limit.bytes = Math.max(0, currentRequest.limit.bytes - meteredBatch(batch));
306+
}
307+
}
294308
}
295309
}
296310
}
297311
return;
298312
} catch (error) {
299-
console.error("Error while reading stream", error);
300-
return;
313+
if (error instanceof ErrorResponse || error instanceof NotFoundError) return;
314+
if (retryCount >= maxRetries) {
315+
throw error;
316+
}
317+
retryCount++;
318+
await new Promise(resolve => setTimeout(resolve, backoffMs));
319+
backoffMs = Math.min(backoffMs * 2, maxBackoffMs);
301320
}
302321
}
303322
}
304323
}
305324

325+
function meteredRecord(batch: SequencedRecord): number {
326+
const fixed = 8 + (2 * batch.headers.length);
327+
const headerSize = batch.headers.reduce((acc, header) => acc + header.name.length + header.value.length, 0);
328+
const bodySize = batch.body.length;
329+
330+
return fixed + headerSize + bodySize;
331+
}
332+
333+
function meteredBatch(batch: SequencedRecordBatch): number {
334+
return batch.records.reduce((acc, record) => acc + meteredRecord(record), 0);
335+
}
336+
306337
export function genS2RequestToken(): string {
307338
return v4().replace(/-/g, "");
308339
}

src/lib/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
5454
export const SDK_METADATA = {
5555
language: "typescript",
5656
openapiDocVersion: "1.0.0",
57-
sdkVersion: "0.3.7",
57+
sdkVersion: "0.3.8",
5858
genVersion: "2.506.0",
59-
userAgent: "speakeasy-sdk/typescript 0.3.7 2.506.0 1.0.0 @s2-dev/streamstore",
59+
userAgent: "speakeasy-sdk/typescript 0.3.8 2.506.0 1.0.0 @s2-dev/streamstore",
6060
} as const;

0 commit comments

Comments
 (0)