@afterrealism/dendri-client 2.3.7 → 2.4.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/LICENSE +202 -21
- package/README.md +61 -59
- package/dist/{chunk-MJW5M75V.js → chunk-MBMSG4EC.js} +200 -14
- package/dist/chunk-MBMSG4EC.js.map +1 -0
- package/dist/dendri.browser.global.js +166 -8
- package/dist/dendri.browser.global.js.map +1 -1
- package/dist/dendri.cjs +199 -12
- package/dist/dendri.cjs.map +1 -1
- package/dist/dendri.d.cts +2 -2
- package/dist/dendri.d.ts +2 -2
- package/dist/dendri.js +3 -3
- package/dist/dendri.js.map +1 -1
- package/dist/dendri.min.global.js +13 -13
- package/dist/dendri.min.global.js.map +1 -1
- package/dist/serializer.msgpack.cjs +3 -3
- package/dist/serializer.msgpack.cjs.map +1 -1
- package/dist/serializer.msgpack.d.cts +17 -4
- package/dist/serializer.msgpack.d.ts +17 -4
- package/dist/serializer.msgpack.js +2 -2
- package/dist/serializer.msgpack.js.map +1 -1
- package/dist/{store-RTivRmUW.d.cts → store-DVE0ih44.d.cts} +24 -5
- package/dist/{store-RTivRmUW.d.ts → store-DVE0ih44.d.ts} +24 -5
- package/dist/store.cjs +189 -11
- package/dist/store.cjs.map +1 -1
- package/dist/store.d.cts +1 -1
- package/dist/store.d.ts +1 -1
- package/dist/store.js +1 -1
- package/package.json +7 -2
- package/dist/chunk-MJW5M75V.js.map +0 -1
package/dist/dendri.cjs
CHANGED
|
@@ -3533,7 +3533,7 @@ var Logger = class {
|
|
|
3533
3533
|
var logger_default = new Logger();
|
|
3534
3534
|
|
|
3535
3535
|
// src/api.ts
|
|
3536
|
-
var version = "2.
|
|
3536
|
+
var version = "2.4.0";
|
|
3537
3537
|
var API = class _API {
|
|
3538
3538
|
constructor(_options) {
|
|
3539
3539
|
this._options = _options;
|
|
@@ -3570,11 +3570,11 @@ var API = class _API {
|
|
|
3570
3570
|
throw new Error(`Could not get an ID from the server.${pathError}`);
|
|
3571
3571
|
}
|
|
3572
3572
|
}
|
|
3573
|
-
/** Fetch TURN credentials from the signaling server's
|
|
3573
|
+
/** Fetch TURN credentials from the signaling server's turn-credentials endpoint. */
|
|
3574
3574
|
async getTurnCredentials() {
|
|
3575
3575
|
const protocol = this._options.secure ? "https" : "http";
|
|
3576
|
-
const { host, port } = this._options;
|
|
3577
|
-
const url = `${protocol}://${host}:${port}/turn`;
|
|
3576
|
+
const { host, port, path, key } = this._options;
|
|
3577
|
+
const url = `${protocol}://${host}:${port}${path}${key}/turn-credentials`;
|
|
3578
3578
|
try {
|
|
3579
3579
|
const controller = new AbortController();
|
|
3580
3580
|
const timeoutId = setTimeout(() => controller.abort(), _API.FETCH_TIMEOUT);
|
|
@@ -3683,6 +3683,9 @@ var ServerMessageType = /* @__PURE__ */ ((ServerMessageType2) => {
|
|
|
3683
3683
|
ServerMessageType2["HostMigrate"] = "HOST-MIGRATE";
|
|
3684
3684
|
ServerMessageType2["PresenceUpdate"] = "PRESENCE-UPDATE";
|
|
3685
3685
|
ServerMessageType2["KeyExchange"] = "KEY-EXCHANGE";
|
|
3686
|
+
ServerMessageType2["ConnectRequest"] = "CONNECT-REQUEST";
|
|
3687
|
+
ServerMessageType2["DcutrConnect"] = "DCUTR-CONNECT";
|
|
3688
|
+
ServerMessageType2["DcutrSync"] = "DCUTR-SYNC";
|
|
3686
3689
|
return ServerMessageType2;
|
|
3687
3690
|
})(ServerMessageType || {});
|
|
3688
3691
|
var TransportMode = /* @__PURE__ */ ((TransportMode2) => {
|
|
@@ -3708,6 +3711,11 @@ var ConnectionQuality = /* @__PURE__ */ ((ConnectionQuality2) => {
|
|
|
3708
3711
|
ConnectionQuality2["Unknown"] = "unknown";
|
|
3709
3712
|
return ConnectionQuality2;
|
|
3710
3713
|
})(ConnectionQuality || {});
|
|
3714
|
+
var TopicClass = /* @__PURE__ */ ((TopicClass2) => {
|
|
3715
|
+
TopicClass2["Persistent"] = "persistent";
|
|
3716
|
+
TopicClass2["Ephemeral"] = "ephemeral";
|
|
3717
|
+
return TopicClass2;
|
|
3718
|
+
})(TopicClass || {});
|
|
3711
3719
|
|
|
3712
3720
|
// src/dendriError.ts
|
|
3713
3721
|
var import_eventemitter3 = __toESM(require_eventemitter3(), 1);
|
|
@@ -3796,6 +3804,7 @@ var Negotiator = class {
|
|
|
3796
3804
|
}
|
|
3797
3805
|
connection;
|
|
3798
3806
|
_pendingCandidates = [];
|
|
3807
|
+
_iceCandidateFilter = null;
|
|
3799
3808
|
/** Returns a PeerConnection object set up correctly (for data, media). */
|
|
3800
3809
|
startConnection(options) {
|
|
3801
3810
|
const peerConnection = this._startPeerConnection();
|
|
@@ -3818,6 +3827,13 @@ var Negotiator = class {
|
|
|
3818
3827
|
_startPeerConnection() {
|
|
3819
3828
|
logger_default.log("Creating RTCPeerConnection.");
|
|
3820
3829
|
const peerConnection = new RTCPeerConnection(this.connection.provider?.options.config);
|
|
3830
|
+
if (this.connection.provider?.options.ipPolicy === "public") {
|
|
3831
|
+
const isPublicCandidate = (c) => {
|
|
3832
|
+
const sdp2 = c.candidate ?? "";
|
|
3833
|
+
return !sdp2.includes("typ host");
|
|
3834
|
+
};
|
|
3835
|
+
this._iceCandidateFilter = isPublicCandidate;
|
|
3836
|
+
}
|
|
3821
3837
|
this._setupListeners(peerConnection);
|
|
3822
3838
|
return peerConnection;
|
|
3823
3839
|
}
|
|
@@ -3830,6 +3846,9 @@ var Negotiator = class {
|
|
|
3830
3846
|
logger_default.log("Listening for ICE candidates.");
|
|
3831
3847
|
peerConnection.onicecandidate = (evt) => {
|
|
3832
3848
|
if (!evt.candidate?.candidate) return;
|
|
3849
|
+
if (this._iceCandidateFilter && !this._iceCandidateFilter(evt.candidate)) {
|
|
3850
|
+
return;
|
|
3851
|
+
}
|
|
3833
3852
|
logger_default.log(`Received ICE candidates for ${peerId}:`, evt.candidate);
|
|
3834
3853
|
provider.socket.send({
|
|
3835
3854
|
type: "CANDIDATE" /* Candidate */,
|
|
@@ -4168,6 +4187,7 @@ var DataConnection = class _DataConnection extends BaseConnection {
|
|
|
4168
4187
|
this.dataChannel.onopen = () => {
|
|
4169
4188
|
logger_default.log(`DC#${this.connectionId} dc connection success`);
|
|
4170
4189
|
this._open = true;
|
|
4190
|
+
this._applyAdaptiveBuffer(dc);
|
|
4171
4191
|
this.emit("open");
|
|
4172
4192
|
};
|
|
4173
4193
|
this.dataChannel.onclose = () => {
|
|
@@ -4175,6 +4195,24 @@ var DataConnection = class _DataConnection extends BaseConnection {
|
|
|
4175
4195
|
this.close();
|
|
4176
4196
|
};
|
|
4177
4197
|
}
|
|
4198
|
+
_applyAdaptiveBuffer(dc) {
|
|
4199
|
+
const pc = this.peerConnection;
|
|
4200
|
+
if (!pc || typeof pc.getStats !== "function") return;
|
|
4201
|
+
pc.getStats().then((stats) => {
|
|
4202
|
+
let rtt = null;
|
|
4203
|
+
stats.forEach((report) => {
|
|
4204
|
+
if (report.type === "candidate-pair" && report.state === "succeeded" && report.currentRoundTripTime) {
|
|
4205
|
+
rtt = report.currentRoundTripTime * 1e3;
|
|
4206
|
+
}
|
|
4207
|
+
});
|
|
4208
|
+
if (rtt !== null) {
|
|
4209
|
+
const bdp = 12.5 * 1024 * 1024 * (rtt / 1e3);
|
|
4210
|
+
const optimal = Math.max(1 * 1024 * 1024, Math.min(32 * 1024 * 1024, Math.ceil(bdp)));
|
|
4211
|
+
dc.bufferedAmountLowThreshold = optimal;
|
|
4212
|
+
}
|
|
4213
|
+
}).catch(() => {
|
|
4214
|
+
});
|
|
4215
|
+
}
|
|
4178
4216
|
/**
|
|
4179
4217
|
* Exposed functionality for users.
|
|
4180
4218
|
*/
|
|
@@ -4709,7 +4747,17 @@ var HybridConnection = class extends import_eventemitter32.EventEmitter {
|
|
|
4709
4747
|
if (this._closed) {
|
|
4710
4748
|
return;
|
|
4711
4749
|
}
|
|
4712
|
-
|
|
4750
|
+
logger_default.log(
|
|
4751
|
+
`HybridConnection: start peer=${this.peer} iceTimeout=${this._options.iceTimeout ?? 1e4}ms encryptRelay=${this._encryptRelay}`
|
|
4752
|
+
);
|
|
4753
|
+
if (typeof this._provider?.on !== "function") {
|
|
4754
|
+
this._attemptWebRTC();
|
|
4755
|
+
return;
|
|
4756
|
+
}
|
|
4757
|
+
this._tryConnectionReversal().then((direct) => {
|
|
4758
|
+
if (direct) return;
|
|
4759
|
+
this._attemptWebRTC();
|
|
4760
|
+
});
|
|
4713
4761
|
}
|
|
4714
4762
|
/** Send data through the best available transport, optionally tagged with a topic. */
|
|
4715
4763
|
send(data, options) {
|
|
@@ -4999,10 +5047,16 @@ var HybridConnection = class extends import_eventemitter32.EventEmitter {
|
|
|
4999
5047
|
this._dataConnection = dc;
|
|
5000
5048
|
this._iceTimer = setTimeout(() => {
|
|
5001
5049
|
if (this._mode !== "webrtc" /* WebRTC */) {
|
|
5050
|
+
logger_default.warn(
|
|
5051
|
+
`HybridConnection: ICE timeout after ${iceTimeout}ms for ${this.peer}, falling back to relay`
|
|
5052
|
+
);
|
|
5002
5053
|
this._fallbackToRelay();
|
|
5003
5054
|
}
|
|
5004
5055
|
}, iceTimeout);
|
|
5005
5056
|
this._dataConnection.on("open", () => {
|
|
5057
|
+
logger_default.log(
|
|
5058
|
+
`HybridConnection: WebRTC opened to ${this.peer} (attempt ${this._upgradeAttempts + 1})`
|
|
5059
|
+
);
|
|
5006
5060
|
this._clearIceTimer();
|
|
5007
5061
|
this._clearUpgradeTimer();
|
|
5008
5062
|
this._upgradeAttempts = 0;
|
|
@@ -5043,6 +5097,7 @@ var HybridConnection = class extends import_eventemitter32.EventEmitter {
|
|
|
5043
5097
|
/** Update the transport mode and emit if changed. */
|
|
5044
5098
|
_setMode(mode) {
|
|
5045
5099
|
if (this._mode !== mode) {
|
|
5100
|
+
logger_default.log(`HybridConnection: transport ${this._mode} -> ${mode} for ${this.peer}`);
|
|
5046
5101
|
this._mode = mode;
|
|
5047
5102
|
this.emit("transportChanged", mode);
|
|
5048
5103
|
}
|
|
@@ -5083,6 +5138,117 @@ var HybridConnection = class extends import_eventemitter32.EventEmitter {
|
|
|
5083
5138
|
this._attemptWebRTC();
|
|
5084
5139
|
}, interval);
|
|
5085
5140
|
}
|
|
5141
|
+
async _tryConnectionReversal() {
|
|
5142
|
+
if (typeof this._provider?.on !== "function") return false;
|
|
5143
|
+
try {
|
|
5144
|
+
const resp = await new Promise((resolve, reject) => {
|
|
5145
|
+
const timer = setTimeout(() => reject(new Error("timeout")), 3e3);
|
|
5146
|
+
const handler = (data) => {
|
|
5147
|
+
clearTimeout(timer);
|
|
5148
|
+
this._provider.off("CONNECT-REQUEST" /* ConnectRequest */, handler);
|
|
5149
|
+
resolve(data);
|
|
5150
|
+
};
|
|
5151
|
+
this._provider.on("CONNECT-REQUEST" /* ConnectRequest */, handler);
|
|
5152
|
+
this._provider.socket.send({
|
|
5153
|
+
type: "CONNECT-REQUEST" /* ConnectRequest */,
|
|
5154
|
+
payload: { peer: this.peer }
|
|
5155
|
+
});
|
|
5156
|
+
});
|
|
5157
|
+
const addr = resp?.address;
|
|
5158
|
+
if (!addr) return false;
|
|
5159
|
+
const pc = new RTCPeerConnection(this._provider.options.config);
|
|
5160
|
+
const dc = pc.createDataChannel("probe", { id: 0 });
|
|
5161
|
+
await new Promise((resolve, reject) => {
|
|
5162
|
+
const timer = setTimeout(() => {
|
|
5163
|
+
pc.close();
|
|
5164
|
+
reject(new Error("direct-dial-timeout"));
|
|
5165
|
+
}, 2500);
|
|
5166
|
+
dc.onopen = () => {
|
|
5167
|
+
clearTimeout(timer);
|
|
5168
|
+
resolve();
|
|
5169
|
+
};
|
|
5170
|
+
dc.onerror = () => {
|
|
5171
|
+
clearTimeout(timer);
|
|
5172
|
+
pc.close();
|
|
5173
|
+
reject(new Error("dc-error"));
|
|
5174
|
+
};
|
|
5175
|
+
});
|
|
5176
|
+
this._dataConnection = void 0;
|
|
5177
|
+
this._setMode("webrtc" /* WebRTC */);
|
|
5178
|
+
pc.close();
|
|
5179
|
+
return true;
|
|
5180
|
+
} catch {
|
|
5181
|
+
return false;
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
5184
|
+
async _gatherSrflxCandidates() {
|
|
5185
|
+
const pc = new RTCPeerConnection({ iceServers: this._provider.options.config?.iceServers });
|
|
5186
|
+
pc.createDataChannel("probe");
|
|
5187
|
+
const offer = await pc.createOffer();
|
|
5188
|
+
await pc.setLocalDescription(offer);
|
|
5189
|
+
const candidates = [];
|
|
5190
|
+
await new Promise((resolve) => {
|
|
5191
|
+
const timer = setTimeout(resolve, 2e3);
|
|
5192
|
+
pc.onicecandidate = (evt) => {
|
|
5193
|
+
if (!evt.candidate) {
|
|
5194
|
+
clearTimeout(timer);
|
|
5195
|
+
resolve();
|
|
5196
|
+
return;
|
|
5197
|
+
}
|
|
5198
|
+
if (!evt.candidate.candidate.includes("typ host")) {
|
|
5199
|
+
candidates.push(evt.candidate.candidate);
|
|
5200
|
+
}
|
|
5201
|
+
};
|
|
5202
|
+
});
|
|
5203
|
+
pc.close();
|
|
5204
|
+
return candidates;
|
|
5205
|
+
}
|
|
5206
|
+
async _dcutrHolePunch() {
|
|
5207
|
+
try {
|
|
5208
|
+
const localAddrs = await this._gatherSrflxCandidates();
|
|
5209
|
+
const t0 = performance.now();
|
|
5210
|
+
const peerAddrs = await new Promise((resolve, reject) => {
|
|
5211
|
+
const timer = setTimeout(() => reject(new Error("dcutr-timeout")), 8e3);
|
|
5212
|
+
const handler = (data) => {
|
|
5213
|
+
clearTimeout(timer);
|
|
5214
|
+
this._provider.off("DCUTR-CONNECT" /* DcutrConnect */, handler);
|
|
5215
|
+
resolve(data?.addresses ?? []);
|
|
5216
|
+
};
|
|
5217
|
+
this._provider.on("DCUTR-CONNECT" /* DcutrConnect */, handler);
|
|
5218
|
+
this._provider.socket.send({
|
|
5219
|
+
type: "DCUTR-CONNECT" /* DcutrConnect */,
|
|
5220
|
+
payload: { addresses: localAddrs }
|
|
5221
|
+
});
|
|
5222
|
+
});
|
|
5223
|
+
const relayRtt = performance.now() - t0;
|
|
5224
|
+
this._provider.socket.send({ type: "DCUTR-SYNC" /* DcutrSync */, payload: {} });
|
|
5225
|
+
await new Promise((r) => setTimeout(r, relayRtt / 2));
|
|
5226
|
+
for (let i = 0; i < Math.min(peerAddrs.length, 4); i++) {
|
|
5227
|
+
try {
|
|
5228
|
+
const pc = new RTCPeerConnection(this._provider.options.config);
|
|
5229
|
+
await new Promise((resolve, reject) => {
|
|
5230
|
+
const timer = setTimeout(() => {
|
|
5231
|
+
pc.close();
|
|
5232
|
+
reject(new Error("dc-dial-timeout"));
|
|
5233
|
+
}, 5e3);
|
|
5234
|
+
const dc = pc.createDataChannel("dcutr");
|
|
5235
|
+
dc.onopen = () => {
|
|
5236
|
+
clearTimeout(timer);
|
|
5237
|
+
resolve();
|
|
5238
|
+
};
|
|
5239
|
+
});
|
|
5240
|
+
this._dataConnection = void 0;
|
|
5241
|
+
this._setMode("webrtc" /* WebRTC */);
|
|
5242
|
+
pc.close();
|
|
5243
|
+
return true;
|
|
5244
|
+
} catch {
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
return false;
|
|
5248
|
+
} catch {
|
|
5249
|
+
return false;
|
|
5250
|
+
}
|
|
5251
|
+
}
|
|
5086
5252
|
};
|
|
5087
5253
|
|
|
5088
5254
|
// src/mediaconnection.ts
|
|
@@ -5379,7 +5545,7 @@ var PollingTransport = class _PollingTransport extends SignalingTransport {
|
|
|
5379
5545
|
};
|
|
5380
5546
|
|
|
5381
5547
|
// src/socket.ts
|
|
5382
|
-
var version2 = "2.
|
|
5548
|
+
var version2 = "2.4.0";
|
|
5383
5549
|
var Socket = class _Socket extends SignalingTransport {
|
|
5384
5550
|
constructor(secure, host, port, path, key, pingInterval = 5e3, jwt) {
|
|
5385
5551
|
super();
|
|
@@ -5421,7 +5587,7 @@ var Socket = class _Socket extends SignalingTransport {
|
|
|
5421
5587
|
if (this._jwt) {
|
|
5422
5588
|
wsUrl += `&jwt=${encodeURIComponent(this._jwt)}`;
|
|
5423
5589
|
}
|
|
5424
|
-
if (
|
|
5590
|
+
if (this._socket || !this._disconnected) {
|
|
5425
5591
|
return;
|
|
5426
5592
|
}
|
|
5427
5593
|
this._socket = new WebSocket(`${wsUrl}&version=${version2}`);
|
|
@@ -6012,7 +6178,7 @@ var Dendri = class _Dendri extends EventEmitterWithError {
|
|
|
6012
6178
|
return;
|
|
6013
6179
|
}
|
|
6014
6180
|
}
|
|
6015
|
-
if (
|
|
6181
|
+
if (userId && !util.validateId(userId)) {
|
|
6016
6182
|
this._delayedAbort("invalid-id" /* InvalidID */, `ID "${userId}" is invalid`);
|
|
6017
6183
|
return;
|
|
6018
6184
|
}
|
|
@@ -8791,7 +8957,13 @@ var Room = class extends import_eventemitter35.EventEmitter {
|
|
|
8791
8957
|
sentViaWebRTC = true;
|
|
8792
8958
|
}
|
|
8793
8959
|
}
|
|
8794
|
-
if (
|
|
8960
|
+
if (this._dendriOptions?.enableRelay && this._peer?.socket) {
|
|
8961
|
+
this._peer.socket.send({
|
|
8962
|
+
type: "DATA" /* Data */,
|
|
8963
|
+
room: this._roomId,
|
|
8964
|
+
payload: wire
|
|
8965
|
+
});
|
|
8966
|
+
} else if (!sentViaWebRTC && this._peer?.socket) {
|
|
8795
8967
|
this._peer.socket.send({
|
|
8796
8968
|
type: "DATA" /* Data */,
|
|
8797
8969
|
room: this._roomId,
|
|
@@ -8825,7 +8997,13 @@ var Room = class extends import_eventemitter35.EventEmitter {
|
|
|
8825
8997
|
sentViaWebRTC = true;
|
|
8826
8998
|
}
|
|
8827
8999
|
}
|
|
8828
|
-
if (
|
|
9000
|
+
if (this._dendriOptions?.enableRelay && this._peer?.socket) {
|
|
9001
|
+
this._peer.socket.send({
|
|
9002
|
+
type: "DATA" /* Data */,
|
|
9003
|
+
room: this._roomId,
|
|
9004
|
+
payload: wire
|
|
9005
|
+
});
|
|
9006
|
+
} else if (!sentViaWebRTC && this._peer?.socket) {
|
|
8829
9007
|
this._peer.socket.send({
|
|
8830
9008
|
type: "DATA" /* Data */,
|
|
8831
9009
|
room: this._roomId,
|
|
@@ -9016,8 +9194,8 @@ var Room = class extends import_eventemitter35.EventEmitter {
|
|
|
9016
9194
|
const remotePeerId = conn.peer;
|
|
9017
9195
|
this._connections.set(remotePeerId, conn);
|
|
9018
9196
|
this._knownPeers.add(remotePeerId);
|
|
9197
|
+
this.emit("peerJoined", remotePeerId);
|
|
9019
9198
|
conn.on("open", () => {
|
|
9020
|
-
this.emit("peerJoined", remotePeerId);
|
|
9021
9199
|
for (const [peerId, c] of this._connections) {
|
|
9022
9200
|
if (peerId !== remotePeerId && c.open) {
|
|
9023
9201
|
c.send({ __room: { type: "peer-joined", peerId: remotePeerId } });
|
|
@@ -9339,6 +9517,14 @@ var Room = class extends import_eventemitter35.EventEmitter {
|
|
|
9339
9517
|
const conn = this._connections.get(peerId);
|
|
9340
9518
|
if (conn?.open) {
|
|
9341
9519
|
conn.send(data);
|
|
9520
|
+
if (this._dendriOptions?.enableRelay && this._peer?.socket) {
|
|
9521
|
+
this._peer.socket.send({
|
|
9522
|
+
type: "DATA" /* Data */,
|
|
9523
|
+
dst: peerId,
|
|
9524
|
+
room: this._roomId,
|
|
9525
|
+
payload: data
|
|
9526
|
+
});
|
|
9527
|
+
}
|
|
9342
9528
|
return;
|
|
9343
9529
|
}
|
|
9344
9530
|
if (!this._isHost && this._hostId) {
|
|
@@ -9403,7 +9589,7 @@ var DendriServerAPI = class {
|
|
|
9403
9589
|
}
|
|
9404
9590
|
/** Get TURN credentials */
|
|
9405
9591
|
async getTurnCredentials() {
|
|
9406
|
-
const res = await fetch(`${this._baseUrl}/turn`);
|
|
9592
|
+
const res = await fetch(`${this._baseUrl}/${this._key}/turn-credentials`);
|
|
9407
9593
|
if (!res.ok) throw new Error(`TURN credentials failed: ${res.status}`);
|
|
9408
9594
|
return res.json();
|
|
9409
9595
|
}
|
|
@@ -9712,6 +9898,7 @@ exports.ServerMessageType = ServerMessageType;
|
|
|
9712
9898
|
exports.SignalingTransport = SignalingTransport;
|
|
9713
9899
|
exports.SocketEventType = SocketEventType;
|
|
9714
9900
|
exports.StreamConnection = StreamConnection;
|
|
9901
|
+
exports.TopicClass = TopicClass;
|
|
9715
9902
|
exports.TopicManager = TopicManager;
|
|
9716
9903
|
exports.TransportMode = TransportMode;
|
|
9717
9904
|
exports.createDendriStore = createDendriStore;
|