@0xinsider/mcp 2.1.0 → 2.4.0

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