madeonsol-x402 2.1.0 → 2.3.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.
- package/README.md +570 -525
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/stream.d.ts +422 -12
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +982 -43
- package/dist/stream.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/stream.d.ts
CHANGED
|
@@ -7,26 +7,270 @@
|
|
|
7
7
|
* not expire: `getToken()` is called on every (re)connect and returns the
|
|
8
8
|
* same value until the subscription lapses or you explicitly rotate it.
|
|
9
9
|
*
|
|
10
|
+
* Recovery (v1 resume): the client remembers a cursor `{instance, seq, ts}` —
|
|
11
|
+
* the last frame whose handlers finished — and on every reconnect asks the
|
|
12
|
+
* server to resume after it (`subscribe {…, resume}`); against an older server
|
|
13
|
+
* it falls back to `replay_since_seq` (same process) / `replay_since_ts`
|
|
14
|
+
* (restarted). Delivery is at-least-once, de-duplicated by event `id`; a
|
|
15
|
+
* `"gap"` event says what could NOT be recovered. `seq` gaps are normal and
|
|
16
|
+
* never mean loss. Close codes: 4001 re-fetches the token (bounded, then
|
|
17
|
+
* `"fatal"`), 4002 (connection limit) waits ≥ 60 s, 4003 stops with
|
|
18
|
+
* `"fatal"`, 4008 (slow consumer) reconnects and resumes.
|
|
19
|
+
*
|
|
10
20
|
* Works in Node (uses the global `WebSocket` on Node 22+, else lazily imports
|
|
11
21
|
* the optional `ws` package) and the browser (native WebSocket). Zero required
|
|
12
22
|
* dependencies.
|
|
13
23
|
*/
|
|
14
24
|
import type { StreamToken } from "./types.js";
|
|
15
|
-
/** Channels you can subscribe to. */
|
|
16
|
-
export type StreamChannel = "kol:trades" | "kol:coordination" | "kol:first_touches" | "deployer:alerts" | "wallet_tracker:events" | "copytrade:signals" | "price_alert:events" | "sniper:deploys" | "token:graduations" | "token:locks" | "token:fee_claims" | "token:surges";
|
|
25
|
+
/** Channels you can subscribe to (mirrors the server registry, services/shared/stream-channels.mjs). */
|
|
26
|
+
export type StreamChannel = "kol:trades" | "kol:coordination" | "kol:first_touches" | "deployer:alerts" | "wallet_tracker:events" | "copytrade:signals" | "price_alert:events" | "sniper:deploys" | "token:graduations" | "token:prices" | "token:locks" | "token:fee_claims" | "token:surges";
|
|
27
|
+
/** Every Solana channel, in the server's order. */
|
|
28
|
+
export declare const STREAM_CHANNELS: readonly StreamChannel[];
|
|
17
29
|
/** Event names delivered on those channels (subscribe to a channel, receive these). */
|
|
18
|
-
export type StreamEventName = "kol:trade" | "kol:coordination" | "kol:first_touch" | "deployer:alert" | "deployer:bond" | "wallet_tracker:event" | "copytrade:signal" | "price_alert:dip" | "price_alert:recovery" | "sniper:deploy" | "token:graduation" | "token:lock" | "token:fee_claim" | "token:surge" | "token:revival";
|
|
30
|
+
export type StreamEventName = "kol:trade" | "kol:coordination" | "kol:first_touch" | "deployer:alert" | "deployer:bond" | "wallet_tracker:event" | "copytrade:signal" | "price_alert:dip" | "price_alert:recovery" | "sniper:deploy" | "token:graduation" | "token:price" | "token:lock" | "token:fee_claim" | "token:surge" | "token:revival";
|
|
19
31
|
/** Lifecycle events you can also listen for. */
|
|
20
|
-
export type StreamLifecycleEvent = "open" | "close" | "reconnect" | "subscribed" | "heartbeat" | "error";
|
|
32
|
+
export type StreamLifecycleEvent = "open" | "close" | "reconnect" | "subscribed" | "updated" | "unsubscribed" | "heartbeat" | "warning" | "cursor" | "replay" | "gap" | "fatal" | "error";
|
|
33
|
+
/**
|
|
34
|
+
* A server `type: "warning"` frame, surfaced as the `"warning"` lifecycle
|
|
35
|
+
* event. Known codes: `channels_rejected` (a subscribe named a channel that
|
|
36
|
+
* does not exist or that your tier cannot hold — each with a reason, plus the
|
|
37
|
+
* full list of channels it accepts) and `channels_revoked` (the server dropped
|
|
38
|
+
* channels you held, e.g. after a plan downgrade). A rejected or revoked
|
|
39
|
+
* channel is silent, so never ignore these.
|
|
40
|
+
*/
|
|
41
|
+
export interface StreamWarning {
|
|
42
|
+
/**
|
|
43
|
+
* Machine-readable code: `channels_rejected`, `channels_revoked`,
|
|
44
|
+
* `replay_in_progress`, and for named subscriptions `invalid_sub_id`,
|
|
45
|
+
* `too_many_subscriptions`, `unknown_sub_id`, `invalid_filters`; the client
|
|
46
|
+
* itself emits `named_subscriptions_unsupported` once when the server
|
|
47
|
+
* ignores `sub_id` (older deployment).
|
|
48
|
+
*/
|
|
49
|
+
code?: string;
|
|
50
|
+
/** The named subscription the warning is about (absent for the default one). */
|
|
51
|
+
sub_id?: string;
|
|
52
|
+
/** Channels the server refused, each with a human-readable reason. */
|
|
53
|
+
rejected?: Array<{
|
|
54
|
+
channel: string;
|
|
55
|
+
reason: string;
|
|
56
|
+
}>;
|
|
57
|
+
/** Channels the server removed from this connection (channels_revoked). */
|
|
58
|
+
revoked?: Array<{
|
|
59
|
+
channel: string;
|
|
60
|
+
reason: string;
|
|
61
|
+
}> | string[];
|
|
62
|
+
/** Every channel the server accepts. */
|
|
63
|
+
valid_channels?: string[];
|
|
64
|
+
/** Optional human-readable message (not sent on every warning). */
|
|
65
|
+
message?: string;
|
|
66
|
+
/** Server timestamp (ms). */
|
|
67
|
+
ts?: number;
|
|
68
|
+
[key: string]: unknown;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resume cursor = the last SAFE point: every event up to it has been
|
|
72
|
+
* processed ("processed" = every handler for that frame returned, or the
|
|
73
|
+
* promise it returned settled). Two positions are kept:
|
|
74
|
+
* - `getProgress()` — what has been received and handled, including replayed frames;
|
|
75
|
+
* - `getCursor()` — the COMMITTED cursor, the only one to persist and resume from.
|
|
76
|
+
* Live frames commit as they are processed. During a resume, replayed frames
|
|
77
|
+
* are delivered but do NOT commit (the server replays channel by channel): the
|
|
78
|
+
* cursor moves to the server's `last_seq` / `last_ts` only when
|
|
79
|
+
* `replay_end` says `complete: true` with no incomplete / best-effort
|
|
80
|
+
* channel. After an INCOMPLETE recovery (or a close mid-replay) it stays at
|
|
81
|
+
* the pre-resume point, and later live frames are delivered but not committed
|
|
82
|
+
* until a recovery completes — so the next reconnect re-requests the
|
|
83
|
+
* unrecovered range (duplicates are dropped by id). Call `acceptGap()` once
|
|
84
|
+
* you have backfilled (or decided to skip) the range. `instance` identifies the server process
|
|
85
|
+
* (seq restarts when it changes), `seq` is the server's global ordinal and
|
|
86
|
+
* `ts` the frame time in ms. Delivery is at-least-once: after a resume you may
|
|
87
|
+
* see a frame again — dedupe by `evt.id` (the client already drops ids it saw
|
|
88
|
+
* recently). Persist it (on the `"cursor"` event or via `getCursor()`) and pass
|
|
89
|
+
* it back as the `resume` option to continue after a process restart.
|
|
90
|
+
*/
|
|
91
|
+
export interface StreamCursor {
|
|
92
|
+
instance: string;
|
|
93
|
+
seq: number;
|
|
94
|
+
ts: number;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A named subscription (Phase 2): one socket can hold several, each with its
|
|
98
|
+
* own channels and filters. `subId` is client-chosen, 1-64 characters of
|
|
99
|
+
* `A-Z a-z 0-9 _ . -`. The plain `subscribe(channels, filters)` call is the
|
|
100
|
+
* connection's implicit `"default"` subscription; its frames carry no
|
|
101
|
+
* `sub_id`. An event that matches several subscriptions is delivered once
|
|
102
|
+
* per matching subscription, each frame stamped with its `sub_id`, and the
|
|
103
|
+
* client dedupes by (sub_id, id) — so the same event CAN reach two handlers
|
|
104
|
+
* legitimately. Tier caps (total per connection, the default one included):
|
|
105
|
+
* PRO 5, ULTRA 10, BUSINESS 20.
|
|
106
|
+
*/
|
|
107
|
+
export interface StreamSubscription {
|
|
108
|
+
subId: string;
|
|
109
|
+
channels: StreamChannel[];
|
|
110
|
+
filters: Record<string, unknown>;
|
|
111
|
+
}
|
|
112
|
+
/** Argument of `subscribe({ subId, channels, filters })`. */
|
|
113
|
+
export interface StreamSubscribeOptions {
|
|
114
|
+
subId: string;
|
|
115
|
+
channels: StreamChannel[];
|
|
116
|
+
/** Filters scoped to THIS subscription only. Omitted = keep the ones it has. */
|
|
117
|
+
filters?: Record<string, unknown>;
|
|
118
|
+
}
|
|
21
119
|
export interface StreamEvent<T = unknown> {
|
|
22
120
|
channel: StreamChannel;
|
|
23
121
|
event: StreamEventName;
|
|
24
122
|
data: T;
|
|
25
123
|
ts: number;
|
|
124
|
+
/** The named subscription this frame was delivered under; absent for the default subscription. */
|
|
125
|
+
sub_id?: string;
|
|
126
|
+
/** Stable event id — the same event carries the same id live and in replay. Dedupe on it. */
|
|
127
|
+
id?: string;
|
|
128
|
+
/**
|
|
129
|
+
* Server-global ordinal. Gaps are NORMAL (it counts every channel and every
|
|
130
|
+
* user) and are never evidence of loss — only a `"gap"` event is.
|
|
131
|
+
*/
|
|
132
|
+
seq?: number | null;
|
|
133
|
+
/** true when the frame was re-sent by a replay/backfill rather than live. */
|
|
134
|
+
replayed?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Where a replayed frame came from: "ring" (the server's in-memory buffer) or
|
|
137
|
+
* "durable" (rebuilt from storage — `seq` is then null).
|
|
138
|
+
*/
|
|
139
|
+
mode?: "ring" | "durable";
|
|
140
|
+
/** true when a durable frame could not reproduce every live field — see `missing`. */
|
|
141
|
+
partial?: boolean;
|
|
142
|
+
/** Live payload keys a durable frame could not reproduce (they are absent, never guessed). */
|
|
143
|
+
missing?: string[];
|
|
144
|
+
/** "bus" for a live-path frame the server re-sent after its own event-bus reconnect. */
|
|
145
|
+
recovered?: string;
|
|
146
|
+
/** true on a token:price state snapshot sent at resume time. */
|
|
147
|
+
snapshot?: boolean;
|
|
148
|
+
}
|
|
149
|
+
/** Outcome of a resume, emitted as `"replay"` after the server's `replay_end`. */
|
|
150
|
+
export interface StreamReplayResult {
|
|
151
|
+
/** "resume" = the server answered the v1 `resume` request; "legacy" = the
|
|
152
|
+
* client fell back to `replay_since_seq` / `replay_since_ts` (older server). */
|
|
153
|
+
protocol: "resume" | "legacy";
|
|
154
|
+
/** The cursor the client resumed from. */
|
|
155
|
+
from: StreamCursor | null;
|
|
156
|
+
/** The resume fields the client sent. */
|
|
157
|
+
request: Record<string, unknown>;
|
|
158
|
+
/** Replayed frames received. */
|
|
159
|
+
received: number;
|
|
160
|
+
/** Replayed frames handed to your handlers (received minus duplicates). */
|
|
161
|
+
delivered: number;
|
|
162
|
+
/** Replayed frames dropped because their id was already delivered. */
|
|
163
|
+
duplicates: number;
|
|
164
|
+
/** false when anything could not be recovered — a `"gap"` event follows. */
|
|
165
|
+
complete: boolean;
|
|
166
|
+
/** Server's replay mode ("ring" | "durable"), null on an older server. */
|
|
167
|
+
mode: string | null;
|
|
168
|
+
/** Why the server could not use its ring (e.g. "instance_changed", "ring_truncated"), or null. */
|
|
169
|
+
resumeReason: string | null;
|
|
170
|
+
/** Raw `replay_start` frame (null if none arrived). */
|
|
171
|
+
start: Record<string, unknown> | null;
|
|
172
|
+
/**
|
|
173
|
+
* Raw `replay_end` frame (null on a client-side timeout). With several
|
|
174
|
+
* named subscriptions this is the LAST one received; `ends` has them all.
|
|
175
|
+
*/
|
|
176
|
+
end: Record<string, unknown> | null;
|
|
177
|
+
/**
|
|
178
|
+
* The subscriptions this recovery covered (`"default"` for the plain one).
|
|
179
|
+
* A client holding N named subscriptions resumes each of them: every
|
|
180
|
+
* subscribe of the reconnect carries the same cursor, the server serves the
|
|
181
|
+
* replays one after another and the cursor commits once ALL have ended,
|
|
182
|
+
* at the smallest `last_seq` / `last_ts` across them.
|
|
183
|
+
*/
|
|
184
|
+
subscriptions: string[];
|
|
185
|
+
/** Raw `replay_end` frame per subscription. */
|
|
186
|
+
ends: Record<string, Record<string, unknown>>;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Part of a resume could not be recovered. It says what is KNOWN: which
|
|
190
|
+
* channels the server could not fully rebuild, the RANGE that may be
|
|
191
|
+
* incomplete (`skipped.from` → `skipped.to`, or from `from` onwards while the
|
|
192
|
+
* cursor stays), the server's reason and whether it is final, and the bounds
|
|
193
|
+
* the server reported (`limits`, and per-channel entries in `channels`:
|
|
194
|
+
* `time_basis`, `truncated_at_ts`, `retry_after_ms`, …). Events in that range
|
|
195
|
+
* MAY be missing — how many, nobody can say, so this never claims a count.
|
|
196
|
+
* Backfill the range from REST if you need certainty. `reasons` uses the
|
|
197
|
+
* server's vocabulary (`backpressure`, `closed`, `source_busy`,
|
|
198
|
+
* `source_error`, `late_ingest_possible`, `row_cap`, `ring_truncated`,
|
|
199
|
+
* `instance_changed`, `window_exceeded`, `not_reconstructable`) plus the
|
|
200
|
+
* client-side `replay_timeout`.
|
|
201
|
+
*/
|
|
202
|
+
export interface StreamGap {
|
|
203
|
+
/** The first reason (convenience). */
|
|
204
|
+
reason: string;
|
|
205
|
+
reasons: string[];
|
|
206
|
+
/**
|
|
207
|
+
* true when EVERY reason is permanent — asking again can never fill it
|
|
208
|
+
* (`not_reconstructable`, `state_stream`, `window_exceeded`, or an older
|
|
209
|
+
* server's `ring_truncated` / `instance_changed`). The client reports it
|
|
210
|
+
* once and commits as if complete. false = transient (`backpressure`,
|
|
211
|
+
* `row_cap`, `source_busy`, `source_error`, `late_ingest` / `best_effort`,
|
|
212
|
+
* `incomplete`, `replay_timeout`, …): the committed cursor stays and the
|
|
213
|
+
* range is requested again on the next reconnect.
|
|
214
|
+
*/
|
|
215
|
+
permanent: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Per-channel entries the server reported as incomplete / not
|
|
218
|
+
* reconstructable, keyed by channel for the default subscription and by
|
|
219
|
+
* `"<sub_id>/<channel>"` for a named one.
|
|
220
|
+
*/
|
|
221
|
+
channels: Record<string, unknown>;
|
|
222
|
+
/** The cursor the resume started from (the committed cursor stays there). */
|
|
223
|
+
from: StreamCursor | null;
|
|
224
|
+
/** true when the server says the gap is transient and worth asking again (`retryable`). */
|
|
225
|
+
retryable: boolean;
|
|
226
|
+
/** How long the server wants you to wait before resuming again (ms), when it says. */
|
|
227
|
+
retryAfterMs: number | null;
|
|
228
|
+
/** For `row_cap`: the ts to resume from next (the client uses it automatically). */
|
|
229
|
+
resumeTsHint: number | null;
|
|
230
|
+
/**
|
|
231
|
+
* true when the CLIENT decided to continue past this gap and move the
|
|
232
|
+
* committed cursor beyond it — the events in `skipped` are not coming back.
|
|
233
|
+
* This is the SDK's own decision (see `onUnrecoverableGap`), never a user
|
|
234
|
+
* approval. false = the cursor stayed put.
|
|
235
|
+
*/
|
|
236
|
+
advancedPastGap: boolean;
|
|
237
|
+
/** "auto" = the client's own decision; "manual" = you called `acceptGap()`. */
|
|
238
|
+
source: "auto" | "manual";
|
|
239
|
+
/**
|
|
240
|
+
* The range that may be incomplete: the channels the server could not fully
|
|
241
|
+
* rebuild and the cursor positions the client jumped between (`to` is null
|
|
242
|
+
* when the cursor did not move). Events in that range may be missing.
|
|
243
|
+
*/
|
|
244
|
+
skipped: {
|
|
245
|
+
channels: string[];
|
|
246
|
+
from: StreamCursor | null;
|
|
247
|
+
to: StreamCursor | null;
|
|
248
|
+
};
|
|
249
|
+
/** Bounds the server reported for this resume (max age, row caps, slack), when it sends them. */
|
|
250
|
+
limits: Record<string, unknown> | null;
|
|
251
|
+
/**
|
|
252
|
+
* true when this gap is retryable but the automatic re-resume budget
|
|
253
|
+
* (`maxResumeRetries`) is spent: the client stops asking again on this
|
|
254
|
+
* connection and the committed cursor stays put until the next reconnect
|
|
255
|
+
* resumes (or you call `acceptGap()`).
|
|
256
|
+
*/
|
|
257
|
+
exhausted: boolean;
|
|
258
|
+
replay: StreamReplayResult;
|
|
259
|
+
}
|
|
260
|
+
/** The stream stopped and will not reconnect on its own. */
|
|
261
|
+
export interface StreamFatal {
|
|
262
|
+
code: number | null;
|
|
263
|
+
reason: string;
|
|
264
|
+
/** The unrecoverable gap that stopped it (`onUnrecoverableGap: "stop"` only). */
|
|
265
|
+
gap?: StreamGap;
|
|
26
266
|
}
|
|
27
267
|
export interface StreamClientOptions {
|
|
28
|
-
/**
|
|
29
|
-
*
|
|
268
|
+
/**
|
|
269
|
+
* Returns your stream token (the SDK wires this to the stream-token
|
|
270
|
+
* endpoint). Called on every (re)connect — including after a 4001 close,
|
|
271
|
+
* which is how a rotated/lapsed token gets replaced. Tokens never expire, so
|
|
272
|
+
* it is never called on a timer.
|
|
273
|
+
*/
|
|
30
274
|
getToken: () => Promise<StreamToken>;
|
|
31
275
|
/** Reconnect automatically on drop (default: true). */
|
|
32
276
|
autoReconnect?: boolean;
|
|
@@ -36,34 +280,200 @@ export interface StreamClientOptions {
|
|
|
36
280
|
heartbeatTimeoutMs?: number;
|
|
37
281
|
/** Override the WebSocket implementation (e.g. inject `ws` explicitly). */
|
|
38
282
|
WebSocketImpl?: unknown;
|
|
283
|
+
/**
|
|
284
|
+
* A cursor you persisted earlier (from `getCursor()` or the `"cursor"`
|
|
285
|
+
* event). The first subscribe then asks the server to resume after it.
|
|
286
|
+
*/
|
|
287
|
+
resume?: StreamCursor | null;
|
|
288
|
+
/** How many recent event ids to remember for de-duplication (default: 10000). */
|
|
289
|
+
dedupeSize?: number;
|
|
290
|
+
/** Consecutive 4001 closes (token rejected) before `"fatal"` (default: 3). */
|
|
291
|
+
maxAuthRetries?: number;
|
|
292
|
+
/** Minimum wait after a 4002 connection-limit close, in ms (default: 60000). */
|
|
293
|
+
connectionLimitBackoffMs?: number;
|
|
294
|
+
/**
|
|
295
|
+
* After a resume subscribe is acked, how long to wait for the server's
|
|
296
|
+
* `replay_start` before assuming an older server that does not understand
|
|
297
|
+
* `resume`, and retrying with `replay_since_seq` / `replay_since_ts`
|
|
298
|
+
* (default: 3000). A live event arriving first triggers the fallback at once.
|
|
299
|
+
*/
|
|
300
|
+
resumeDetectMs?: number;
|
|
301
|
+
/** Give up waiting for a fallback replay's `replay_end` after this many ms (default: 15000). */
|
|
302
|
+
legacyReplayTimeoutMs?: number;
|
|
303
|
+
/**
|
|
304
|
+
* How often to resume again after a RETRYABLE gap before giving up on the
|
|
305
|
+
* automatic retry (default: 5). The next reconnect resumes again anyway.
|
|
306
|
+
*/
|
|
307
|
+
maxResumeRetries?: number;
|
|
308
|
+
/** Wait before an automatic re-resume when the server names none (default: 30000 ms). */
|
|
309
|
+
resumeRetryDelayMs?: number;
|
|
310
|
+
/**
|
|
311
|
+
* What to do when the server reports a gap that asking again can never fill
|
|
312
|
+
* (`retryable: false`).
|
|
313
|
+
* - `"advance"` (default): report it on the `"gap"` event with
|
|
314
|
+
* `advancedPastGap: true` and the skipped range, commit past it and keep
|
|
315
|
+
* streaming. The skipped events are not delivered — backfill them from
|
|
316
|
+
* REST if you need them.
|
|
317
|
+
* - `"stop"`: do not move the cursor, stop the stream and emit `"fatal"`
|
|
318
|
+
* with the gap, so YOU decide. `acceptGap()` then `connect()` continues.
|
|
319
|
+
*/
|
|
320
|
+
onUnrecoverableGap?: "advance" | "stop";
|
|
39
321
|
}
|
|
40
|
-
type Listener = (data: unknown, evt?: StreamEvent) =>
|
|
322
|
+
type Listener = (data: unknown, evt?: StreamEvent) => unknown;
|
|
41
323
|
export declare class MadeOnSolStream {
|
|
42
324
|
private opts;
|
|
43
325
|
private ws;
|
|
44
326
|
private listeners;
|
|
45
327
|
private desired;
|
|
328
|
+
/** Named subscriptions (Phase 2), in creation order; the default one is `desired`. */
|
|
329
|
+
private named;
|
|
330
|
+
/** sub_ids of the subscribes sent on this connection whose `subscribed` ack is still due (acks arrive in order). */
|
|
331
|
+
private ackExpect;
|
|
332
|
+
private namedUnsupportedWarned;
|
|
333
|
+
private listWaiters;
|
|
46
334
|
private closedByUser;
|
|
335
|
+
private stopped;
|
|
47
336
|
private attempt;
|
|
337
|
+
private authFailures;
|
|
48
338
|
private hbTimer;
|
|
49
339
|
private reconnectTimer;
|
|
50
340
|
private connecting;
|
|
341
|
+
/** Server process id of the CURRENT connection (from connected/subscribed). */
|
|
342
|
+
private serverInstance;
|
|
343
|
+
/** Whether this connection already sent its first subscribe (the only one that resumes). */
|
|
344
|
+
private firstSubscribeSent;
|
|
345
|
+
/** COMMITTED (safe) cursor — the one to persist and resume from. */
|
|
346
|
+
private cursor;
|
|
347
|
+
/** Received progress — every handled frame, including replayed ones. */
|
|
348
|
+
private progress;
|
|
349
|
+
/** true after an incomplete recovery: live frames are not committed until one completes. */
|
|
350
|
+
private unsafe;
|
|
351
|
+
private seen;
|
|
352
|
+
private inflight;
|
|
353
|
+
private recovery;
|
|
354
|
+
/** Automatic re-resume after a retryable gap. */
|
|
355
|
+
private retryTimer;
|
|
356
|
+
private resumeRetries;
|
|
357
|
+
/** The last gap reported (for acceptGap()'s report). */
|
|
358
|
+
private lastGap;
|
|
51
359
|
constructor(opts: StreamClientOptions);
|
|
52
|
-
/** Register a handler. Use an event name, `"*"` for every event, or a lifecycle event.
|
|
360
|
+
/** Register a handler. Use an event name, `"*"` for every event, or a lifecycle event.
|
|
361
|
+
* An event handler may return a promise: the cursor only advances past a frame once
|
|
362
|
+
* every handler for it (and for every earlier frame) has settled. */
|
|
363
|
+
on(event: "warning", fn: (warning: StreamWarning) => unknown): this;
|
|
364
|
+
on(event: "cursor", fn: (cursor: StreamCursor) => unknown): this;
|
|
365
|
+
on(event: "replay", fn: (result: StreamReplayResult) => unknown): this;
|
|
366
|
+
on(event: "gap", fn: (gap: StreamGap) => unknown): this;
|
|
367
|
+
on(event: "fatal", fn: (fatal: StreamFatal) => unknown): this;
|
|
53
368
|
on(event: StreamEventName | StreamLifecycleEvent | "*", fn: Listener): this;
|
|
54
369
|
/** Remove a handler (or all handlers for an event when `fn` is omitted). */
|
|
55
|
-
off(event: string, fn?:
|
|
370
|
+
off(event: string, fn?: (...args: never[]) => unknown): this;
|
|
371
|
+
/** The COMMITTED resume cursor (last safe point) — persist this one. Null before the first. */
|
|
372
|
+
getCursor(): StreamCursor | null;
|
|
373
|
+
/** Received progress: the last handled frame, replayed ones included (NOT safe to resume from). */
|
|
374
|
+
getProgress(): StreamCursor | null;
|
|
375
|
+
/** true while an incomplete recovery holds the committed cursor back. */
|
|
376
|
+
isRecoveryIncomplete(): boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Accept the last reported gap: commit the received progress as the cursor
|
|
379
|
+
* and let live frames commit again. Call it after you backfilled the range
|
|
380
|
+
* the `"gap"` event named (or decided you do not need it). It re-reports the
|
|
381
|
+
* gap first, with `source: "manual"` and the range being skipped.
|
|
382
|
+
*/
|
|
383
|
+
acceptGap(): void;
|
|
56
384
|
private emit;
|
|
57
|
-
/**
|
|
385
|
+
/** Call every handler for a data frame; collect what they returned (for completion tracking). */
|
|
386
|
+
private callHandlers;
|
|
387
|
+
/**
|
|
388
|
+
* Subscribe to one or more channels (connects on first call). Optional
|
|
389
|
+
* server-side filters. `subscribe(channels, filters)` is the connection's
|
|
390
|
+
* default subscription; `subscribe({ subId, channels, filters })` opens (or
|
|
391
|
+
* extends) a NAMED subscription with its own channels and filters, whose
|
|
392
|
+
* frames carry `evt.sub_id` (see StreamSubscription).
|
|
393
|
+
*/
|
|
58
394
|
subscribe(channels: StreamChannel[], filters?: Record<string, unknown>): this;
|
|
59
|
-
|
|
395
|
+
subscribe(opts: StreamSubscribeOptions): this;
|
|
396
|
+
/**
|
|
397
|
+
* Replace the filters of a subscription (`"default"` for the plain one).
|
|
398
|
+
* The server acks with an `updated` frame; a refused update (for example a
|
|
399
|
+
* `token:prices` subscription without valid `mints`) arrives as a `warning`
|
|
400
|
+
* with code `invalid_filters` and the previous filters stay.
|
|
401
|
+
*/
|
|
402
|
+
updateSubscription(subId: string, filters: Record<string, unknown>): this;
|
|
403
|
+
/**
|
|
404
|
+
* `unsubscribe(channels)` stops those channels on the default subscription;
|
|
405
|
+
* `unsubscribe(subId)` removes a whole named subscription.
|
|
406
|
+
*/
|
|
60
407
|
unsubscribe(channels: StreamChannel[]): this;
|
|
61
|
-
|
|
408
|
+
unsubscribe(subId: string): this;
|
|
409
|
+
/** Every subscription this client asks for (local view, no round trip). */
|
|
410
|
+
getSubscriptions(): StreamSubscription[];
|
|
411
|
+
/**
|
|
412
|
+
* Ask the server what this connection holds (`list` → `subscriptions`).
|
|
413
|
+
* Resolves with the local view when not connected or when the server does
|
|
414
|
+
* not answer within `timeoutMs`.
|
|
415
|
+
*/
|
|
416
|
+
listSubscriptions(timeoutMs?: number): Promise<StreamSubscription[]>;
|
|
417
|
+
/**
|
|
418
|
+
* A pre-Phase-2 server (ignores sub_id) answers every resume with ONE
|
|
419
|
+
* replay for the whole connection, reported without sub_id: only "default"
|
|
420
|
+
* can still be awaited. Finishes the recovery at once when that one has
|
|
421
|
+
* already ended.
|
|
422
|
+
*/
|
|
423
|
+
private collapsePending;
|
|
424
|
+
/** A subscription removed while its replay was still awaited: stop waiting for it. */
|
|
425
|
+
private forgetPending;
|
|
426
|
+
/** Open the connection (also called implicitly by subscribe). Restarts a stream that went `"fatal"`. */
|
|
62
427
|
connect(): Promise<void>;
|
|
63
428
|
/** Close the connection and stop reconnecting. */
|
|
64
429
|
close(): void;
|
|
430
|
+
private handleClose;
|
|
431
|
+
/** `onUnrecoverableGap: "stop"`: stop the stream and hand the decision to the caller. */
|
|
432
|
+
private haltForGap;
|
|
433
|
+
private fatal;
|
|
434
|
+
/** The subscribe frames for the given subscriptions (default first, then named in creation order). */
|
|
435
|
+
private subscribeFrames;
|
|
436
|
+
/**
|
|
437
|
+
* Send the subscribe(s). On a connection's FIRST subscribe (or an explicit
|
|
438
|
+
* retry after a retryable gap) every subscription is sent with the SAME
|
|
439
|
+
* resume cursor: the server serves one replay per subscription, one after
|
|
440
|
+
* another, and holds live frames until the last replay_end. A later
|
|
441
|
+
* subscribe adds channels live (no resume).
|
|
442
|
+
*/
|
|
65
443
|
private sendSubscribe;
|
|
444
|
+
/**
|
|
445
|
+
* The server did not answer `resume` (older deployment): retry with the
|
|
446
|
+
* legacy fields. Such a server has no named subscriptions either, so the
|
|
447
|
+
* one legacy replay covers the union of channels and resolves every pending
|
|
448
|
+
* subscription at once.
|
|
449
|
+
*/
|
|
450
|
+
private fallbackToLegacy;
|
|
451
|
+
private dropRecovery;
|
|
452
|
+
/**
|
|
453
|
+
* A retryable gap: ask the server again on this connection after its
|
|
454
|
+
* retry_after_ms (row_cap resumes from resume_ts_hint). Bounded — the next
|
|
455
|
+
* reconnect resumes anyway.
|
|
456
|
+
*/
|
|
457
|
+
private scheduleResumeRetry;
|
|
458
|
+
/**
|
|
459
|
+
* One `replay_end` per subscription → one aggregate the single-replay logic
|
|
460
|
+
* can run on unchanged: complete only when every subscription is; the
|
|
461
|
+
* commit position is the SMALLEST last_seq / last_ts across them (a later
|
|
462
|
+
* subscription's replay covered more, but the earlier one's live frames
|
|
463
|
+
* from that point on are still only in the live flush); channel entries
|
|
464
|
+
* keyed `"<sub_id>/<channel>"` for named subscriptions; `retryable` when
|
|
465
|
+
* any subscription says so.
|
|
466
|
+
*/
|
|
467
|
+
private aggregateEnds;
|
|
468
|
+
private finishRecovery;
|
|
66
469
|
private handleMessage;
|
|
470
|
+
/** Dedupe by id, hand the frame to the handlers, track completion for the cursor. */
|
|
471
|
+
private deliver;
|
|
472
|
+
private drainInflight;
|
|
473
|
+
/** Queue a position behind every frame still being handled (or apply it now). */
|
|
474
|
+
private enqueue;
|
|
475
|
+
/** Move `progress` (always) and the committed cursor (when `commit`) to `pos`. */
|
|
476
|
+
private apply;
|
|
67
477
|
private scheduleReconnect;
|
|
68
478
|
private resetHeartbeat;
|
|
69
479
|
private clearHeartbeat;
|
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}
|