k2-im 0.2.8 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/im-browser/src/http/application-http-adapters.js +1 -1
- package/dist/modules/im-browser/src/http/requests/pull-offline-channel.js +1 -1
- package/dist/modules/im-chat-kit/src/pinia/applications.store.js +1 -1
- package/dist/modules/im-chat-kit/src/vue/thread/ImThreadViewport.js +1 -1
- package/dist/modules/im-core/src/mapping/merge.js +1 -1
- package/dist/modules/im-core/src/state/conversation-deletion-boundary.js +1 -0
- package/dist/modules/im-core/src/state/domain-state.js +1 -1
- package/dist/modules/im-sdk/src/runtime/recent-history-fetcher.js +1 -1
- package/dist/modules/im-sdk/src/runtime/session-runtime.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,n,i)=>((t,n,i)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[n]=i)(t,"symbol"!=typeof n?n+"":n,i);import{getApplicationPage as n,ignoreApplication as i,acceptApplication as r}from"./requests/applications.js";class a extends Error{constructor(e,n){super(`application HTTP 失败(${e}):${n||"unknown error"}`),t(this,"code"),this.code=e,this.name="ApplicationHttpError"}}class o extends Error{constructor(e){super(`application 映射失败:${e}`),this.name="ApplicationMappingError"}}function s(e){return"string"==typeof e||"number"==typeof e?String(e).trim():""}function u(e){const t=s(e);if(""===t)return;if(/^\d+$/.test(t)){const e=Number(t);if(!Number.isSafeInteger(e)||e<=0)return;return t.length>=13?e:1e3*e}const n=Date.parse(t);return Number.isFinite(n)?n:void 0}function c(e){const t=s(e.status);if(void 0===e.status||""===t)return!0;const n=function(e){switch(e){case 0:case 1:case 2:return e;default:return}}(Number(t));if(void 0===n)throw new o(`未知申请状态:${t}`);return 0===n}function p(e){const t=s(e.type);if(""===t)return!0;if(1!==Number(t))throw new o(`联系人申请页出现未知 type:${t}`);return!0}function l(e){const t=Number(s(e.type));if(2!==t&&3!==t&&4!==t&&5!==t)throw new o(`GROUP/CHANNEL 混合页出现未知 type:${s(e.type)||"<empty>"}`);return t}function f(e){if(!Number.isInteger(e.limit)||e.limit<=0||e.limit>50)throw new o("limit 必须为 1-50");if(void 0===e.cursor)return{page:1,pageSize:e.limit};if(!/^[1-9]\d*$/.test(e.cursor))throw new o("page cursor 必须为正十进制整数");const t=Number(e.cursor);if(!Number.isSafeInteger(t))throw new o("page cursor 超出安全整数范围");return{page:t,pageSize:e.limit}}function m(e){if(null!=e&&Array.isArray(e.list))return e.list;const t=e?.count??e?.total,n=0===t||"string"==typeof t&&/^0+$/.test(t.trim());if(null===e?.list&&n)return[];throw new o("data.list 必须是数组,或在 count=0 时为 null")}function d(e){const t=e.trim();if(""===t)throw new o("申请记录 id 不能为空");return t}function g(e){const t=d(s(e.id)||s(e.aid)),n=s(e.user_id)||s(e.user_info?.user_id),i=s(e.nick_name
|
|
1
|
+
var e=Object.defineProperty,t=(t,n,i)=>((t,n,i)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[n]=i)(t,"symbol"!=typeof n?n+"":n,i);import{getApplicationPage as n,ignoreApplication as i,acceptApplication as r}from"./requests/applications.js";class a extends Error{constructor(e,n){super(`application HTTP 失败(${e}):${n||"unknown error"}`),t(this,"code"),this.code=e,this.name="ApplicationHttpError"}}class o extends Error{constructor(e){super(`application 映射失败:${e}`),this.name="ApplicationMappingError"}}function s(e){return"string"==typeof e||"number"==typeof e?String(e).trim():""}function u(e){const t=s(e);if(""===t)return;if(/^\d+$/.test(t)){const e=Number(t);if(!Number.isSafeInteger(e)||e<=0)return;return t.length>=13?e:1e3*e}const n=Date.parse(t);return Number.isFinite(n)?n:void 0}function c(e){const t=s(e.status);if(void 0===e.status||""===t)return!0;const n=function(e){switch(e){case 0:case 1:case 2:return e;default:return}}(Number(t));if(void 0===n)throw new o(`未知申请状态:${t}`);return 0===n}function p(e){const t=s(e.type);if(""===t)return!0;if(1!==Number(t))throw new o(`联系人申请页出现未知 type:${t}`);return!0}function l(e){const t=Number(s(e.type));if(2!==t&&3!==t&&4!==t&&5!==t)throw new o(`GROUP/CHANNEL 混合页出现未知 type:${s(e.type)||"<empty>"}`);return t}function f(e){if(!Number.isInteger(e.limit)||e.limit<=0||e.limit>50)throw new o("limit 必须为 1-50");if(void 0===e.cursor)return{page:1,pageSize:e.limit};if(!/^[1-9]\d*$/.test(e.cursor))throw new o("page cursor 必须为正十进制整数");const t=Number(e.cursor);if(!Number.isSafeInteger(t))throw new o("page cursor 超出安全整数范围");return{page:t,pageSize:e.limit}}function m(e){if(null!=e&&Array.isArray(e.list))return e.list;const t=e?.count??e?.total,n=0===t||"string"==typeof t&&/^0+$/.test(t.trim());if(null===e?.list&&n)return[];throw new o("data.list 必须是数组,或在 count=0 时为 null")}function d(e){const t=e.trim();if(""===t)throw new o("申请记录 id 不能为空");return t}function g(e){const t=d(s(e.id)||s(e.aid)),n=s(e.user_id)||s(e.user_info?.user_id),i=s(e.nick_name)||s(e.nickname)||s(e.name)||s(e.user_info?.nick_name)||s(e.user_info?.nickname)||s(e.user_info?.name);if(""===n||""===i)throw new o(`联系人申请人身份不能为空(applicationId=${t})`);const r=s(e.head_img_url)||s(e.avatar)||s(e.user_info?.head_img_url)||s(e.user_info?.avatar),a=s(e.user_info?.mid),c=u(e.create_time??e.createTime??e.update_version);return{applicationId:t,applicantId:n,applicantName:i,...""===r?{}:{applicantAvatar:r},...""===a?{}:{applicantDisplayId:a},message:s(e.remarks)||s(e.introduce_self),...void 0===c?{}:{createdAt:c}}}function _(e){const t=d(s(e.id)||s(e.aid)),n=s(e.group_id)||s(e.group_info?.group_id);if(""===n)throw new o(`GROUP id 不能为空(applicationId=${t})`);const i=s(e.user_id)||s(e.user_info?.user_id),r=s(e.nick_name)||s(e.nickname)||s(e.name)||s(e.user_info?.nick_name)||s(e.user_info?.nickname)||s(e.user_info?.name);if(""===i||""===r)throw new o(`GROUP 申请人或邀请人身份不能为空(applicationId=${t})`);const a=s(e.head_img_url)||s(e.avatar)||s(e.user_info?.head_img_url)||s(e.user_info?.avatar),c=s(e.user_info?.mid),p=s(e.group_info?.name)||s(e.group_info?.group_name);if(""===p)throw new o(`GROUP 名称不能为空(applicationId=${t})`);const l=s(e.group_info?.head_img_url)||s(e.group_info?.avatar),f=u(e.create_time??e.createTime??e.update_version);return{applicationId:t,groupId:n,kind:3===Number(e.type)?"invite":"request",actor:{id:i,name:r,...""===a?{}:{avatarUrl:a},...""===c?{}:{displayId:c}},target:{id:n,name:p,...""===l?{}:{avatarUrl:l}},message:s(e.remarks)||s(e.introduce_self),...void 0===f?{}:{createdAt:f}}}async function w(e,t,n){const i=await n(e.client,{applicationId:d(t),clientType:e.clientType});if(!i.ok)throw new a(i.code,i.message)}function h(e){return{listPendingApplications:async function(t){const{pageSize:i}=f(t);let{page:r}=f(t);for(let t=0;t<20;t+=1){const t=await n(e.client,{listType:1,page:r,pageSize:i,clientType:e.clientType});if(!t.ok)throw new a(t.code,t.message);const o=m(t.data),s=o.filter(e=>p(e)&&c(e)).map(g),u=o.length<i,l=r+1;if(s.length>0||u)return{items:s,exhausted:u,...u?{}:{nextCursor:String(l)}};r=l}return{items:[],exhausted:!1,nextCursor:String(r)}},acceptApplication:t=>w(e,t,r),ignoreApplication:t=>w(e,t,i)}}function y(e){return{listPendingApplications:async function(t){const{pageSize:i}=f(t);let{page:r}=f(t);for(let t=0;t<20;t+=1){const t=await n(e.client,{listType:2,page:r,pageSize:i,clientType:e.clientType});if(!t.ok)throw new a(t.code,t.message);const o=m(t.data),s=o.filter(e=>{const t=l(e);return(2===t||3===t)&&c(e)}).map(_),u=o.length<i,p=r+1;if(s.length>0||u)return{items:s,exhausted:u,...u?{}:{nextCursor:String(p)}};r=p}return{items:[],exhausted:!1,nextCursor:String(r)}},acceptApplication:t=>w(e,t,r),ignoreApplication:t=>w(e,t,i)}}export{a as ApplicationHttpError,o as ApplicationMappingError,h as createContactApplicationHttpAdapter,y as createGroupApplicationHttpAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{encodeChannelSessionsRequest as e,decodeChannelSessionsResponse as n,encodeChannelMessagesRequest as o,decodeChannelMessagesResponse as t,decodeChannelMessagesResponseAsync as a,encodeChannelHistoryRequest as s,decodeChannelHistoryResponse as i}from"../../../../im-core/src/mapping/channel-offline-mapper.js";import{throwIfAborted as r}from"../../../../im-core/src/abort.js";import{
|
|
1
|
+
import{encodeChannelSessionsRequest as e,decodeChannelSessionsResponse as n,encodeChannelMessagesRequest as o,decodeChannelMessagesResponse as t,decodeChannelMessagesResponseAsync as a,encodeChannelHistoryRequest as s,decodeChannelHistoryResponse as i}from"../../../../im-core/src/mapping/channel-offline-mapper.js";import{throwIfAborted as r}from"../../../../im-core/src/abort.js";import{pullChannelMessagesRespCodec as c}from"../../../../im-protocol/src/protobuf/registry.js";import{compareBySortKey as d}from"../../../../im-core/src/mapping/sort.js";async function l(o){const t=[];for(const a of u(o.channels,20)){const s=e({userId:o.userId,clientType:o.clientType,channels:a}),i=await o.http.postProtobuf({path:"/channel/v1/sessions",body:s}),r={selfId:o.userId,keepRaw:o.keepRaw??!0,expectedChannelIds:a.map(e=>e.channelId),diagnostic:{endpoint:"sessions",surface:"session-last",...void 0===o.operationId?{}:{operationId:o.operationId},clientTypeHeader:o.clientType,clientTypeBody:o.clientType}},c=n(i,r);await f(o,c.sessions.filter(e=>"active"===e.channelState||0===e.raw?.status).map(e=>e.channelId)),t.push(...n(i,{...r,onContentDecodeError:o.onContentDecodeError,onReaction:o.onReaction},o.decryptDeps).sessions)}return t}async function p(e){const n=function(e){if(void 0===e)return 10;if(!Number.isInteger(e)||e<=0)throw new Error("channel offline: channelBatchSize 必须为正整数");return Math.min(e,10)}(e.channelBatchSize),s=e.messageCount??30,i=function(e){if(void 0===e)return 100;if(!Number.isInteger(e)||e<=0)throw new Error("channel offline: maxPagesPerBatch 必须为正整数");return e}(e.maxPagesPerBatch),c=/* @__PURE__ */new Map;for(const d of u(e.pulls,n)){let n=d.map(e=>({...e}));const l=new Map(n.map(e=>[e.channelId,/* @__PURE__ */new Set([e.baseIndex])]));let p=0;for(;n.length>0;){r(e.signal),await(e.beforePage?.()),r(e.signal);const d=e.isChannelCurrent;if(void 0!==d&&(n=n.filter(e=>d(e.channelId))),0===n.length)break;if(p>=i){const e=n.map(({channelId:e,baseIndex:n})=>`${e}@${n}`).join(",");throw new Error(`channel offline 分页超过 maxPagesPerBatch=${i}(active=${e})`)}p+=1;const h=o({userId:e.userId,clientType:e.clientType,pulls:n.map(e=>({channelId:e.channelId,baseIndex:e.baseIndex,direction:0,count:s,contain:0}))});r(e.signal);const I=await e.http.postProtobuf({path:"/channel/v1/offlineMessages",body:h,...void 0===e.signal?{}:{signal:e.signal}});r(e.signal),await f(e,n.map(e=>e.channelId)),r(e.signal);const u={selfId:e.userId,keepRaw:e.keepRaw??!0,expectedChannelIds:n.map(e=>e.channelId),diagnostic:{endpoint:"offlineMessages",surface:"offline-batch",...void 0===e.operationId?{}:{operationId:e.operationId},clientTypeHeader:e.clientType,clientTypeBody:e.clientType},onContentDecodeError:e.onContentDecodeError,onReaction:e.onReaction},g=void 0===e.yieldToEventLoop?t(I,u,e.decryptDeps):await a(I,u,e.decryptDeps,{yieldToEventLoop:e.yieldToEventLoop,signal:e.signal});r(e.signal);const y=[];for(const e of n){const n=g.nextBaseIndexes[e.channelId],o=g.messageCounts[e.channelId]??0;if(void 0===n)continue;const t=l.get(e.channelId);if(t.has(n))throw new Error(`channel offline cursor 循环(channelId=${e.channelId}, baseIndex=${n})`);o<s||(t.add(n),y.push({channelId:e.channelId,baseIndex:n}))}await(e.onPage?.(g.messages,{pulls:n.map(e=>({...e})),nextBaseIndexes:{...g.nextBaseIndexes},messageCounts:{...g.messageCounts}})),r(e.signal);for(const e of g.messages)c.has(e.id)||c.set(e.id,e);n=y}}return[...c.values()].sort(d)}async function h(e){r(e.signal);const n=e.count??30;if(!Number.isInteger(n)||n<=0)throw new Error("channel latest: count 必须为正整数");void 0!==e.decryptDeps&&void 0!==e.prepareKey&&await e.prepareKey(e.channelId);const s=o({userId:e.userId,clientType:e.clientType,pulls:[{channelId:e.channelId,baseIndex:"",direction:1,count:n,contain:0}]});r(e.signal);const i=await e.http.postProtobuf({path:"/channel/v1/offlineMessages",body:s,...void 0===e.signal?{}:{signal:e.signal}});r(e.signal);const d={selfId:e.userId,keepRaw:e.keepRaw??!0,expectedChannelIds:[e.channelId],diagnostic:{endpoint:"offlineMessages",surface:"history-page",...void 0===e.operationId?{}:{operationId:e.operationId},clientTypeHeader:e.clientType,clientTypeBody:e.clientType},onContentDecodeError:e.onContentDecodeError,onReaction:e.onReaction},l=void 0===e.yieldToEventLoop?{...t(i,d,e.decryptDeps),firstBaseIndex:c.decode(i).lsMessage[0]?.sIndex}:await a(i,d,e.decryptDeps,{yieldToEventLoop:e.yieldToEventLoop,signal:e.signal}),p=l.batchSize===n,h=l.firstBaseIndex;if(p&&("string"!=typeof h||""===h.trim()))throw new Error(`channel latest: 满页缺少向旧 cursor(channelId=${e.channelId})`);return{messages:l.messages,hasOlder:p,...p?{nextCursor:h}:{}}}async function I(e){r(e.signal);const n=e.count??30;void 0!==e.decryptDeps&&void 0!==e.prepareKey&&await e.prepareKey(e.channelId);const o=s({userId:e.userId,clientType:e.clientType,channelId:e.channelId,baseIndex:e.baseIndex,count:n,contain:e.contain??0});r(e.signal);const t=await e.http.postProtobuf({path:"/channel/v1/offlineMessages",body:o,...void 0===e.signal?{}:{signal:e.signal}});r(e.signal);return i(t,{selfId:e.userId,channelId:e.channelId,requestedBaseIndex:e.baseIndex,requestedCount:n,keepRaw:e.keepRaw??!0,diagnostic:{endpoint:"history",surface:"history-page",...void 0===e.operationId?{}:{operationId:e.operationId},clientTypeHeader:e.clientType,clientTypeBody:e.clientType},onContentDecodeError:e.onContentDecodeError,onReaction:e.onReaction},e.decryptDeps)}async function f(e,n){if(void 0===e.decryptDeps||void 0===e.prepareKeys)return;const o=[...new Set(n.filter(Boolean))];o.length>0&&await e.prepareKeys(o)}function u(e,n){const o=[];for(let t=0;t<e.length;t+=n)o.push(e.slice(t,t+n));return o}export{I as pullChannelHistory,h as pullChannelLatestPage,p as pullChannelOfflineMessages,l as pullChannelSessions};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineStore as e}from"pinia";import{ref as t,shallowRef as
|
|
1
|
+
import{defineStore as e}from"pinia";import{ref as t,shallowRef as n,computed as o}from"vue";import{getImChatKitContext as a,registerImChatKitStoreDisposer as r,resolveImChatKitPinia as i}from"./context.js";function c(e){return`${e.domain}:${e.applicationId}`}function l(e,t){const n="object"==typeof e&&null!==e?e:null;return Object.freeze({code:null!==n&&"string"==typeof n.code?n.code:"IM_CHAT_KIT_APPLICATIONS_ACTION_FAILED",category:null!==n&&(o=n.category,"auth"===o||"network"===o||"protocol"===o||"permission"===o||"validation"===o||"state"===o||"unsupported"===o||"contract"===o)?n.category:"state",operation:null!==n&&"string"==typeof n.operation?n.operation:`applications.${t}`,retryable:null!==n&&"boolean"==typeof n.retryable?n.retryable:"reload"===t});var o}function u(r){return e("k2-im-applications",()=>{const e=a(r).runtime,i=t([]),u=t(!1),p=n(null),s=t({}),f=n({}),d=o(()=>i.value.length),v=o(()=>{let e=0,t=0,n=0;for(const o of i.value)"contact"===o.ref.domain?e+=1:"group"===o.ref.domain?t+=1:n+=1;return Object.freeze({contact:e,group:t,channel:n})});let g=!1,b=0,O=0,j=0,y=0,z=0,I=!1;const m=/* @__PURE__ */new Map;function k(){b+=1,O+=1,j+=1,y+=1,z=0,I=!1,m.clear(),i.value=[],u.value=!1,p.value=null,s.value={},f.value={}}function h(t){return{client:t,generation:e.getGeneration(),stateEpoch:b}}function A(t){return!g&&t.client===e.getProductClient()&&t.generation===e.getGeneration()&&t.stateEpoch===b}async function _(){if(g)return Object.freeze({ok:!1,operation:"reload",reason:"stale"});z+=1;const t=++O;let n;try{n=h(e.ensureProductClient())}catch(e){const t=l(e,"reload");return p.value=t,u.value=!1,Object.freeze({ok:!1,operation:"reload",reason:"failed",error:t})}u.value=!0,p.value=null;try{const e=await n.client.applications.listPending();return t===O&&A(n)?(i.value=Object.freeze([...e]),Object.freeze({ok:!0,operation:"reload"})):Object.freeze({ok:!1,operation:"reload",reason:"stale"})}catch(e){if(t!==O||!A(n))return Object.freeze({ok:!1,operation:"reload",reason:"stale"});const o=l(e,"reload");return p.value=o,Object.freeze({ok:!1,operation:"reload",reason:"failed",error:o})}finally{t===O&&A(n)&&(u.value=!1)}}function P(){if(g)return;const t=b,n=e.getGeneration(),o=e.getProductClient(),a=z,r=++y;queueMicrotask(()=>{r===y&&(g||t!==b||n!==e.getGeneration()||o!==e.getProductClient()||a!==z||_())})}const C=e.subscribeProductEvents(function(e){if("connection:changed"===e.type){const t="authenticated"===e.snapshot.connectionState;return t&&!I&&z>0&&P(),void(I=t)}"contact-application:received"!==e.type&&"channel-join-application:received"!==e.type&&"application:updated"!==e.type||P()});async function E(t,n){const o="contact"===(a=t).domain?Object.freeze({domain:"contact",applicationId:a.applicationId}):"group"===a.domain?Object.freeze({domain:"group",applicationId:a.applicationId,conversation:Object.freeze({conversationType:"group",conversationId:a.conversation.conversationId})}):Object.freeze({domain:"channel",applicationId:a.applicationId,conversation:Object.freeze({conversationType:"channel",conversationId:a.conversation.conversationId})});var a;const r=c(o);if(g)return Object.freeze({ok:!1,operation:n,reason:"stale",application:o});const p=++j;m.set(r,p),s.value={...s.value,[r]:n};const{[r]:d,...v}=f.value;let b;f.value=v;try{b=h(e.ensureProductClient())}catch(e){const t=l(e,n);f.value={...f.value,[r]:t};const{[r]:a,...i}=s.value;return s.value=i,m.delete(r),Object.freeze({ok:!1,operation:n,reason:"failed",application:o,error:t})}const y=()=>A(b)&&m.get(r)===p;try{return await b.client.applications[n](o),y()?(O+=1,u.value=!1,i.value=Object.freeze(i.value.filter(e=>c(e.ref)!==r)),Object.freeze({ok:!0,operation:n,application:o})):Object.freeze({ok:!1,operation:n,reason:"stale",application:o})}catch(e){if(!y())return Object.freeze({ok:!1,operation:n,reason:"stale",application:o});const t=l(e,n);return function(e){return"IM_SDK_APPLICATION_REQUEST_ALREADY_HANDLED"===e.code||"IM_SDK_APPLICATION_ALREADY_HANDLED"===e.code}(t)?(O+=1,u.value=!1,i.value=Object.freeze(i.value.filter(e=>c(e.ref)!==r)),Object.freeze({ok:!1,operation:n,reason:"failed",application:o,error:t})):(f.value={...f.value,[r]:t},Object.freeze({ok:!1,operation:n,reason:"failed",application:o,error:t}))}finally{if(y()){m.delete(r);const{[r]:e,...t}=s.value;s.value=t}}}return{items:i,loading:u,error:p,processingKeys:s,itemErrors:f,pendingCount:d,domainCounts:v,reload:_,accept:function(e){return E(e,"accept")},ignore:function(e){return E(e,"ignore")},reset:function(){g||k()},dispose:function(){g||(g=!0,C(),k())}}})}const p=/* @__PURE__ */new WeakMap,s=/* @__PURE__ */new WeakMap;function f(e=i()){a(e);let t=p.get(e);void 0===t&&(t=u(e),p.set(e,t));const n=t(e);return s.get(e)!==n&&(s.set(e,n),r(e,()=>{n.dispose(),n.$dispose(),s.get(e)===n&&s.delete(e)})),n}export{c as applicationKey,f as useImApplicationsStore};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineComponent as e,ref as t,provide as o,watch as n,nextTick as i,onMounted as l,onBeforeUnmount as r,computed as s,h as a}from"vue";import{resolveImThreadActiveDate as c}from"../../thread/active-date.js";import{createNewMessageBadgeController as d}from"../../thread/new-message-badge.js";import{refreshPrependMessageAnchorPosition as u,isMessageVisibleForNewMessageBadge as v,resolvePrependMessageAnchorPosition as f,resolveCenteredMessageScrollTop as p,shouldPrefetchOlderHistory as h,shouldLoadNewerHistoryPage as g,resolvePrependMessageAnchorAdjustment as m}from"../../thread/viewport-rules.js";import{createThreadIdleTask as b}from"./thread-idle-task.js";import{createThreadLayoutMeasurements as y}from"./thread-layout-measurements.js";import{THREAD_VIEWPORT_REGISTRATION_KEY as T}from"./thread-viewport-context.js";const w=.5;function M(e){const t=e.ownerDocument.defaultView?.devicePixelRatio;return 1+1/(void 0!==t&&Number.isFinite(t)&&t>0?t:1)}const O=e({name:"ImThreadViewport",props:{messageIds:{type:Array,required:!0},contentKey:{type:String,default:""},loadingOlder:{type:Boolean,default:!1},hasNewer:{type:Boolean,default:!1},loadingNewer:{type:Boolean,default:!1},followThreshold:{type:Number,default:120},olderPrefetchThreshold:{type:Number,default:120},followNewMessages:{type:Boolean,default:!0},shouldFollowAppendedMessage:{type:Function,default:void 0},pendingSendMessageIds:{type:Array,default:()=>[]},visibleMargin:{type:Number,default:8},resizeFollowEnabled:{type:Boolean,default:!0},activeDateOffset:{type:Number,default:16},activeDateEnabled:{type:Boolean,default:!1}},emits:{"reach-start":()=>!0,"reach-end":()=>!0,"visible-range":e=>!0,settled:e=>!0,"new-message-count":e=>!0,"user-scroll":()=>!0,"active-date-change":e=>!0},setup(e,{emit:O,expose:H,slots:x}){const E=t(null),N=t(null),L=/* @__PURE__ */new Map;let B;const P=/* @__PURE__ */new Map,A=/* @__PURE__ */new Set,R=/* @__PURE__ */new Map;let S,C,F,I,k=0,D=[];const Y=y({requestFrame:xe,observe:e=>F?.observe(e),unobserve:e=>{e===E.value||e===N.value||P.has(e)||F?.unobserve(e)}});let j,z,U=!1;const V=/* @__PURE__ */new Set;let q,K=!1,W=0,$="",G=1,J=!1,Q=!1,X=!0,Z=!1,_=!1,ee=!0,te=!1,oe=0,ne=-1,ie=-1;const le=b();let re,se,ae,ce;const de=t(!0),ue=t(0),ve=d(e=>{ue.value=e,O("new-message-count",e)});function fe(t){const o=Number.isFinite(e.followThreshold)?Math.max(0,e.followThreshold):0;return t.scrollHeight-t.clientHeight-t.scrollTop<=o}function pe(t=e.messageIds){return t.flatMap(e=>{const t=L.get(e);if(void 0===t)return[];const o=t.getBoundingClientRect(),n=t.querySelector("[data-im-thread-anchor-point]");return[{id:e,top:o.top,bottom:o.bottom,anchorTop:n?.getBoundingClientRect().top??o.top}]})}function he(e="",t=1){const o=Math.min(1,Math.max(0,t));""!==$&&$!==e&&R.get($)?.element.style.removeProperty("opacity"),$=e,G=o,""!==e&&R.get(e)?.element.style.setProperty("opacity",String(o))}function ge(){he()}function me(){const t=E.value;if(K||null===t||!e.activeDateEnabled)return;const o=[...R.entries()].filter(([,e])=>t.contains(e.element)).map(([e,t])=>{const o=t.element.getBoundingClientRect();return{key:e,label:t.label,top:o.top,height:o.height}}).sort((e,t)=>e.top-t.top),n=t.getBoundingClientRect(),i=o.find(e=>e.height>0)?.height??28,l=c({markers:o,viewportTop:n.top,overlayTop:Number.isFinite(e.activeDateOffset)?Math.max(0,e.activeDateOffset):0,overlayHeight:i});if(null===l)return ge(),void O("active-date-change",null);he(l.inlineDateKey,l.inlineOpacity),O("active-date-change",l)}function be(e){C={scrollTop:e.scrollTop,scrollHeight:e.scrollHeight,width:e.clientWidth,height:e.clientHeight}}function ye(e){const t=C;if(void 0===t)return!1;const o=Math.max(0,e.scrollHeight-e.clientHeight);return o<t.scrollHeight-t.height&&t.scrollTop>o&&Math.abs(e.scrollTop-o)<=M(e)}function Te(e){return e.scrollTop<0||e.scrollTop>Math.max(0,e.scrollHeight-e.clientHeight)+M(e)}function we(e){return ye(e)||void 0!==q&&("smooth"===q.behavior||Math.abs(e.scrollTop-q.targetTop)<=M(e))?0:e.scrollTop-k}function Me(e,t){0!==t&&(k=e.scrollTop-t,q=void 0,Se(!0))}function Oe(t,o){const n=we(t);if(void 0!==ae)return ae.expectedOffset-=n,Ye(),Me(t,n),Z||Ue(),!1;const i=C;if(void 0===i)return!1;const l=S,r=void 0===l?void 0:pe([l.id])[0],s=t.scrollTop-i.scrollTop,a=ye(t)?0:s,c=void 0===l||void 0===r?0:(r.anchorTop??r.top)-o.top-l.offset+s;return(i.scrollHeight!==t.scrollHeight||i.width!==t.clientWidth||i.height!==t.clientHeight||Math.abs(c)>w)&&(C=void 0,!(J||Q||e.loadingOlder||e.loadingNewer||e.hasNewer||!e.resizeFollowEnabled||Te(t))&&de.value&&Math.abs(a)<=w?(lt(),!0):(void 0!==l&&function(e){const t=E.value;if(null===t||void 0===e)return;if(Te(t))return void Ve(e);const o=t.getBoundingClientRect(),n=m(e,pe([e.id]),{top:o.top,bottom:o.bottom});if(void 0!==n){const e=Math.max(0,t.scrollHeight-t.clientHeight),o=Math.min(e,Math.max(0,t.scrollTop+n));Fe(o),t.scrollTop=o,k=t.scrollTop,C=void 0}}({...l,offset:l.offset-a}),Me(t,n),!1))}function He(){const t=E.value;if(K||null===t)return;const o=t.getBoundingClientRect();if(Oe(t,o))return;const n=pe(void 0!==j&&U?e.messageIds.filter(e=>A.has(e)):e.messageIds);if(void 0!==j&&U&&0===n.length)return void(de.value=fe(t));const i=n.filter(t=>v({viewportTop:o.top,viewportBottom:o.bottom,messageTop:t.top,messageBottom:t.bottom,margin:e.visibleMargin})).map(e=>e.id),l=i.length!==D.length||i.some((e,t)=>D[t]!==e);D=Object.freeze(i),S=f(n,{top:o.top,bottom:o.bottom}),be(t),ve.acknowledgeVisible(i),de.value=fe(t),l&&O("visible-range",D),O("settled",{visibleMessageIds:D,...0===D.length?{}:{newestVisibleMessageId:D[D.length-1]},isAtBottom:de.value,newMessageCount:ue.value})}function xe(e){if(V.add(e),void 0!==z)return;const t=()=>{z=void 0;const e=[...V];V.clear(),e.forEach(e=>e())};z="function"==typeof globalThis.requestAnimationFrame?globalThis.requestAnimationFrame(t):globalThis.setTimeout(t,0)}function Ee(){xe(He)}function Ne(){const e=E.value;if(null===e)return;const t=e.getBoundingClientRect(),o=f(pe(),{top:t.top,bottom:t.bottom});void 0!==o&&(S=o,be(e))}function Le(){return X&&void 0===ae&&!Q&&!e.loadingOlder}function Be(){Ne(),X=!1,ne=oe,Q=!0,de.value=!1,O("reach-start"),xe(()=>{e.loadingOlder||(Q=!1)})}function Pe(t){return e.hasNewer&&!J&&!e.loadingOlder&&!e.loadingNewer&&fe(t)}function Ae(){Ne(),J=!0,de.value=!1,ie=oe,O("reach-end"),xe(()=>{e.loadingNewer||(J=!1)})}function Re(){const e=E.value;null!==e&&oe!==ie&&Pe(e)&&Ae()}function Se(t=!1){const o=E.value;if(K||null===o)return;const n=o.scrollTop,i=Math.max(0,o.scrollHeight-o.clientHeight),l=Math.min(i,Math.max(0,k)),r=Math.min(i,Math.max(0,n)),s=ye(o),a=q;let c=!1;if(void 0!==a){const e=Math.abs(n-a.targetTop)<=M(o);c="smooth"===a.behavior||e,("smooth"!==a.behavior||e)&&(q=void 0)}c||s||Z||!ee||void 0!==ae||n===k||(Z=!0,_=!0,oe+=1);const d=Z&&!c&&!s&&n!==k;d&&(W+=1,O("user-scroll"),xe(me)),Z&&!te&&Je(),!X&&_&&oe!==ne&&n<k&&n>qe()&&We(),void 0===ae||c||(Z?s||t||(ae.expectedOffset-=n-k):(Ye(),Ue())),Le()&&d&&h({previousScrollTop:l,currentScrollTop:r,topThreshold:e.olderPrefetchThreshold})&&Be(),d&&Pe(o)&&g({previousScrollTop:l,currentScrollTop:r,isAtBottom:fe(o),isHistoryWindow:e.hasNewer,isPageSettling:c})&&Ae(),k=n,Ee()}function Ce(){Se()}function Fe(e,t="auto"){q={targetTop:e,behavior:t}}function Ie(e){const t=ae,o=N.value;if(void 0!==t&&null!==o){if(t.visualOffset=Math.abs(e)<=w?0:e,0===t.visualOffset)return o.style.removeProperty("transform"),void o.style.removeProperty("will-change");o.style.setProperty("transform",`translate3d(0, ${t.visualOffset}px, 0)`),o.style.setProperty("will-change","transform")}}function ke(){void 0!==ce&&(clearTimeout(ce),ce=void 0),void 0!==ae&&0!==ae.visualOffset&&(S=void 0,C=void 0);const e=N.value;e?.style.removeProperty("transform"),e?.style.removeProperty("will-change"),ae=void 0,q=void 0}function De(){const e=E.value,t=ae;if(null===e||void 0===t)return;const o=L.get(t.anchor.id);if(void 0===o)return;return(o.querySelector("[data-im-thread-anchor-point]")??o).getBoundingClientRect().top-e.getBoundingClientRect().top}function Ye(){const e=ae,t=De();if(void 0===e||void 0===t)return;const o=e.expectedOffset-t;if(Math.abs(o)<=w)return;const n=E.value;null!==n&&ye(n)&&(k=n.scrollTop),Ie(e.visualOffset+o),e.committed=!1,e.attempts=0}function je(){void 0!==ce&&clearTimeout(ce),ce=setTimeout(()=>{ce=void 0,Z||!0!==ae?.committed||ke()},500)}function ze(e,t=!1){const o=E.value,n=ae;if(K||null===o||void 0===n||Te(o)||Z&&!t)return;if(t){const e=we(o);n.expectedOffset-=e,Ye(),Me(o,e)}const i=e?.visualOffset??n.visualOffset;if(Math.abs(i)<=w)return n.committed=!0,void je();const l=Math.max(0,o.scrollHeight-o.clientHeight),r=o.scrollTop,s=Math.min(l,Math.max(0,r-i));Fe(s),o.scrollTop=s;const a=o.scrollTop,c=i+a-r,d=M(o),u=(r-i<0||r-i>l)&&Math.abs(a-s)<=d;if(k=a,Math.abs(c)>d&&!u)return Ie(c),Fe(a),n.committed=!1,n.attempts+=1,void(n.attempts<8&&!Z&&Ue());0!==n.visualOffset&&Ie(0),k=a,n.expectedOffset=void 0===e?De()??n.expectedOffset:e.currentOffset-(a-r),S={...n.anchor,offset:n.expectedOffset},be(o),n.committed=!0,n.attempts=0,je()}function Ue(){void 0===ae||ae.attempts>=8||(void 0!==ce&&clearTimeout(ce),ce=setTimeout(()=>{ce=void 0,ze()},120))}function Ve(e){if(void 0===e)return;void 0===ae&&(ae={anchor:e,expectedOffset:e.offset,visualOffset:0,committed:!1,attempts:0});const t=E.value;if(!Z&&null!==t&&!Te(t)&&0===ae.visualOffset){const e=De();if(void 0!==e)return void ze({visualOffset:ae.expectedOffset-e,currentOffset:e})}Ye(),Z||ze()}function qe(){return Number.isFinite(e.olderPrefetchThreshold)?Math.max(0,e.olderPrefetchThreshold):0}function Ke(e=!1){W+=1,"smooth"===q?.behavior&&(q=void 0),_=!1,Z&&!e||(Z=!0,oe+=1),te&&le.cancel()}function We(){const t=E.value;if(null!==t&&oe!==ne&&!Q&&!e.loadingOlder){if(void 0!==ae){if(ze(void 0,!0),!ae.committed)return;ke()}X=!0,Le()&&t.scrollTop<=qe()&&Be()}}function $e(){W+=1,S=void 0,C=void 0,le.cancel(),ke(),Z=!1,_=!1,te=!1,re=void 0,se=void 0,oe+=1,ne=-1,ie=-1,X=!0,Q=!1,J=!1,q=void 0}function Ge(){te||null!==E.value&&Te(E.value)||(le.cancel(),Z=!1,_=!1,void 0!==ae&&(ae.attempts=0),ze())}function Je(){te||le.schedule(Ge,120)}function Qe(){q=void 0,Ge()}function Xe(e){ee=!1;const t=!te;te=!0,Ke(t),re=e.touches?.[0]?.clientY}function Ze(e){const t=e.touches?.[0]?.clientY;void 0!==t&&(void 0!==re&&t!==re&&(W+=1),void 0!==re&&t>re?We():void 0!==re&&t<re&&Re(),re=t)}function _e(){te=!1,re=void 0,Je()}function et(e){ee=!0,Ke(),e.deltaY<0?We():e.deltaY>0&&Re(),Je()}function tt(e){"touch"!==e.pointerType&&(ee=!0,Ke(),se=e.clientY,Je())}function ot(e){"touch"!==e.pointerType&&Z&&void 0!==se&&(e.clientY!==se&&(W+=1),e.clientY<se?We():e.clientY>se&&Re(),se=e.clientY,Je())}function nt(e){"touch"!==e.pointerType&&(se=void 0,Je())}function it(e){["ArrowUp","ArrowDown","PageUp","PageDown","Home","End"," "].includes(e.key)&&(ee=!0,Ke(),"ArrowUp"===e.key||"PageUp"===e.key||"Home"===e.key||" "===e.key&&e.shiftKey?We():Re(),Je())}function lt(e="auto"){const t=E.value;if(null===t)return;W+=1,C=void 0,ke();const o=Math.max(0,t.scrollHeight-t.clientHeight);Fe(o,e),t.scrollTo?.({top:o,behavior:e}),t.scrollTop!==o&&(t.scrollTop=o),k=t.scrollTop,ve.clear(),U=!1,He()}function rt(){const e=E.value;return null!==e&&e.clientWidth>0&&e.clientHeight>0}function st(e,t){const o=E.value;if(null===o||void 0===e||!o.contains(e)||o.clientHeight<=0)return!1;W+=1,ke();const n=o.getBoundingClientRect(),i=e.getBoundingClientRect(),l=t.block??"center";let r;r="start"===l?o.scrollTop+i.top-n.top:"end"===l?o.scrollTop+i.bottom-n.bottom:"nearest"===l?i.top>=n.top&&i.bottom<=n.bottom?o.scrollTop:i.top<n.top?o.scrollTop+i.top-n.top:o.scrollTop+i.bottom-n.bottom:p({currentScrollTop:o.scrollTop,scrollHeight:o.scrollHeight,targetHeight:i.height,targetTop:i.top,viewportHeight:o.clientHeight,viewportTop:n.top});const s=Math.max(0,o.scrollHeight-o.clientHeight),a=Math.min(s,Math.max(0,r));C=void 0;const c=t.behavior??"auto";return Fe(a,c),o.scrollTo?.({top:a,behavior:c}),o.scrollTop!==a&&(o.scrollTop=a),k=o.scrollTop,U=!1,He(),!0}function at(e){const t=E.value;if(null===t||void 0===e||!t.contains(e)||t.clientHeight<=0)return null;const o=e.getBoundingClientRect(),n=t.scrollTop+o.top-t.getBoundingClientRect().top+o.height/2,i=t.clientHeight/2;return{older:n<i-1,newer:t.scrollHeight-n<i-1}}return o(T,{registerLayoutMeasurement:Y.register,registerMessageNode:function(e,t){const o=L.get(e);if(o!==t){if(void 0!==o&&(j?.unobserve(o),o.style.removeProperty("--im-thread-placeholder-play-state"),Y.hasTarget(o)||F?.unobserve?.(o),P.delete(o),A.delete(e)),null===t)return L.delete(e),void A.delete(e);L.set(e,t),P.set(t,e),"function"==typeof globalThis.IntersectionObserver&&t.style.setProperty("--im-thread-placeholder-play-state","paused"),j?.observe(t),F?.observe(t),Ee()}},registerDateNode:function(e,t,o){const n=R.get(e);null!==o?(R.set(e,{element:o,label:t}),$===e&&o.style.setProperty("opacity",String(G)),n?.element!==o&&(o.dataset.imThreadDateSeparator=e)):R.delete(e)},registerEntryUnreadNode:e=>{B=e??void 0}}),n(()=>e.contentKey,(e,t)=>{if(e===t)return;$e();const o=E.value;null!==o&&(k=o.scrollTop)},{flush:"sync"}),n(()=>e.messageIds,async(t,o)=>{if(t.length===o.length&&t.every((e,t)=>e===o[t]))return;const n=E.value;if(null===n)return;const l=new Set(o);o.length>0&&t.length>0&&!t.some(e=>l.has(e))&&$e();const r=e.contentKey,s=de.value,a=o[o.length-1],c=void 0===a?-1:t.indexOf(a),d=c<0?[]:t.slice(c+1).filter(e=>!l.has(e)),v=d.some(t=>e.pendingSendMessageIds.includes(t)),f=J||e.loadingNewer||Q||e.loadingOlder,p=t.length===o.length&&t.every(e=>l.has(e))&&t.some((e,t)=>e!==o[t]),h=o[0],g=void 0!==h&&t.indexOf(h)>0;let m;if(void 0!==S&&(g||d.length>0&&f)){Z&&0!==we(n)&&Se();const e=n.getBoundingClientRect(),o=t.includes(S.id)?pe([S.id]):[],i=o[0],r=void 0!==i&&i.bottom>e.top&&i.top<e.bottom?o:pe(t.filter(e=>l.has(e)));m=u(S,r,{top:e.top,bottom:e.bottom}),void 0===m||void 0===ae||t.includes(ae.anchor.id)||(ae.anchor=m,ae.expectedOffset=m.offset)}const b=W;if(await i(),!K&&e.contentKey===r&&W===b)if(v&&e.followNewMessages)lt();else if(p&&s&&e.followNewMessages&&e.resizeFollowEnabled&&!e.hasNewer&&!f)lt();else{if(g&&(Q=!1,Ve(m)),d.length>0){if(f)return J=!1,Ve(m),de.value=!1,void Ee();(s||d.some(t=>!0===e.shouldFollowAppendedMessage?.(t)))&&e.followNewMessages?lt():ve.add(d)}Ee()}},{flush:"pre"}),n(()=>e.loadingNewer,(t,o)=>{!t&&o&&J&&xe(()=>{e.loadingNewer||(J=!1)})},{flush:"pre"}),n(()=>e.loadingOlder,(e,t)=>{e?Q=!0:t&&Q&&(Q=!1)},{flush:"post"}),l(()=>{const t=E.value;if(null!==t){if(k=t.scrollTop,t.addEventListener("scroll",Ce,{passive:!0}),t.addEventListener("scrollend",Qe,{passive:!0}),t.addEventListener("touchstart",Xe,{passive:!0}),t.addEventListener("touchmove",Ze,{passive:!0}),t.addEventListener("touchend",_e,{passive:!0}),t.addEventListener("touchcancel",_e,{passive:!0}),t.addEventListener("wheel",et,{passive:!0}),t.addEventListener("pointerdown",tt,{passive:!0}),t.addEventListener("pointermove",ot,{passive:!0}),t.addEventListener("pointerup",nt,{passive:!0}),t.addEventListener("pointercancel",nt,{passive:!0}),t.addEventListener("keydown",it),"function"==typeof globalThis.ResizeObserver){F=new globalThis.ResizeObserver(e=>{if(K||null===E.value)return;Y.resized(e.map(e=>e.target));e.some(({target:e})=>e===t||e===N.value||P.has(e))&&He()}),F.observe(t),null!==N.value&&F.observe(N.value);for(const e of L.values())F.observe(e);Y.observeTargets()}if(I=t.ownerDocument.fonts,I?.addEventListener("loadingdone",Y.invalidateAll),"function"==typeof globalThis.IntersectionObserver){j=new globalThis.IntersectionObserver(e=>{for(const t of e){const e=P.get(t.target);if(void 0===e)continue;const o=t.target,n=t.isIntersecting?"running":"paused";o.style.getPropertyValue("--im-thread-placeholder-play-state")!==n&&o.style.setProperty("--im-thread-placeholder-play-state",n),t.isIntersecting?A.add(e):A.delete(e)}U=!0,Ee()},{root:t,rootMargin:`${Number.isFinite(e.visibleMargin)?Math.max(0,e.visibleMargin):0}px 0px`});for(const e of L.values())j.observe(e)}Ee()}}),r(()=>{K=!0;const e=E.value;null!==e&&e.removeEventListener("scroll",Ce),null!==e&&(e.removeEventListener("scrollend",Qe),e.removeEventListener("touchstart",Xe),e.removeEventListener("touchmove",Ze),e.removeEventListener("touchend",_e),e.removeEventListener("touchcancel",_e),e.removeEventListener("wheel",et),e.removeEventListener("pointerdown",tt),e.removeEventListener("pointermove",ot),e.removeEventListener("pointerup",nt),e.removeEventListener("pointercancel",nt),e.removeEventListener("keydown",it)),le.cancel(),ke(),void 0!==z&&("number"==typeof z&&"function"==typeof globalThis.cancelAnimationFrame?globalThis.cancelAnimationFrame(z):globalThis.clearTimeout(z),z=void 0,V.clear()),I?.removeEventListener("loadingdone",Y.invalidateAll),Y.dispose(),F?.disconnect(),j?.disconnect(),ge(),B=void 0;for(const e of L.values())e.style.removeProperty("--im-thread-placeholder-play-state");L.clear(),P.clear(),A.clear(),R.clear(),ve.clear()}),H({getViewportElement:()=>E.value,clearNewMessageBadge:function(){ve.clear()},clearActiveDate:ge,isAtBottom:s(()=>de.value),isMeasurable:rt,isScrollable:function(){const e=E.value;return rt()&&null!==e&&e.scrollHeight>e.clientHeight+1},getMessageCenteringNeeds:function(e){return at(L.get(e))},newMessageCount:s(()=>ue.value),prepareHistoryPageAppend:function(){J=!0,de.value=!1},cancelHistoryPageAppend:function(){J=!1,Ee()},trackRemoteMessageIds:(e,t)=>ve.trackRemote(e,t),scrollToLatest:lt,scrollToMessage:function(e,t={}){return st(L.get(e),t)},scrollToEntryUnread:()=>st(B,{block:"center",behavior:"auto"}),getEntryUnreadCenteringNeeds:function(){return at(B)},focusViewport:()=>E.value?.focus({preventScroll:!0})}),()=>a("div",{ref:E,"data-im-thread-viewport":"",role:"log",tabindex:-1},[a("div",{ref:N,"data-im-thread-viewport-content":""},x.default?.())])}});export{O as ImThreadViewport};
|
|
1
|
+
import{defineComponent as e,ref as t,provide as o,watch as n,nextTick as i,onMounted as l,onBeforeUnmount as r,computed as s,h as a}from"vue";import{resolveImThreadActiveDate as c}from"../../thread/active-date.js";import{createNewMessageBadgeController as d}from"../../thread/new-message-badge.js";import{refreshPrependMessageAnchorPosition as u,isMessageVisibleForNewMessageBadge as v,resolvePrependMessageAnchorPosition as f,resolveCenteredMessageScrollTop as p,shouldPrefetchOlderHistory as h,shouldLoadNewerHistoryPage as g,resolvePrependMessageAnchorAdjustment as m}from"../../thread/viewport-rules.js";import{createThreadIdleTask as b}from"./thread-idle-task.js";import{createThreadLayoutMeasurements as y}from"./thread-layout-measurements.js";import{THREAD_VIEWPORT_REGISTRATION_KEY as T}from"./thread-viewport-context.js";const w=.5;function M(e){const t=e.ownerDocument.defaultView?.devicePixelRatio;return 1+1/(void 0!==t&&Number.isFinite(t)&&t>0?t:1)}const O=e({name:"ImThreadViewport",props:{messageIds:{type:Array,required:!0},contentKey:{type:String,default:""},loadingOlder:{type:Boolean,default:!1},hasNewer:{type:Boolean,default:!1},loadingNewer:{type:Boolean,default:!1},followThreshold:{type:Number,default:120},olderPrefetchThreshold:{type:Number,default:120},followNewMessages:{type:Boolean,default:!0},shouldFollowAppendedMessage:{type:Function,default:void 0},pendingSendMessageIds:{type:Array,default:()=>[]},visibleMargin:{type:Number,default:8},resizeFollowEnabled:{type:Boolean,default:!0},activeDateOffset:{type:Number,default:16},activeDateEnabled:{type:Boolean,default:!1}},emits:{"reach-start":()=>!0,"reach-end":()=>!0,"visible-range":e=>!0,settled:e=>!0,"new-message-count":e=>!0,"user-scroll":()=>!0,"active-date-change":e=>!0},setup(e,{emit:O,expose:H,slots:x}){const E=t(null),N=t(null),L=/* @__PURE__ */new Map;let B;const P=/* @__PURE__ */new Map,A=/* @__PURE__ */new Set,R=/* @__PURE__ */new Map;let S,C,F,I,k=0,D=[];const Y=y({requestFrame:xe,observe:e=>F?.observe(e),unobserve:e=>{e===E.value||e===N.value||P.has(e)||F?.unobserve(e)}});let j,z,U=!1;const V=/* @__PURE__ */new Set;let q,K=!1,W=0,$="",G=1,J=!1,Q=!1,X=!0,Z=!1,_=!1,ee=!0,te=!1,oe=0,ne=-1,ie=-1;const le=b();let re,se,ae,ce;const de=t(!0),ue=t(0),ve=d(e=>{ue.value=e,O("new-message-count",e)});function fe(t){const o=Number.isFinite(e.followThreshold)?Math.max(0,e.followThreshold):0;return t.scrollHeight-t.clientHeight-t.scrollTop<=o}function pe(t=e.messageIds){return t.flatMap(e=>{const t=L.get(e);if(void 0===t)return[];const o=t.getBoundingClientRect(),n=t.querySelector("[data-im-thread-anchor-point]");return[{id:e,top:o.top,bottom:o.bottom,anchorTop:n?.getBoundingClientRect().top??o.top}]})}function he(e="",t=1){const o=Math.min(1,Math.max(0,t));""!==$&&$!==e&&R.get($)?.element.style.removeProperty("opacity"),$=e,G=o,""!==e&&R.get(e)?.element.style.setProperty("opacity",String(o))}function ge(){he()}function me(){const t=E.value;if(K||null===t||!e.activeDateEnabled)return;const o=[...R.entries()].filter(([,e])=>t.contains(e.element)).map(([e,t])=>{const o=t.element.getBoundingClientRect();return{key:e,label:t.label,top:o.top,height:o.height}}).sort((e,t)=>e.top-t.top),n=t.getBoundingClientRect(),i=o.find(e=>e.height>0)?.height??28,l=c({markers:o,viewportTop:n.top,overlayTop:Number.isFinite(e.activeDateOffset)?Math.max(0,e.activeDateOffset):0,overlayHeight:i});if(null===l)return ge(),void O("active-date-change",null);he(l.inlineDateKey,l.inlineOpacity),O("active-date-change",l)}function be(e){C={scrollTop:e.scrollTop,scrollHeight:e.scrollHeight,width:e.clientWidth,height:e.clientHeight}}function ye(e){const t=C;if(void 0===t)return!1;const o=Math.max(0,e.scrollHeight-e.clientHeight);return o<t.scrollHeight-t.height&&t.scrollTop>o&&Math.abs(e.scrollTop-o)<=M(e)}function Te(e){return e.scrollTop<0||e.scrollTop>Math.max(0,e.scrollHeight-e.clientHeight)+M(e)}function we(e){return ye(e)||void 0!==q&&("smooth"===q.behavior||Math.abs(e.scrollTop-q.targetTop)<=M(e))?0:e.scrollTop-k}function Me(e,t){0!==t&&(k=e.scrollTop-t,q=void 0,Se(!0))}function Oe(t,o){const n=we(t);if(void 0!==ae)return ae.expectedOffset-=n,Ye(),Me(t,n),Z||Ue(),!1;const i=C;if(void 0===i)return!1;const l=S,r=void 0===l?void 0:pe([l.id])[0],s=t.scrollTop-i.scrollTop,a=ye(t)?0:s,c=void 0===l||void 0===r?0:(r.anchorTop??r.top)-o.top-l.offset+s;return(i.scrollHeight!==t.scrollHeight||i.width!==t.clientWidth||i.height!==t.clientHeight||Math.abs(c)>w)&&(C=void 0,!(J||Q||e.loadingOlder||e.loadingNewer||e.hasNewer||!e.resizeFollowEnabled||Te(t))&&de.value&&Math.abs(a)<=w?(lt(),!0):(void 0!==l&&function(e){const t=E.value;if(null===t||void 0===e)return;if(Te(t))return void Ve(e);const o=t.getBoundingClientRect(),n=m(e,pe([e.id]),{top:o.top,bottom:o.bottom});if(void 0!==n){const e=Math.max(0,t.scrollHeight-t.clientHeight),o=Math.min(e,Math.max(0,t.scrollTop+n));Fe(o),t.scrollTop=o,k=t.scrollTop,C=void 0}}({...l,offset:l.offset-a}),Me(t,n),!1))}function He(){const t=E.value;if(K||null===t)return;const o=t.getBoundingClientRect();if(Oe(t,o))return;const n=pe(void 0!==j&&U?e.messageIds.filter(e=>A.has(e)):e.messageIds);if(void 0!==j&&U&&0===n.length)return void(de.value=fe(t));const i=n.filter(t=>v({viewportTop:o.top,viewportBottom:o.bottom,messageTop:t.top,messageBottom:t.bottom,margin:e.visibleMargin})).map(e=>e.id),l=i.length!==D.length||i.some((e,t)=>D[t]!==e);D=Object.freeze(i),S=f(n,{top:o.top,bottom:o.bottom}),be(t),ve.acknowledgeVisible(i),de.value=fe(t),l&&O("visible-range",D),O("settled",{visibleMessageIds:D,...0===D.length?{}:{newestVisibleMessageId:D[D.length-1]},isAtBottom:de.value,newMessageCount:ue.value})}function xe(e){if(V.add(e),void 0!==z)return;const t=()=>{z=void 0;const e=[...V];V.clear(),e.forEach(e=>e())};z="function"==typeof globalThis.requestAnimationFrame?globalThis.requestAnimationFrame(t):globalThis.setTimeout(t,0)}function Ee(){xe(He)}function Ne(){const e=E.value;if(null===e)return;const t=e.getBoundingClientRect(),o=f(pe(),{top:t.top,bottom:t.bottom});void 0!==o&&(S=o,be(e))}function Le(){return X&&void 0===ae&&!Q&&!e.loadingOlder}function Be(){Ne(),X=!1,ne=oe,Q=!0,de.value=!1,O("reach-start"),xe(()=>{e.loadingOlder||(Q=!1)})}function Pe(t){return e.hasNewer&&!J&&!e.loadingOlder&&!e.loadingNewer&&fe(t)}function Ae(){Ne(),J=!0,de.value=!1,ie=oe,O("reach-end"),xe(()=>{e.loadingNewer||(J=!1)})}function Re(){const e=E.value;null!==e&&oe!==ie&&Pe(e)&&Ae()}function Se(t=!1){const o=E.value;if(K||null===o)return;const n=o.scrollTop,i=Math.max(0,o.scrollHeight-o.clientHeight),l=Math.min(i,Math.max(0,k)),r=Math.min(i,Math.max(0,n)),s=ye(o),a=q;let c=!1;if(void 0!==a){const e=Math.abs(n-a.targetTop)<=M(o);c="smooth"===a.behavior||e,("smooth"!==a.behavior||e)&&(q=void 0)}c||s||Z||!ee||void 0!==ae||n===k||(Z=!0,_=!0,oe+=1);const d=Z&&!c&&!s&&n!==k;d&&(W+=1,O("user-scroll"),xe(me)),Z&&!te&&Je(),!X&&_&&oe!==ne&&n<k&&n>qe()&&We(),void 0===ae||c||(Z?s||t||(ae.expectedOffset-=n-k):(Ye(),Ue())),Le()&&d&&h({previousScrollTop:l,currentScrollTop:r,topThreshold:e.olderPrefetchThreshold})&&Be(),d&&Pe(o)&&g({previousScrollTop:l,currentScrollTop:r,isAtBottom:fe(o),isHistoryWindow:e.hasNewer,isPageSettling:c})&&Ae(),k=n,s?He():Ee()}function Ce(){Se()}function Fe(e,t="auto"){q={targetTop:e,behavior:t}}function Ie(e){const t=ae,o=N.value;if(void 0!==t&&null!==o){if(t.visualOffset=Math.abs(e)<=w?0:e,0===t.visualOffset)return o.style.removeProperty("transform"),void o.style.removeProperty("will-change");o.style.setProperty("transform",`translate3d(0, ${t.visualOffset}px, 0)`),o.style.setProperty("will-change","transform")}}function ke(){void 0!==ce&&(clearTimeout(ce),ce=void 0),void 0!==ae&&0!==ae.visualOffset&&(S=void 0,C=void 0);const e=N.value;e?.style.removeProperty("transform"),e?.style.removeProperty("will-change"),ae=void 0,q=void 0}function De(){const e=E.value,t=ae;if(null===e||void 0===t)return;const o=L.get(t.anchor.id);if(void 0===o)return;return(o.querySelector("[data-im-thread-anchor-point]")??o).getBoundingClientRect().top-e.getBoundingClientRect().top}function Ye(){const e=ae,t=De();if(void 0===e||void 0===t)return;const o=e.expectedOffset-t;if(Math.abs(o)<=w)return;const n=E.value;null!==n&&ye(n)&&(k=n.scrollTop),Ie(e.visualOffset+o),e.committed=!1,e.attempts=0}function je(){void 0!==ce&&clearTimeout(ce),ce=setTimeout(()=>{ce=void 0,Z||!0!==ae?.committed||ke()},500)}function ze(e,t=!1){const o=E.value,n=ae;if(K||null===o||void 0===n||Te(o)||Z&&!t)return;if(t){const e=we(o);n.expectedOffset-=e,Ye(),Me(o,e)}const i=e?.visualOffset??n.visualOffset;if(Math.abs(i)<=w)return n.committed=!0,void je();const l=Math.max(0,o.scrollHeight-o.clientHeight),r=o.scrollTop,s=Math.min(l,Math.max(0,r-i));Fe(s),o.scrollTop=s;const a=o.scrollTop,c=i+a-r,d=M(o),u=(r-i<0||r-i>l)&&Math.abs(a-s)<=d;if(k=a,Math.abs(c)>d&&!u)return Ie(c),Fe(a),n.committed=!1,n.attempts+=1,void(n.attempts<8&&!Z&&Ue());0!==n.visualOffset&&Ie(0),k=a,n.expectedOffset=void 0===e?De()??n.expectedOffset:e.currentOffset-(a-r),S={...n.anchor,offset:n.expectedOffset},be(o),n.committed=!0,n.attempts=0,je()}function Ue(){void 0===ae||ae.attempts>=8||(void 0!==ce&&clearTimeout(ce),ce=setTimeout(()=>{ce=void 0,ze()},120))}function Ve(e){if(void 0===e)return;void 0===ae&&(ae={anchor:e,expectedOffset:e.offset,visualOffset:0,committed:!1,attempts:0});const t=E.value;if(!Z&&null!==t&&!Te(t)&&0===ae.visualOffset){const e=De();if(void 0!==e)return void ze({visualOffset:ae.expectedOffset-e,currentOffset:e})}Ye(),Z||ze()}function qe(){return Number.isFinite(e.olderPrefetchThreshold)?Math.max(0,e.olderPrefetchThreshold):0}function Ke(e=!1){W+=1,"smooth"===q?.behavior&&(q=void 0),_=!1,Z&&!e||(Z=!0,oe+=1),te&&le.cancel()}function We(){const t=E.value;if(null!==t&&oe!==ne&&!Q&&!e.loadingOlder){if(void 0!==ae){if(ze(void 0,!0),!ae.committed)return;ke()}X=!0,Le()&&t.scrollTop<=qe()&&Be()}}function $e(){W+=1,S=void 0,C=void 0,le.cancel(),ke(),Z=!1,_=!1,te=!1,re=void 0,se=void 0,oe+=1,ne=-1,ie=-1,X=!0,Q=!1,J=!1,q=void 0}function Ge(){te||null!==E.value&&Te(E.value)||(le.cancel(),Z=!1,_=!1,void 0!==ae&&(ae.attempts=0),ze())}function Je(){te||le.schedule(Ge,120)}function Qe(){q=void 0,Ge()}function Xe(e){ee=!1;const t=!te;te=!0,Ke(t),re=e.touches?.[0]?.clientY}function Ze(e){const t=e.touches?.[0]?.clientY;void 0!==t&&(void 0!==re&&t!==re&&(W+=1),void 0!==re&&t>re?We():void 0!==re&&t<re&&Re(),re=t)}function _e(){te=!1,re=void 0,Je()}function et(e){ee=!0,Ke(),e.deltaY<0?We():e.deltaY>0&&Re(),Je()}function tt(e){"touch"!==e.pointerType&&(ee=!0,Ke(),se=e.clientY,Je())}function ot(e){"touch"!==e.pointerType&&Z&&void 0!==se&&(e.clientY!==se&&(W+=1),e.clientY<se?We():e.clientY>se&&Re(),se=e.clientY,Je())}function nt(e){"touch"!==e.pointerType&&(se=void 0,Je())}function it(e){["ArrowUp","ArrowDown","PageUp","PageDown","Home","End"," "].includes(e.key)&&(ee=!0,Ke(),"ArrowUp"===e.key||"PageUp"===e.key||"Home"===e.key||" "===e.key&&e.shiftKey?We():Re(),Je())}function lt(e="auto"){const t=E.value;if(null===t)return;W+=1,C=void 0,ke();const o=Math.max(0,t.scrollHeight-t.clientHeight);Fe(o,e),t.scrollTo?.({top:o,behavior:e}),t.scrollTop!==o&&(t.scrollTop=o),k=t.scrollTop,ve.clear(),U=!1,He()}function rt(){const e=E.value;return null!==e&&e.clientWidth>0&&e.clientHeight>0}function st(e,t){const o=E.value;if(null===o||void 0===e||!o.contains(e)||o.clientHeight<=0)return!1;W+=1,ke();const n=o.getBoundingClientRect(),i=e.getBoundingClientRect(),l=t.block??"center";let r;r="start"===l?o.scrollTop+i.top-n.top:"end"===l?o.scrollTop+i.bottom-n.bottom:"nearest"===l?i.top>=n.top&&i.bottom<=n.bottom?o.scrollTop:i.top<n.top?o.scrollTop+i.top-n.top:o.scrollTop+i.bottom-n.bottom:p({currentScrollTop:o.scrollTop,scrollHeight:o.scrollHeight,targetHeight:i.height,targetTop:i.top,viewportHeight:o.clientHeight,viewportTop:n.top});const s=Math.max(0,o.scrollHeight-o.clientHeight),a=Math.min(s,Math.max(0,r));C=void 0;const c=t.behavior??"auto";return Fe(a,c),o.scrollTo?.({top:a,behavior:c}),o.scrollTop!==a&&(o.scrollTop=a),k=o.scrollTop,U=!1,He(),!0}function at(e){const t=E.value;if(null===t||void 0===e||!t.contains(e)||t.clientHeight<=0)return null;const o=e.getBoundingClientRect(),n=t.scrollTop+o.top-t.getBoundingClientRect().top+o.height/2,i=t.clientHeight/2;return{older:n<i-1,newer:t.scrollHeight-n<i-1}}return o(T,{registerLayoutMeasurement:Y.register,registerMessageNode:function(e,t){const o=L.get(e);if(o!==t){if(void 0!==o&&(j?.unobserve(o),o.style.removeProperty("--im-thread-placeholder-play-state"),Y.hasTarget(o)||F?.unobserve?.(o),P.delete(o),A.delete(e)),null===t)return L.delete(e),void A.delete(e);L.set(e,t),P.set(t,e),"function"==typeof globalThis.IntersectionObserver&&t.style.setProperty("--im-thread-placeholder-play-state","paused"),j?.observe(t),F?.observe(t),Ee()}},registerDateNode:function(e,t,o){const n=R.get(e);null!==o?(R.set(e,{element:o,label:t}),$===e&&o.style.setProperty("opacity",String(G)),n?.element!==o&&(o.dataset.imThreadDateSeparator=e)):R.delete(e)},registerEntryUnreadNode:e=>{B=e??void 0}}),n(()=>e.contentKey,(e,t)=>{if(e===t)return;$e();const o=E.value;null!==o&&(k=o.scrollTop)},{flush:"sync"}),n(()=>e.messageIds,async(t,o)=>{if(t.length===o.length&&t.every((e,t)=>e===o[t]))return;const n=E.value;if(null===n)return;const l=new Set(o);o.length>0&&t.length>0&&!t.some(e=>l.has(e))&&$e();const r=e.contentKey,s=de.value,a=o[o.length-1],c=void 0===a?-1:t.indexOf(a),d=c<0?[]:t.slice(c+1).filter(e=>!l.has(e)),v=d.some(t=>e.pendingSendMessageIds.includes(t)),f=J||e.loadingNewer||Q||e.loadingOlder,p=t.length===o.length&&t.every(e=>l.has(e))&&t.some((e,t)=>e!==o[t]),h=o[0],g=void 0!==h&&t.indexOf(h)>0;let m;if(void 0!==S&&(g||d.length>0&&f)){Z&&0!==we(n)&&Se();const e=n.getBoundingClientRect(),o=t.includes(S.id)?pe([S.id]):[],i=o[0],r=void 0!==i&&i.bottom>e.top&&i.top<e.bottom?o:pe(t.filter(e=>l.has(e)));m=u(S,r,{top:e.top,bottom:e.bottom}),void 0===m||void 0===ae||t.includes(ae.anchor.id)||(ae.anchor=m,ae.expectedOffset=m.offset)}const b=W;if(await i(),!K&&e.contentKey===r&&W===b)if(v&&e.followNewMessages)lt();else if(p&&s&&e.followNewMessages&&e.resizeFollowEnabled&&!e.hasNewer&&!f)lt();else{if(g&&(Q=!1,Ve(m)),d.length>0){if(f)return J=!1,Ve(m),de.value=!1,void Ee();(s||d.some(t=>!0===e.shouldFollowAppendedMessage?.(t)))&&e.followNewMessages?lt():ve.add(d)}Ee()}},{flush:"pre"}),n(()=>e.loadingNewer,(t,o)=>{!t&&o&&J&&xe(()=>{e.loadingNewer||(J=!1)})},{flush:"pre"}),n(()=>e.loadingOlder,(e,t)=>{e?Q=!0:t&&Q&&(Q=!1)},{flush:"post"}),l(()=>{const t=E.value;if(null!==t){if(k=t.scrollTop,t.addEventListener("scroll",Ce,{passive:!0}),t.addEventListener("scrollend",Qe,{passive:!0}),t.addEventListener("touchstart",Xe,{passive:!0}),t.addEventListener("touchmove",Ze,{passive:!0}),t.addEventListener("touchend",_e,{passive:!0}),t.addEventListener("touchcancel",_e,{passive:!0}),t.addEventListener("wheel",et,{passive:!0}),t.addEventListener("pointerdown",tt,{passive:!0}),t.addEventListener("pointermove",ot,{passive:!0}),t.addEventListener("pointerup",nt,{passive:!0}),t.addEventListener("pointercancel",nt,{passive:!0}),t.addEventListener("keydown",it),"function"==typeof globalThis.ResizeObserver){F=new globalThis.ResizeObserver(e=>{if(K||null===E.value)return;Y.resized(e.map(e=>e.target));e.some(({target:e})=>e===t||e===N.value||P.has(e))&&He()}),F.observe(t),null!==N.value&&F.observe(N.value);for(const e of L.values())F.observe(e);Y.observeTargets()}if(I=t.ownerDocument.fonts,I?.addEventListener("loadingdone",Y.invalidateAll),"function"==typeof globalThis.IntersectionObserver){j=new globalThis.IntersectionObserver(e=>{for(const t of e){const e=P.get(t.target);if(void 0===e)continue;const o=t.target,n=t.isIntersecting?"running":"paused";o.style.getPropertyValue("--im-thread-placeholder-play-state")!==n&&o.style.setProperty("--im-thread-placeholder-play-state",n),t.isIntersecting?A.add(e):A.delete(e)}U=!0,Ee()},{root:t,rootMargin:`${Number.isFinite(e.visibleMargin)?Math.max(0,e.visibleMargin):0}px 0px`});for(const e of L.values())j.observe(e)}Ee()}}),r(()=>{K=!0;const e=E.value;null!==e&&e.removeEventListener("scroll",Ce),null!==e&&(e.removeEventListener("scrollend",Qe),e.removeEventListener("touchstart",Xe),e.removeEventListener("touchmove",Ze),e.removeEventListener("touchend",_e),e.removeEventListener("touchcancel",_e),e.removeEventListener("wheel",et),e.removeEventListener("pointerdown",tt),e.removeEventListener("pointermove",ot),e.removeEventListener("pointerup",nt),e.removeEventListener("pointercancel",nt),e.removeEventListener("keydown",it)),le.cancel(),ke(),void 0!==z&&("number"==typeof z&&"function"==typeof globalThis.cancelAnimationFrame?globalThis.cancelAnimationFrame(z):globalThis.clearTimeout(z),z=void 0,V.clear()),I?.removeEventListener("loadingdone",Y.invalidateAll),Y.dispose(),F?.disconnect(),j?.disconnect(),ge(),B=void 0;for(const e of L.values())e.style.removeProperty("--im-thread-placeholder-play-state");L.clear(),P.clear(),A.clear(),R.clear(),ve.clear()}),H({getViewportElement:()=>E.value,clearNewMessageBadge:function(){ve.clear()},clearActiveDate:ge,isAtBottom:s(()=>de.value),isMeasurable:rt,isScrollable:function(){const e=E.value;return rt()&&null!==e&&e.scrollHeight>e.clientHeight+1},getMessageCenteringNeeds:function(e){return at(L.get(e))},newMessageCount:s(()=>ue.value),prepareHistoryPageAppend:function(){J=!0,de.value=!1},cancelHistoryPageAppend:function(){J=!1,Ee()},trackRemoteMessageIds:(e,t)=>ve.trackRemote(e,t),scrollToLatest:lt,scrollToMessage:function(e,t={}){return st(L.get(e),t)},scrollToEntryUnread:()=>st(B,{block:"center",behavior:"auto"}),getEntryUnreadCenteringNeeds:function(){return at(B)},focusViewport:()=>E.value?.focus({preventScroll:!0})}),()=>a("div",{ref:E,"data-im-thread-viewport":"",role:"log",tabindex:-1},[a("div",{ref:N,"data-im-thread-viewport-content":""},x.default?.())])}});export{O as ImThreadViewport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{encodeConversationKey as e}from"../conversation-identity.js";import{mergeMessageReactions as t}from"../state/message-reactions.js";import{resolveMessageServerTime as i,computeMessageSortKey as o}from"./sort.js";const n={unread:0,delivered:1,read:2};function r(e,t){return n[t]>n[e]?t:e}function d(e,t){return"sent"===e||"sent"===t?"sent":t}function a(e,n,a=""){const s=i(e)??0,c=i(n)??0,y=c>=s,u=y?{...e,...n}:{...n,...e},l=!0===e.readBySelf||!0===n.readBySelf,v=Math.max(s,c),f=Math.min(e.createdAt,n.createdAt),p=void 0===e.extensions&&void 0===n.extensions?void 0:y?{...e.extensions,...n.extensions}:{...n.extensions,...e.extensions},b=o({...u,createdAt:f,serverTime:v,extensions:p}),g="failed"===e.status&&!1===e.failure?.retryable&&"sent"===n.status?"failed":d(e.status,n.status),h="failed"===g?n.failure??e.failure:void 0,T=t(e.reactions,n.reactions,a),N=!0===e.encryption.decryptFailed,U=!0===n.encryption.decryptFailed;let w=u.contentType,I=u.body,A=u.encryption,x=u.mention;N&&!U?(w=n.contentType,I=n.body,A=n.encryption,x=n.mention):!N&&U&&(w=e.contentType,I=e.body,A=e.encryption,x=e.mention),!0!==n.edited||U||(w=n.contentType,I=n.body,A=n.encryption,x=n.mention);const z=e.body.voice?.waveform??n.body.voice?.waveform;if(void 0!==I.voice&&void 0===I.voice.waveform&&void 0!==z&&(I={...I,voice:{...I.voice,waveform:z}}),void 0!==I.video&&void 0===I.video.size){const t=I.video,i=[e.body.video,n.body.video].find(e=>"bytes"===e?.sizeUnit&&void 0!==e.size&&e.url===t.url&&e.fileEncryptType===t.fileEncryptType&&e.md5===t.md5&&m(e.teaKey,t.teaKey)&&(void 0===t.unverifiedFileLength||t.unverifiedFileLength===String(e.size)));void 0!==i&&(I={...I,video:{...t,size:i.size,sizeUnit:"bytes"}})}const E=!0===e.edited||!0===n.edited,S=e.deletedForEveryone??n.deletedForEveryone;if(void 0!==S){const t={...u,...l?{readBySelf:!0}:{},id:e.id,createdAt:f,serverTime:v>0?v:void 0,status:g,failure:h,receipt:r(e.receipt,n.receipt),sortKey:b,extensions:p,recalled:void 0,deletedForEveryone:S,body:{},encryption:u.encryption};return delete t.reactions,t}const k=e.recalled??n.recalled;if(void 0!==k){const t={...u,...l?{readBySelf:!0}:{},id:e.id,createdAt:f,serverTime:v>0?v:void 0,status:g,failure:h,receipt:r(e.receipt,n.receipt),sortKey:b,extensions:p,recalled:k,body:{},encryption:u.encryption};return delete t.reactions,t}const K={...u,...l?{readBySelf:!0}:{},id:e.id,createdAt:f,serverTime:v>0?v:void 0,status:g,failure:h,receipt:r(e.receipt,n.receipt),sortKey:b,extensions:p,contentType:w,body:I,encryption:A,...void 0===T?{}:{reactions:T},...E?{edited:!0}:{}};return void 0!==x?K.mention=x:delete K.mention,K}function s(t,i=""){const o=/* @__PURE__ */new Map;for(const n of t){const t=JSON.stringify([e(n),n.id]),r=o.get(t);o.set(t,void 0===r?n:a(r,n,i))}return[...o.values()]}function c(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.fileName===t.fileName&&e.size===t.size&&e.extension===t.extension&&e.fileType===t.fileType&&e.mimeType===t.mimeType&&e.md5===t.md5&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)}function y(e,t){return e===t||void 0!==e&&void 0!==t&&JSON.stringify(e)===JSON.stringify(t)}function u(e,t){return void 0===e||void 0===t?e===t:e.atAll===t.atAll&&e.atUserIds.length===t.atUserIds.length&&(!e.atUserIds.some((e,i)=>e!==t.atUserIds[i])&&function(e,t){if(void 0===e||void 0===t)return e===t;const i=Object.keys(e);return i.length===Object.keys(t).length&&i.every(i=>e[i]===t[i])}(e.atUsersName,t.atUsersName))}function m(e,t){return void 0===e||void 0===t?e===t:e.length===t.length&&e.every((e,i)=>e===t[i])}function l(e,t){return void 0===e||void 0===t?e===t:e.caption===t.caption&&e.items.length===t.items.length&&e.items.every((e,i)=>function(e,t){return e.kind===t.kind&&e.url===t.url&&e.width===t.width&&e.height===t.height&&e.durationMs===t.durationMs&&e.thumbUrl===t.thumbUrl&&m(e.thumbData,t.thumbData)&&e.md5===t.md5&&e.size===t.size&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)&&e.hd===t.hd}(e,t.items[i]))}function v(e,t){return e.id===t.id&&e.conversationId===t.conversationId&&e.conversationType===t.conversationType&&e.senderId===t.senderId&&e.contentType===t.contentType&&JSON.stringify(e.body.customerService)===JSON.stringify(t.body.customerService)&&e.body.text===t.body.text&&function(e,t){return void 0===e||void 0===t?e===t:e.eventType===t.eventType&&e.timelineVisibility===t.timelineVisibility&&e.operatorId===t.operatorId&&e.rawNotifyType===t.rawNotifyType&&e.errcode===t.errcode&&e.fallbackText===t.fallbackText&&function(e,t){return void 0===e||void 0===t?e===t:e.length===t.length&&e.every((e,i)=>e===t[i])}(e.targetUserIds,t.targetUserIds)&&y(e.payload,t.payload)&&y(e.action,t.action)&&y(e.pinnedMessageAction,t.pinnedMessageAction)}(e.body.system,t.body.system)&&e.createdAt===t.createdAt&&e.sortKey===t.sortKey&&e.status===t.status&&e.serverTime===t.serverTime&&e.receipt===t.receipt&&e.readBySelf===t.readBySelf&&e.refMessageId===t.refMessageId&&e.edited===t.edited&&(e.recalled?.by??"")===(t.recalled?.by??"")&&(e.recalled?.at??0)===(t.recalled?.at??0)&&(e.deletedForEveryone?.by??"")===(t.deletedForEveryone?.by??"")&&(e.deletedForEveryone?.at??0)===(t.deletedForEveryone?.at??0)&&(e.deletedForEveryone?.reason??"")===(t.deletedForEveryone?.reason??"")&&function(e,t){return void 0===e||void 0===t?e===t:e.version===t.version&&e.total===t.total&&e.currentUserEmoji===t.currentUserEmoji&&e.events.length===t.events.length&&e.events.every((e,i)=>{const o=t.events[i];return void 0!==o&&e.id===o.id&&e.senderId===o.senderId&&e.emoji===o.emoji&&e.action===o.action&&e.createdAt===o.createdAt})}(e.reactions,t.reactions)&&e.encryption.encrypted===t.encryption.encrypted&&e.encryption.scheme===t.encryption.scheme&&e.encryption.decryptFailed===t.encryption.decryptFailed&&u(e.mention,t.mention)&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.width===t.width&&e.height===t.height&&m(e.thumbData,t.thumbData)&&e.md5===t.md5&&e.imageType===t.imageType&&e.size===t.size&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)}(e.body.image,t.body.image)&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.width===t.width&&e.height===t.height&&e.duration===t.duration&&e.durationUnit===t.durationUnit&&e.sizeUnit===t.sizeUnit&&e.unverifiedFileLength===t.unverifiedFileLength&&m(e.thumbData,t.thumbData)&&e.md5===t.md5&&e.size===t.size&&e.describe===t.describe&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)}(e.body.video,t.body.video)&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.durationMs===t.durationMs&&e.size===t.size&&e.md5===t.md5&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)&&(e.waveform?.length??0)===(t.waveform?.length??0)}(e.body.voice,t.body.voice)&&c(e.body.file,t.body.file)&&(void 0===e.body.filesAlbum||void 0===t.body.filesAlbum?e.body.filesAlbum===t.body.filesAlbum:e.body.filesAlbum.caption===t.body.filesAlbum.caption&&e.body.filesAlbum.items.length===t.body.filesAlbum.items.length&&e.body.filesAlbum.items.every((e,i)=>c(e,t.body.filesAlbum.items[i])))&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.width===t.width&&e.height===t.height&&e.exprType===t.exprType&&e.imageType===t.imageType&&e.size===t.size&&e.describe===t.describe&&e.contentId===t.contentId&&e.packageName===t.packageName&&m(e.thumbData,t.thumbData)}(e.body.sticker,t.body.sticker)&&function(e,t){return void 0===e||void 0===t?e===t:e.targetId===t.targetId&&e.avatar===t.avatar&&e.displayName===t.displayName&&e.username===t.username&&e.gender===t.gender&&e.kind===t.kind&&e.rawKind===t.rawKind}(e.body.contact,t.body.contact)&&function(e,t){return void 0===e||void 0===t?e===t:e.appId===t.appId&&e.host===t.host&&e.developerId===t.developerId&&e.name===t.name&&e.icon===t.icon&&e.productId===t.productId&&e.isDynamicHost===t.isDynamicHost&&e.suffixAddress===t.suffixAddress&&e.showType===t.showType&&e.rawShowType===t.rawShowType&&e.description===t.description&&e.currencySource===t.currencySource&&e.currencyType===t.currencyType&&e.gamePath===t.gamePath&&e.subGameName===t.subGameName&&e.gamePreviewUrl===t.gamePreviewUrl&&e.gamePreviewWidth===t.gamePreviewWidth&&e.gamePreviewHeight===t.gamePreviewHeight}(e.body.miniProgram,t.body.miniProgram)&&function(e,t){return void 0===e||void 0===t?e===t:JSON.stringify(e.modules)===JSON.stringify(t.modules)&&JSON.stringify(e.commands)===JSON.stringify(t.commands)}(e.body.robot,t.body.robot)&&function(e,t){return void 0===e||void 0===t?e===t:e.gameType===t.gameType&&e.value===t.value}(e.body.game,t.body.game)&&function(e,t){return void 0===e||void 0===t?e===t:e.fromUid===t.fromUid&&e.toUid===t.toUid&&e.fromUserName===t.fromUserName&&e.toUserName===t.toUserName&&e.amount===t.amount&&e.currencyType===t.currencyType&&e.status===t.status&&e.serialNumber===t.serialNumber&&e.remark===t.remark&&e.sessionType===t.sessionType&&e.transferTime===t.transferTime&&e.receiveTime===t.receiveTime&&e.returnTime===t.returnTime&&e.isRead===t.isRead&&e.transferMsgId===t.transferMsgId&&e.coinName===t.coinName&&e.coinIcon===t.coinIcon}(e.body.transfer,t.body.transfer)&&function(e,t){return void 0===e||void 0===t?e===t:e.fromUid===t.fromUid&&e.toUid===t.toUid&&e.fromUserName===t.fromUserName&&e.toUserName===t.toUserName&&e.giftType===t.giftType&&e.giftName===t.giftName&&e.giftIcon===t.giftIcon&&e.explain===t.explain&&e.state===t.state&&e.serialNumber===t.serialNumber&&e.sessionType===t.sessionType&&e.initiateTime===t.initiateTime&&e.amount===t.amount&&e.receiveTime===t.receiveTime&&e.returnTime===t.returnTime&&e.isRead===t.isRead&&e.zhangCount===t.zhangCount&&e.benCount===t.benCount&&e.fissionNumber===t.fissionNumber}(e.body.gift,t.body.gift)&&function(e,t){return void 0===e||void 0===t?e===t:e.callKind===t.callKind&&e.outcome===t.outcome&&e.durationMs===t.durationMs&&e.outgoing===t.outgoing}(e.body.call,t.body.call)&&function(e,t){return void 0===e||void 0===t?e===t:e.packetId===t.packetId&&e.packetType===t.packetType&&e.amount===t.amount&&e.count===t.count&&e.showAmount===t.showAmount&&e.thunderRate===t.thunderRate&&e.isThunder===t.isThunder&&e.thunderNumber===t.thunderNumber&&e.fromUid===t.fromUid&&e.toUid===t.toUid&&e.currencyType===t.currencyType&&e.coinName===t.coinName}(e.body.redPacket,t.body.redPacket)&&l(e.body.mediaAlbum,t.body.mediaAlbum)&&function(e,t){return void 0===e||void 0===t?e===t:e.reason===t.reason}(e.body.unknown,t.body.unknown)&&function(e,t){return void 0===e||void 0===t?e===t:e.code===t.code&&e.reason===t.reason}(e.failure,t.failure)}export{s as dedupeById,v as isMessageEqual,a as mergeMessage,r as mergeReceipt,d as mergeSendStatus};
|
|
1
|
+
import{encodeConversationKey as e}from"../conversation-identity.js";import{mergeMessageReactions as t}from"../state/message-reactions.js";import{resolveMessageServerTime as i,computeMessageSortKey as n}from"./sort.js";const o={unread:0,delivered:1,read:2};function r(e,t){return o[t]>o[e]?t:e}function d(e,t){return"sent"===e||"sent"===t?"sent":t}function a(e,o,a=""){const s=i(e)??0,c=i(o)??0,y=c>=s,u=y?{...e,...o}:{...o,...e},l=!0===e.readBySelf||!0===o.readBySelf,v=Math.max(s,c),p=Math.min(e.createdAt,o.createdAt),f=void 0===e.extensions&&void 0===o.extensions?void 0:y?{...e.extensions,...o.extensions}:{...o.extensions,...e.extensions},b=n({...u,createdAt:p,serverTime:v,extensions:f}),g="failed"===e.status&&!1===e.failure?.retryable&&"sent"===o.status?"failed":d(e.status,o.status),h="failed"===g?o.failure??e.failure:void 0,T=t(e.reactions,o.reactions,a),N=!0===e.encryption.decryptFailed,U=!0===o.encryption.decryptFailed;let w=u.contentType,I=u.body,A=u.encryption,x=u.mention;N&&!U?(w=o.contentType,I=o.body,A=o.encryption,x=o.mention):!N&&U&&(w=e.contentType,I=e.body,A=e.encryption,x=e.mention),!0!==o.edited||U||(w=o.contentType,I=o.body,A=o.encryption,x=o.mention);const z=e.body.voice?.waveform??o.body.voice?.waveform;if(void 0!==I.voice&&void 0===I.voice.waveform&&void 0!==z&&(I={...I,voice:{...I.voice,waveform:z}}),void 0!==I.video&&void 0===I.video.size){const t=I.video,i=[e.body.video,o.body.video].find(e=>"bytes"===e?.sizeUnit&&void 0!==e.size&&e.url===t.url&&e.fileEncryptType===t.fileEncryptType&&e.md5===t.md5&&m(e.teaKey,t.teaKey)&&(void 0===t.unverifiedFileLength||t.unverifiedFileLength===String(e.size)));void 0!==i&&(I={...I,video:{...t,size:i.size,sizeUnit:"bytes"}})}const E=!0===e.edited||!0===o.edited,S=e.deletedForEveryone??o.deletedForEveryone;if(void 0!==S){const t={...u,...l?{readBySelf:!0}:{},id:e.id,createdAt:p,serverTime:v>0?v:void 0,status:g,failure:h,receipt:r(e.receipt,o.receipt),sortKey:b,extensions:f,recalled:void 0,deletedForEveryone:S,body:{},encryption:u.encryption};return delete t.reactions,t}const k=e.recalled??o.recalled;if(void 0!==k){const t={...u,...l?{readBySelf:!0}:{},id:e.id,createdAt:p,serverTime:v>0?v:void 0,status:g,failure:h,receipt:r(e.receipt,o.receipt),sortKey:b,extensions:f,recalled:k,body:{},encryption:u.encryption};return delete t.reactions,t}const K={...u,...l?{readBySelf:!0}:{},id:e.id,createdAt:p,serverTime:v>0?v:void 0,status:g,failure:h,receipt:r(e.receipt,o.receipt),sortKey:b,extensions:f,contentType:w,body:I,encryption:A,...void 0===T?{}:{reactions:T},...E?{edited:!0}:{}};return void 0!==x?K.mention=x:delete K.mention,K}function s(t,i=""){const n=/* @__PURE__ */new Map;for(const o of t){const t=JSON.stringify([e(o),o.id]),r=n.get(t);n.set(t,void 0===r?o:a(r,o,i))}return[...n.values()]}function c(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.fileName===t.fileName&&e.size===t.size&&e.extension===t.extension&&e.fileType===t.fileType&&e.mimeType===t.mimeType&&e.md5===t.md5&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)}function y(e,t){return e===t||void 0!==e&&void 0!==t&&JSON.stringify(e)===JSON.stringify(t)}function u(e,t){return void 0===e||void 0===t?e===t:e.atAll===t.atAll&&e.atUserIds.length===t.atUserIds.length&&(!e.atUserIds.some((e,i)=>e!==t.atUserIds[i])&&function(e,t){if(void 0===e||void 0===t)return e===t;const i=Object.keys(e);return i.length===Object.keys(t).length&&i.every(i=>e[i]===t[i])}(e.atUsersName,t.atUsersName))}function m(e,t){return void 0===e||void 0===t?e===t:e.length===t.length&&e.every((e,i)=>e===t[i])}function l(e,t){return void 0===e||void 0===t?e===t:e.caption===t.caption&&e.items.length===t.items.length&&e.items.every((e,i)=>function(e,t){return e.kind===t.kind&&e.url===t.url&&e.width===t.width&&e.height===t.height&&e.durationMs===t.durationMs&&e.thumbUrl===t.thumbUrl&&m(e.thumbData,t.thumbData)&&e.md5===t.md5&&e.size===t.size&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)&&e.hd===t.hd}(e,t.items[i]))}function v(e,t){return e.id===t.id&&e.conversationId===t.conversationId&&e.conversationType===t.conversationType&&e.senderId===t.senderId&&e.contentType===t.contentType&&JSON.stringify(e.body.customerService)===JSON.stringify(t.body.customerService)&&e.body.text===t.body.text&&function(e,t){return void 0===e||void 0===t?e===t:e.eventType===t.eventType&&e.timelineVisibility===t.timelineVisibility&&e.operatorId===t.operatorId&&e.rawNotifyType===t.rawNotifyType&&e.errcode===t.errcode&&e.fallbackText===t.fallbackText&&function(e,t){return void 0===e||void 0===t?e===t:e.length===t.length&&e.every((e,i)=>e===t[i])}(e.targetUserIds,t.targetUserIds)&&y(e.payload,t.payload)&&y(e.action,t.action)&&y(e.pinnedMessageAction,t.pinnedMessageAction)}(e.body.system,t.body.system)&&e.createdAt===t.createdAt&&e.sortKey===t.sortKey&&e.status===t.status&&e.serverTime===t.serverTime&&e.receipt===t.receipt&&e.readBySelf===t.readBySelf&&e.refMessageId===t.refMessageId&&e.edited===t.edited&&(e.recalled?.by??"")===(t.recalled?.by??"")&&(e.recalled?.at??0)===(t.recalled?.at??0)&&(e.deletedForEveryone?.by??"")===(t.deletedForEveryone?.by??"")&&(e.deletedForEveryone?.at??0)===(t.deletedForEveryone?.at??0)&&(e.deletedForEveryone?.reason??"")===(t.deletedForEveryone?.reason??"")&&function(e,t){return void 0===e||void 0===t?e===t:e.version===t.version&&e.total===t.total&&e.currentUserEmoji===t.currentUserEmoji&&e.events.length===t.events.length&&e.events.every((e,i)=>{const n=t.events[i];return void 0!==n&&e.id===n.id&&e.senderId===n.senderId&&e.emoji===n.emoji&&e.action===n.action&&e.createdAt===n.createdAt})}(e.reactions,t.reactions)&&e.encryption.encrypted===t.encryption.encrypted&&e.encryption.scheme===t.encryption.scheme&&e.encryption.decryptFailed===t.encryption.decryptFailed&&u(e.mention,t.mention)&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.width===t.width&&e.height===t.height&&m(e.thumbData,t.thumbData)&&e.md5===t.md5&&e.imageType===t.imageType&&e.size===t.size&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)}(e.body.image,t.body.image)&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.width===t.width&&e.height===t.height&&e.duration===t.duration&&e.durationUnit===t.durationUnit&&e.sizeUnit===t.sizeUnit&&e.unverifiedFileLength===t.unverifiedFileLength&&m(e.thumbData,t.thumbData)&&e.md5===t.md5&&e.size===t.size&&e.describe===t.describe&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)}(e.body.video,t.body.video)&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.durationMs===t.durationMs&&e.size===t.size&&e.md5===t.md5&&e.fileEncryptType===t.fileEncryptType&&m(e.teaKey,t.teaKey)&&(e.waveform?.length??0)===(t.waveform?.length??0)}(e.body.voice,t.body.voice)&&c(e.body.file,t.body.file)&&(void 0===e.body.filesAlbum||void 0===t.body.filesAlbum?e.body.filesAlbum===t.body.filesAlbum:e.body.filesAlbum.caption===t.body.filesAlbum.caption&&e.body.filesAlbum.items.length===t.body.filesAlbum.items.length&&e.body.filesAlbum.items.every((e,i)=>c(e,t.body.filesAlbum.items[i])))&&function(e,t){return void 0===e||void 0===t?e===t:e.url===t.url&&e.width===t.width&&e.height===t.height&&e.exprType===t.exprType&&e.imageType===t.imageType&&e.size===t.size&&e.describe===t.describe&&e.contentId===t.contentId&&e.packageName===t.packageName&&m(e.thumbData,t.thumbData)}(e.body.sticker,t.body.sticker)&&function(e,t){return void 0===e||void 0===t?e===t:e.targetId===t.targetId&&e.avatar===t.avatar&&e.displayName===t.displayName&&e.username===t.username&&e.gender===t.gender&&e.kind===t.kind&&e.rawKind===t.rawKind}(e.body.contact,t.body.contact)&&function(e,t){return void 0===e||void 0===t?e===t:e.appId===t.appId&&e.host===t.host&&e.developerId===t.developerId&&e.name===t.name&&e.icon===t.icon&&e.productId===t.productId&&e.isDynamicHost===t.isDynamicHost&&e.suffixAddress===t.suffixAddress&&e.showType===t.showType&&e.rawShowType===t.rawShowType&&e.description===t.description&&e.currencySource===t.currencySource&&e.currencyType===t.currencyType&&e.gamePath===t.gamePath&&e.subGameName===t.subGameName&&e.gamePreviewUrl===t.gamePreviewUrl&&e.gamePreviewWidth===t.gamePreviewWidth&&e.gamePreviewHeight===t.gamePreviewHeight}(e.body.miniProgram,t.body.miniProgram)&&function(e,t){return void 0===e||void 0===t?e===t:JSON.stringify(e.modules)===JSON.stringify(t.modules)&&JSON.stringify(e.commands)===JSON.stringify(t.commands)}(e.body.robot,t.body.robot)&&function(e,t){return void 0===e||void 0===t?e===t:e.gameType===t.gameType&&e.value===t.value}(e.body.game,t.body.game)&&function(e,t){return void 0===e||void 0===t?e===t:e.fromUid===t.fromUid&&e.toUid===t.toUid&&e.fromUserName===t.fromUserName&&e.toUserName===t.toUserName&&e.amount===t.amount&&e.currencyType===t.currencyType&&e.status===t.status&&e.serialNumber===t.serialNumber&&e.remark===t.remark&&e.sessionType===t.sessionType&&e.transferTime===t.transferTime&&e.receiveTime===t.receiveTime&&e.returnTime===t.returnTime&&e.isRead===t.isRead&&e.transferMsgId===t.transferMsgId&&e.coinName===t.coinName&&e.coinIcon===t.coinIcon}(e.body.transfer,t.body.transfer)&&function(e,t){return void 0===e||void 0===t?e===t:e.fromUid===t.fromUid&&e.toUid===t.toUid&&e.fromUserName===t.fromUserName&&e.toUserName===t.toUserName&&e.giftType===t.giftType&&e.giftName===t.giftName&&e.giftIcon===t.giftIcon&&e.explain===t.explain&&e.state===t.state&&e.serialNumber===t.serialNumber&&e.sessionType===t.sessionType&&e.initiateTime===t.initiateTime&&e.amount===t.amount&&e.receiveTime===t.receiveTime&&e.returnTime===t.returnTime&&e.isRead===t.isRead&&e.zhangCount===t.zhangCount&&e.benCount===t.benCount&&e.fissionNumber===t.fissionNumber}(e.body.gift,t.body.gift)&&function(e,t){return void 0===e||void 0===t?e===t:e.callKind===t.callKind&&e.outcome===t.outcome&&e.durationMs===t.durationMs&&e.outgoing===t.outgoing}(e.body.call,t.body.call)&&function(e,t){return void 0===e||void 0===t?e===t:e.packetId===t.packetId&&e.packetType===t.packetType&&e.amount===t.amount&&e.count===t.count&&e.showAmount===t.showAmount&&e.thunderRate===t.thunderRate&&e.isThunder===t.isThunder&&e.thunderNumber===t.thunderNumber&&e.fromUid===t.fromUid&&e.toUid===t.toUid&&e.currencyType===t.currencyType&&e.coinName===t.coinName}(e.body.redPacket,t.body.redPacket)&&l(e.body.mediaAlbum,t.body.mediaAlbum)&&function(e,t){return void 0===e||void 0===t?e===t:e.reason===t.reason}(e.body.unknown,t.body.unknown)&&function(e,t){return void 0===e||void 0===t?e===t:e.code===t.code&&e.reason===t.reason}(e.failure,t.failure)}function p(e,t){return v(e,{...e,body:t.body,contentType:t.contentType,encryption:t.encryption,edited:t.edited,recalled:t.recalled})}export{s as dedupeById,v as isMessageEqual,p as isMessageRecoveryBodyEqual,a as mergeMessage,r as mergeReceipt,d as mergeSendStatus};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{resolveMessageServerTime as e}from"../mapping/sort.js";function n(n,o,r){const s=n.conversationType;if("direct"!==s&&"group"!==s&&"channel"!==s)return;let i=r?.serverTime??0;const t=new Set(r?.messageIds);for(const n of o){const o=e(n);void 0===o||o<i||(o>i&&(i=o,t.clear()),t.add(n.id))}return 0===i?void 0:{kind:"conversation-deletion-boundary",conversation:{conversationType:s,conversationId:n.conversationId},serverTime:i,messageIds:[...t]}}function o(n,o){const r=e(n);return void 0!==r&&(r>o.serverTime||r===o.serverTime&&!o.messageIds.includes(n.id))}function r(n){if("object"!=typeof n||null===n)throw new Error("会话删除位置格式无效");const o=n,r=n,s="group-deletion-boundary"===r.kind?{conversationType:"group",conversationId:r.conversationId}:"conversation-deletion-boundary"===o.kind?o.conversation:void 0;if("object"!=typeof s||null===s||!["direct","group","channel"].includes(s.conversationType)||"string"!=typeof s.conversationId||""===s.conversationId||void 0===e(o)||!Array.isArray(o.messageIds)||0===o.messageIds.length||o.messageIds.some(e=>"string"!=typeof e||""===e))throw new Error("会话删除位置格式无效");return{kind:"conversation-deletion-boundary",conversation:{conversationType:s.conversationType,conversationId:s.conversationId},serverTime:o.serverTime,messageIds:[...o.messageIds]}}export{n as captureConversationDeletionBoundary,o as isAfterConversationDeletion,r as parseConversationDeletionBoundary};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{encodeConversationKey as e,conversationRefFromMessage as t,conversationRefFromPinnedMessage as n,conversationRefFromSession as o}from"../conversation-identity.js";import{compareChannelReadPosition as r,getChannelReadOrder as s}from"../mapping/channel-read-position.js";import{collectTransferStatusBySerialNumber as i,synchronizeTransferStatusMessages as a,applyTransferStatusToBody as c}from"../mapping/transfer-status.js";import{parseChannelSyncCheckpoint as d,channelSyncCheckpointKey as u}from"../sync/channel-sync-checkpoint.js";import{createDraftStore as l}from"./draft-store.js";import{rollbackMessageReaction as v,applyMessageReaction as f}from"./message-reactions.js";import{createMessageStore as p}from"./message-store.js";import{createMessageWindowStore as y}from"./message-window-store.js";import{createPinnedMessageStore as m}from"./pinned-message-store.js";import{createReadStore as g}from"./read-store.js";import{sortSessions as h}from"./session-sort.js";import{createSessionStore as C}from"./session-store.js";import{createImTextSearchMatcher as w,extractSearchText as I}from"../mapping/search-text.js";import{normalizeStoredMessageContent as T,LOCAL_MEDIA_ERROR_CODE as M,failInterruptedUpload as S}from"../mapping/stored-message.js";import{isMessageVisibleInTimeline as b,lastMessageSummaryEqual as U,sessionFromMessage as K}from"../mapping/session-mapper.js";import{isMessageEqual as E,dedupeById as A,mergeMessage as R}from"../mapping/merge.js";import{newClientMessageId as P}from"../mapping/message-id.js";import{computeSortKey as N,resolveMessageTimestamp as x,computeMessageSortKey as $}from"../mapping/sort.js";import{backfillGroupMention as D}from"../mapping/group-message-mapper.js";import{isConversationUnreadMessage as B}from"../mapping/unread-divider.js";function j(e){return"direct"===e||"robot"===e||"customerService"===e?"local":"server"}function F(e,t){const n=t?.includeMuted??!1;let o=0;for(const t of e)!n&&t.muted||(o+=t.unreadCount>0?t.unreadCount:!0===t.manuallyUnread?1:0);return o}const L="im:deleted-conversations",_="im:terminated-conversations",k="im:membership-reset-sort-keys",O="im:pending-message-reactions",H="im:transfer-status-records",z=["sendMessages","mentionAll","editProfile","manageMembers","manageAdmins","moderateMessages","manageMute","dismissChannel","transferOwnership"];function q(e,t){return e===t||void 0!==e&&void 0!==t&&z.every(n=>e[n]===t[n])}function G(e,t){return e===t||void 0!==e&&void 0!==t&&e.role===t.role&&e.baseState===t.baseState&&e.resolvedState===t.resolvedState&&e.allMembersMuted===t.allMembersMuted&&e.currentUserMuted===t.currentUserMuted&&e.mutePeriod===t.mutePeriod}function W(e,t){return e.id===t.id&&e.type===t.type&&e.title===t.title&&e.avatar===t.avatar&&U(e.lastMessageSummary,t.lastMessageSummary)&&e.timestamp===t.timestamp&&e.unreadCount===t.unreadCount&&(e.manuallyUnread??!1)===(t.manuallyUnread??!1)&&(e.mentionUnreadCount??0)===(t.mentionUnreadCount??0)&&e.pinned===t.pinned&&e.muted===t.muted&&e.topTime===t.topTime&&e.lastMessageSendState===t.lastMessageSendState&&e.lastMessageReceipt===t.lastMessageReceipt&&e.readCursor===t.readCursor&&e.groupState===t.groupState&&e.channelState===t.channelState&&q(e.channelPermissions,t.channelPermissions)&&G(e.channelAccessSnapshot,t.channelAccessSnapshot)&&e.sendDisabledReason===t.sendDisabledReason}function J(U){const z=p({getSelfId:U.getSelfId}),J=/* @__PURE__ */new Map,Q=/* @__PURE__ */new Map,V=C(),X=C(),Y=g(),Z=l(),ee=m(),te=/* @__PURE__ */new Map,ne=/* @__PURE__ */new Map;let oe=0;function re(e){ne.set(e,++oe)}let se=1;const ie=/* @__PURE__ */new Set,ae=/* @__PURE__ */new Set,ce=/* @__PURE__ */new Map,{storage:de}=U;let ue=Promise.resolve();const le=/* @__PURE__ */new Map,ve=/* @__PURE__ */new Map,fe=/* @__PURE__ */new Map;let pe=0;const ye=U.unreadMode??j,me=/* @__PURE__ */new Set;function ge(e={}){const t=y({storage:de,loadOlderFromRemote:U.loadOlderFromRemote,loadNewerFromRemote:U.loadNewerFromRemote,shouldIncludeMessage:qe,normalizeStoredUpload:qt,...e});return me.add(t),t}const he=ge();function Ce(e,t){let n;for(const o of me){const r=o.list().find(n=>n.id===e&&n.conversationId===t);if(void 0!==r){if(void 0!==n&&n.conversationType!==r.conversationType)throw new Error(`裸 conversationId 存在多类型消息歧义:${t}`);n=r}}return n}function we(e,t){const n=z.get(t,e);if(n?.conversationId===e.conversationId&&n.conversationType===e.conversationType)return n;for(const n of me){const o=n.list().find(n=>n.id===t&&n.conversationId===e.conversationId&&n.conversationType===e.conversationType);if(void 0!==o)return o}}function Ie(e,n){const o=we(t(e),e.id);void 0===o||z.has(e.id,e)||z.upsert(o);const r=z.upsert(e,n);return{...r,previous:o,changed:void 0===o?r.changed:!E(o,r.message)}}function Te(e){const t=new Map(z.getByConversation(e).map(e=>[e.id,e]));for(const n of me)if(Me(n,e))for(const o of n.list())o.conversationType!==e.conversationType||o.conversationId!==e.conversationId||t.has(o.id)||t.set(o.id,o);return[...t.values()].sort((e,t)=>e.sortKey.localeCompare(t.sortKey))}function Me(t,n){const o=t.info();return void 0===o.conversation?o.conversationId===n.conversationId:e(o.conversation)===e(n)}let Se=!1;function be(t){return`${e(t.conversation)}\0${t.parentMessageId}`}function Ue(){if(void 0===de||Se)return;const e=[...J.values()].flat();ft(()=>de.setMeta(O,e)).catch(e=>Je("保存待处理 Reaction 失败",e))}function Ke(e){const t=e.body.transfer;if("transfer"!==e.contentType||void 0===t)return e;const n=Q.get(t.serialNumber);if(void 0===n||0!==t.status&&0===n.status)return e;const o={...t,status:n.status,...1===n.status&&void 0!==n.occurredTime?{receiveTime:n.occurredTime}:{},...2===n.status||3===n.status?{returnTime:n.occurredTime??t.returnTime}:{}};return t.status===o.status&&t.receiveTime===o.receiveTime&&t.returnTime===o.returnTime&&t.isRead===o.isRead?e:{...e,body:{transfer:c(t,o)}}}function Ee(t,n){const o=`${e(t)}\0${n}`;return!!J.delete(o)&&(Ue(),!0)}function Ae(t){const n=`${e(t)}\0`;let o=!1;for(const e of J.keys())e.startsWith(n)&&(J.delete(e),o=!0);return o&&Ue(),o}function Re(e,t){const n=we(e.conversation,e.parentMessageId);if(void 0===n){const t=be(e),n=J.get(t)??[];return n.some(t=>t.id===e.id)?"duplicate":(J.set(t,[...n,e]),Ue(),"pending")}if(at(n),void 0!==n.recalled||void 0!==n.deletedForEveryone)return"duplicate";const o=f(n.reactions,e,U.getSelfId?.()??"");return o===n.reactions?"duplicate":(Jt([{...n,reactions:o}],t),"applied")}function Pe(n,o){const r=t(n),s=`${e(r)}\0${n.id}`,i=J.get(s);if(void 0!==i){J.delete(s),Ue();for(const e of i)Re(e,o)}}function Ne(e){for(const t of[...J.values()]){const n=t[0];if(void 0===n)continue;const o=we(n.conversation,n.parentMessageId);void 0!==o&&(void 0!==o.recalled||void 0!==o.deletedForEveryone?Ee(n.conversation,n.parentMessageId):Pe(o,e))}}let xe=0;const $e=/* @__PURE__ */new Map,De=/* @__PURE__ */new Map,Be=/* @__PURE__ */new Map,je=/* @__PURE__ */new Map,Fe=/* @__PURE__ */new Map;function Le(t){return e(t)}function _e(e){return ke(e)||ie.has(Le(e))||ie.has(e.conversationId)}function ke(e){return ae.has(Le(e))||ae.has(e.conversationId)}function Oe(e){const t=ie.delete(Le(e)),n=ie.delete(e.conversationId);return t||n}function He(e){const t=Oe(e),n=ae.delete(Le(e)),o=ae.delete(e.conversationId);return{deleted:t,terminal:n||o}}function ze(e,t){if(""===t||"system"!==e.contentType)return!1;const n=e.body.system;return!0===n?.targetUserIds?.includes(t)&&("group"===e.conversationType?"group_member_joined"===n.eventType||"group_member_invited"===n.eventType:"channel"===e.conversationType&&("channel_member_joined"===n.eventType||"channel_member_invited"===n.eventType||"channel_created"===n.eventType))}function qe(n){const o=t(n);if(ke(o)||_e(o)&&void 0===X.get(o))return!1;if("group"!==o.conversationType)return!0;const r=ce.get(e(o));return void 0===r||n.sortKey>=r}function Ge(t){const n=e(t),o=(De.get(n)??0)+1;return De.set(n,o),o}function We(t){const n=e(t),o=($e.get(n)??0)+1;return $e.set(n,o),o}function Je(e,t){U.emitter.emit({type:"error",error:{scope:"storage",message:e,cause:t}})}function Qe(e){U.emitter.emit({type:"session:updated",session:e,conversation:o(e)})}const Ve=/* @__PURE__ */new Set,Xe=/* @__PURE__ */new Set,Ye=/* @__PURE__ */new Map,Ze=/* @__PURE__ */new Map;let et=0,tt=Promise.resolve(),nt=0,ot=Promise.resolve(),rt=0;const st=/* @__PURE__ */new Map;let it;function at(n){const o=e(t(n));it?.keys.has(o)&&it.messages.set(`${o}\0${n.id}`,n)}function ct(t){const n=e(t);st.set(n,(st.get(n)??0)+1)}function dt(e){return it?.writes.push(e),void 0!==it&&e.catch(()=>{}),e}async function ut(e){const t=(await Promise.allSettled(e)).find(e=>"rejected"===e.status);if(void 0!==t)throw t.reason}function lt(e){const t=ot.then(e);return ot=t.then(()=>{},()=>{}),t}function vt(t,n){const o=rt,r=t.map(t=>[e(t),st.get(e(t))??0]);return()=>o===rt&&n()&&r.every(([e,t])=>(st.get(e)??0)===t)}function ft(e){const t=0===nt?(()=>{try{return e()}catch(e){return Promise.reject(e)}})():tt.then(e),n=t.then(()=>{},()=>{});Ve.add(n),n.finally(()=>Ve.delete(n));for(const e of Xe)e.writes.push(t);return dt(t)}function pt(e){nt+=1;const t=Promise.all([...Ve]),n=tt.then(()=>t).then(e);return tt=n.then(()=>{},()=>{}),tt.finally(()=>{nt-=1}),dt(n)}function yt(e){const t=e.body.system;if(void 0===t?.pinnedMessageAction)return e;const{pinnedMessageAction:n,...o}=t;return{...e,body:{...e.body,system:o}}}function mt(n){if(void 0!==de&&!Se&&0!==n.length){for(const o of Xe)for(const r of n)o.messages.add(`${e(t(r))}\0${r.id}`);ft(()=>de.saveMessages(n.map(yt))).catch(e=>Je("消息落盘失败",e))}}function gt(e){const{lastMessageSendState:t,manuallyUnread:n,...o}=e;return o}function ht(t){if(void 0!==de&&!Se){for(const n of Xe)n.sessions.add(e(o(t)));ft(()=>de.saveSessions([gt(t)])).catch(e=>Je("会话落盘失败",e))}}function Ct(e,t,n){if(void 0===de||Se)return;const o=++et;Ye.set(e,{version:o,persist:()=>Ct(e,t,n)});for(const t of Xe)t.metadata.add(e);const r=Ze.get(e),s=ft(()=>void 0===r?de.setMeta(e,t()):r.then(()=>de.setMeta(e,t()))),i=s.then(()=>{},()=>{});Ze.set(e,i),i.then(()=>{Ze.get(e)===i&&Ze.delete(e)}),s.then(()=>{Ye.get(e)?.version===o&&Ye.delete(e)},e=>Je(n,e))}function wt(){Ct(L,()=>[...ie],"删除会话标记保存失败")}function It(){Ct(_,()=>[...ae],"成员资格终止标记保存失败")}function Tt(){Ct(k,()=>[...ce.entries()],"重新入群的历史起点保存失败")}function Mt(t){if(void 0!==de&&!Se){for(const n of Xe)void 0!==t.conversationType&&n.reads.add(e({conversationType:t.conversationType,conversationId:t.conversationId}));ft(()=>de.saveReadState(t)).catch(e=>Je("已读态落盘失败",e))}}function St(t){if(e(t),"supergroup"===t.conversationType)throw new Error("supergroup 草稿未实现,不得 fallback 到其他会话类型")}function bt(e){return St(e),Object.freeze({conversationType:e.conversationType,conversationId:e.conversationId})}function Ut(e,t,n){if(St(e),"string"!=typeof t.text)throw new TypeError("草稿 text 必须是字符串");if(void 0!==t.attachments&&t.attachments.length>0)throw new Error("草稿附件尚未支持:attachments 只接受空集合");if(void 0!==t.mentions&&!Array.isArray(t.mentions))throw new TypeError("草稿 mentions 必须是数组");const o=(t.mentions??[]).map(e=>{if("string"!=typeof e.userId||""===e.userId.trim()||"string"!=typeof e.displayName)throw new TypeError("草稿 mention 必须包含非空 userId 与字符串 displayName");return Object.freeze({userId:e.userId,displayName:e.displayName})}),r=Object.freeze({conversationType:e.conversationType,conversationId:e.conversationId});return Object.freeze({ref:r,text:t.text,mentions:Object.freeze(o),...void 0===t.replyToMessageId?{}:{replyToMessageId:t.replyToMessageId},attachments:Object.freeze([]),updatedAt:n})}function Kt(e,t){return e.text===t.text&&e.replyToMessageId===t.replyToMessageId&&e.mentions.length===t.mentions.length&&e.mentions.every((e,n)=>{const o=t.mentions[n];return void 0!==o&&e.userId===o.userId&&e.displayName===o.displayName})}function Et(t,n){St(t);const o=e(t),r=(le.get(o)??Promise.resolve()).catch(()=>{}).then(n),s=r.then(()=>{},()=>{});return le.set(o,s),s.finally(()=>{le.get(o)===s&&le.delete(o)}),r}async function At(t,n){const o=bt(t),r=e(o);if(void 0!==n&&(!Number.isFinite(n)||n<0))throw new Error(`草稿 expectedUpdatedAt 非法:${n}`);const s=pe,i=fe.get(r)??0;return await Et(o,async()=>{const e=Z.get(o);if(null===e||void 0!==n&&e.updatedAt!==n)return!1;if(void 0!==de&&await de.deleteDraft(o),s!==pe||i!==(fe.get(r)??0))throw new Error("草稿状态已失效,拒绝过期清理回灌内存");return Z.delete(o),U.emitter.emit({type:"draft:cleared",conversation:o}),!0})}function Rt(t,n,o,r,s){const i=cn(t);if(void 0===i)return;const a={...i,...void 0===s||s===De.get(e(t))?{title:n,avatar:o??i.avatar}:{},...void 0!==r?{muted:r}:{}};W(i,a)||dn(a)}function Pt(t,n){const o=U.profile;if(void 0===o)return Promise.resolve(null);const r={conversationType:"direct",conversationId:t},s=e(r),i=Fe.get(t);if(!0!==n?.forceRefresh&&void 0!==i&&i.revision===$e.get(s))return i.promise;const a=xe,c=We(r),d=Ge(r),u=(async()=>{const e=await o.getUserProfile(t,n);if(null!==e&&e.id===t&&a===xe&&c===$e.get(s)){const n=e.remark?.trim()?e.remark:e.nickname||t;Rt(r,n,e.avatar??"",e.muted,d)}return e})().finally(()=>{Fe.get(t)?.promise===u&&Fe.delete(t)});return Fe.set(t,{revision:c,promise:u}),u}async function Nt(t,n){const{conversationId:o,conversationType:r}=t;if("direct"===r){try{await Pt(o,!0===n?.force?{forceRefresh:!0}:void 0)}catch(e){U.emitter.emit({type:"error",error:{scope:"http",message:"会话资料补齐失败",cause:e}})}return!1}const s=e(t),i=!0===n?.force;if(!i&&(je.has(s)||Be.has(s)))return!1;const a=xe,c=We(t),d=Ge(t);i&&je.set(s,c);const{profile:u,channelProfile:l}=U,v=i?{forceRefresh:!0}:void 0;try{if("group"===r){if(void 0===u)return!1;const e=await u.getGroupProfile(o,v);if(a!==xe||c!==$e.get(s))return!1;null!==e&&(Rt(t,e.name,e.avatar??"",e.muted,d),3===e.status&&an({conversationType:"group",conversationId:o},"group_dismissed"),i&&U.emitter.emit({type:"profile:updated",profileType:"group",id:o}))}else if("channel"===r){if(void 0===l)return!1;const e=await l.getProfile(o,v);if(a!==xe||c!==$e.get(s))return!1;if(null!==e){Rt(t,e.name,e.avatar??"",e.muted,d);const r=cn(t)?.channelState,s="left"===r||"removed"===r||"dismissed"===r,a="left"===e.channelState||"removed"===e.channelState||"dismissed"===e.channelState;if(!0===n?.allowChannelRecovery&&s&&"dismissed"!==r&&"active"===e.channelState)return on(o,"active",void 0,{permissions:e.permissions,...void 0===e.accessSnapshot?{}:{snapshot:e.accessSnapshot}}),i&&U.emitter.emit({type:"channel-profile:updated",channelId:o,conversation:{conversationType:"channel",conversationId:o}}),!0;const c=s&&(!a||"dismissed"===r||"dismissed"!==e.channelState);if(a&&!c)return an({conversationType:"channel",conversationId:o},`channel_${e.channelState}`),i&&U.emitter.emit({type:"channel-profile:updated",channelId:o,conversation:{conversationType:"channel",conversationId:o}}),!1;if(!c){const t=e.permissions.sendMessages?void 0:`channel_${e.channelState}`;on(o,e.channelState,t,{permissions:e.permissions,...void 0===e.accessSnapshot?{}:{snapshot:e.accessSnapshot}})}i&&U.emitter.emit({type:"channel-profile:updated",channelId:o,conversation:{conversationType:"channel",conversationId:o}})}}return!1}catch(e){return U.emitter.emit({type:"error",error:{scope:"http",message:"会话资料补齐失败",cause:e}}),!1}finally{i&&a===xe&&je.get(s)===c&&je.delete(s)}}function xt(e){return B(e,U.getSelfId?.()??"")}function $t(e){const t=Y.get(e);if(void 0===t||""===t.readCursor)return;const n="string"==typeof e?t.conversationType:e.conversationType;if("channel"===n){const o={conversationType:n,conversationId:"string"==typeof e?e:e.conversationId};return Te(o).find(e=>e.extensions?.historyCursor===t.readCursor)?.sortKey??t.readCursorSortKey}const o="string"==typeof e?z.getByConversation(e).find(e=>e.id===t.readCursor):we(e,t.readCursor);return o?.sortKey??t.readCursorSortKey}function Dt(e,t){let n=0;for(const o of z.getByConversation(e))b(o)&&xt(o)&&(void 0===t||o.sortKey>t)&&(n+=1);return n}function Bt(e){const t=U.getSelfId?.();if(void 0===t||""===t||e.senderId===t)return!1;const{mention:n}=e;return void 0!==n&&(n.atAll||n.atUserIds.includes(t))}function jt(e,t){let n=0;for(const o of z.getByConversation(e))!0!==o.readBySelf&&Bt(o)&&(void 0===t||o.sortKey>t)&&(n+=1);return n}function Ft(e,t=!0){const n=void 0===e.conversationType?V.get(e.conversationId):void 0,o=void 0===e.conversationType&&void 0!==n?{...e,conversationType:n.type}:e,r=void 0===o.conversationType?o.conversationId:{conversationType:o.conversationType,conversationId:o.conversationId},s=Y.get(r);if("channel"===o.conversationType&&re(o.conversationId),Y.set(o),t&&Mt(o),void 0===s||s.readCursor!==o.readCursor||s.readCursorSortKey!==o.readCursorSortKey||s.unreadCount!==o.unreadCount||(s.manuallyUnread??!1)!==(o.manuallyUnread??!1)){if(void 0===o.conversationType)return void U.emitter.emit({type:"error",error:{scope:"storage",message:`已读状态缺少复合身份,拒绝发布 read:updated(conversationId=${o.conversationId})`}});U.emitter.emit({type:"read:updated",conversationId:o.conversationId,conversation:{conversationType:o.conversationType,conversationId:o.conversationId},readCursor:o.readCursor,unreadCount:o.unreadCount,...!0===o.manuallyUnread?{manuallyUnread:!0}:{}})}}function Lt(n,o){if(void 0===n||n.sortKey===o.sortKey)return;const r=t(o),s=Y.get(r),i="channel"===o.conversationType?o.extensions?.historyCursor:void 0,a="direct"===o.conversationType||"group"===o.conversationType||"robot"===o.conversationType||"customerService"===o.conversationType;void 0!==s&&(a&&s.readCursor===o.id||"string"==typeof i&&""!==i&&s.readCursor===i||s.readCursorSortKey===n.sortKey)&&Ft({...s,readCursorSortKey:o.sortKey});const c=e(r);"group"===o.conversationType&&ce.get(c)===n.sortKey&&(ce.set(c,o.sortKey),Tt())}function _t(e){const t=e?.channelAccessSnapshot?.role;return"owner"===t||"admin"===t}function kt(e,t,n,o,r=cn(e)){const s=o??Y.get(e);if(void 0===t){if(void 0===r){if("string"==typeof e||void 0===s||s.unreadCount<=0)return;return{id:e.conversationId,type:e.conversationType,title:"",lastMessagePreview:"",timestamp:0,unreadCount:s.unreadCount,mentionUnreadCount:s.mentionUnreadCount,readCursor:s.readCursor,pinned:!1,muted:!1}}const t={...r,..."clear"===n?{lastMessagePreview:"",timestamp:0}:{},...void 0===s?{}:{unreadCount:s.unreadCount,manuallyUnread:s.manuallyUnread,mentionUnreadCount:s.mentionUnreadCount,readCursor:s.readCursor||r.readCursor}};return"clear"===n&&(delete t.lastMessageSummary,delete t.lastMessageSenderId,delete t.lastMessageSystemEvent,delete t.lastMessageSystemTargetsSelf,delete t.lastMessageMention,delete t.lastMessageRecalled,delete t.lastMessageDeletedForEveryone,delete t.lastMessageSendState,delete t.lastMessageReceipt),t}const i=s?.unreadCount??r?.unreadCount??0,a=void 0===s?r?.manuallyUnread:s.manuallyUnread,c=K(t,{unreadCount:i,mentionUnreadCount:s?.mentionUnreadCount??r?.mentionUnreadCount??0,selfId:U.getSelfId?.(),showChannelModerationDeleted:_t(r)});return void 0===r?{...c,...void 0===a?{}:{manuallyUnread:a},readCursor:(s?.readCursor??"")||c.readCursor}:{...c,title:r.title||c.title,avatar:r.avatar??c.avatar,pinned:r.pinned,muted:r.muted,topTime:r.topTime,...void 0===a?{}:{manuallyUnread:a},readCursor:(s?.readCursor??"")||r.readCursor,groupState:r.groupState,channelState:r.channelState,channelPermissions:r.channelPermissions,channelAccessSnapshot:r.channelAccessSnapshot,sendDisabledReason:r.sendDisabledReason}}function Ot(e,t){if(void 0===e)return;const n=V.get({conversationType:e.type,conversationId:e.id});void 0!==n&&W(n,e)||(V.set(e),X.delete({conversationType:e.type,conversationId:e.id}),Qe(e),t&&ht(e),""===e.title&&Nt({conversationType:e.type,conversationId:e.id}))}function Ht(e,t,n="preserve",o=cn(e)){const r=t.findLast(e=>function(e,t){return!!b(e)&&("channel"!==e.conversationType||void 0===e.deletedForEveryone||_t(t))}(e,o)),s="string"==typeof e?o?.type:e.conversationType;return kt(e,r,void 0===r&&"channel"===s&&!_t(o)&&(t.some(e=>void 0!==e.deletedForEveryone)||"channel-moderation-deleted"===o?.lastMessageSummary?.kind||void 0!==o?.lastMessageDeletedForEveryone)?"clear":n,void 0,o)}function zt(e,t=!1){(t||void 0!==V.get(e))&&Ot(Ht(e,z.getByConversation(e)),!0)}function qt(e){if("uploading"!==e.status&&("failed"!==e.status||e.failure?.code!==M))return e;const t=z.get(e.id,e);return void 0!==t&&t.conversationType===e.conversationType&&t.conversationId===e.conversationId?t:S(T(e))}function Gt(n,o=()=>!0){const r=[],s=A(n,U.getSelfId?.()??"").map(e=>{const t=qt(e);let n={...t,sortKey:$(t)};if(n=T(n),"group"===n.conversationType&&"text"===n.contentType){const e=D(n.body.text??"",n.mention);void 0!==e&&(n.mention=e)}return Ke(n)}),i=/* @__PURE__ */new Map;for(const n of s){if("transfer"!==n.contentType||void 0===n.body.transfer)continue;const o=t(n);i.set(e(o),o)}const c=[...i.values()].flatMap(e=>Te(e)),d=a(c,s),u=new Set(s.map(e=>e.id));for(const e of d){if(!o())break;const{previous:n,message:s,isNew:i,changed:a}=Ie(e);if(Lt(n,s),void 0!==n&&a)for(const e of me){if(!o())return r;e.list().some(e=>e.id===s.id&&e.conversationType===s.conversationType&&e.conversationId===s.conversationId)&&e.applyIncoming([s])}if(!o())return r;i?U.emitter.emit({type:"message:received",message:s,conversation:t(s),source:"offline",channelLifecycleEffects:!1}):a&&U.emitter.emit({type:"message:updated",message:s,conversation:t(s),source:"offline",channelLifecycleEffects:!1}),u.has(s.id)&&r.push(s)}return r}function Wt(e){const t=qt(e);let n={...t,sortKey:$(t)};if(n=T(n),"group"===n.conversationType&&"text"===n.contentType){const e=D(n.body.text??"",n.mention);void 0!==e&&(n.mention=e)}return Ke(n)}function Jt(n,o,r={}){const s=U.getSelfId?.()??"";if("live"===o){let i=!1,a=!1;for(const c of n){const n=t(c);if(ze(c,s)){const t=He(n);t.deleted&&(i=!0),t.terminal&&("group"===n.conversationType?(ce.set(e(n),c.sortKey),Tt()):"channel"===n.conversationType&&ce.delete(e(n)),U.diagnostics?.record("info","core","conversation","membership-termination-cleared",()=>({conversation:n,data:{source:o,eventType:c.body.system?.eventType,groupHistoryLowerBoundApplied:"group"===n.conversationType}})),a=!0)}else""!==s&&c.senderId===s&&!0!==r.newOutgoing||ke(n)||!Oe(n)||(i=!0)}i&&wt(),a&&It()}const i=!0===U.diagnostics?.isEnabled("debug","conversation")?/* @__PURE__ */new Map:void 0,c=(n,o)=>{if(void 0===i)return;const r=t(n),s=e(r),a=i.get(s)??{ref:r,tombstone:0,groupLowerBound:0};"tombstone"===o?a.tombstone+=1:a.groupLowerBound+=1,i.set(s,a)},d=ie.size>0||ae.size>0?n.filter(e=>{const n=t(e),o=!_e(n)||!0===r.backfillOnly&&void 0!==X.get(n)&&!ke(n);return o||c(e,"tombstone"),o}):n,u=function(n){const o=/* @__PURE__ */new Map;if(0===ce.size)return o;for(const r of A(n,U.getSelfId?.()??"")){if("group"!==r.conversationType)continue;const n=t(r),s=e(n),i=ce.get(s);if(void 0===i)continue;const a=we(n,r.id);if(void 0===a||a.sortKey!==i)continue;const c=R(a,r,U.getSelfId?.()??"");c.sortKey!==i&&(ce.set(s,c.sortKey),o.set(s,c.id))}return o.size>0&&Tt(),o}(d),l=n=>u.get(e(t(n)))===n.id,v=ce.size>0?d.filter(e=>{const t=l(e)||qe(e);return t||c(e,"groupLowerBound"),t}):d,f=0===u.size?v:[...v.filter(l),...v.filter(e=>!l(e))];for(const e of i?.values()??[])U.diagnostics?.record("debug","core","conversation","membership-filter-dropped",()=>({conversation:e.ref,data:{source:o,tombstoneDroppedCount:e.tombstone,groupHistoryLowerBoundDroppedCount:e.groupLowerBound}}));const p=/* @__PURE__ */new Map,y=/* @__PURE__ */new Map,m=/* @__PURE__ */new Map,g=/* @__PURE__ */new Map,h=/* @__PURE__ */new Map,C=/* @__PURE__ */new Set,w=A(f,s).map(Ke),I=/* @__PURE__ */new Map;for(const n of w){if("transfer"!==n.contentType||void 0===n.body.transfer)continue;const o=t(n);I.set(e(o),o)}const T=[...I.values()].flatMap(e=>Te(e)),M=a(T,w),S=[],K=[];for(const n of M){if("channel"===n.conversationType&&it?.keys.has(e(t(n)))&&!it.current())continue;const{previous:s,message:i,isNew:a,changed:c}=Ie(n,{authoritativeFailure:!0===r.authoritativeOutboxFailure});if(at(i),!0===r.backfillOnly&&!0===r.refreshSessionSummary){const n=t(i);p.set(e(n),n)}if(!a&&!c)continue;Lt(s,i);for(const e of me)e.applyIncoming([i]);a?U.emitter.emit({type:"message:received",message:i,conversation:t(i),source:o,channelLifecycleEffects:!0===r.applyChannelLifecycleEffects}):U.emitter.emit({type:"message:updated",message:i,conversation:t(i),source:o,channelLifecycleEffects:!0===r.applyChannelLifecycleEffects});const d=t(i);if(!a&&void 0!==s&&!0!==s.readBySelf&&!0===i.readBySelf){const t=$t(d),n=void 0===t||s.sortKey>t,o=e(d);n&&b(s)&&xt(s)&&void 0===s.recalled&&void 0===s.deletedForEveryone&&m.set(o,(m.get(o)??0)-1),n&&Bt(s)&&void 0===s.recalled&&void 0===s.deletedForEveryone&&h.set(o,(h.get(o)??0)-1)}ke(d)||(S.push(i),p.set(e(d),d),a&&!0!==r.backfillOnly&&K.push(i))}const E=/* @__PURE__ */new Map;for(const n of K){const r=t(n),s=e(r);xt(n)&&C.add(s),E.has(s)||E.set(s,$t(r));const i=E.get(s),a=void 0===i||n.sortKey>i;if(b(n)&&a&&xt(n)&&!0!==n.readBySelf&&void 0===n.recalled&&void 0===n.deletedForEveryone){const e=ye(n.conversationType);("local"===e||"server"===e&&"live"===o)&&y.set(s,(y.get(s)??0)+1)}a&&!0!==n.readBySelf&&Bt(n)&&void 0===n.recalled&&void 0===n.deletedForEveryone&&g.set(s,(g.get(s)??0)+1)}for(const t of p.values()){if(!0===r.backfillOnly){!0===r.refreshSessionSummary&&zt(t);continue}const n=e(t),o=y.get(n)??0,s=g.get(n)??0,i=m.get(n)??0,a=h.get(n)??0,c=C.has(n),d=Y.get(t);if(o>0||s>0||c||void 0!==d&&(0!==i||0!==a)){const e=d??{...t,readCursor:"",unreadCount:0},n={...e,unreadCount:Math.max(0,e.unreadCount+o+i),mentionUnreadCount:Math.max(0,(e.mentionUnreadCount??0)+s+a)};c&&delete n.manuallyUnread,Ft(n)}zt(t,K.some(e=>e.conversationType===t.conversationType&&e.conversationId===t.conversationId&&b(e)))}mt(S.filter(e=>void 0!==we(t(e),e.id)));for(const e of S)void 0===e.recalled&&void 0===e.deletedForEveryone?Pe(e,o):Ee(t(e),e.id)}function Qt(e,t,n=Date.now()){const o={conversationType:"direct",conversationId:e},r=we(o,t),s=z.getByConversation(o).findLast(e=>"direct_contact_established"===e.body.system?.eventType);if(void 0!==r&&void 0!==s&&x(s)>=x(r))return;const i=`${t}:contact-required`;if(void 0!==z.get(i,o))return;Jt([{id:i,conversationId:e,conversationType:"direct",senderId:e,contentType:"system",body:{system:{eventType:"direct_contact_required",targetUserIds:[e],action:{type:"request-contact",userId:e}}},createdAt:n,sortKey:N(n,i),status:"sent",receipt:"unread",encryption:{encrypted:!1,decryptFailed:!1}}],"live")}const Vt=/* @__PURE__ */new Map;let Xt=0;function Yt(e){const t=Y.get(e);if(!0!==t?.manuallyUnread)return!1;const n={...t};return delete n.manuallyUnread,Ft(n),zt(e),!0}function Zt(e,t,n,r,s){const i="string"==typeof e?e:e.conversationId,a=cn(e),c="string"==typeof e?void 0===a?void 0:o(a):e;if(void 0!==a&&"server"!==ye(a.type))return void U.emitter.emit({type:"error",error:{scope:"unknown",message:`applyServerUnread 不应用于本地未读会话(conversationId=${i}, type=${a.type}),已忽略`}});if(!Number.isFinite(t))return void U.emitter.emit({type:"error",error:{scope:"unknown",message:`applyServerUnread 收到非法未读数(conversationId=${i}, count=${t}),已忽略`}});"channel"===c?.conversationType&&te.delete(i);const d=Y.get(e);let u=d?.readCursor??"",l=d?.readCursorSortKey;const v=void 0===n||""===n?void 0:void 0===c?z.getByConversation(i).find(e=>e.id===n)??Ce(n,i):we(c,n);void 0!==v&&v.conversationId===i&&(void 0===l||v.sortKey>l)&&(u=v.id,l=v.sortKey),void 0!==r&&(u=r),Ft({...void 0===c?{conversationId:i}:c,readCursor:u,readCursorSortKey:l,unreadCount:Math.max(0,Math.floor(t)),...t>0?{}:{manuallyUnread:d?.manuallyUnread},mentionUnreadCount:0===t||!1===s?0:!0===s?Math.max(1,d?.mentionUnreadCount??0):d?.mentionUnreadCount}),zt(e,t>0&&void 0!==c&&!_e(c))}function en(e){const t=te.get(e.conversation.conversationId);return t?.handle.transactionId===e.transactionId?t:void 0}function tn(e,t,n,o=!1){const r=cn(e),s=we(e,t);if("channel"!==r?.type||"channel"!==s?.conversationType||s.conversationId!==e.conversationId||s.extensions?.historyCursor!==n)throw new Error(`CHANNEL 已读位置不可信(channelId=${e.conversationId}, messageId=${t})`);o||te.delete(e.conversationId);const i=Y.get(e),a=void 0===i?r.mentionUnreadCount:i.mentionUnreadCount;Ft({...e,readCursor:n,readCursorSortKey:s.sortKey,unreadCount:i?.unreadCount??r.unreadCount,...void 0===a?{}:{mentionUnreadCount:a}}),zt(e)}function nn(e,t,n){const o=e.conversation,r=o.conversationId,i=en(e);if(void 0===i)throw new Error(`CHANNEL 乐观已读事务已失效(channelId=${r})`);const a=we(o,t);if(void 0===a||a.conversationId!==r||"channel"!==a.conversationType)throw new Error(`CHANNEL 乐观已读消息不可信(channelId=${r}, messageId=${t})`);if(a.extensions?.historyCursor!==n)throw new Error(`CHANNEL 乐观已读 cursor 与消息不一致(channelId=${r}, messageId=${t})`);i.steps.at(-1)?.readCursor!==n&&(i.steps.push({readCursor:n,messageId:t,...s(a)}),tn(o,t,n,!0))}function on(t,n,o,r){const s={conversationType:"channel",conversationId:t},i=e(s);if(_e(s)&&void 0===X.get(s))return;const a=cn(s);if(void 0===a){We(s),je.delete(i);return void dn({id:t,type:"channel",title:"",lastMessagePreview:"",timestamp:0,unreadCount:0,pinned:!1,muted:!1,channelState:n,channelPermissions:r?.permissions,channelAccessSnapshot:r?.snapshot,sendDisabledReason:o})}if("channel"!==a.type)throw new Error(`setChannelRestriction: 会话 ${t} 类型为 ${a.type},拒绝写入 CHANNEL 状态`);We(s),je.delete(i);const c=r?.permissions,d=r?.snapshot;if(a.channelState===n&&a.sendDisabledReason===o&&q(a.channelPermissions,c)&&G(a.channelAccessSnapshot,d))return void(void 0!==V.get(s)&&zt(s));const u={...a,channelState:n,channelPermissions:c,channelAccessSnapshot:d,sendDisabledReason:o};void 0!==V.get(s)?dn(Ht(s,z.getByConversation(s),"preserve",u)):dn(u)}async function rn(e,t){if(""===t.trim())throw new Error("本机删除消息需要非空 messageId");const n=()=>{if(ee.isPinnedMessage(e,t))throw Object.assign(new Error("置顶消息必须先取消置顶才能删除"),{code:"IM_MESSAGE_PINNED"})};n();const o=we(e,t),r=z.get(t,e),s=void 0!==r&&r.conversationType===e.conversationType&&r.conversationId===e.conversationId,i=z.getByConversation(e).filter(e=>e.id!==t),a=void 0===V.get(e)?void 0:Ht(e,i,"clear"),c=void 0===a?void 0:gt(a);function d(e){return void 0!==e&&(void 0===r||!E(r,e))}const u=void 0===de?{deleted:!1,superseded:!1}:await pt(async()=>{n();const r=we(e,t)??o??await de.getMessage(e,t)??void 0;if(n(),d(z.get(t,e)))return{deleted:!1,superseded:!0};const s=await de.deleteMessage(e,t,c);if(ee.isPinnedMessage(e,t)){const o=we(e,t)??r;void 0!==o&&await de.saveMessages([yt(o)]);const s=V.get(e);return void 0!==s&&await de.saveSessions([gt(s)]),n(),{deleted:!1,superseded:!0}}return{deleted:s,superseded:!1}});if(u.superseded||d(z.get(t,e)))return!1;const l=s&&z.delete(e,t);let v=!1;for(const n of me)v=n.removeMessage(e,t)||v;if(!u.deleted&&!l&&!v)return!1;const f=void 0===V.get(e)?void 0:Ht(e,z.getByConversation(e),"clear");return Ot(f,!1),void 0===f||void 0!==a&&W(a,f)||ht(f),Ee(e,t),U.emitter.emit({type:"message:removed",conversation:{...e},messageId:t,scope:"local-only"}),!0}function sn(t,o={}){const r="string"==typeof t?t:t.conversationId,s=V.get(t),i=ee.get(t),a="string"==typeof t?void 0!==s?{conversationType:s.type,conversationId:r}:void 0===i?void 0:n(i):t;if(void 0===a)throw new Error(`裸 conversationId 无法确定删除类型:${r}`);Ge(a),Be.delete(e(a)),"direct"===a.conversationType&&(We(a),Fe.delete(a.conversationId)),ct(a);const c=z.getByConversation(a).length;!function(t){const n=bt(t),o=e(n);fe.set(o,(fe.get(o)??0)+1),null!==Z.get(n)&&(Z.delete(n),U.emitter.emit({type:"draft:cleared",conversation:n})),Et(n,async()=>{void 0!==de&&await de.deleteDraft(n)}).catch(e=>Je("删会话草稿失败",e))}(a),Ae(a),V.delete(t),X.delete(t),"channel"===a.conversationType&&(re(a.conversationId),te.delete(a.conversationId)),Y.delete(t),z.deleteByConversation(t),ee.clear(t);const d=Le(a);if(!0===o.terminal){ae.add(d);const e=ce.delete(d);ie.delete(d),ie.delete(r),e&&Tt(),U.diagnostics?.record("info","core","conversation","membership-terminated",()=>({conversation:a,data:{reason:o.terminalReason??"membership-terminated",removedMessageCount:c}}))}else ie.add(d);for(const e of me)Me(e,a)&&e.reset();U.emitter.emit({type:"session:removed",conversationId:r,conversation:a}),wt(),!0===o.terminal&&It(),void 0!==de&&pt(async()=>{await ut([de.deleteConversationMessages(a),de.deleteSession(a),de.deleteReadState(a),de.removePinnedMessage(a)])}).catch(e=>Je("删除会话持久数据失败",e))}function an(e,t){sn(e,{terminal:!0,terminalReason:t})}function cn(e){if("string"==typeof e){const t=[...V.getAll(),...X.getAll()].filter(t=>t.id===e);if(t.length>1)throw new Error(`裸 conversationId 存在多类型歧义:${e}`);return t[0]}return V.get(e)??X.get(e)}function dn(e){const t=o(e);void 0!==V.get(t)?(V.set(e),Qe(e),ht(e)):(X.set(e),U.emitter.emit({type:"conversation-context:updated",conversation:t}))}return{upsertMessages:Jt,commitReceivedMessages:function(n,o,r,s){if(void 0===de){for(const e of s?.events??[])s.apply(e);return void Jt(n,o,r)}const i={writes:[],messages:/* @__PURE__ */new Set,sessions:/* @__PURE__ */new Set,reads:/* @__PURE__ */new Set,metadata:/* @__PURE__ */new Set};Xe.add(i);try{const a=(s?.events??[]).filter(e=>"ignored"!==s.apply(e));Jt(n,o,r);const c=a.flatMap(e=>{const t=we(e.conversation,e.parentMessageId);return void 0===t?[]:[t]});a.length>0&&Ue();const d=/* @__PURE__ */new Map,u=[];for(const o of[...n,...c]){const n=t(o),r=e(n),s=we(n,o.id);void 0!==s&&(d.set(r,n),i.messages.has(`${r}\0${s.id}`)||u.push(s))}mt(u);for(const[e,t]of d){const n=V.get(t),o=Y.get(t);void 0===n||i.sessions.has(e)||ht(n),void 0===o||i.reads.has(e)||Mt(o)}for(const[e,t]of Ye)i.metadata.has(e)||t.persist()}finally{Xe.delete(i)}return ut(i.writes)},applyReaction:Re,rollbackReaction:function(t,n,o){const r=we(t,n);if(void 0===r){const r=`${e(t)}\0${n}`,s=J.get(r);if(void 0===s)return!1;const i=s.filter(e=>e.id!==o);return i.length!==s.length&&(0===i.length?J.delete(r):J.set(r,i),Ue(),!0)}const s=v(r.reactions,o,U.getSelfId?.()??"");if(s===r.reactions)return!1;const i={...r};return void 0===s?delete i.reactions:i.reactions=s,Jt([i],"live"),!0},appendDirectContactRequiredNotice:Qt,appendDirectMessageRefusedNotice:function(e,t,n=Date.now()){const o={conversationType:"direct",conversationId:e},r=`${t}:message-refused`;if(void 0!==z.get(r,o))return;const s=z.get(t,o),i="direct"===s?.conversationType&&s.conversationId===e?x(s):n;Jt([{id:r,conversationId:e,conversationType:"direct",senderId:e,contentType:"system",body:{system:{eventType:"direct_message_refused",targetUserIds:[e]}},createdAt:i,sortKey:N(i,r),status:"sent",receipt:"unread",encryption:{encrypted:!1,decryptFailed:!1}}],"live")},appendDirectContactRequiredTextFailure:function(e,t=Date.now()){const n=P(),o={id:n,conversationId:e.conversationId,conversationType:"direct",senderId:e.senderId,contentType:"text",body:{text:e.text},createdAt:t,sortKey:N(t,n),status:"failed",receipt:"unread",encryption:{encrypted:!1,decryptFailed:!1},failure:{code:33281,reason:"rejected",displayCode:"contactRequired",retryable:!1},...void 0===e.refMessageId?{}:{refMessageId:e.refMessageId}};return Jt([o],"live"),Qt(e.conversationId,n,t+1),o},reconcileDirectContactEstablishedNotice:function(e,t,n=Date.now()){const o=Vt.get(e);if(void 0!==o)return o;const r={conversationType:"direct",conversationId:e},s=Xt,i=(async()=>{const o=z.getByConversation(r).filter(e=>{const t=e.body.system?.eventType;return"direct_contact_required"===t||"direct_contact_established"===t}),i=o.filter(e=>"direct_contact_required"===e.body.system?.eventType),a=i.at(-1)?.createdAt??0,c=o.findLast(e=>"direct_contact_established"===e.body.system?.eventType)?.createdAt??0,d=c>=a&&c>0;if(0===i.length&&d)return;const u=$t(r);for(const e of i)try{const t=await rn(r,e.id),n=we(r,e.id);t||"direct_contact_required"!==n?.body.system?.eventType||U.emitter.emit({type:"error",error:{scope:"storage",message:"联系人关系已建立,但旧的申请添加提示未能删除",cause:{conversation:r,messageId:e.id}}})}catch(t){U.emitter.emit({type:"error",error:{scope:"storage",message:"联系人关系已建立,但删除旧的申请添加提示失败",cause:{conversation:r,messageId:e.id,error:t}}})}if(s!==Xt)return;const l=Y.get(r);if(void 0!==l&&(Ft({...l,...void 0===l.readCursorSortKey&&void 0!==u?{readCursorSortKey:u}:{},unreadCount:Dt(r,u)}),zt(r)),d)return;const v=Number.isFinite(n)&&n>0?n:Date.now(),f=Math.max(v,a+1);!function(e,t,n=Date.now(),o=n){const r=function(e,t){return`${""===e.trim()?`contact-established:${t}`:e}:contact-established`}(t,o);if(void 0!==z.get(r,{conversationType:"direct",conversationId:e}))return;Jt([{id:r,conversationId:e,conversationType:"direct",senderId:e,contentType:"system",body:{system:{eventType:"direct_contact_established",targetUserIds:[e]}},createdAt:n,sortKey:N(n,r),status:"sent",receipt:"unread",encryption:{encrypted:!1}}],"live")}(e,t,f,v)})().finally(()=>{Vt.get(e)===i&&Vt.delete(e)});return Vt.set(e,i),i},recallMessage:function(e,t,n){const o=we(e,t);void 0!==o&&Jt([{...o,recalled:n,body:{}}],"live")},deleteChannelMessageForEveryone:function(e,t,n){const o=we(e,t);void 0!==o&&"channel"===o.conversationType&&Jt([{...o,recalled:void 0,deletedForEveryone:n,body:{}}],"live")},editMessage:function(e,t,n,o){const r=we(e,t);if(void 0===r)return;const s={...r,body:n,edited:!0};void 0!==o?s.mention=o:delete s.mention,Jt([s],"live")},applyTransferStatusBySerialNumber:async function(e,t,n){const o=function(e,t){if(void 0===e)return t;if(0===e.status&&0!==t.status)return t;if(0===t.status&&0!==e.status)return e;const n=e.occurredTime??0,o=t.occurredTime??0;return n!==o?o>n?t:e:t.status>e.status?t:e}(Q.get(e),{serialNumber:e,status:t,...void 0===n?{}:{occurredTime:n}});Q.set(o.serialNumber,o),await async function(){if(void 0===de)return;const e=[...Q.values()],t=ue.then(()=>de.setMeta(H,e));dt(t),ue=t.catch(()=>{});try{await t}catch(e){throw Je("保存转账状态记录失败",e),e}}();const r=/* @__PURE__ */new Map;for(const t of i(z.getAll(),e,o.status,o.occurredTime))r.set(t.id,t);for(const t of V.getAll()){const n=Te({conversationType:t.type,conversationId:t.id});for(const t of i(n,e,o.status,o.occurredTime))r.set(t.id,t)}0!==r.size&&Jt([...r.values()],"live")},getMessage:e=>z.get(e),getMessagesById:e=>z.getById(e),getConversationMessage:we,getLoadedMessagesByConversation:Te,resolveConversationMessage:async function(n,o,r={}){const s=we(n,o);if(void 0!==s||void 0===de)return s;try{const r=await de.getMessage(n,o);if(null===r||e(t(r))!==e(n))return;return Wt(r)}catch(e){if(Je("按消息 ID 读取本地历史失败",e),!0===r.throwOnStorageError)throw e;return}},getMessages:()=>z.getAll(),getMessagesByConversation:e=>z.getByConversation(e),deleteLocalMessage:rn,clearLocalConversationHistory:async function(e){ct(e);const t={...e},n=new Map(z.getByConversation(t).map(e=>[e.id,e])),o=V.get(t),r=Y.get(t),s=void 0===r&&void 0===o?void 0:{...t,readCursor:r?.readCursor??o?.readCursor??"",...void 0===r?.readCursorSortKey?{}:{readCursorSortKey:r.readCursorSortKey},unreadCount:0,mentionUnreadCount:0},i=void 0===o?void 0:kt(t,void 0,"clear",s);if(void 0!==de){if(void 0===de.clearConversationHistory)throw new Error("当前 storage 未实现 clearConversationHistory,拒绝非原子清空本机会话历史");await pt(()=>de.clearConversationHistory(t,void 0===i?void 0:gt(i),s))}const a=Y.get(t);void 0!==s&&(a?.conversationType===r?.conversationType&&a?.conversationId===r?.conversationId&&a?.readCursor===r?.readCursor&&a?.readCursorSortKey===r?.readCursorSortKey&&a?.unreadCount===r?.unreadCount&&a?.mentionUnreadCount===r?.mentionUnreadCount)&&Ft(s,!1);for(const[e,o]of n){const n=z.get(e,t);void 0!==n&&E(o,n)&&z.delete(t,e)}const c=z.getByConversation(t);for(const e of me)e.clearConversation(t)&&e.applyIncoming(c);Ae(t),void 0!==V.get(t)&&Ot(Ht(t,c,"clear"),!1),U.emitter.emit({type:"conversation-history:cleared",conversation:t,scope:"local-only"})},commitChannelSyncPage:function(n,o,r,s){const i=vt(n,r);return lt(async()=>{if(!i())return!1;if(void 0===de)throw new Error("CHANNEL 严格同步提交需要 storage");const r={writes:[],messages:/* @__PURE__ */new Map,keys:new Set(n.map(e)),current:i};let a;it=r;try{const e=o();if(e instanceof Promise)throw e.catch(()=>{}),new Error("CHANNEL 页 mutation 必须同步执行")}catch(e){a={cause:e}}finally{it=void 0}if(await ut(r.writes),void 0!==a)throw a.cause;if(!i())return!1;const c=[...r.messages.values()].flatMap(e=>{const n=we(t(e),e.id);return void 0===n?[]:[yt(n)]}),d=[];c.length>0&&d.push(ft(()=>de.saveMessages(c)));for(const e of n){const t=V.get(e),n=Y.get(e),o=ee.get(e);void 0!==t&&d.push(ft(()=>de.saveSessions([gt(t)]))),void 0!==n&&d.push(ft(()=>de.saveReadState(n))),d.push(ft(()=>void 0===o?de.removePinnedMessage(e):de.savePinnedMessage(o)))}const u=[[O,[...J.values()].flat()],[H,[...Q.values()]],[L,[...ie]],[_,[...ae]],[k,[...ce.entries()]]];for(const[e,t]of u)d.push(ft(()=>de.setMeta(e,t)));return void 0!==s&&d.push(ft(async()=>{i()&&await s()})),await ut(d),i()})},saveChannelSyncCheckpoint:function(e,t){const n=d(e,e.conversation);if(void 0===n)return Promise.reject(new Error("CHANNEL 同步位置无效"));const o=vt([n.conversation],t);return lt(async()=>{if(!o())return!1;if(void 0===de)throw new Error("CHANNEL 同步位置保存需要 storage");let e=!1;return await ft(async()=>{o()&&(await de.setMeta(u(n.conversation),n),e=!0)}),e&&o()})},waitForChannelSyncPersistence:async function(){for(;;){const e=ot,t=tt;if(await Promise.all([e,t,...Ve]),e===ot&&t===tt&&0===Ve.size)return}},getSession:e=>V.get(e),getConversationContext:cn,isMembershipTerminated:ke,prepareConversation:function(e,t={}){const n=o(e);if("supergroup"===n.conversationType)throw new Error("prepareConversation:supergroup 未实现");const r=cn(n);if(void 0!==r){const t=r.title||e.title,n=r.avatar??e.avatar;return void(t===r.title&&n===r.avatar||dn({...r,title:t,avatar:n}))}if(ke(n)){if(!0!==t.membershipConfirmed)throw new Error("准备聊天失败:需要重新确认成员资格");ae.delete(Le(n)),ae.delete(n.conversationId),It()}dn({...e,...void 0===e.channelPermissions?{}:{channelPermissions:{...e.channelPermissions}},...void 0===e.channelAccessSnapshot?{}:{channelAccessSnapshot:{...e.channelAccessSnapshot}}}),(Y.get(n)?.unreadCount??0)>0&&!_e(n)&&zt(n,!0)},ensureConversation:function(t){const n=o(t);if(e(n),"supergroup"===n.conversationType)throw new Error("ensureConversation:supergroup 未实现");const r=V.get(n);if(void 0!==r)return r;const s={...t,id:n.conversationId,type:n.conversationType,...void 0===t.channelPermissions?{}:{channelPermissions:{...t.channelPermissions}},...void 0===t.channelAccessSnapshot?{}:{channelAccessSnapshot:{...t.channelAccessSnapshot}},...void 0===t.extensions?{}:{extensions:{...t.extensions}}},i=He(n);return i.deleted&&wt(),i.terminal&&It(),V.set(s),X.delete(n),Qe(s),ht(s),s},getSessions:()=>V.getAll(),getConversationList:function(){const e=[];for(const t of V.getAll()){const n=o(t);e.push({...t,draft:Z.get(n)})}return h(e)},getReadState:e=>Y.get(e),getPinnedMessage:e=>ee.get(e),setPinnedMessage:function(e,t){const o=function(e){const t=we(n(e),e.messageId);return void 0===t?e:{...e,preview:{state:"ready",message:t}}}(e);ee.set(o)&&(U.emitter.emit({type:"pinned-message:updated",conversationId:o.conversationId,conversation:{conversationType:o.conversationType,conversationId:o.conversationId},pinnedMessage:o,reason:t}),function(e){void 0===de||Se||ft(()=>de.savePinnedMessage(e)).catch(e=>Je("置顶消息落盘失败",e))}(o))},clearPinnedMessage:function(e,t){const o="string"==typeof e?e:e.conversationId,r=ee.get(e);if(!ee.clear(e))return;const s="string"==typeof e?void 0===r?void 0:n(r):e;if(void 0===s)throw new Error(`置顶消息清理缺少复合身份:${o}`);U.emitter.emit({type:"pinned-message:updated",conversationId:o,conversation:s,pinnedMessage:null,reason:t}),function(e){void 0===de||Se||ft(()=>de.removePinnedMessage(e)).catch(e=>Je("置顶消息删除失败",e))}(e)},isPinnedMessage:(e,t)=>ee.isPinnedMessage(e,t),setReadState:e=>{const t=void 0===e.conversationType?V.get(e.conversationId):void 0,n=void 0===e.conversationType&&void 0!==t?{...e,conversationType:t.type}:e;"channel"===n.conversationType&&re(n.conversationId),Y.set(n),Mt(n)},markConversationUnread:function(e){const t=V.get(e);if(void 0===t)return!1;const n=Y.get(e)??{...e,readCursor:t.readCursor??"",unreadCount:t.unreadCount,mentionUnreadCount:t.mentionUnreadCount};return!(n.unreadCount>0||!0===n.manuallyUnread)&&(Ft({...n,manuallyUnread:!0}),zt(e),!0)},clearConversationManualUnread:Yt,advanceRead:function(e,n){const o="string"==typeof e?z.getByConversation(e).find(e=>e.id===n)??Ce(n,e):we(e,n);if(void 0===o)return;const r="string"==typeof e?t(o):e,s="string"==typeof e?e:e.conversationId;if(o.conversationId!==s||o.conversationType!==r.conversationType)return;const i=$t(r);if(void 0!==i&&i>=o.sortKey)return void("string"!=typeof e&&Yt(e));const a={...r,readCursor:n,readCursorSortKey:o.sortKey,unreadCount:Dt(r,o.sortKey),mentionUnreadCount:jt(r,o.sortKey)};return Ft(a),zt(r),a},applyServerUnread:Zt,applyChannelReadPosition:tn,getChannelReadRevision:e=>ne.get(e.conversationId)??oe,hasPendingChannelRead:e=>te.has(e.conversationId),applyChannelReadSummary:(e,t)=>Zt(e,t.unreadCount,void 0,t.readCursor,t.hasUnreadMention),beginChannelReadTransaction:function(e){const t=e.conversationId,n=cn(e);if(void 0===n||"channel"!==n.type)throw new Error(`CHANNEL 乐观已读事务要求 channel 会话(conversationId=${t}, type=${n?.type??"missing"})`);if(te.has(t))throw new Error(`CHANNEL 乐观已读事务已存在(channelId=${t})`);const o={conversation:e,transactionId:se++},r=Y.get(e)??{conversationId:t,readCursor:n.readCursor??"",unreadCount:n.unreadCount,...void 0===n.mentionUnreadCount?{}:{mentionUnreadCount:n.mentionUnreadCount}};return te.set(t,{handle:o,baseReadState:{...r},steps:[],committedThrough:-1}),re(t),o},applyChannelReadOptimistically:nn,applyChannelConversationReadOptimistically:function(e,t,n){nn(e,t,n);const o=en(e).steps.at(-1);if(void 0!==o.clearedCounts)return;const i=Y.get(e.conversation),a=Te(e.conversation).filter(e=>r(s(e),o)>0&&xt(e)&&b(e)&&!0!==e.readBySelf&&void 0===e.recalled&&void 0===e.deletedForEveryone),c=Math.min(i.unreadCount,a.length),d=Math.min(i.mentionUnreadCount??0,a.filter(Bt).length);o.clearedCounts={unread:i.unreadCount-c,mention:(i.mentionUnreadCount??0)-d},Ft({...i,unreadCount:c,mentionUnreadCount:d}),zt(e.conversation)},commitChannelReadTransaction:function(e,t){const n=en(e);if(void 0===n)return!1;const o=n.steps.findLastIndex(e=>e.readCursor===t);if(o<0)throw new Error(`CHANNEL 已确认 cursor 不属于乐观事务(channelId=${e.conversation.conversationId}, cursor=${t})`);return n.committedThrough=Math.max(n.committedThrough,o),re(e.conversation.conversationId),n.committedThrough===n.steps.length-1&&te.delete(e.conversation.conversationId),!0},rollbackChannelReadTransaction:function(e){const t=en(e);if(void 0===t)return!1;const n=e.conversation,o=n.conversationId,r=Y.get(n),s=t.committedThrough>=0?t.steps[t.committedThrough]:void 0,i=void 0===s?t.baseReadState:void 0;let a=r?.unreadCount??i?.unreadCount??0,c=r?.mentionUnreadCount??i?.mentionUnreadCount??0;for(const e of t.steps.slice(t.committedThrough+1))a+=e.clearedCounts?.unread??0,c+=e.clearedCounts?.mention??0;const d=void 0!==i?.mentionUnreadCount||void 0!==r?.mentionUnreadCount,u={conversationId:o,conversationType:"channel",readCursor:s?.readCursor??i?.readCursor??"",readCursorSortKey:s?.sortKey??i?.readCursorSortKey,unreadCount:a,...d?{mentionUnreadCount:c}:{}};return te.delete(o),Ft(u),zt(n),!0},setGroupRestriction:function(e,t,n){const o=cn({conversationType:"group",conversationId:e});if(void 0===o){return void dn({id:e,type:"group",title:"",lastMessagePreview:"",timestamp:0,unreadCount:0,pinned:!1,muted:!1,groupState:t,sendDisabledReason:n})}if(o.groupState===t&&o.sendDisabledReason===n)return;dn({...o,groupState:t,sendDisabledReason:n})},setChannelRestriction:on,setPinned:function(e,t){const n=V.get(e);if(void 0===n||n.pinned===t)return;const o={...n,pinned:t,topTime:t?Date.now():void 0};V.set(o),Qe(o),ht(o)},setMuted:function(e,t){const n=cn(e);if(void 0===n||n.muted===t)return;dn({...n,muted:t})},removeConversation:function(e){sn(e)},removeConversationForMembershipTermination:an,refreshConversationProfile:function(e,t){Nt({conversationType:t,conversationId:e},{force:!0})},readDirectProfile:Pt,beginConversationProfileRead:function(t,n){const o={...t},r=e(o),s=xe,i=!0!==n?.forceRefresh&&(je.has(r)||Be.has(r))?void 0:Ge(o);void 0!==i&&!0===n?.forceRefresh&&Be.set(r,i);const a=()=>{s===xe&&void 0!==i&&Be.get(r)===i&&Be.delete(r)};return Object.assign(e=>{try{if(void 0===i||e.id!==o.conversationId||s!==xe)return;Rt(o,e.title,e.avatar??"",void 0,i)}finally{a()}},{finish:a})},recoverChannelFromProfile:function(e){return Nt({conversationType:"channel",conversationId:e},{force:!0,allowChannelRecovery:!0})},updateConversationProfile:function(e,t){const n=cn(e);if(void 0===n)return;Ge(o(n));const r={...n,...void 0!==t.title?{title:t.title}:{},...void 0!==t.avatar?{avatar:t.avatar}:{}};W(n,r)||dn(r)},getTotalUnread:function(e){return F(V.getAll(),e)},getDraft:function(e){return Z.get(bt(e))},saveDraft:async function(t,n){const o=bt(t),r=e(o),s=Ut(o,n,0),i=pe,a=fe.get(r)??0;return await Et(o,async()=>{const e=Z.get(o),t=Math.max(Date.now(),(ve.get(r)??e?.updatedAt??0)+1),n=Ut(o,s,t);if(null!==e&&Kt(e,n))return e;if(void 0!==de&&await de.saveDraft(n),i!==pe||a!==(fe.get(r)??0))throw new Error("草稿状态已失效,拒绝过期写入回灌内存");return Z.set(n),ve.set(r,t),U.emitter.emit({type:"draft:updated",conversation:n.ref,draft:n}),n})},clearDraft:async function(e){await At(e)},clearDraftIfUnchanged:async function(e,t){return await At(e,t)},invalidateAndDrainDraftOperations:async function(){for(pe+=1;le.size>0;)await Promise.all([...le.values()])},clearSession(){rt+=1,xe+=1,pe+=1,Xt+=1,Vt.clear(),$e.clear(),De.clear(),Be.clear(),je.clear(),Fe.clear(),z.clear(),V.clear(),X.clear(),Y.clear(),Z.clear(),le.clear(),ve.clear(),fe.clear(),te.clear(),ne.clear(),oe+=1,ee.clearAll(),ie.clear(),ae.clear(),ce.clear(),Ye.clear(),J.clear();for(const e of me)e.reset()},hydrate:async function(r=()=>!0){if(void 0!==de&&r()){Se=!0;try{const s=await de.getMeta(L);if(!r())return;if(null!==s)for(const e of s)ie.add(e);const i=await de.getMeta(_);if(!r())return;if(null!==i)for(const e of i)ae.add(e);const a=await de.getMeta(k);if(!r())return;if(null!==a)for(const[e,t]of a)"string"==typeof e&&"string"==typeof t&&ce.set(e,t);const c=await de.getMeta(O);if(!r())return;if(null!==c)for(const e of c){const t=be(e);J.set(t,[...J.get(t)??[],e])}const d=await de.getMeta(H);if(!r())return;if(Array.isArray(d))for(const e of d){if("object"!=typeof e||null===e)continue;const t=Reflect.get(e,"serialNumber"),n=Reflect.get(e,"status"),o=Reflect.get(e,"occurredTime");"string"!=typeof t||""===t.trim()||0!==n&&1!==n&&2!==n&&3!==n||void 0!==o&&("number"!=typeof o||!Number.isFinite(o)||o<=0)||Q.set(t,{serialNumber:t,status:n,...void 0===o?{}:{occurredTime:o}})}const u=await de.getPinnedMessages();if(!r())return;for(const e of u){if(!r())return;_e({conversationType:e.conversationType,conversationId:e.conversationId})||ee.set(e)&&U.emitter.emit({type:"pinned-message:updated",conversationId:e.conversationId,conversation:n(e),pinnedMessage:e,reason:"hydrate"})}const l=(await de.getSessions()).filter(e=>!_e({conversationType:e.type,conversationId:e.id}));if(!r())return;for(const e of l){if(!r())return;const t=Ht(o(e),[],"preserve",e),n=o(t),s=V.get(n);V.set(t),X.delete(n),void 0!==s&&W(s,t)||Qe(t)}const v=await de.getReadStates();if(!r())return;for(const e of v)"channel"===e.conversationType&&re(e.conversationId),Y.set(e);const f=pe,p=await de.getDrafts();if(!r())return;if(f!==pe)return;for(const t of p){if(!r())return;if(!Number.isFinite(t.updatedAt)||t.updatedAt<0)throw new Error(`草稿 updatedAt 非法:${t.updatedAt}`);const n=Ut(t.ref,t,t.updatedAt);if(_e(n.ref)){try{if(await de.deleteDraft(n.ref),!r())return}catch(e){if(!r())return;Je("清理已删会话残留草稿失败",e)}continue}const o=e(n.ref);ve.set(o,Math.max(ve.get(o)??0,n.updatedAt));const s=Z.get(n.ref);null!==s&&s.updatedAt===n.updatedAt&&Kt(s,n)||(Z.set(n),U.emitter.emit({type:"draft:updated",conversation:n.ref,draft:n}))}for(const n of l){if(!r())return;const s=o(n),i=(await de.getMessages(s,{limit:50})).filter(n=>e(t(n))===e(s)).filter(qe);if(!r())return;const a=[];if(Gt(i.map(e=>{const t=qt(T(e));return t!==e&&a.push(t),t}),r),!r())return;if(a.length>0)try{if(await de.saveMessages(a),!r())return}catch(e){if(!r())return;Je("本地消息修复态落盘失败",e)}if(!r())return;zt(s)}}catch(e){r()&&Je("本地历史回读失败",e)}finally{Se=!1,r()&&Ne("offline")}}},loadOlderMessages:async function(n,o){if(void 0===de)return[];try{const r=await de.getMessages(n,o),s="string"==typeof n?r.filter(qe):r.filter(o=>e(t(o))===e(n)).filter(qe),i=Se;let a;Se=!0;try{a=Gt(s)}finally{Se=i}return Se||Ne("offline"),a.map(e=>we(t(e),e.id)??e)}catch(e){return Je("加载更早消息失败",e),[]}},searchMessages:async function(n,o){const r=o.keyword?.trim()??"",s=o.contentTypes;if(""===r&&(void 0===s||0===s.length))return{results:[],exhausted:!0};const i=""===r?void 0:await w(r),a=e=>{const t=void 0===s||s.includes(e.contentType),n=void 0===i||null!==i.match(I(e));return t&&n},c=(e,t)=>e.sortKey<t.sortKey?1:e.sortKey>t.sortKey?-1:0,d=e=>function(e,t){const n=t?.match(I(e));return{message:e,ranges:n?.ranges.map(({start:e,end:t})=>[e,t])??[]}}(e,i);if(void 0===de)return(()=>{const e=z.getByConversation(n).filter(a).sort(c),t=(void 0===o.beforeSortKey?e:e.filter(e=>e.sortKey<o.beforeSortKey)).slice(0,o.limit),r=t.length<o.limit;return{results:t.map(d),exhausted:r,...r?{}:{nextBeforeSortKey:t.at(-1)?.sortKey}}})();let u;try{u=await de.searchMessages(n,{...void 0!==o.keyword?{keyword:o.keyword}:{},...void 0!==s?{contentTypes:s}:{},limit:o.limit,...void 0!==o.beforeSortKey?{beforeSortKey:o.beforeSortKey}:{}})}catch(e){throw Je("会话内搜索失败",e),e}const l=u.exhausted?void 0:u.nextBeforeSortKey,v=new Map(z.getByConversation(n).map(e=>[e.id,e])),f=/* @__PURE__ */new Map;for(const o of u.items){const r=Wt(o);e(t(r))===e(n)&&f.set(r.id,v.get(r.id)??r)}for(const e of v.values()){const t=void 0===o.beforeSortKey||e.sortKey<o.beforeSortKey,n=void 0===l||e.sortKey>=l;t&&n&&a(e)&&f.set(e.id,e)}return{results:[...f.values()].filter(a).sort(c).map(d),exhausted:u.exhausted,...u.exhausted?{}:{nextBeforeSortKey:u.nextBeforeSortKey}}},messageWindow:he,createMessageWindow:function(e={}){const t=ge(e);let n=!1;return{window:t,dispose(){n||(n=!0,t.reset(),me.delete(t))}}}}}export{J as createDomainState,j as defaultConversationUnreadMode,F as sumSessionsUnread};
|
|
1
|
+
import{encodeConversationKey as e,conversationRefFromMessage as t,conversationRefFromPinnedMessage as n,conversationRefFromSession as o}from"../conversation-identity.js";import{compareChannelReadPosition as r,getChannelReadOrder as s}from"../mapping/channel-read-position.js";import{computeSortKey as i,resolveMessageTimestamp as a,computeMessageSortKey as c,resolveMessageServerTime as d}from"../mapping/sort.js";import{collectTransferStatusBySerialNumber as u,synchronizeTransferStatusMessages as l,applyTransferStatusToBody as v}from"../mapping/transfer-status.js";import{parseChannelSyncCheckpoint as f,channelSyncCheckpointKey as p}from"../sync/channel-sync-checkpoint.js";import{parseConversationDeletionBoundary as y,isAfterConversationDeletion as m,captureConversationDeletionBoundary as g}from"./conversation-deletion-boundary.js";import{createDraftStore as h}from"./draft-store.js";import{rollbackMessageReaction as C,applyMessageReaction as w}from"./message-reactions.js";import{createMessageStore as I}from"./message-store.js";import{createMessageWindowStore as T}from"./message-window-store.js";import{createPinnedMessageStore as M}from"./pinned-message-store.js";import{createReadStore as S}from"./read-store.js";import{sortSessions as b}from"./session-sort.js";import{createSessionStore as E}from"./session-store.js";import{createImTextSearchMatcher as K,extractSearchText as U}from"../mapping/search-text.js";import{normalizeStoredMessageContent as A,LOCAL_MEDIA_ERROR_CODE as R,failInterruptedUpload as P}from"../mapping/stored-message.js";import{isMessageVisibleInTimeline as N,lastMessageSummaryEqual as x,sessionFromMessage as $}from"../mapping/session-mapper.js";import{isMessageEqual as D,isMessageRecoveryBodyEqual as B,dedupeById as j,mergeMessage as F}from"../mapping/merge.js";import{newClientMessageId as L}from"../mapping/message-id.js";import{backfillGroupMention as _}from"../mapping/group-message-mapper.js";import{isConversationUnreadMessage as k}from"../mapping/unread-divider.js";function O(e){return"direct"===e||"robot"===e||"customerService"===e?"local":"server"}function H(e,t){const n=t?.includeMuted??!1;let o=0;for(const t of e)!n&&t.muted||(o+=t.unreadCount>0?t.unreadCount:!0===t.manuallyUnread?1:0);return o}const z="im:deleted-conversations",q="im:terminated-conversations",G="im:membership-reset-sort-keys",W="im:pending-message-reactions",J="im:transfer-status-records",Q=["sendMessages","mentionAll","editProfile","manageMembers","manageAdmins","moderateMessages","manageMute","dismissChannel","transferOwnership"];function V(e,t){return e===t||void 0!==e&&void 0!==t&&Q.every(n=>e[n]===t[n])}function X(e,t){return e===t||void 0!==e&&void 0!==t&&e.role===t.role&&e.baseState===t.baseState&&e.resolvedState===t.resolvedState&&e.allMembersMuted===t.allMembersMuted&&e.currentUserMuted===t.currentUserMuted&&e.mutePeriod===t.mutePeriod}function Y(e,t){return e.id===t.id&&e.type===t.type&&e.title===t.title&&e.avatar===t.avatar&&x(e.lastMessageSummary,t.lastMessageSummary)&&e.timestamp===t.timestamp&&e.unreadCount===t.unreadCount&&(e.manuallyUnread??!1)===(t.manuallyUnread??!1)&&(e.mentionUnreadCount??0)===(t.mentionUnreadCount??0)&&e.pinned===t.pinned&&e.muted===t.muted&&e.topTime===t.topTime&&e.lastMessageSendState===t.lastMessageSendState&&e.lastMessageReceipt===t.lastMessageReceipt&&e.readCursor===t.readCursor&&e.groupState===t.groupState&&e.channelState===t.channelState&&V(e.channelPermissions,t.channelPermissions)&&X(e.channelAccessSnapshot,t.channelAccessSnapshot)&&e.sendDisabledReason===t.sendDisabledReason}function Z(x){const Q=I({getSelfId:x.getSelfId}),Z=/* @__PURE__ */new Map,ee=/* @__PURE__ */new Map,te=E(),ne=E(),oe=S(),re=h(),se=M(),ie=/* @__PURE__ */new Map,ae=/* @__PURE__ */new Map;let ce=0;function de(e){ae.set(e,++ce)}let ue=1;const le=/* @__PURE__ */new Set,ve=/* @__PURE__ */new Map,fe=/* @__PURE__ */new Set,pe=/* @__PURE__ */new Map,{storage:ye}=x;let me=Promise.resolve();const ge=/* @__PURE__ */new Map,he=/* @__PURE__ */new Map,Ce=/* @__PURE__ */new Map;let we=0;const Ie=x.unreadMode??O,Te=/* @__PURE__ */new Set;function Me(e={}){const t=T({storage:ye,loadOlderFromRemote:x.loadOlderFromRemote,loadNewerFromRemote:x.loadNewerFromRemote,shouldIncludeMessage:Ze,normalizeStoredUpload:Zt,...e});return Te.add(t),t}const Se=Me();function be(e,t){let n;for(const o of Te){const r=o.list().find(n=>n.id===e&&n.conversationId===t);if(void 0!==r){if(void 0!==n&&n.conversationType!==r.conversationType)throw new Error(`裸 conversationId 存在多类型消息歧义:${t}`);n=r}}return n}function Ee(e,t){const n=Q.get(t,e);if(n?.conversationId===e.conversationId&&n.conversationType===e.conversationType)return n;for(const n of Te){const o=n.list().find(n=>n.id===t&&n.conversationId===e.conversationId&&n.conversationType===e.conversationType);if(void 0!==o)return o}}function Ke(e,n){const o=Ee(t(e),e.id);void 0===o||Q.has(e.id,e)||Q.upsert(o);const r=Q.upsert(e,n);return{...r,previous:o,changed:void 0===o?r.changed:!D(o,r.message)}}function Ue(e){const t=new Map(Q.getByConversation(e).map(e=>[e.id,e]));for(const n of Te)if(Ae(n,e))for(const o of n.list())o.conversationType!==e.conversationType||o.conversationId!==e.conversationId||t.has(o.id)||t.set(o.id,o);return[...t.values()].sort((e,t)=>e.sortKey.localeCompare(t.sortKey))}function Ae(t,n){const o=t.info();return void 0===o.conversation?o.conversationId===n.conversationId:e(o.conversation)===e(n)}let Re=!1;function Pe(t){return`${e(t.conversation)}\0${t.parentMessageId}`}function Ne(){if(void 0===ye||Re)return;const e=[...Z.values()].flat();It(()=>ye.setMeta(W,e)).catch(e=>nt("保存待处理 Reaction 失败",e))}function xe(e){const t=e.body.transfer;if("transfer"!==e.contentType||void 0===t)return e;const n=ee.get(t.serialNumber);if(void 0===n||0!==t.status&&0===n.status)return e;const o={...t,status:n.status,...1===n.status&&void 0!==n.occurredTime?{receiveTime:n.occurredTime}:{},...2===n.status||3===n.status?{returnTime:n.occurredTime??t.returnTime}:{}};return t.status===o.status&&t.receiveTime===o.receiveTime&&t.returnTime===o.returnTime&&t.isRead===o.isRead?e:{...e,body:{transfer:v(t,o)}}}function $e(t,n){const o=`${e(t)}\0${n}`;return!!Z.delete(o)&&(Ne(),!0)}function De(t){const n=`${e(t)}\0`;let o=!1;for(const e of Z.keys())e.startsWith(n)&&(Z.delete(e),o=!0);return o&&Ne(),o}function Be(e,t){const n=Ee(e.conversation,e.parentMessageId);if(void 0===n){const t=Pe(e),n=Z.get(t)??[];return n.some(t=>t.id===e.id)?"duplicate":(Z.set(t,[...n,e]),Ne(),"pending")}if(yt(n),void 0!==n.recalled||void 0!==n.deletedForEveryone)return"duplicate";const o=w(n.reactions,e,x.getSelfId?.()??"");return o===n.reactions?"duplicate":(nn([{...n,reactions:o}],t),"applied")}function je(n,o){const r=t(n),s=`${e(r)}\0${n.id}`,i=Z.get(s);if(void 0!==i){Z.delete(s),Ne();for(const e of i)Be(e,o)}}function Fe(e){for(const t of[...Z.values()]){const n=t[0];if(void 0===n)continue;const o=Ee(n.conversation,n.parentMessageId);void 0!==o&&(void 0!==o.recalled||void 0!==o.deletedForEveryone?$e(n.conversation,n.parentMessageId):je(o,e))}}let Le=0;const _e=/* @__PURE__ */new Map,ke=/* @__PURE__ */new Map,Oe=/* @__PURE__ */new Map,He=/* @__PURE__ */new Map,ze=/* @__PURE__ */new Map;function qe(t){return e(t)}function Ge(e){return We(e)||le.has(qe(e))||le.has(e.conversationId)}function We(e){return fe.has(qe(e))||fe.has(e.conversationId)}function Je(t,n={}){return(!0===n.includeRestored||Ge(t))&&!We(t)&&ve.has(e(t))}function Qe(){return[...le,...ve.values()]}function Ve(e){const t=le.delete(qe(e)),n=le.delete(e.conversationId);return t||n}function Xe(e){const t=Ve(e),n=fe.delete(qe(e)),o=fe.delete(e.conversationId);return{deleted:t,terminal:n||o}}function Ye(e,t){if(""===t||"system"!==e.contentType)return!1;const n=e.body.system;return!0===n?.targetUserIds?.includes(t)&&("group"===e.conversationType?"group_member_joined"===n.eventType||"group_member_invited"===n.eventType:"channel"===e.conversationType&&("channel_member_joined"===n.eventType||"channel_member_invited"===n.eventType||"channel_created"===n.eventType))}function Ze(n){const o=t(n);if(We(o)||Ge(o)&&void 0===ne.get(o))return!1;if("group"!==o.conversationType)return!0;const r=pe.get(e(o));return void 0===r||n.sortKey>=r}function et(t){const n=e(t),o=(ke.get(n)??0)+1;return ke.set(n,o),o}function tt(t){const n=e(t),o=(_e.get(n)??0)+1;return _e.set(n,o),o}function nt(e,t){x.emitter.emit({type:"error",error:{scope:"storage",message:e,cause:t}})}function ot(e){x.emitter.emit({type:"session:updated",session:e,conversation:o(e)})}const rt=/* @__PURE__ */new Set,st=/* @__PURE__ */new Set,it=/* @__PURE__ */new Map,at=/* @__PURE__ */new Map;let ct=0,dt=Promise.resolve(),ut=0,lt=Promise.resolve(),vt=0;const ft=/* @__PURE__ */new Map;let pt;function yt(n){const o=e(t(n));pt?.keys.has(o)&&pt.messages.set(`${o}\0${n.id}`,n)}function mt(t){const n=e(t);ft.set(n,(ft.get(n)??0)+1)}function gt(e){return pt?.writes.push(e),void 0!==pt&&e.catch(()=>{}),e}async function ht(e){const t=(await Promise.allSettled(e)).find(e=>"rejected"===e.status);if(void 0!==t)throw t.reason}function Ct(e){const t=lt.then(e);return lt=t.then(()=>{},()=>{}),t}function wt(t,n){const o=vt,r=t.map(t=>[e(t),ft.get(e(t))??0]);return()=>o===vt&&n()&&r.every(([e,t])=>(ft.get(e)??0)===t)}function It(e){const t=0===ut?(()=>{try{return e()}catch(e){return Promise.reject(e)}})():dt.then(e),n=t.then(()=>{},()=>{});rt.add(n),n.finally(()=>rt.delete(n));for(const e of st)e.writes.push(t);return gt(t)}function Tt(e){ut+=1;const t=Promise.all([...rt]),n=dt.then(()=>t).then(e);return dt=n.then(()=>{},()=>{}),dt.finally(()=>{ut-=1}),gt(n)}function Mt(e){const t=e.body.system;if(void 0===t?.pinnedMessageAction)return e;const{pinnedMessageAction:n,...o}=t;return{...e,body:{...e.body,system:o}}}function St(n){if(void 0!==ye&&!Re&&0!==n.length){for(const o of st)for(const r of n)o.messages.add(`${e(t(r))}\0${r.id}`);It(()=>ye.saveMessages(n.map(Mt))).catch(e=>nt("消息落盘失败",e))}}function bt(e){const{lastMessageSendState:t,manuallyUnread:n,...o}=e;return o}function Et(t){if(void 0!==ye&&!Re){for(const n of st)n.sessions.add(e(o(t)));It(()=>ye.saveSessions([bt(t)])).catch(e=>nt("会话落盘失败",e))}}function Kt(e,t,n){if(void 0===ye||Re)return;const o=++ct;it.set(e,{version:o,persist:()=>Kt(e,t,n)});for(const t of st)t.metadata.add(e);const r=at.get(e),s=It(()=>void 0===r?ye.setMeta(e,t()):r.then(()=>ye.setMeta(e,t()))),i=s.then(()=>{},()=>{});at.set(e,i),i.then(()=>{at.get(e)===i&&at.delete(e)}),s.then(()=>{it.get(e)?.version===o&&it.delete(e)},e=>nt(n,e))}function Ut(){Kt(z,Qe,"删除会话标记保存失败")}function At(){Kt(q,()=>[...fe],"成员资格终止标记保存失败")}function Rt(){Kt(G,()=>[...pe.entries()],"重新入群的历史起点保存失败")}function Pt(t){if(void 0!==ye&&!Re){for(const n of st)void 0!==t.conversationType&&n.reads.add(e({conversationType:t.conversationType,conversationId:t.conversationId}));It(()=>ye.saveReadState(t)).catch(e=>nt("已读态落盘失败",e))}}function Nt(t){if(e(t),"supergroup"===t.conversationType)throw new Error("supergroup 草稿未实现,不得 fallback 到其他会话类型")}function xt(e){return Nt(e),Object.freeze({conversationType:e.conversationType,conversationId:e.conversationId})}function $t(e,t,n){if(Nt(e),"string"!=typeof t.text)throw new TypeError("草稿 text 必须是字符串");if(void 0!==t.attachments&&t.attachments.length>0)throw new Error("草稿附件尚未支持:attachments 只接受空集合");if(void 0!==t.mentions&&!Array.isArray(t.mentions))throw new TypeError("草稿 mentions 必须是数组");const o=(t.mentions??[]).map(e=>{if("string"!=typeof e.userId||""===e.userId.trim()||"string"!=typeof e.displayName)throw new TypeError("草稿 mention 必须包含非空 userId 与字符串 displayName");return Object.freeze({userId:e.userId,displayName:e.displayName})}),r=Object.freeze({conversationType:e.conversationType,conversationId:e.conversationId});return Object.freeze({ref:r,text:t.text,mentions:Object.freeze(o),...void 0===t.replyToMessageId?{}:{replyToMessageId:t.replyToMessageId},attachments:Object.freeze([]),updatedAt:n})}function Dt(e,t){return e.text===t.text&&e.replyToMessageId===t.replyToMessageId&&e.mentions.length===t.mentions.length&&e.mentions.every((e,n)=>{const o=t.mentions[n];return void 0!==o&&e.userId===o.userId&&e.displayName===o.displayName})}function Bt(t,n){Nt(t);const o=e(t),r=(ge.get(o)??Promise.resolve()).catch(()=>{}).then(n),s=r.then(()=>{},()=>{});return ge.set(o,s),s.finally(()=>{ge.get(o)===s&&ge.delete(o)}),r}async function jt(t,n){const o=xt(t),r=e(o);if(void 0!==n&&(!Number.isFinite(n)||n<0))throw new Error(`草稿 expectedUpdatedAt 非法:${n}`);const s=we,i=Ce.get(r)??0;return await Bt(o,async()=>{const e=re.get(o);if(null===e||void 0!==n&&e.updatedAt!==n)return!1;if(void 0!==ye&&await ye.deleteDraft(o),s!==we||i!==(Ce.get(r)??0))throw new Error("草稿状态已失效,拒绝过期清理回灌内存");return re.delete(o),x.emitter.emit({type:"draft:cleared",conversation:o}),!0})}function Ft(t,n,o,r,s){const i=mn(t);if(void 0===i)return;const a={...i,...void 0===s||s===ke.get(e(t))?{title:n,avatar:o??i.avatar}:{},...void 0!==r?{muted:r}:{}};Y(i,a)||gn(a)}function Lt(t,n){const o=x.profile;if(void 0===o)return Promise.resolve(null);const r={conversationType:"direct",conversationId:t},s=e(r),i=ze.get(t);if(!0!==n?.forceRefresh&&void 0!==i&&i.revision===_e.get(s))return i.promise;const a=Le,c=tt(r),d=et(r),u=(async()=>{const e=await o.getUserProfile(t,n);if(null!==e&&e.id===t&&a===Le&&c===_e.get(s)){const n=e.remark?.trim()?e.remark:e.nickname||t;Ft(r,n,e.avatar??"",e.muted,d)}return e})().finally(()=>{ze.get(t)?.promise===u&&ze.delete(t)});return ze.set(t,{revision:c,promise:u}),u}async function _t(t,n){const{conversationId:o,conversationType:r}=t;if("direct"===r){try{await Lt(o,!0===n?.force?{forceRefresh:!0}:void 0)}catch(e){x.emitter.emit({type:"error",error:{scope:"http",message:"会话资料补齐失败",cause:e}})}return!1}const s=e(t),i=!0===n?.force;if(!i&&(He.has(s)||Oe.has(s)))return!1;const a=Le,c=tt(t),d=et(t);i&&He.set(s,c);const{profile:u,channelProfile:l}=x,v=i?{forceRefresh:!0}:void 0;try{if("group"===r){if(void 0===u)return!1;const e=await u.getGroupProfile(o,v);if(a!==Le||c!==_e.get(s))return!1;null!==e&&(Ft(t,e.name,e.avatar??"",e.muted,d),3===e.status&&yn({conversationType:"group",conversationId:o},"group_dismissed"),i&&x.emitter.emit({type:"profile:updated",profileType:"group",id:o}))}else if("channel"===r){if(void 0===l)return!1;const e=await l.getProfile(o,v);if(a!==Le||c!==_e.get(s))return!1;if(null!==e){Ft(t,e.name,e.avatar??"",e.muted,d);const r=mn(t)?.channelState,s="left"===r||"removed"===r||"dismissed"===r,a="left"===e.channelState||"removed"===e.channelState||"dismissed"===e.channelState;if(!0===n?.allowChannelRecovery&&s&&"dismissed"!==r&&"active"===e.channelState)return vn(o,"active",void 0,{permissions:e.permissions,...void 0===e.accessSnapshot?{}:{snapshot:e.accessSnapshot}}),i&&x.emitter.emit({type:"channel-profile:updated",channelId:o,conversation:{conversationType:"channel",conversationId:o}}),!0;const c=s&&(!a||"dismissed"===r||"dismissed"!==e.channelState);if(a&&!c)return yn({conversationType:"channel",conversationId:o},`channel_${e.channelState}`),i&&x.emitter.emit({type:"channel-profile:updated",channelId:o,conversation:{conversationType:"channel",conversationId:o}}),!1;if(!c){const t=e.permissions.sendMessages?void 0:`channel_${e.channelState}`;vn(o,e.channelState,t,{permissions:e.permissions,...void 0===e.accessSnapshot?{}:{snapshot:e.accessSnapshot}})}i&&x.emitter.emit({type:"channel-profile:updated",channelId:o,conversation:{conversationType:"channel",conversationId:o}})}}return!1}catch(e){return x.emitter.emit({type:"error",error:{scope:"http",message:"会话资料补齐失败",cause:e}}),!1}finally{i&&a===Le&&He.get(s)===c&&He.delete(s)}}function kt(e){return k(e,x.getSelfId?.()??"")}function Ot(e){const t=oe.get(e);if(void 0===t||""===t.readCursor)return;const n="string"==typeof e?t.conversationType:e.conversationType;if("channel"===n){const o={conversationType:n,conversationId:"string"==typeof e?e:e.conversationId};return Ue(o).find(e=>e.extensions?.historyCursor===t.readCursor)?.sortKey??t.readCursorSortKey}const o="string"==typeof e?Q.getByConversation(e).find(e=>e.id===t.readCursor):Ee(e,t.readCursor);return o?.sortKey??t.readCursorSortKey}function Ht(e,t){let n=0;for(const o of Q.getByConversation(e))N(o)&&kt(o)&&(void 0===t||o.sortKey>t)&&(n+=1);return n}function zt(e){const t=x.getSelfId?.();if(void 0===t||""===t||e.senderId===t)return!1;const{mention:n}=e;return void 0!==n&&(n.atAll||n.atUserIds.includes(t))}function qt(e,t){let n=0;for(const o of Q.getByConversation(e))!0!==o.readBySelf&&zt(o)&&(void 0===t||o.sortKey>t)&&(n+=1);return n}function Gt(e,t=!0){const n=void 0===e.conversationType?te.get(e.conversationId):void 0,o=void 0===e.conversationType&&void 0!==n?{...e,conversationType:n.type}:e,r=void 0===o.conversationType?o.conversationId:{conversationType:o.conversationType,conversationId:o.conversationId},s=oe.get(r);if("channel"===o.conversationType&&de(o.conversationId),oe.set(o),t&&Pt(o),void 0===s||s.readCursor!==o.readCursor||s.readCursorSortKey!==o.readCursorSortKey||s.unreadCount!==o.unreadCount||(s.manuallyUnread??!1)!==(o.manuallyUnread??!1)){if(void 0===o.conversationType)return void x.emitter.emit({type:"error",error:{scope:"storage",message:`已读状态缺少复合身份,拒绝发布 read:updated(conversationId=${o.conversationId})`}});x.emitter.emit({type:"read:updated",conversationId:o.conversationId,conversation:{conversationType:o.conversationType,conversationId:o.conversationId},readCursor:o.readCursor,unreadCount:o.unreadCount,...!0===o.manuallyUnread?{manuallyUnread:!0}:{}})}}function Wt(n,o){if(void 0===n||n.sortKey===o.sortKey)return;const r=t(o),s=oe.get(r),i="channel"===o.conversationType?o.extensions?.historyCursor:void 0,a="direct"===o.conversationType||"group"===o.conversationType||"robot"===o.conversationType||"customerService"===o.conversationType;void 0!==s&&(a&&s.readCursor===o.id||"string"==typeof i&&""!==i&&s.readCursor===i||s.readCursorSortKey===n.sortKey)&&Gt({...s,readCursorSortKey:o.sortKey});const c=e(r);"group"===o.conversationType&&pe.get(c)===n.sortKey&&(pe.set(c,o.sortKey),Rt())}function Jt(e){const t=e?.channelAccessSnapshot?.role;return"owner"===t||"admin"===t}function Qt(e,t,n,o,r=mn(e)){const s=o??oe.get(e);if(void 0===t){if(void 0===r){if("string"==typeof e||void 0===s||s.unreadCount<=0)return;return{id:e.conversationId,type:e.conversationType,title:"",lastMessagePreview:"",timestamp:0,unreadCount:s.unreadCount,mentionUnreadCount:s.mentionUnreadCount,readCursor:s.readCursor,pinned:!1,muted:!1}}const t={...r,..."clear"===n?{lastMessagePreview:"",timestamp:0}:{},...void 0===s?{}:{unreadCount:s.unreadCount,manuallyUnread:s.manuallyUnread,mentionUnreadCount:s.mentionUnreadCount,readCursor:s.readCursor||r.readCursor}};return"clear"===n&&(delete t.lastMessageSummary,delete t.lastMessageSenderId,delete t.lastMessageSystemEvent,delete t.lastMessageSystemTargetsSelf,delete t.lastMessageMention,delete t.lastMessageRecalled,delete t.lastMessageDeletedForEveryone,delete t.lastMessageSendState,delete t.lastMessageReceipt),t}const i=s?.unreadCount??r?.unreadCount??0,a=void 0===s?r?.manuallyUnread:s.manuallyUnread,c=$(t,{unreadCount:i,mentionUnreadCount:s?.mentionUnreadCount??r?.mentionUnreadCount??0,selfId:x.getSelfId?.(),showChannelModerationDeleted:Jt(r)});return void 0===r?{...c,...void 0===a?{}:{manuallyUnread:a},readCursor:(s?.readCursor??"")||c.readCursor}:{...c,title:r.title||c.title,avatar:r.avatar??c.avatar,pinned:r.pinned,muted:r.muted,topTime:r.topTime,...void 0===a?{}:{manuallyUnread:a},readCursor:(s?.readCursor??"")||r.readCursor,groupState:r.groupState,channelState:r.channelState,channelPermissions:r.channelPermissions,channelAccessSnapshot:r.channelAccessSnapshot,sendDisabledReason:r.sendDisabledReason}}function Vt(e,t){if(void 0===e)return;const n=te.get({conversationType:e.type,conversationId:e.id});void 0!==n&&Y(n,e)||(te.set(e),ne.delete({conversationType:e.type,conversationId:e.id}),ot(e),t&&Et(e),""===e.title&&_t({conversationType:e.type,conversationId:e.id}))}function Xt(e,t,n="preserve",o=mn(e)){const r=t.findLast(e=>function(e,t){return!!N(e)&&("channel"!==e.conversationType||void 0===e.deletedForEveryone||Jt(t))}(e,o)),s="string"==typeof e?o?.type:e.conversationType;return Qt(e,r,void 0===r&&"channel"===s&&!Jt(o)&&(t.some(e=>void 0!==e.deletedForEveryone)||"channel-moderation-deleted"===o?.lastMessageSummary?.kind||void 0!==o?.lastMessageDeletedForEveryone)?"clear":n,void 0,o)}function Yt(e,t=!1){(t||void 0!==te.get(e))&&Vt(Xt(e,Q.getByConversation(e)),!0)}function Zt(e){if("uploading"!==e.status&&("failed"!==e.status||e.failure?.code!==R))return e;const t=Q.get(e.id,e);return void 0!==t&&t.conversationType===e.conversationType&&t.conversationId===e.conversationId?t:P(A(e))}function en(n,o=()=>!0){const r=[],s=j(n,x.getSelfId?.()??"").map(e=>{const t=Zt(e);let n={...t,sortKey:c(t)};if(n=A(n),"group"===n.conversationType&&"text"===n.contentType){const e=_(n.body.text??"",n.mention);void 0!==e&&(n.mention=e)}return xe(n)}),i=/* @__PURE__ */new Map;for(const n of s){if("transfer"!==n.contentType||void 0===n.body.transfer)continue;const o=t(n);i.set(e(o),o)}const a=[...i.values()].flatMap(e=>Ue(e)),d=l(a,s),u=new Set(s.map(e=>e.id));for(const e of d){if(!o())break;const{previous:n,message:s,isNew:i,changed:a}=Ke(e);if(Wt(n,s),void 0!==n&&a)for(const e of Te){if(!o())return r;e.list().some(e=>e.id===s.id&&e.conversationType===s.conversationType&&e.conversationId===s.conversationId)&&e.applyIncoming([s])}if(!o())return r;i?x.emitter.emit({type:"message:received",message:s,conversation:t(s),source:"offline",channelLifecycleEffects:!1}):a&&x.emitter.emit({type:"message:updated",message:s,conversation:t(s),source:"offline",channelLifecycleEffects:!1}),u.has(s.id)&&r.push(s)}return r}function tn(e){const t=Zt(e);let n={...t,sortKey:c(t)};if(n=A(n),"group"===n.conversationType&&"text"===n.contentType){const e=_(n.body.text??"",n.mention);void 0!==e&&(n.mention=e)}return xe(n)}function nn(n,o,r={}){const s=x.getSelfId?.()??"";if("offline"===o&&!0!==r.backfillOnly){let o=!1;for(const r of n){if(r.senderId===s||!N(r)||void 0!==r.recalled||void 0!==r.deletedForEveryone)continue;const n=t(r),i=ve.get(e(n));void 0!==i&&!We(n)&&m(r,i)&&Ve(n)&&(o=!0)}o&&Ut(),n=n.filter(n=>{const o=ve.get(e(t(n)));return void 0===o||m(n,o)||void 0!==Ee(t(n),n.id)})}if("live"===o){let i=!1,a=!1;for(const c of n){const n=t(c);if(Ye(c,s)){const t=Xe(n);t.deleted&&(i=!0),t.terminal&&("group"===n.conversationType?(pe.set(e(n),c.sortKey),Rt()):"channel"===n.conversationType&&pe.delete(e(n)),x.diagnostics?.record("info","core","conversation","membership-termination-cleared",()=>({conversation:n,data:{source:o,eventType:c.body.system?.eventType,groupHistoryLowerBoundApplied:"group"===n.conversationType}})),a=!0)}else""!==s&&c.senderId===s&&!0!==r.newOutgoing||We(n)||!Ve(n)||(i=!0)}i&&Ut(),a&&At()}const i=!0===x.diagnostics?.isEnabled("debug","conversation")?/* @__PURE__ */new Map:void 0,a=(n,o)=>{if(void 0===i)return;const r=t(n),s=e(r),a=i.get(s)??{ref:r,tombstone:0,groupLowerBound:0};"tombstone"===o?a.tombstone+=1:a.groupLowerBound+=1,i.set(s,a)},c=le.size>0||fe.size>0?n.filter(e=>{const n=t(e),o=!Ge(n)||!0===r.backfillOnly&&void 0!==ne.get(n)&&!We(n);return o||a(e,"tombstone"),o}):n,d=function(n){const o=/* @__PURE__ */new Map;if(0===pe.size)return o;for(const r of j(n,x.getSelfId?.()??"")){if("group"!==r.conversationType)continue;const n=t(r),s=e(n),i=pe.get(s);if(void 0===i)continue;const a=Ee(n,r.id);if(void 0===a||a.sortKey!==i)continue;const c=F(a,r,x.getSelfId?.()??"");c.sortKey!==i&&(pe.set(s,c.sortKey),o.set(s,c.id))}return o.size>0&&Rt(),o}(c),u=n=>d.get(e(t(n)))===n.id,v=pe.size>0?c.filter(e=>{const t=u(e)||Ze(e);return t||a(e,"groupLowerBound"),t}):c,f=0===d.size?v:[...v.filter(u),...v.filter(e=>!u(e))];for(const e of i?.values()??[])x.diagnostics?.record("debug","core","conversation","membership-filter-dropped",()=>({conversation:e.ref,data:{source:o,tombstoneDroppedCount:e.tombstone,groupHistoryLowerBoundDroppedCount:e.groupLowerBound}}));const p=/* @__PURE__ */new Map,y=/* @__PURE__ */new Map,g=/* @__PURE__ */new Map,h=/* @__PURE__ */new Map,C=/* @__PURE__ */new Map,w=/* @__PURE__ */new Set,I=j(f,s).map(xe),T=/* @__PURE__ */new Map;for(const n of I){if("transfer"!==n.contentType||void 0===n.body.transfer)continue;const o=t(n);T.set(e(o),o)}const M=[...T.values()].flatMap(e=>Ue(e)),S=l(M,I),b=[],E=[];for(const n of S){if("channel"===n.conversationType&&pt?.keys.has(e(t(n)))&&!pt.current())continue;const{previous:s,message:i,isNew:a,changed:c}=Ke(n,{authoritativeFailure:!0===r.authoritativeOutboxFailure});if(yt(i),!0===r.backfillOnly&&!0===r.refreshSessionSummary){const n=t(i);p.set(e(n),n)}if(!a&&!c)continue;Wt(s,i);for(const e of Te)e.applyIncoming([i]);a?x.emitter.emit({type:"message:received",message:i,conversation:t(i),source:o,channelLifecycleEffects:!0===r.applyChannelLifecycleEffects}):x.emitter.emit({type:"message:updated",message:i,conversation:t(i),source:o,channelLifecycleEffects:!0===r.applyChannelLifecycleEffects});const d=t(i);if(!a&&void 0!==s&&!0!==s.readBySelf&&!0===i.readBySelf){const t=Ot(d),n=void 0===t||s.sortKey>t,o=e(d);n&&N(s)&&kt(s)&&void 0===s.recalled&&void 0===s.deletedForEveryone&&g.set(o,(g.get(o)??0)-1),n&&zt(s)&&void 0===s.recalled&&void 0===s.deletedForEveryone&&C.set(o,(C.get(o)??0)-1)}We(d)||(b.push(i),p.set(e(d),d),a&&!0!==r.backfillOnly&&E.push(i))}const K=/* @__PURE__ */new Map;for(const n of E){const r=t(n),s=e(r);kt(n)&&w.add(s),K.has(s)||K.set(s,Ot(r));const i=K.get(s),a=void 0===i||n.sortKey>i;if(N(n)&&a&&kt(n)&&!0!==n.readBySelf&&void 0===n.recalled&&void 0===n.deletedForEveryone){const e=Ie(n.conversationType);("local"===e||"server"===e&&"live"===o)&&y.set(s,(y.get(s)??0)+1)}a&&!0!==n.readBySelf&&zt(n)&&void 0===n.recalled&&void 0===n.deletedForEveryone&&h.set(s,(h.get(s)??0)+1)}for(const t of p.values()){if(!0===r.backfillOnly){!0===r.refreshSessionSummary&&Yt(t);continue}const n=e(t),o=y.get(n)??0,s=h.get(n)??0,i=g.get(n)??0,a=C.get(n)??0,c=w.has(n),d=oe.get(t);if(o>0||s>0||c||void 0!==d&&(0!==i||0!==a)){const e=d??{...t,readCursor:"",unreadCount:0},n={...e,unreadCount:Math.max(0,e.unreadCount+o+i),mentionUnreadCount:Math.max(0,(e.mentionUnreadCount??0)+s+a)};c&&delete n.manuallyUnread,Gt(n)}Yt(t,E.some(e=>e.conversationType===t.conversationType&&e.conversationId===t.conversationId&&N(e)))}St(b.filter(e=>void 0!==Ee(t(e),e.id)));for(const e of b)void 0===e.recalled&&void 0===e.deletedForEveryone?je(e,o):$e(t(e),e.id)}function on(e,t,n=Date.now()){const o={conversationType:"direct",conversationId:e},r=Ee(o,t),s=Q.getByConversation(o).findLast(e=>"direct_contact_established"===e.body.system?.eventType);if(void 0!==r&&void 0!==s&&a(s)>=a(r))return;const c=`${t}:contact-required`;if(void 0!==Q.get(c,o))return;nn([{id:c,conversationId:e,conversationType:"direct",senderId:e,contentType:"system",body:{system:{eventType:"direct_contact_required",targetUserIds:[e],action:{type:"request-contact",userId:e}}},createdAt:n,sortKey:i(n,c),status:"sent",receipt:"unread",encryption:{encrypted:!1,decryptFailed:!1}}],"live")}const rn=/* @__PURE__ */new Map;let sn=0;function an(e){const t=oe.get(e);if(!0!==t?.manuallyUnread)return!1;const n={...t};return delete n.manuallyUnread,Gt(n),Yt(e),!0}function cn(e,t,n,r,s){const i="string"==typeof e?e:e.conversationId,a=mn(e),c="string"==typeof e?void 0===a?void 0:o(a):e;if(void 0!==a&&"server"!==Ie(a.type))return void x.emitter.emit({type:"error",error:{scope:"unknown",message:`applyServerUnread 不应用于本地未读会话(conversationId=${i}, type=${a.type}),已忽略`}});if(!Number.isFinite(t))return void x.emitter.emit({type:"error",error:{scope:"unknown",message:`applyServerUnread 收到非法未读数(conversationId=${i}, count=${t}),已忽略`}});"channel"===c?.conversationType&&ie.delete(i);const d=oe.get(e);let u=d?.readCursor??"",l=d?.readCursorSortKey;const v=void 0===n||""===n?void 0:void 0===c?Q.getByConversation(i).find(e=>e.id===n)??be(n,i):Ee(c,n);void 0!==v&&v.conversationId===i&&(void 0===l||v.sortKey>l)&&(u=v.id,l=v.sortKey),void 0!==r&&(u=r),Gt({...void 0===c?{conversationId:i}:c,readCursor:u,readCursorSortKey:l,unreadCount:Math.max(0,Math.floor(t)),...t>0?{}:{manuallyUnread:d?.manuallyUnread},mentionUnreadCount:0===t||!1===s?0:!0===s?Math.max(1,d?.mentionUnreadCount??0):d?.mentionUnreadCount}),Yt(e,t>0&&void 0!==c&&!Ge(c))}function dn(e){const t=ie.get(e.conversation.conversationId);return t?.handle.transactionId===e.transactionId?t:void 0}function un(e,t,n,o=!1){const r=mn(e),s=Ee(e,t);if("channel"!==r?.type||"channel"!==s?.conversationType||s.conversationId!==e.conversationId||s.extensions?.historyCursor!==n)throw new Error(`CHANNEL 已读位置不可信(channelId=${e.conversationId}, messageId=${t})`);o||ie.delete(e.conversationId);const i=oe.get(e),a=void 0===i?r.mentionUnreadCount:i.mentionUnreadCount;Gt({...e,readCursor:n,readCursorSortKey:s.sortKey,unreadCount:i?.unreadCount??r.unreadCount,...void 0===a?{}:{mentionUnreadCount:a}}),Yt(e)}function ln(e,t,n){const o=e.conversation,r=o.conversationId,i=dn(e);if(void 0===i)throw new Error(`CHANNEL 乐观已读事务已失效(channelId=${r})`);const a=Ee(o,t);if(void 0===a||a.conversationId!==r||"channel"!==a.conversationType)throw new Error(`CHANNEL 乐观已读消息不可信(channelId=${r}, messageId=${t})`);if(a.extensions?.historyCursor!==n)throw new Error(`CHANNEL 乐观已读 cursor 与消息不一致(channelId=${r}, messageId=${t})`);i.steps.at(-1)?.readCursor!==n&&(i.steps.push({readCursor:n,messageId:t,...s(a)}),un(o,t,n,!0))}function vn(t,n,o,r){const s={conversationType:"channel",conversationId:t},i=e(s);if(Ge(s)&&void 0===ne.get(s)&&!Je(s))return;const a=mn(s);if(void 0===a){tt(s),He.delete(i);return void gn({id:t,type:"channel",title:"",lastMessagePreview:"",timestamp:0,unreadCount:0,pinned:!1,muted:!1,channelState:n,channelPermissions:r?.permissions,channelAccessSnapshot:r?.snapshot,sendDisabledReason:o})}if("channel"!==a.type)throw new Error(`setChannelRestriction: 会话 ${t} 类型为 ${a.type},拒绝写入 CHANNEL 状态`);tt(s),He.delete(i);const c=r?.permissions,d=r?.snapshot;if(a.channelState===n&&a.sendDisabledReason===o&&V(a.channelPermissions,c)&&X(a.channelAccessSnapshot,d))return void(void 0!==te.get(s)&&Yt(s));const u={...a,channelState:n,channelPermissions:c,channelAccessSnapshot:d,sendDisabledReason:o};void 0!==te.get(s)?gn(Xt(s,Q.getByConversation(s),"preserve",u)):gn(u)}async function fn(e,t){if(""===t.trim())throw new Error("本机删除消息需要非空 messageId");const n=()=>{if(se.isPinnedMessage(e,t))throw Object.assign(new Error("置顶消息必须先取消置顶才能删除"),{code:"IM_MESSAGE_PINNED"})};n();const o=Ee(e,t),r=Q.get(t,e),s=void 0!==r&&r.conversationType===e.conversationType&&r.conversationId===e.conversationId,i=Q.getByConversation(e).filter(e=>e.id!==t),a=void 0===te.get(e)?void 0:Xt(e,i,"clear"),c=void 0===a?void 0:bt(a);function d(e){return void 0!==e&&(void 0===r||!D(r,e))}const u=void 0===ye?{deleted:!1,superseded:!1}:await Tt(async()=>{n();const r=Ee(e,t)??o??await ye.getMessage(e,t)??void 0;if(n(),d(Q.get(t,e)))return{deleted:!1,superseded:!0};const s=await ye.deleteMessage(e,t,c);if(se.isPinnedMessage(e,t)){const o=Ee(e,t)??r;void 0!==o&&await ye.saveMessages([Mt(o)]);const s=te.get(e);return void 0!==s&&await ye.saveSessions([bt(s)]),n(),{deleted:!1,superseded:!0}}return{deleted:s,superseded:!1}});if(u.superseded||d(Q.get(t,e)))return!1;const l=s&&Q.delete(e,t);let v=!1;for(const n of Te)v=n.removeMessage(e,t)||v;if(!u.deleted&&!l&&!v)return!1;const f=void 0===te.get(e)?void 0:Xt(e,Q.getByConversation(e),"clear");return Vt(f,!1),void 0===f||void 0!==a&&Y(a,f)||Et(f),$e(e,t),x.emitter.emit({type:"message:removed",conversation:{...e},messageId:t,scope:"local-only"}),!0}function pn(t,o={}){const r="string"==typeof t?t:t.conversationId,s=te.get(t),i=se.get(t),a="string"==typeof t?void 0!==s?{conversationType:s.type,conversationId:r}:void 0===i?void 0:n(i):t;if(void 0===a)throw new Error(`裸 conversationId 无法确定删除类型:${r}`);if(et(a),Oe.delete(e(a)),"direct"===a.conversationType&&(tt(a),ze.delete(a.conversationId)),mt(a),"direct"===a.conversationType||"group"===a.conversationType||"channel"===a.conversationType)if(!0===o.terminal)ve.delete(e(a));else{const t=g(a,Ue(a),ve.get(e(a)));void 0!==t&&ve.set(e(a),t)}const c=Q.getByConversation(a).length;!function(t){const n=xt(t),o=e(n);Ce.set(o,(Ce.get(o)??0)+1),null!==re.get(n)&&(re.delete(n),x.emitter.emit({type:"draft:cleared",conversation:n})),Bt(n,async()=>{void 0!==ye&&await ye.deleteDraft(n)}).catch(e=>nt("删会话草稿失败",e))}(a),De(a),te.delete(t),ne.delete(t),"channel"===a.conversationType&&(de(a.conversationId),ie.delete(a.conversationId)),oe.delete(t),Q.deleteByConversation(t),se.clear(t);const d=qe(a);if(!0===o.terminal){fe.add(d);const e=pe.delete(d);le.delete(d),le.delete(r),e&&Rt(),x.diagnostics?.record("info","core","conversation","membership-terminated",()=>({conversation:a,data:{reason:o.terminalReason??"membership-terminated",removedMessageCount:c}}))}else le.add(d);for(const e of Te)Ae(e,a)&&e.reset();x.emitter.emit({type:"session:removed",conversationId:r,conversation:a}),Ut(),!0===o.terminal&&At(),void 0!==ye&&Tt(async()=>{await ht([ye.deleteConversationMessages(a),ye.deleteSession(a),ye.deleteReadState(a),ye.removePinnedMessage(a)])}).catch(e=>nt("删除会话持久数据失败",e))}function yn(e,t){pn(e,{terminal:!0,terminalReason:t})}function mn(e){if("string"==typeof e){const t=[...te.getAll(),...ne.getAll()].filter(t=>t.id===e);if(t.length>1)throw new Error(`裸 conversationId 存在多类型歧义:${e}`);return t[0]}return te.get(e)??ne.get(e)}function gn(e){const t=o(e);void 0!==te.get(t)?(te.set(e),ot(e),Et(e)):(ne.set(e),x.emitter.emit({type:"conversation-context:updated",conversation:t}))}async function hn(n,o){let r=await ye.getMessages(n,{limit:50});const s=o=>o.filter(o=>e(t(o))===e(n)&&Ze(o)),a=s(r);if(!["direct","group","channel"].includes(n.conversationType)||!o())return a;let c=g(n,a);for(;o()&&50===r.length;){const e=r[0].sortKey;if(void 0!==c&&e<i(c.serverTime,""))break;if(r=await ye.getMessages(n,{beforeSortKey:e,limit:50}),!o())return[];if(r.some(t=>t.sortKey>=e))throw new Error("会话本地历史游标没有向前推进");const t=s(r);c=g(n,t,c),a.push(...t.filter(e=>void 0!==c&&d(e)===c.serverTime))}return a}return{upsertMessages:nn,commitReceivedMessages:function(n,o,r,s){if(void 0===ye){for(const e of s?.events??[])s.apply(e);return void nn(n,o,r)}const i={writes:[],messages:/* @__PURE__ */new Set,sessions:/* @__PURE__ */new Set,reads:/* @__PURE__ */new Set,metadata:/* @__PURE__ */new Set};st.add(i);try{const a=(s?.events??[]).filter(e=>"ignored"!==s.apply(e));nn(n,o,r);const c=a.flatMap(e=>{const t=Ee(e.conversation,e.parentMessageId);return void 0===t?[]:[t]});a.length>0&&Ne();const d=/* @__PURE__ */new Map,u=[];for(const o of[...n,...c]){const n=t(o),r=e(n),s=Ee(n,o.id);void 0!==s&&(d.set(r,n),i.messages.has(`${r}\0${s.id}`)||u.push(s))}St(u);for(const[e,t]of d){const n=te.get(t),o=oe.get(t);void 0===n||i.sessions.has(e)||Et(n),void 0===o||i.reads.has(e)||Pt(o)}for(const[e,t]of it)i.metadata.has(e)||t.persist()}finally{st.delete(i)}return ht(i.writes)},prepareOfflineMessageUpdate:function(n,o){if(void 0===ye)return!0;const r=t(n),s=ve.get(e(r));if(void 0===s||Ge(r)||m(n,s)||void 0!==Ee(r,n.id))return!0;const i=vt,a=e(r),c=ft.get(a)??0;o();let d=!1,u=Ee(r,n.id);const l=x.emitter.subscribe(o=>{"message:received"!==o.type&&"message:updated"!==o.type||o.message.id!==n.id||e(t(o.message))!==a||("live"!==o.source||void 0!==u&&B(u,o.message)||(d=!0),u=o.message)});return ye.getMessage(r,n.id).then(s=>{if(o(),i!==vt||(ft.get(a)??0)!==c)throw new DOMException("消息提交前的本地历史读取已失效","AbortError");return!d&&(void 0===Ee(r,n.id)&&null!==s&&s.id===n.id&&e(t(s))===a&&Ze(s)&&Q.upsert(s),!0)}).finally(l)},applyReaction:Be,rollbackReaction:function(t,n,o){const r=Ee(t,n);if(void 0===r){const r=`${e(t)}\0${n}`,s=Z.get(r);if(void 0===s)return!1;const i=s.filter(e=>e.id!==o);return i.length!==s.length&&(0===i.length?Z.delete(r):Z.set(r,i),Ne(),!0)}const s=C(r.reactions,o,x.getSelfId?.()??"");if(s===r.reactions)return!1;const i={...r};return void 0===s?delete i.reactions:i.reactions=s,nn([i],"live"),!0},appendDirectContactRequiredNotice:on,appendDirectMessageRefusedNotice:function(e,t,n=Date.now()){const o={conversationType:"direct",conversationId:e},r=`${t}:message-refused`;if(void 0!==Q.get(r,o))return;const s=Q.get(t,o),c="direct"===s?.conversationType&&s.conversationId===e?a(s):n;nn([{id:r,conversationId:e,conversationType:"direct",senderId:e,contentType:"system",body:{system:{eventType:"direct_message_refused",targetUserIds:[e]}},createdAt:c,sortKey:i(c,r),status:"sent",receipt:"unread",encryption:{encrypted:!1,decryptFailed:!1}}],"live")},appendDirectContactRequiredTextFailure:function(e,t=Date.now()){const n=L(),o={id:n,conversationId:e.conversationId,conversationType:"direct",senderId:e.senderId,contentType:"text",body:{text:e.text},createdAt:t,sortKey:i(t,n),status:"failed",receipt:"unread",encryption:{encrypted:!1,decryptFailed:!1},failure:{code:33281,reason:"rejected",displayCode:"contactRequired",retryable:!1},...void 0===e.refMessageId?{}:{refMessageId:e.refMessageId}};return nn([o],"live"),on(e.conversationId,n,t+1),o},reconcileDirectContactEstablishedNotice:function(e,t,n=Date.now()){const o=rn.get(e);if(void 0!==o)return o;const r={conversationType:"direct",conversationId:e},s=sn,a=(async()=>{const o=Q.getByConversation(r).filter(e=>{const t=e.body.system?.eventType;return"direct_contact_required"===t||"direct_contact_established"===t}),a=o.filter(e=>"direct_contact_required"===e.body.system?.eventType),c=a.at(-1)?.createdAt??0,d=o.findLast(e=>"direct_contact_established"===e.body.system?.eventType)?.createdAt??0,u=d>=c&&d>0;if(0===a.length&&u)return;const l=Ot(r);for(const e of a)try{const t=await fn(r,e.id),n=Ee(r,e.id);t||"direct_contact_required"!==n?.body.system?.eventType||x.emitter.emit({type:"error",error:{scope:"storage",message:"联系人关系已建立,但旧的申请添加提示未能删除",cause:{conversation:r,messageId:e.id}}})}catch(t){x.emitter.emit({type:"error",error:{scope:"storage",message:"联系人关系已建立,但删除旧的申请添加提示失败",cause:{conversation:r,messageId:e.id,error:t}}})}if(s!==sn)return;const v=oe.get(r);if(void 0!==v&&(Gt({...v,...void 0===v.readCursorSortKey&&void 0!==l?{readCursorSortKey:l}:{},unreadCount:Ht(r,l)}),Yt(r)),u)return;const f=Number.isFinite(n)&&n>0?n:Date.now(),p=Math.max(f,c+1);!function(e,t,n=Date.now(),o=n){const r=function(e,t){return`${""===e.trim()?`contact-established:${t}`:e}:contact-established`}(t,o);if(void 0!==Q.get(r,{conversationType:"direct",conversationId:e}))return;nn([{id:r,conversationId:e,conversationType:"direct",senderId:e,contentType:"system",body:{system:{eventType:"direct_contact_established",targetUserIds:[e]}},createdAt:n,sortKey:i(n,r),status:"sent",receipt:"unread",encryption:{encrypted:!1}}],"live")}(e,t,p,f)})().finally(()=>{rn.get(e)===a&&rn.delete(e)});return rn.set(e,a),a},recallMessage:function(e,t,n){const o=Ee(e,t);void 0!==o&&nn([{...o,recalled:n,body:{}}],"live")},deleteChannelMessageForEveryone:function(e,t,n){const o=Ee(e,t);void 0!==o&&"channel"===o.conversationType&&nn([{...o,recalled:void 0,deletedForEveryone:n,body:{}}],"live")},editMessage:function(e,t,n,o){const r=Ee(e,t);if(void 0===r)return;const s={...r,body:n,edited:!0};void 0!==o?s.mention=o:delete s.mention,nn([s],"live")},applyTransferStatusBySerialNumber:async function(e,t,n){const o=function(e,t){if(void 0===e)return t;if(0===e.status&&0!==t.status)return t;if(0===t.status&&0!==e.status)return e;const n=e.occurredTime??0,o=t.occurredTime??0;return n!==o?o>n?t:e:t.status>e.status?t:e}(ee.get(e),{serialNumber:e,status:t,...void 0===n?{}:{occurredTime:n}});ee.set(o.serialNumber,o),await async function(){if(void 0===ye)return;const e=[...ee.values()],t=me.then(()=>ye.setMeta(J,e));gt(t),me=t.catch(()=>{});try{await t}catch(e){throw nt("保存转账状态记录失败",e),e}}();const r=/* @__PURE__ */new Map;for(const t of u(Q.getAll(),e,o.status,o.occurredTime))r.set(t.id,t);for(const t of te.getAll()){const n=Ue({conversationType:t.type,conversationId:t.id});for(const t of u(n,e,o.status,o.occurredTime))r.set(t.id,t)}0!==r.size&&nn([...r.values()],"live")},getMessage:e=>Q.get(e),getMessagesById:e=>Q.getById(e),getConversationMessage:Ee,getLoadedMessagesByConversation:Ue,hasRecoverableConversationDeletion:Je,resolveConversationMessage:async function(n,o,r={}){const s=Ee(n,o);if(void 0!==s||void 0===ye)return s;try{const r=await ye.getMessage(n,o);if(null===r||e(t(r))!==e(n))return;return tn(r)}catch(e){if(nt("按消息 ID 读取本地历史失败",e),!0===r.throwOnStorageError)throw e;return}},getMessages:()=>Q.getAll(),getMessagesByConversation:e=>Q.getByConversation(e),deleteLocalMessage:fn,clearLocalConversationHistory:async function(e){mt(e);const t={...e},n=new Map(Q.getByConversation(t).map(e=>[e.id,e])),o=te.get(t),r=oe.get(t),s=void 0===r&&void 0===o?void 0:{...t,readCursor:r?.readCursor??o?.readCursor??"",...void 0===r?.readCursorSortKey?{}:{readCursorSortKey:r.readCursorSortKey},unreadCount:0,mentionUnreadCount:0},i=void 0===o?void 0:Qt(t,void 0,"clear",s);if(void 0!==ye){if(void 0===ye.clearConversationHistory)throw new Error("当前 storage 未实现 clearConversationHistory,拒绝非原子清空本机会话历史");await Tt(()=>ye.clearConversationHistory(t,void 0===i?void 0:bt(i),s))}const a=oe.get(t);void 0!==s&&(a?.conversationType===r?.conversationType&&a?.conversationId===r?.conversationId&&a?.readCursor===r?.readCursor&&a?.readCursorSortKey===r?.readCursorSortKey&&a?.unreadCount===r?.unreadCount&&a?.mentionUnreadCount===r?.mentionUnreadCount)&&Gt(s,!1);for(const[e,o]of n){const n=Q.get(e,t);void 0!==n&&D(o,n)&&Q.delete(t,e)}const c=Q.getByConversation(t);for(const e of Te)e.clearConversation(t)&&e.applyIncoming(c);De(t),void 0!==te.get(t)&&Vt(Xt(t,c,"clear"),!1),x.emitter.emit({type:"conversation-history:cleared",conversation:t,scope:"local-only"})},commitChannelSyncPage:function(n,o,r,s){const i=wt(n,r);return Ct(async()=>{if(!i())return!1;if(void 0===ye)throw new Error("CHANNEL 严格同步提交需要 storage");const r={writes:[],messages:/* @__PURE__ */new Map,keys:new Set(n.map(e)),current:i};let a;pt=r;try{const e=o();if(e instanceof Promise)throw e.catch(()=>{}),new Error("CHANNEL 页 mutation 必须同步执行")}catch(e){a={cause:e}}finally{pt=void 0}if(await ht(r.writes),void 0!==a)throw a.cause;if(!i())return!1;const c=[...r.messages.values()].flatMap(e=>{const n=Ee(t(e),e.id);return void 0===n?[]:[Mt(n)]}),d=[];c.length>0&&d.push(It(()=>ye.saveMessages(c)));for(const e of n){const t=te.get(e),n=oe.get(e),o=se.get(e);void 0!==t&&d.push(It(()=>ye.saveSessions([bt(t)]))),void 0!==n&&d.push(It(()=>ye.saveReadState(n))),d.push(It(()=>void 0===o?ye.removePinnedMessage(e):ye.savePinnedMessage(o)))}const u=[[W,[...Z.values()].flat()],[J,[...ee.values()]],[z,Qe()],[q,[...fe]],[G,[...pe.entries()]]];for(const[e,t]of u)d.push(It(()=>ye.setMeta(e,t)));return void 0!==s&&d.push(It(async()=>{i()&&await s()})),await ht(d),i()})},saveChannelSyncCheckpoint:function(e,t){const n=f(e,e.conversation);if(void 0===n)return Promise.reject(new Error("CHANNEL 同步位置无效"));const o=wt([n.conversation],t);return Ct(async()=>{if(!o())return!1;if(void 0===ye)throw new Error("CHANNEL 同步位置保存需要 storage");let e=!1;return await It(async()=>{o()&&(await ye.setMeta(p(n.conversation),n),e=!0)}),e&&o()})},waitForChannelSyncPersistence:async function(){for(;;){const e=lt,t=dt;if(await Promise.all([e,t,...rt]),e===lt&&t===dt&&0===rt.size)return}},getSession:e=>te.get(e),getConversationContext:mn,isMembershipTerminated:We,prepareConversation:function(e,t={}){const n=o(e);if("supergroup"===n.conversationType)throw new Error("prepareConversation:supergroup 未实现");const r=mn(n);if(void 0!==r){const t=r.title||e.title,n=r.avatar??e.avatar;return void(t===r.title&&n===r.avatar||gn({...r,title:t,avatar:n}))}if(We(n)){if(!0!==t.membershipConfirmed)throw new Error("准备聊天失败:需要重新确认成员资格");fe.delete(qe(n)),fe.delete(n.conversationId),At()}gn({...e,...void 0===e.channelPermissions?{}:{channelPermissions:{...e.channelPermissions}},...void 0===e.channelAccessSnapshot?{}:{channelAccessSnapshot:{...e.channelAccessSnapshot}}}),(oe.get(n)?.unreadCount??0)>0&&!Ge(n)&&Yt(n,!0)},ensureConversation:function(t){const n=o(t);if(e(n),"supergroup"===n.conversationType)throw new Error("ensureConversation:supergroup 未实现");const r=te.get(n);if(void 0!==r)return r;const s={...t,id:n.conversationId,type:n.conversationType,...void 0===t.channelPermissions?{}:{channelPermissions:{...t.channelPermissions}},...void 0===t.channelAccessSnapshot?{}:{channelAccessSnapshot:{...t.channelAccessSnapshot}},...void 0===t.extensions?{}:{extensions:{...t.extensions}}},i=Xe(n);return i.deleted&&Ut(),i.terminal&&At(),te.set(s),ne.delete(n),ot(s),Et(s),s},getSessions:()=>te.getAll(),getConversationList:function(){const e=[];for(const t of te.getAll()){const n=o(t);e.push({...t,draft:re.get(n)})}return b(e)},getReadState:e=>oe.get(e),getPinnedMessage:e=>se.get(e),setPinnedMessage:function(e,t){const o=function(e){const t=Ee(n(e),e.messageId);return void 0===t?e:{...e,preview:{state:"ready",message:t}}}(e);se.set(o)&&(x.emitter.emit({type:"pinned-message:updated",conversationId:o.conversationId,conversation:{conversationType:o.conversationType,conversationId:o.conversationId},pinnedMessage:o,reason:t}),function(e){void 0===ye||Re||It(()=>ye.savePinnedMessage(e)).catch(e=>nt("置顶消息落盘失败",e))}(o))},clearPinnedMessage:function(e,t){const o="string"==typeof e?e:e.conversationId,r=se.get(e);if(!se.clear(e))return;const s="string"==typeof e?void 0===r?void 0:n(r):e;if(void 0===s)throw new Error(`置顶消息清理缺少复合身份:${o}`);x.emitter.emit({type:"pinned-message:updated",conversationId:o,conversation:s,pinnedMessage:null,reason:t}),function(e){void 0===ye||Re||It(()=>ye.removePinnedMessage(e)).catch(e=>nt("置顶消息删除失败",e))}(e)},isPinnedMessage:(e,t)=>se.isPinnedMessage(e,t),setReadState:e=>{const t=void 0===e.conversationType?te.get(e.conversationId):void 0,n=void 0===e.conversationType&&void 0!==t?{...e,conversationType:t.type}:e;"channel"===n.conversationType&&de(n.conversationId),oe.set(n),Pt(n)},markConversationUnread:function(e){const t=te.get(e);if(void 0===t)return!1;const n=oe.get(e)??{...e,readCursor:t.readCursor??"",unreadCount:t.unreadCount,mentionUnreadCount:t.mentionUnreadCount};return!(n.unreadCount>0||!0===n.manuallyUnread)&&(Gt({...n,manuallyUnread:!0}),Yt(e),!0)},clearConversationManualUnread:an,advanceRead:function(e,n){const o="string"==typeof e?Q.getByConversation(e).find(e=>e.id===n)??be(n,e):Ee(e,n);if(void 0===o)return;const r="string"==typeof e?t(o):e,s="string"==typeof e?e:e.conversationId;if(o.conversationId!==s||o.conversationType!==r.conversationType)return;const i=Ot(r);if(void 0!==i&&i>=o.sortKey)return void("string"!=typeof e&&an(e));const a={...r,readCursor:n,readCursorSortKey:o.sortKey,unreadCount:Ht(r,o.sortKey),mentionUnreadCount:qt(r,o.sortKey)};return Gt(a),Yt(r),a},applyServerUnread:cn,applyChannelReadPosition:un,getChannelReadRevision:e=>ae.get(e.conversationId)??ce,hasPendingChannelRead:e=>ie.has(e.conversationId),applyChannelReadSummary:(e,t)=>cn(e,t.unreadCount,void 0,t.readCursor,t.hasUnreadMention),beginChannelReadTransaction:function(e){const t=e.conversationId,n=mn(e);if(void 0===n||"channel"!==n.type)throw new Error(`CHANNEL 乐观已读事务要求 channel 会话(conversationId=${t}, type=${n?.type??"missing"})`);if(ie.has(t))throw new Error(`CHANNEL 乐观已读事务已存在(channelId=${t})`);const o={conversation:e,transactionId:ue++},r=oe.get(e)??{conversationId:t,readCursor:n.readCursor??"",unreadCount:n.unreadCount,...void 0===n.mentionUnreadCount?{}:{mentionUnreadCount:n.mentionUnreadCount}};return ie.set(t,{handle:o,baseReadState:{...r},steps:[],committedThrough:-1}),de(t),o},applyChannelReadOptimistically:ln,applyChannelConversationReadOptimistically:function(e,t,n){ln(e,t,n);const o=dn(e).steps.at(-1);if(void 0!==o.clearedCounts)return;const i=oe.get(e.conversation),a=Ue(e.conversation).filter(e=>r(s(e),o)>0&&kt(e)&&N(e)&&!0!==e.readBySelf&&void 0===e.recalled&&void 0===e.deletedForEveryone),c=Math.min(i.unreadCount,a.length),d=Math.min(i.mentionUnreadCount??0,a.filter(zt).length);o.clearedCounts={unread:i.unreadCount-c,mention:(i.mentionUnreadCount??0)-d},Gt({...i,unreadCount:c,mentionUnreadCount:d}),Yt(e.conversation)},commitChannelReadTransaction:function(e,t){const n=dn(e);if(void 0===n)return!1;const o=n.steps.findLastIndex(e=>e.readCursor===t);if(o<0)throw new Error(`CHANNEL 已确认 cursor 不属于乐观事务(channelId=${e.conversation.conversationId}, cursor=${t})`);return n.committedThrough=Math.max(n.committedThrough,o),de(e.conversation.conversationId),n.committedThrough===n.steps.length-1&&ie.delete(e.conversation.conversationId),!0},rollbackChannelReadTransaction:function(e){const t=dn(e);if(void 0===t)return!1;const n=e.conversation,o=n.conversationId,r=oe.get(n),s=t.committedThrough>=0?t.steps[t.committedThrough]:void 0,i=void 0===s?t.baseReadState:void 0;let a=r?.unreadCount??i?.unreadCount??0,c=r?.mentionUnreadCount??i?.mentionUnreadCount??0;for(const e of t.steps.slice(t.committedThrough+1))a+=e.clearedCounts?.unread??0,c+=e.clearedCounts?.mention??0;const d=void 0!==i?.mentionUnreadCount||void 0!==r?.mentionUnreadCount,u={conversationId:o,conversationType:"channel",readCursor:s?.readCursor??i?.readCursor??"",readCursorSortKey:s?.sortKey??i?.readCursorSortKey,unreadCount:a,...d?{mentionUnreadCount:c}:{}};return ie.delete(o),Gt(u),Yt(n),!0},setGroupRestriction:function(e,t,n){const o=mn({conversationType:"group",conversationId:e});if(void 0===o){return void gn({id:e,type:"group",title:"",lastMessagePreview:"",timestamp:0,unreadCount:0,pinned:!1,muted:!1,groupState:t,sendDisabledReason:n})}if(o.groupState===t&&o.sendDisabledReason===n)return;gn({...o,groupState:t,sendDisabledReason:n})},setChannelRestriction:vn,setPinned:function(e,t){const n=te.get(e);if(void 0===n||n.pinned===t)return;const o={...n,pinned:t,topTime:t?Date.now():void 0};te.set(o),ot(o),Et(o)},setMuted:function(e,t){const n=mn(e);if(void 0===n||n.muted===t)return;gn({...n,muted:t})},removeConversation:function(e){pn(e)},removeConversationForMembershipTermination:yn,refreshConversationProfile:function(e,t){_t({conversationType:t,conversationId:e},{force:!0})},readDirectProfile:Lt,beginConversationProfileRead:function(t,n){const o={...t},r=e(o),s=Le,i=!0!==n?.forceRefresh&&(He.has(r)||Oe.has(r))?void 0:et(o);void 0!==i&&!0===n?.forceRefresh&&Oe.set(r,i);const a=()=>{s===Le&&void 0!==i&&Oe.get(r)===i&&Oe.delete(r)};return Object.assign(e=>{try{if(void 0===i||e.id!==o.conversationId||s!==Le)return;Ft(o,e.title,e.avatar??"",void 0,i)}finally{a()}},{finish:a})},recoverChannelFromProfile:function(e){return _t({conversationType:"channel",conversationId:e},{force:!0,allowChannelRecovery:!0})},updateConversationProfile:function(e,t){const n=mn(e);if(void 0===n)return;et(o(n));const r={...n,...void 0!==t.title?{title:t.title}:{},...void 0!==t.avatar?{avatar:t.avatar}:{}};Y(n,r)||gn(r)},getTotalUnread:function(e){return H(te.getAll(),e)},getDraft:function(e){return re.get(xt(e))},saveDraft:async function(t,n){const o=xt(t),r=e(o),s=$t(o,n,0),i=we,a=Ce.get(r)??0;return await Bt(o,async()=>{const e=re.get(o),t=Math.max(Date.now(),(he.get(r)??e?.updatedAt??0)+1),n=$t(o,s,t);if(null!==e&&Dt(e,n))return e;if(void 0!==ye&&await ye.saveDraft(n),i!==we||a!==(Ce.get(r)??0))throw new Error("草稿状态已失效,拒绝过期写入回灌内存");return re.set(n),he.set(r,t),x.emitter.emit({type:"draft:updated",conversation:n.ref,draft:n}),n})},clearDraft:async function(e){await jt(e)},clearDraftIfUnchanged:async function(e,t){return await jt(e,t)},invalidateAndDrainDraftOperations:async function(){for(we+=1;ge.size>0;)await Promise.all([...ge.values()])},clearSession(){vt+=1,Le+=1,we+=1,sn+=1,rn.clear(),_e.clear(),ke.clear(),Oe.clear(),He.clear(),ze.clear(),Q.clear(),te.clear(),ne.clear(),oe.clear(),re.clear(),ge.clear(),he.clear(),Ce.clear(),ie.clear(),ae.clear(),ce+=1,se.clearAll(),le.clear(),ve.clear(),fe.clear(),pe.clear(),it.clear(),Z.clear();for(const e of Te)e.reset()},hydrate:async function(t=()=>!0){if(void 0!==ye&&t()){Re=!0;try{const r=await ye.getMeta(z);if(!t())return;if(null!==r)for(const t of r)if("string"==typeof t)le.add(t);else{const n=y(t);ve.set(e(n.conversation),n)}const s=await ye.getMeta(q);if(!t())return;if(null!==s)for(const e of s)fe.add(e);const i=await ye.getMeta(G);if(!t())return;if(null!==i)for(const[e,t]of i)"string"==typeof e&&"string"==typeof t&&pe.set(e,t);const a=await ye.getMeta(W);if(!t())return;if(null!==a)for(const e of a){const t=Pe(e);Z.set(t,[...Z.get(t)??[],e])}const c=await ye.getMeta(J);if(!t())return;if(Array.isArray(c))for(const e of c){if("object"!=typeof e||null===e)continue;const t=Reflect.get(e,"serialNumber"),n=Reflect.get(e,"status"),o=Reflect.get(e,"occurredTime");"string"!=typeof t||""===t.trim()||0!==n&&1!==n&&2!==n&&3!==n||void 0!==o&&("number"!=typeof o||!Number.isFinite(o)||o<=0)||ee.set(t,{serialNumber:t,status:n,...void 0===o?{}:{occurredTime:o}})}const d=await ye.getPinnedMessages();if(!t())return;for(const e of d){if(!t())return;Ge({conversationType:e.conversationType,conversationId:e.conversationId})||se.set(e)&&x.emitter.emit({type:"pinned-message:updated",conversationId:e.conversationId,conversation:n(e),pinnedMessage:e,reason:"hydrate"})}const u=(await ye.getSessions()).filter(e=>!Ge({conversationType:e.type,conversationId:e.id}));if(!t())return;for(const e of u){if(!t())return;const n=Xt(o(e),[],"preserve",e),r=o(n),s=te.get(r);te.set(n),ne.delete(r),void 0!==s&&Y(s,n)||ot(n)}const l=await ye.getReadStates();if(!t())return;for(const e of l)"channel"===e.conversationType&&de(e.conversationId),oe.set(e);const v=we,f=await ye.getDrafts();if(!t())return;if(v!==we)return;for(const n of f){if(!t())return;if(!Number.isFinite(n.updatedAt)||n.updatedAt<0)throw new Error(`草稿 updatedAt 非法:${n.updatedAt}`);const o=$t(n.ref,n,n.updatedAt);if(Ge(o.ref)){try{if(await ye.deleteDraft(o.ref),!t())return}catch(e){if(!t())return;nt("清理已删会话残留草稿失败",e)}continue}const r=e(o.ref);he.set(r,Math.max(he.get(r)??0,o.updatedAt));const s=re.get(o.ref);null!==s&&s.updatedAt===o.updatedAt&&Dt(s,o)||(re.set(o),x.emitter.emit({type:"draft:updated",conversation:o.ref,draft:o}))}for(const e of u){if(!t())return;const n=o(e),r=await hn(n,t);if(!t())return;const s=[];if(en(r.map(e=>{const t=Zt(A(e));return t!==e&&s.push(t),t}),t),!t())return;if(s.length>0)try{if(await ye.saveMessages(s),!t())return}catch(e){if(!t())return;nt("本地消息修复态落盘失败",e)}if(!t())return;Yt(n)}}catch(e){t()&&nt("本地历史回读失败",e)}finally{Re=!1,t()&&Fe("offline")}}},loadOlderMessages:async function(n,o){if(void 0===ye)return[];try{const r=await ye.getMessages(n,o),s="string"==typeof n?r.filter(Ze):r.filter(o=>e(t(o))===e(n)).filter(Ze),i=Re;let a;Re=!0;try{a=en(s)}finally{Re=i}return Re||Fe("offline"),a.map(e=>Ee(t(e),e.id)??e)}catch(e){return nt("加载更早消息失败",e),[]}},searchMessages:async function(n,o){const r=o.keyword?.trim()??"",s=o.contentTypes;if(""===r&&(void 0===s||0===s.length))return{results:[],exhausted:!0};const i=""===r?void 0:await K(r),a=e=>{const t=void 0===s||s.includes(e.contentType),n=void 0===i||null!==i.match(U(e));return t&&n},c=(e,t)=>e.sortKey<t.sortKey?1:e.sortKey>t.sortKey?-1:0,d=e=>function(e,t){const n=t?.match(U(e));return{message:e,ranges:n?.ranges.map(({start:e,end:t})=>[e,t])??[]}}(e,i);if(void 0===ye)return(()=>{const e=Q.getByConversation(n).filter(a).sort(c),t=(void 0===o.beforeSortKey?e:e.filter(e=>e.sortKey<o.beforeSortKey)).slice(0,o.limit),r=t.length<o.limit;return{results:t.map(d),exhausted:r,...r?{}:{nextBeforeSortKey:t.at(-1)?.sortKey}}})();let u;try{u=await ye.searchMessages(n,{...void 0!==o.keyword?{keyword:o.keyword}:{},...void 0!==s?{contentTypes:s}:{},limit:o.limit,...void 0!==o.beforeSortKey?{beforeSortKey:o.beforeSortKey}:{}})}catch(e){throw nt("会话内搜索失败",e),e}const l=u.exhausted?void 0:u.nextBeforeSortKey,v=new Map(Q.getByConversation(n).map(e=>[e.id,e])),f=/* @__PURE__ */new Map;for(const o of u.items){const r=tn(o);e(t(r))===e(n)&&f.set(r.id,v.get(r.id)??r)}for(const e of v.values()){const t=void 0===o.beforeSortKey||e.sortKey<o.beforeSortKey,n=void 0===l||e.sortKey>=l;t&&n&&a(e)&&f.set(e.id,e)}return{results:[...f.values()].filter(a).sort(c).map(d),exhausted:u.exhausted,...u.exhausted?{}:{nextBeforeSortKey:u.nextBeforeSortKey}}},messageWindow:Se,createMessageWindow:function(e={}){const t=Me(e);let n=!1;return{window:t,dispose(){n||(n=!0,t.reset(),Te.delete(t))}}}}}export{Z as createDomainState,O as defaultConversationUnreadMode,H as sumSessionsUnread};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveGroupHistoryPageBoundary as e}from"./group-history-page-boundary.js";import{throwIfAborted as r}from"../../../im-core/src/abort.js";import{pullGroupHistory as o}from"../../../im-browser/src/http/requests/pull-offline-group.js";import{
|
|
1
|
+
import{resolveGroupHistoryPageBoundary as e}from"./group-history-page-boundary.js";import{throwIfAborted as r}from"../../../im-core/src/abort.js";import{pullGroupHistory as o}from"../../../im-browser/src/http/requests/pull-offline-group.js";import{yieldToBrowser as t}from"../../../im-browser/src/scheduling/yield-to-browser.js";import{pullChannelLatestPage as s}from"../../../im-browser/src/http/requests/pull-offline-channel.js";function n(n){return async(i,p)=>{r(p);const a="group"===i.conversationType?n.groupAsyncDecrypt?.({conversationType:"group",conversationId:i.conversationId},p):void 0;a?.assertCurrent?.();const c=await n.authProvider.getLoginContext();if(r(p),null===c)throw new Error("最近历史请求缺少当前账号");n.assertLoginContext?.(c.userId),a?.assertCurrent?.();const u=[],y=[],d=e=>{y.push({...e,source:"history"})},l=e=>{u.push(e)};if("group"===i.conversationType){const s={...n.groupDecrypt(),onDecryptRecovery:d},m=Date.now(),g=await o({asyncDecrypt:a,http:n.http,userId:c.userId,clientType:n.clientType,groupId:i.conversationId,baseTime:m,direct:1,limit:30,decryptDeps:s,prepareKeys:e=>n.prepareGroupKeys(e,{signal:p,priority:n.keyPriority?.(i)??"foreground"}),onReaction:l,signal:p,keepRaw:!1,yieldToEventLoop:t});r(p),a?.assertCurrent?.();const h=e({conversationId:i.conversationId,direction:"older",baseTime:m,batchSize:g.batchSize,boundaryTime:g.oldestEntryTime,limit:30});return{messages:g.messages,reactions:u,recoveries:y,...h}}const m={...n.channelDecrypt(),onDecryptRecovery:d},g=await s({http:n.http,userId:c.userId,clientType:n.clientType,channelId:i.conversationId,count:30,decryptDeps:m,prepareKey:e=>n.prepareChannelKeys([e],{signal:p,priority:n.keyPriority?.(i)??"foreground"}),onReaction:l,signal:p,keepRaw:!1,yieldToEventLoop:t});return r(p),{messages:g.messages,reactions:u,recoveries:y,exhausted:!g.hasOlder,...void 0===g.nextCursor?{}:{nextCursor:g.nextCursor}}}}export{n as createRecentHistoryFetcher};
|