@abraca/dabra 1.0.22 → 1.0.23
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/abracadabra-provider.cjs +91 -18
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +91 -18
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +34 -3
- package/package.json +1 -1
- package/src/AbracadabraClient.ts +17 -0
- package/src/IdentityDoc.ts +42 -6
- package/src/webrtc/DevicePairingChannel.ts +101 -13
- package/src/webrtc/SignalingSocket.ts +2 -2
|
@@ -3222,6 +3222,18 @@ var AbracadabraClient = class {
|
|
|
3222
3222
|
auth: false
|
|
3223
3223
|
});
|
|
3224
3224
|
}
|
|
3225
|
+
/**
|
|
3226
|
+
* Fetch a short-lived anonymous pairing token for WebRTC signaling.
|
|
3227
|
+
* No authentication required. The token only grants access to `__pairing_*` rooms.
|
|
3228
|
+
*/
|
|
3229
|
+
static async getPairingToken(serverUrl) {
|
|
3230
|
+
let base = serverUrl;
|
|
3231
|
+
while (base.endsWith("/")) base = base.slice(0, -1);
|
|
3232
|
+
const resp = await fetch(`${base}/auth/pairing-token`, { method: "POST" });
|
|
3233
|
+
if (!resp.ok) throw new Error(`Failed to fetch pairing token: ${resp.status}`);
|
|
3234
|
+
const { token } = await resp.json();
|
|
3235
|
+
return token;
|
|
3236
|
+
}
|
|
3225
3237
|
/** Get encryption info for a document. */
|
|
3226
3238
|
async getDocEncryption(docId) {
|
|
3227
3239
|
return this.request("GET", `/docs/${encodeURIComponent(docId)}/encryption`);
|
|
@@ -8858,8 +8870,8 @@ var SignalingSocket = class extends EventEmitter {
|
|
|
8858
8870
|
break;
|
|
8859
8871
|
case "joined":
|
|
8860
8872
|
this.emit("joined", {
|
|
8861
|
-
|
|
8862
|
-
|
|
8873
|
+
peer_id: msg.peer_id,
|
|
8874
|
+
user_id: msg.user_id,
|
|
8863
8875
|
muted: msg.muted,
|
|
8864
8876
|
video: msg.video,
|
|
8865
8877
|
screen: msg.screen,
|
|
@@ -10297,6 +10309,7 @@ var ManualSignaling = class extends EventEmitter {
|
|
|
10297
10309
|
const CODE_CHARSET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
10298
10310
|
const CODE_LENGTH = 6;
|
|
10299
10311
|
const PAIRING_TIMEOUT_MS = 300 * 1e3;
|
|
10312
|
+
const SIGNALING_CONNECT_TIMEOUT_MS = 5e3;
|
|
10300
10313
|
function generatePairingCode() {
|
|
10301
10314
|
const bytes = crypto.getRandomValues(new Uint8Array(CODE_LENGTH));
|
|
10302
10315
|
return Array.from(bytes).map((b) => CODE_CHARSET[b % 32]).join("");
|
|
@@ -10314,6 +10327,7 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10314
10327
|
this._destroyed = false;
|
|
10315
10328
|
this._pendingRequest = null;
|
|
10316
10329
|
this._connectedPeerId = null;
|
|
10330
|
+
this._usingFallback = false;
|
|
10317
10331
|
this.role = role;
|
|
10318
10332
|
this.pairingCode = pairingCode;
|
|
10319
10333
|
}
|
|
@@ -10468,12 +10482,41 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10468
10482
|
}
|
|
10469
10483
|
this.removeAllListeners();
|
|
10470
10484
|
}
|
|
10485
|
+
async resolveToken(serverUrl) {
|
|
10486
|
+
if (this.config.token && serverUrl === this.config.serverUrl) return this.config.token;
|
|
10487
|
+
let base = serverUrl ?? this.config.serverUrl;
|
|
10488
|
+
while (base.endsWith("/")) base = base.slice(0, -1);
|
|
10489
|
+
const resp = await fetch(`${base}/auth/pairing-token`, { method: "POST" });
|
|
10490
|
+
if (!resp.ok) throw new Error(`Failed to fetch pairing token: ${resp.status} ${resp.statusText}`);
|
|
10491
|
+
const { token } = await resp.json();
|
|
10492
|
+
return token;
|
|
10493
|
+
}
|
|
10471
10494
|
start() {
|
|
10495
|
+
this.connectToServer(this.config.serverUrl);
|
|
10496
|
+
this.timeoutHandle = setTimeout(() => {
|
|
10497
|
+
if (!this._destroyed) {
|
|
10498
|
+
this.emit("error", /* @__PURE__ */ new Error("Pairing timed out"));
|
|
10499
|
+
this.destroy();
|
|
10500
|
+
}
|
|
10501
|
+
}, PAIRING_TIMEOUT_MS);
|
|
10502
|
+
}
|
|
10503
|
+
connectToServer(serverUrl, signalingUrl) {
|
|
10504
|
+
const roomId = codeToRoomId(this.pairingCode);
|
|
10505
|
+
const tokenPromise = this.resolveToken(serverUrl);
|
|
10506
|
+
const tokenFactory = async () => {
|
|
10507
|
+
const t = await tokenPromise;
|
|
10508
|
+
if (typeof t === "function") return await t();
|
|
10509
|
+
return t;
|
|
10510
|
+
};
|
|
10511
|
+
if (!this.config.iceServers) new AbracadabraClient({ url: serverUrl }).getIceServers().then((servers) => {
|
|
10512
|
+
if (servers.length > 0) this._resolvedIceServers = servers;
|
|
10513
|
+
});
|
|
10472
10514
|
this.webrtc = new AbracadabraWebRTC({
|
|
10473
|
-
docId:
|
|
10474
|
-
url:
|
|
10475
|
-
|
|
10476
|
-
|
|
10515
|
+
docId: roomId,
|
|
10516
|
+
url: serverUrl,
|
|
10517
|
+
signalingUrl: signalingUrl ?? void 0,
|
|
10518
|
+
token: tokenFactory,
|
|
10519
|
+
iceServers: this.config.iceServers ?? this._resolvedIceServers,
|
|
10477
10520
|
e2ee: this.config.e2ee,
|
|
10478
10521
|
enableDocSync: false,
|
|
10479
10522
|
enableAwarenessSync: false,
|
|
@@ -10481,6 +10524,10 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10481
10524
|
autoConnect: false,
|
|
10482
10525
|
WebSocketPolyfill: this.config.WebSocketPolyfill
|
|
10483
10526
|
});
|
|
10527
|
+
let connected = false;
|
|
10528
|
+
this.webrtc.on("connected", () => {
|
|
10529
|
+
connected = true;
|
|
10530
|
+
});
|
|
10484
10531
|
this.webrtc.on("e2eeEstablished", ({ peerId }) => {
|
|
10485
10532
|
this._connectedPeerId = peerId;
|
|
10486
10533
|
this.emit("connected");
|
|
@@ -10494,14 +10541,25 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10494
10541
|
this.webrtc.on("signalingError", (err) => {
|
|
10495
10542
|
this.emit("error", /* @__PURE__ */ new Error(`Signaling: ${err.message}`));
|
|
10496
10543
|
});
|
|
10497
|
-
this.
|
|
10498
|
-
|
|
10499
|
-
this.
|
|
10500
|
-
this.
|
|
10501
|
-
|
|
10502
|
-
|
|
10544
|
+
if (this.config.fallbackSignalingUrl && !signalingUrl) {
|
|
10545
|
+
const fallbackTimer = setTimeout(() => {
|
|
10546
|
+
if (this._destroyed || connected) return;
|
|
10547
|
+
if (this.webrtc) {
|
|
10548
|
+
this.webrtc.destroy();
|
|
10549
|
+
this.webrtc = null;
|
|
10550
|
+
}
|
|
10551
|
+
this._usingFallback = true;
|
|
10552
|
+
this.emit("fallback", { url: this.config.fallbackSignalingUrl });
|
|
10553
|
+
this.connectToServer(this.config.fallbackSignalingUrl);
|
|
10554
|
+
}, SIGNALING_CONNECT_TIMEOUT_MS);
|
|
10555
|
+
this.webrtc.on("connected", () => clearTimeout(fallbackTimer));
|
|
10556
|
+
}
|
|
10503
10557
|
this.webrtc.connect();
|
|
10504
10558
|
}
|
|
10559
|
+
/** Whether the connection fell back to the fallback signaling server. */
|
|
10560
|
+
get usingFallback() {
|
|
10561
|
+
return this._usingFallback;
|
|
10562
|
+
}
|
|
10505
10563
|
sendMessage(msg) {
|
|
10506
10564
|
if (!this.webrtc || !this._connectedPeerId) return;
|
|
10507
10565
|
this.webrtc.sendCustomMessage(this._connectedPeerId, JSON.stringify(msg));
|
|
@@ -10749,26 +10807,41 @@ var IdentityDocProvider = class extends EventEmitter {
|
|
|
10749
10807
|
});
|
|
10750
10808
|
for (const { url, key } of targets) {
|
|
10751
10809
|
if (this.providers.has(key)) continue;
|
|
10752
|
-
this.
|
|
10810
|
+
this.connectToServer(key, url);
|
|
10753
10811
|
}
|
|
10754
10812
|
if (this.config.webrtc && !this.webrtc) this._connectWebRTC();
|
|
10755
10813
|
}
|
|
10756
|
-
|
|
10814
|
+
connectToServer(key, serverUrl) {
|
|
10815
|
+
if (this._destroyed) return;
|
|
10816
|
+
const existingProvider = this.providers.get(key);
|
|
10817
|
+
if (existingProvider) {
|
|
10818
|
+
existingProvider.destroy();
|
|
10819
|
+
this.providers.delete(key);
|
|
10820
|
+
}
|
|
10821
|
+
const existingWs = this.websockets.get(key);
|
|
10822
|
+
if (existingWs) {
|
|
10823
|
+
existingWs.destroy();
|
|
10824
|
+
this.websockets.delete(key);
|
|
10825
|
+
}
|
|
10757
10826
|
const token = this.config.tokens?.[serverUrl] ?? this.config.token ?? "";
|
|
10758
10827
|
const ws = new AbracadabraWS({
|
|
10759
10828
|
url: serverUrl.replace(/^http/, "ws").replace(/\/$/, "").concat("/ws"),
|
|
10760
10829
|
WebSocketPolyfill: void 0
|
|
10761
10830
|
});
|
|
10762
10831
|
this.websockets.set(key, ws);
|
|
10763
|
-
const
|
|
10832
|
+
const providerConfig = {
|
|
10764
10833
|
name: this.docId,
|
|
10765
10834
|
document: this.document,
|
|
10766
10835
|
websocketProvider: ws,
|
|
10767
|
-
token,
|
|
10768
10836
|
serverAgnostic: true,
|
|
10769
10837
|
disableOfflineStore: key !== "local" && key !== "sync" ? true : this.config.disableOfflineStore ?? false,
|
|
10770
10838
|
...this.config.providerDefaults
|
|
10771
|
-
}
|
|
10839
|
+
};
|
|
10840
|
+
if (this.config.cryptoIdentity && this.config.signChallenge) {
|
|
10841
|
+
providerConfig.cryptoIdentity = this.config.cryptoIdentity;
|
|
10842
|
+
providerConfig.signChallenge = this.config.signChallenge;
|
|
10843
|
+
} else providerConfig.token = token;
|
|
10844
|
+
const provider = new AbracadabraProvider(providerConfig);
|
|
10772
10845
|
provider.on("synced", () => this.emit("synced", { server: key }));
|
|
10773
10846
|
provider.on("status", (data) => this.emit("status", {
|
|
10774
10847
|
server: key,
|
|
@@ -10975,7 +11048,7 @@ var IdentityDocProvider = class extends EventEmitter {
|
|
|
10975
11048
|
...this.config,
|
|
10976
11049
|
syncServerUrl: url
|
|
10977
11050
|
};
|
|
10978
|
-
this.
|
|
11051
|
+
this.connectToServer("sync", url);
|
|
10979
11052
|
}
|
|
10980
11053
|
}
|
|
10981
11054
|
getProvider(key) {
|