pmxtjs 2.46.3 → 2.46.4
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/dist/esm/pmxt/client.js +1 -0
- package/dist/esm/pmxt/ws-client.d.ts +4 -1
- package/dist/esm/pmxt/ws-client.js +38 -20
- package/dist/pmxt/client.js +1 -0
- package/dist/pmxt/ws-client.d.ts +4 -1
- package/dist/pmxt/ws-client.js +38 -20
- package/generated/package.json +1 -1
- package/package.json +2 -2
- package/pmxt/client.ts +2 -0
- package/pmxt/ws-client.ts +41 -20
package/dist/esm/pmxt/client.js
CHANGED
|
@@ -384,6 +384,7 @@ export class Exchange {
|
|
|
384
384
|
}
|
|
385
385
|
internals.activeSubs.delete(subKey);
|
|
386
386
|
internals.subscriptions.delete(requestId);
|
|
387
|
+
internals.dataQueues.delete(requestId);
|
|
387
388
|
internals.dataStore.delete(requestId);
|
|
388
389
|
const firstArg = args[0] ?? "";
|
|
389
390
|
const symbols = Array.isArray(firstArg)
|
|
@@ -18,7 +18,9 @@ export declare class SidecarWsClient {
|
|
|
18
18
|
private accessToken;
|
|
19
19
|
private authParamName;
|
|
20
20
|
private closed;
|
|
21
|
-
/** requestId ->
|
|
21
|
+
/** requestId -> queued data payloads for single-event watch methods */
|
|
22
|
+
private dataQueues;
|
|
23
|
+
/** requestId[:symbol] -> latest data payload for batch snapshots */
|
|
22
24
|
private dataStore;
|
|
23
25
|
/** requestId -> subscription metadata */
|
|
24
26
|
private subscriptions;
|
|
@@ -30,6 +32,7 @@ export declare class SidecarWsClient {
|
|
|
30
32
|
private connect;
|
|
31
33
|
private getWebSocketConstructor;
|
|
32
34
|
private dispatch;
|
|
35
|
+
private deliverOrQueue;
|
|
33
36
|
subscribe(exchange: string, method: string, args: any[], credentials?: Record<string, any>, timeoutMs?: number): Promise<any>;
|
|
34
37
|
subscribeBatch(exchange: string, method: string, args: any[], credentials?: Record<string, any>, timeoutMs?: number): Promise<Record<string, any>>;
|
|
35
38
|
close(): void;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* does not support the /ws endpoint.
|
|
8
8
|
*/
|
|
9
9
|
import { PmxtError } from "./errors.js";
|
|
10
|
+
const MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION = 100_000;
|
|
10
11
|
/**
|
|
11
12
|
* Multiplexed WebSocket client for the pmxt sidecar.
|
|
12
13
|
*
|
|
@@ -19,7 +20,9 @@ export class SidecarWsClient {
|
|
|
19
20
|
accessToken;
|
|
20
21
|
authParamName;
|
|
21
22
|
closed = false;
|
|
22
|
-
/** requestId ->
|
|
23
|
+
/** requestId -> queued data payloads for single-event watch methods */
|
|
24
|
+
dataQueues = new Map();
|
|
25
|
+
/** requestId[:symbol] -> latest data payload for batch snapshots */
|
|
23
26
|
dataStore = new Map();
|
|
24
27
|
/** requestId -> subscription metadata */
|
|
25
28
|
subscriptions = new Map();
|
|
@@ -154,16 +157,27 @@ export class SidecarWsClient {
|
|
|
154
157
|
if (eventType === "data" && requestId) {
|
|
155
158
|
const symbol = msg.symbol || "";
|
|
156
159
|
const data = msg.data || {};
|
|
157
|
-
// Store by (requestId:symbol) for batch methods
|
|
160
|
+
// Store by (requestId:symbol) for batch methods.
|
|
158
161
|
this.dataStore.set(`${requestId}:${symbol}`, data);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
162
|
+
this.deliverOrQueue(requestId, data);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
deliverOrQueue(requestId, data) {
|
|
166
|
+
const sub = this.subscriptions.get(requestId);
|
|
167
|
+
if (sub?.resolve) {
|
|
168
|
+
sub.resolve(data);
|
|
169
|
+
sub.resolve = null;
|
|
170
|
+
sub.reject = null;
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
let queue = this.dataQueues.get(requestId);
|
|
174
|
+
if (!queue) {
|
|
175
|
+
queue = [];
|
|
176
|
+
this.dataQueues.set(requestId, queue);
|
|
177
|
+
}
|
|
178
|
+
queue.push(data);
|
|
179
|
+
if (queue.length > MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION) {
|
|
180
|
+
queue.splice(0, queue.length - MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION);
|
|
167
181
|
}
|
|
168
182
|
}
|
|
169
183
|
// ------------------------------------------------------------------
|
|
@@ -233,8 +247,8 @@ export class SidecarWsClient {
|
|
|
233
247
|
throw new PmxtError('[ws-client] Cannot send: WebSocket not connected');
|
|
234
248
|
}
|
|
235
249
|
this.ws.send(JSON.stringify(message));
|
|
236
|
-
// Wait for first data event
|
|
237
|
-
await this.waitForData(requestId, timeoutMs);
|
|
250
|
+
// Wait for first data event.
|
|
251
|
+
const firstData = await this.waitForData(requestId, timeoutMs);
|
|
238
252
|
// Collect per-symbol data
|
|
239
253
|
const result = {};
|
|
240
254
|
for (const symbol of symbols) {
|
|
@@ -246,9 +260,8 @@ export class SidecarWsClient {
|
|
|
246
260
|
}
|
|
247
261
|
// If no per-symbol data, return the single data event as-is
|
|
248
262
|
if (Object.keys(result).length === 0) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return data;
|
|
263
|
+
if (firstData && typeof firstData === "object") {
|
|
264
|
+
return firstData;
|
|
252
265
|
}
|
|
253
266
|
}
|
|
254
267
|
return result;
|
|
@@ -264,6 +277,8 @@ export class SidecarWsClient {
|
|
|
264
277
|
}
|
|
265
278
|
this.ws = null;
|
|
266
279
|
}
|
|
280
|
+
this.dataQueues.clear();
|
|
281
|
+
this.dataStore.clear();
|
|
267
282
|
}
|
|
268
283
|
get connected() {
|
|
269
284
|
return this.ws !== null && !this.closed;
|
|
@@ -272,11 +287,14 @@ export class SidecarWsClient {
|
|
|
272
287
|
// Internal
|
|
273
288
|
// ------------------------------------------------------------------
|
|
274
289
|
waitForData(requestId, timeoutMs) {
|
|
275
|
-
// Check if data is already available
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
|
|
279
|
-
|
|
290
|
+
// Check if queued data is already available.
|
|
291
|
+
const queue = this.dataQueues.get(requestId);
|
|
292
|
+
if (queue && queue.length > 0) {
|
|
293
|
+
const next = queue.shift();
|
|
294
|
+
if (queue.length === 0) {
|
|
295
|
+
this.dataQueues.delete(requestId);
|
|
296
|
+
}
|
|
297
|
+
return Promise.resolve(next);
|
|
280
298
|
}
|
|
281
299
|
return new Promise((resolve, reject) => {
|
|
282
300
|
const sub = this.subscriptions.get(requestId);
|
package/dist/pmxt/client.js
CHANGED
|
@@ -387,6 +387,7 @@ class Exchange {
|
|
|
387
387
|
}
|
|
388
388
|
internals.activeSubs.delete(subKey);
|
|
389
389
|
internals.subscriptions.delete(requestId);
|
|
390
|
+
internals.dataQueues.delete(requestId);
|
|
390
391
|
internals.dataStore.delete(requestId);
|
|
391
392
|
const firstArg = args[0] ?? "";
|
|
392
393
|
const symbols = Array.isArray(firstArg)
|
package/dist/pmxt/ws-client.d.ts
CHANGED
|
@@ -18,7 +18,9 @@ export declare class SidecarWsClient {
|
|
|
18
18
|
private accessToken;
|
|
19
19
|
private authParamName;
|
|
20
20
|
private closed;
|
|
21
|
-
/** requestId ->
|
|
21
|
+
/** requestId -> queued data payloads for single-event watch methods */
|
|
22
|
+
private dataQueues;
|
|
23
|
+
/** requestId[:symbol] -> latest data payload for batch snapshots */
|
|
22
24
|
private dataStore;
|
|
23
25
|
/** requestId -> subscription metadata */
|
|
24
26
|
private subscriptions;
|
|
@@ -30,6 +32,7 @@ export declare class SidecarWsClient {
|
|
|
30
32
|
private connect;
|
|
31
33
|
private getWebSocketConstructor;
|
|
32
34
|
private dispatch;
|
|
35
|
+
private deliverOrQueue;
|
|
33
36
|
subscribe(exchange: string, method: string, args: any[], credentials?: Record<string, any>, timeoutMs?: number): Promise<any>;
|
|
34
37
|
subscribeBatch(exchange: string, method: string, args: any[], credentials?: Record<string, any>, timeoutMs?: number): Promise<Record<string, any>>;
|
|
35
38
|
close(): void;
|
package/dist/pmxt/ws-client.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.SidecarWsClient = void 0;
|
|
12
12
|
const errors_js_1 = require("./errors.js");
|
|
13
|
+
const MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION = 100_000;
|
|
13
14
|
/**
|
|
14
15
|
* Multiplexed WebSocket client for the pmxt sidecar.
|
|
15
16
|
*
|
|
@@ -22,7 +23,9 @@ class SidecarWsClient {
|
|
|
22
23
|
accessToken;
|
|
23
24
|
authParamName;
|
|
24
25
|
closed = false;
|
|
25
|
-
/** requestId ->
|
|
26
|
+
/** requestId -> queued data payloads for single-event watch methods */
|
|
27
|
+
dataQueues = new Map();
|
|
28
|
+
/** requestId[:symbol] -> latest data payload for batch snapshots */
|
|
26
29
|
dataStore = new Map();
|
|
27
30
|
/** requestId -> subscription metadata */
|
|
28
31
|
subscriptions = new Map();
|
|
@@ -157,16 +160,27 @@ class SidecarWsClient {
|
|
|
157
160
|
if (eventType === "data" && requestId) {
|
|
158
161
|
const symbol = msg.symbol || "";
|
|
159
162
|
const data = msg.data || {};
|
|
160
|
-
// Store by (requestId:symbol) for batch methods
|
|
163
|
+
// Store by (requestId:symbol) for batch methods.
|
|
161
164
|
this.dataStore.set(`${requestId}:${symbol}`, data);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
this.deliverOrQueue(requestId, data);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
deliverOrQueue(requestId, data) {
|
|
169
|
+
const sub = this.subscriptions.get(requestId);
|
|
170
|
+
if (sub?.resolve) {
|
|
171
|
+
sub.resolve(data);
|
|
172
|
+
sub.resolve = null;
|
|
173
|
+
sub.reject = null;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let queue = this.dataQueues.get(requestId);
|
|
177
|
+
if (!queue) {
|
|
178
|
+
queue = [];
|
|
179
|
+
this.dataQueues.set(requestId, queue);
|
|
180
|
+
}
|
|
181
|
+
queue.push(data);
|
|
182
|
+
if (queue.length > MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION) {
|
|
183
|
+
queue.splice(0, queue.length - MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION);
|
|
170
184
|
}
|
|
171
185
|
}
|
|
172
186
|
// ------------------------------------------------------------------
|
|
@@ -236,8 +250,8 @@ class SidecarWsClient {
|
|
|
236
250
|
throw new errors_js_1.PmxtError('[ws-client] Cannot send: WebSocket not connected');
|
|
237
251
|
}
|
|
238
252
|
this.ws.send(JSON.stringify(message));
|
|
239
|
-
// Wait for first data event
|
|
240
|
-
await this.waitForData(requestId, timeoutMs);
|
|
253
|
+
// Wait for first data event.
|
|
254
|
+
const firstData = await this.waitForData(requestId, timeoutMs);
|
|
241
255
|
// Collect per-symbol data
|
|
242
256
|
const result = {};
|
|
243
257
|
for (const symbol of symbols) {
|
|
@@ -249,9 +263,8 @@ class SidecarWsClient {
|
|
|
249
263
|
}
|
|
250
264
|
// If no per-symbol data, return the single data event as-is
|
|
251
265
|
if (Object.keys(result).length === 0) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return data;
|
|
266
|
+
if (firstData && typeof firstData === "object") {
|
|
267
|
+
return firstData;
|
|
255
268
|
}
|
|
256
269
|
}
|
|
257
270
|
return result;
|
|
@@ -267,6 +280,8 @@ class SidecarWsClient {
|
|
|
267
280
|
}
|
|
268
281
|
this.ws = null;
|
|
269
282
|
}
|
|
283
|
+
this.dataQueues.clear();
|
|
284
|
+
this.dataStore.clear();
|
|
270
285
|
}
|
|
271
286
|
get connected() {
|
|
272
287
|
return this.ws !== null && !this.closed;
|
|
@@ -275,11 +290,14 @@ class SidecarWsClient {
|
|
|
275
290
|
// Internal
|
|
276
291
|
// ------------------------------------------------------------------
|
|
277
292
|
waitForData(requestId, timeoutMs) {
|
|
278
|
-
// Check if data is already available
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
|
|
293
|
+
// Check if queued data is already available.
|
|
294
|
+
const queue = this.dataQueues.get(requestId);
|
|
295
|
+
if (queue && queue.length > 0) {
|
|
296
|
+
const next = queue.shift();
|
|
297
|
+
if (queue.length === 0) {
|
|
298
|
+
this.dataQueues.delete(requestId);
|
|
299
|
+
}
|
|
300
|
+
return Promise.resolve(next);
|
|
283
301
|
}
|
|
284
302
|
return new Promise((resolve, reject) => {
|
|
285
303
|
const sub = this.subscriptions.get(requestId);
|
package/generated/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxtjs",
|
|
3
|
-
"version": "2.46.
|
|
3
|
+
"version": "2.46.4",
|
|
4
4
|
"description": "Unified prediction market data API - The ccxt for prediction markets",
|
|
5
5
|
"author": "PMXT Contributors",
|
|
6
6
|
"repository": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"unified"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"pmxt-core": "2.46.
|
|
46
|
+
"pmxt-core": "2.46.4",
|
|
47
47
|
"ws": "^8.18.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
package/pmxt/client.ts
CHANGED
|
@@ -61,6 +61,7 @@ interface SidecarWsClientInternals {
|
|
|
61
61
|
ws: RawWebSocketLike | null;
|
|
62
62
|
activeSubs: Map<string, string>;
|
|
63
63
|
subscriptions: Map<string, { reject: ((error: Error) => void) | null }>;
|
|
64
|
+
dataQueues: Map<string, any[]>;
|
|
64
65
|
dataStore: Map<string, any>;
|
|
65
66
|
}
|
|
66
67
|
|
|
@@ -538,6 +539,7 @@ export abstract class Exchange {
|
|
|
538
539
|
|
|
539
540
|
internals.activeSubs.delete(subKey);
|
|
540
541
|
internals.subscriptions.delete(requestId);
|
|
542
|
+
internals.dataQueues.delete(requestId);
|
|
541
543
|
internals.dataStore.delete(requestId);
|
|
542
544
|
|
|
543
545
|
const firstArg = args[0] ?? "";
|
package/pmxt/ws-client.ts
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import { PmxtError } from "./errors.js";
|
|
11
11
|
|
|
12
|
+
const MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION = 100_000;
|
|
13
|
+
|
|
12
14
|
interface WsSubscription {
|
|
13
15
|
readonly requestId: string;
|
|
14
16
|
readonly method: string;
|
|
@@ -39,7 +41,9 @@ export class SidecarWsClient {
|
|
|
39
41
|
private authParamName: string;
|
|
40
42
|
private closed = false;
|
|
41
43
|
|
|
42
|
-
/** requestId ->
|
|
44
|
+
/** requestId -> queued data payloads for single-event watch methods */
|
|
45
|
+
private dataQueues: Map<string, any[]> = new Map();
|
|
46
|
+
/** requestId[:symbol] -> latest data payload for batch snapshots */
|
|
43
47
|
private dataStore: Map<string, any> = new Map();
|
|
44
48
|
/** requestId -> subscription metadata */
|
|
45
49
|
private subscriptions: Map<string, WsSubscription> = new Map();
|
|
@@ -189,17 +193,30 @@ export class SidecarWsClient {
|
|
|
189
193
|
const symbol = msg.symbol || "";
|
|
190
194
|
const data = msg.data || {};
|
|
191
195
|
|
|
192
|
-
// Store by (requestId:symbol) for batch methods
|
|
196
|
+
// Store by (requestId:symbol) for batch methods.
|
|
193
197
|
this.dataStore.set(`${requestId}:${symbol}`, data);
|
|
194
|
-
|
|
195
|
-
|
|
198
|
+
this.deliverOrQueue(requestId, data);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
196
201
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
private deliverOrQueue(requestId: string, data: any): void {
|
|
203
|
+
const sub = this.subscriptions.get(requestId);
|
|
204
|
+
if (sub?.resolve) {
|
|
205
|
+
sub.resolve(data);
|
|
206
|
+
sub.resolve = null;
|
|
207
|
+
sub.reject = null;
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
let queue = this.dataQueues.get(requestId);
|
|
212
|
+
if (!queue) {
|
|
213
|
+
queue = [];
|
|
214
|
+
this.dataQueues.set(requestId, queue);
|
|
215
|
+
}
|
|
216
|
+
queue.push(data);
|
|
217
|
+
|
|
218
|
+
if (queue.length > MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION) {
|
|
219
|
+
queue.splice(0, queue.length - MAX_QUEUED_MESSAGES_PER_SUBSCRIPTION);
|
|
203
220
|
}
|
|
204
221
|
}
|
|
205
222
|
|
|
@@ -297,8 +314,8 @@ export class SidecarWsClient {
|
|
|
297
314
|
}
|
|
298
315
|
this.ws.send(JSON.stringify(message));
|
|
299
316
|
|
|
300
|
-
// Wait for first data event
|
|
301
|
-
await this.waitForData(requestId, timeoutMs);
|
|
317
|
+
// Wait for first data event.
|
|
318
|
+
const firstData = await this.waitForData(requestId, timeoutMs);
|
|
302
319
|
|
|
303
320
|
// Collect per-symbol data
|
|
304
321
|
const result: Record<string, any> = {};
|
|
@@ -312,9 +329,8 @@ export class SidecarWsClient {
|
|
|
312
329
|
|
|
313
330
|
// If no per-symbol data, return the single data event as-is
|
|
314
331
|
if (Object.keys(result).length === 0) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return data;
|
|
332
|
+
if (firstData && typeof firstData === "object") {
|
|
333
|
+
return firstData;
|
|
318
334
|
}
|
|
319
335
|
}
|
|
320
336
|
|
|
@@ -331,6 +347,8 @@ export class SidecarWsClient {
|
|
|
331
347
|
}
|
|
332
348
|
this.ws = null;
|
|
333
349
|
}
|
|
350
|
+
this.dataQueues.clear();
|
|
351
|
+
this.dataStore.clear();
|
|
334
352
|
}
|
|
335
353
|
|
|
336
354
|
get connected(): boolean {
|
|
@@ -342,11 +360,14 @@ export class SidecarWsClient {
|
|
|
342
360
|
// ------------------------------------------------------------------
|
|
343
361
|
|
|
344
362
|
private waitForData(requestId: string, timeoutMs: number): Promise<any> {
|
|
345
|
-
// Check if data is already available
|
|
346
|
-
const
|
|
347
|
-
if (
|
|
348
|
-
|
|
349
|
-
|
|
363
|
+
// Check if queued data is already available.
|
|
364
|
+
const queue = this.dataQueues.get(requestId);
|
|
365
|
+
if (queue && queue.length > 0) {
|
|
366
|
+
const next = queue.shift();
|
|
367
|
+
if (queue.length === 0) {
|
|
368
|
+
this.dataQueues.delete(requestId);
|
|
369
|
+
}
|
|
370
|
+
return Promise.resolve(next);
|
|
350
371
|
}
|
|
351
372
|
|
|
352
373
|
return new Promise<any>((resolve, reject) => {
|