@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/dist/index.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- export { q as DexAggregatorOptions, r as DexClient, p as DexRequestContext, L as LIB_VERSION, P as PostOptions, o as TokenProvider } from './index-D3RVUCiG.cjs';
1
+ export { q as DexAggregatorOptions, r as DexClient, p as DexRequestContext, L as LIB_VERSION, P as PostOptions, o as TokenProvider } from './index-CuPWnFsI.cjs';
2
2
  import './WatchlistApi-18jD3YH5.cjs';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { q as DexAggregatorOptions, r as DexClient, p as DexRequestContext, L as LIB_VERSION, P as PostOptions, o as TokenProvider } from './index-BhyMM-wS.js';
1
+ export { q as DexAggregatorOptions, r as DexClient, p as DexRequestContext, L as LIB_VERSION, P as PostOptions, o as TokenProvider } from './index-DWL6morC.js';
2
2
  import './WatchlistApi-18jD3YH5.js';
package/dist/index.mjs CHANGED
@@ -264,10 +264,24 @@ var StreamApi = class {
264
264
  constructor(context) {
265
265
  __publicField(this, "realtimeClient");
266
266
  __publicField(this, "listenersMap");
267
- const realtimeEndpoint = this.buildWsUrl(context.streamUrl, context.accessToken);
267
+ __publicField(this, "context");
268
+ __publicField(this, "initPromise", null);
269
+ this.context = context;
270
+ this.listenersMap = /* @__PURE__ */ new Map();
271
+ }
272
+ /**
273
+ * Initialize Centrifuge client with current token
274
+ * This is called lazily when connect() is called
275
+ */
276
+ async initClient() {
277
+ if (this.realtimeClient) {
278
+ return;
279
+ }
280
+ const token = await this.getTokenValue();
281
+ const realtimeEndpoint = this.buildWsUrl(this.context.streamUrl, token);
268
282
  this.realtimeClient = new Centrifuge(realtimeEndpoint, {
269
283
  getToken: async (_ctx) => {
270
- return typeof context.accessToken === "string" ? context.accessToken : await context.accessToken.getToken();
284
+ return this.getTokenValue();
271
285
  }
272
286
  });
273
287
  this.realtimeClient.on("connected", () => {
@@ -277,34 +291,73 @@ var StreamApi = class {
277
291
  }).on("error", (err) => {
278
292
  console.error("[streaming] error: ", err);
279
293
  });
280
- this.listenersMap = /* @__PURE__ */ new Map();
294
+ }
295
+ /**
296
+ * Wait for initialization to complete
297
+ * If not initialized, auto-connect first
298
+ */
299
+ async ensureInitialized() {
300
+ if (!this.initPromise) {
301
+ this.connect();
302
+ }
303
+ await this.initPromise;
304
+ }
305
+ /**
306
+ * Get token value from string or TokenProvider
307
+ */
308
+ async getTokenValue() {
309
+ return typeof this.context.accessToken === "string" ? this.context.accessToken : await this.context.accessToken.getToken();
281
310
  }
282
311
  /**
283
312
  * Build WebSocket URL with token as query parameter
284
313
  */
285
- buildWsUrl(endpoint, accessToken) {
314
+ buildWsUrl(endpoint, token) {
286
315
  const url = new URL(endpoint);
287
- if (typeof accessToken === "string") {
288
- url.searchParams.set("token", accessToken);
289
- }
316
+ url.searchParams.set("token", token);
290
317
  return url.toString();
291
318
  }
319
+ /**
320
+ * Connect to the WebSocket server.
321
+ * This is automatically called when you use subscribe methods if not already connected.
322
+ * You can also call this method manually for explicit control.
323
+ */
292
324
  connect() {
293
- this.realtimeClient.connect();
325
+ this.initPromise = this.initClient().then(() => {
326
+ this.realtimeClient.connect();
327
+ });
328
+ }
329
+ /**
330
+ * Disconnect from the WebSocket server.
331
+ * All subscriptions will be automatically removed.
332
+ */
333
+ disconnect() {
334
+ if (this.realtimeClient) {
335
+ this.realtimeClient.disconnect();
336
+ }
337
+ }
338
+ /**
339
+ * Check if the WebSocket is currently connected.
340
+ */
341
+ isConnected() {
342
+ return this.realtimeClient?.state === "connected";
294
343
  }
295
344
  /**
296
345
  * Start batching commands for efficient bulk operations
297
346
  * All subscription commands after this call will be batched until stopBatching is called
298
347
  */
299
348
  startBatching() {
300
- this.realtimeClient.startBatching();
349
+ if (this.realtimeClient) {
350
+ this.realtimeClient.startBatching();
351
+ }
301
352
  }
302
353
  /**
303
354
  * Stop batching and flush all collected commands to the server
304
355
  * This will send all batched subscription commands in a single network request
305
356
  */
306
357
  stopBatching() {
307
- this.realtimeClient.stopBatching();
358
+ if (this.realtimeClient) {
359
+ this.realtimeClient.stopBatching();
360
+ }
308
361
  }
309
362
  /**
310
363
  * Batch subscribe method that accepts a function containing subscription calls
@@ -334,26 +387,31 @@ var StreamApi = class {
334
387
  });
335
388
  }
336
389
  subscribe(channel, fn, filter, methodName) {
337
- let sub = this.realtimeClient.getSubscription(channel);
338
390
  let listeners = this.listenersMap.get(channel);
339
- if (!sub) {
391
+ if (!listeners) {
340
392
  listeners = /* @__PURE__ */ new Set();
341
393
  this.listenersMap.set(channel, listeners);
342
- console.log("[xrealtime] create new sub: ", channel);
343
- const processedFilter = filter && methodName ? replaceFilterFields(filter, methodName) : filter;
344
- sub = this.realtimeClient.newSubscription(channel, {
345
- delta: "fossil",
346
- ...processedFilter && { filter: processedFilter }
347
- });
348
- sub.on("subscribed", () => {
349
- console.log("[xrealtime] subscribed", channel);
350
- }).on("unsubscribed", () => {
351
- console.log("[xrealtime] unsubscribed", channel);
352
- }).on("publication", (ctx) => {
353
- listeners?.forEach((it) => it(ctx.data));
354
- }).subscribe();
355
- }
356
- listeners?.add(fn);
394
+ }
395
+ listeners.add(fn);
396
+ this.ensureInitialized().then(() => {
397
+ let sub = this.realtimeClient.getSubscription(channel);
398
+ if (!sub) {
399
+ console.log("[xrealtime] create new sub: ", channel);
400
+ const processedFilter = filter && methodName ? replaceFilterFields(filter, methodName) : filter;
401
+ sub = this.realtimeClient.newSubscription(channel, {
402
+ delta: "fossil",
403
+ ...processedFilter && { filter: processedFilter }
404
+ });
405
+ sub.on("subscribed", () => {
406
+ console.log("[xrealtime] subscribed", channel);
407
+ }).on("unsubscribed", () => {
408
+ console.log("[xrealtime] unsubscribed", channel);
409
+ }).on("publication", (ctx) => {
410
+ const currentListeners = this.listenersMap.get(channel);
411
+ currentListeners?.forEach((it) => it(ctx.data));
412
+ }).subscribe();
413
+ }
414
+ });
357
415
  return new StreamUnsubscrible(this, channel, fn);
358
416
  }
