@liberfi.io/react-predict 0.3.47 → 0.3.48

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/server.mjs CHANGED
@@ -625,6 +625,13 @@ var DEFAULT_RECONNECT_BASE = 1e3;
625
625
  var DEFAULT_RECONNECT_MAX = 3e4;
626
626
  var DEFAULT_PING_INTERVAL = 2e4;
627
627
  var DEFAULT_PONG_TIMEOUT = 1e4;
628
+ var MAX_SUBSCRIPTION_FRAME_BYTES = 3500;
629
+ function byteLength(str) {
630
+ if (typeof TextEncoder !== "undefined") {
631
+ return new TextEncoder().encode(str).length;
632
+ }
633
+ return str.length;
634
+ }
628
635
  var PredictWsClient = class {
629
636
  ws = null;
630
637
  wsUrl;
@@ -742,7 +749,7 @@ var PredictWsClient = class {
742
749
  const set = this.subs.channels.get(ch);
743
750
  for (const slug of marketSlugs) set.add(slug);
744
751
  }
745
- this.send({ type: "subscribe", channels, market_slugs: marketSlugs });
752
+ this.sendChunkedSubscription("subscribe", channels, marketSlugs);
746
753
  }
747
754
  /**
748
755
  * Unsubscribe from one or more channels for the given market slugs.
@@ -752,7 +759,7 @@ var PredictWsClient = class {
752
759
  const set = this.subs.channels.get(ch);
753
760
  for (const slug of marketSlugs) set.delete(slug);
754
761
  }
755
- this.send({ type: "unsubscribe", channels, market_slugs: marketSlugs });
762
+ this.sendChunkedSubscription("unsubscribe", channels, marketSlugs);
756
763
  }
757
764
  // -------------------------------------------------------------------------
758
765
  // Subscription — convenience (single channel)
@@ -908,14 +915,40 @@ var PredictWsClient = class {
908
915
  restoreSubscriptions() {
909
916
  for (const [channel, slugs] of this.subs.channels.entries()) {
910
917
  if (slugs.size > 0) {
911
- this.send({
912
- type: "subscribe",
913
- channels: [channel],
914
- market_slugs: Array.from(slugs)
915
- });
918
+ this.sendChunkedSubscription("subscribe", [channel], Array.from(slugs));
916
919
  }
917
920
  }
918
921
  }
922
+ /**
923
+ * Send a subscribe/unsubscribe message, splitting `marketSlugs` across
924
+ * multiple frames so no single frame exceeds the server read limit.
925
+ */
926
+ sendChunkedSubscription(type, channels, marketSlugs) {
927
+ if (marketSlugs.length === 0) {
928
+ this.send({ type, channels, market_slugs: [] });
929
+ return;
930
+ }
931
+ const envelopeBytes = byteLength(
932
+ JSON.stringify({ type, channels, market_slugs: [] })
933
+ );
934
+ const budget = MAX_SUBSCRIPTION_FRAME_BYTES - envelopeBytes;
935
+ let chunk = [];
936
+ let chunkBytes = 0;
937
+ const flush = () => {
938
+ if (chunk.length > 0) {
939
+ this.send({ type, channels, market_slugs: chunk });
940
+ chunk = [];
941
+ chunkBytes = 0;
942
+ }
943
+ };
944
+ for (const slug of marketSlugs) {
945
+ const slugBytes = byteLength(JSON.stringify(slug)) + 1;
946
+ if (chunk.length > 0 && chunkBytes + slugBytes > budget) flush();
947
+ chunk.push(slug);
948
+ chunkBytes += slugBytes;
949
+ }
950
+ flush();
951
+ }
919
952
  startPing() {
920
953
  this.stopPing();
921
954
  this.pingTimer = setInterval(() => {