@chainstream-io/sdk 0.1.21 → 0.1.22
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 +1 -1
- package/dist/{index-D3RVUCiG.d.cts → index-CuPWnFsI.d.cts} +39 -1
- package/dist/{index-BhyMM-wS.d.ts → index-DWL6morC.d.ts} +39 -1
- package/dist/index.cjs +96 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +96 -37
- package/dist/index.mjs.map +1 -1
- package/dist/stream/index.cjs +91 -31
- package/dist/stream/index.cjs.map +1 -1
- package/dist/stream/index.d.cts +1 -1
- package/dist/stream/index.d.ts +1 -1
- package/dist/stream/index.mjs +91 -31
- package/dist/stream/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -320,12 +320,42 @@ interface Unsubscrible {
|
|
|
320
320
|
declare class StreamApi {
|
|
321
321
|
private realtimeClient;
|
|
322
322
|
private listenersMap;
|
|
323
|
+
private context;
|
|
324
|
+
private initPromise;
|
|
323
325
|
constructor(context: DexRequestContext);
|
|
326
|
+
/**
|
|
327
|
+
* Initialize Centrifuge client with current token
|
|
328
|
+
* This is called lazily when connect() is called
|
|
329
|
+
*/
|
|
330
|
+
private initClient;
|
|
331
|
+
/**
|
|
332
|
+
* Wait for initialization to complete
|
|
333
|
+
* If not initialized, auto-connect first
|
|
334
|
+
*/
|
|
335
|
+
private ensureInitialized;
|
|
336
|
+
/**
|
|
337
|
+
* Get token value from string or TokenProvider
|
|
338
|
+
*/
|
|
339
|
+
private getTokenValue;
|
|
324
340
|
/**
|
|
325
341
|
* Build WebSocket URL with token as query parameter
|
|
326
342
|
*/
|
|
327
343
|
private buildWsUrl;
|
|
344
|
+
/**
|
|
345
|
+
* Connect to the WebSocket server.
|
|
346
|
+
* This is automatically called when you use subscribe methods if not already connected.
|
|
347
|
+
* You can also call this method manually for explicit control.
|
|
348
|
+
*/
|
|
328
349
|
connect(): void;
|
|
350
|
+
/**
|
|
351
|
+
* Disconnect from the WebSocket server.
|
|
352
|
+
* All subscriptions will be automatically removed.
|
|
353
|
+
*/
|
|
354
|
+
disconnect(): void;
|
|
355
|
+
/**
|
|
356
|
+
* Check if the WebSocket is currently connected.
|
|
357
|
+
*/
|
|
358
|
+
isConnected(): boolean;
|
|
329
359
|
/**
|
|
330
360
|
* Start batching commands for efficient bulk operations
|
|
331
361
|
* All subscription commands after this call will be batched until stopBatching is called
|
|
@@ -470,8 +500,16 @@ interface DexAggregatorOptions {
|
|
|
470
500
|
debug?: boolean;
|
|
471
501
|
serverUrl?: string;
|
|
472
502
|
streamUrl?: string;
|
|
503
|
+
/**
|
|
504
|
+
* Whether to automatically connect to WebSocket on initialization.
|
|
505
|
+
* Default: false
|
|
506
|
+
*
|
|
507
|
+
* If set to true, WebSocket will connect automatically.
|
|
508
|
+
* If false or not set, you need to manually call `client.stream.connect()` when needed.
|
|
509
|
+
*/
|
|
510
|
+
autoConnectWebSocket?: boolean;
|
|
473
511
|
}
|
|
474
|
-
declare const LIB_VERSION = "0.1.
|
|
512
|
+
declare const LIB_VERSION = "0.1.22";
|
|
475
513
|
declare class DexClient {
|
|
476
514
|
readonly requestCtx: DexRequestContext;
|
|
477
515
|
readonly _configuration: Configuration;
|
|
@@ -320,12 +320,42 @@ interface Unsubscrible {
|
|
|
320
320
|
declare class StreamApi {
|
|
321
321
|
private realtimeClient;
|
|
322
322
|
private listenersMap;
|
|
323
|
+
private context;
|
|
324
|
+
private initPromise;
|
|
323
325
|
constructor(context: DexRequestContext);
|
|
326
|
+
/**
|
|
327
|
+
* Initialize Centrifuge client with current token
|
|
328
|
+
* This is called lazily when connect() is called
|
|
329
|
+
*/
|
|
330
|
+
private initClient;
|
|
331
|
+
/**
|
|
332
|
+
* Wait for initialization to complete
|
|
333
|
+
* If not initialized, auto-connect first
|
|
334
|
+
*/
|
|
335
|
+
private ensureInitialized;
|
|
336
|
+
/**
|
|
337
|
+
* Get token value from string or TokenProvider
|
|
338
|
+
*/
|
|
339
|
+
private getTokenValue;
|
|
324
340
|
/**
|
|
325
341
|
* Build WebSocket URL with token as query parameter
|
|
326
342
|
*/
|
|
327
343
|
private buildWsUrl;
|
|
344
|
+
/**
|
|
345
|
+
* Connect to the WebSocket server.
|
|
346
|
+
* This is automatically called when you use subscribe methods if not already connected.
|
|
347
|
+
* You can also call this method manually for explicit control.
|
|
348
|
+
*/
|
|
328
349
|
connect(): void;
|
|
350
|
+
/**
|
|
351
|
+
* Disconnect from the WebSocket server.
|
|
352
|
+
* All subscriptions will be automatically removed.
|
|
353
|
+
*/
|
|
354
|
+
disconnect(): void;
|
|
355
|
+
/**
|
|
356
|
+
* Check if the WebSocket is currently connected.
|
|
357
|
+
*/
|
|
358
|
+
isConnected(): boolean;
|
|
329
359
|
/**
|
|
330
360
|
* Start batching commands for efficient bulk operations
|
|
331
361
|
* All subscription commands after this call will be batched until stopBatching is called
|
|
@@ -470,8 +500,16 @@ interface DexAggregatorOptions {
|
|
|
470
500
|
debug?: boolean;
|
|
471
501
|
serverUrl?: string;
|
|
472
502
|
streamUrl?: string;
|
|
503
|
+
/**
|
|
504
|
+
* Whether to automatically connect to WebSocket on initialization.
|
|
505
|
+
* Default: false
|
|
506
|
+
*
|
|
507
|
+
* If set to true, WebSocket will connect automatically.
|
|
508
|
+
* If false or not set, you need to manually call `client.stream.connect()` when needed.
|
|
509
|
+
*/
|
|
510
|
+
autoConnectWebSocket?: boolean;
|
|
473
511
|
}
|
|
474
|
-
declare const LIB_VERSION = "0.1.
|
|
512
|
+
declare const LIB_VERSION = "0.1.22";
|
|
475
513
|
declare class DexClient {
|
|
476
514
|
readonly requestCtx: DexRequestContext;
|
|
477
515
|
readonly _configuration: Configuration;
|
package/dist/index.cjs
CHANGED
|
@@ -289,10 +289,24 @@ var StreamApi = class {
|
|
|
289
289
|
constructor(context) {
|
|
290
290
|
__publicField(this, "realtimeClient");
|
|
291
291
|
__publicField(this, "listenersMap");
|
|
292
|
-
|
|
292
|
+
__publicField(this, "context");
|
|
293
|
+
__publicField(this, "initPromise", null);
|
|
294
|
+
this.context = context;
|
|
295
|
+
this.listenersMap = /* @__PURE__ */ new Map();
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Initialize Centrifuge client with current token
|
|
299
|
+
* This is called lazily when connect() is called
|
|
300
|
+
*/
|
|
301
|
+
async initClient() {
|
|
302
|
+
if (this.realtimeClient) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const token = await this.getTokenValue();
|
|
306
|
+
const realtimeEndpoint = this.buildWsUrl(this.context.streamUrl, token);
|
|
293
307
|
this.realtimeClient = new import_centrifuge.Centrifuge(realtimeEndpoint, {
|
|
294
308
|
getToken: async (_ctx) => {
|
|
295
|
-
return
|
|
309
|
+
return this.getTokenValue();
|
|
296
310
|
}
|
|
297
311
|
});
|
|
298
312
|
this.realtimeClient.on("connected", () => {
|
|
@@ -302,34 +316,73 @@ var StreamApi = class {
|
|
|
302
316
|
}).on("error", (err) => {
|
|
303
317
|
console.error("[streaming] error: ", err);
|
|
304
318
|
});
|
|
305
|
-
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Wait for initialization to complete
|
|
322
|
+
* If not initialized, auto-connect first
|
|
323
|
+
*/
|
|
324
|
+
async ensureInitialized() {
|
|
325
|
+
if (!this.initPromise) {
|
|
326
|
+
this.connect();
|
|
327
|
+
}
|
|
328
|
+
await this.initPromise;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Get token value from string or TokenProvider
|
|
332
|
+
*/
|
|
333
|
+
async getTokenValue() {
|
|
334
|
+
return typeof this.context.accessToken === "string" ? this.context.accessToken : await this.context.accessToken.getToken();
|
|
306
335
|
}
|
|
307
336
|
/**
|
|
308
337
|
* Build WebSocket URL with token as query parameter
|
|
309
338
|
*/
|
|
310
|
-
buildWsUrl(endpoint,
|
|
339
|
+
buildWsUrl(endpoint, token) {
|
|
311
340
|
const url = new URL(endpoint);
|
|
312
|
-
|
|
313
|
-
url.searchParams.set("token", accessToken);
|
|
314
|
-
}
|
|
341
|
+
url.searchParams.set("token", token);
|
|
315
342
|
return url.toString();
|
|
316
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Connect to the WebSocket server.
|
|
346
|
+
* This is automatically called when you use subscribe methods if not already connected.
|
|
347
|
+
* You can also call this method manually for explicit control.
|
|
348
|
+
*/
|
|
317
349
|
connect() {
|
|
318
|
-
this.
|
|
350
|
+
this.initPromise = this.initClient().then(() => {
|
|
351
|
+
this.realtimeClient.connect();
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Disconnect from the WebSocket server.
|
|
356
|
+
* All subscriptions will be automatically removed.
|
|
357
|
+
*/
|
|
358
|
+
disconnect() {
|
|
359
|
+
if (this.realtimeClient) {
|
|
360
|
+
this.realtimeClient.disconnect();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check if the WebSocket is currently connected.
|
|
365
|
+
*/
|
|
366
|
+
isConnected() {
|
|
367
|
+
return this.realtimeClient?.state === "connected";
|
|
319
368
|
}
|
|
320
369
|
/**
|
|
321
370
|
* Start batching commands for efficient bulk operations
|
|
322
371
|
* All subscription commands after this call will be batched until stopBatching is called
|
|
323
372
|
*/
|
|
324
373
|
startBatching() {
|
|
325
|
-
this.realtimeClient
|
|
374
|
+
if (this.realtimeClient) {
|
|
375
|
+
this.realtimeClient.startBatching();
|
|
376
|
+
}
|
|
326
377
|
}
|
|
327
378
|
/**
|
|
328
379
|
* Stop batching and flush all collected commands to the server
|
|
329
380
|
* This will send all batched subscription commands in a single network request
|
|
330
381
|
*/
|
|
331
382
|
stopBatching() {
|
|
332
|
-
this.realtimeClient
|
|
383
|
+
if (this.realtimeClient) {
|
|
384
|
+
this.realtimeClient.stopBatching();
|
|
385
|
+
}
|
|
333
386
|
}
|
|
334
387
|
/**
|
|
335
388
|
* Batch subscribe method that accepts a function containing subscription calls
|
|
@@ -359,26 +412,31 @@ var StreamApi = class {
|
|
|
359
412
|
});
|
|
360
413
|
}
|
|
361
414
|
subscribe(channel, fn, filter, methodName) {
|
|
362
|
-
let sub = this.realtimeClient.getSubscription(channel);
|
|
363
415
|
let listeners = this.listenersMap.get(channel);
|
|
364
|
-
if (!
|
|
416
|
+
if (!listeners) {
|
|
365
417
|
listeners = /* @__PURE__ */ new Set();
|
|
366
418
|
this.listenersMap.set(channel, listeners);
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
419
|
+
}
|
|
420
|
+
listeners.add(fn);
|
|
421
|
+
this.ensureInitialized().then(() => {
|
|
422
|
+
let sub = this.realtimeClient.getSubscription(channel);
|
|
423
|
+
if (!sub) {
|
|
424
|
+
console.log("[xrealtime] create new sub: ", channel);
|
|
425
|
+
const processedFilter = filter && methodName ? replaceFilterFields(filter, methodName) : filter;
|
|
426
|
+
sub = this.realtimeClient.newSubscription(channel, {
|
|
427
|
+
delta: "fossil",
|
|
428
|
+
...processedFilter && { filter: processedFilter }
|
|
429
|
+
});
|
|
430
|
+
sub.on("subscribed", () => {
|
|
431
|
+
console.log("[xrealtime] subscribed", channel);
|
|
432
|
+
}).on("unsubscribed", () => {
|
|
433
|
+
console.log("[xrealtime] unsubscribed", channel);
|
|
434
|
+
}).on("publication", (ctx) => {
|
|
435
|
+
const currentListeners = this.listenersMap.get(channel);
|
|
436
|
+
currentListeners?.forEach((it) => it(ctx.data));
|
|
437
|
+
}).subscribe();
|
|
438
|
+
}
|
|
439
|
+
});
|
|
382
440
|
return new StreamUnsubscrible(this, channel, fn);
|
|
383
441
|
}
|
|
384
442
|
unsubscribe(channel, fn) {
|
|
@@ -390,12 +448,14 @@ var StreamApi = class {
|
|
|
390
448
|
console.log("unsubscribe, remain listeners: ", listeners.size);
|
|
391
449
|
if (listeners.size === 0) {
|
|
392
450
|
console.log("unsubscribe channel: ", channel);
|
|
393
|
-
const sub = this.realtimeClient.getSubscription(channel);
|
|
394
|
-
if (sub) {
|
|
395
|
-
sub.unsubscribe();
|
|
396
|
-
this.realtimeClient.removeSubscription(sub);
|
|
397
|
-
}
|
|
398
451
|
this.listenersMap.delete(channel);
|
|
452
|
+
this.ensureInitialized().then(() => {
|
|
453
|
+
const sub = this.realtimeClient.getSubscription(channel);
|
|
454
|
+
if (sub) {
|
|
455
|
+
sub.unsubscribe();
|
|
456
|
+
this.realtimeClient.removeSubscription(sub);
|
|
457
|
+
}
|
|
458
|
+
});
|
|
399
459
|
}
|
|
400
460
|
}
|
|
401
461
|
formatScientificNotation(value) {
|
|
@@ -8172,7 +8232,7 @@ var WatchlistApi = class extends BaseAPI {
|
|
|
8172
8232
|
|
|
8173
8233
|
// src/index.ts
|
|
8174
8234
|
var import_event_source_polyfill = require("event-source-polyfill");
|
|
8175
|
-
var LIB_VERSION = "0.1.
|
|
8235
|
+
var LIB_VERSION = "0.1.22";
|
|
8176
8236
|
var UserAgentMiddleware = class {
|
|
8177
8237
|
async pre(context) {
|
|
8178
8238
|
if (!context.init.headers) {
|
|
@@ -8210,9 +8270,6 @@ var DexClient = class {
|
|
|
8210
8270
|
__publicField(this, "endpoint");
|
|
8211
8271
|
const baseUrl = options.serverUrl ?? "https://api-dex.chainstream.io";
|
|
8212
8272
|
const streamUrl = options.streamUrl ?? "wss://realtime-dex.chainstream.io/connection/websocket";
|
|
8213
|
-
const tokenProvider = typeof accessToken === "string" ? {
|
|
8214
|
-
getToken: () => accessToken
|
|
8215
|
-
} : accessToken;
|
|
8216
8273
|
this.requestCtx = { baseUrl, streamUrl, accessToken };
|
|
8217
8274
|
const config = new Configuration({
|
|
8218
8275
|
basePath: baseUrl,
|
|
@@ -8242,7 +8299,9 @@ var DexClient = class {
|
|
|
8242
8299
|
this.jobs = new JobsApi(config);
|
|
8243
8300
|
this.kyt = new KYTApi(config);
|
|
8244
8301
|
this.endpoint = new EndpointApi(config);
|
|
8245
|
-
|
|
8302
|
+
if (options.autoConnectWebSocket === true) {
|
|
8303
|
+
this.stream.connect();
|
|
8304
|
+
}
|
|
8246
8305
|
}
|
|
8247
8306
|
async waitForJob(jobId, timeout = 6e4) {
|
|
8248
8307
|
const accessToken = typeof this.requestCtx.accessToken === "string" ? this.requestCtx.accessToken : await this.requestCtx.accessToken.getToken();
|