@onyx-p/imlib-web 2.2.3 → 2.2.5

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/index.esm.js CHANGED
@@ -20492,7 +20492,7 @@ const parseSingleDialogMessages = (dialogId, originalMessageList, aesKey) => {
20492
20492
  messageType: messageInstance.messageType,
20493
20493
  isOffLineMessage: false,
20494
20494
  isPersited: messageInstance.isPersited,
20495
- messageId: Long.isLong(dialogMessage.localId) ? dialogMessage.localId.toString() : undefined,
20495
+ messageId: Long.isLong(dialogMessage.localId) ? dialogMessage.localId.toNumber : 0,
20496
20496
  messageUId: dialogMessage.msgId.toString(),
20497
20497
  sentTime: dialogMessage.seqno.toString(),
20498
20498
  sentStatus: SentStatus.SENT,
@@ -20562,7 +20562,7 @@ const parseChatRecordMsgDetails$1 = (conversationOpt, msgDetails) => {
20562
20562
  messageType: messageInstance.messageType,
20563
20563
  isOffLineMessage: false,
20564
20564
  isPersited: messageInstance.isPersited,
20565
- messageId: item.msgId + '',
20565
+ messageId: 0,
20566
20566
  messageUId: item.msgId + '',
20567
20567
  sentTime: item.msgSendTime + '',
20568
20568
  sentStatus: SentStatus.SENT,
@@ -20704,6 +20704,21 @@ var MessageReceiptManager$1 = {
20704
20704
  }
20705
20705
  };
20706
20706
 
20707
+ let oldestMessageId = 0;
20708
+ let lastMessageId = 0;
20709
+ function setInitialMessageId(oldestMessageId_tmp, lastMessageId_tmp) {
20710
+ oldestMessageId = oldestMessageId_tmp;
20711
+ lastMessageId = lastMessageId_tmp;
20712
+ }
20713
+ function generateNewMessageId() {
20714
+ lastMessageId++;
20715
+ return lastMessageId;
20716
+ }
20717
+ function generateOldMessageId() {
20718
+ oldestMessageId--;
20719
+ return oldestMessageId;
20720
+ }
20721
+
20707
20722
  class MessageLoader {
20708
20723
  watcher;
20709
20724
  pullingMsg = false;
@@ -20807,6 +20822,9 @@ class MessageLoader {
20807
20822
  RecallMessageStore.remove(m.content.messageUId);
20808
20823
  } else {
20809
20824
  m.isOffLineMessage = isOffLineMessage;
20825
+ if (!m.messageId) {
20826
+ m.messageId = generateNewMessageId();
20827
+ }
20810
20828
  ConversationManager$1.get().setConversationCacheByMessage(m);
20811
20829
  messageList.push(m);
20812
20830
  if (m.messageType === MessageTypes.RECALL) {
@@ -20994,10 +21012,10 @@ class MessageCache {
20994
21012
  currentAppKey = '';
20995
21013
  currentUserId = '';
20996
21014
  APP_INFO_KEY = 'im_app_info';
20997
- DB_NAME_PREFIX = 'im_message_cache';
21015
+ DB_NAME_PREFIX = 'im_message_cache_new';
20998
21016
  DB_VERSION = 2;
20999
- STORE_NAME = 'messages';
21000
- DIALOG_STATE_STORE = 'dialogStates';
21017
+ STORE_NAME = 'messages_new';
21018
+ DIALOG_STATE_STORE = 'dialogStates_new';
21001
21019
  encryptKey = {
21002
21020
  key: ''
21003
21021
  };
@@ -21005,7 +21023,8 @@ class MessageCache {
21005
21023
  SALT_SUFFIX = 'im_message_cache_salt_suffix';
21006
21024
  constructor(appKey, userId) {
21007
21025
  this.generateEncryptKey(appKey, userId);
21008
- this.init(appKey, userId);
21026
+ this.currentAppKey = appKey;
21027
+ this.currentUserId = userId;
21009
21028
  }
21010
21029
  generateEncryptKey(appKey, userId) {
21011
21030
  const saltedInput = `${this.SALT_PREFIX}${appKey}_${userId}${this.SALT_SUFFIX}`;
@@ -21023,9 +21042,7 @@ class MessageCache {
21023
21042
  iv: iv
21024
21043
  };
21025
21044
  }
21026
- async init(appKey, userId) {
21027
- this.currentAppKey = appKey;
21028
- this.currentUserId = userId;
21045
+ async initDB() {
21029
21046
  await this.checkAndResetDatabase();
21030
21047
  await this.initDatabase();
21031
21048
  }
@@ -21038,7 +21055,7 @@ class MessageCache {
21038
21055
  await this.deleteDatabase();
21039
21056
  }
21040
21057
  } catch (error) {
21041
- console.error('解析存储的AppKey和UserId出错', error);
21058
+ logger.error('解析存储的AppKey和UserId出错', error);
21042
21059
  await this.deleteDatabase();
21043
21060
  }
21044
21061
  }
@@ -21058,11 +21075,11 @@ class MessageCache {
21058
21075
  const dbName = this.getDBName();
21059
21076
  const deleteRequest = indexedDB.deleteDatabase(dbName);
21060
21077
  deleteRequest.onsuccess = () => {
21061
- console.log(`数据库 ${dbName} 已成功删除`);
21078
+ logger.info(`数据库 ${dbName} 已成功删除`);
21062
21079
  resolve();
21063
21080
  };
21064
21081
  deleteRequest.onerror = event => {
21065
- console.error(`删除数据库 ${dbName} 失败`, event);
21082
+ logger.error(`删除数据库 ${dbName} 失败`, event);
21066
21083
  resolve();
21067
21084
  };
21068
21085
  });
@@ -21075,7 +21092,7 @@ class MessageCache {
21075
21092
  const dbName = this.getDBName();
21076
21093
  const request = indexedDB.open(dbName, this.DB_VERSION);
21077
21094
  request.onerror = event => {
21078
- console.error('数据库打开失败', event);
21095
+ logger.error('数据库打开失败', event);
21079
21096
  reject(new Error('数据库打开失败'));
21080
21097
  };
21081
21098
  request.onsuccess = event => {
@@ -21083,7 +21100,7 @@ class MessageCache {
21083
21100
  this.loadAllDialogStates().then(() => {
21084
21101
  resolve();
21085
21102
  }).catch(err => {
21086
- console.error('加载会话状态失败', err);
21103
+ logger.error('加载会话状态失败', err);
21087
21104
  resolve();
21088
21105
  });
21089
21106
  };
@@ -21091,7 +21108,10 @@ class MessageCache {
21091
21108
  const db = event.target.result;
21092
21109
  if (!db.objectStoreNames.contains(this.STORE_NAME)) {
21093
21110
  const store = db.createObjectStore(this.STORE_NAME, {
21094
- keyPath: 'messageUId'
21111
+ keyPath: 'messageId'
21112
+ });
21113
+ store.createIndex('messageUId', 'messageUId', {
21114
+ unique: true
21095
21115
  });
21096
21116
  store.createIndex('dialogId', 'dialogId', {
21097
21117
  unique: false
@@ -21155,7 +21175,7 @@ class MessageCache {
21155
21175
  resolve();
21156
21176
  };
21157
21177
  request.onerror = event => {
21158
- console.error('更新会话状态失败', event);
21178
+ logger.error('更新会话状态失败', event);
21159
21179
  reject(new Error('更新会话状态失败'));
21160
21180
  };
21161
21181
  });
@@ -21166,7 +21186,7 @@ class MessageCache {
21166
21186
  const contentStr = JSON.stringify(content);
21167
21187
  return aes256Encrypt(contentStr, this.encryptKey);
21168
21188
  } catch (error) {
21169
- console.error('加密消息内容失败', error);
21189
+ logger.error('加密消息内容失败', error);
21170
21190
  return '';
21171
21191
  }
21172
21192
  }
@@ -21178,7 +21198,7 @@ class MessageCache {
21178
21198
  const decryptedStr = aes256Decrypt(encryptedHex, this.encryptKey);
21179
21199
  return JSON.parse(decryptedStr);
21180
21200
  } catch (error) {
21181
- console.error('解密消息内容失败', error);
21201
+ logger.error('解密消息内容失败', error);
21182
21202
  return null;
21183
21203
  }
21184
21204
  }
@@ -21208,7 +21228,7 @@ class MessageCache {
21208
21228
  resolve();
21209
21229
  };
21210
21230
  transaction.onerror = event => {
21211
- console.error('添加消息事务失败', event);
21231
+ logger.error('添加消息事务失败', event);
21212
21232
  reject(new Error('添加消息事务失败'));
21213
21233
  };
21214
21234
  });
@@ -21251,7 +21271,7 @@ class MessageCache {
21251
21271
  try {
21252
21272
  message.content = this.decryptContent(message.content);
21253
21273
  } catch (error) {
21254
- console.error('解密消息内容失败', error);
21274
+ logger.error('解密消息内容失败', error);
21255
21275
  message.content = null;
21256
21276
  }
21257
21277
  }
@@ -21275,7 +21295,7 @@ class MessageCache {
21275
21295
  };
21276
21296
  };
21277
21297
  transaction.onerror = event => {
21278
- console.error('获取消息事务失败', event);
21298
+ logger.error('获取消息事务失败', event);
21279
21299
  reject(new Error('获取消息事务失败'));
21280
21300
  };
21281
21301
  });
@@ -21380,7 +21400,7 @@ class MessageCache {
21380
21400
  }
21381
21401
  };
