@quitting/core 1.2.0 → 1.3.1

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.
@@ -1,8 +1,8 @@
1
1
  import { Centrifuge as e } from "centrifuge";
2
- import { Room as t, Track as n, setLogLevel as r } from "livekit-client";
2
+ import { Room as t, Track as n, createLocalAudioTrack as r, createLocalVideoTrack as i, setLogLevel as a } from "livekit-client";
3
3
  export * from "@quitting/contract";
4
4
  //#region src/events.ts
5
- var i = class {
5
+ var o = class {
6
6
  listeners = /* @__PURE__ */ new Map();
7
7
  on(e, t) {
8
8
  return this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t), () => this.off(e, t);
@@ -21,13 +21,13 @@ var i = class {
21
21
  removeAllListeners() {
22
22
  this.listeners.clear();
23
23
  }
24
- }, a = class extends Error {
24
+ }, s = class extends Error {
25
25
  code;
26
26
  httpStatus;
27
27
  constructor(e, t, n) {
28
28
  super(n), this.name = "ApiError", this.code = e, this.httpStatus = t;
29
29
  }
30
- }, o = class {
30
+ }, c = class {
31
31
  apiBase;
32
32
  tokenGetter;
33
33
  constructor(e, t) {
@@ -39,19 +39,19 @@ var i = class {
39
39
  ...t.headers
40
40
  }, i = this.tokenGetter();
41
41
  i && (r.Authorization = `Bearer ${i}`), r["X-Trace-Id"] = crypto.randomUUID?.() || Math.random().toString(36).slice(2);
42
- let o = await fetch(n, {
42
+ let a = await fetch(n, {
43
43
  ...t,
44
44
  headers: r
45
45
  });
46
- if (!o.ok) {
47
- let e = 0, t = `HTTP ${o.status}`;
46
+ if (!a.ok) {
47
+ let e = 0, t = `HTTP ${a.status}`;
48
48
  try {
49
- let n = await o.json();
49
+ let n = await a.json();
50
50
  n?.code && (e = Number(n.code)), n?.message && (t = n.message);
51
51
  } catch {}
52
- throw new a(e, o.status, t);
52
+ throw new s(e, a.status, t);
53
53
  }
54
- return o.json();
54
+ return a.json();
55
55
  }
56
56
  async sendBeacon(e, t) {
57
57
  let n = `${this.apiBase}${e}`, r = { "Content-Type": "application/json" }, i = this.tokenGetter();
@@ -209,7 +209,7 @@ var i = class {
209
209
  body: JSON.stringify({ md5: e })
210
210
  });
211
211
  }
212
- }, s = class {
212
+ }, l = class {
213
213
  transport;
214
214
  sessionToken = null;
215
215
  centrifugoToken = null;
@@ -262,7 +262,7 @@ var i = class {
262
262
  logout() {
263
263
  this.refreshTimer &&= (clearTimeout(this.refreshTimer), null), this.sessionToken = null, this.centrifugoToken = null;
264
264
  }
265
- }, c = class extends i {
265
+ }, u = class extends o {
266
266
  client = null;
267
267
  subscriptions = /* @__PURE__ */ new Map();
268
268
  refCount = /* @__PURE__ */ new Map();
@@ -387,20 +387,23 @@ var i = class {
387
387
  disconnect() {
388
388
  this.client &&= (this.client.disconnect(), null), this.subscriptions.clear(), this.refCount.clear(), this.currentState = "disconnected";
389
389
  }
390
- }, l = null;
391
- async function u(e) {
392
- r("silent"), l &&= (clearTimeout(l), null);
390
+ }, d = null;
391
+ function f() {
392
+ a("silent"), d &&= (clearTimeout(d), null);
393
+ }
394
+ async function p(e) {
395
+ f();
393
396
  try {
394
397
  await e.disconnect();
395
398
  } finally {
396
- l = setTimeout(() => {
397
- r("warn"), l = null;
399
+ d = setTimeout(() => {
400
+ a("warn"), d = null;
398
401
  }, 1500);
399
402
  }
400
403
  }
401
404
  //#endregion
402
405
  //#region src/call.ts
403
- var d = class extends i {
406
+ var m = class extends o {
404
407
  callId;
405
408
  callType;
406
409
  roomName;
@@ -494,11 +497,11 @@ var d = class extends i {
494
497
  } catch (e) {
495
498
  console.error("[im] callEnd 失败", e);
496
499
  }
497
- await u(this.room), this.emitSession("ended", { reason: t });
500
+ await p(this.room), this.emitSession("ended", { reason: t });
498
501
  }
499
502
  }
500
503
  async end(e) {
501
- this.ended || (this.ended = !0, await u(this.room), this.emitSession("ended", { reason: e }));
504
+ this.ended || (this.ended = !0, await p(this.room), this.emitSession("ended", { reason: e }));
502
505
  }
503
506
  registerRpcMethod(e, t) {
504
507
  this.room.localParticipant.registerRpcMethod(e, (e) => t(e.payload));
@@ -528,7 +531,7 @@ var d = class extends i {
528
531
  return this.token;
529
532
  }
530
533
  token;
531
- }, f = class {
534
+ }, h = class {
532
535
  transport;
533
536
  livekitWs;
534
537
  identity;
@@ -538,7 +541,7 @@ var d = class extends i {
538
541
  this.transport = e, this.livekitWs = t, this.identity = n, this.iceServers = r;
539
542
  }
540
543
  async init(e, t) {
541
- let n = await this.transport.callInit(e, t), r = new d({
544
+ let n = await this.transport.callInit(e, t), r = new m({
542
545
  callId: n.callId,
543
546
  callType: t,
544
547
  roomName: n.roomName,
@@ -550,7 +553,7 @@ var d = class extends i {
550
553
  return this.currentSession = r, r;
551
554
  }
552
555
  async accept(e, t) {
553
- let n = await this.transport.callAccept(e), r = new d({
556
+ let n = await this.transport.callAccept(e), r = new m({
554
557
  callId: e,
555
558
  callType: t,
556
559
  roomName: n.roomName,
@@ -580,8 +583,8 @@ var d = class extends i {
580
583
  };
581
584
  //#endregion
582
585
  //#region src/meeting.ts
583
- r("warn");
584
- var p = class e extends i {
586
+ a("warn");
587
+ var g = class e extends o {
585
588
  meetingId;
586
589
  title;
587
590
  roomName;
@@ -598,6 +601,8 @@ var p = class e extends i {
598
601
  membersCacheAt = 0;
599
602
  static MEMBERS_CACHE_TTL = 8e3;
600
603
  pendingAttach = /* @__PURE__ */ new Map();
604
+ preparedMic = null;
605
+ preparedCamera = null;
601
606
  constructor(e) {
602
607
  super(), this.meetingId = e.meetingId, this.title = e.title, this.roomName = e.roomName, this.identity = e.identity, this.token = e.token, this.isHost = e.isHost, this.hostIdentity = e.hostIdentity, this.livekitWs = e.livekitWs, this.iceServers = e.iceServers, this.room = new t({
603
608
  adaptiveStream: !0,
@@ -657,15 +662,30 @@ var p = class e extends i {
657
662
  let e = this.room.localParticipant.identity;
658
663
  e && (this.identity = e, this.hostIdentity ||= e), this.emitSession("connected", {});
659
664
  }
665
+ async prepareLocalTracks() {
666
+ try {
667
+ this.preparedMic = await r();
668
+ } catch {
669
+ this.preparedMic = null;
670
+ }
671
+ try {
672
+ this.preparedCamera = await i();
673
+ } catch {
674
+ this.preparedCamera = null;
675
+ }
676
+ }
677
+ discardPreparedTracks() {
678
+ this.preparedMic?.stop(), this.preparedMic = null, this.preparedCamera?.stop(), this.preparedCamera = null;
679
+ }
660
680
  async enableDevices() {
661
681
  let e = [], t = !1, n = !1;
662
682
  try {
663
- await this.room.localParticipant.setMicrophoneEnabled(!0), t = !0;
683
+ this.preparedMic ? (await this.room.localParticipant.publishTrack(this.preparedMic), this.preparedMic = null) : await this.room.localParticipant.setMicrophoneEnabled(!0), t = !0;
664
684
  } catch (t) {
665
685
  e.push(`mic: ${t?.message || String(t)}`), console.warn("[im] 麦克风开启失败,会议继续(音频不可用)", t);
666
686
  }
667
687
  try {
668
- await this.room.localParticipant.setCameraEnabled(!0), n = !0;
688
+ this.preparedCamera ? (await this.room.localParticipant.publishTrack(this.preparedCamera), this.preparedCamera = null) : await this.room.localParticipant.setCameraEnabled(!0), n = !0;
669
689
  } catch (t) {
670
690
  e.push(`camera: ${t?.message || String(t)}`), console.warn("[im] 摄像头开启失败,会议继续(视频不可用)", t);
671
691
  }
@@ -684,17 +704,17 @@ var p = class e extends i {
684
704
  }
685
705
  async leave(e) {
686
706
  if (!this.ended) {
687
- this.ended = !0;
707
+ this.ended = !0, f();
688
708
  try {
689
709
  await e.meetingLeave(this.meetingId);
690
710
  } catch (e) {
691
711
  console.error("[im] meetingLeave 失败", e);
692
712
  }
693
- await u(this.room), this.emitSession("ended", {});
713
+ await p(this.room), this.emitSession("ended", {});
694
714
  }
695
715
  }
696
716
  async end() {
697
- this.ended || (this.ended = !0, await u(this.room), this.emitSession("ended", {}));
717
+ this.ended || (this.ended = !0, await p(this.room), this.emitSession("ended", {}));
698
718
  }
699
719
  getRemoteParticipants() {
700
720
  let e = [];
@@ -768,7 +788,7 @@ var p = class e extends i {
768
788
  console.error(`[im] session handler error: ${e}`, t);
769
789
  }
770
790
  }
771
- }, m = class {
791
+ }, _ = class {
772
792
  transport;
773
793
  livekitWs;
774
794
  identity;
@@ -781,7 +801,7 @@ var p = class e extends i {
781
801
  let n = await this.transport.meetingCreate({
782
802
  inviteeUids: e,
783
803
  title: t
784
- }), r = new p({
804
+ }), r = new g({
785
805
  meetingId: n.meetingId,
786
806
  title: t,
787
807
  roomName: n.roomName,
@@ -794,9 +814,10 @@ var p = class e extends i {
794
814
  });
795
815
  this.currentSession = r;
796
816
  try {
797
- await r.connect(), r.enableDevices().catch((e) => console.warn("[im] enableDevices 异常", e));
817
+ let e = r.prepareLocalTracks().catch((e) => console.warn("[im] 设备预获取失败", e));
818
+ await r.connect(), await e, r.enableDevices().catch((e) => console.warn("[im] enableDevices 异常", e));
798
819
  } catch (e) {
799
- throw this.currentSession = null, this.transport.meetingLeave(n.meetingId).catch(() => {}), e;
820
+ throw this.currentSession = null, r.discardPreparedTracks(), this.transport.meetingLeave(n.meetingId).catch(() => {}), e;
800
821
  }
801
822
  return {
802
823
  meetingId: n.meetingId,
@@ -805,7 +826,7 @@ var p = class e extends i {
805
826
  };
806
827
  }
807
828
  async join(e, t = "") {
808
- let n = await this.transport.meetingJoin(e), r = new p({
829
+ let n = await this.transport.meetingJoin(e), r = new g({
809
830
  meetingId: e,
810
831
  title: t,
811
832
  roomName: n.roomName,
@@ -818,16 +839,17 @@ var p = class e extends i {
818
839
  });
819
840
  this.currentSession = r;
820
841
  try {
821
- await r.connect(), r.enableDevices().catch((e) => console.warn("[im] enableDevices 异常", e));
842
+ let e = r.prepareLocalTracks().catch((e) => console.warn("[im] 设备预获取失败", e));
843
+ await r.connect(), await e, r.enableDevices().catch((e) => console.warn("[im] enableDevices 异常", e));
822
844
  } catch (t) {
823
- throw this.currentSession = null, this.transport.meetingLeave(e).catch(() => {}), t;
845
+ throw this.currentSession = null, r.discardPreparedTracks(), this.transport.meetingLeave(e).catch(() => {}), t;
824
846
  }
825
847
  return r;
826
848
  }
827
849
  async respond(e, t, n) {
828
850
  let r = await this.transport.meetingRespond(e, t);
829
851
  if (t !== "accept" || !r?.token || !r?.roomName) return null;
830
- let i = new p({
852
+ let i = new g({
831
853
  meetingId: e,
832
854
  title: r.title || n || "",
833
855
  roomName: r.roomName,
@@ -840,9 +862,10 @@ var p = class e extends i {
840
862
  });
841
863
  this.currentSession = i;
842
864
  try {
843
- await i.connect(), i.enableDevices().catch((e) => console.warn("[im] enableDevices 异常", e));
865
+ let e = i.prepareLocalTracks().catch((e) => console.warn("[im] 设备预获取失败", e));
866
+ await i.connect(), await e, i.enableDevices().catch((e) => console.warn("[im] enableDevices 异常", e));
844
867
  } catch (t) {
845
- throw this.currentSession = null, this.transport.meetingLeave(e).catch(() => {}), t;
868
+ throw this.currentSession = null, i.discardPreparedTracks(), this.transport.meetingLeave(e).catch(() => {}), t;
846
869
  }
847
870
  return i;
848
871
  }
@@ -852,7 +875,7 @@ var p = class e extends i {
852
875
  async dissolve() {
853
876
  if (!this.currentSession) return !1;
854
877
  let e = this.currentSession;
855
- return await this.transport.meetingDissolve(e.meetingId), this.currentSession = null, await e.end().catch(() => {}), !0;
878
+ return f(), await this.transport.meetingDissolve(e.meetingId), this.currentSession = null, await e.end().catch(() => {}), !0;
856
879
  }
857
880
  async getParticipantCount() {
858
881
  return this.currentSession ? (await this.transport.meetingParticipantCount(this.currentSession.meetingId)).count : 0;
@@ -870,7 +893,7 @@ var p = class e extends i {
870
893
  async getMembers(e = !1) {
871
894
  return this.currentSession ? this.currentSession.refreshMembers(this.transport, e) : [];
872
895
  }
873
- }, h = class {
896
+ }, v = class {
874
897
  transport;
875
898
  realtime;
876
899
  uid;
@@ -940,7 +963,7 @@ var p = class e extends i {
940
963
  dialogChannel(e) {
941
964
  return `dialog#${[this.uid, e].sort()[0]},${[this.uid, e].sort()[1]}`;
942
965
  }
943
- }, g = class {
966
+ }, y = class {
944
967
  transport;
945
968
  constructor(e) {
946
969
  this.transport = e;
@@ -968,7 +991,7 @@ var p = class e extends i {
968
991
  }
969
992
  return { mediaId: i.mediaId };
970
993
  }
971
- }, _ = class {
994
+ }, b = class {
972
995
  transport;
973
996
  byExternal = /* @__PURE__ */ new Map();
974
997
  byUid = /* @__PURE__ */ new Map();
@@ -997,7 +1020,7 @@ var p = class e extends i {
997
1020
  let n = this.byExternal.get(e);
998
1021
  n && n.online !== t && (n.online = t);
999
1022
  }
1000
- }, v = [
1023
+ }, x = [
1001
1024
  "message",
1002
1025
  "message_preview",
1003
1026
  "message:revoked",
@@ -1022,7 +1045,7 @@ var p = class e extends i {
1022
1045
  "session:kicked",
1023
1046
  "connection:state",
1024
1047
  "presence:update"
1025
- ], y = class extends i {
1048
+ ], S = class extends o {
1026
1049
  auth;
1027
1050
  transport;
1028
1051
  realtime;
@@ -1042,7 +1065,7 @@ var p = class e extends i {
1042
1065
  name = "";
1043
1066
  avatar = "";
1044
1067
  constructor(e) {
1045
- super(), this.appId = e.appId, this.apiBase = e.apiBase, this.livekitWs = e.livekitWs, this.auth = new s(null), this.transport = new o(e.apiBase, () => this.auth.getToken()), this.auth = new s(this.transport), this.realtime = new c(e.centrifugoWs, async () => await this.auth.getCentrifugoToken(this.name, this.avatar));
1068
+ super(), this.appId = e.appId, this.apiBase = e.apiBase, this.livekitWs = e.livekitWs, this.auth = new l(null), this.transport = new c(e.apiBase, () => this.auth.getToken()), this.auth = new l(this.transport), this.realtime = new u(e.centrifugoWs, async () => await this.auth.getCentrifugoToken(this.name, this.avatar));
1046
1069
  }
1047
1070
  async connect(e) {
1048
1071
  e.name && (this.name = e.name), e.avatar && (this.avatar = e.avatar), this.clientType = e.clientType ?? 4;
@@ -1055,7 +1078,7 @@ var p = class e extends i {
1055
1078
  async initAfterAuth() {
1056
1079
  await this.loadClientConfig();
1057
1080
  let e = this.clientConfig?.iceServers ?? [];
1058
- this.call = new f(this.transport, this.livekitWs, this.uid, e), this.meeting = new m(this.transport, this.livekitWs, this.uid, e), this.message = new h(this.transport, this.realtime, this.uid), this.media = new g(this.transport), this.users = new _(this.transport), await this.realtime.connect(this.uid);
1081
+ this.call = new h(this.transport, this.livekitWs, this.uid, e), this.meeting = new _(this.transport, this.livekitWs, this.uid, e), this.message = new v(this.transport, this.realtime, this.uid), this.media = new y(this.transport), this.users = new b(this.transport), await this.realtime.connect(this.uid);
1059
1082
  try {
1060
1083
  let e = await this.transport.getSessionState();
1061
1084
  this.sessionState = e.state, this.emit("session:state", {
@@ -1075,10 +1098,14 @@ var p = class e extends i {
1075
1098
  t && e?.meetingId === t.meetingId && e?.hostUid && (t.hostIdentity = e.hostUid);
1076
1099
  }), this.realtime.on("meeting:dissolved", (e) => {
1077
1100
  let t = this.meeting?.currentSession;
1078
- t && e?.meetingId === t.meetingId && t.end().catch((e) => console.warn("[im] dissolved end session 失败", e));
1101
+ t && e?.meetingId === t.meetingId && t.end().catch((e) => console.warn("[im] dissolved end session 失败", e)).finally(() => {
1102
+ this.meeting?.currentSession === t && (this.meeting.currentSession = null);
1103
+ });
1079
1104
  }), this.realtime.on("meeting:kicked", (e) => {
1080
1105
  let t = this.meeting?.currentSession;
1081
- t && e?.meetingId === t.meetingId && t.end().catch((e) => console.warn("[im] kicked end session 失败", e));
1106
+ t && e?.meetingId === t.meetingId && t.end().catch((e) => console.warn("[im] kicked end session 失败", e)).finally(() => {
1107
+ this.meeting?.currentSession === t && (this.meeting.currentSession = null);
1108
+ });
1082
1109
  }), this.realtime.on("session:kicked", (e) => {
1083
1110
  if (!(e?.clientType !== void 0 && e.clientType !== this.clientType)) {
1084
1111
  console.warn("[im] 会话被踢(同端新登录),断开连接");
@@ -1117,15 +1144,15 @@ var p = class e extends i {
1117
1144
  }
1118
1145
  }
1119
1146
  forwardRealtimeEvents() {
1120
- for (let e of v) this.realtime.on(e, (t) => {
1147
+ for (let e of x) this.realtime.on(e, (t) => {
1121
1148
  this.emit(e, t);
1122
1149
  });
1123
1150
  }
1124
1151
  async disconnect() {
1125
- this.call?.currentSession && await this.call.end("user_left").catch(() => {}), this.meeting?.currentSession && await this.meeting.leave().catch(() => {}), this.realtime.disconnect(), this.auth.logout(), this.removeAllListeners();
1152
+ this.call?.currentSession && await this.call.end("user_left").catch(() => {}), this.meeting?.currentSession && await this.meeting.leave().catch(() => {}), this.realtime.disconnect(), this.auth.logout();
1126
1153
  }
1127
1154
  };
1128
1155
  //#endregion
1129
- export { a as ApiError, s as AuthManager, f as CallController, d as CallSession, i as EventEmitter, y as ImClient, g as MediaUploader, m as MeetingController, p as MeetingSession, h as MessageController, c as RealtimeConnection, o as Transport, _ as UserDirectory };
1156
+ export { s as ApiError, l as AuthManager, h as CallController, m as CallSession, o as EventEmitter, S as ImClient, y as MediaUploader, _ as MeetingController, g as MeetingSession, v as MessageController, u as RealtimeConnection, c as Transport, b as UserDirectory };
1130
1157
 
1131
1158
  //# sourceMappingURL=im-core.es.js.map