@s2-dev/streamstore 0.3.9 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -12
- package/docs/sdks/account/README.md +38 -35
- package/docs/sdks/basin/README.md +38 -35
- package/docs/sdks/stream/README.md +22 -27
- package/funcs/accountCreateBasin.d.ts +2 -1
- package/funcs/accountCreateBasin.d.ts.map +1 -1
- package/funcs/accountCreateBasin.js +3 -4
- package/funcs/accountCreateBasin.js.map +1 -1
- package/funcs/accountDeleteBasin.d.ts +1 -1
- package/funcs/accountDeleteBasin.d.ts.map +1 -1
- package/funcs/accountDeleteBasin.js +3 -2
- package/funcs/accountDeleteBasin.js.map +1 -1
- package/funcs/accountGetBasinConfig.d.ts +2 -1
- package/funcs/accountGetBasinConfig.d.ts.map +1 -1
- package/funcs/accountGetBasinConfig.js +3 -4
- package/funcs/accountGetBasinConfig.js.map +1 -1
- package/funcs/accountListBasins.d.ts +1 -1
- package/funcs/accountListBasins.d.ts.map +1 -1
- package/funcs/accountListBasins.js +2 -4
- package/funcs/accountListBasins.js.map +1 -1
- package/funcs/accountReconfigureBasin.d.ts +2 -1
- package/funcs/accountReconfigureBasin.d.ts.map +1 -1
- package/funcs/accountReconfigureBasin.js +3 -4
- package/funcs/accountReconfigureBasin.js.map +1 -1
- package/funcs/basinCreateStream.d.ts +2 -1
- package/funcs/basinCreateStream.d.ts.map +1 -1
- package/funcs/basinCreateStream.js +14 -4
- package/funcs/basinCreateStream.js.map +1 -1
- package/funcs/basinDeleteStream.d.ts +1 -1
- package/funcs/basinDeleteStream.d.ts.map +1 -1
- package/funcs/basinDeleteStream.js +3 -2
- package/funcs/basinDeleteStream.js.map +1 -1
- package/funcs/basinGetStreamConfig.d.ts +2 -1
- package/funcs/basinGetStreamConfig.d.ts.map +1 -1
- package/funcs/basinGetStreamConfig.js +3 -4
- package/funcs/basinGetStreamConfig.js.map +1 -1
- package/funcs/basinListStreams.d.ts +1 -1
- package/funcs/basinListStreams.d.ts.map +1 -1
- package/funcs/basinListStreams.js +3 -3
- package/funcs/basinListStreams.js.map +1 -1
- package/funcs/basinReconfigureStream.d.ts +2 -1
- package/funcs/basinReconfigureStream.d.ts.map +1 -1
- package/funcs/basinReconfigureStream.js +3 -4
- package/funcs/basinReconfigureStream.js.map +1 -1
- package/funcs/streamAppend.d.ts +2 -1
- package/funcs/streamAppend.d.ts.map +1 -1
- package/funcs/streamAppend.js +3 -4
- package/funcs/streamAppend.js.map +1 -1
- package/funcs/streamCheckTail.d.ts +2 -1
- package/funcs/streamCheckTail.d.ts.map +1 -1
- package/funcs/streamCheckTail.js +3 -4
- package/funcs/streamCheckTail.js.map +1 -1
- package/funcs/streamRead.d.ts +1 -1
- package/funcs/streamRead.d.ts.map +1 -1
- package/funcs/streamRead.js +2 -2
- package/funcs/streamRead.js.map +1 -1
- package/index.extras.d.ts +16 -5
- package/index.extras.d.ts.map +1 -1
- package/index.extras.js +89 -26
- package/index.extras.js.map +1 -1
- package/jsr.json +1 -1
- package/lib/config.d.ts +2 -2
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +2 -2
- package/lib/config.js.map +1 -1
- package/lib/matchers.d.ts +1 -1
- package/lib/matchers.d.ts.map +1 -1
- package/lib/matchers.js +11 -10
- package/lib/matchers.js.map +1 -1
- package/models/components/index.d.ts +0 -1
- package/models/components/index.d.ts.map +1 -1
- package/models/components/index.js +0 -1
- package/models/components/index.js.map +1 -1
- package/models/errors/apierror.d.ts +5 -8
- package/models/errors/apierror.d.ts.map +1 -1
- package/models/errors/apierror.js +9 -3
- package/models/errors/apierror.js.map +1 -1
- package/models/errors/index.d.ts +1 -0
- package/models/errors/index.d.ts.map +1 -1
- package/models/errors/index.js +1 -0
- package/models/errors/index.js.map +1 -1
- package/models/errors/retryableerror.d.ts +31 -0
- package/models/errors/retryableerror.d.ts.map +1 -0
- package/models/errors/retryableerror.js +77 -0
- package/models/errors/retryableerror.js.map +1 -0
- package/models/operations/append.d.ts +0 -27
- package/models/operations/append.d.ts.map +1 -1
- package/models/operations/append.js +1 -40
- package/models/operations/append.js.map +1 -1
- package/models/operations/checktail.d.ts +0 -28
- package/models/operations/checktail.d.ts.map +1 -1
- package/models/operations/checktail.js +1 -42
- package/models/operations/checktail.js.map +1 -1
- package/models/operations/createbasin.d.ts +0 -27
- package/models/operations/createbasin.d.ts.map +1 -1
- package/models/operations/createbasin.js +1 -40
- package/models/operations/createbasin.js.map +1 -1
- package/models/operations/createstream.d.ts +0 -27
- package/models/operations/createstream.d.ts.map +1 -1
- package/models/operations/createstream.js +1 -40
- package/models/operations/createstream.js.map +1 -1
- package/models/operations/deletebasin.d.ts +0 -26
- package/models/operations/deletebasin.d.ts.map +1 -1
- package/models/operations/deletebasin.js +1 -38
- package/models/operations/deletebasin.js.map +1 -1
- package/models/operations/deletestream.d.ts +0 -26
- package/models/operations/deletestream.d.ts.map +1 -1
- package/models/operations/deletestream.js +1 -38
- package/models/operations/deletestream.js.map +1 -1
- package/models/operations/getbasinconfig.d.ts +0 -28
- package/models/operations/getbasinconfig.d.ts.map +1 -1
- package/models/operations/getbasinconfig.js +1 -42
- package/models/operations/getbasinconfig.js.map +1 -1
- package/models/operations/getstreamconfig.d.ts +0 -28
- package/models/operations/getstreamconfig.d.ts.map +1 -1
- package/models/operations/getstreamconfig.js +1 -42
- package/models/operations/getstreamconfig.js.map +1 -1
- package/models/operations/listbasins.d.ts +2 -4
- package/models/operations/listbasins.d.ts.map +1 -1
- package/models/operations/listbasins.js +4 -8
- package/models/operations/listbasins.js.map +1 -1
- package/models/operations/liststreams.d.ts +2 -4
- package/models/operations/liststreams.d.ts.map +1 -1
- package/models/operations/liststreams.js +4 -8
- package/models/operations/liststreams.js.map +1 -1
- package/models/operations/read.d.ts +2 -10
- package/models/operations/read.d.ts.map +1 -1
- package/models/operations/read.js +6 -23
- package/models/operations/read.js.map +1 -1
- package/models/operations/reconfigurebasin.d.ts +0 -27
- package/models/operations/reconfigurebasin.d.ts.map +1 -1
- package/models/operations/reconfigurebasin.js +1 -40
- package/models/operations/reconfigurebasin.js.map +1 -1
- package/models/operations/reconfigurestream.d.ts +0 -27
- package/models/operations/reconfigurestream.d.ts.map +1 -1
- package/models/operations/reconfigurestream.js +1 -40
- package/models/operations/reconfigurestream.js.map +1 -1
- package/package.json +1 -1
- package/sdk/account.d.ts +5 -4
- package/sdk/account.d.ts.map +1 -1
- package/sdk/account.js.map +1 -1
- package/sdk/basin.d.ts +5 -4
- package/sdk/basin.d.ts.map +1 -1
- package/sdk/basin.js.map +1 -1
- package/sdk/stream.d.ts +3 -2
- package/sdk/stream.d.ts.map +1 -1
- package/sdk/stream.js.map +1 -1
- package/src/funcs/accountCreateBasin.ts +12 -10
- package/src/funcs/accountDeleteBasin.ts +12 -8
- package/src/funcs/accountGetBasinConfig.ts +12 -10
- package/src/funcs/accountListBasins.ts +11 -9
- package/src/funcs/accountReconfigureBasin.ts +12 -10
- package/src/funcs/basinCreateStream.ts +23 -10
- package/src/funcs/basinDeleteStream.ts +12 -8
- package/src/funcs/basinGetStreamConfig.ts +12 -10
- package/src/funcs/basinListStreams.ts +11 -7
- package/src/funcs/basinReconfigureStream.ts +12 -10
- package/src/funcs/streamAppend.ts +12 -10
- package/src/funcs/streamCheckTail.ts +12 -10
- package/src/funcs/streamRead.ts +10 -7
- package/src/index.extras.ts +170 -52
- package/src/lib/config.ts +3 -2
- package/src/lib/matchers.ts +16 -10
- package/src/models/components/index.ts +0 -1
- package/src/models/errors/apierror.ts +13 -7
- package/src/models/errors/index.ts +1 -0
- package/src/models/errors/retryableerror.ts +69 -0
- package/src/models/operations/append.ts +0 -68
- package/src/models/operations/checktail.ts +0 -74
- package/src/models/operations/createbasin.ts +0 -72
- package/src/models/operations/createstream.ts +0 -72
- package/src/models/operations/deletebasin.ts +0 -68
- package/src/models/operations/deletestream.ts +0 -68
- package/src/models/operations/getbasinconfig.ts +0 -74
- package/src/models/operations/getstreamconfig.ts +0 -74
- package/src/models/operations/listbasins.ts +6 -12
- package/src/models/operations/liststreams.ts +6 -12
- package/src/models/operations/read.ts +10 -33
- package/src/models/operations/reconfigurebasin.ts +0 -72
- package/src/models/operations/reconfigurestream.ts +0 -72
- package/src/sdk/account.ts +5 -4
- package/src/sdk/basin.ts +5 -4
- package/src/sdk/stream.ts +3 -2
- package/models/components/httpmetadata.d.ts +0 -37
- package/models/components/httpmetadata.d.ts.map +0 -1
- package/models/components/httpmetadata.js +0 -86
- package/models/components/httpmetadata.js.map +0 -1
- package/src/models/components/httpmetadata.ts +0 -87
|
@@ -10,6 +10,7 @@ import { safeParse } from "../lib/schemas.js";
|
|
|
10
10
|
import { RequestOptions } from "../lib/sdks.js";
|
|
11
11
|
import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js";
|
|
12
12
|
import { pathToFunc } from "../lib/url.js";
|
|
13
|
+
import * as components from "../models/components/index.js";
|
|
13
14
|
import { APIError } from "../models/errors/apierror.js";
|
|
14
15
|
import {
|
|
15
16
|
ConnectionError,
|
|
@@ -36,9 +37,10 @@ export async function streamAppend(
|
|
|
36
37
|
options?: RequestOptions,
|
|
37
38
|
): Promise<
|
|
38
39
|
Result<
|
|
39
|
-
|
|
40
|
-
| errors.ErrorResponse
|
|
40
|
+
components.AppendOutput,
|
|
41
41
|
| errors.ErrorResponse
|
|
42
|
+
| errors.RetryableError
|
|
43
|
+
| errors.RetryableError
|
|
42
44
|
| APIError
|
|
43
45
|
| SDKValidationError
|
|
44
46
|
| UnexpectedClientError
|
|
@@ -115,7 +117,7 @@ export async function streamAppend(
|
|
|
115
117
|
|
|
116
118
|
const doResult = await client._do(req, {
|
|
117
119
|
context,
|
|
118
|
-
errorCodes: ["400", "401", "404", "4XX", "500", "5XX"],
|
|
120
|
+
errorCodes: ["400", "401", "404", "499", "4XX", "500", "503", "504", "5XX"],
|
|
119
121
|
retryConfig: context.retryConfig,
|
|
120
122
|
retryCodes: context.retryCodes,
|
|
121
123
|
});
|
|
@@ -129,9 +131,10 @@ export async function streamAppend(
|
|
|
129
131
|
};
|
|
130
132
|
|
|
131
133
|
const [result] = await M.match<
|
|
132
|
-
|
|
133
|
-
| errors.ErrorResponse
|
|
134
|
+
components.AppendOutput,
|
|
134
135
|
| errors.ErrorResponse
|
|
136
|
+
| errors.RetryableError
|
|
137
|
+
| errors.RetryableError
|
|
135
138
|
| APIError
|
|
136
139
|
| SDKValidationError
|
|
137
140
|
| UnexpectedClientError
|
|
@@ -140,14 +143,13 @@ export async function streamAppend(
|
|
|
140
143
|
| RequestTimeoutError
|
|
141
144
|
| ConnectionError
|
|
142
145
|
>(
|
|
143
|
-
M.json(200,
|
|
144
|
-
key: "AppendOutput",
|
|
145
|
-
}),
|
|
146
|
+
M.json(200, components.AppendOutput$inboundSchema),
|
|
146
147
|
M.jsonErr([400, 401, 404], errors.ErrorResponse$inboundSchema),
|
|
147
|
-
M.jsonErr(
|
|
148
|
+
M.jsonErr(499, errors.RetryableError$inboundSchema),
|
|
149
|
+
M.jsonErr([500, 503, 504], errors.RetryableError$inboundSchema),
|
|
148
150
|
M.fail("4XX"),
|
|
149
151
|
M.fail("5XX"),
|
|
150
|
-
)(response,
|
|
152
|
+
)(response, { extraFields: responseFields });
|
|
151
153
|
if (!result.ok) {
|
|
152
154
|
return result;
|
|
153
155
|
}
|
|
@@ -10,6 +10,7 @@ import { safeParse } from "../lib/schemas.js";
|
|
|
10
10
|
import { RequestOptions } from "../lib/sdks.js";
|
|
11
11
|
import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js";
|
|
12
12
|
import { pathToFunc } from "../lib/url.js";
|
|
13
|
+
import * as components from "../models/components/index.js";
|
|
13
14
|
import { APIError } from "../models/errors/apierror.js";
|
|
14
15
|
import {
|
|
15
16
|
ConnectionError,
|
|
@@ -36,9 +37,10 @@ export async function streamCheckTail(
|
|
|
36
37
|
options?: RequestOptions,
|
|
37
38
|
): Promise<
|
|
38
39
|
Result<
|
|
39
|
-
|
|
40
|
-
| errors.ErrorResponse
|
|
40
|
+
components.CheckTailResponse,
|
|
41
41
|
| errors.ErrorResponse
|
|
42
|
+
| errors.RetryableError
|
|
43
|
+
| errors.RetryableError
|
|
42
44
|
| APIError
|
|
43
45
|
| SDKValidationError
|
|
44
46
|
| UnexpectedClientError
|
|
@@ -110,7 +112,7 @@ export async function streamCheckTail(
|
|
|
110
112
|
|
|
111
113
|
const doResult = await client._do(req, {
|
|
112
114
|
context,
|
|
113
|
-
errorCodes: ["400", "401", "404", "4XX", "500", "5XX"],
|
|
115
|
+
errorCodes: ["400", "401", "404", "499", "4XX", "500", "503", "504", "5XX"],
|
|
114
116
|
retryConfig: context.retryConfig,
|
|
115
117
|
retryCodes: context.retryCodes,
|
|
116
118
|
});
|
|
@@ -124,9 +126,10 @@ export async function streamCheckTail(
|
|
|
124
126
|
};
|
|
125
127
|
|
|
126
128
|
const [result] = await M.match<
|
|
127
|
-
|
|
128
|
-
| errors.ErrorResponse
|
|
129
|
+
components.CheckTailResponse,
|
|
129
130
|
| errors.ErrorResponse
|
|
131
|
+
| errors.RetryableError
|
|
132
|
+
| errors.RetryableError
|
|
130
133
|
| APIError
|
|
131
134
|
| SDKValidationError
|
|
132
135
|
| UnexpectedClientError
|
|
@@ -135,14 +138,13 @@ export async function streamCheckTail(
|
|
|
135
138
|
| RequestTimeoutError
|
|
136
139
|
| ConnectionError
|
|
137
140
|
>(
|
|
138
|
-
M.json(200,
|
|
139
|
-
key: "CheckTailResponse",
|
|
140
|
-
}),
|
|
141
|
+
M.json(200, components.CheckTailResponse$inboundSchema),
|
|
141
142
|
M.jsonErr([400, 401, 404], errors.ErrorResponse$inboundSchema),
|
|
142
|
-
M.jsonErr(
|
|
143
|
+
M.jsonErr(499, errors.RetryableError$inboundSchema),
|
|
144
|
+
M.jsonErr([500, 503, 504], errors.RetryableError$inboundSchema),
|
|
143
145
|
M.fail("4XX"),
|
|
144
146
|
M.fail("5XX"),
|
|
145
|
-
)(response,
|
|
147
|
+
)(response, { extraFields: responseFields });
|
|
146
148
|
if (!result.ok) {
|
|
147
149
|
return result;
|
|
148
150
|
}
|
package/src/funcs/streamRead.ts
CHANGED
|
@@ -43,7 +43,8 @@ export async function streamRead(
|
|
|
43
43
|
Result<
|
|
44
44
|
operations.ReadResponse,
|
|
45
45
|
| errors.ErrorResponse
|
|
46
|
-
| errors.
|
|
46
|
+
| errors.RetryableError
|
|
47
|
+
| errors.RetryableError
|
|
47
48
|
| APIError
|
|
48
49
|
| SDKValidationError
|
|
49
50
|
| UnexpectedClientError
|
|
@@ -126,7 +127,7 @@ export async function streamRead(
|
|
|
126
127
|
|
|
127
128
|
const doResult = await client._do(req, {
|
|
128
129
|
context,
|
|
129
|
-
errorCodes: ["400", "401", "404", "4XX", "500", "5XX"],
|
|
130
|
+
errorCodes: ["400", "401", "404", "499", "4XX", "500", "503", "504", "5XX"],
|
|
130
131
|
retryConfig: context.retryConfig,
|
|
131
132
|
retryCodes: context.retryCodes,
|
|
132
133
|
});
|
|
@@ -142,7 +143,8 @@ export async function streamRead(
|
|
|
142
143
|
const [result] = await M.match<
|
|
143
144
|
operations.ReadResponse,
|
|
144
145
|
| errors.ErrorResponse
|
|
145
|
-
| errors.
|
|
146
|
+
| errors.RetryableError
|
|
147
|
+
| errors.RetryableError
|
|
146
148
|
| APIError
|
|
147
149
|
| SDKValidationError
|
|
148
150
|
| UnexpectedClientError
|
|
@@ -151,13 +153,14 @@ export async function streamRead(
|
|
|
151
153
|
| RequestTimeoutError
|
|
152
154
|
| ConnectionError
|
|
153
155
|
>(
|
|
154
|
-
M.json(200, operations.ReadResponse$inboundSchema
|
|
155
|
-
M.sse(200, operations.ReadResponse$inboundSchema
|
|
156
|
+
M.json(200, operations.ReadResponse$inboundSchema),
|
|
157
|
+
M.sse(200, operations.ReadResponse$inboundSchema),
|
|
156
158
|
M.jsonErr([400, 401, 404], errors.ErrorResponse$inboundSchema),
|
|
157
|
-
M.jsonErr(
|
|
159
|
+
M.jsonErr(499, errors.RetryableError$inboundSchema),
|
|
160
|
+
M.jsonErr([500, 503, 504], errors.RetryableError$inboundSchema),
|
|
158
161
|
M.fail("4XX"),
|
|
159
162
|
M.fail("5XX"),
|
|
160
|
-
)(response,
|
|
163
|
+
)(response, { extraFields: responseFields });
|
|
161
164
|
if (!result.ok) {
|
|
162
165
|
return result;
|
|
163
166
|
}
|
package/src/index.extras.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
StreamConfig,
|
|
15
15
|
StreamInfo,
|
|
16
16
|
} from "./models/components";
|
|
17
|
-
import {
|
|
17
|
+
import { NotFoundError, RetryableError } from "./models/errors";
|
|
18
18
|
import {
|
|
19
19
|
GetBasinConfigRequest,
|
|
20
20
|
ListBasinsRequest,
|
|
@@ -37,6 +37,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
37
37
|
import { basinDeleteStream } from "./funcs/basinDeleteStream";
|
|
38
38
|
import { EventStream } from "./lib/event-streams";
|
|
39
39
|
import { ClientKind, S2Cloud, S2Endpoints } from "./endpoints";
|
|
40
|
+
import { HTTPClient } from "./lib/http";
|
|
40
41
|
|
|
41
42
|
export type ReadRequest = Omit<ReadRequestInner, "stream">;
|
|
42
43
|
export type AppendRequest = Omit<AppendRequestInner, "stream">;
|
|
@@ -64,19 +65,39 @@ export * from "./endpoints";
|
|
|
64
65
|
|
|
65
66
|
export type S2ClientConfig = {
|
|
66
67
|
authToken?: string;
|
|
68
|
+
userAgent?: string;
|
|
67
69
|
requestTimeout?: number;
|
|
68
70
|
endpoints?: S2Endpoints;
|
|
71
|
+
appedRetryPolicy?: AppendRetryPolicy;
|
|
72
|
+
maxRetries?: number;
|
|
73
|
+
initialBackoffMs?: number;
|
|
74
|
+
maxBackoffMs?: number;
|
|
75
|
+
httpClient?: HTTPClient;
|
|
69
76
|
};
|
|
70
77
|
|
|
78
|
+
export enum AppendRetryPolicy {
|
|
79
|
+
All,
|
|
80
|
+
NoSideEffects,
|
|
81
|
+
}
|
|
82
|
+
|
|
71
83
|
const defaultS2ClientConfig: S2ClientConfig = {
|
|
72
84
|
requestTimeout: 3000,
|
|
73
85
|
endpoints: S2Endpoints.forCloud(S2Cloud.Aws),
|
|
86
|
+
appedRetryPolicy: AppendRetryPolicy.All,
|
|
87
|
+
httpClient: new HTTPClient({
|
|
88
|
+
fetcher: async (request) => fetch(request),
|
|
89
|
+
}),
|
|
74
90
|
};
|
|
75
91
|
|
|
92
|
+
|
|
76
93
|
export class S2Client {
|
|
77
94
|
private config: S2ClientConfig;
|
|
78
|
-
private _account?: S2Account;
|
|
95
|
+
private _account?: S2Account;
|
|
96
|
+
|
|
79
97
|
get account(): S2Account {
|
|
98
|
+
// this.httpClient.addHook("beforeRequest", (request) => {
|
|
99
|
+
// if (this.config.userAgent) request.headers.set("User-Agent", this.config.userAgent);
|
|
100
|
+
// });
|
|
80
101
|
return (this._account ??= new S2Account(this.config));
|
|
81
102
|
}
|
|
82
103
|
|
|
@@ -96,9 +117,16 @@ class S2Account {
|
|
|
96
117
|
private readonly accountURLSuffx = "/v1alpha";
|
|
97
118
|
|
|
98
119
|
constructor(config: S2ClientConfig) {
|
|
120
|
+
if (config.userAgent !== undefined) {
|
|
121
|
+
config.httpClient?.addHook("beforeRequest", (request) => {
|
|
122
|
+
request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
|
|
123
|
+
console.log(request)
|
|
124
|
+
});
|
|
125
|
+
}
|
|
99
126
|
this._account = new InnerAccount({
|
|
100
127
|
...(config.authToken !== undefined && { bearerAuth: config.authToken }),
|
|
101
|
-
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout })
|
|
128
|
+
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout }),
|
|
129
|
+
...(config.httpClient !== undefined && { httpClient: config.httpClient }),
|
|
102
130
|
});
|
|
103
131
|
this.config = config;
|
|
104
132
|
}
|
|
@@ -106,7 +134,7 @@ class S2Account {
|
|
|
106
134
|
get URL(): string | undefined {
|
|
107
135
|
if (!this.config.endpoints) return undefined;
|
|
108
136
|
return `https://${ClientKind.toAuthority({ kind: "Account" }, this.config.endpoints)}${this.accountURLSuffx}`;
|
|
109
|
-
}
|
|
137
|
+
}
|
|
110
138
|
|
|
111
139
|
basin(basinName: string): S2Basin {
|
|
112
140
|
return new S2Basin(basinName, this.config);
|
|
@@ -116,15 +144,23 @@ class S2Account {
|
|
|
116
144
|
request?: ListBasinsRequest
|
|
117
145
|
): Promise<PageIterator<ListBasinsResponse, { cursor: string }>> {
|
|
118
146
|
const url = this.URL;
|
|
119
|
-
return
|
|
147
|
+
return retryWithExponentialBackoff(
|
|
148
|
+
() => this._account.listBasins(request ?? {}, url ? { serverURL: url } : {}),
|
|
149
|
+
this.config.maxRetries,
|
|
150
|
+
this.config.initialBackoffMs,
|
|
151
|
+
this.config.maxBackoffMs
|
|
152
|
+
);
|
|
120
153
|
}
|
|
121
154
|
|
|
122
155
|
async getBasinConfig(basin: string): Promise<BasinConfig | undefined> {
|
|
123
156
|
const _request: GetBasinConfigRequest = { basin };
|
|
124
157
|
const url = this.URL;
|
|
125
|
-
return (
|
|
126
|
-
, url ? { serverURL: url } : {}
|
|
127
|
-
|
|
158
|
+
return retryWithExponentialBackoff(
|
|
159
|
+
() => this._account.getBasinConfig(_request, url ? { serverURL: url } : {}),
|
|
160
|
+
this.config.maxRetries,
|
|
161
|
+
this.config.initialBackoffMs,
|
|
162
|
+
this.config.maxBackoffMs
|
|
163
|
+
);
|
|
128
164
|
}
|
|
129
165
|
|
|
130
166
|
async createBasin(basin: string, request?: CreateBasinRequest): Promise<BasinInfo | undefined> {
|
|
@@ -134,14 +170,22 @@ class S2Account {
|
|
|
134
170
|
createBasinRequest: request ?? {},
|
|
135
171
|
};
|
|
136
172
|
const url = this.URL;
|
|
137
|
-
return (
|
|
138
|
-
url ? { serverURL: url } : {}
|
|
139
|
-
|
|
173
|
+
return retryWithExponentialBackoff(
|
|
174
|
+
() => this._account.createBasin(_request, url ? { serverURL: url } : {}),
|
|
175
|
+
this.config.maxRetries,
|
|
176
|
+
this.config.initialBackoffMs,
|
|
177
|
+
this.config.maxBackoffMs
|
|
178
|
+
);
|
|
140
179
|
}
|
|
141
180
|
|
|
142
|
-
async deleteBasin(basin: string, if_exists?: boolean): Promise<void
|
|
181
|
+
async deleteBasin(basin: string, if_exists?: boolean): Promise<void> {
|
|
143
182
|
const url = this.URL;
|
|
144
|
-
const response = await
|
|
183
|
+
const response = await retryWithExponentialBackoff(
|
|
184
|
+
() => accountDeleteBasin(this._account, { basin }, url ? { serverURL: url } : {}),
|
|
185
|
+
this.config.maxRetries,
|
|
186
|
+
this.config.initialBackoffMs,
|
|
187
|
+
this.config.maxBackoffMs
|
|
188
|
+
);
|
|
145
189
|
if (if_exists && response.error instanceof NotFoundError) return;
|
|
146
190
|
if (response.error) throw new Error(response.error.message);
|
|
147
191
|
return;
|
|
@@ -150,9 +194,12 @@ class S2Account {
|
|
|
150
194
|
async reconfigureBasin(basin: string, config: BasinConfig): Promise<BasinConfig | undefined> {
|
|
151
195
|
const url = this.URL;
|
|
152
196
|
const _request: ReconfigureBasinRequest = { basin, basinConfig: config };
|
|
153
|
-
return (
|
|
154
|
-
, url ? { serverURL: url } : {}
|
|
155
|
-
|
|
197
|
+
return retryWithExponentialBackoff(
|
|
198
|
+
() => this._account.reconfigureBasin(_request, url ? { serverURL: url } : {}),
|
|
199
|
+
this.config.maxRetries,
|
|
200
|
+
this.config.initialBackoffMs,
|
|
201
|
+
this.config.maxBackoffMs
|
|
202
|
+
);
|
|
156
203
|
}
|
|
157
204
|
}
|
|
158
205
|
|
|
@@ -162,13 +209,18 @@ class S2Basin {
|
|
|
162
209
|
private basinName: string;
|
|
163
210
|
private config: S2ClientConfig;
|
|
164
211
|
private clientKind: ClientKind;
|
|
165
|
-
private readonly basinURLSuffx = "/v1alpha";
|
|
212
|
+
private readonly basinURLSuffx = "/v1alpha";
|
|
166
213
|
|
|
167
214
|
private get URL(): string {
|
|
168
215
|
return `https://${ClientKind.toAuthority(this.clientKind, this.config.endpoints ?? S2Endpoints.forCloud(S2Cloud.Aws))}${this.basinURLSuffx}`;
|
|
169
216
|
}
|
|
170
217
|
|
|
171
218
|
constructor(basinName: string, config: S2ClientConfig) {
|
|
219
|
+
if (config.userAgent !== undefined) {
|
|
220
|
+
config.httpClient?.addHook("beforeRequest", (request) => {
|
|
221
|
+
request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
|
|
222
|
+
});
|
|
223
|
+
}
|
|
172
224
|
this._basin = new InnerBasin({
|
|
173
225
|
...(config.authToken !== undefined && { bearerAuth: config.authToken }),
|
|
174
226
|
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout })
|
|
@@ -185,13 +237,21 @@ class S2Basin {
|
|
|
185
237
|
async listStreams(
|
|
186
238
|
request: ListStreamsRequest
|
|
187
239
|
): Promise<PageIterator<ListStreamsResponse, { cursor: string }>> {
|
|
188
|
-
return
|
|
240
|
+
return retryWithExponentialBackoff(
|
|
241
|
+
() => this._basin.listStreams(request, { serverURL: this.URL }),
|
|
242
|
+
this.config.maxRetries,
|
|
243
|
+
this.config.initialBackoffMs,
|
|
244
|
+
this.config.maxBackoffMs
|
|
245
|
+
);
|
|
189
246
|
}
|
|
190
247
|
|
|
191
248
|
async getStreamConfig(stream: string): Promise<StreamConfig | undefined> {
|
|
192
|
-
return (
|
|
193
|
-
|
|
194
|
-
|
|
249
|
+
return retryWithExponentialBackoff(
|
|
250
|
+
() => this._basin.getStreamConfig({ stream }, { serverURL: this.URL }),
|
|
251
|
+
this.config.maxRetries,
|
|
252
|
+
this.config.initialBackoffMs,
|
|
253
|
+
this.config.maxBackoffMs
|
|
254
|
+
);
|
|
195
255
|
}
|
|
196
256
|
|
|
197
257
|
async createStream(stream: string, request?: CreateStreamRequest): Promise<StreamInfo | undefined> {
|
|
@@ -200,27 +260,33 @@ class S2Basin {
|
|
|
200
260
|
s2RequestToken: genS2RequestToken(),
|
|
201
261
|
createStreamRequest: request ?? {},
|
|
202
262
|
};
|
|
203
|
-
return (
|
|
204
|
-
|
|
205
|
-
|
|
263
|
+
return retryWithExponentialBackoff(
|
|
264
|
+
() => this._basin.createStream(_request, { serverURL: this.URL }),
|
|
265
|
+
this.config.maxRetries,
|
|
266
|
+
this.config.initialBackoffMs,
|
|
267
|
+
this.config.maxBackoffMs
|
|
268
|
+
);
|
|
206
269
|
}
|
|
207
270
|
|
|
208
271
|
async deleteStream(stream: string, if_exists?: boolean): Promise<void | undefined> {
|
|
209
|
-
const response = await
|
|
210
|
-
serverURL: this.URL,
|
|
211
|
-
|
|
272
|
+
const response = await retryWithExponentialBackoff(
|
|
273
|
+
() => basinDeleteStream(this._basin, { stream }, { serverURL: this.URL }),
|
|
274
|
+
this.config.maxRetries,
|
|
275
|
+
this.config.initialBackoffMs,
|
|
276
|
+
this.config.maxBackoffMs
|
|
277
|
+
);
|
|
212
278
|
if (if_exists && response instanceof NotFoundError) return;
|
|
213
279
|
if (response.error) throw new Error(response.error.message);
|
|
214
280
|
return;
|
|
215
281
|
}
|
|
216
282
|
|
|
217
|
-
async reconfigureStream(stream: string, config: StreamConfig): Promise<StreamConfig
|
|
218
|
-
return (
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
)
|
|
283
|
+
async reconfigureStream(stream: string, config: StreamConfig): Promise<StreamConfig> {
|
|
284
|
+
return retryWithExponentialBackoff(
|
|
285
|
+
() => this._basin.reconfigureStream({ stream, streamConfig: config }, { serverURL: this.URL }),
|
|
286
|
+
this.config.maxRetries,
|
|
287
|
+
this.config.initialBackoffMs,
|
|
288
|
+
this.config.maxBackoffMs
|
|
289
|
+
);
|
|
224
290
|
}
|
|
225
291
|
}
|
|
226
292
|
|
|
@@ -239,35 +305,55 @@ class Stream {
|
|
|
239
305
|
this.config = config;
|
|
240
306
|
this.clientKind = { kind: "Basin" as const, basin: basinName };
|
|
241
307
|
this.streamName = streamName;
|
|
308
|
+
if (config.userAgent !== undefined) {
|
|
309
|
+
config.httpClient?.addHook("beforeRequest", (request) => {
|
|
310
|
+
request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
|
|
311
|
+
});
|
|
312
|
+
}
|
|
242
313
|
this._stream = new InnerStream({
|
|
243
314
|
...(config.authToken !== undefined && { bearerAuth: config.authToken }),
|
|
244
315
|
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout })
|
|
245
316
|
});
|
|
246
317
|
}
|
|
247
318
|
|
|
248
|
-
async checkTail(): Promise<CheckTailResponse
|
|
319
|
+
async checkTail(): Promise<CheckTailResponse> {
|
|
249
320
|
return (
|
|
250
321
|
await this._stream.checkTail({ stream: this.streamName }, { serverURL: this.basinURL })
|
|
251
|
-
)
|
|
322
|
+
);
|
|
252
323
|
}
|
|
253
324
|
|
|
254
|
-
async append(request: AppendRequest): Promise<AppendOutput
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
325
|
+
async append(request: AppendRequest): Promise<AppendOutput> {
|
|
326
|
+
switch (this.config.appedRetryPolicy) {
|
|
327
|
+
case AppendRetryPolicy.All:
|
|
328
|
+
case undefined:
|
|
329
|
+
return retryWithExponentialBackoff(
|
|
330
|
+
() => this._stream.append({ ...request, stream: this.streamName }, { serverURL: this.basinURL }),
|
|
331
|
+
this.config.maxRetries,
|
|
332
|
+
this.config.initialBackoffMs,
|
|
333
|
+
this.config.maxBackoffMs
|
|
334
|
+
);
|
|
335
|
+
case AppendRetryPolicy.NoSideEffects:
|
|
336
|
+
return (
|
|
337
|
+
await this._stream.append({ ...request, stream: this.streamName }, {
|
|
338
|
+
serverURL: this.basinURL,
|
|
339
|
+
})
|
|
340
|
+
);
|
|
341
|
+
default:
|
|
342
|
+
throw new Error("Invalid AppendRetryPolicy");
|
|
343
|
+
}
|
|
258
344
|
}
|
|
259
345
|
|
|
260
|
-
async read(request: ReadRequest): Promise<Output
|
|
346
|
+
async read(request: ReadRequest): Promise<Output> {
|
|
261
347
|
return (
|
|
262
|
-
await this._stream.read({ ...request, stream: this.streamName }, { serverURL: this.basinURL })
|
|
263
|
-
)
|
|
348
|
+
await this._stream.read({ ...request, stream: this.streamName }, { serverURL: this.basinURL }) as Output
|
|
349
|
+
);
|
|
264
350
|
}
|
|
265
351
|
|
|
266
352
|
async *readStream(request: ReadRequest): AsyncGenerator<ReadResponse, void, undefined> {
|
|
267
353
|
let currentRequest: ReadRequest = { ...request };
|
|
268
|
-
let
|
|
354
|
+
let initialBackoffMs = this.config.initialBackoffMs ?? 100;
|
|
269
355
|
const maxBackoffMs = 5000;
|
|
270
|
-
const maxRetries = 5;
|
|
356
|
+
const maxRetries = this.config.maxRetries ?? 5;
|
|
271
357
|
let retryCount = 0;
|
|
272
358
|
|
|
273
359
|
while (true) {
|
|
@@ -281,7 +367,7 @@ class Stream {
|
|
|
281
367
|
acceptHeaderOverride: ReadAcceptEnum.textEventStream
|
|
282
368
|
}
|
|
283
369
|
);
|
|
284
|
-
stream = response
|
|
370
|
+
stream = response as EventStream<ReadResponse>;
|
|
285
371
|
if (!stream) return;
|
|
286
372
|
|
|
287
373
|
for await (const event of stream) {
|
|
@@ -310,13 +396,16 @@ class Stream {
|
|
|
310
396
|
}
|
|
311
397
|
return;
|
|
312
398
|
} catch (error) {
|
|
313
|
-
if (error instanceof
|
|
314
|
-
|
|
399
|
+
if (error instanceof RetryableError) {
|
|
400
|
+
if (retryCount >= maxRetries) {
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
retryCount++;
|
|
404
|
+
await new Promise(resolve => setTimeout(resolve, initialBackoffMs));
|
|
405
|
+
initialBackoffMs = Math.min(initialBackoffMs * 2, maxBackoffMs);
|
|
406
|
+
} else {
|
|
315
407
|
throw error;
|
|
316
408
|
}
|
|
317
|
-
retryCount++;
|
|
318
|
-
await new Promise(resolve => setTimeout(resolve, backoffMs));
|
|
319
|
-
backoffMs = Math.min(backoffMs * 2, maxBackoffMs);
|
|
320
409
|
}
|
|
321
410
|
}
|
|
322
411
|
}
|
|
@@ -336,4 +425,33 @@ function meteredBatchSize(batch: SequencedRecordBatch): number {
|
|
|
336
425
|
|
|
337
426
|
export function genS2RequestToken(): string {
|
|
338
427
|
return uuidv4().replace(/-/g, "");
|
|
339
|
-
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async function retryWithExponentialBackoff<T>(
|
|
431
|
+
operation: () => Promise<T>,
|
|
432
|
+
maxAttempts: number = 5,
|
|
433
|
+
initialBackoffMs: number = 100,
|
|
434
|
+
maxBackoffMs: number = 5000
|
|
435
|
+
): Promise<T> {
|
|
436
|
+
let attempt = 0;
|
|
437
|
+
|
|
438
|
+
while (attempt < maxAttempts) {
|
|
439
|
+
try {
|
|
440
|
+
return await operation();
|
|
441
|
+
} catch (error) {
|
|
442
|
+
if (error instanceof RetryableError) {
|
|
443
|
+
attempt++;
|
|
444
|
+
if (attempt >= maxAttempts) throw error;
|
|
445
|
+
|
|
446
|
+
const jitter = Math.random() * 0.3 + 0.85;
|
|
447
|
+
const delayMs = Math.min(initialBackoffMs * Math.pow(2, attempt) * jitter, maxBackoffMs);
|
|
448
|
+
|
|
449
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
450
|
+
} else {
|
|
451
|
+
throw error;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
throw new Error("Max retry attempts reached");
|
|
457
|
+
}
|
package/src/lib/config.ts
CHANGED
|
@@ -54,7 +54,8 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
|
|
|
54
54
|
export const SDK_METADATA = {
|
|
55
55
|
language: "typescript",
|
|
56
56
|
openapiDocVersion: "1.0.0",
|
|
57
|
-
sdkVersion: "0.3.
|
|
57
|
+
sdkVersion: "0.3.14",
|
|
58
58
|
genVersion: "2.506.0",
|
|
59
|
-
userAgent:
|
|
59
|
+
userAgent:
|
|
60
|
+
"speakeasy-sdk/typescript 0.3.14 2.506.0 1.0.0 @s2-dev/streamstore",
|
|
60
61
|
} as const;
|
package/src/lib/matchers.ts
CHANGED
|
@@ -160,7 +160,6 @@ export type MatchedError<Matchers> = Matchers extends Matcher<any, infer E>[]
|
|
|
160
160
|
: never;
|
|
161
161
|
export type MatchFunc<T, E> = (
|
|
162
162
|
response: Response,
|
|
163
|
-
request: Request,
|
|
164
163
|
options?: { resultKey?: string; extraFields?: Record<string, unknown> },
|
|
165
164
|
) => Promise<[result: Result<T, E>, raw: unknown]>;
|
|
166
165
|
|
|
@@ -169,7 +168,6 @@ export function match<T, E>(
|
|
|
169
168
|
): MatchFunc<T, E | APIError | SDKValidationError> {
|
|
170
169
|
return async function matchFunc(
|
|
171
170
|
response: Response,
|
|
172
|
-
request: Request,
|
|
173
171
|
options?: { resultKey?: string; extraFields?: Record<string, unknown> },
|
|
174
172
|
): Promise<
|
|
175
173
|
[result: Result<T, E | APIError | SDKValidationError>, raw: unknown]
|
|
@@ -191,14 +189,15 @@ export function match<T, E>(
|
|
|
191
189
|
}
|
|
192
190
|
|
|
193
191
|
if (!matcher) {
|
|
194
|
-
await
|
|
192
|
+
const responseBody = await response.text();
|
|
195
193
|
return [{
|
|
196
194
|
ok: false,
|
|
197
|
-
error: new APIError(
|
|
195
|
+
error: new APIError(
|
|
196
|
+
"Unexpected API response status or content-type",
|
|
198
197
|
response,
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
},
|
|
198
|
+
responseBody,
|
|
199
|
+
),
|
|
200
|
+
}, responseBody];
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
const encoding = matcher.enc;
|
|
@@ -224,7 +223,7 @@ export function match<T, E>(
|
|
|
224
223
|
raw = await discardResponseBody(response);
|
|
225
224
|
break;
|
|
226
225
|
case "fail":
|
|
227
|
-
raw = await
|
|
226
|
+
raw = await response.text();
|
|
228
227
|
break;
|
|
229
228
|
default:
|
|
230
229
|
encoding satisfies never;
|
|
@@ -234,7 +233,11 @@ export function match<T, E>(
|
|
|
234
233
|
if (matcher.enc === "fail") {
|
|
235
234
|
return [{
|
|
236
235
|
ok: false,
|
|
237
|
-
error: new APIError(
|
|
236
|
+
error: new APIError(
|
|
237
|
+
"API error occurred",
|
|
238
|
+
response,
|
|
239
|
+
typeof raw === "string" ? raw : "",
|
|
240
|
+
),
|
|
238
241
|
}, raw];
|
|
239
242
|
}
|
|
240
243
|
|
|
@@ -253,11 +256,14 @@ export function match<T, E>(
|
|
|
253
256
|
...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null),
|
|
254
257
|
[resultKey]: raw,
|
|
255
258
|
};
|
|
256
|
-
} else {
|
|
259
|
+
} else if (matcher.hdrs) {
|
|
257
260
|
data = {
|
|
258
261
|
...options?.extraFields,
|
|
259
262
|
...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null),
|
|
263
|
+
...(isPlainObject(raw) ? raw : null),
|
|
260
264
|
};
|
|
265
|
+
} else {
|
|
266
|
+
data = raw;
|
|
261
267
|
}
|
|
262
268
|
|
|
263
269
|
if ("err" in matcher) {
|
|
@@ -14,7 +14,6 @@ export * from "./createbasinrequest.js";
|
|
|
14
14
|
export * from "./createstreamrequest.js";
|
|
15
15
|
export * from "./formatoption.js";
|
|
16
16
|
export * from "./header.js";
|
|
17
|
-
export * from "./httpmetadata.js";
|
|
18
17
|
export * from "./listbasinsresponse.js";
|
|
19
18
|
export * from "./liststreamsresponse.js";
|
|
20
19
|
export * from "./output.js";
|
|
@@ -3,19 +3,25 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export class APIError extends Error {
|
|
6
|
+
public readonly statusCode: number;
|
|
7
|
+
public readonly contentType: string;
|
|
8
|
+
|
|
6
9
|
constructor(
|
|
7
10
|
message: string,
|
|
8
|
-
public readonly
|
|
9
|
-
|
|
10
|
-
request: Request;
|
|
11
|
-
},
|
|
11
|
+
public readonly rawResponse: Response,
|
|
12
|
+
public readonly body: string = "",
|
|
12
13
|
) {
|
|
14
|
+
const statusCode = rawResponse.status;
|
|
15
|
+
const contentType = rawResponse.headers.get("content-type") || "";
|
|
16
|
+
const bodyString = body.length > 0 ? `\n${body}` : "";
|
|
17
|
+
|
|
13
18
|
super(
|
|
14
|
-
`${message}: Status ${
|
|
15
|
-
httpMeta.response.headers.get("content-type") || ""
|
|
16
|
-
}`,
|
|
19
|
+
`${message}: Status ${statusCode} Content-Type ${contentType} Body ${bodyString}`,
|
|
17
20
|
);
|
|
18
21
|
|
|
22
|
+
this.statusCode = statusCode;
|
|
23
|
+
this.contentType = contentType;
|
|
24
|
+
|
|
19
25
|
this.name = "APIError";
|
|
20
26
|
}
|
|
21
27
|
}
|