@0xinsider/mcp 2.14.0 → 2.14.3

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.
Files changed (105) hide show
  1. package/README.md +14 -0
  2. package/dist/cli-lib.d.ts.map +1 -1
  3. package/dist/cli-lib.js +14 -10
  4. package/dist/cli-lib.js.map +1 -1
  5. package/dist/client.d.ts +8 -2
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +84 -37
  8. package/dist/client.js.map +1 -1
  9. package/dist/constants.d.ts +1 -1
  10. package/dist/constants.js +1 -1
  11. package/dist/product-cli/index.d.ts.map +1 -1
  12. package/dist/product-cli/index.js +25 -7
  13. package/dist/product-cli/index.js.map +1 -1
  14. package/dist/product-cli/oauth.js +6 -6
  15. package/dist/product-cli/oauth.js.map +1 -1
  16. package/dist/product-cli/storage.d.ts +1 -1
  17. package/dist/product-cli/storage.js +3 -3
  18. package/dist/product-cli/storage.js.map +1 -1
  19. package/dist/prompts/index.js.map +1 -1
  20. package/dist/resources/index.d.ts.map +1 -1
  21. package/dist/resources/index.js +75 -33
  22. package/dist/resources/index.js.map +1 -1
  23. package/dist/sdk/client.d.ts +23 -8
  24. package/dist/sdk/client.d.ts.map +1 -1
  25. package/dist/sdk/client.js +63 -25
  26. package/dist/sdk/client.js.map +1 -1
  27. package/dist/sdk/data-quality.d.ts +4 -4
  28. package/dist/sdk/data-quality.d.ts.map +1 -1
  29. package/dist/sdk/data-quality.js +1 -1
  30. package/dist/sdk/data-quality.js.map +1 -1
  31. package/dist/sdk/errors.d.ts +5 -6
  32. package/dist/sdk/errors.d.ts.map +1 -1
  33. package/dist/sdk/errors.js +4 -5
  34. package/dist/sdk/errors.js.map +1 -1
  35. package/dist/sdk/index.d.ts +5 -5
  36. package/dist/sdk/index.d.ts.map +1 -1
  37. package/dist/sdk/index.js +3 -3
  38. package/dist/sdk/index.js.map +1 -1
  39. package/dist/sdk/pagination.d.ts +3 -3
  40. package/dist/sdk/pagination.d.ts.map +1 -1
  41. package/dist/sdk/pagination.js +3 -3
  42. package/dist/sdk/pagination.js.map +1 -1
  43. package/dist/sdk/retry.js +4 -2
  44. package/dist/sdk/retry.js.map +1 -1
  45. package/dist/sdk/schema.d.ts +207 -39
  46. package/dist/sdk/schema.d.ts.map +1 -1
  47. package/dist/sdk/stream.d.ts +28 -8
  48. package/dist/sdk/stream.d.ts.map +1 -1
  49. package/dist/sdk/stream.js +277 -76
  50. package/dist/sdk/stream.js.map +1 -1
  51. package/dist/sdk/webhooks.d.ts +14 -6
  52. package/dist/sdk/webhooks.d.ts.map +1 -1
  53. package/dist/sdk/webhooks.js +11 -3
  54. package/dist/sdk/webhooks.js.map +1 -1
  55. package/dist/server.js +1 -1
  56. package/dist/server.js.map +1 -1
  57. package/dist/tools/explore-markets.d.ts +7 -7
  58. package/dist/tools/explore-markets.d.ts.map +1 -1
  59. package/dist/tools/explore-markets.js +2 -2
  60. package/dist/tools/explore-markets.js.map +1 -1
  61. package/dist/tools/games.js +4 -4
  62. package/dist/tools/games.js.map +1 -1
  63. package/dist/tools/get-insider-radar.js +2 -2
  64. package/dist/tools/get-insider-radar.js.map +1 -1
  65. package/dist/tools/get-large-positions.d.ts +6 -6
  66. package/dist/tools/get-large-positions.d.ts.map +1 -1
  67. package/dist/tools/get-large-positions.js +4 -6
  68. package/dist/tools/get-large-positions.js.map +1 -1
  69. package/dist/tools/get-leaderboard.d.ts.map +1 -1
  70. package/dist/tools/get-leaderboard.js +9 -3
  71. package/dist/tools/get-leaderboard.js.map +1 -1
  72. package/dist/tools/get-market-flow.js +2 -2
  73. package/dist/tools/get-market-flow.js.map +1 -1
  74. package/dist/tools/get-position-timeline.d.ts +4 -4
  75. package/dist/tools/get-position-timeline.d.ts.map +1 -1
  76. package/dist/tools/get-position-timeline.js +4 -6
  77. package/dist/tools/get-position-timeline.js.map +1 -1
  78. package/dist/tools/get-positions.d.ts +8 -8
  79. package/dist/tools/get-positions.d.ts.map +1 -1
  80. package/dist/tools/get-positions.js +2 -2
  81. package/dist/tools/get-positions.js.map +1 -1
  82. package/dist/tools/get-suspicious-trades.js +4 -4
  83. package/dist/tools/get-suspicious-trades.js.map +1 -1
  84. package/dist/tools/get-trader-pnl.js +2 -2
  85. package/dist/tools/get-trader-pnl.js.map +1 -1
  86. package/dist/tools/get-trader.js +2 -2
  87. package/dist/tools/get-trader.js.map +1 -1
  88. package/dist/tools/get-trending-wallets.d.ts +3 -3
  89. package/dist/tools/get-trending-wallets.d.ts.map +1 -1
  90. package/dist/tools/get-trending-wallets.js +4 -6
  91. package/dist/tools/get-trending-wallets.js.map +1 -1
  92. package/dist/tools/get-whale-trades.d.ts.map +1 -1
  93. package/dist/tools/get-whale-trades.js +4 -6
  94. package/dist/tools/get-whale-trades.js.map +1 -1
  95. package/dist/tools/pick-of-the-day.js +9 -9
  96. package/dist/tools/pick-of-the-day.js.map +1 -1
  97. package/dist/tools/read-parity.js +46 -46
  98. package/dist/tools/read-parity.js.map +1 -1
  99. package/dist/tools/result.d.ts +5 -1
  100. package/dist/tools/result.d.ts.map +1 -1
  101. package/dist/tools/result.js +11 -7
  102. package/dist/tools/result.js.map +1 -1
  103. package/dist/tools/search-markets.js +2 -2
  104. package/dist/tools/search-markets.js.map +1 -1
  105. package/package.json +7 -3