359
417
  unsubscribe(channel, fn) {
@@ -365,12 +423,14 @@ var StreamApi = class {
365
423
  console.log("unsubscribe, remain listeners: ", listeners.size);
366
424
  if (listeners.size === 0) {
367
425
  console.log("unsubscribe channel: ", channel);
368
- const sub = this.realtimeClient.getSubscription(channel);
369
- if (sub) {
370
- sub.unsubscribe();
371
- this.realtimeClient.removeSubscription(sub);
372
- }
373
426
  this.listenersMap.delete(channel);
427
+ this.ensureInitialized().then(() => {
428
+ const sub = this.realtimeClient.getSubscription(channel);
429
+ if (sub) {
430
+ sub.unsubscribe();
431
+ this.realtimeClient.removeSubscription(sub);
432
+ }
433
+ });
374
434
  }
375
435
  }
376
436
  formatScientificNotation(value) {
@@ -8147,7 +8207,7 @@ var WatchlistApi = class extends BaseAPI {
8147
8207
 
8148
8208
  // src/index.ts
8149
8209
  import { EventSourcePolyfill } from "event-source-polyfill";
8150
- var LIB_VERSION = "0.1.20";
8210
+ var LIB_VERSION = "0.1.22";
8151
8211
  var UserAgentMiddleware = class {
8152
8212
  async pre(context) {
8153
8213
  if (!context.init.headers) {
@@ -8185,9 +8245,6 @@ var DexClient = class {
8185
8245
  __publicField(this, "endpoint");
8186
8246
  const baseUrl = options.serverUrl ?? "https://api-dex.chainstream.io";
8187
8247
  const streamUrl = options.streamUrl ?? "wss://realtime-dex.chainstream.io/connection/websocket";
8188
- const tokenProvider = typeof accessToken === "string" ? {
8189
- getToken: () => accessToken
8190
- } : accessToken;
8191
8248
  this.requestCtx = { baseUrl, streamUrl, accessToken };
8192
8249
  const config = new Configuration({
8193
8250
  basePath: baseUrl,
@@ -8217,7 +8274,9 @@ var DexClient = class {
8217
8274
  this.jobs = new JobsApi(config);
8218
8275
  this.kyt = new KYTApi(config);
8219
8276
  this.endpoint = new EndpointApi(config);
8220
- this.stream.connect();
8277
+ if (options.autoConnectWebSocket === true) {
8278
+ this.stream.connect();
8279
+ }
8221
8280
  }
8222
8281
  async waitForJob(jobId, timeout = 6e4) {
8223
8282
  const accessToken = typeof this.requestCtx.accessToken === "string" ? this.requestCtx.accessToken : await this.requestCtx.accessToken.getToken();