@0xinsider/mcp 2.0.1 → 2.1.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 (100) hide show
  1. package/README.md +27 -7
  2. package/dist/catalog.generated.d.ts +4 -0
  3. package/dist/catalog.generated.d.ts.map +1 -1
  4. package/dist/catalog.generated.js +5 -0
  5. package/dist/catalog.generated.js.map +1 -1
  6. package/dist/cli-lib.d.ts +1 -0
  7. package/dist/cli-lib.d.ts.map +1 -1
  8. package/dist/cli-lib.js +48 -8
  9. package/dist/cli-lib.js.map +1 -1
  10. package/dist/client.d.ts +36 -2
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +42 -4
  13. package/dist/client.js.map +1 -1
  14. package/dist/constants.d.ts +1 -1
  15. package/dist/constants.js +1 -1
  16. package/dist/product-cli/client.d.ts +3 -2
  17. package/dist/product-cli/client.d.ts.map +1 -1
  18. package/dist/product-cli/client.js.map +1 -1
  19. package/dist/sdk/client.d.ts +705 -131
  20. package/dist/sdk/client.d.ts.map +1 -1
  21. package/dist/sdk/client.js +719 -125
  22. package/dist/sdk/client.js.map +1 -1
  23. package/dist/sdk/errors.d.ts +42 -4
  24. package/dist/sdk/errors.d.ts.map +1 -1
  25. package/dist/sdk/errors.js +103 -2
  26. package/dist/sdk/errors.js.map +1 -1
  27. package/dist/sdk/index.d.ts +9 -8
  28. package/dist/sdk/index.d.ts.map +1 -1
  29. package/dist/sdk/index.js +6 -4
  30. package/dist/sdk/index.js.map +1 -1
  31. package/dist/sdk/pagination.d.ts +133 -15
  32. package/dist/sdk/pagination.d.ts.map +1 -1
  33. package/dist/sdk/pagination.js +132 -34
  34. package/dist/sdk/pagination.js.map +1 -1
  35. package/dist/sdk/retry.d.ts +68 -0
  36. package/dist/sdk/retry.d.ts.map +1 -0
  37. package/dist/sdk/retry.js +125 -0
  38. package/dist/sdk/retry.js.map +1 -0
  39. package/dist/sdk/schema.d.ts +1536 -430
  40. package/dist/sdk/schema.d.ts.map +1 -1
  41. package/dist/sdk/stream.d.ts +318 -8
  42. package/dist/sdk/stream.d.ts.map +1 -1
  43. package/dist/sdk/stream.js +503 -56
  44. package/dist/sdk/stream.js.map +1 -1
  45. package/dist/sdk/webhooks.d.ts +18 -3
  46. package/dist/sdk/webhooks.d.ts.map +1 -1
  47. package/dist/sdk/webhooks.js +13 -1
  48. package/dist/sdk/webhooks.js.map +1 -1
  49. package/dist/server.d.ts.map +1 -1
  50. package/dist/server.js +2 -1
  51. package/dist/server.js.map +1 -1
  52. package/dist/tools/explore-markets.d.ts.map +1 -1
  53. package/dist/tools/explore-markets.js +2 -5
  54. package/dist/tools/explore-markets.js.map +1 -1
  55. package/dist/tools/get-insider-radar.d.ts.map +1 -1
  56. package/dist/tools/get-insider-radar.js +3 -10
  57. package/dist/tools/get-insider-radar.js.map +1 -1
  58. package/dist/tools/get-large-positions.d.ts.map +1 -1
  59. package/dist/tools/get-large-positions.js +3 -10
  60. package/dist/tools/get-large-positions.js.map +1 -1
  61. package/dist/tools/get-leaderboard.d.ts.map +1 -1
  62. package/dist/tools/get-leaderboard.js +3 -10
  63. package/dist/tools/get-leaderboard.js.map +1 -1
  64. package/dist/tools/get-market-intel.d.ts.map +1 -1
  65. package/dist/tools/get-market-intel.js +3 -6
  66. package/dist/tools/get-market-intel.js.map +1 -1
  67. package/dist/tools/get-position-timeline.d.ts.map +1 -1
  68. package/dist/tools/get-position-timeline.js +3 -10
  69. package/dist/tools/get-position-timeline.js.map +1 -1
  70. package/dist/tools/get-positions.d.ts +2 -0
  71. package/dist/tools/get-positions.d.ts.map +1 -1
  72. package/dist/tools/get-positions.js +8 -11
  73. package/dist/tools/get-positions.js.map +1 -1
  74. package/dist/tools/get-trader-pnl.d.ts.map +1 -1
  75. package/dist/tools/get-trader-pnl.js +3 -6
  76. package/dist/tools/get-trader-pnl.js.map +1 -1
  77. package/dist/tools/get-trader.d.ts.map +1 -1
  78. package/dist/tools/get-trader.js +3 -6
  79. package/dist/tools/get-trader.js.map +1 -1
  80. package/dist/tools/get-trending-wallets.d.ts.map +1 -1
  81. package/dist/tools/get-trending-wallets.js +3 -10
  82. package/dist/tools/get-trending-wallets.js.map +1 -1
  83. package/dist/tools/get-whale-trades.d.ts.map +1 -1
  84. package/dist/tools/get-whale-trades.js +4 -11
  85. package/dist/tools/get-whale-trades.js.map +1 -1
  86. package/dist/tools/pick-of-the-day.d.ts.map +1 -1
  87. package/dist/tools/pick-of-the-day.js +5 -21
  88. package/dist/tools/pick-of-the-day.js.map +1 -1
  89. package/dist/tools/read-parity.d.ts +1 -0
  90. package/dist/tools/read-parity.d.ts.map +1 -1
  91. package/dist/tools/read-parity.js +69 -44
  92. package/dist/tools/read-parity.js.map +1 -1
  93. package/dist/tools/result.d.ts +31 -0
  94. package/dist/tools/result.d.ts.map +1 -0
  95. package/dist/tools/result.js +70 -0
  96. package/dist/tools/result.js.map +1 -0
  97. package/dist/tools/search-markets.d.ts.map +1 -1
  98. package/dist/tools/search-markets.js +16 -11
  99. package/dist/tools/search-markets.js.map +1 -1
  100. package/package.json +4 -4
