react-websocket 3.3.0 → 3.6.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 +15 -6
- package/dist/chaos.cjs +284 -0
- package/dist/chaos.cjs.map +1 -0
- package/dist/chaos.d.cts +131 -0
- package/dist/chaos.d.ts +131 -0
- package/dist/chaos.js +283 -0
- package/dist/chaos.js.map +1 -0
- package/dist/core.cjs +271 -72
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +166 -11
- package/dist/core.d.ts +166 -11
- package/dist/core.js +271 -73
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +64 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +221 -11
- package/dist/index.d.ts +140 -5
- package/dist/index.js +65 -2
- package/dist/index.js.map +1 -1
- package/dist/timeline.cjs +162 -0
- package/dist/timeline.cjs.map +1 -0
- package/dist/timeline.d.cts +379 -0
- package/dist/timeline.d.ts +140 -0
- package/dist/timeline.js +161 -0
- package/dist/timeline.js.map +1 -0
- package/package.json +67 -16
package/dist/core.js
CHANGED
|
@@ -348,13 +348,18 @@ function createClient(url, options = {}) {
|
|
|
348
348
|
set({ lastMessage: message });
|
|
349
349
|
emit("message", message, event);
|
|
350
350
|
}
|
|
351
|
-
function send(message, sendOptions) {
|
|
351
|
+
function send(message, sendOptions = {}) {
|
|
352
352
|
const data = options.serialize ? options.serialize(message) : options.json ? JSON.stringify(message) : message;
|
|
353
|
+
const { key, priority, maxBuffered } = sendOptions;
|
|
353
354
|
if (ws && ws.readyState === OPEN) {
|
|
355
|
+
if (maxBuffered !== void 0 && ws.bufferedAmount > maxBuffered) {
|
|
356
|
+
log("dropped message: send buffer above maxBuffered");
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
354
359
|
ws.send(data);
|
|
355
360
|
return true;
|
|
356
361
|
}
|
|
357
|
-
if (queueLimit === 0 || sendOptions
|
|
362
|
+
if (queueLimit === 0 || sendOptions.volatile) {
|
|
358
363
|
log("dropped message: socket is not open");
|
|
359
364
|
return false;
|
|
360
365
|
}
|
|
@@ -362,19 +367,23 @@ function createClient(url, options = {}) {
|
|
|
362
367
|
log("dropped message: no WebSocket implementation available");
|
|
363
368
|
return false;
|
|
364
369
|
}
|
|
365
|
-
const key = sendOptions?.key;
|
|
366
370
|
if (key !== void 0) pending = pending.filter((entry) => {
|
|
367
371
|
if (entry.key !== key) return true;
|
|
368
372
|
dropped(entry);
|
|
369
373
|
return false;
|
|
370
374
|
});
|
|
371
|
-
pending.
|
|
375
|
+
let head = pending.findIndex((entry) => !entry.priority);
|
|
376
|
+
if (head < 0) head = pending.length;
|
|
377
|
+
const entry = {
|
|
372
378
|
data,
|
|
373
379
|
key,
|
|
374
|
-
|
|
375
|
-
|
|
380
|
+
priority,
|
|
381
|
+
onDrop: sendOptions.onDrop
|
|
382
|
+
};
|
|
383
|
+
if (priority) pending.splice(head++, 0, entry);
|
|
384
|
+
else pending.push(entry);
|
|
376
385
|
if (pending.length > queueLimit) {
|
|
377
|
-
dropped(pending.
|
|
386
|
+
dropped(pending.splice(head < pending.length ? head : 0, 1)[0]);
|
|
378
387
|
log(`dropped oldest queued message: queue limit (${queueLimit}) reached`);
|
|
379
388
|
}
|
|
380
389
|
return false;
|
|
@@ -650,6 +659,8 @@ function createWebSocketLatency(client, options) {
|
|
|
650
659
|
//#endregion
|
|
651
660
|
//#region src/requests.ts
|
|
652
661
|
const lastIds = /* @__PURE__ */ new WeakMap();
|
|
662
|
+
const VOLATILE$2 = { volatile: true };
|
|
663
|
+
const noop = () => {};
|
|
653
664
|
/**
|
|
654
665
|
* Send requests and await their replies, matched by an id the library generates.
|
|
655
666
|
*
|
|
@@ -670,8 +681,8 @@ const lastIds = /* @__PURE__ */ new WeakMap();
|
|
|
670
681
|
*/
|
|
671
682
|
function createWebSocketRequests(client, options) {
|
|
672
683
|
const waiting = /* @__PURE__ */ new Map();
|
|
673
|
-
function
|
|
674
|
-
for (const entry of [...waiting.values()]) if (test(entry)) entry.
|
|
684
|
+
function endWhere(test, reason, cancel) {
|
|
685
|
+
for (const entry of [...waiting.values()]) if (test(entry)) entry.end(true, reason(), cancel);
|
|
675
686
|
}
|
|
676
687
|
const offs = [
|
|
677
688
|
client.on("message", (message) => {
|
|
@@ -679,83 +690,137 @@ function createWebSocketRequests(client, options) {
|
|
|
679
690
|
const entry = id == null ? void 0 : waiting.get(String(id));
|
|
680
691
|
if (!entry) return;
|
|
681
692
|
const error = options.error?.(message);
|
|
682
|
-
if (error === void 0) entry.
|
|
683
|
-
else entry.
|
|
693
|
+
if (error === void 0) entry.receive(message);
|
|
694
|
+
else entry.end(true, error);
|
|
684
695
|
}),
|
|
685
696
|
client.on("open", () => {
|
|
686
697
|
for (const entry of waiting.values()) entry.socket ??= client.socket;
|
|
687
698
|
}),
|
|
688
699
|
client.subscribe(() => {
|
|
689
700
|
const { status } = client.getSnapshot();
|
|
690
|
-
if (status === "closed" || status === "idle")
|
|
691
|
-
else
|
|
701
|
+
if (status === "closed" || status === "idle") endWhere(() => true, () => /* @__PURE__ */ new Error("WebSocket was closed before the request was answered"));
|
|
702
|
+
else endWhere((entry) => entry.socket !== null && entry.socket !== client.socket, () => /* @__PURE__ */ new Error("WebSocket connection was lost before the request was answered"));
|
|
692
703
|
})
|
|
693
704
|
];
|
|
705
|
+
/**
|
|
706
|
+
* Send `message` as a new request. `next` gets each reply that isn't an error and returns
|
|
707
|
+
* whether it was the last; `done` runs once, when the request ends. Returns a function that
|
|
708
|
+
* ends it from this side and tells the server.
|
|
709
|
+
*/
|
|
710
|
+
function start(message, requestOptions, next, done) {
|
|
711
|
+
const { signal, priority } = requestOptions;
|
|
712
|
+
if (signal?.aborted) {
|
|
713
|
+
done(true, signal.reason);
|
|
714
|
+
return noop;
|
|
715
|
+
}
|
|
716
|
+
const id = (lastIds.get(client) ?? 0) + 1;
|
|
717
|
+
lastIds.set(client, id);
|
|
718
|
+
const key = String(id);
|
|
719
|
+
const timeout = requestOptions.timeout ?? options.timeout ?? 1e4;
|
|
720
|
+
const release = client.acquire();
|
|
721
|
+
let timer;
|
|
722
|
+
const onAbort = () => entry.end(true, signal.reason, true);
|
|
723
|
+
function arm() {
|
|
724
|
+
clearTimeout(timer);
|
|
725
|
+
if (timeout > 0 && timeout < Infinity) timer = setTimeout(() => entry.end(true, new DOMException(`Request ${id} timed out after ${timeout}ms`, "TimeoutError"), true), timeout);
|
|
726
|
+
}
|
|
727
|
+
const entry = {
|
|
728
|
+
socket: null,
|
|
729
|
+
receive(reply) {
|
|
730
|
+
if (next(reply)) entry.end(false);
|
|
731
|
+
else arm();
|
|
732
|
+
},
|
|
733
|
+
end(failed, reason, cancel) {
|
|
734
|
+
if (!waiting.delete(key)) return;
|
|
735
|
+
clearTimeout(timer);
|
|
736
|
+
signal?.removeEventListener("abort", onAbort);
|
|
737
|
+
release();
|
|
738
|
+
done(failed, reason);
|
|
739
|
+
if (cancel && options.cancel) try {
|
|
740
|
+
client.send(options.cancel(id), entry.socket ? VOLATILE$2 : { priority });
|
|
741
|
+
} catch (error) {
|
|
742
|
+
queueMicrotask(() => {
|
|
743
|
+
throw error;
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
waiting.set(key, entry);
|
|
749
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
750
|
+
arm();
|
|
751
|
+
const { status } = client.getSnapshot();
|
|
752
|
+
if (status === "closed" || status === "idle") entry.end(true, /* @__PURE__ */ new Error(`WebSocket is ${status}: request not sent`));
|
|
753
|
+
else try {
|
|
754
|
+
if (client.send(options.send(message, id), {
|
|
755
|
+
...requestOptions,
|
|
756
|
+
onDrop() {
|
|
757
|
+
entry.end(true, /* @__PURE__ */ new Error("Request was dropped from the send queue before it was sent"));
|
|
758
|
+
requestOptions.onDrop?.();
|
|
759
|
+
}
|
|
760
|
+
})) entry.socket = client.socket;
|
|
761
|
+
else if (client.socket?.readyState === 1) entry.end(true, /* @__PURE__ */ new Error("WebSocket send buffer is full: request dropped"));
|
|
762
|
+
else if (requestOptions.volatile) entry.end(true, /* @__PURE__ */ new Error("WebSocket is not open: request dropped"));
|
|
763
|
+
} catch (error) {
|
|
764
|
+
entry.end(true, error);
|
|
765
|
+
}
|
|
766
|
+
return () => entry.end(false, void 0, true);
|
|
767
|
+
}
|
|
694
768
|
return {
|
|
695
769
|
client,
|
|
696
770
|
request(message, requestOptions = {}) {
|
|
697
|
-
const { signal } = requestOptions;
|
|
698
|
-
if (signal?.aborted) return Promise.reject(signal.reason);
|
|
699
|
-
const id = (lastIds.get(client) ?? 0) + 1;
|
|
700
|
-
lastIds.set(client, id);
|
|
701
|
-
const key = String(id);
|
|
702
|
-
const timeout = requestOptions.timeout ?? options.timeout ?? 1e4;
|
|
703
771
|
return new Promise((resolve, reject) => {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (status === "closed" || status === "idle") {
|
|
729
|
-
entry.reject(/* @__PURE__ */ new Error(`WebSocket is ${status}: request not sent`));
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
let sent;
|
|
772
|
+
start(message, requestOptions, (reply) => {
|
|
773
|
+
resolve(reply);
|
|
774
|
+
return true;
|
|
775
|
+
}, (failed, reason) => {
|
|
776
|
+
if (failed) reject(reason);
|
|
777
|
+
});
|
|
778
|
+
});
|
|
779
|
+
},
|
|
780
|
+
stream(message, requestOptions = {}) {
|
|
781
|
+
const last = options.done;
|
|
782
|
+
if (!last) throw new TypeError("stream() needs the `done` option");
|
|
783
|
+
const replies = [];
|
|
784
|
+
let ended;
|
|
785
|
+
let wake = noop;
|
|
786
|
+
const stop = start(message, requestOptions, (reply) => {
|
|
787
|
+
replies.push(reply);
|
|
788
|
+
wake();
|
|
789
|
+
return last(reply);
|
|
790
|
+
}, (failed, reason) => {
|
|
791
|
+
if (requestOptions.signal?.aborted) replies.length = 0;
|
|
792
|
+
ended = [failed, reason];
|
|
793
|
+
wake();
|
|
794
|
+
});
|
|
795
|
+
async function* read() {
|
|
733
796
|
try {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
} catch (error) {
|
|
742
|
-
entry.reject(error);
|
|
743
|
-
return;
|
|
797
|
+
for (;;) if (replies.length) yield replies.shift();
|
|
798
|
+
else if (ended) {
|
|
799
|
+
if (ended[0]) throw ended[1];
|
|
800
|
+
return;
|
|
801
|
+
} else await new Promise((resolve) => wake = resolve);
|
|
802
|
+
} finally {
|
|
803
|
+
stop();
|
|
744
804
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
805
|
+
}
|
|
806
|
+
const iterator = read();
|
|
807
|
+
const close = iterator.return;
|
|
808
|
+
iterator.return = (value) => {
|
|
809
|
+
stop();
|
|
810
|
+
return close.call(iterator, value);
|
|
811
|
+
};
|
|
812
|
+
return iterator;
|
|
748
813
|
},
|
|
749
814
|
pending: () => waiting.size,
|
|
750
815
|
dispose() {
|
|
751
816
|
offs.forEach((off) => off());
|
|
752
|
-
|
|
817
|
+
endWhere(() => true, () => /* @__PURE__ */ new Error("Requests were disposed"), true);
|
|
753
818
|
}
|
|
754
819
|
};
|
|
755
820
|
}
|
|
756
821
|
//#endregion
|
|
757
822
|
//#region src/responder.ts
|
|
758
|
-
const VOLATILE = { volatile: true };
|
|
823
|
+
const VOLATILE$1 = { volatile: true };
|
|
759
824
|
const abortError = (message) => new DOMException(message, "AbortError");
|
|
760
825
|
/**
|
|
761
826
|
* Answer requests the server sends: run a handler for tools that only exist in the browser
|
|
@@ -796,9 +861,9 @@ function createWebSocketResponder(client, options) {
|
|
|
796
861
|
/** Send a reply, or an `error` reply if building or encoding it throws. */
|
|
797
862
|
function reply(id, build) {
|
|
798
863
|
try {
|
|
799
|
-
return client.send(build(), VOLATILE);
|
|
864
|
+
return client.send(build(), VOLATILE$1);
|
|
800
865
|
} catch (error) {
|
|
801
|
-
return client.send(options.error(id, error), VOLATILE);
|
|
866
|
+
return client.send(options.error(id, error), VOLATILE$1);
|
|
802
867
|
}
|
|
803
868
|
}
|
|
804
869
|
function receive(incoming) {
|
|
@@ -897,6 +962,123 @@ function createWebSocketResponder(client, options) {
|
|
|
897
962
|
};
|
|
898
963
|
}
|
|
899
964
|
//#endregion
|
|
965
|
+
//#region src/sendrate.ts
|
|
966
|
+
const VOLATILE = { volatile: true };
|
|
967
|
+
/**
|
|
968
|
+
* Send high-rate state, such as aim, cursor or position, at a rate that adapts to the
|
|
969
|
+
* connection. Messages are coalesced per key between ticks. The rate drops by half when the
|
|
970
|
+
* send buffer fills up or the round trip grows, and climbs back one tick per second at a time
|
|
971
|
+
* when the link keeps up, so players on a poor connection degrade smoothly instead of building
|
|
972
|
+
* up lag.
|
|
973
|
+
*
|
|
974
|
+
* Ticks run only while the socket is open and something is waiting. Messages waiting during a
|
|
975
|
+
* reconnect go out after it; `close()` drops them. It doesn't open the connection by itself.
|
|
976
|
+
*
|
|
977
|
+
* @example
|
|
978
|
+
* ```ts
|
|
979
|
+
* export const stream = createWebSocketSendRate(game, { latency, maxRate: 30 });
|
|
980
|
+
*
|
|
981
|
+
* // On every pointer move: at most 30 a second, fewer on a congested link.
|
|
982
|
+
* stream.send({ type: 'aim', angle }, 'aim');
|
|
983
|
+
* ```
|
|
984
|
+
*/
|
|
985
|
+
function createWebSocketSendRate(client, options = {}) {
|
|
986
|
+
const { maxBuffered = 1024, latency, maxRttIncrease = 100 } = options;
|
|
987
|
+
const maxRate = options.maxRate ?? 30;
|
|
988
|
+
const minRate = Math.min(options.minRate ?? 5, maxRate);
|
|
989
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
990
|
+
const pending = /* @__PURE__ */ new Map();
|
|
991
|
+
let rate = maxRate;
|
|
992
|
+
let snapshot = {
|
|
993
|
+
rate: maxRate,
|
|
994
|
+
congested: false
|
|
995
|
+
};
|
|
996
|
+
let last = -Infinity;
|
|
997
|
+
let best = Infinity;
|
|
998
|
+
let slow = false;
|
|
999
|
+
let measured;
|
|
1000
|
+
let timer;
|
|
1001
|
+
let disposed = false;
|
|
1002
|
+
function flush() {
|
|
1003
|
+
for (const [key, message] of pending) {
|
|
1004
|
+
if (!client.send(message, VOLATILE)) return;
|
|
1005
|
+
pending.delete(key);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
function publish(congested) {
|
|
1009
|
+
const rounded = Math.round(rate);
|
|
1010
|
+
if (rounded === snapshot.rate && congested === snapshot.congested) return;
|
|
1011
|
+
snapshot = {
|
|
1012
|
+
rate: rounded,
|
|
1013
|
+
congested
|
|
1014
|
+
};
|
|
1015
|
+
for (const listener of [...listeners]) listener();
|
|
1016
|
+
}
|
|
1017
|
+
function schedule() {
|
|
1018
|
+
if (disposed || timer !== void 0 || !pending.size || client.getSnapshot().status !== "open") return;
|
|
1019
|
+
timer = setTimeout(tick, Math.max(0, last + 1e3 / rate - performance.now()));
|
|
1020
|
+
}
|
|
1021
|
+
function stop() {
|
|
1022
|
+
clearTimeout(timer);
|
|
1023
|
+
timer = void 0;
|
|
1024
|
+
}
|
|
1025
|
+
function tick() {
|
|
1026
|
+
timer = void 0;
|
|
1027
|
+
last = performance.now();
|
|
1028
|
+
const measurement = latency?.getSnapshot();
|
|
1029
|
+
if (measurement !== measured) {
|
|
1030
|
+
measured = measurement;
|
|
1031
|
+
const rtt = measurement?.rtt;
|
|
1032
|
+
if (rtt !== void 0) {
|
|
1033
|
+
best = Math.min(best, rtt);
|
|
1034
|
+
slow = rtt - best > maxRttIncrease;
|
|
1035
|
+
if (slow) rate /= 2;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
const full = (client.socket?.bufferedAmount ?? 0) > maxBuffered;
|
|
1039
|
+
if (full) rate /= 2;
|
|
1040
|
+
else {
|
|
1041
|
+
flush();
|
|
1042
|
+
if (!slow) rate++;
|
|
1043
|
+
}
|
|
1044
|
+
rate = Math.min(maxRate, Math.max(minRate, rate));
|
|
1045
|
+
publish(full || slow);
|
|
1046
|
+
schedule();
|
|
1047
|
+
}
|
|
1048
|
+
const offs = [client.on("open", () => {
|
|
1049
|
+
best = Infinity;
|
|
1050
|
+
slow = false;
|
|
1051
|
+
measured = latency?.getSnapshot();
|
|
1052
|
+
schedule();
|
|
1053
|
+
}), client.subscribe(() => {
|
|
1054
|
+
const { status } = client.getSnapshot();
|
|
1055
|
+
if (status !== "open") stop();
|
|
1056
|
+
if (status === "closed" || status === "idle") pending.clear();
|
|
1057
|
+
})];
|
|
1058
|
+
return {
|
|
1059
|
+
client,
|
|
1060
|
+
send(message, key) {
|
|
1061
|
+
pending.delete(key);
|
|
1062
|
+
pending.set(key, message);
|
|
1063
|
+
schedule();
|
|
1064
|
+
},
|
|
1065
|
+
flush,
|
|
1066
|
+
getSnapshot: () => snapshot,
|
|
1067
|
+
subscribe(listener) {
|
|
1068
|
+
listeners.add(listener);
|
|
1069
|
+
return () => {
|
|
1070
|
+
listeners.delete(listener);
|
|
1071
|
+
};
|
|
1072
|
+
},
|
|
1073
|
+
dispose() {
|
|
1074
|
+
disposed = true;
|
|
1075
|
+
stop();
|
|
1076
|
+
pending.clear();
|
|
1077
|
+
offs.forEach((off) => off());
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
//#endregion
|
|
900
1082
|
//#region src/state.ts
|
|
901
1083
|
/**
|
|
902
1084
|
* Keep state derived from a client's messages, like a reducer that runs on every message.
|
|
@@ -917,14 +1099,30 @@ function createWebSocketResponder(client, options) {
|
|
|
917
1099
|
* ```
|
|
918
1100
|
*/
|
|
919
1101
|
function createWebSocketState(client, options) {
|
|
920
|
-
const { initialState, reduce } = options;
|
|
1102
|
+
const { initialState, reduce, batch } = options;
|
|
921
1103
|
let state = initialState;
|
|
1104
|
+
let notified = state;
|
|
1105
|
+
let frame = false;
|
|
922
1106
|
const listeners = /* @__PURE__ */ new Set();
|
|
923
|
-
function
|
|
924
|
-
|
|
1107
|
+
function notify() {
|
|
1108
|
+
if (Object.is(state, notified)) return;
|
|
1109
|
+
notified = state;
|
|
1110
|
+
for (const listener of [...listeners]) listener();
|
|
1111
|
+
}
|
|
1112
|
+
function flush() {
|
|
1113
|
+
frame = false;
|
|
1114
|
+
notify();
|
|
1115
|
+
}
|
|
1116
|
+
function update(change, later) {
|
|
1117
|
+
const next = typeof change === "function" ? change(state) : change;
|
|
925
1118
|
if (Object.is(next, state)) return;
|
|
926
1119
|
state = next;
|
|
927
|
-
|
|
1120
|
+
if (!later) notify();
|
|
1121
|
+
else if (!frame) {
|
|
1122
|
+
frame = true;
|
|
1123
|
+
if (typeof requestAnimationFrame === "function") requestAnimationFrame(flush);
|
|
1124
|
+
else setTimeout(flush, 16);
|
|
1125
|
+
}
|
|
928
1126
|
}
|
|
929
1127
|
return {
|
|
930
1128
|
client,
|
|
@@ -936,9 +1134,9 @@ function createWebSocketState(client, options) {
|
|
|
936
1134
|
listeners.delete(listener);
|
|
937
1135
|
};
|
|
938
1136
|
},
|
|
939
|
-
setState,
|
|
940
|
-
reset: () =>
|
|
941
|
-
dispose: client.on("message", (message) =>
|
|
1137
|
+
setState: (change) => update(change),
|
|
1138
|
+
reset: () => update(initialState),
|
|
1139
|
+
dispose: client.on("message", (message) => update((current) => reduce(current, message), batch === "frame"))
|
|
942
1140
|
};
|
|
943
1141
|
}
|
|
944
1142
|
//#endregion
|
|
@@ -1025,6 +1223,6 @@ function createWebSocketTopics(client, options) {
|
|
|
1025
1223
|
};
|
|
1026
1224
|
}
|
|
1027
1225
|
//#endregion
|
|
1028
|
-
export { MessageError, createWebSocket, createWebSocketLatency, createWebSocketRequests, createWebSocketResponder, createWebSocketState, createWebSocketTopics };
|
|
1226
|
+
export { MessageError, createWebSocket, createWebSocketLatency, createWebSocketRequests, createWebSocketResponder, createWebSocketSendRate, createWebSocketState, createWebSocketTopics };
|
|
1029
1227
|
|
|
1030
1228
|
//# sourceMappingURL=core.js.map
|