21382
21402
  deleteRequest.onerror = event => {
21383
- console.error('删除消息失败', id, event);
21403
+ logger.error('删除消息失败', id, event);
21384
21404
  if (!hasError) {
21385
21405
  hasError = true;
21386
21406
  reject(new Error('删除消息失败'));
@@ -21486,131 +21506,142 @@ class MessageCache {
21486
21506
  }
21487
21507
  };
21488
21508
  request.onerror = event => {
21489
- console.error('清除过期消息失败', event);
21509
+ logger.error('清除过期消息失败', event);
21490
21510
  reject(new Error('清除过期消息失败'));
21491
21511
  };
21492
21512
  });
21493
21513
  }
21494
- async getMessagesByPage(dialogId, pageSize = 20, cursorPosition = null) {
21514
+ async getLatestMessage(conversation) {
21515
+ const dialogId = getFullDialogId(conversation);
21495
21516
  if (!this.db) {
21496
- return {
21497
- messages: [],
21498
- nextCursor: null
21499
- };
21517
+ return null;
21500
21518
  }
21501
21519
  return new Promise((resolve, reject) => {
21502
21520
  const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21503
21521
  const store = transaction.objectStore(this.STORE_NAME);
21504
21522
  const index = store.index('dialogId_sentTime');
21505
- const range = IDBKeyRange.bound([dialogId, cursorPosition || ''], [dialogId, '\uffff']);
21506
- const messages = [];
21507
- let nextCursor = null;
21508
- let count = 0;
21509
- const cursorRequest = index.openCursor(range);
21523
+ const range = IDBKeyRange.bound([dialogId, ''], [dialogId, '\uffff']);
21524
+ const direction = 'prev';
21525
+ const cursorRequest = index.openCursor(range, direction);
21510
21526
  cursorRequest.onsuccess = event => {
21511
21527
  const cursor = event.target.result;
21512
- if (cursor && count < pageSize) {
21513
- messages.push(cursor.value);
21514
- count++;
21515
- cursor.continue();
21516
- } else if (cursor) {
21517
- nextCursor = cursor.value.sentTime;
21528
+ if (cursor) {
21529
+ const message = {
21530
+ ...cursor.value
21531
+ };
21532
+ if (typeof message.content === 'string' && message.content) {
21533
+ try {
21534
+ message.content = this.decryptContent(message.content);
21535
+ } catch (error) {
21536
+ logger.error('解密消息内容失败', error);
21537
+ message.content = null;
21538
+ }
21539
+ }
21540
+ resolve(message);
21518
21541
  } else {
21519
- nextCursor = null;
21520
- }
21521
- if (!cursor || count >= pageSize) {
21522
- resolve({
21523
- messages,
21524
- nextCursor
21525
- });
21542
+ resolve(null);
21526
21543
  }
21527
21544
  };
21528
21545
  cursorRequest.onerror = event => {
21529
- reject(new Error('获取分页消息失败'));
21546
+ logger.error('获取最新消息失败', event);
21547
+ resolve(null);
21530
21548
  };
21531
21549
  });
21532
21550
  }
21533
- async updateMessagesStatus(messageUIds, newStatus) {
21534
- if (!this.db || messageUIds.length === 0) {
21535
- return;
21551
+ async upsertMessage(message) {
21552
+ if (!this.db) {
21553
+ throw new Error('数据库未初始化');
21536
21554
  }
21537
21555
  return new Promise((resolve, reject) => {
21538
21556
  const transaction = this.db.transaction(this.STORE_NAME, 'readwrite');
21539
21557
  const store = transaction.objectStore(this.STORE_NAME);
21540
- let completed = 0;
21541
- let hasError = false;
21542
- messageUIds.forEach(id => {
21543
- const getRequest = store.get(id);
21544
- getRequest.onsuccess = () => {
21545
- const message = getRequest.result;
21546
- if (message) {
21547
- message.receivedStatus = newStatus;
21548
- store.put(message);
21549
- }
21550
- completed++;
21551
- if (completed === messageUIds.length && !hasError) {
21552
- resolve();
21553
- }
21554
- };
21555
- getRequest.onerror = event => {
21556
- if (!hasError) {
21557
- hasError = true;
21558
- reject(new Error('更新消息状态失败'));
21559
- }
21560
- };
21561
- });
21562
- transaction.oncomplete = () => {
21558
+ const messageToStore = {
21559
+ ...message
21560
+ };
21561
+ if (messageToStore.content) {
21562
+ const encryptedContent = this.encryptContent(messageToStore.content);
21563
+ messageToStore.content = encryptedContent;
21564
+ }
21565
+ const request = store.put(messageToStore);
21566
+ request.onsuccess = () => {
21563
21567
  resolve();
21564
21568
  };
21565
- transaction.onerror = event => {
21566
- reject(new Error('批量更新事务失败'));
21569
+ request.onerror = event => {
21570
+ logger.error('更新/插入消息失败', event);
21571
+ reject(new Error('更新/插入消息失败'));
21567
21572
  };
21568
21573
  });
21569
21574
  }
21570
- async changeUser(appKey, userId) {
21571
- if (this.currentAppKey === appKey && this.currentUserId === userId) {
21572
- return;
21573
- }
21574
- this.currentAppKey = appKey;
21575
- this.currentUserId = userId;
21576
- this.generateEncryptKey(appKey, userId);
21577
- await this.checkAndResetDatabase();
21578
- await this.initDatabase();
21579
- }
21580
- async getLatestMessage(conversation) {
21581
- const dialogId = getFullDialogId(conversation);
21575
+ async getMessageById(messageId) {
21582
21576
  if (!this.db) {
21583
21577
  return null;
21584
21578
  }
21585
21579
  return new Promise((resolve, reject) => {
21586
21580
  const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21587
21581
  const store = transaction.objectStore(this.STORE_NAME);
21588
- const index = store.index('dialogId_sentTime');
21589
- const range = IDBKeyRange.bound([dialogId, ''], [dialogId, '\uffff']);
21590
- const direction = 'prev';
21591
- const cursorRequest = index.openCursor(range, direction);
21592
- cursorRequest.onsuccess = event => {
21593
- const cursor = event.target.result;
21594
- if (cursor) {
21595
- const message = {
21596
- ...cursor.value
21582
+ const request = store.get(messageId);
21583
+ request.onsuccess = () => {
21584
+ const message = request.result;
21585
+ if (message) {
21586
+ const decryptedMessage = {
21587
+ ...message
21597
21588
  };
21598
- if (typeof message.content === 'string' && message.content) {
21589
+ if (typeof decryptedMessage.content === 'string' && decryptedMessage.content) {
21599
21590
  try {
21600
- message.content = this.decryptContent(message.content);
21591
+ decryptedMessage.content = this.decryptContent(decryptedMessage.content);
21601
21592
  } catch (error) {
21602
- console.error('解密消息内容失败', error);
21603
- message.content = null;
21593
+ logger.error('解密消息内容失败', error);
21594
+ decryptedMessage.content = null;
21604
21595
  }
21605
21596
  }
21606
- resolve(message);
21597
+ resolve(decryptedMessage);
21607
21598
  } else {
21608
21599
  resolve(null);
21609
21600
  }
21610
21601
  };
21611
- cursorRequest.onerror = event => {
21612
- console.error('获取最新消息失败', event);
21613
- reject(new Error('获取最新消息失败'));
21602
+ request.onerror = event => {
21603
+ logger.error('查询消息失败', event);
21604
+ resolve(null);
21605
+ };
21606
+ });
21607
+ }
21608
+ async getMessageIdRange() {
21609
+ if (!this.db) {
21610
+ return null;
21611
+ }
21612
+ return new Promise((resolve, reject) => {
21613
+ const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21614
+ const store = transaction.objectStore(this.STORE_NAME);
21615
+ let newest = null;
21616
+ let oldest = null;
21617
+ const oldestRequest = store.openCursor();
21618
+ oldestRequest.onsuccess = event => {
21619
+ const cursor = event.target.result;
21620
+ if (cursor) {
21621
+ oldest = cursor.value.messageId;
21622
+ const newestRequest = store.openCursor(null, 'prev');
21623
+ newestRequest.onsuccess = event => {
21624
+ const cursor = event.target.result;
21625
+ if (cursor) {
21626
+ newest = cursor.value.messageId;
21627
+ if (newest && oldest) {
21628
+ resolve({
21629
+ newest,
21630
+ oldest
21631
+ });
21632
+ } else {
21633
+ resolve(null);
21634
+ }
21635
+ } else {
21636
+ resolve(null);
21637
+ }
21638
+ };
21639
+ } else {
21640
+ resolve(null);
21641
+ }
21642
+ };
21643
+ transaction.onerror = event => {
21644
+ resolve(null);
21614
21645
  };
21615
21646
  });
21616
21647
  }
@@ -21727,16 +21758,29 @@ class LibLoader {
21727
21758
  webSocketServer.close();
21728
21759
  return Promise.resolve();
21729
21760
  }
21730
- setUserLogged() {
21761
+ async setUserLogged() {
21731
21762
  ConversationManager$1.get().destroyed();
21732
21763
  ConversationManager$1.create(this.options.appkey, accountStore.uid.toString(), this.watcher.conversationState);
21733
21764
  MessageReceiptManager$1.create(this.options.appkey, accountStore.uid.toString());
21734
- MessageCache$1.create(this.options.appkey, accountStore.uid.toString());
21735
21765
  this.messageLoader?.stop();
21736
21766
  this.messageLoader = new MessageLoader(this.watcher, this.options);
21737
21767
  SentMessageStore.reset();
21738
21768
  RecallMessageStore.reset();
21739
21769
  DialogSecretKey$1.reset();
21770
+ MessageCache$1.create(this.options.appkey, accountStore.uid.toString());
21771
+ MessageCache$1.get().initDB().then(() => {
21772
+ return MessageCache$1.get().getMessageIdRange();
21773
+ }).then(result => {
21774
+ if (result) {
21775
+ const {
21776
+ oldest,
21777
+ newest
21778
+ } = result;
21779
+ setInitialMessageId(oldest, newest);
21780
+ } else {
21781
+ setInitialMessageId(10000, 10000);
21782
+ }
21783
+ });
21740
21784
  if (this.getConnectionStatus() === ConnectionStatus.CONNECTED) {
21741
21785
  this.handleUserConnected();
21742
21786
  }
@@ -28380,37 +28424,31 @@ function requireProtobufjs () {
28380
28424
  var protobufjsExports = requireProtobufjs();
28381
28425
  var protobuf = /*@__PURE__*/getDefaultExportFromCjs(protobufjsExports);
28382
28426
 
28383
- const transSentAttrs2IReceivedMessage = (message, options, sentStatus = SentStatus.SENDING) => ({
28384
- conversationType: options.conversation.conversationType,
28385
- targetId: options.conversation.targetId,
28386
- senderUserId: options.senderUserId,
28387
- messageDirection: MessageDirection.SEND,
28388
- isCounted: message.isCounted,
28389
- isMentioned: false,
28390
- content: deepClone(message.content),
28391
- messageType: message.messageType,
28392
- isOffLineMessage: false,
28393
- isPersited: message.isPersited,
28394
- messageId: options.messageId,
28395
- messageUId: '0',
28396
- sentTime: options.sentTime,
28397
- sentStatus,
28398
- receivedTime: '0',
28399
- isStatusMessage: message.isStatusMessage,
28400
- receivedStatus: ReceivedStatus.IDLE,
28401
- disableNotification: true,
28402
- burnAfterReadingFlag: false
28403
- });
28404
-
28405
- let UniqueLocalId = 0;
28406
- function generateMessageId() {
28407
- UniqueLocalId++;
28408
- const time = getServerTime$1();
28409
- if (UniqueLocalId < time) {
28410
- UniqueLocalId = time;
28411
- }
28412
- return 230000000000000 + UniqueLocalId;
28413
- }
28427
+ const transSentAttrs2IReceivedMessage = (message, options, sentStatus = SentStatus.SENDING) => {
28428
+ const conversation = ConversationManager$1.get().get(options.conversation);
28429
+ return {
28430
+ conversationType: options.conversation.conversationType,
28431
+ targetId: options.conversation.targetId,
28432
+ senderUserId: options.senderUserId,
28433
+ messageDirection: MessageDirection.SEND,
28434
+ isCounted: message.isCounted,
28435
+ isMentioned: false,
28436
+ content: deepClone(message.content),
28437
+ messageType: message.messageType,
28438
+ isOffLineMessage: false,
28439
+ isPersited: message.isPersited,
28440
+ messageId: options.messageId,
28441
+ messageUId: "local" + options.sentTime,
28442
+ sentTime: options.sentTime,
28443
+ sentStatus,
28444
+ receivedTime: options.sentTime,
28445
+ isStatusMessage: message.isStatusMessage,
28446
+ receivedStatus: ReceivedStatus.IDLE,
28447
+ disableNotification: true,
28448
+ burnAfterReadingFlag: conversation?.burnAfterReadingFlag ?? false,
28449
+ burnAfterReadingTime: conversation?.burnAfterReadingTime ?? 0
28450
+ };
28451
+ };
28414
28452
 
28415
28453
  const getBlobUrl = blob => {
28416
28454
  const URL = window.URL || window.webkitURL;
@@ -28881,10 +28919,12 @@ const sendRecallMessage = async (conversation, options) => {
28881
28919
  const sentAttris = {
28882
28920
  conversation,
28883
28921
  senderUserId: accountStore.uid,
28884
- messageId: '0',
28922
+ messageId: 0,
28885
28923
  sentTime: getServerTime$1().toString()
28886
28924
  };
28887
28925
  const receivedMessage = transSentAttrs2IReceivedMessage(recallCommandMessage, sentAttris, SentStatus.SENT);
28926
+ receivedMessage.burnAfterReadingFlag = false;
28927
+ receivedMessage.burnAfterReadingTime = 0;
28888
28928
  ConversationManager$1.get().setConversationCacheByMessage(receivedMessage);
28889
28929
  return {
28890
28930
  code: ErrorCode.SUCCESS,
@@ -28933,12 +28973,16 @@ async function createSendFunction(fileType, conversation, msgBody, hooks, sendOp
28933
28973
  });
28934
28974
  }
28935
28975
  async function internal_sendMessage(conversation, message, options, uploadOptions) {
28936
- const checkResult = beforeSend(conversation, message, options);
28976
+ const checkResult = await beforeSend(conversation, message, options);
28937
28977
  if (checkResult.code !== ErrorCode.SUCCESS || !checkResult.message || !checkResult.sentArgs) {
28938
28978
  return {
28939
28979
  code: checkResult.code
28940
28980
  };
28941
28981
  }
28982
+ {
28983
+ const receivedMessage = transSentAttrs2IReceivedMessage(checkResult.message, checkResult.sentArgs);
28984
+ await saveSentMessage(receivedMessage, checkResult.sentArgs);
28985
+ }
28942
28986
  let {
28943
28987
  message: sentMessage,
28944
28988
  sentArgs
@@ -28947,30 +28991,30 @@ async function internal_sendMessage(conversation, message, options, uploadOption
28947
28991
  const uploadResult = await uploadOptions.task(sentMessage, uploadOptions.files);
28948
28992
  sentMessage = uploadResult.message;
28949
28993
  if (!uploadResult.finished) {
28994
+ const receivedMessage = transSentAttrs2IReceivedMessage(checkResult.message, checkResult.sentArgs, SentStatus.FAILED);
28995
+ await saveSentMessage(receivedMessage, sentArgs);
28950
28996
  return {
28951
28997
  code: ErrorCode.UPLOAD_FILE_FAILED,
28952
- data: transSentAttrs2IReceivedMessage(sentMessage, sentArgs, SentStatus.FAILED)
28998
+ data: receivedMessage
28953
28999
  };
28954
29000
  }
28955
29001
  }
28956
29002
  return send(sentMessage, sentArgs);
28957
29003
  }
28958
- function beforeSend(conversation, message, options) {
28959
- if (!LibLoader.loader || LibLoader.loader.getConnectionStatus() !== ConnectionStatus.CONNECTED) {
28960
- return {
28961
- code: ErrorCode.RC_NET_CHANNEL_INVALID
28962
- };
28963
- }
29004
+ async function beforeSend(conversation, message, options) {
28964
29005
  const mediaAttribute = JSON.stringify(filterNullProperty(message.content));
28965
29006
  if (getByteLength(mediaAttribute) > MAX_MESSAGE_CONTENT_BYTES) {
28966
29007
  return {
28967
29008
  code: ErrorCode.RC_MSG_CONTENT_EXCEED_LIMIT
28968
29009
  };
28969
29010
  }
29011
+ if (message.isPersited) {
29012
+ await ConversationManager$1.get().loadConvsationsIfNotExist([conversation]);
29013
+ }
28970
29014
  const sentArgs = {
28971
29015
  conversation: conversation,
28972
29016
  senderUserId: accountStore.uid,
28973
- messageId: options?.messageId ?? generateMessageId().toString(),
29017
+ messageId: generateNewMessageId(),
28974
29018
  sentTime: getMessageSentTime().toString(),
28975
29019
  pushConfig: options?.pushConfig
28976
29020
  };
@@ -28987,12 +29031,6 @@ function beforeSend(conversation, message, options) {
28987
29031
  async function send(message, sentArgs) {
28988
29032
  const dialogId = getFullDialogId(sentArgs.conversation);
28989
29033
  const receivedMessage = transSentAttrs2IReceivedMessage(message, sentArgs);
28990
- if (message.isPersited) {
28991
- await ConversationManager$1.get().loadConvsationsIfNotExist([sentArgs.conversation]);
28992
- }
28993
- const conversation = ConversationManager$1.get().get(sentArgs.conversation);
28994
- receivedMessage.burnAfterReadingFlag = conversation?.burnAfterReadingFlag ?? false;
28995
- receivedMessage.burnAfterReadingTime = conversation?.burnAfterReadingTime ?? 0;
28996
29034
  const secretKey = await DialogSecretKey$1.getDialogAesKey(dialogId.toString());
28997
29035
  if (!secretKey) {
28998
29036
  receivedMessage.sentStatus = SentStatus.FAILED;
@@ -29015,7 +29053,7 @@ async function send(message, sentArgs) {
29015
29053
  const mediaEncryptedString = aes256Encrypt(mediaAttribute, secretKey);
29016
29054
  SentMessageStore.addMessage(sentArgs.messageId);
29017
29055
  const baseParams = {
29018
- localId: Long.fromString(sentArgs.messageId),
29056
+ localId: Long.fromNumber(sentArgs.messageId),
29019
29057
  mediaFlag: message.messageType !== MessageTypes.TEXT,
29020
29058
  mediaConstructor: message.messageType,
29021
29059
  msgPreContent: '',
@@ -29046,9 +29084,10 @@ async function send(message, sentArgs) {
29046
29084
  receivedMessage.sentTime = response.data.msgSendTime.toString();
29047
29085
  receivedMessage.messageUId = response.data.msgId.toString();
29048
29086
  receivedMessage.sentStatus = SentStatus.SENT;
29049
- ConversationManager$1.get().setConversationCacheByMessage(receivedMessage);
29087
+ await saveSentMessage(receivedMessage, sentArgs);
29050
29088
  } else {
29051
29089
  receivedMessage.sentStatus = SentStatus.FAILED;
29090
+ await saveSentMessage(receivedMessage, sentArgs);
29052
29091
  }
29053
29092
  return {
29054
29093
  code: response.code,
@@ -29064,6 +29103,18 @@ function getMessageSentTime() {
29064
29103
  }
29065
29104
  return UniqueSentTime;
29066
29105
  }
29106
+ async function saveSentMessage(receivedMessage, options) {
29107
+ try {
29108
+ const cache = MessageCache$1.get();
29109
+ if (receivedMessage.isPersited && cache) {
29110
+ await cache.upsertMessage(receivedMessage);
29111
+ const latestMessage = await cache.getLatestMessage(options.conversation);
29112
+ ConversationManager$1.get().updateLatestMessage(options.conversation, latestMessage);
29113
+ }
29114
+ } catch (error) {
29115
+ logger.error('saveSentMessage -> ', error);
29116
+ }
29117
+ }
29067
29118
 
29068
29119
  class IMClient extends EventEmitter {
29069
29120
  options;
@@ -29240,7 +29291,6 @@ class IMClient extends EventEmitter {
29240
29291
  });
29241
29292
  }
29242
29293
  async getPreviousHistoryMessages(conversation, timestamp, count = 20) {
29243
- debugger;
29244
29294
  const cachedResult = await MessageCache$1.get().getPreviousMessages(conversation, timestamp ?? '0', count);
29245
29295
  if (!timestamp && cachedResult.messages.length) {
29246
29296
  ConversationManager$1.get().updateLatestMessage(conversation, cachedResult.messages[cachedResult.messages.length - 1]);
@@ -29264,8 +29314,13 @@ class IMClient extends EventEmitter {
29264
29314
  return remotesResult;
29265
29315
  }
29266
29316
  const remotesMessages = remotesResult.data.list;
29317
+ for (let i = remotesMessages.length - 1; i >= 0; i--) {
29318
+ const message = remotesMessages[i];
29319
+ if (!message.messageId) {
29320
+ message.messageId = generateOldMessageId();
29321
+ }
29322
+ }
29267
29323
  if (!remotesTimestamp || remotesTimestamp == '0') {
29268
- debugger;
29269
29324
  ConversationManager$1.get().updateLatestMessage(conversation, remotesMessages[remotesMessages.length - 1]);
29270
29325
  }
29271
29326
  MessageCache$1.get().addMessages(remotesMessages, conversation, !remotesResult.data.hasMore);
package/index.umd.js CHANGED
@@ -20498,7 +20498,7 @@
20498
20498
  messageType: messageInstance.messageType,
20499
20499
  isOffLineMessage: false,
20500
20500
  isPersited: messageInstance.isPersited,
20501
- messageId: Long.isLong(dialogMessage.localId) ? dialogMessage.localId.toString() : undefined,
20501
+ messageId: Long.isLong(dialogMessage.localId) ? dialogMessage.localId.toNumber : 0,
20502
20502
  messageUId: dialogMessage.msgId.toString(),
20503
20503
  sentTime: dialogMessage.seqno.toString(),
20504
20504
  sentStatus: exports.SentStatus.SENT,
@@ -20568,7 +20568,7 @@
20568
20568
  messageType: messageInstance.messageType,
20569
20569
  isOffLineMessage: false,
20570
20570
  isPersited: messageInstance.isPersited,
20571
- messageId: item.msgId + '',
20571
+ messageId: 0,
20572
20572
  messageUId: item.msgId + '',
20573
20573
  sentTime: item.msgSendTime + '',
20574
20574
  sentStatus: exports.SentStatus.SENT,
@@ -20710,6 +20710,21 @@
20710
20710
  }
20711
20711
  };
20712
20712
 
20713
+ let oldestMessageId = 0;
20714
+ let lastMessageId = 0;
20715
+ function setInitialMessageId(oldestMessageId_tmp, lastMessageId_tmp) {
20716
+ oldestMessageId = oldestMessageId_tmp;
20717
+ lastMessageId = lastMessageId_tmp;
20718
+ }
20719
+ function generateNewMessageId() {
20720
+ lastMessageId++;
20721
+ return lastMessageId;
20722
+ }
20723
+ function generateOldMessageId() {
20724
+ oldestMessageId--;
20725
+ return oldestMessageId;
20726
+ }
20727
+
20713
20728
  class MessageLoader {
20714
20729
  watcher;
20715
20730
  pullingMsg = false;
@@ -20813,6 +20828,9 @@
20813
20828
  RecallMessageStore.remove(m.content.messageUId);
20814
20829
  } else {
20815
20830
  m.isOffLineMessage = isOffLineMessage;
20831
+ if (!m.messageId) {
20832
+ m.messageId = generateNewMessageId();
20833
+ }
20816
20834
  ConversationManager$1.get().setConversationCacheByMessage(m);
20817
20835
  messageList.push(m);
20818
20836
  if (m.messageType === MessageTypes.RECALL) {
@@ -21000,10 +21018,10 @@
21000
21018
  currentAppKey = '';
21001
21019
  currentUserId = '';
21002
21020
  APP_INFO_KEY = 'im_app_info';
21003
- DB_NAME_PREFIX = 'im_message_cache';
21021
+ DB_NAME_PREFIX = 'im_message_cache_new';
21004
21022
  DB_VERSION = 2;
21005
- STORE_NAME = 'messages';
21006
- DIALOG_STATE_STORE = 'dialogStates';
21023
+ STORE_NAME = 'messages_new';
21024
+ DIALOG_STATE_STORE = 'dialogStates_new';
21007
21025
  encryptKey = {
21008
21026
  key: ''
21009
21027
  };
@@ -21011,7 +21029,8 @@
21011
21029
  SALT_SUFFIX = 'im_message_cache_salt_suffix';
21012
21030
  constructor(appKey, userId) {
21013
21031
  this.generateEncryptKey(appKey, userId);
21014
- this.init(appKey, userId);
21032
+ this.currentAppKey = appKey;
21033
+ this.currentUserId = userId;
21015
21034
  }
21016
21035
  generateEncryptKey(appKey, userId) {
21017
21036
  const saltedInput = `${this.SALT_PREFIX}${appKey}_${userId}${this.SALT_SUFFIX}`;
@@ -21029,9 +21048,7 @@
21029
21048
  iv: iv
21030
21049
  };
21031
21050
  }
21032
- async init(appKey, userId) {
21033
- this.currentAppKey = appKey;
21034
- this.currentUserId = userId;
21051
+ async initDB() {
21035
21052
  await this.checkAndResetDatabase();
21036
21053
  await this.initDatabase();
21037
21054
  }
@@ -21044,7 +21061,7 @@
21044
21061
  await this.deleteDatabase();
21045
21062
  }
21046
21063
  } catch (error) {
21047
- console.error('解析存储的AppKey和UserId出错', error);
21064
+ logger.error('解析存储的AppKey和UserId出错', error);
21048
21065
  await this.deleteDatabase();
21049
21066
  }
21050
21067
  }
@@ -21064,11 +21081,11 @@
21064
21081
  const dbName = this.getDBName();
21065
21082
  const deleteRequest = indexedDB.deleteDatabase(dbName);
21066
21083
  deleteRequest.onsuccess = () => {
21067
- console.log(`数据库 ${dbName} 已成功删除`);
21084
+ logger.info(`数据库 ${dbName} 已成功删除`);
21068
21085
  resolve();
21069
21086
  };
21070
21087
  deleteRequest.onerror = event => {
21071
- console.error(`删除数据库 ${dbName} 失败`, event);
21088
+ logger.error(`删除数据库 ${dbName} 失败`, event);
21072
21089
  resolve();
21073
21090
  };
21074
21091
  });
@@ -21081,7 +21098,7 @@
21081
21098
  const dbName = this.getDBName();
21082
21099
  const request = indexedDB.open(dbName, this.DB_VERSION);
21083
21100
  request.onerror = event => {
21084
- console.error('数据库打开失败', event);
21101
+ logger.error('数据库打开失败', event);
21085
21102
  reject(new Error('数据库打开失败'));
21086
21103
  };
21087
21104
  request.onsuccess = event => {
@@ -21089,7 +21106,7 @@
21089
21106
  this.loadAllDialogStates().then(() => {
21090
21107
  resolve();
21091
21108
  }).catch(err => {
21092
- console.error('加载会话状态失败', err);
21109
+ logger.error('加载会话状态失败', err);
21093
21110
  resolve();
21094
21111
  });
21095
21112
  };
@@ -21097,7 +21114,10 @@
21097
21114
  const db = event.target.result;
21098
21115
  if (!db.objectStoreNames.contains(this.STORE_NAME)) {
21099
21116
  const store = db.createObjectStore(this.STORE_NAME, {
21100
- keyPath: 'messageUId'
21117
+ keyPath: 'messageId'
21118
+ });
21119
+ store.createIndex('messageUId', 'messageUId', {
21120
+ unique: true
21101
21121
  });
21102
21122
  store.createIndex('dialogId', 'dialogId', {
21103
21123
  unique: false
@@ -21161,7 +21181,7 @@
21161
21181
  resolve();
21162
21182
  };
21163
21183
  request.onerror = event => {
21164
- console.error('更新会话状态失败', event);
21184
+ logger.error('更新会话状态失败', event);
21165
21185
  reject(new Error('更新会话状态失败'));
21166
21186
  };
21167
21187
  });
@@ -21172,7 +21192,7 @@
21172
21192
  const contentStr = JSON.stringify(content);
21173
21193
  return aes256Encrypt(contentStr, this.encryptKey);
21174
21194
  } catch (error) {
21175
- console.error('加密消息内容失败', error);
21195
+ logger.error('加密消息内容失败', error);
21176
21196
  return '';
21177
21197
  }
21178
21198
  }
@@ -21184,7 +21204,7 @@
21184
21204
  const decryptedStr = aes256Decrypt(encryptedHex, this.encryptKey);
21185
21205
  return JSON.parse(decryptedStr);
21186
21206
  } catch (error) {
21187
- console.error('解密消息内容失败', error);
21207
+ logger.error('解密消息内容失败', error);
21188
21208
  return null;
21189
21209
  }
21190
21210
  }
@@ -21214,7 +21234,7 @@
21214
21234
  resolve();
21215
21235
  };
21216
21236
  transaction.onerror = event => {
21217
- console.error('添加消息事务失败', event);
21237
+ logger.error('添加消息事务失败', event);
21218
21238
  reject(new Error('添加消息事务失败'));
21219
21239
  };
21220
21240
  });
@@ -21257,7 +21277,7 @@
21257
21277
  try {
21258
21278
  message.content = this.decryptContent(message.content);
21259
21279
  } catch (error) {
21260
- console.error('解密消息内容失败', error);
21280
+ logger.error('解密消息内容失败', error);
21261
21281
  message.content = null;
21262
21282
  }
21263
21283
  }
@@ -21281,7 +21301,7 @@
21281
21301
  };
21282
21302
  };
21283
21303
  transaction.onerror = event => {
21284
- console.error('获取消息事务失败', event);
21304
+ logger.error('获取消息事务失败', event);
21285
21305
  reject(new Error('获取消息事务失败'));
21286
21306
  };
21287
21307
  });
@@ -21386,7 +21406,7 @@
21386
21406
  }
21387
21407
  };
21388
21408
  deleteRequest.onerror = event => {
21389
- console.error('删除消息失败', id, event);
21409
+ logger.error('删除消息失败', id, event);
21390
21410
  if (!hasError) {
21391
21411
  hasError = true;
21392
21412
  reject(new Error('删除消息失败'));
@@ -21492,131 +21512,142 @@
21492
21512
  }
21493
21513
  };
21494
21514
  request.onerror = event => {
21495
- console.error('清除过期消息失败', event);
21515
+ logger.error('清除过期消息失败', event);
21496
21516
  reject(new Error('清除过期消息失败'));
21497
21517
  };
21498
21518
  });
21499
21519
  }
21500
- async getMessagesByPage(dialogId, pageSize = 20, cursorPosition = null) {
21520
+ async getLatestMessage(conversation) {
21521
+ const dialogId = getFullDialogId(conversation);
21501
21522
  if (!this.db) {
21502
- return {
21503
- messages: [],
21504
- nextCursor: null
21505
- };
21523
+ return null;
21506
21524
  }
21507
21525
  return new Promise((resolve, reject) => {
21508
21526
  const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21509
21527
  const store = transaction.objectStore(this.STORE_NAME);
21510
21528
  const index = store.index('dialogId_sentTime');
21511
- const range = IDBKeyRange.bound([dialogId, cursorPosition || ''], [dialogId, '\uffff']);
21512
- const messages = [];
21513
- let nextCursor = null;
21514
- let count = 0;
21515
- const cursorRequest = index.openCursor(range);
21529
+ const range = IDBKeyRange.bound([dialogId, ''], [dialogId, '\uffff']);
21530
+ const direction = 'prev';
21531
+ const cursorRequest = index.openCursor(range, direction);
21516
21532
  cursorRequest.onsuccess = event => {
21517
21533
  const cursor = event.target.result;
21518
- if (cursor && count < pageSize) {
21519
- messages.push(cursor.value);
21520
- count++;
21521
- cursor.continue();
21522
- } else if (cursor) {
21523
- nextCursor = cursor.value.sentTime;
21534
+ if (cursor) {
21535
+ const message = {
21536
+ ...cursor.value
21537
+ };
21538
+ if (typeof message.content === 'string' && message.content) {
21539
+ try {
21540
+ message.content = this.decryptContent(message.content);
21541
+ } catch (error) {
21542
+ logger.error('解密消息内容失败', error);
21543
+ message.content = null;
21544
+ }
21545
+ }
21546
+ resolve(message);
21524
21547
  } else {
21525
- nextCursor = null;
21526
- }
21527
- if (!cursor || count >= pageSize) {
21528
- resolve({
21529
- messages,
21530
- nextCursor
21531
- });
21548
+ resolve(null);
21532
21549
  }
21533
21550
  };
21534
21551
  cursorRequest.onerror = event => {
21535
- reject(new Error('获取分页消息失败'));
21552
+ logger.error('获取最新消息失败', event);
21553
+ resolve(null);
21536
21554
  };
21537
21555
  });
21538
21556
  }
21539
- async updateMessagesStatus(messageUIds, newStatus) {
21540
- if (!this.db || messageUIds.length === 0) {
21541
- return;
21557
+ async upsertMessage(message) {
21558
+ if (!this.db) {
21559
+ throw new Error('数据库未初始化');
21542
21560
  }
21543
21561
  return new Promise((resolve, reject) => {
21544
21562
  const transaction = this.db.transaction(this.STORE_NAME, 'readwrite');
21545
21563
  const store = transaction.objectStore(this.STORE_NAME);
21546
- let completed = 0;
21547
- let hasError = false;
21548
- messageUIds.forEach(id => {
21549
- const getRequest = store.get(id);
21550
- getRequest.onsuccess = () => {
21551
- const message = getRequest.result;
21552
- if (message) {
21553
- message.receivedStatus = newStatus;
21554
- store.put(message);
21555
- }
21556
- completed++;
21557
- if (completed === messageUIds.length && !hasError) {
21558
- resolve();
21559
- }
21560
- };
21561
- getRequest.onerror = event => {
21562
- if (!hasError) {
21563
- hasError = true;
21564
- reject(new Error('更新消息状态失败'));
21565
- }
21566
- };
21567
- });
21568
- transaction.oncomplete = () => {
21564
+ const messageToStore = {
21565
+ ...message
21566
+ };
21567
+ if (messageToStore.content) {
21568
+ const encryptedContent = this.encryptContent(messageToStore.content);
21569
+ messageToStore.content = encryptedContent;
21570
+ }
21571
+ const request = store.put(messageToStore);
21572
+ request.onsuccess = () => {
21569
21573
  resolve();
21570
21574
  };
21571
- transaction.onerror = event => {
21572
- reject(new Error('批量更新事务失败'));
21575
+ request.onerror = event => {
21576
+ logger.error('更新/插入消息失败', event);
21577
+ reject(new Error('更新/插入消息失败'));
21573
21578
  };
21574
21579
  });
21575
21580
  }
21576
- async changeUser(appKey, userId) {
21577
- if (this.currentAppKey === appKey && this.currentUserId === userId) {
21578
- return;
21579
- }
21580
- this.currentAppKey = appKey;
21581
- this.currentUserId = userId;
21582
- this.generateEncryptKey(appKey, userId);
21583
- await this.checkAndResetDatabase();
21584
- await this.initDatabase();
21585
- }
21586
- async getLatestMessage(conversation) {
21587
- const dialogId = getFullDialogId(conversation);
21581
+ async getMessageById(messageId) {
21588
21582
  if (!this.db) {
21589
21583
  return null;
21590
21584
  }
21591
21585
  return new Promise((resolve, reject) => {
21592
21586
  const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21593
21587
  const store = transaction.objectStore(this.STORE_NAME);
21594
- const index = store.index('dialogId_sentTime');
21595
- const range = IDBKeyRange.bound([dialogId, ''], [dialogId, '\uffff']);
21596
- const direction = 'prev';
21597
- const cursorRequest = index.openCursor(range, direction);
21598
- cursorRequest.onsuccess = event => {
21599
- const cursor = event.target.result;
21600
- if (cursor) {
21601
- const message = {
21602
- ...cursor.value
21588
+ const request = store.get(messageId);
21589
+ request.onsuccess = () => {
21590
+ const message = request.result;
21591
+ if (message) {
21592
+ const decryptedMessage = {
21593
+ ...message
21603
21594
  };
21604
- if (typeof message.content === 'string' && message.content) {
21595
+ if (typeof decryptedMessage.content === 'string' && decryptedMessage.content) {
21605
21596
  try {
21606
- message.content = this.decryptContent(message.content);
21597
+ decryptedMessage.content = this.decryptContent(decryptedMessage.content);
21607
21598
  } catch (error) {
21608
- console.error('解密消息内容失败', error);
21609
- message.content = null;
21599
+ logger.error('解密消息内容失败', error);
21600
+ decryptedMessage.content = null;
21610
21601
  }
21611
21602
  }
21612
- resolve(message);
21603
+ resolve(decryptedMessage);
21613
21604
  } else {
21614
21605
  resolve(null);
21615
21606
  }
21616
21607
  };
21617
- cursorRequest.onerror = event => {
21618
- console.error('获取最新消息失败', event);
21619
- reject(new Error('获取最新消息失败'));
21608
+ request.onerror = event => {
21609
+ logger.error('查询消息失败', event);
21610
+ resolve(null);
21611
+ };
21612
+ });
21613
+ }
21614
+ async getMessageIdRange() {
21615
+ if (!this.db) {
21616
+ return null;
21617
+ }
21618
+ return new Promise((resolve, reject) => {
21619
+ const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21620
+ const store = transaction.objectStore(this.STORE_NAME);
21621
+ let newest = null;
21622
+ let oldest = null;
21623
+ const oldestRequest = store.openCursor();
21624
+ oldestRequest.onsuccess = event => {
21625
+ const cursor = event.target.result;
21626
+ if (cursor) {
21627
+ oldest = cursor.value.messageId;
21628
+ const newestRequest = store.openCursor(null, 'prev');
21629
+ newestRequest.onsuccess = event => {
21630
+ const cursor = event.target.result;
21631
+ if (cursor) {
21632
+ newest = cursor.value.messageId;
21633
+ if (newest && oldest) {
21634
+ resolve({
21635
+ newest,
21636
+ oldest
21637
+ });
21638
+ } else {
21639
+ resolve(null);
21640
+ }
21641
+ } else {
21642
+ resolve(null);
21643
+ }
21644
+ };
21645
+ } else {
21646
+ resolve(null);
21647
+ }
21648
+ };
21649
+ transaction.onerror = event => {
21650
+ resolve(null);
21620
21651
  };
21621
21652
  });
21622
21653
  }
@@ -21733,16 +21764,29 @@
21733
21764
  webSocketServer.close();
21734
21765
  return Promise.resolve();
21735
21766
  }
21736
- setUserLogged() {
21767
+ async setUserLogged() {
21737
21768
  ConversationManager$1.get().destroyed();
21738
21769
  ConversationManager$1.create(this.options.appkey, accountStore.uid.toString(), this.watcher.conversationState);
21739
21770
  MessageReceiptManager$1.create(this.options.appkey, accountStore.uid.toString());
21740
- MessageCache$1.create(this.options.appkey, accountStore.uid.toString());
21741
21771
  this.messageLoader?.stop();
21742
21772
  this.messageLoader = new MessageLoader(this.watcher, this.options);
21743
21773
  SentMessageStore.reset();
21744
21774
  RecallMessageStore.reset();
21745
21775
  DialogSecretKey$1.reset();
21776
+ MessageCache$1.create(this.options.appkey, accountStore.uid.toString());
21777
+ MessageCache$1.get().initDB().then(() => {
21778
+ return MessageCache$1.get().getMessageIdRange();
21779
+ }).then(result => {
21780
+ if (result) {
21781
+ const {
21782
+ oldest,
21783
+ newest
21784
+ } = result;
21785
+ setInitialMessageId(oldest, newest);
21786
+ } else {
21787
+ setInitialMessageId(10000, 10000);
21788
+ }
21789
+ });
21746
21790
  if (this.getConnectionStatus() === exports.ConnectionStatus.CONNECTED) {
21747
21791
  this.handleUserConnected();
21748
21792
  }
@@ -28386,37 +28430,31 @@
28386
28430
  var protobufjsExports = requireProtobufjs();
28387
28431
  var protobuf = /*@__PURE__*/getDefaultExportFromCjs(protobufjsExports);
28388
28432
 
28389
- const transSentAttrs2IReceivedMessage = (message, options, sentStatus = exports.SentStatus.SENDING) => ({
28390
- conversationType: options.conversation.conversationType,
28391
- targetId: options.conversation.targetId,
28392
- senderUserId: options.senderUserId,
28393
- messageDirection: exports.MessageDirection.SEND,
28394
- isCounted: message.isCounted,
28395
- isMentioned: false,
28396
- content: deepClone(message.content),
28397
- messageType: message.messageType,
28398
- isOffLineMessage: false,
28399
- isPersited: message.isPersited,
28400
- messageId: options.messageId,
28401
- messageUId: '0',
28402
- sentTime: options.sentTime,
28403
- sentStatus,
28404
- receivedTime: '0',
28405
- isStatusMessage: message.isStatusMessage,
28406
- receivedStatus: exports.ReceivedStatus.IDLE,
28407
- disableNotification: true,
28408
- burnAfterReadingFlag: false
28409
- });
28410
-
28411
- let UniqueLocalId = 0;
28412
- function generateMessageId() {
28413
- UniqueLocalId++;
28414
- const time = getServerTime$1();
28415
- if (UniqueLocalId < time) {
28416
- UniqueLocalId = time;
28417
- }
28418
- return 230000000000000 + UniqueLocalId;
28419
- }
28433
+ const transSentAttrs2IReceivedMessage = (message, options, sentStatus = exports.SentStatus.SENDING) => {
28434
+ const conversation = ConversationManager$1.get().get(options.conversation);
28435
+ return {
28436
+ conversationType: options.conversation.conversationType,
28437
+ targetId: options.conversation.targetId,
28438
+ senderUserId: options.senderUserId,
28439
+ messageDirection: exports.MessageDirection.SEND,
28440
+ isCounted: message.isCounted,
28441
+ isMentioned: false,
28442
+ content: deepClone(message.content),
28443
+ messageType: message.messageType,
28444
+ isOffLineMessage: false,
28445
+ isPersited: message.isPersited,
28446
+ messageId: options.messageId,
28447
+ messageUId: "local" + options.sentTime,
28448
+ sentTime: options.sentTime,
28449
+ sentStatus,
28450
+ receivedTime: options.sentTime,
28451
+ isStatusMessage: message.isStatusMessage,
28452
+ receivedStatus: exports.ReceivedStatus.IDLE,
28453
+ disableNotification: true,
28454
+ burnAfterReadingFlag: conversation?.burnAfterReadingFlag ?? false,
28455
+ burnAfterReadingTime: conversation?.burnAfterReadingTime ?? 0
28456
+ };
28457
+ };
28420
28458
 
28421
28459
  const getBlobUrl = blob => {
28422
28460
  const URL = window.URL || window.webkitURL;
@@ -28887,10 +28925,12 @@
28887
28925
  const sentAttris = {
28888
28926
  conversation,
28889
28927
  senderUserId: accountStore.uid,
28890
- messageId: '0',
28928
+ messageId: 0,
28891
28929
  sentTime: getServerTime$1().toString()
28892
28930
  };
28893
28931
  const receivedMessage = transSentAttrs2IReceivedMessage(recallCommandMessage, sentAttris, exports.SentStatus.SENT);
28932
+ receivedMessage.burnAfterReadingFlag = false;
28933
+ receivedMessage.burnAfterReadingTime = 0;
28894
28934
  ConversationManager$1.get().setConversationCacheByMessage(receivedMessage);
28895
28935
  return {
28896
28936
  code: exports.ErrorCode.SUCCESS,
@@ -28939,12 +28979,16 @@
28939
28979
  });
28940
28980
  }
28941
28981
  async function internal_sendMessage(conversation, message, options, uploadOptions) {
28942
- const checkResult = beforeSend(conversation, message, options);
28982
+ const checkResult = await beforeSend(conversation, message, options);
28943
28983
  if (checkResult.code !== exports.ErrorCode.SUCCESS || !checkResult.message || !checkResult.sentArgs) {
28944
28984
  return {
28945
28985
  code: checkResult.code
28946
28986
  };
28947
28987
  }
28988
+ {
28989
+ const receivedMessage = transSentAttrs2IReceivedMessage(checkResult.message, checkResult.sentArgs);
28990
+ await saveSentMessage(receivedMessage, checkResult.sentArgs);
28991
+ }
28948
28992
  let {
28949
28993
  message: sentMessage,
28950
28994
  sentArgs
@@ -28953,30 +28997,30 @@
28953
28997
  const uploadResult = await uploadOptions.task(sentMessage, uploadOptions.files);
28954
28998
  sentMessage = uploadResult.message;
28955
28999
  if (!uploadResult.finished) {
29000
+ const receivedMessage = transSentAttrs2IReceivedMessage(checkResult.message, checkResult.sentArgs, exports.SentStatus.FAILED);
29001
+ await saveSentMessage(receivedMessage, sentArgs);
28956
29002
  return {
28957
29003
  code: exports.ErrorCode.UPLOAD_FILE_FAILED,
28958
- data: transSentAttrs2IReceivedMessage(sentMessage, sentArgs, exports.SentStatus.FAILED)
29004
+ data: receivedMessage
28959
29005
  };
28960
29006
  }
28961
29007
  }
28962
29008
  return send(sentMessage, sentArgs);
28963
29009
  }
28964
- function beforeSend(conversation, message, options) {
28965
- if (!LibLoader.loader || LibLoader.loader.getConnectionStatus() !== exports.ConnectionStatus.CONNECTED) {
28966
- return {
28967
- code: exports.ErrorCode.RC_NET_CHANNEL_INVALID
28968
- };
28969
- }
29010
+ async function beforeSend(conversation, message, options) {
28970
29011
  const mediaAttribute = JSON.stringify(filterNullProperty(message.content));
28971
29012
  if (getByteLength(mediaAttribute) > MAX_MESSAGE_CONTENT_BYTES) {
28972
29013
  return {
28973
29014
  code: exports.ErrorCode.RC_MSG_CONTENT_EXCEED_LIMIT
28974
29015
  };
28975
29016
  }
29017
+ if (message.isPersited) {
29018
+ await ConversationManager$1.get().loadConvsationsIfNotExist([conversation]);
29019
+ }
28976
29020
  const sentArgs = {
28977
29021
  conversation: conversation,
28978
29022
  senderUserId: accountStore.uid,
28979
- messageId: options?.messageId ?? generateMessageId().toString(),
29023
+ messageId: generateNewMessageId(),
28980
29024
  sentTime: getMessageSentTime().toString(),
28981
29025
  pushConfig: options?.pushConfig
28982
29026
  };
@@ -28993,12 +29037,6 @@
28993
29037
  async function send(message, sentArgs) {
28994
29038
  const dialogId = getFullDialogId(sentArgs.conversation);
28995
29039
  const receivedMessage = transSentAttrs2IReceivedMessage(message, sentArgs);
28996
- if (message.isPersited) {
28997
- await ConversationManager$1.get().loadConvsationsIfNotExist([sentArgs.conversation]);
28998
- }
28999
- const conversation = ConversationManager$1.get().get(sentArgs.conversation);
29000
- receivedMessage.burnAfterReadingFlag = conversation?.burnAfterReadingFlag ?? false;
29001
- receivedMessage.burnAfterReadingTime = conversation?.burnAfterReadingTime ?? 0;
29002
29040
  const secretKey = await DialogSecretKey$1.getDialogAesKey(dialogId.toString());
29003
29041
  if (!secretKey) {
29004
29042
  receivedMessage.sentStatus = exports.SentStatus.FAILED;
@@ -29021,7 +29059,7 @@
29021
29059
  const mediaEncryptedString = aes256Encrypt(mediaAttribute, secretKey);
29022
29060
  SentMessageStore.addMessage(sentArgs.messageId);
29023
29061
  const baseParams = {
29024
- localId: Long.fromString(sentArgs.messageId),
29062
+ localId: Long.fromNumber(sentArgs.messageId),
29025
29063
  mediaFlag: message.messageType !== MessageTypes.TEXT,
29026
29064
  mediaConstructor: message.messageType,
29027
29065
  msgPreContent: '',
@@ -29052,9 +29090,10 @@
29052
29090
  receivedMessage.sentTime = response.data.msgSendTime.toString();
29053
29091
  receivedMessage.messageUId = response.data.msgId.toString();
29054
29092
  receivedMessage.sentStatus = exports.SentStatus.SENT;
29055
- ConversationManager$1.get().setConversationCacheByMessage(receivedMessage);
29093
+ await saveSentMessage(receivedMessage, sentArgs);
29056
29094
  } else {
29057
29095
  receivedMessage.sentStatus = exports.SentStatus.FAILED;
29096
+ await saveSentMessage(receivedMessage, sentArgs);
29058
29097
  }
29059
29098
  return {
29060
29099
  code: response.code,
@@ -29070,6 +29109,18 @@
29070
29109
  }
29071
29110
  return UniqueSentTime;
29072
29111
  }
29112
+ async function saveSentMessage(receivedMessage, options) {
29113
+ try {
29114
+ const cache = MessageCache$1.get();
29115
+ if (receivedMessage.isPersited && cache) {
29116
+ await cache.upsertMessage(receivedMessage);
29117
+ const latestMessage = await cache.getLatestMessage(options.conversation);
29118
+ ConversationManager$1.get().updateLatestMessage(options.conversation, latestMessage);
29119
+ }
29120
+ } catch (error) {
29121
+ logger.error('saveSentMessage -> ', error);
29122
+ }
29123
+ }
29073
29124
 
29074
29125
  class IMClient extends EventEmitter {
29075
29126
  options;
@@ -29246,7 +29297,6 @@
29246
29297
  });
29247
29298
  }
29248
29299
  async getPreviousHistoryMessages(conversation, timestamp, count = 20) {
29249
- debugger;
29250
29300
  const cachedResult = await MessageCache$1.get().getPreviousMessages(conversation, timestamp ?? '0', count);
29251
29301
  if (!timestamp && cachedResult.messages.length) {
29252
29302
  ConversationManager$1.get().updateLatestMessage(conversation, cachedResult.messages[cachedResult.messages.length - 1]);
@@ -29270,8 +29320,13 @@
29270
29320
  return remotesResult;
29271
29321
  }
29272
29322
  const remotesMessages = remotesResult.data.list;
29323
+ for (let i = remotesMessages.length - 1; i >= 0; i--) {
29324
+ const message = remotesMessages[i];
29325
+ if (!message.messageId) {
29326
+ message.messageId = generateOldMessageId();
29327
+ }
29328
+ }
29273
29329
  if (!remotesTimestamp || remotesTimestamp == '0') {
29274
- debugger;
29275
29330
  ConversationManager$1.get().updateLatestMessage(conversation, remotesMessages[remotesMessages.length - 1]);
29276
29331
  }
29277
29332
  MessageCache$1.get().addMessages(remotesMessages, conversation, !remotesResult.data.hasMore);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onyx-p/imlib-web",
3
- "version": "2.2.3",
3
+ "version": "2.2.5",
4
4
  "main": "index.umd.js",
5
5
  "module": "index.esm.js",
6
6
  "types": "types/index.d.ts",
@@ -75,7 +75,7 @@ export default interface IReceivedMessage {
75
75
  /**
76
76
  * CPP 独有字段 消息本地 ID
77
77
  */
78
- messageId?: string;
78
+ messageId: number;
79
79
  /**
80
80
  * 消息发送状态
81
81
  */