@@ -21,8 +21,27 @@
21
21
  *
22
22
  * Filters (per-connection, subscribe-time): `event` (comma-separated frame
23
23
  * types), `condition_id`, and `min_grade` (S|A|B|C|D|F).
24
+ *
25
+ * Protocol validity (#16248). The decoder is bounded and fails visibly:
26
+ * - A successful response whose media type is not `text/event-stream` is
27
+ * `StreamProtocolError` (`unexpected_media_type`), not an empty stream.
28
+ * - A data frame whose payload is not JSON, not an object, or has no usable
29
+ * sequence (a finite `seq` in the envelope, or a finite SSE `id`) is a
30
+ * `StreamProtocolError` (`invalid_json`, `invalid_envelope`,
31
+ * `unusable_sequence`); a resync frame whose payload is not an object is
32
+ * `invalid_resync`. Before #16248 such frames were skipped or yielded with
33
+ * `NaN`, and the next valid frame moved the cursor past the gap.
34
+ * - A frame that has not reached its blank-line delimiter after
35
+ * `maxFrameBytes` (default 1 MiB) is `frame_too_large`; the reader is
36
+ * released and the connection closed.
37
+ * - The error carries `lastSeq`, the last sequence delivered before it, so a
38
+ * malformed frame never moves the cursor and a caller can decide whether
39
+ * to resume from there (which replays the frame while it is retained),
40
+ * skip past `frameId`, or refetch state. No raw payload is on the error.
41
+ * Comment lines (`: keep-alive`), LF and CRLF framing, unknown SSE fields
42
+ * and unknown-but-valid envelope `type`s are compatible as before.
24
43
  */
25
- import type { Grade, OxinsiderApiClient } from "./client.js";
44
+ import { type Grade, type OxinsiderApiClient } from "./client.js";
26
45
  /** A live feed envelope frame: `{ seq, published_at, type, ...payload }`. */
27
46
  export interface FeedEnvelope {
28
47
  /** Cluster-shared monotonic sequence id; also the SSE event id. */
@@ -68,14 +87,78 @@ export interface StreamOptions extends StreamFilters {
68
87
  /** Invoked once for the resync marker frame, if one is emitted. */
69
88
  onResync?: (marker: ResyncMarker) => void;
70
89
  /**
71
- * Optional cursor object whose `seq` is updated to the last delivered
90
+ * Optional cursor object whose `seq` is updated to the last DELIVERED
72
91
  * envelope `seq` as frames arrive. Pass the same object back as
73
92
  * `lastEventId: cursor.seq` on reconnect to resume from where you left off.
93
+ *
94
+ * Received, not processed (#16247). It is written before the frame reaches
95
+ * your code, so it says the frame arrived and nothing about whether your
96
+ * handling of it succeeded: resuming from it after a handler failure skips
97
+ * that event. When losing an event would lose work, drive the stream with
98
+ * `consumeStreamCheckpointed`, whose `StreamCheckpoint` advances only after
99
+ * the handler and your durable write resolve, and keep this cursor for
100
+ * transport progress.
74
101
  */
75
102
  cursor?: {
76
103
  seq?: number;
77
104
  };
105
+ /**
106
+ * Byte ceiling for one undelivered frame (#16248). Default
107
+ * `DEFAULT_MAX_STREAM_FRAME_BYTES` (1 MiB). A connection that sends more
108
+ * than this without a blank-line delimiter ends with
109
+ * `StreamProtocolError` (`frame_too_large`) and the reader is released.
110
+ * A positive finite integer; the largest real frame is a few KB.
111
+ */
112
+ maxFrameBytes?: number;
113
+ }
114
+ /** Default for `StreamOptions.maxFrameBytes`: 1 MiB. */
115
+ export declare const DEFAULT_MAX_STREAM_FRAME_BYTES = 1048576;
116
+ /** What the stream did that the SSE contract does not allow. */
117
+ export type StreamProtocolErrorReason =
118
+ /** A 2xx whose `Content-Type` is not `text/event-stream`. */
119
+ "unexpected_media_type"
120
+ /** A data frame whose payload is not JSON. */
121
+ | "invalid_json"
122
+ /** A data frame whose payload is JSON but not an object (or is `null`, an array). */
123
+ | "invalid_envelope"
124
+ /** A data frame with no finite `seq` in the envelope and no finite SSE `id`. */
125
+ | "unusable_sequence"
126
+ /** A resync frame whose payload is not an object, or whose `type` is not `resync`. */
127
+ | "invalid_resync"
128
+ /** A frame grew past `maxFrameBytes` without reaching its delimiter. */
129
+ | "frame_too_large";
130
+ /**
131
+ * The stream broke the SSE contract (#16248). The connection is closed and
132
+ * the reader released before this is thrown. `lastSeq` is the last sequence
133
+ * delivered on this connection, or `undefined` when none was: no malformed
134
+ * frame moves the cursor. `frameId` is the SSE `id` of the offending frame
135
+ * when it carried one, `event` its SSE event name, `bytes` its size, and
136
+ * `mediaType` the response's `Content-Type` for `unexpected_media_type`. The
137
+ * raw payload is deliberately not carried: it may hold data you would not
138
+ * want in a log, and `frameId` plus `lastSeq` name the frame exactly.
139
+ *
140
+ * `streamFeedResilient` treats this as permanent: reconnecting from
141
+ * `lastSeq` would replay the same frame while the server retains it. Decide:
142
+ * resume from `lastSeq` later, resume after `frameId` to skip it, or refetch
143
+ * state and attach live.
144
+ */
145
+ export declare class StreamProtocolError extends Error {
146
+ readonly reason: StreamProtocolErrorReason;
147
+ readonly lastSeq: number | undefined;
148
+ readonly frameId: number | undefined;
149
+ readonly event: string | undefined;
150
+ readonly bytes: number | undefined;
151
+ readonly mediaType: string | undefined;
152
+ constructor(reason: StreamProtocolErrorReason, detail: {
153
+ lastSeq: number | undefined;
154
+ frameId?: number;
155
+ event?: string;
156
+ bytes?: number;
157
+ mediaType?: string | null;
158
+ });
78
159
  }
160
+ /** `Content-Type` names an event stream: `text/event-stream`, with or without parameters. */
161
+ export declare function isEventStreamMediaType(contentType: string | null): boolean;
79
162
  /** One yielded item from the stream iterator. */
80
163
  export type StreamEvent = {
81
164
  kind: "event";
@@ -114,9 +197,23 @@ export interface ResilientStreamOptions extends StreamOptions {
114
197
  * the previous connection ended (`undefined` for a clean server close).
115
198
  */
116
199
  onReconnect?: (attempt: number, lastSeq: number | undefined, cause: unknown) => void;
200
+ /**
201
+ * The longest server-requested wait (`Retry-After`) the loop holds
202
+ * in-process, in ms. Default `DEFAULT_MAX_STREAM_RETRY_AFTER_MS` (60 000,
203
+ * the REST client's ceiling). A refusal asking for longer ends the loop
204
+ * with `StreamRetryDeferredError`, which carries the not-before instant
205
+ * (`retryAt`) and the seq to resume after (`lastSeq`), so the wait is
206
+ * yours to schedule and no reconnect is spent on it. `Infinity` opts into
207
+ * waiting however long the server says, in timer-sized chunks; it can hold
208
+ * the process for days on a `monthly_quota_exceeded` refusal, which is why
209
+ * it is not the default (#16249).
210
+ */
211
+ maxRetryAfterMs?: number;
117
212
  }
118
213
  /** Default for `ResilientStreamOptions.maxReconnects`. */
119
214
  export declare const DEFAULT_MAX_STREAM_RECONNECTS = 10;
215
+ /** Default for `ResilientStreamOptions.maxRetryAfterMs`. */
216
+ export declare const DEFAULT_MAX_STREAM_RETRY_AFTER_MS = 60000;
120
217
  /**
121
218
  * `streamFeedResilient` gave up after `maxReconnects` consecutive failed
122
219
  * connections. `lastSeq` is the seq to resume after (pass it as `lastEventId`
@@ -127,16 +224,42 @@ export declare class StreamReconnectsExhaustedError extends Error {
127
224
  readonly attempts: number;
128
225
  constructor(attempts: number, lastSeq: number | undefined, cause: unknown);
129
226
  }
227
+ /**
228
+ * `streamFeedResilient` was refused with a `Retry-After` longer than
229
+ * `maxRetryAfterMs`, so the wait is yours to schedule (#16249). `retryAt` is
230
+ * the server's not-before instant as this client read it (the header's
231
+ * seconds added to the local clock, or the header's HTTP-date); `cause` is
232
+ * the refusal, whose `retryAt` (from the body's `retry_at`) is the server's
233
+ * own clock reading of the same instant. `lastSeq` is the seq to resume after:
234
+ * pass it as `lastEventId` when you reconnect at `retryAt`. `attempts` is how
235
+ * many consecutive failed connections preceded this one; the refusal itself
236
+ * spent none of `maxReconnects`.
237
+ *
238
+ * Nothing here was clamped: a wait the timer cannot hold is never shortened
239
+ * into an earlier reconnect.
240
+ */
241
+ export declare class StreamRetryDeferredError extends Error {
242
+ readonly retryAt: Date;
243
+ readonly retryAfterMs: number;
244
+ readonly lastSeq: number | undefined;
245
+ readonly attempts: number;
246
+ constructor(retryAfterMs: number, lastSeq: number | undefined, attempts: number, cause: unknown);
247
+ }
130
248
  /**
131
249
  * `streamFeed` with the reconnect-and-resume loop built in (#14286).
132
250
  *
133
251
  * - A clean server close, a network error, a 429 or a 5xx reconnects,
134
252
  * resuming after the last delivered seq (`Last-Event-ID`). Before any frame
135
253
  * arrives it resumes from `lastEventId`, or attaches live when that is unset.
136
- * - The wait is `Retry-After` plus jitter when the refusal carries one,
137
- * otherwise a jittered backoff from 1 s capped at 30 s.
254
+ * - The wait is `Retry-After` (delta-seconds or an HTTP-date) plus jitter when
255
+ * the refusal carries one, otherwise a jittered backoff from 1 s capped at
256
+ * 30 s. A `Retry-After` past `maxRetryAfterMs` (60 s by default) is not
257
+ * waited out: the loop throws `StreamRetryDeferredError` with `retryAt` and
258
+ * `lastSeq`, spending no reconnect, and never clamps the wait to an earlier
259
+ * one (#16249).
138
260
  * - Any other 4xx (400, 401, 402, 403, 423) is thrown at once: it cannot heal
139
- * on its own.
261
+ * on its own. So is `StreamProtocolError` (#16248): a resume from
262
+ * `lastSeq` would replay the malformed frame, so the decision is yours.
140
263
  * - After `maxReconnects` consecutive connections that delivered nothing, it
141
264
  * throws `StreamReconnectsExhaustedError` carrying `lastSeq`.
142
265
  * - `resync` markers are yielded unchanged, and `onResync` still fires. The
@@ -148,7 +271,10 @@ export declare class StreamReconnectsExhaustedError extends Error {
148
271
  * - No request deadline applies, as with `streamFeed`.
149
272
  *
150
273
  * `options.cursor`, when passed, tracks the last delivered seq across every
151
- * connection.
274
+ * connection -- delivered, not processed (#16247). This loop resumes from it,
275
+ * so a consumer whose handler can fail should drive the stream with
276
+ * `consumeStreamCheckpointed` instead, which resumes from an acknowledged
277
+ * checkpoint and replays the event it failed on.
152
278
  *
153
279
  * @example
154
280
  * const controller = new AbortController();
@@ -166,17 +292,201 @@ export declare function streamFeedResilient(client: OxinsiderApiClient, options?
166
292
  * Callback-style stream consumer for environments where an async iterator is
167
293
  * awkward. Returns a promise that resolves when the stream ends (or rejects on
168
294
  * error / abort). Pass a `signal` to stop it.
295
+ *
296
+ * Delivery, not processing (#16247): `options.cursor` is written by
297
+ * `streamFeed` BEFORE the frame is yielded, so it has already moved past an
298
+ * event whose `onEvent` then throws. Reconnecting from it skips that event.
299
+ * For a consumer that must not lose work, use `consumeStreamCheckpointed`,
300
+ * which advances an acknowledged checkpoint only after the handler and your
301
+ * own durable write have both resolved.
169
302
  */
170
303
  export declare function consumeStream(client: OxinsiderApiClient, handlers: {
171
304
  onEvent?: (envelope: FeedEnvelope, seq: number) => void | Promise<void>;
172
305
  onResync?: (marker: ResyncMarker, seq: number | null) => void | Promise<void>;
173
306
  }, options?: StreamOptions): Promise<void>;
174
- interface ParsedSseFrame {
307
+ /**
308
+ * An acknowledged processing checkpoint (#16247): the last `seq` whose
309
+ * handling COMPLETED, which is not the same thing as the last `seq` that
310
+ * arrived. `StreamOptions.cursor` is the received cursor -- transport
311
+ * progress, written before the frame is handed to you. This is the processed
312
+ * one, written after your handler and your own durable write have resolved.
313
+ *
314
+ * Own the object if you persist the checkpoint yourself: pass it in, read
315
+ * `seq` after the consumer returns or throws, and pass the stored value back
316
+ * as `lastEventId` when you resume in a later process.
317
+ */
318
+ export interface StreamCheckpoint {
319
+ /** The last acknowledged sequence, or `undefined` until one is acknowledged. */
320
+ seq?: number;
321
+ }
322
+ /** What the checkpoint advanced past: a feed envelope, or a resync refresh. */
323
+ export type StreamCheckpointReason = "event" | "resync";
324
+ /**
325
+ * Which awaited step rejected: your event handler, your resync refresh, or
326
+ * your `onCheckpoint` durable write.
327
+ */
328
+ export type StreamHandlerStage = "event" | "resync" | "checkpoint";
329
+ /** The recovery state around one handler failure, as it is decided. */
330
+ export interface StreamHandlerFailure {
331
+ /**
332
+ * The sequence whose processing failed; `undefined` only for a resync
333
+ * marker that carried no SSE id.
334
+ */
335
+ seq: number | undefined;
336
+ /** Which awaited step rejected. */
337
+ stage: StreamHandlerStage;
338
+ /** 1-based consecutive failures at this sequence. Resets on any success. */
339
+ attempt: number;
340
+ /** Whether the consumer will reconnect and replay, or throw next. */
341
+ willRetry: boolean;
342
+ /**
343
+ * The sequence the replay resumes AFTER, so the failed frame is delivered
344
+ * again while the server retains it. `undefined` means the replay attaches
345
+ * live and the failed frame is gone: that happens only when nothing has
346
+ * been acknowledged, no `lastEventId` was given, and the failing sequence
347
+ * is not a positive integer to step back from.
348
+ */
349
+ replayFrom: number | undefined;
350
+ /** The acknowledged checkpoint, which this failure did NOT advance. */
351
+ checkpoint: number | undefined;
352
+ }
353
+ /**
354
+ * `consumeStreamCheckpointed` gave up after `maxHandlerRetries` consecutive
355
+ * failures at the same sequence (#16247). `checkpoint` is the acknowledged
356
+ * sequence, still behind the failing one, and `replayFrom` is the point a
357
+ * later resume should pass as `lastEventId` to deliver the failed frame
358
+ * again while the server retains it. `cause` is the last rejection your
359
+ * handler produced.
360
+ */
361
+ export declare class StreamHandlerFailedError extends Error {
362
+ readonly seq: number | undefined;
363
+ readonly stage: StreamHandlerStage;
364
+ readonly attempts: number;
365
+ readonly checkpoint: number | undefined;
366
+ readonly replayFrom: number | undefined;
367
+ constructor(detail: {
368
+ seq: number | undefined;
369
+ stage: StreamHandlerStage;
370
+ attempts: number;
371
+ checkpoint: number | undefined;
372
+ replayFrom: number | undefined;
373
+ }, cause: unknown);
374
+ }
375
+ /** Default for `CheckpointedStreamOptions.maxHandlerRetries`. */
376
+ export declare const DEFAULT_MAX_HANDLER_RETRIES = 3;
377
+ export interface CheckpointedStreamOptions extends ResilientStreamOptions {
378
+ /**
379
+ * Where the acknowledged checkpoint is written. Pass your own object to
380
+ * read it after the consumer returns; omit it and the consumer keeps one
381
+ * internally, which `onCheckpoint` still reports.
382
+ */
383
+ checkpoint?: StreamCheckpoint;
384
+ /**
385
+ * Consecutive failures at the SAME sequence tolerated before the consumer
386
+ * throws `StreamHandlerFailedError`. Each retry closes the connection and
387
+ * replays from the checkpoint after a jittered backoff (1 s to 30 s). `0`
388
+ * gives up on the first failure. Default `DEFAULT_MAX_HANDLER_RETRIES` (3).
389
+ */
390
+ maxHandlerRetries?: number;
391
+ /**
392
+ * Called on every handler failure with the recovery state, before the
393
+ * backoff and before any throw. It is the visible signal that work is being
394
+ * replayed rather than lost; it is not awaited and must not throw.
395
+ */
396
+ onHandlerError?: (error: unknown, failure: StreamHandlerFailure) => void;
397
+ }
398
+ export interface CheckpointedStreamHandlers {
399
+ /**
400
+ * Apply one feed envelope. Awaited: the connection is not read again until
401
+ * it settles. Reject to leave the checkpoint before this event.
402
+ */
403
+ onEvent: (envelope: FeedEnvelope, seq: number) => void | Promise<void>;
404
+ /**
405
+ * Refresh state after a resync marker. Awaited, so it is a real barrier:
406
+ * the checkpoint moves to the marker only once this resolves. Reject and
407
+ * the refresh is retried under the same bounded policy as an event.
408
+ */
409
+ onResync?: (marker: ResyncMarker, seq: number | null) => void | Promise<void>;
410
+ /**
411
+ * Persist the checkpoint. Awaited BEFORE the in-memory checkpoint advances,
412
+ * so a failed write leaves the checkpoint where it was and the event is
413
+ * replayed rather than lost.
414
+ */
415
+ onCheckpoint?: (seq: number, reason: StreamCheckpointReason) => void | Promise<void>;
416
+ }
417
+ /**
418
+ * The stream consumer for work that must not be silently dropped (#16247):
419
+ * it separates the received cursor from an acknowledged processing
420
+ * checkpoint, and only the checkpoint decides where a reconnect resumes.
421
+ *
422
+ * Ordering, per frame, for `kind: "event"`:
423
+ * 1. `onEvent` is awaited. Nothing is read from the connection while it
424
+ * runs, so a slow handler is backpressure on the socket, never a queue:
425
+ * at most one frame is ever in flight and nothing is buffered on your
426
+ * behalf.
427
+ * 2. `onCheckpoint(seq, "event")` is awaited -- your durable write.
428
+ * 3. Only then does `checkpoint.seq` become `seq`, and only then does the
429
+ * next reconnect resume after it.
430
+ * A rejection at step 1 or 2 leaves the checkpoint BEFORE the event: the
431
+ * connection is closed, a jittered backoff runs, and the consumer reconnects
432
+ * from the checkpoint, which replays the unacknowledged event while the
433
+ * server retains it. `onHandlerError` reports each failure with its attempt
434
+ * number, the replay point and whether another attempt follows. After
435
+ * `maxHandlerRetries` consecutive failures at the same sequence it throws
436
+ * `StreamHandlerFailedError`, carrying the unadvanced checkpoint.
437
+ *
438
+ * A `resync` marker is the same barrier: `onResync` is awaited, then
439
+ * `onCheckpoint(seq, "resync")`, and an interrupted refresh commits nothing,
440
+ * so the recovery is retried instead of being recorded as done. (The
441
+ * fire-and-forget `StreamOptions.onResync` notification is not awaited and is
442
+ * not a barrier -- do not use it as one.)
443
+ *
444
+ * Delivery is AT-LEAST-ONCE. A replay re-delivers every unacknowledged frame,
445
+ * and a handler that succeeded but whose `onCheckpoint` write failed sees its
446
+ * event again. Deduplicate on `seq` (it is monotonic per cluster) or make the
447
+ * side effect idempotent; nothing here can promise exactly-once side effects.
448
+ *
449
+ * `options.cursor` is untouched in meaning: it still tracks the last
450
+ * DELIVERED seq, including frames whose handler later failed, and it rewinds
451
+ * when a replay re-delivers them. Read it for transport progress; never as
452
+ * proof that the work was done.
453
+ *
454
+ * Transport recovery, `Retry-After` handling, permanent 4xx and
455
+ * `StreamProtocolError` behave exactly as in `streamFeedResilient`, which
456
+ * this drives. `StreamReconnectsExhaustedError` and
457
+ * `StreamRetryDeferredError` surface unchanged; their `lastSeq` is the
458
+ * acknowledged checkpoint, because a reconnect can only happen between
459
+ * handlers. Aborting `signal` ends the consumer without throwing: a handler
460
+ * already running is awaited (it is not cancelled for you -- pass the same
461
+ * signal into your own work if you want that), and if it succeeds its
462
+ * checkpoint is committed before the consumer returns.
463
+ *
464
+ * @example
465
+ * const checkpoint = { seq: await loadCheckpoint() };
466
+ * await consumeStreamCheckpointed(client, {
467
+ * onEvent: async (envelope, seq) => { await applyOnce(seq, envelope); },
468
+ * onResync: async () => { await refetchCurrentState(); },
469
+ * onCheckpoint: async (seq) => { await saveCheckpoint(seq); },
470
+ * }, {
471
+ * event: ["WhaleTradesInserted"],
472
+ * lastEventId: checkpoint.seq,
473
+ * checkpoint,
474
+ * signal: controller.signal,
475
+ * onHandlerError: (error, failure) =>
476
+ * console.warn("replaying", failure.seq, failure.attempt, failure.willRetry, error),
477
+ * });
478
+ */
479
+ export declare function consumeStreamCheckpointed(client: OxinsiderApiClient, handlers: CheckpointedStreamHandlers, options?: CheckpointedStreamOptions): Promise<void>;
480
+ export interface ParsedSseFrame {
175
481
  event?: string;
176
482
  id?: number;
177
483
  data: string;
178
484
  }
179
485
  /** Parse one SSE frame (without the trailing blank line). */
180
486
  export declare function parseSseFrame(raw: string): ParsedSseFrame | null;
181
- export {};
487
+ /**
488
+ * Turn one parsed SSE frame into a `StreamEvent`, or throw
489
+ * `StreamProtocolError` (#16248). `lastSeq` is only carried onto the error.
490
+ */
491
+ export declare function decodeStreamFrame(parsed: ParsedSseFrame, lastSeq: number | undefined): StreamEvent;
182
492
  //# sourceMappingURL=stream.d.ts.map
@@ -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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"}