@@ -85,7 +85,7 @@ export interface StreamOptions extends StreamFilters {
85
85
  * remains valid across replicas and process restarts while retained. When
86
86
  * omitted the stream starts from the live head.
87
87
  */
88
- lastEventId?: number | string;
88
+ lastEventId?: number | string | undefined;
89
89
  /** Cooperative cancellation; abort to close the stream. */
90
90
  signal?: AbortSignal;
91
91
  /** Invoked once for the resync marker frame, if one is emitted. */
@@ -104,7 +104,7 @@ export interface StreamOptions extends StreamFilters {
104
104
  * transport progress.
105
105
  */
106
106
  cursor?: {
107
- seq?: number;
107
+ seq?: number | undefined;
108
108
  };
109
109
  /**
110
110
  * Byte ceiling for one undelivered frame (#16248). Default
@@ -115,9 +115,28 @@ export interface StreamOptions extends StreamFilters {
115
115
  * A positive finite integer; the largest real frame is a few KB.
116
116
  */
117
117
  maxFrameBytes?: number;
118
+ /**
119
+ * Deadline for response headers and a finite refusal body, per connection.
120
+ * Default `DEFAULT_TIMEOUT_MS` (15 seconds); `null` explicitly disables it.
121
+ * Cleared once a readable `text/event-stream` response is established.
122
+ * Independent of the client's REST `timeoutMs` and the stream's lifetime.
123
+ */
124
+ openTimeoutMs?: number | null;
125
+ /** Maximum refusal body bytes retained before cancellation. Default 64 KiB. */
126
+ maxErrorBodyBytes?: number;
118
127
  }
119
128
  /** Default for `StreamOptions.maxFrameBytes`: 1 MiB. */
120
129
  export declare const DEFAULT_MAX_STREAM_FRAME_BYTES = 1048576;
130
+ /** Default for `StreamOptions.maxErrorBodyBytes`: 64 KiB. */
131
+ export declare const DEFAULT_MAX_STREAM_ERROR_BODY_BYTES = 65536;
132
+ /** A refusal's HTTP error retains this diagnostic as `cause`, without raw text. */
133
+ export type StreamRefusalBodyErrorReason = "absent" | "empty" | "invalid_json" | "too_large" | "deadline_exceeded" | "read_failed";
134
+ export declare class StreamRefusalBodyError extends Error {
135
+ readonly reason: StreamRefusalBodyErrorReason;
136
+ readonly bytes: number;
137
+ readonly maxBytes: number;
138
+ constructor(reason: StreamRefusalBodyErrorReason, bytes: number, maxBytes: number, cause?: unknown);
139
+ }
121
140
  /** What the stream did that the SSE contract does not allow. */
122
141
  export type StreamProtocolErrorReason =
123
142
  /** A 2xx whose `Content-Type` is not `text/event-stream`. */
@@ -156,8 +175,8 @@ export declare class StreamProtocolError extends Error {
156
175
  readonly mediaType: string | undefined;
157
176
  constructor(reason: StreamProtocolErrorReason, detail: {
158
177
  lastSeq: number | undefined;
159
- frameId?: number;
160
- event?: string;
178
+ frameId?: number | undefined;
179
+ event?: string | undefined;
161
180
  bytes?: number;
162
181
  mediaType?: string | null;
163
182
  });
@@ -179,7 +198,7 @@ export type StreamEvent = {
179
198
  * `StreamEvent`: `kind: "event"` carries the `FeedEnvelope`, `kind: "resync"`
180
199
  * carries the `ResyncMarker`.
181
200
  *
182
- * Pass `options.cursor` (a `{ seq?: number }` object) to have the last
201
+ * Pass `options.cursor` (a `{ seq?: number | undefined }` object) to have the last
183
202
  * delivered `seq` written back as frames arrive; reconnect with
184
203
  * `lastEventId: cursor.seq` to resume after a transport drop.
185
204
  *
@@ -274,7 +293,8 @@ export declare class StreamRetryDeferredError extends Error {
274
293
  * - Aborting `signal` ends the iterator without throwing, during a connection
275
294
  * or a backoff. Each connection's body reader is cancelled when it ends, so
276
295
  * reconnects do not accumulate sockets.
277
- * - No request deadline applies, as with `streamFeed`.
296
+ * - `openTimeoutMs` bounds only opening and refusal reads; healthy streams
297
+ * have no lifetime deadline, as with `streamFeed`.
278
298
  *
279
299
  * `options.cursor`, when passed, tracks the last delivered seq across every
280
300
  * connection -- delivered, not processed (#16247). This loop resumes from it,
@@ -495,8 +515,8 @@ export interface CheckpointedStreamHandlers {
495
515
  */
496
516
  export declare function consumeStreamCheckpointed(client: OxinsiderApiClient, handlers: CheckpointedStreamHandlers, options?: CheckpointedStreamOptions): Promise<void>;
497
517
  export interface ParsedSseFrame {
498
- event?: string;
499
- id?: number;
518
+ event?: string | undefined;
519
+ id?: number | undefined;
500
520
  data: string;
501
521
  }
502
522
  /** Parse one SSE frame (without the trailing blank line). */
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../sdk/src/stream.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../sdk/src/stream.ts"],"names":[],"mappings":"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"}
@@ -45,11 +45,25 @@
45
45
  * Comment lines (`: keep-alive`), LF and CRLF framing, unknown SSE fields
46
46
  * and unknown-but-valid envelope `type`s are compatible as before.
47
47
  */
48
- import { resolveApiUrl } from "./client.js";
49
- import { errorFromResponse, OxinsiderApiError } from "./errors.js";
48
+ import { DEFAULT_TIMEOUT_MS, resolveApiUrl, } from "./client.js";
49
+ import { errorFromResponse, OxinsiderApiError, RequestTimeoutError, } from "./errors.js";
50
50
  import { RETRY_AFTER_CEILING_MS, retryAfterSeconds, waitUnlessAborted, } from "./retry.js";
51
51
  /** Default for `StreamOptions.maxFrameBytes`: 1 MiB. */
52
52
  export const DEFAULT_MAX_STREAM_FRAME_BYTES = 1_048_576;
53
+ /** Default for `StreamOptions.maxErrorBodyBytes`: 64 KiB. */
54
+ export const DEFAULT_MAX_STREAM_ERROR_BODY_BYTES = 65_536;
55
+ export class StreamRefusalBodyError extends Error {
56
+ reason;
57
+ bytes;
58
+ maxBytes;
59
+ constructor(reason, bytes, maxBytes, cause) {
60
+ super(`0xinsider stream refusal body ${reason} (${String(bytes)} bytes read; limit ${String(maxBytes)})`, { cause });
61
+ this.reason = reason;
62
+ this.bytes = bytes;
63
+ this.maxBytes = maxBytes;
64
+ this.name = "StreamRefusalBodyError";
65
+ }
66
+ }
53
67
  /**
54
68
  * The stream broke the SSE contract (#16248). The connection is closed and
55
69
  * the reader released before this is thrown. `lastSeq` is the last sequence
@@ -113,6 +127,163 @@ function assertMaxFrameBytes(value) {
113
127
  }
114
128
  return value;
115
129
  }
130
+ /** Validate transport options before a reconnect can spend an attempt. */
131
+ function streamConnectionOptions(options) {
132
+ const maxFrameBytes = assertMaxFrameBytes(options.maxFrameBytes ?? DEFAULT_MAX_STREAM_FRAME_BYTES);
133
+ const maxErrorBodyBytes = options.maxErrorBodyBytes ?? DEFAULT_MAX_STREAM_ERROR_BODY_BYTES;
134
+ if (!Number.isSafeInteger(maxErrorBodyBytes) || maxErrorBodyBytes < 1) {
135
+ throw new Error(`maxErrorBodyBytes must be a positive safe integer, got ${String(maxErrorBodyBytes)}`);
136
+ }
137
+ const openTimeoutMs = options.openTimeoutMs === undefined
138
+ ? DEFAULT_TIMEOUT_MS
139
+ : options.openTimeoutMs;
140
+ // Node's timer contract clamps larger values to 1 ms. Reject rather than
141
+ // making a requested long opening window expire immediately.
142
+ if (openTimeoutMs !== null &&
143
+ (!Number.isInteger(openTimeoutMs) ||
144
+ openTimeoutMs < 1 ||
145
+ openTimeoutMs > 2_147_483_647)) {
146
+ throw new Error(`openTimeoutMs must be an integer from 1 to 2147483647 ms or null, got ${String(openTimeoutMs)}`);
147
+ }
148
+ return { maxFrameBytes, maxErrorBodyBytes, openTimeoutMs };
149
+ }
150
+ /** Clear only the owned opening timer; caller cancellation lives until disposal. */
151
+ function streamConnectionSignal(timeoutMs, caller) {
152
+ const controller = new AbortController();
153
+ let timer;
154
+ const established = () => {
155
+ clearTimeout(timer);
156
+ timer = undefined;
157
+ };
158
+ const onCallerAbort = () => {
159
+ established();
160
+ controller.abort(caller?.reason);
161
+ };
162
+ // Manual forwarding supports every Node >=18, including versions without
163
+ // AbortSignal.any, and allows both sources to be disposed explicitly.
164
+ if (caller?.aborted)
165
+ onCallerAbort();
166
+ else
167
+ caller?.addEventListener("abort", onCallerAbort, { once: true });
168
+ if (!controller.signal.aborted && timeoutMs !== null) {
169
+ timer = setTimeout(() => controller.abort(new RequestTimeoutError("getStream", timeoutMs)), timeoutMs);
170
+ }
171
+ return {
172
+ signal: controller.signal,
173
+ established,
174
+ dispose: () => {
175
+ established();
176
+ caller?.removeEventListener("abort", onCallerAbort);
177
+ },
178
+ };
179
+ }
180
+ /** Bound injected readers too: their stream may not observe fetch's signal. */
181
+ async function streamWork(work, signal) {
182
+ let onAbort;
183
+ const aborted = new Promise((_, reject) => {
184
+ onAbort = () => {
185
+ const reason = signal.reason;
186
+ reject(reason);
187
+ };
188
+ if (signal.aborted)
189
+ onAbort();
190
+ else
191
+ signal.addEventListener("abort", onAbort, { once: true });
192
+ });
193
+ try {
194
+ return await Promise.race([aborted, work]);
195
+ }
196
+ finally {
197
+ if (onAbort)
198
+ signal.removeEventListener("abort", onAbort);
199
+ }
200
+ }
201
+ const STREAM_CLEANUP_TIMEOUT_MS = 2_000;
202
+ /** A non-cooperative injected cancel cannot hold a reconnect indefinitely. */
203
+ async function cancelStreamBody(cancel) {
204
+ if (!cancel)
205
+ return undefined;
206
+ let timer;
207
+ const cancelled = Promise.resolve()
208
+ .then(cancel)
209
+ .then(() => undefined, (cause) => new Error("0xinsider stream body cancellation failed", { cause }));
210
+ const deadline = new Promise((resolve) => {
211
+ timer = setTimeout(() => resolve(new Error(`0xinsider stream body cancellation did not settle within ${String(STREAM_CLEANUP_TIMEOUT_MS)} ms; completion is unknown`)), STREAM_CLEANUP_TIMEOUT_MS);
212
+ });
213
+ try {
214
+ return await Promise.race([cancelled, deadline]);
215
+ }
216
+ finally {
217
+ clearTimeout(timer);
218
+ }
219
+ }
220
+ /** Preserve HTTP classification when cleanup also fails. */
221
+ function withStreamCleanupCause(primary, cleanup) {
222
+ if (primary instanceof Error) {
223
+ const cause = primary.cause;
224
+ try {
225
+ primary.cause =
226
+ cause === undefined
227
+ ? cleanup
228
+ : new AggregateError([cause, cleanup], "Stream failure and body cleanup failure");
229
+ return primary;
230
+ }
231
+ catch (annotationFailure) {
232
+ return new AggregateError([primary, cleanup, annotationFailure], "Stream failure could not retain its cleanup diagnostic", { cause: primary });
233
+ }
234
+ }
235
+ return new AggregateError([primary, cleanup], "Stream failure and body cleanup failure", { cause: primary });
236
+ }
237
+ async function streamRefusal(response, reader, signal, maxBytes, caller) {
238
+ const retryAfter = retryAfterSeconds(response);
239
+ const requestId = response.headers.get("x-request-id");
240
+ let bytes = 0;
241
+ let body = null;
242
+ let diagnostic;
243
+ if (!reader)
244
+ diagnostic = new StreamRefusalBodyError("absent", bytes, maxBytes);
245
+ else {
246
+ const decoder = new TextDecoder();
247
+ let text = "";
248
+ try {
249
+ for (;;) {
250
+ const { value, done } = await streamWork(reader.read(), signal);
251
+ if (done)
252
+ break;
253
+ bytes += value.byteLength;
254
+ if (bytes > maxBytes) {
255
+ diagnostic = new StreamRefusalBodyError("too_large", bytes, maxBytes);
256
+ break;
257
+ }
258
+ text += decoder.decode(value, { stream: true });
259
+ }
260
+ if (!diagnostic) {
261
+ text += decoder.decode();
262
+ if (text === "")
263
+ diagnostic = new StreamRefusalBodyError("empty", bytes, maxBytes);
264
+ else {
265
+ try {
266
+ body = JSON.parse(text);
267
+ }
268
+ catch {
269
+ diagnostic = new StreamRefusalBodyError("invalid_json", bytes, maxBytes);
270
+ }
271
+ }
272
+ }
273
+ }
274
+ catch (cause) {
275
+ if (caller?.aborted)
276
+ throw caller.reason;
277
+ diagnostic = new StreamRefusalBodyError(signal.aborted ? "deadline_exceeded" : "read_failed", bytes, maxBytes, cause);
278
+ }
279
+ }
280
+ const error = errorFromResponse(response.status, body, retryAfter, {
281
+ requestId,
282
+ });
283
+ if (diagnostic)
284
+ error.cause = diagnostic;
285
+ return error;
286
+ }
116
287
  /** `Content-Type` names an event stream: `text/event-stream`, with or without parameters. */
117
288
  export function isEventStreamMediaType(contentType) {
118
289
  if (contentType === null)
@@ -125,7 +296,7 @@ export function isEventStreamMediaType(contentType) {
125
296
  * `StreamEvent`: `kind: "event"` carries the `FeedEnvelope`, `kind: "resync"`
126
297
  * carries the `ResyncMarker`.
127
298
  *
128
- * Pass `options.cursor` (a `{ seq?: number }` object) to have the last
299
+ * Pass `options.cursor` (a `{ seq?: number | undefined }` object) to have the last
129
300
  * delivered `seq` written back as frames arrive; reconnect with
130
301
  * `lastEventId: cursor.seq` to resume after a transport drop.
131
302
  *
@@ -135,7 +306,7 @@ export function isEventStreamMediaType(contentType) {
135
306
  * }
136
307
  */
137
308
  export async function* streamFeed(client, options = {}) {
138
- const maxFrameBytes = assertMaxFrameBytes(options.maxFrameBytes ?? DEFAULT_MAX_STREAM_FRAME_BYTES);
309
+ const { maxFrameBytes, maxErrorBodyBytes, openTimeoutMs } = streamConnectionOptions(options);
139
310
  const apiKey = client.getApiKey();
140
311
  // The sandbox takes no credential; it answers the stream route with a 400
141
312
  // saying streams are not simulated, and that answer is the server's to
@@ -150,41 +321,73 @@ export async function* streamFeed(client, options = {}) {
150
321
  if (options.lastEventId !== undefined) {
151
322
  headers.set("last-event-id", String(options.lastEventId));
152
323
  }
153
- const fetchImpl = client.getFetch();
154
- const response = await fetchImpl(url, {
155
- method: "GET",
156
- headers,
157
- signal: options.signal,
158
- });
159
- if (!response.ok) {
160
- const body = await safeText(response);
161
- throw errorFromResponse(response.status, tryParse(body), retryAfterSeconds(response), { requestId: response.headers.get("x-request-id") });
162
- }
163
- // A 2xx that is not an event stream (an HTML page from a proxy, a JSON body
164
- // from a route that moved) used to read as an empty stream that closed
165
- // cleanly, which the reconnect loop then retried as an outage (#16248).
166
- const mediaType = response.headers.get("content-type");
167
- if (!isEventStreamMediaType(mediaType)) {
168
- await response.body?.cancel().catch(() => undefined);
169
- throw new StreamProtocolError("unexpected_media_type", {
170
- lastSeq: undefined,
171
- mediaType,
172
- });
173
- }
174
- if (!response.body) {
175
- throw new Error("Stream response has no readable body");
176
- }
177
- const reader = response.body.getReader();
178
- const decoder = new TextDecoder();
179
- const encoder = new TextEncoder();
180
- let buffer = "";
181
- // Bytes of `buffer`: exact, since every chunk adds its own byte length and
182
- // a cut re-measures the remainder. Bounded by `maxFrameBytes`.
183
- let bufferedBytes = 0;
184
- let lastSeq;
324
+ const connection = streamConnectionSignal(openTimeoutMs, options.signal);
325
+ let response;
326
+ let reader;
327
+ let failure;
328
+ let failed = false;
185
329
  try {
330
+ connection.signal.throwIfAborted();
331
+ const pendingResponse = client.getFetch()(url, {
332
+ method: "GET",
333
+ headers,
334
+ signal: connection.signal,
335
+ });
336
+ try {
337
+ response = await streamWork(pendingResponse, connection.signal);
338
+ }
339
+ catch (error) {
340
+ // An injected fetch may ignore abort. Observe its eventual response and
341
+ // cancel it instead of abandoning a late connection. The timeout error
342
+ // keeps any cleanup diagnostic; an uncooperative fetch itself is outside
343
+ // the SDK's control.
344
+ pendingResponse.then(async (lateResponse) => {
345
+ const body = lateResponse.body;
346
+ const cleanup = await cancelStreamBody(body ? () => body.cancel(error) : undefined);
347
+ if (cleanup)
348
+ withStreamCleanupCause(error, cleanup);
349
+ }, (lateFailure) => {
350
+ if (lateFailure !== error && error instanceof Error) {
351
+ withStreamCleanupCause(error, new Error("Opening fetch failed after cancellation", {
352
+ cause: lateFailure,
353
+ }));
354
+ }
355
+ });
356
+ throw error;
357
+ }
358
+ if (!response.ok) {
359
+ try {
360
+ reader = response.body?.getReader();
361
+ }
362
+ catch (cause) {
363
+ const error = errorFromResponse(response.status, null, retryAfterSeconds(response), {
364
+ requestId: response.headers.get("x-request-id"),
365
+ });
366
+ error.cause = new StreamRefusalBodyError("read_failed", 0, maxErrorBodyBytes, cause);
367
+ throw error;
368
+ }
369
+ throw await streamRefusal(response, reader, connection.signal, maxErrorBodyBytes, options.signal);
370
+ }
371
+ const mediaType = response.headers.get("content-type");
372
+ if (!isEventStreamMediaType(mediaType)) {
373
+ throw new StreamProtocolError("unexpected_media_type", {
374
+ lastSeq: undefined,
375
+ mediaType,
376
+ });
377
+ }
378
+ if (!response.body)
379
+ throw new Error("Stream response has no readable body");
380
+ reader = response.body.getReader();
381
+ connection.established();
382
+ const decoder = new TextDecoder();
383
+ const encoder = new TextEncoder();
384
+ let buffer = "";
385
+ // Bytes of `buffer`: exact, since every chunk adds its own byte length and
386
+ // a cut re-measures the remainder. Bounded by `maxFrameBytes`.
387
+ let bufferedBytes = 0;
388
+ let lastSeq;
186
389
  for (;;) {
187
- const { value, done } = await reader.read();
390
+ const { value, done } = await streamWork(reader.read(), connection.signal);
188
391
  if (done)
189
392
  break;
190
393
  buffer += decoder.decode(value, { stream: true });
@@ -236,18 +439,25 @@ export async function* streamFeed(client, options = {}) {
236
439
  }
237
440
  }
238
441
  }
442
+ catch (error) {
443
+ failed = true;
444
+ failure = error;
445
+ throw error;
446
+ }
239
447
  finally {
240
- // `releaseLock()` detaches the reader but leaves the body -- and the
241
- // underlying HTTP connection -- open. Any early exit from the consumer
242
- // loop (`break`, `return`, or a throw from a handler) runs this block via
243
- // the generator's `return()`, so without `cancel()` every early exit leaks
244
- // one open connection to the SSE endpoint. The documented reconnect loop
245
- // makes that one leak per reconnect, until the process runs out of sockets
246
- // or the server's per-user SSE lease cap rejects the user's own
247
- // reconnects. `cancel()` releases the lock as part of cancelling, and can
248
- // reject on an already-errored stream, so the rejection is swallowed to
249
- // keep the `finally` non-throwing (#9682).
250
- await reader.cancel().catch(() => undefined);
448
+ // Cancel even when the consumer breaks, and always release the lock.
449
+ // Cancellation failures remain visible without replacing an HTTP status.
450
+ connection.dispose();
451
+ const ownedReader = reader;
452
+ const ownedBody = response?.body;
453
+ const cleanup = await cancelStreamBody(ownedReader
454
+ ? () => ownedReader.cancel(failure)
455
+ : ownedBody
456
+ ? () => ownedBody.cancel(failure)
457
+ : undefined);
458
+ ownedReader?.releaseLock();
459
+ if (cleanup)
460
+ throw failed ? withStreamCleanupCause(failure, cleanup) : cleanup;
251
461
  }
252
462
  }
253
463
  /** Default for `ResilientStreamOptions.maxReconnects`. */
@@ -353,7 +563,7 @@ function streamBackoffMs(attempt) {
353
563
  return ceiling / 2 + Math.random() * (ceiling / 2);
354
564
  }
355
565
  function assertMaxRetryAfterMs(value) {
356
- if (Number.isNaN(value) || value < 0) {
566
+ if (typeof value !== "number" || Number.isNaN(value) || value < 0) {
357
567
  throw new Error(`maxRetryAfterMs must be a non-negative number of milliseconds or Infinity, got ${String(value)}`);
358
568
  }
359
569
  return value;
@@ -381,7 +591,8 @@ function assertMaxRetryAfterMs(value) {
381
591
  * - Aborting `signal` ends the iterator without throwing, during a connection
382
592
  * or a backoff. Each connection's body reader is cancelled when it ends, so
383
593
  * reconnects do not accumulate sockets.
384
- * - No request deadline applies, as with `streamFeed`.
594
+ * - `openTimeoutMs` bounds only opening and refusal reads; healthy streams
595
+ * have no lifetime deadline, as with `streamFeed`.
385
596
  *
386
597
  * `options.cursor`, when passed, tracks the last delivered seq across every
387
598
  * connection -- delivered, not processed (#16247). This loop resumes from it,
@@ -406,6 +617,7 @@ export async function* streamFeedResilient(client, options = {}) {
406
617
  throw new Error(`maxReconnects must be a non-negative integer, got ${String(maxReconnects)}`);
407
618
  }
408
619
  const retryAfterCeilingMs = assertMaxRetryAfterMs(maxRetryAfterMs);
620
+ const connectionOptions = streamConnectionOptions(streamOptions);
409
621
  // The one configuration error `streamFeed` throws before any request; it
410
622
  // would otherwise count as a transport failure and burn every reconnect.
411
623
  if (!client.getApiKey() && !client.isSandbox()) {
@@ -422,6 +634,7 @@ export async function* streamFeedResilient(client, options = {}) {
422
634
  try {
423
635
  for await (const frame of streamFeed(client, {
424
636
  ...streamOptions,
637
+ ...connectionOptions,
425
638
  cursor,
426
639
  lastEventId: cursor.seq ?? initialLastEventId,
427
640
  })) {
@@ -607,6 +820,12 @@ export async function consumeStreamCheckpointed(client, handlers, options = {})
607
820
  if (!Number.isInteger(maxHandlerRetries) || maxHandlerRetries < 0) {
608
821
  throw new Error(`maxHandlerRetries must be a non-negative integer, got ${String(maxHandlerRetries)}`);
609
822
  }
823
+ streamConnectionOptions(streamOptions);
824
+ const maxReconnects = streamOptions.maxReconnects ?? DEFAULT_MAX_STREAM_RECONNECTS;
825
+ if (!Number.isInteger(maxReconnects) || maxReconnects < 0) {
826
+ throw new Error(`maxReconnects must be a non-negative integer, got ${String(maxReconnects)}`);
827
+ }
828
+ assertMaxRetryAfterMs(streamOptions.maxRetryAfterMs ?? DEFAULT_MAX_STREAM_RETRY_AFTER_MS);
610
829
  const signal = streamOptions.signal;
611
830
  // The caller's received cursor, if they passed one. It keeps its delivery
612
831
  // meaning: this consumer mirrors every frame into it and never reads it
@@ -829,7 +1048,7 @@ export function decodeStreamFrame(parsed, lastSeq) {
829
1048
  if (!isPlainObject(payload)) {
830
1049
  throw new StreamProtocolError("invalid_resync", detail);
831
1050
  }
832
- if ("type" in payload && payload.type !== "resync") {
1051
+ if ("type" in payload && payload["type"] !== "resync") {
833
1052
  throw new StreamProtocolError("invalid_resync", detail);
834
1053
  }
835
1054
  return {
@@ -844,8 +1063,8 @@ export function decodeStreamFrame(parsed, lastSeq) {
844
1063
  if (!isPlainObject(payload)) {
845
1064
  throw new StreamProtocolError("invalid_envelope", detail);
846
1065
  }
847
- const seq = typeof payload.seq === "number" && Number.isFinite(payload.seq)
848
- ? payload.seq
1066
+ const seq = typeof payload["seq"] === "number" && Number.isFinite(payload["seq"])
1067
+ ? payload["seq"]
849
1068
  : parsed.id;
850
1069
  if (seq === undefined || !Number.isFinite(seq)) {
851
1070
  throw new StreamProtocolError("unusable_sequence", detail);
@@ -892,13 +1111,13 @@ const permanentTerminalErrors = new WeakSet();
892
1111
  * consumer's reconnect path like any 5xx.
893
1112
  */
894
1113
  function terminalStreamError(payload, detail) {
895
- if (!isPlainObject(payload) || !isPlainObject(payload.error)) {
1114
+ if (!isPlainObject(payload) || !isPlainObject(payload["error"])) {
896
1115
  return new StreamProtocolError("invalid_envelope", detail);
897
1116
  }
898
- const body = payload.error;
899
- const retry = payload.retry === true;
900
- const code = typeof body.code === "string" ? body.code : undefined;
901
- const reason = typeof body.reason === "string" ? body.reason : undefined;
1117
+ const body = payload["error"];
1118
+ const retry = payload["retry"] === true;
1119
+ const code = typeof body["code"] === "string" ? body["code"] : undefined;
1120
+ const reason = typeof body["reason"] === "string" ? body["reason"] : undefined;
902
1121
  const status = reason !== undefined && STREAM_ERROR_UNAVAILABLE_REASONS.has(reason)
903
1122
  ? 503
904
1123
  : ((code !== undefined ? STREAM_ERROR_CODE_STATUS[code] : undefined) ??
@@ -911,22 +1130,4 @@ function terminalStreamError(payload, detail) {
911
1130
  function isPlainObject(value) {
912
1131
  return typeof value === "object" && value !== null && !Array.isArray(value);
913
1132
  }
914
- function tryParse(text) {
915
- if (text === null || text === "")
916
- return null;
917
- try {
918
- return JSON.parse(text);
919
- }
920
- catch {
921
- return null;
922
- }
923
- }
924
- async function safeText(response) {
925
- try {
926
- return await response.text();
927
- }
928
- catch {
929
- return "";
930
- }
931
- }
932
1133
  //# sourceMappingURL=stream.js.map