@quitting/core 1.0.2 → 1.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../src/call.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../src/call.ts"],"names":[],"mappings":"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"}
@@ -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();
@@ -95,6 +95,9 @@ var i = class {
95
95
  usersByExternal(e) {
96
96
  return this.request(`/users/by-external?ids=${e.map(encodeURIComponent).join(",")}`);
97
97
  }
98
+ listUsers() {
99
+ return this.request("/users");
100
+ }
98
101
  callInit(e, t) {
99
102
  return this.request("/call/init", {
100
103
  method: "POST",
@@ -206,7 +209,7 @@ var i = class {
206
209
  body: JSON.stringify({ md5: e })
207
210
  });
208
211
  }
209
- }, s = class {
212
+ }, l = class {
210
213
  transport;
211
214
  sessionToken = null;
212
215
  centrifugoToken = null;
@@ -259,7 +262,7 @@ var i = class {
259
262
  logout() {
260
263
  this.refreshTimer &&= (clearTimeout(this.refreshTimer), null), this.sessionToken = null, this.centrifugoToken = null;
261
264
  }
262
- }, c = class extends i {
265
+ }, u = class extends o {
263
266
  client = null;
264
267
  subscriptions = /* @__PURE__ */ new Map();
265
268
  refCount = /* @__PURE__ */ new Map();
@@ -274,7 +277,7 @@ var i = class {
274
277
  return this.currentState;
275
278
  }
276
279
  async connect(t) {
277
- this.uid = t, this.client = new e(this.wsUrl, { getToken: async () => await this.tokenGetter() }), this.client.on("connected", () => {
280
+ this.uid = t, this.client && this.disconnect(), this.client = new e(this.wsUrl, { getToken: async () => await this.tokenGetter() }), this.client.on("connected", () => {
278
281
  this.currentState = "connected", this.emit("connection:state", "connected"), this.subscribe(`personal#${t}`);
279
282
  }), this.client.on("disconnected", (e) => {
280
283
  this.currentState = "disconnected", this.emit("connection:state", "disconnected"), console.warn("[im] centrifugo disconnected", e?.reason);
@@ -348,6 +351,12 @@ var i = class {
348
351
  case "read_receipt":
349
352
  this.emit("read_receipt", n);
350
353
  break;
354
+ case "typing":
355
+ this.emit("typing", {
356
+ from: n.from || "",
357
+ isTyping: !!n.isTyping
358
+ });
359
+ break;
351
360
  case "presence:update":
352
361
  {
353
362
  let e = n.changes || [];
@@ -376,9 +385,25 @@ var i = class {
376
385
  }
377
386
  }
378
387
  disconnect() {
379
- this.client &&= (this.client.disconnect(), null), this.subscriptions.clear(), this.currentState = "disconnected";
388
+ this.client &&= (this.client.disconnect(), null), this.subscriptions.clear(), this.refCount.clear(), this.currentState = "disconnected";
389
+ }
390
+ }, d = null;
391
+ function f() {
392
+ a("silent"), d &&= (clearTimeout(d), null);
393
+ }
394
+ async function p(e) {
395
+ f();
396
+ try {
397
+ await e.disconnect();
398
+ } finally {
399
+ d = setTimeout(() => {
400
+ a("warn"), d = null;
401
+ }, 1500);
380
402
  }
381
- }, l = class extends i {
403
+ }
404
+ //#endregion
405
+ //#region src/call.ts
406
+ var m = class extends o {
382
407
  callId;
383
408
  callType;
384
409
  roomName;
@@ -472,25 +497,11 @@ var i = class {
472
497
  } catch (e) {
473
498
  console.error("[im] callEnd 失败", e);
474
499
  }
475
- r("silent");
476
- try {
477
- await this.room.disconnect();
478
- } finally {
479
- r("warn");
480
- }
481
- this.emitSession("ended", { reason: t });
500
+ await p(this.room), this.emitSession("ended", { reason: t });
482
501
  }
483
502
  }
484
503
  async end(e) {
485
- if (!this.ended) {
486
- this.ended = !0, r("silent");
487
- try {
488
- await this.room.disconnect();
489
- } finally {
490
- r("warn");
491
- }
492
- this.emitSession("ended", { reason: e });
493
- }
504
+ this.ended || (this.ended = !0, await p(this.room), this.emitSession("ended", { reason: e }));
494
505
  }
495
506
  registerRpcMethod(e, t) {
496
507
  this.room.localParticipant.registerRpcMethod(e, (e) => t(e.payload));
@@ -520,7 +531,7 @@ var i = class {
520
531
  return this.token;
521
532
  }
522
533
  token;
523
- }, u = class {
534
+ }, h = class {
524
535
  transport;
525
536
  livekitWs;
526
537
  identity;
@@ -530,7 +541,7 @@ var i = class {
530
541
  this.transport = e, this.livekitWs = t, this.identity = n, this.iceServers = r;
531
542
  }
532
543
  async init(e, t) {
533
- let n = await this.transport.callInit(e, t), r = new l({
544
+ let n = await this.transport.callInit(e, t), r = new m({
534
545
  callId: n.callId,
535
546
  callType: t,
536
547
  roomName: n.roomName,
@@ -542,7 +553,7 @@ var i = class {
542
553
  return this.currentSession = r, r;
543
554
  }
544
555
  async accept(e, t) {
545
- let n = await this.transport.callAccept(e), r = new l({
556
+ let n = await this.transport.callAccept(e), r = new m({
546
557
  callId: e,
547
558
  callType: t,
548
559
  roomName: n.roomName,
@@ -572,16 +583,8 @@ var i = class {
572
583
  };
573
584
  //#endregion
574
585
  //#region src/meeting.ts
575
- r("warn");
576
- async function d(e) {
577
- r("silent");
578
- try {
579
- await e.disconnect();
580
- } finally {
581
- r("warn");
582
- }
583
- }
584
- var f = 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 f = 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,
@@ -633,19 +638,54 @@ var f = class e extends i {
633
638
  }).on("activeSpeakersChanged", (e) => {
634
639
  let t = e.map((e) => e.identity);
635
640
  this.emitSession("activeSpeakersChanged", { identities: t });
641
+ }).on("trackMuted", (e, t) => {
642
+ e.source === n.Source.Microphone ? this.emitSession("participantMuteChanged", {
643
+ identity: t.identity,
644
+ muted: !0,
645
+ kind: "audio"
646
+ }) : e.source === n.Source.Camera && this.emitSession("participantMuteChanged", {
647
+ identity: t.identity,
648
+ muted: !0,
649
+ kind: "video"
650
+ });
651
+ }).on("trackUnmuted", (e, t) => {
652
+ e.source === n.Source.Microphone ? this.emitSession("participantMuteChanged", {
653
+ identity: t.identity,
654
+ muted: !1,
655
+ kind: "audio"
656
+ }) : e.source === n.Source.Camera && this.emitSession("participantMuteChanged", {
657
+ identity: t.identity,
658
+ muted: !1,
659
+ kind: "video"
660
+ });
636
661
  }), await this.room.connect(this.livekitWs, this.token, { rtcConfig: { iceServers: this.iceServers } });
637
662
  let e = this.room.localParticipant.identity;
638
663
  e && (this.identity = e, this.hostIdentity ||= e), this.emitSession("connected", {});
639
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
+ }
640
680
  async enableDevices() {
641
681
  let e = [], t = !1, n = !1;
642
682
  try {
643
- 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;
644
684
  } catch (t) {
645
685
  e.push(`mic: ${t?.message || String(t)}`), console.warn("[im] 麦克风开启失败,会议继续(音频不可用)", t);
646
686
  }
647
687
  try {
648
- 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;
649
689
  } catch (t) {
650
690
  e.push(`camera: ${t?.message || String(t)}`), console.warn("[im] 摄像头开启失败,会议继续(视频不可用)", t);
651
691
  }
@@ -664,17 +704,17 @@ var f = class e extends i {
664
704
  }
665
705
  async leave(e) {
666
706
  if (!this.ended) {
667
- this.ended = !0;
707
+ this.ended = !0, f();
668
708
  try {
669
709
  await e.meetingLeave(this.meetingId);
670
710
  } catch (e) {
671
711
  console.error("[im] meetingLeave 失败", e);
672
712
  }
673
- await d(this.room), this.emitSession("ended", {});
713
+ await p(this.room), this.emitSession("ended", {});
674
714
  }
675
715
  }
676
716
  async end() {
677
- this.ended || (this.ended = !0, await d(this.room), this.emitSession("ended", {}));
717
+ this.ended || (this.ended = !0, await p(this.room), this.emitSession("ended", {}));
678
718
  }
679
719
  getRemoteParticipants() {
680
720
  let e = [];
@@ -748,7 +788,7 @@ var f = class e extends i {
748
788
  console.error(`[im] session handler error: ${e}`, t);
749
789
  }
750
790
  }
751
- }, p = class {
791
+ }, _ = class {
752
792
  transport;
753
793
  livekitWs;
754
794
  identity;
@@ -761,7 +801,7 @@ var f = class e extends i {
761
801
  let n = await this.transport.meetingCreate({
762
802
  inviteeUids: e,
763
803
  title: t
764
- }), r = new f({
804
+ }), r = new g({
765
805
  meetingId: n.meetingId,
766
806
  title: t,
767
807
  roomName: n.roomName,
@@ -774,9 +814,10 @@ var f = class e extends i {
774
814
  });
775
815
  this.currentSession = r;
776
816
  try {
777
- 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));
778
819
  } catch (e) {
779
- 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;
780
821
  }
781
822
  return {
782
823
  meetingId: n.meetingId,
@@ -785,7 +826,7 @@ var f = class e extends i {
785
826
  };
786
827
  }
787
828
  async join(e, t = "") {
788
- let n = await this.transport.meetingJoin(e), r = new f({
829
+ let n = await this.transport.meetingJoin(e), r = new g({
789
830
  meetingId: e,
790
831
  title: t,
791
832
  roomName: n.roomName,
@@ -798,16 +839,17 @@ var f = class e extends i {
798
839
  });
799
840
  this.currentSession = r;
800
841
  try {
801
- 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));
802
844
  } catch (t) {
803
- throw this.currentSession = null, this.transport.meetingLeave(e).catch(() => {}), t;
845
+ throw this.currentSession = null, r.discardPreparedTracks(), this.transport.meetingLeave(e).catch(() => {}), t;
804
846
  }
805
847
  return r;
806
848
  }
807
849
  async respond(e, t, n) {
808
850
  let r = await this.transport.meetingRespond(e, t);
809
851
  if (t !== "accept" || !r?.token || !r?.roomName) return null;
810
- let i = new f({
852
+ let i = new g({
811
853
  meetingId: e,
812
854
  title: r.title || n || "",
813
855
  roomName: r.roomName,
@@ -820,9 +862,10 @@ var f = class e extends i {
820
862
  });
821
863
  this.currentSession = i;
822
864
  try {
823
- 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));
824
867
  } catch (t) {
825
- throw this.currentSession = null, this.transport.meetingLeave(e).catch(() => {}), t;
868
+ throw this.currentSession = null, i.discardPreparedTracks(), this.transport.meetingLeave(e).catch(() => {}), t;
826
869
  }
827
870
  return i;
828
871
  }
@@ -831,8 +874,8 @@ var f = class e extends i {
831
874
  }
832
875
  async dissolve() {
833
876
  if (!this.currentSession) return !1;
834
- let e = this.currentSession.meetingId;
835
- return await this.transport.meetingDissolve(e), this.currentSession = null, !0;
877
+ let e = this.currentSession;
878
+ return f(), await this.transport.meetingDissolve(e.meetingId), this.currentSession = null, await e.end().catch(() => {}), !0;
836
879
  }
837
880
  async getParticipantCount() {
838
881
  return this.currentSession ? (await this.transport.meetingParticipantCount(this.currentSession.meetingId)).count : 0;
@@ -850,7 +893,7 @@ var f = class e extends i {
850
893
  async getMembers(e = !1) {
851
894
  return this.currentSession ? this.currentSession.refreshMembers(this.transport, e) : [];
852
895
  }
853
- }, m = class {
896
+ }, v = class {
854
897
  transport;
855
898
  realtime;
856
899
  uid;
@@ -920,7 +963,7 @@ var f = class e extends i {
920
963
  dialogChannel(e) {
921
964
  return `dialog#${[this.uid, e].sort()[0]},${[this.uid, e].sort()[1]}`;
922
965
  }
923
- }, h = class {
966
+ }, y = class {
924
967
  transport;
925
968
  constructor(e) {
926
969
  this.transport = e;
@@ -948,7 +991,36 @@ var f = class e extends i {
948
991
  }
949
992
  return { mediaId: i.mediaId };
950
993
  }
951
- }, g = [
994
+ }, b = class {
995
+ transport;
996
+ byExternal = /* @__PURE__ */ new Map();
997
+ byUid = /* @__PURE__ */ new Map();
998
+ loaded = !1;
999
+ loading = null;
1000
+ constructor(e) {
1001
+ this.transport = e;
1002
+ }
1003
+ async list(e = !1) {
1004
+ return this.loaded && !e ? [...this.byExternal.values()] : (this.loading ||= this.transport.listUsers().then((e) => {
1005
+ for (let t of e.users || []) this.upsert(t);
1006
+ this.loaded = !0;
1007
+ }).finally(() => {
1008
+ this.loading = null;
1009
+ }), await this.loading, [...this.byExternal.values()]);
1010
+ }
1011
+ async resolve(e) {
1012
+ let t = this.byExternal.get(e) || this.byUid.get(e);
1013
+ if (t) return t;
1014
+ if (!this.loaded) return await this.list(), this.byExternal.get(e) || this.byUid.get(e);
1015
+ }
1016
+ upsert(e) {
1017
+ this.byExternal.set(e.externalId, e), this.byUid.set(e.uid, e);
1018
+ }
1019
+ updateOnline(e, t) {
1020
+ let n = this.byExternal.get(e);
1021
+ n && n.online !== t && (n.online = t);
1022
+ }
1023
+ }, x = [
952
1024
  "message",
953
1025
  "message_preview",
954
1026
  "message:revoked",
@@ -973,7 +1045,7 @@ var f = class e extends i {
973
1045
  "session:kicked",
974
1046
  "connection:state",
975
1047
  "presence:update"
976
- ], _ = class extends i {
1048
+ ], S = class extends o {
977
1049
  auth;
978
1050
  transport;
979
1051
  realtime;
@@ -981,29 +1053,32 @@ var f = class e extends i {
981
1053
  meeting;
982
1054
  message;
983
1055
  media;
1056
+ users;
984
1057
  uid = "";
985
1058
  appId;
986
1059
  sessionState = "idle";
1060
+ clientType = 4;
1061
+ realtimeBound = !1;
987
1062
  clientConfig = null;
988
1063
  livekitWs;
989
1064
  apiBase;
990
1065
  name = "";
991
1066
  avatar = "";
992
1067
  constructor(e) {
993
- 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));
994
1069
  }
995
1070
  async connect(e) {
996
- e.name && (this.name = e.name), e.avatar && (this.avatar = e.avatar);
1071
+ e.name && (this.name = e.name), e.avatar && (this.avatar = e.avatar), this.clientType = e.clientType ?? 4;
997
1072
  let t = await this.auth.login(this.appId, e.externalId, e.clientType ?? 4, e.deviceName);
998
1073
  return this.uid = t.uid, t.name && (this.name = t.name), t.avatarUrl && (this.avatar = t.avatarUrl), await this.initAfterAuth(), t;
999
1074
  }
1000
1075
  async connectWithExternalJwt(e) {
1001
- e.name && (this.name = e.name), e.avatar && (this.avatar = e.avatar), this.uid = e.uid, this.auth.setExternalToken(e.jwt, e.expiresAt), await this.initAfterAuth();
1076
+ e.name && (this.name = e.name), e.avatar && (this.avatar = e.avatar), this.uid = e.uid, this.clientType = e.clientType ?? 4, this.auth.setExternalToken(e.jwt, e.expiresAt), await this.initAfterAuth();
1002
1077
  }
1003
1078
  async initAfterAuth() {
1004
1079
  await this.loadClientConfig();
1005
1080
  let e = this.clientConfig?.iceServers ?? [];
1006
- this.call = new u(this.transport, this.livekitWs, this.uid, e), this.meeting = new p(this.transport, this.livekitWs, this.uid, e), this.message = new m(this.transport, this.realtime, this.uid), this.media = new h(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);
1007
1082
  try {
1008
1083
  let e = await this.transport.getSessionState();
1009
1084
  this.sessionState = e.state, this.emit("session:state", {
@@ -1014,7 +1089,7 @@ var f = class e extends i {
1014
1089
  } catch (e) {
1015
1090
  console.warn("[im] 同步 sessionState 失败", e);
1016
1091
  }
1017
- this.realtime.on("call:invite", () => {}), this.realtime.on("call:busy", () => {
1092
+ this.realtimeBound || (this.realtimeBound = !0, this.realtime.on("call:busy", () => {
1018
1093
  this.call.currentSession = null;
1019
1094
  }), this.realtime.on("call:no_answer", () => {
1020
1095
  this.call.currentSession = null;
@@ -1023,17 +1098,25 @@ var f = class e extends i {
1023
1098
  t && e?.meetingId === t.meetingId && e?.hostUid && (t.hostIdentity = e.hostUid);
1024
1099
  }), this.realtime.on("meeting:dissolved", (e) => {
1025
1100
  let t = this.meeting?.currentSession;
1026
- 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
+ });
1027
1104
  }), this.realtime.on("meeting:kicked", (e) => {
1028
1105
  let t = this.meeting?.currentSession;
1029
- t && e?.meetingId === t.meetingId && t.end().catch((e) => console.warn("[im] kicked end session 失败", e));
1030
- }), this.realtime.on("session:kicked", () => {
1031
- console.warn("[im] 会话被踢(同端新登录),断开连接");
1032
- try {
1033
- this.realtime.disconnect();
1034
- } catch {}
1035
- this.auth.logout(), this.uid = "";
1036
- }), this.forwardRealtimeEvents(), this.fetchAndEmitPendingInvites();
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
+ });
1109
+ }), this.realtime.on("session:kicked", (e) => {
1110
+ if (!(e?.clientType !== void 0 && e.clientType !== this.clientType)) {
1111
+ console.warn("[im] 会话被踢(同端新登录),断开连接");
1112
+ try {
1113
+ this.realtime.disconnect();
1114
+ } catch {}
1115
+ this.auth.logout(), this.uid = "";
1116
+ }
1117
+ }), this.realtime.on("presence:update", (e) => {
1118
+ e?.uid && this.users?.updateOnline(e.uid, !!e.online);
1119
+ }), this.forwardRealtimeEvents()), this.fetchAndEmitPendingInvites();
1037
1120
  }
1038
1121
  async loadClientConfig() {
1039
1122
  if (!this.clientConfig) try {
@@ -1061,7 +1144,7 @@ var f = class e extends i {
1061
1144
  }
1062
1145
  }
1063
1146
  forwardRealtimeEvents() {
1064
- for (let e of g) this.realtime.on(e, (t) => {
1147
+ for (let e of x) this.realtime.on(e, (t) => {
1065
1148
  this.emit(e, t);
1066
1149
  });
1067
1150
  }
@@ -1070,6 +1153,6 @@ var f = class e extends i {
1070
1153
  }
1071
1154
  };
1072
1155
  //#endregion
1073
- export { a as ApiError, s as AuthManager, u as CallController, l as CallSession, i as EventEmitter, _ as ImClient, h as MediaUploader, p as MeetingController, f as MeetingSession, m as MessageController, c as RealtimeConnection, o as Transport };
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 };
1074
1157
 
1075
1158
  //# sourceMappingURL=im-core.es.js.map