k2-im 0.2.16 → 0.2.17
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/chat-kit-pinia.d.ts +55 -11
- package/dist/chat-kit-vue.d.ts +5 -5
- package/dist/chat-kit.d.ts +101 -11
- package/dist/index.d.ts +104 -13
- package/dist/modules/im-browser/src/http/cm-http-adapter.js +1 -1
- package/dist/modules/im-browser/src/http/request-timeout.js +1 -0
- package/dist/modules/im-browser/src/http/requests/core-json-request.js +1 -1
- package/dist/modules/im-browser/src/http/requests/get-conversation-background-presets.js +1 -1
- package/dist/modules/im-browser/src/http/requests/pull-offline-channel.js +1 -1
- package/dist/modules/im-browser/src/media/media-download-request.js +1 -0
- package/dist/modules/im-browser/src/media/media-downloader.js +1 -1
- package/dist/modules/im-browser/src/media/media-preview-preparation-executor.js +1 -1
- package/dist/modules/im-browser/src/media/media-transfer-policy.js +1 -1
- package/dist/modules/im-browser/src/storage/indexed-db-storage-adapter.js +1 -1
- package/dist/modules/im-chat-kit/src/runtime/chat-runtime.js +1 -1
- package/dist/modules/im-chat-kit/src/runtime/media-object-url-registry.js +1 -1
- package/dist/modules/im-chat-kit/src/services/media.service.js +1 -1
- package/dist/modules/im-chat-kit/src/utils/media-transfer-presentation.js +1 -1
- package/dist/modules/im-core/src/mapping/group-offline-mapper.js +1 -1
- package/dist/modules/im-core/src/message-flow/media/media-sender.js +1 -1
- package/dist/modules/im-sdk/src/create-im-client.js +1 -1
- package/dist/modules/im-sdk/src/product/conversation-handle.js +1 -1
- package/dist/modules/im-sdk/src/product/media.js +1 -1
- package/dist/modules/im-sdk/src/runtime/history-page-size.js +1 -0
- package/dist/modules/im-sdk/src/runtime/local-media-preview.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/dist/sdk.d.ts +49 -10
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{openDB as e,deleteDB as t}from"idb";import{encodeConversationKey as a,conversationRefFromPinnedMessage as n,conversationRefFromMessage as o,conversationRefFromSession as s}from"../../../im-core/src/conversation-identity.js";import{createImTextSearchMatcher as r,extractSearchText as i}from"../../../im-core/src/mapping/search-text.js";import{normalizeStoredMessageContent as c}from"../../../im-core/src/mapping/stored-message.js";import{computeMessageSortKey as d}from"../../../im-core/src/mapping/sort.js";import{isStaleMiniProgramShowTypeProjection as l}from"../../../im-core/src/mapping/mini-program-body.js";import{channelSyncCheckpointKey as y}from"../../../im-core/src/sync/channel-sync-checkpoint.js";const u=1073741824;const v="channel:list-version",m="schema:conversation-key-v1",w="schema:message-server-order-v1",g="schema:mini-program-game-preview-v1",f="im:membership-reset-sort-keys",p="default",h="";function b(e){if(void 0!==e&&/^\d+$/.test(e))return e.replace(/^0+(?=\d)/,"")}function S(e,t){const a=b(e),n=b(t);return void 0===a?void 0===n?0:-1:void 0===n?1:a.length!==n.length?a.length>n.length?1:-1:a===n?0:a>n?1:-1}function j(e){return`conversation:${a(e)}`}function k(e,t){return`${a(e)}\0${t}`}function M(e){const{key:t,conversationKey:a,...n}=e;return{...n,conversation:{...n.conversation},sContent:n.sContent.slice()}}function A(e,t){return JSON.stringify([a(e),t])}function C(e){const t=o(e);return{...e,messageKey:A(t,e.id),conversationKey:a(t)}}function I(e){const{messageKey:t,conversationKey:a,...n}=e;return n}function P(e){return{...e,id:a(s(e)),conversationId:e.id}}function K(e){if(void 0===e.conversationId)return e;const{conversationId:t,...a}=e;return{...a,id:t}}function x(e){return void 0===e.conversationType?e:{...e,conversationId:a(e),storageConversationId:e.conversationId}}function _(e){if(void 0===e.storageConversationId)return e;const{storageConversationId:t,...a}=e;return{...a,conversationId:t}}function B(e){return{...e,conversationId:a(n(e)),storageConversationId:e.conversationId}}function R(e){if(void 0===e.storageConversationId)return e;const{storageConversationId:t,...a}=e;return{...a,conversationId:t}}function N(e){const{conversationKey:t,...a}=e;return a}function T(e,t){if(new Set(t.map(e=>e.conversationType)).size>1)throw new Error(`裸 conversationId 存在多类型歧义:${e}`)}function O(e){return`${e.kind}:${encodeURIComponent(e.messageId)}:${e.resourceVersion}`}async function D(e,t){const a=e.done;a.catch(()=>{});try{const e=await t();return await a,e}catch(t){try{e.abort()}catch{}throw await a.catch(()=>{}),t}}function L(e){return e.catch(()=>{}),e}async function H(e,t,a){const n=e.transaction(t);return await D(n,async()=>await n.store.get(a))}async function E(e,t){const a=e.transaction(t);return await D(a,async()=>await a.store.getAll())}async function V(e,a){const n=a.namespaceFactory.forAccount(e).name("durable","storage","indexed-db");"undefined"!=typeof indexedDB&&await t(n)}function $(t){const{namespaceFactory:b}=t;let V=null,$=null,z=0,F=Promise.resolve(),G=Promise.resolve(),U=0;const q=t.mediaAssetCache?.maxPendingWriteBytes??268435456;if(!Number.isSafeInteger(q)||q<=0)throw new RangeError("媒体资产缓存待写内存预算必须是正整数");function J(){if(null===V)throw new Error("ImStoragePort 未 open:请先 open({ namespace }) 再读写");return V}function Q(e){const t=z,a=$,n=()=>{if(t!==z||a!==$)throw new Error("最近历史缓存操作已失效:账号或存储已改变");J()},o=F.then(async()=>{n();const t=await e();return n(),t});return F=o.then(()=>{},()=>{}),o}function W(e,t){return 2!==e.version||!Number.isFinite(e.fetchedAt)||e.fetchedAt<0||t-e.fetchedAt>=864e5}async function Y(e){if(!Number.isSafeInteger(e.byteLength)||e.byteLength<0)throw new Error("最近历史缓存 byteLength 必须是非负安全整数");const t=Date.now();if(e.byteLength>2097152||W(e,t))return!1;const n=a(e.conversation),o=J().transaction("recentHistoryPages","readwrite");return D(o,async()=>{const a=await o.store.getAll(),s=[];for(const e of a)W(e,t)?await o.store.delete(e.conversationKey):e.conversationKey!==n&&s.push(e);const r={...e,conversationKey:n};s.push(r),s.sort((e,t)=>e.fetchedAt-t.fetchedAt||e.conversationKey.localeCompare(t.conversationKey));let i=s.reduce((e,t)=>e+t.byteLength,0);const c=[];for(;s.length>20||i>8388608;){const e=s.shift();c.push(e),i-=e.byteLength}if(c.includes(r))return!1;await o.store.put(r);for(const e of c)await o.store.delete(e.conversationKey);return!0})}function X(e){const t=G.then(e,e);return G=t.then(()=>{},()=>{}),t}function Z(e,t){if(e!==z||null===t||t!==$)throw new Error("媒体资产缓存账号代际已失效")}function ee(){return Math.max(0,Math.floor(t.mediaAssetCache?.now?.()??Date.now()))}function te(e,a){const n=t.mediaAssetCache?.strategies.resolve(e.kind)?.maxIdleMs;return void 0!==n&&(!Number.isSafeInteger(e.lastAccessedAt)||e.lastAccessedAt<0||a-e.lastAccessedAt>=n)}async function ae(e,t){Z(e,t);const a=await E(J(),"mediaAssetMeta");Z(e,t);const n=ee(),o=a.filter(e=>te(e,n));await oe(o.map(e=>e.key),e,t),Z(e,t);const s=new Set(o.map(e=>e.key));return a.filter(e=>!s.has(e.key))}async function ne(e){const a=t.mediaAssetCache?.estimateStorage??(async()=>"undefined"==typeof navigator||void 0===navigator.storage?.estimate?{}:await navigator.storage.estimate());try{const{quota:t,usage:n}=await a();if(void 0===t||!Number.isFinite(t)||t<=0)return u;const o=e.reduce((e,t)=>e+t.byteLength,0),s=Math.max(0,(n??0)-o),r=Math.max(536870912,Math.floor(.2*t));return Math.max(0,Math.min(2147483648,Math.floor(t-s-r)))}catch{return u}}async function oe(e,t,a){if(0===e.length)return;Z(t,a);const n=J().transaction(["mediaAssets","mediaAssetMeta"],"readwrite");await D(n,async()=>{await Promise.all(e.flatMap(e=>[L(n.objectStore("mediaAssets").delete(e)),L(n.objectStore("mediaAssetMeta").delete(e))]))})}async function se(e,a,n,o){Z(e,a);const s=J(),r=t.mediaAssetCache?.strategies;if(void 0===r)return;const i=o??await E(s,"mediaAssetMeta");Z(e,a);const c=/* @__PURE__ */new Set;for(const e of r.list()){const t=i.filter(t=>t.kind===e.kind).sort((e,t)=>e.lastAccessedAt-t.lastAccessedAt);let a=t.reduce((e,t)=>e+t.byteLength,0),n=t.length;for(const o of t){if(a<=e.softMaxBytes&&n<=e.maxEntries)break;c.add(o.key),a-=o.byteLength,n-=1}}const d=i.filter(e=>!c.has(e.key)).sort((e,t)=>e.lastAccessedAt-t.lastAccessedAt),l=Math.max(0,Math.min(await ne(i),n??Number.POSITIVE_INFINITY));let y=d.reduce((e,t)=>e+t.byteLength,0);for(const e of d){if(y<=l)break;c.add(e.key),y-=e.byteLength}await oe([...c],e,a)}return{supportsChannelSyncCheckpoint:!0,recentHistoryCache:{get:e=>Q(async()=>{const t=a(e),n=J().transaction("recentHistoryPages","readwrite");return D(n,async()=>{const e=await n.store.get(t);if(void 0===e)return null;if(W(e,Date.now()))return await n.store.delete(t),null;const{conversationKey:a,...o}=e;return o})}),async put(e){if("function"==typeof structuredClone){const t=structuredClone(e);return Q(()=>Y(t))}const t=function(e){return new Promise((t,a)=>{const n=new MessageChannel,o=()=>{n.port1.close(),n.port2.close()};n.port1.onmessage=e=>{o(),t(e.data)},n.port1.onmessageerror=()=>{o(),a(new DOMException("最近历史缓存快照无法反序列化","DataCloneError"))};try{n.port2.postMessage(e)}catch(e){o(),a(e)}})}(e).then(e=>({ok:!0,value:e}),e=>({ok:!1,error:e}));return Q(async()=>{const e=await t;if(!e.ok)throw e.error;return Y(e.value)})},delete:e=>Q(async()=>{await J().delete("recentHistoryPages",a(e))}),clear:()=>Q(async()=>{await J().clear("recentHistoryPages")})},async open({namespace:t}){if(null!==V&&$===t)return;null!==V&&(V.close(),V=null),$=t;const n=++z,s=b.forAccount(t).name("durable","storage","indexed-db");let r;const i=await e(s,16,{upgrade(e,t,a,n){if(e.objectStoreNames.contains("messages"))n.objectStore("messages").indexNames.contains("by_conversation_key_sort")||n.objectStore("messages").createIndex("by_conversation_key_sort",["conversationKey","sortKey"]);else{const t=e.createObjectStore("messages",{keyPath:"messageKey"});t.createIndex("by_conv_sort",["conversationId","sortKey"]),t.createIndex("by_conversation_key_sort",["conversationKey","sortKey"])}if(e.objectStoreNames.contains("sessions")||e.createObjectStore("sessions",{keyPath:"id"}),e.objectStoreNames.contains("readStates")||e.createObjectStore("readStates",{keyPath:"conversationId"}),e.objectStoreNames.contains("drafts")||e.createObjectStore("drafts",{keyPath:"conversationKey"}),e.objectStoreNames.contains("outbox")||e.createObjectStore("outbox",{keyPath:"id"}),e.objectStoreNames.contains("meta")||e.createObjectStore("meta",{keyPath:"key"}),e.objectStoreNames.contains("userProfiles")||e.createObjectStore("userProfiles",{keyPath:"id"}),e.objectStoreNames.contains("groupMembers")||e.createObjectStore("groupMembers",{keyPath:"groupId"}),e.objectStoreNames.contains("groupProfiles")||e.createObjectStore("groupProfiles",{keyPath:"id"}),e.objectStoreNames.contains("pinnedMessages")||e.createObjectStore("pinnedMessages",{keyPath:"conversationId"}),e.objectStoreNames.contains("channelProfiles")||e.createObjectStore("channelProfiles",{keyPath:"id"}),e.objectStoreNames.contains("channelMembers")||e.createObjectStore("channelMembers",{keyPath:["channelId","userId"]}),e.objectStoreNames.contains("channelMemberSnapshots")||e.createObjectStore("channelMemberSnapshots",{keyPath:"channelId"}),e.objectStoreNames.contains("channelMentionCandidateSnapshots")||e.createObjectStore("channelMentionCandidateSnapshots",{keyPath:"channelId"}),e.objectStoreNames.contains("conversationBackgrounds")||e.createObjectStore("conversationBackgrounds",{keyPath:"key"}),e.objectStoreNames.contains("mediaAssets")||e.createObjectStore("mediaAssets",{keyPath:"key"}),!e.objectStoreNames.contains("mediaAssetMeta")){const t=e.createObjectStore("mediaAssetMeta",{keyPath:"key"});t.createIndex("by_kind_access",["kind","lastAccessedAt"]),t.createIndex("by_access","lastAccessedAt")}if(!e.objectStoreNames.contains("decryptRecoveries")){e.createObjectStore("decryptRecoveries",{keyPath:"key"}).createIndex("by_conversation","conversationKey")}if(t>0&&t<13&&(n.objectStore("mediaAssets").clear(),n.objectStore("mediaAssetMeta").clear()),e.objectStoreNames.contains("recentHistoryPages")||e.createObjectStore("recentHistoryPages",{keyPath:"conversationKey"}),t>0&&t<16&&"messageKey"!==n.objectStore("messages").keyPath){(async()=>{const t=await n.objectStore("messages").getAll();for(const e of t)e.messageKey=A(o(e),e.id);e.deleteObjectStore("messages");const a=e.createObjectStore("messages",{keyPath:"messageKey"});a.createIndex("by_conv_sort",["conversationId","sortKey"]),a.createIndex("by_conversation_key_sort",["conversationKey","sortKey"]);for(let e=0;e<t.length;e+=128){const n=t.slice(e,e+128);await Promise.all(n.map(async e=>a.put(e)))}})().catch(e=>{r=e,n.done.catch(()=>{});try{n.abort()}catch{}})}}}).catch(e=>{throw r??e});if(n===z){try{await async function(e){const t=e.transaction(["messages","sessions","readStates","pinnedMessages","meta"],"readwrite");try{const e=t.objectStore("meta");if(!0===(await e.get(m))?.value)return void await t.done;const a=t.objectStore("messages");for(const e of await a.getAll())void 0===e.conversationKey&&await a.put(C(e));const n=t.objectStore("sessions"),o=/* @__PURE__ */new Map;for(const e of await n.getAll()){if(void 0!==e.conversationId)continue;const t=K(e);o.set(t.id,t.type),await n.put(P(t)),await n.delete(e.id)}const s=t.objectStore("readStates");for(const e of await s.getAll()){if(void 0!==e.storageConversationId)continue;const t=e.conversationType??o.get(e.conversationId);if(void 0===t)continue;const a={...e,conversationType:t};await s.put(x(a)),await s.delete(e.conversationId)}const r=t.objectStore("pinnedMessages");for(const e of await r.getAll()){if(void 0!==e.storageConversationId)continue;const t=R(e);await r.put(B(t)),await r.delete(e.conversationId)}await e.put({key:m,value:!0}),await t.done}catch(e){try{t.abort()}catch{}try{await t.done}catch{}throw e}}(i),await async function(e){const t=e.transaction(["messages","readStates","meta"],"readwrite");try{const e=t.objectStore("meta");if(!0===(await e.get(w))?.value)return void await t.done;const n=t.objectStore("readStates"),s=await n.getAll(),r=/* @__PURE__ */new Map;for(const e of s){const t=_(e);"channel"===t.conversationType&&void 0!==t.readCursorSortKey&&""!==t.readCursor&&r.set(a(t),{cursor:t.readCursor})}const i=/* @__PURE__ */new Map,c=t.objectStore("messages");let l=await c.openCursor();for(;null!==l;){const e=l.value,t=a(o(e)),n=d(e),s=r.get(t);if(void 0!==s&&e.extensions?.historyCursor===s.cursor&&(s.sortKey=n),n!==e.sortKey){let a=i.get(t);void 0===a&&(a=/* @__PURE__ */new Map,i.set(t,a)),a.set(e.sortKey,n),await l.update({...e,sortKey:n})}l=await l.continue()}for(const e of s){const t=_(e);if(void 0===t.conversationType)continue;const s=a(t);let d=r.get(s)?.sortKey??(void 0===t.readCursorSortKey?void 0:i.get(s)?.get(t.readCursorSortKey));if(void 0===d&&void 0!==t.readCursorSortKey&&"channel"!==t.conversationType&&""!==t.readCursor){const e=await c.get(A(t,t.readCursor));void 0!==e&&a(o(e))===s&&(d=e.sortKey)}void 0!==d&&d!==t.readCursorSortKey&&await n.put({...e,readCursorSortKey:d})}const y=await e.get(f);if(Array.isArray(y?.value)){let t=!1;const a=y.value.map(e=>{if(!Array.isArray(e)||2!==e.length||"string"!=typeof e[0]||"string"!=typeof e[1])return e;const a=i.get(e[0])?.get(e[1]);return void 0===a?e:(t=!0,[e[0],a])});t&&await e.put({key:f,value:a})}await e.put({key:w,value:!0}),await t.done}catch(e){try{t.abort()}catch{}try{await t.done}catch{}throw e}}(i),await async function(e){const t=e.transaction(["messages","meta"],"readwrite");try{const e=t.objectStore("meta");if(!0===(await e.get(g))?.value)return void await t.done;const a=t.objectStore("messages");let n=await a.openCursor();for(;null!==n;){const e=n.value.body?.miniProgram;"miniProgram"===n.value.contentType&&void 0!==e&&l(e)&&await n.delete(),n=await n.continue()}await e.put({key:g,value:!0}),await t.done}catch(e){try{t.abort()}catch{}try{await t.done}catch{}throw e}}(i)}catch(e){throw i.close(),e}if(n===z){V=i;try{await X(()=>ae(n,t))}catch(e){if(i.close(),n!==z)return;throw V===i&&(V=null),e}}else i.close()}else i.close()},async close(){const e=G;z+=1,$=null,null!==V&&(V.close(),V=null),await e},clearRebuildableCaches:async()=>Q(async()=>{const e=z,t=$;await X(async()=>{Z(e,t);const a=J().transaction(["userProfiles","groupMembers","groupProfiles","channelProfiles","channelMembers","channelMemberSnapshots","channelMentionCandidateSnapshots","mediaAssets","mediaAssetMeta","meta","recentHistoryPages"],"readwrite");await D(a,async()=>{await Promise.all([L(a.objectStore("userProfiles").clear()),L(a.objectStore("groupMembers").clear()),L(a.objectStore("groupProfiles").clear()),L(a.objectStore("channelProfiles").clear()),L(a.objectStore("channelMembers").clear()),L(a.objectStore("channelMemberSnapshots").clear()),L(a.objectStore("channelMentionCandidateSnapshots").clear()),L(a.objectStore("mediaAssets").clear()),L(a.objectStore("mediaAssetMeta").clear()),L(a.objectStore("meta").delete(v)),L(a.objectStore("recentHistoryPages").clear())])})})}),async hasMany(e){const a=z,n=$,o=e.map(e=>({...e}));return await X(async()=>{if(Z(a,n),0===o.length)return Object.freeze([]);const e=J().transaction(["mediaAssets","mediaAssetMeta"],"readonly"),s=ee(),r=await D(e,async()=>{const a=/* @__PURE__ */new Map;return await Promise.all(o.map(n=>{if(void 0===t.mediaAssetCache?.strategies.resolve(n.kind))return!1;const o=O(n);let r=a.get(o);return void 0===r&&(r=L(Promise.all([L(e.objectStore("mediaAssets").getKey(o)),L(e.objectStore("mediaAssetMeta").get(o))]).then(([e,t])=>void 0!==e&&void 0!==t&&t.kind===n.kind&&t.messageId===n.messageId&&t.resourceVersion===n.resourceVersion&&Number.isSafeInteger(t.byteLength)&&t.byteLength>0&&!te(t,s))),a.set(o,r)),r}))});return Z(a,n),Object.freeze(r)})},async get(e){const a=z,n=$;return await X(async()=>{if(Z(a,n),void 0===t.mediaAssetCache?.strategies.resolve(e.kind))return null;const o=O(e),s=J(),[r,i]=await Promise.all([H(s,"mediaAssets",o),H(s,"mediaAssetMeta",o)]);Z(a,n);const c=ee();return void 0===r||void 0===i||te(i,c)?(await oe([o],a,n),null):(await s.put("mediaAssetMeta",{...i,lastAccessedAt:c}),Z(a,n),{kind:i.kind,messageId:i.messageId,resourceVersion:i.resourceVersion,blob:r.blob,...void 0===i.mimeType?{}:{mimeType:i.mimeType}})})},async put(e){const a=z,n=$;Z(a,n);const o=e.blob.size;if(o>q||U+o>q)return"skipped";U+=o;try{return await X(()=>async function(e,a,n){Z(a,n);const o=t.mediaAssetCache?.strategies.resolve(e.kind);if(void 0===o)return"skipped";const s=e.blob,r=s.size,i=await ae(a,n),c=await ne(i);if(Z(a,n),0===r||r>o.maxEntryBytes||c<=0||r>Math.floor(c/2))return"skipped";const d=O(e),l=ee(),y=i.find(e=>e.key===d),u={key:d,kind:e.kind,messageId:e.messageId,resourceVersion:e.resourceVersion,byteLength:r,...void 0===e.mimeType?{}:{mimeType:e.mimeType},createdAt:y?.createdAt??l,lastAccessedAt:l},v=async()=>{Z(a,n);const e=J().transaction(["mediaAssets","mediaAssetMeta"],"readwrite");await D(e,async()=>{await Promise.all([L(e.objectStore("mediaAssets").put({key:d,blob:s})),L(e.objectStore("mediaAssetMeta").put(u))])})};let m=!1;try{await v()}catch(e){if(!(e instanceof DOMException)||"QuotaExceededError"!==e.name)throw e;m=!0,await se(a,n,Math.max(0,c-r)),await v()}const w=void 0===y?[...i,u]:i.map(e=>e.key===d?u:e);return await se(a,n,void 0,m?void 0:w),Z(a,n),void 0===await H(J(),"mediaAssets",d)?"skipped":"stored"}(e,a,n))}finally{U=Math.max(0,U-o)}},async clear(){const e=z,t=$;await X(async()=>{Z(e,t);const a=J().transaction(["mediaAssets","mediaAssetMeta"],"readwrite");await D(a,async()=>{await Promise.all([L(a.objectStore("mediaAssets").clear()),L(a.objectStore("mediaAssetMeta").clear())])})})},async prune(){const e=z,t=$;await X(()=>ae(e,t))},async getMessage(e,t){const n=await H(J(),"messages",A(e,t));if(void 0===n)return null;const s=I(n);return a(o(s))===a(e)?s:null},async getMessages(e,t){const n="string"==typeof e?"by_conv_sort":"by_conversation_key_sort",o="string"==typeof e?e:a(e);if(await async function(e){if("string"!=typeof e)return;const t=IDBKeyRange.bound([e,""],[e,h]),a=J().transaction("messages");T(e,(await D(a,async()=>await a.store.index("by_conv_sort").getAll(t))).map(I))}(e),void 0===t.beforeSortKey&&void 0!==t.afterSortKey){const e=IDBKeyRange.bound([o,t.afterSortKey],[o,h]),a=[],s=J().transaction("messages");return await D(s,async()=>{let o=await s.store.index(n).openCursor(e,"next");for(;null!==o&&a.length<t.limit;)a.push(o.value),o=await o.continue()}),a.map(I)}const s=void 0===t.beforeSortKey?IDBKeyRange.bound([o,""],[o,h]):IDBKeyRange.bound([o,""],[o,t.beforeSortKey],!1,!0),r=[],i=J().transaction("messages");return await D(i,async()=>{let e=await i.store.index(n).openCursor(s,"prev");for(;null!==e&&r.length<t.limit;)r.push(e.value),e=await e.continue()}),r.reverse().map(I)},async saveMessages(e){if(0===e.length)return;const t=J().transaction("messages","readwrite");await D(t,async()=>{await Promise.all(e.map(e=>L(t.store.put(C(e)))))})},async searchMessages(e,t){const n=a(e),o=t.keyword?.trim()??"",s=t.contentTypes;if(""===o&&(void 0===s||0===s.length))return{items:[],exhausted:!0};const d=""===o?void 0:await r(o),l=void 0===t.beforeSortKey?IDBKeyRange.bound([n,""],[n,h]):IDBKeyRange.bound([n,""],[n,t.beforeSortKey],!1,!0),y=[];let u,v=0;const m=J().transaction("messages"),w=await D(m,async()=>{let e=await m.store.index("by_conversation_key_sort").openCursor(l,"prev");for(;null!==e&&y.length<t.limit&&v<2e3;){const t=c(I(e.value));v+=1,u=t.sortKey;const a=void 0===s||s.includes(t.contentType),n=void 0===d||null!==d.match(i(t));a&&n&&y.push(t),e=await e.continue()}return null===e});return{items:y,exhausted:w,...w?{}:{nextBeforeSortKey:u}}},async getDecryptRecoveries(e){const t=a(e),n=J().transaction("decryptRecoveries");return(await D(n,async()=>await n.store.index("by_conversation").getAll(t))).map(M)},async saveDecryptRecovery(e){if(0===e.sContent.byteLength||e.sContent.byteLength>65536)throw new Error(`解密恢复密文字节长度非法:${e.sContent.byteLength}`);await J().put("decryptRecoveries",function(e){const t=a(e.conversation);return{...e,key:k(e.conversation,e.messageId),conversationKey:t,conversation:{...e.conversation},sContent:e.sContent.slice()}}(e))},async deleteDecryptRecovery(e,t){await J().delete("decryptRecoveries",k(e,t))},async deleteConversationDecryptRecoveries(e){const t=a(e),n=J().transaction("decryptRecoveries","readwrite");await D(n,async()=>{let e=await n.store.index("by_conversation").openCursor(IDBKeyRange.only(t));for(;null!==e;)await e.delete(),e=await e.continue()})},getSessions:async()=>(await E(J(),"sessions")).map(K),async saveSessions(e){if(0===e.length)return;const t=J().transaction("sessions","readwrite");await D(t,async()=>{for(const a of e)await t.store.put(P(a)),await t.store.delete(a.id)})},async deleteSession(e){if("string"!=typeof e){const t=J().transaction(["sessions","conversationBackgrounds"],"readwrite");return void await D(t,async()=>{await t.objectStore("sessions").delete(a(e)),await t.objectStore("conversationBackgrounds").delete(j(e))})}const t=(await E(J(),"sessions")).map(K).filter(t=>t.id===e);T(e,t.map(e=>({conversationType:e.type})));const n=J().transaction(["sessions","conversationBackgrounds"],"readwrite");await D(n,async()=>{if(void 0!==t[0]){const e=s(t[0]);await n.objectStore("sessions").delete(a(e)),await n.objectStore("conversationBackgrounds").delete(j(e))}await n.objectStore("sessions").delete(e)})},async deleteReadState(e){if("string"!=typeof e)return void await J().delete("readStates",a(e));const t=(await E(J(),"readStates")).map(_).filter(t=>t.conversationId===e).filter(e=>void 0!==e.conversationType);T(e,t),void 0!==t[0]&&await J().delete("readStates",a(t[0])),await J().delete("readStates",e)},deleteMessage:async(e,t,n)=>Q(async()=>{if(void 0!==n&&(n.id!==e.conversationId||n.type!==e.conversationType))throw new Error("删除后的会话摘要必须匹配目标会话");const o=J().transaction(["messages","sessions","decryptRecoveries","recentHistoryPages"],"readwrite");return D(o,async()=>{const s=o.objectStore("messages"),r=A(e,t),i=await s.get(r);if(void 0!==i){const t=I(i);if(t.conversationType!==e.conversationType||t.conversationId!==e.conversationId)return!1;await s.delete(r)}return await o.objectStore("decryptRecoveries").delete(k(e,t)),await o.objectStore("recentHistoryPages").delete(a(e)),void 0!==n&&await o.objectStore("sessions").put(P(n)),void 0!==i})}),deleteConversationMessages:async e=>Q(async()=>{const t="string"==typeof(n=e)?n:n.conversationId;var n;const o="string"==typeof e?"by_conv_sort":"by_conversation_key_sort",s="string"==typeof e?e:a(e),r=IDBKeyRange.bound([s,""],[s,h]),i=J().transaction(["messages","decryptRecoveries","recentHistoryPages","meta"],"readwrite");return D(i,async()=>{const n=i.objectStore("messages"),s=i.objectStore("decryptRecoveries");let c=[],d=[];if("string"==typeof e){const a=(await n.index("by_conv_sort").getAll(r)).map(I);c=(await s.getAll()).filter(t=>t.conversation.conversationId===e),d=(await i.objectStore("recentHistoryPages").getAll()).filter(e=>e.conversation.conversationId===t);const o=await i.objectStore("meta").get(y({conversationType:"channel",conversationId:t}));T(t,[...void 0===o?[]:[{conversationType:"channel"}],...a,...d.map(e=>({conversationType:e.conversation.conversationType})),...c.map(e=>({conversationType:e.conversation.conversationType}))])}await i.objectStore("meta").delete(y("string"==typeof e?{conversationType:"channel",conversationId:t}:e));let l=await n.index(o).openCursor(r);for(;null!==l;)await l.delete(),l=await l.continue();if("string"==typeof e){for(const e of c)await s.delete(e.key);for(const e of d)await i.objectStore("recentHistoryPages").delete(e.conversationKey)}else{await i.objectStore("recentHistoryPages").delete(a(e));let t=await s.index("by_conversation").openCursor(IDBKeyRange.only(a(e)));for(;null!==t;)await t.delete(),t=await t.continue()}})}),clearConversationHistory:async(e,t,n)=>Q(async()=>{const o=a(e),s=IDBKeyRange.bound([o,""],[o,h]),r=J().transaction(["messages","sessions","readStates","decryptRecoveries","recentHistoryPages","meta"],"readwrite");return D(r,async()=>{await r.objectStore("meta").delete(y(e)),await r.objectStore("recentHistoryPages").delete(o);let a=await r.objectStore("messages").index("by_conversation_key_sort").openCursor(s);for(;null!==a;)await a.delete(),a=await a.continue();let i=await r.objectStore("decryptRecoveries").index("by_conversation").openCursor(IDBKeyRange.only(o));for(;null!==i;)await i.delete(),i=await i.continue();void 0!==t&&await r.objectStore("sessions").put(P(t)),void 0!==n&&(await r.objectStore("readStates").put(x(n)),await r.objectStore("readStates").delete(n.conversationId))})}),getReadStates:async()=>(await E(J(),"readStates")).map(_),async saveReadState(e){const t=J().transaction("readStates","readwrite");await D(t,async()=>{await t.store.put(x(e)),void 0!==e.conversationType&&await t.store.delete(e.conversationId)})},getDrafts:async()=>(await E(J(),"drafts")).map(N),async saveDraft(e){await J().put("drafts",function(e){return{...e,conversationKey:a(e.ref)}}(e))},async deleteDraft(e){await J().delete("drafts",a(e))},getConversationBackground:async e=>(await H(J(),"conversationBackgrounds",j(e)))?.background??null,async saveConversationBackground(e,t){const a=j(e);await J().put("conversationBackgrounds",{key:a,background:t})},async deleteConversationBackground(e){await J().delete("conversationBackgrounds",j(e))},getDefaultConversationBackground:async()=>(await H(J(),"conversationBackgrounds",p))?.background??null,async saveDefaultConversationBackground(e){await J().put("conversationBackgrounds",{key:p,background:e})},async deleteDefaultConversationBackground(){await J().delete("conversationBackgrounds",p)},getOutbox:async()=>E(J(),"outbox"),async saveOutboxMessage(e){await J().put("outbox",e)},async removeOutboxMessage(e){await J().delete("outbox",e)},getPinnedMessages:async()=>(await E(J(),"pinnedMessages")).map(R),async savePinnedMessage(e){const t=J().transaction("pinnedMessages","readwrite");await D(t,async()=>{await t.store.put(B(e)),await t.store.delete(e.conversationId)})},async removePinnedMessage(e){if("string"!=typeof e)return void await J().delete("pinnedMessages",a(e));const t=(await E(J(),"pinnedMessages")).map(R).filter(t=>t.conversationId===e);T(e,t),void 0!==t[0]&&await J().delete("pinnedMessages",a(n(t[0]))),await J().delete("pinnedMessages",e)},async getMeta(e){const t=await H(J(),"meta",e);return void 0===t?null:t.value},async setMeta(e,t){await J().put("meta",{key:e,value:t})},getUserProfile:async e=>await H(J(),"userProfiles",e)??null,async saveUserProfile(e){await J().put("userProfiles",e)},getGroupMembers:async e=>await H(J(),"groupMembers",e)??null,async saveGroupMembers(e){await J().put("groupMembers",e)},getGroupProfile:async e=>await H(J(),"groupProfiles",e)??null,async saveGroupProfile(e){await J().put("groupProfiles",e)},getChannelProfile:async e=>await H(J(),"channelProfiles",e)??null,getChannelProfiles:async()=>E(J(),"channelProfiles"),async saveChannelProfiles(e){if(0===e.length)return;const t=J().transaction("channelProfiles","readwrite");await D(t,async()=>{await Promise.all(e.map(e=>L(t.store.put(e))))})},async getChannelListVersion(){const e=await H(J(),"meta",v);return"string"==typeof e?.value&&/^\d+$/.test(e.value)?e.value:"0"},async saveChannelListVersion(e){if(!/^\d+$/.test(e))throw new Error(`CHANNEL list version 非法:${e}`);await J().put("meta",{key:v,value:e})},async getChannelMembers(e,t){if(0===t.length)return[];const a=J().transaction("channelMembers");return(await D(a,async()=>await Promise.all(t.map(t=>L(a.store.get([e,t])))))).filter(e=>void 0!==e)},async saveChannelMembers(e){if(0===e.length)return;const t=J().transaction("channelMembers","readwrite");await D(t,async()=>{for(const a of e){const e=await t.store.get([a.channelId,a.userId]);void 0!==e&&S(a.updateVersion,e.updateVersion)<0||await t.store.put(a)}})},async deleteChannelMembers(e){const t=IDBKeyRange.bound([e,""],[e,h]),a=J().transaction("channelMembers","readwrite");await D(a,async()=>{let e=await a.store.openCursor(t);for(;null!==e;)await e.delete(),e=await e.continue()})},getChannelMemberSnapshot:async e=>await H(J(),"channelMemberSnapshots",e)??null,async saveChannelMemberSnapshot(e){await J().put("channelMemberSnapshots",e)},async deleteChannelMemberSnapshot(e){await J().delete("channelMemberSnapshots",e)},getChannelMentionCandidateSnapshot:async e=>await H(J(),"channelMentionCandidateSnapshots",e)??null,async saveChannelMentionCandidateSnapshot(e){await J().put("channelMentionCandidateSnapshots",e)},async deleteChannelMentionCandidateSnapshot(e){await J().delete("channelMentionCandidateSnapshots",e)}}}export{$ as createIndexedDbStorageAdapter,V as deleteIndexedDbNamespace};
|
|
1
|
+
import{openDB as e,deleteDB as t}from"idb";import{encodeConversationKey as a,conversationRefFromPinnedMessage as n,conversationRefFromMessage as o,conversationRefFromSession as s}from"../../../im-core/src/conversation-identity.js";import{createImTextSearchMatcher as r,extractSearchText as i}from"../../../im-core/src/mapping/search-text.js";import{normalizeStoredMessageContent as c}from"../../../im-core/src/mapping/stored-message.js";import{computeMessageSortKey as d}from"../../../im-core/src/mapping/sort.js";import{isStaleMiniProgramShowTypeProjection as l}from"../../../im-core/src/mapping/mini-program-body.js";import{channelSyncCheckpointKey as y}from"../../../im-core/src/sync/channel-sync-checkpoint.js";const u=1073741824;const v="channel:list-version",m="schema:conversation-key-v1",w="schema:message-server-order-v1",g="schema:mini-program-game-preview-v1",f="im:membership-reset-sort-keys",p="default",h="";function b(e){if(void 0!==e&&/^\d+$/.test(e))return e.replace(/^0+(?=\d)/,"")}function S(e,t){const a=b(e),n=b(t);return void 0===a?void 0===n?0:-1:void 0===n?1:a.length!==n.length?a.length>n.length?1:-1:a===n?0:a>n?1:-1}function k(e){return`conversation:${a(e)}`}function j(e,t){return`${a(e)}\0${t}`}function M(e){const{key:t,conversationKey:a,...n}=e;return{...n,conversation:{...n.conversation},sContent:n.sContent.slice()}}function C(e,t){return JSON.stringify([a(e),t])}function A(e){const t=o(e);return{...e,messageKey:C(t,e.id),conversationKey:a(t)}}function I(e){const{messageKey:t,conversationKey:a,...n}=e;return n}function P(e){return{...e,id:a(s(e)),conversationId:e.id}}function K(e){if(void 0===e.conversationId)return e;const{conversationId:t,...a}=e;return{...a,id:t}}function x(e){return void 0===e.conversationType?e:{...e,conversationId:a(e),storageConversationId:e.conversationId}}function _(e){if(void 0===e.storageConversationId)return e;const{storageConversationId:t,...a}=e;return{...a,conversationId:t}}function B(e){return{...e,conversationId:a(n(e)),storageConversationId:e.conversationId}}function R(e){if(void 0===e.storageConversationId)return e;const{storageConversationId:t,...a}=e;return{...a,conversationId:t}}function N(e){const{conversationKey:t,...a}=e;return a}function T(e,t){if(new Set(t.map(e=>e.conversationType)).size>1)throw new Error(`裸 conversationId 存在多类型歧义:${e}`)}function O(e){return`${e.kind}:${encodeURIComponent(e.messageId)}:${e.resourceVersion}`}async function D(e,t){const a=e.done;a.catch(()=>{});try{const e=await t();return await a,e}catch(t){try{e.abort()}catch{}throw await a.catch(()=>{}),t}}function L(e){return e.catch(()=>{}),e}async function H(e,t,a){const n=e.transaction(t);return await D(n,async()=>await n.store.get(a))}async function E(e,t){const a=e.transaction(t);return await D(a,async()=>await a.store.getAll())}async function V(e,a){const n=a.namespaceFactory.forAccount(e).name("durable","storage","indexed-db");"undefined"!=typeof indexedDB&&await t(n)}function $(t){const{namespaceFactory:b}=t;let V=null,$=null,z=0,F=Promise.resolve(),G=Promise.resolve(),U=0;const q=t.mediaAssetCache?.maxPendingWriteBytes??268435456;if(!Number.isSafeInteger(q)||q<=0)throw new RangeError("媒体资产缓存待写内存预算必须是正整数");function J(){if(null===V)throw new Error("ImStoragePort 未 open:请先 open({ namespace }) 再读写");return V}function Q(e){const t=z,a=$,n=()=>{if(t!==z||a!==$)throw new Error("最近历史缓存操作已失效:账号或存储已改变");J()},o=F.then(async()=>{n();const t=await e();return n(),t});return F=o.then(()=>{},()=>{}),o}function W(e,t){return 2!==e.version||!Number.isFinite(e.fetchedAt)||e.fetchedAt<0||t-e.fetchedAt>=864e5}async function Y(e){if(!Number.isSafeInteger(e.byteLength)||e.byteLength<0)throw new Error("最近历史缓存 byteLength 必须是非负安全整数");const t=Date.now();if(e.byteLength>2097152||W(e,t))return!1;const n=a(e.conversation),o=J().transaction("recentHistoryPages","readwrite");return D(o,async()=>{const a=await o.store.getAll(),s=[];for(const e of a)W(e,t)?await o.store.delete(e.conversationKey):e.conversationKey!==n&&s.push(e);const r={...e,conversationKey:n};s.push(r),s.sort((e,t)=>e.fetchedAt-t.fetchedAt||e.conversationKey.localeCompare(t.conversationKey));let i=s.reduce((e,t)=>e+t.byteLength,0);const c=[];for(;s.length>20||i>8388608;){const e=s.shift();c.push(e),i-=e.byteLength}if(c.includes(r))return!1;await o.store.put(r);for(const e of c)await o.store.delete(e.conversationKey);return!0})}function X(e){const t=G.then(e,e);return G=t.then(()=>{},()=>{}),t}function Z(e,t){if(e!==z||null===t||t!==$)throw new Error("媒体资产缓存账号代际已失效")}function ee(){return Math.max(0,Math.floor(t.mediaAssetCache?.now?.()??Date.now()))}function te(e,a){const n=t.mediaAssetCache?.strategies.resolve(e.kind)?.maxIdleMs;return void 0!==n&&(!Number.isSafeInteger(e.lastAccessedAt)||e.lastAccessedAt<0||a-e.lastAccessedAt>=n)}async function ae(e,t){Z(e,t);const a=await E(J(),"mediaAssetMeta");Z(e,t);const n=ee(),o=a.filter(e=>te(e,n));await oe(o.map(e=>e.key),e,t),Z(e,t);const s=new Set(o.map(e=>e.key));return a.filter(e=>!s.has(e.key))}async function ne(e){const a=t.mediaAssetCache?.estimateStorage??(async()=>"undefined"==typeof navigator||void 0===navigator.storage?.estimate?{}:await navigator.storage.estimate());try{const{quota:t,usage:n}=await a();if(void 0===t||!Number.isFinite(t)||t<=0)return u;const o=e.reduce((e,t)=>e+t.byteLength,0),s=Math.max(0,(n??0)-o),r=Math.max(536870912,Math.floor(.2*t));return Math.max(0,Math.min(2147483648,Math.floor(t-s-r)))}catch{return u}}async function oe(e,t,a){if(0===e.length)return;Z(t,a);const n=J().transaction(["mediaAssets","mediaAssetMeta"],"readwrite");await D(n,async()=>{await Promise.all(e.flatMap(e=>[L(n.objectStore("mediaAssets").delete(e)),L(n.objectStore("mediaAssetMeta").delete(e))]))})}async function se(e,a,n,o){Z(e,a);const s=J(),r=t.mediaAssetCache?.strategies;if(void 0===r)return;const i=o??await E(s,"mediaAssetMeta");Z(e,a);const c=/* @__PURE__ */new Set;for(const e of r.list()){const t=i.filter(t=>t.kind===e.kind).sort((e,t)=>e.lastAccessedAt-t.lastAccessedAt);let a=t.reduce((e,t)=>e+t.byteLength,0),n=t.length;for(const o of t){if(a<=e.softMaxBytes&&n<=e.maxEntries)break;c.add(o.key),a-=o.byteLength,n-=1}}const d=i.filter(e=>!c.has(e.key)).sort((e,t)=>e.lastAccessedAt-t.lastAccessedAt),l=Math.max(0,Math.min(await ne(i),n??Number.POSITIVE_INFINITY));let y=d.reduce((e,t)=>e+t.byteLength,0);for(const e of d){if(y<=l)break;c.add(e.key),y-=e.byteLength}await oe([...c],e,a)}return{supportsChannelSyncCheckpoint:!0,recentHistoryCache:{get:e=>Q(async()=>{const t=a(e),n=J().transaction("recentHistoryPages","readwrite");return D(n,async()=>{const e=await n.store.get(t);if(void 0===e)return null;if(W(e,Date.now()))return await n.store.delete(t),null;const{conversationKey:a,...o}=e;return o})}),async put(e){if("function"==typeof structuredClone){const t=structuredClone(e);return Q(()=>Y(t))}const t=function(e){return new Promise((t,a)=>{const n=new MessageChannel,o=()=>{n.port1.close(),n.port2.close()};n.port1.onmessage=e=>{o(),t(e.data)},n.port1.onmessageerror=()=>{o(),a(new DOMException("最近历史缓存快照无法反序列化","DataCloneError"))};try{n.port2.postMessage(e)}catch(e){o(),a(e)}})}(e).then(e=>({ok:!0,value:e}),e=>({ok:!1,error:e}));return Q(async()=>{const e=await t;if(!e.ok)throw e.error;return Y(e.value)})},delete:e=>Q(async()=>{await J().delete("recentHistoryPages",a(e))}),clear:()=>Q(async()=>{await J().clear("recentHistoryPages")})},async open({namespace:t}){if(null!==V&&$===t)return;null!==V&&(V.close(),V=null),$=t;const n=++z,s=b.forAccount(t).name("durable","storage","indexed-db");let r;const i=await e(s,16,{upgrade(e,t,a,n){if(e.objectStoreNames.contains("messages"))n.objectStore("messages").indexNames.contains("by_conversation_key_sort")||n.objectStore("messages").createIndex("by_conversation_key_sort",["conversationKey","sortKey"]);else{const t=e.createObjectStore("messages",{keyPath:"messageKey"});t.createIndex("by_conv_sort",["conversationId","sortKey"]),t.createIndex("by_conversation_key_sort",["conversationKey","sortKey"])}if(e.objectStoreNames.contains("sessions")||e.createObjectStore("sessions",{keyPath:"id"}),e.objectStoreNames.contains("readStates")||e.createObjectStore("readStates",{keyPath:"conversationId"}),e.objectStoreNames.contains("drafts")||e.createObjectStore("drafts",{keyPath:"conversationKey"}),e.objectStoreNames.contains("outbox")||e.createObjectStore("outbox",{keyPath:"id"}),e.objectStoreNames.contains("meta")||e.createObjectStore("meta",{keyPath:"key"}),e.objectStoreNames.contains("userProfiles")||e.createObjectStore("userProfiles",{keyPath:"id"}),e.objectStoreNames.contains("groupMembers")||e.createObjectStore("groupMembers",{keyPath:"groupId"}),e.objectStoreNames.contains("groupProfiles")||e.createObjectStore("groupProfiles",{keyPath:"id"}),e.objectStoreNames.contains("pinnedMessages")||e.createObjectStore("pinnedMessages",{keyPath:"conversationId"}),e.objectStoreNames.contains("channelProfiles")||e.createObjectStore("channelProfiles",{keyPath:"id"}),e.objectStoreNames.contains("channelMembers")||e.createObjectStore("channelMembers",{keyPath:["channelId","userId"]}),e.objectStoreNames.contains("channelMemberSnapshots")||e.createObjectStore("channelMemberSnapshots",{keyPath:"channelId"}),e.objectStoreNames.contains("channelMentionCandidateSnapshots")||e.createObjectStore("channelMentionCandidateSnapshots",{keyPath:"channelId"}),e.objectStoreNames.contains("conversationBackgrounds")||e.createObjectStore("conversationBackgrounds",{keyPath:"key"}),e.objectStoreNames.contains("mediaAssets")||e.createObjectStore("mediaAssets",{keyPath:"key"}),!e.objectStoreNames.contains("mediaAssetMeta")){const t=e.createObjectStore("mediaAssetMeta",{keyPath:"key"});t.createIndex("by_kind_access",["kind","lastAccessedAt"]),t.createIndex("by_access","lastAccessedAt")}if(!e.objectStoreNames.contains("decryptRecoveries")){e.createObjectStore("decryptRecoveries",{keyPath:"key"}).createIndex("by_conversation","conversationKey")}if(t>0&&t<13&&(n.objectStore("mediaAssets").clear(),n.objectStore("mediaAssetMeta").clear()),e.objectStoreNames.contains("recentHistoryPages")||e.createObjectStore("recentHistoryPages",{keyPath:"conversationKey"}),t>0&&t<16&&"messageKey"!==n.objectStore("messages").keyPath){(async()=>{const t=await n.objectStore("messages").getAll();for(const e of t)e.messageKey=C(o(e),e.id);e.deleteObjectStore("messages");const a=e.createObjectStore("messages",{keyPath:"messageKey"});a.createIndex("by_conv_sort",["conversationId","sortKey"]),a.createIndex("by_conversation_key_sort",["conversationKey","sortKey"]);for(let e=0;e<t.length;e+=128){const n=t.slice(e,e+128);await Promise.all(n.map(async e=>a.put(e)))}})().catch(e=>{r=e,n.done.catch(()=>{});try{n.abort()}catch{}})}}}).catch(e=>{throw r??e});if(n===z){try{await async function(e){const t=e.transaction(["messages","sessions","readStates","pinnedMessages","meta"],"readwrite");try{const e=t.objectStore("meta");if(!0===(await e.get(m))?.value)return void await t.done;const a=t.objectStore("messages");for(const e of await a.getAll())void 0===e.conversationKey&&await a.put(A(e));const n=t.objectStore("sessions"),o=/* @__PURE__ */new Map;for(const e of await n.getAll()){if(void 0!==e.conversationId)continue;const t=K(e);o.set(t.id,t.type),await n.put(P(t)),await n.delete(e.id)}const s=t.objectStore("readStates");for(const e of await s.getAll()){if(void 0!==e.storageConversationId)continue;const t=e.conversationType??o.get(e.conversationId);if(void 0===t)continue;const a={...e,conversationType:t};await s.put(x(a)),await s.delete(e.conversationId)}const r=t.objectStore("pinnedMessages");for(const e of await r.getAll()){if(void 0!==e.storageConversationId)continue;const t=R(e);await r.put(B(t)),await r.delete(e.conversationId)}await e.put({key:m,value:!0}),await t.done}catch(e){try{t.abort()}catch{}try{await t.done}catch{}throw e}}(i),await async function(e){const t=e.transaction(["messages","readStates","meta"],"readwrite");try{const e=t.objectStore("meta");if(!0===(await e.get(w))?.value)return void await t.done;const n=t.objectStore("readStates"),s=await n.getAll(),r=/* @__PURE__ */new Map;for(const e of s){const t=_(e);"channel"===t.conversationType&&void 0!==t.readCursorSortKey&&""!==t.readCursor&&r.set(a(t),{cursor:t.readCursor})}const i=/* @__PURE__ */new Map,c=t.objectStore("messages");let l=await c.openCursor();for(;null!==l;){const e=l.value,t=a(o(e)),n=d(e),s=r.get(t);if(void 0!==s&&e.extensions?.historyCursor===s.cursor&&(s.sortKey=n),n!==e.sortKey){let a=i.get(t);void 0===a&&(a=/* @__PURE__ */new Map,i.set(t,a)),a.set(e.sortKey,n),await l.update({...e,sortKey:n})}l=await l.continue()}for(const e of s){const t=_(e);if(void 0===t.conversationType)continue;const s=a(t);let d=r.get(s)?.sortKey??(void 0===t.readCursorSortKey?void 0:i.get(s)?.get(t.readCursorSortKey));if(void 0===d&&void 0!==t.readCursorSortKey&&"channel"!==t.conversationType&&""!==t.readCursor){const e=await c.get(C(t,t.readCursor));void 0!==e&&a(o(e))===s&&(d=e.sortKey)}void 0!==d&&d!==t.readCursorSortKey&&await n.put({...e,readCursorSortKey:d})}const y=await e.get(f);if(Array.isArray(y?.value)){let t=!1;const a=y.value.map(e=>{if(!Array.isArray(e)||2!==e.length||"string"!=typeof e[0]||"string"!=typeof e[1])return e;const a=i.get(e[0])?.get(e[1]);return void 0===a?e:(t=!0,[e[0],a])});t&&await e.put({key:f,value:a})}await e.put({key:w,value:!0}),await t.done}catch(e){try{t.abort()}catch{}try{await t.done}catch{}throw e}}(i),await async function(e){const t=e.transaction(["messages","meta"],"readwrite");try{const e=t.objectStore("meta");if(!0===(await e.get(g))?.value)return void await t.done;const a=t.objectStore("messages");let n=await a.openCursor();for(;null!==n;){const e=n.value.body?.miniProgram;"miniProgram"===n.value.contentType&&void 0!==e&&l(e)&&await n.delete(),n=await n.continue()}await e.put({key:g,value:!0}),await t.done}catch(e){try{t.abort()}catch{}try{await t.done}catch{}throw e}}(i)}catch(e){throw i.close(),e}if(n===z){V=i;try{await X(()=>ae(n,t))}catch(e){if(i.close(),n!==z)return;throw V===i&&(V=null),e}}else i.close()}else i.close()},async close(){const e=G;z+=1,$=null,null!==V&&(V.close(),V=null),await e},clearRebuildableCaches:async()=>Q(async()=>{const e=z,t=$;await X(async()=>{Z(e,t);const a=J().transaction(["userProfiles","groupMembers","groupProfiles","channelProfiles","channelMembers","channelMemberSnapshots","channelMentionCandidateSnapshots","mediaAssets","mediaAssetMeta","meta","recentHistoryPages"],"readwrite");await D(a,async()=>{await Promise.all([L(a.objectStore("userProfiles").clear()),L(a.objectStore("groupMembers").clear()),L(a.objectStore("groupProfiles").clear()),L(a.objectStore("channelProfiles").clear()),L(a.objectStore("channelMembers").clear()),L(a.objectStore("channelMemberSnapshots").clear()),L(a.objectStore("channelMentionCandidateSnapshots").clear()),L(a.objectStore("mediaAssets").clear()),L(a.objectStore("mediaAssetMeta").clear()),L(a.objectStore("meta").delete(v)),L(a.objectStore("recentHistoryPages").clear())])})})}),async hasMany(e){const a=z,n=$,o=e.map(e=>({...e}));return await X(async()=>{if(Z(a,n),0===o.length)return Object.freeze([]);const e=J().transaction(["mediaAssets","mediaAssetMeta"],"readonly"),s=ee(),r=await D(e,async()=>{const a=/* @__PURE__ */new Map;return await Promise.all(o.map(n=>{if(void 0===t.mediaAssetCache?.strategies.resolve(n.kind))return!1;const o=O(n);let r=a.get(o);return void 0===r&&(r=L(Promise.all([L(e.objectStore("mediaAssets").getKey(o)),L(e.objectStore("mediaAssetMeta").get(o))]).then(([e,t])=>void 0!==e&&void 0!==t&&t.kind===n.kind&&t.messageId===n.messageId&&t.resourceVersion===n.resourceVersion&&Number.isSafeInteger(t.byteLength)&&t.byteLength>0&&!te(t,s))),a.set(o,r)),r}))});return Z(a,n),Object.freeze(r)})},async get(e){const a=z,n=$;return await X(async()=>{if(Z(a,n),void 0===t.mediaAssetCache?.strategies.resolve(e.kind))return null;const o=O(e),s=J(),[r,i]=await Promise.all([H(s,"mediaAssets",o),H(s,"mediaAssetMeta",o)]);Z(a,n);const c=ee();return void 0===r||void 0===i||te(i,c)?(await oe([o],a,n),null):(await s.put("mediaAssetMeta",{...i,lastAccessedAt:c}),Z(a,n),{kind:i.kind,messageId:i.messageId,resourceVersion:i.resourceVersion,blob:r.blob,...void 0===i.mimeType?{}:{mimeType:i.mimeType}})})},async put(e,a){const n=z,o=$;Z(n,o);const s=e.blob.size;if(s>q||U+s>q)return"skipped";U+=s;try{return await X(()=>async function(e,a,n,o=()=>!0){if(Z(a,n),!o())return"skipped";const s=t.mediaAssetCache?.strategies.resolve(e.kind);if(void 0===s)return"skipped";const r=e.blob,i=r.size,c=await ae(a,n),d=await ne(c);if(Z(a,n),0===i||i>s.maxEntryBytes||d<=0||i>Math.floor(d/2))return"skipped";const l=O(e),y=ee(),u=c.find(e=>e.key===l),v={key:l,kind:e.kind,messageId:e.messageId,resourceVersion:e.resourceVersion,byteLength:i,...void 0===e.mimeType?{}:{mimeType:e.mimeType},createdAt:u?.createdAt??y,lastAccessedAt:y},m=async()=>{if(Z(a,n),!o())return!1;const e=J().transaction(["mediaAssets","mediaAssetMeta"],"readwrite");return await D(e,async()=>{await Promise.all([L(e.objectStore("mediaAssets").put({key:l,blob:r})),L(e.objectStore("mediaAssetMeta").put(v))])}),!0};let w=!1;try{if(!await m())return"skipped"}catch(e){if(!o())return"skipped";if(!(e instanceof DOMException)||"QuotaExceededError"!==e.name)throw e;if(w=!0,await se(a,n,Math.max(0,d-i)),!await m())return"skipped"}const g=void 0===u?[...c,v]:c.map(e=>e.key===l?v:e);return await se(a,n,void 0,w?void 0:g),Z(a,n),void 0===await H(J(),"mediaAssets",l)?"skipped":"stored"}(e,n,o,a?.isCurrent))}finally{U=Math.max(0,U-s)}},async clear(){const e=z,t=$;await X(async()=>{Z(e,t);const a=J().transaction(["mediaAssets","mediaAssetMeta"],"readwrite");await D(a,async()=>{await Promise.all([L(a.objectStore("mediaAssets").clear()),L(a.objectStore("mediaAssetMeta").clear())])})})},async prune(){const e=z,t=$;await X(()=>ae(e,t))},async getMessage(e,t){const n=await H(J(),"messages",C(e,t));if(void 0===n)return null;const s=I(n);return a(o(s))===a(e)?s:null},async getMessages(e,t){const n="string"==typeof e?"by_conv_sort":"by_conversation_key_sort",o="string"==typeof e?e:a(e);if(await async function(e){if("string"!=typeof e)return;const t=IDBKeyRange.bound([e,""],[e,h]),a=J().transaction("messages");T(e,(await D(a,async()=>await a.store.index("by_conv_sort").getAll(t))).map(I))}(e),void 0===t.beforeSortKey&&void 0!==t.afterSortKey){const e=IDBKeyRange.bound([o,t.afterSortKey],[o,h]),a=[],s=J().transaction("messages");return await D(s,async()=>{let o=await s.store.index(n).openCursor(e,"next");for(;null!==o&&a.length<t.limit;)a.push(o.value),o=await o.continue()}),a.map(I)}const s=void 0===t.beforeSortKey?IDBKeyRange.bound([o,""],[o,h]):IDBKeyRange.bound([o,""],[o,t.beforeSortKey],!1,!0),r=[],i=J().transaction("messages");return await D(i,async()=>{let e=await i.store.index(n).openCursor(s,"prev");for(;null!==e&&r.length<t.limit;)r.push(e.value),e=await e.continue()}),r.reverse().map(I)},async saveMessages(e){if(0===e.length)return;const t=J().transaction("messages","readwrite");await D(t,async()=>{await Promise.all(e.map(e=>L(t.store.put(A(e)))))})},async searchMessages(e,t){const n=a(e),o=t.keyword?.trim()??"",s=t.contentTypes;if(""===o&&(void 0===s||0===s.length))return{items:[],exhausted:!0};const d=""===o?void 0:await r(o),l=void 0===t.beforeSortKey?IDBKeyRange.bound([n,""],[n,h]):IDBKeyRange.bound([n,""],[n,t.beforeSortKey],!1,!0),y=[];let u,v=0;const m=J().transaction("messages"),w=await D(m,async()=>{let e=await m.store.index("by_conversation_key_sort").openCursor(l,"prev");for(;null!==e&&y.length<t.limit&&v<2e3;){const t=c(I(e.value));v+=1,u=t.sortKey;const a=void 0===s||s.includes(t.contentType),n=void 0===d||null!==d.match(i(t));a&&n&&y.push(t),e=await e.continue()}return null===e});return{items:y,exhausted:w,...w?{}:{nextBeforeSortKey:u}}},async getDecryptRecoveries(e){const t=a(e),n=J().transaction("decryptRecoveries");return(await D(n,async()=>await n.store.index("by_conversation").getAll(t))).map(M)},async saveDecryptRecovery(e){if(0===e.sContent.byteLength||e.sContent.byteLength>65536)throw new Error(`解密恢复密文字节长度非法:${e.sContent.byteLength}`);await J().put("decryptRecoveries",function(e){const t=a(e.conversation);return{...e,key:j(e.conversation,e.messageId),conversationKey:t,conversation:{...e.conversation},sContent:e.sContent.slice()}}(e))},async deleteDecryptRecovery(e,t){await J().delete("decryptRecoveries",j(e,t))},async deleteConversationDecryptRecoveries(e){const t=a(e),n=J().transaction("decryptRecoveries","readwrite");await D(n,async()=>{let e=await n.store.index("by_conversation").openCursor(IDBKeyRange.only(t));for(;null!==e;)await e.delete(),e=await e.continue()})},getSessions:async()=>(await E(J(),"sessions")).map(K),async saveSessions(e){if(0===e.length)return;const t=J().transaction("sessions","readwrite");await D(t,async()=>{for(const a of e)await t.store.put(P(a)),await t.store.delete(a.id)})},async deleteSession(e){if("string"!=typeof e){const t=J().transaction(["sessions","conversationBackgrounds"],"readwrite");return void await D(t,async()=>{await t.objectStore("sessions").delete(a(e)),await t.objectStore("conversationBackgrounds").delete(k(e))})}const t=(await E(J(),"sessions")).map(K).filter(t=>t.id===e);T(e,t.map(e=>({conversationType:e.type})));const n=J().transaction(["sessions","conversationBackgrounds"],"readwrite");await D(n,async()=>{if(void 0!==t[0]){const e=s(t[0]);await n.objectStore("sessions").delete(a(e)),await n.objectStore("conversationBackgrounds").delete(k(e))}await n.objectStore("sessions").delete(e)})},async deleteReadState(e){if("string"!=typeof e)return void await J().delete("readStates",a(e));const t=(await E(J(),"readStates")).map(_).filter(t=>t.conversationId===e).filter(e=>void 0!==e.conversationType);T(e,t),void 0!==t[0]&&await J().delete("readStates",a(t[0])),await J().delete("readStates",e)},deleteMessage:async(e,t,n)=>Q(async()=>{if(void 0!==n&&(n.id!==e.conversationId||n.type!==e.conversationType))throw new Error("删除后的会话摘要必须匹配目标会话");const o=J().transaction(["messages","sessions","decryptRecoveries","recentHistoryPages"],"readwrite");return D(o,async()=>{const s=o.objectStore("messages"),r=C(e,t),i=await s.get(r);if(void 0!==i){const t=I(i);if(t.conversationType!==e.conversationType||t.conversationId!==e.conversationId)return!1;await s.delete(r)}return await o.objectStore("decryptRecoveries").delete(j(e,t)),await o.objectStore("recentHistoryPages").delete(a(e)),void 0!==n&&await o.objectStore("sessions").put(P(n)),void 0!==i})}),deleteConversationMessages:async e=>Q(async()=>{const t="string"==typeof(n=e)?n:n.conversationId;var n;const o="string"==typeof e?"by_conv_sort":"by_conversation_key_sort",s="string"==typeof e?e:a(e),r=IDBKeyRange.bound([s,""],[s,h]),i=J().transaction(["messages","decryptRecoveries","recentHistoryPages","meta"],"readwrite");return D(i,async()=>{const n=i.objectStore("messages"),s=i.objectStore("decryptRecoveries");let c=[],d=[];if("string"==typeof e){const a=(await n.index("by_conv_sort").getAll(r)).map(I);c=(await s.getAll()).filter(t=>t.conversation.conversationId===e),d=(await i.objectStore("recentHistoryPages").getAll()).filter(e=>e.conversation.conversationId===t);const o=await i.objectStore("meta").get(y({conversationType:"channel",conversationId:t}));T(t,[...void 0===o?[]:[{conversationType:"channel"}],...a,...d.map(e=>({conversationType:e.conversation.conversationType})),...c.map(e=>({conversationType:e.conversation.conversationType}))])}await i.objectStore("meta").delete(y("string"==typeof e?{conversationType:"channel",conversationId:t}:e));let l=await n.index(o).openCursor(r);for(;null!==l;)await l.delete(),l=await l.continue();if("string"==typeof e){for(const e of c)await s.delete(e.key);for(const e of d)await i.objectStore("recentHistoryPages").delete(e.conversationKey)}else{await i.objectStore("recentHistoryPages").delete(a(e));let t=await s.index("by_conversation").openCursor(IDBKeyRange.only(a(e)));for(;null!==t;)await t.delete(),t=await t.continue()}})}),clearConversationHistory:async(e,t,n)=>Q(async()=>{const o=a(e),s=IDBKeyRange.bound([o,""],[o,h]),r=J().transaction(["messages","sessions","readStates","decryptRecoveries","recentHistoryPages","meta"],"readwrite");return D(r,async()=>{await r.objectStore("meta").delete(y(e)),await r.objectStore("recentHistoryPages").delete(o);let a=await r.objectStore("messages").index("by_conversation_key_sort").openCursor(s);for(;null!==a;)await a.delete(),a=await a.continue();let i=await r.objectStore("decryptRecoveries").index("by_conversation").openCursor(IDBKeyRange.only(o));for(;null!==i;)await i.delete(),i=await i.continue();void 0!==t&&await r.objectStore("sessions").put(P(t)),void 0!==n&&(await r.objectStore("readStates").put(x(n)),await r.objectStore("readStates").delete(n.conversationId))})}),getReadStates:async()=>(await E(J(),"readStates")).map(_),async saveReadState(e){const t=J().transaction("readStates","readwrite");await D(t,async()=>{await t.store.put(x(e)),void 0!==e.conversationType&&await t.store.delete(e.conversationId)})},getDrafts:async()=>(await E(J(),"drafts")).map(N),async saveDraft(e){await J().put("drafts",function(e){return{...e,conversationKey:a(e.ref)}}(e))},async deleteDraft(e){await J().delete("drafts",a(e))},getConversationBackground:async e=>(await H(J(),"conversationBackgrounds",k(e)))?.background??null,async saveConversationBackground(e,t){const a=k(e);await J().put("conversationBackgrounds",{key:a,background:t})},async deleteConversationBackground(e){await J().delete("conversationBackgrounds",k(e))},getDefaultConversationBackground:async()=>(await H(J(),"conversationBackgrounds",p))?.background??null,async saveDefaultConversationBackground(e){await J().put("conversationBackgrounds",{key:p,background:e})},async deleteDefaultConversationBackground(){await J().delete("conversationBackgrounds",p)},getOutbox:async()=>E(J(),"outbox"),async saveOutboxMessage(e){await J().put("outbox",e)},async removeOutboxMessage(e){await J().delete("outbox",e)},getPinnedMessages:async()=>(await E(J(),"pinnedMessages")).map(R),async savePinnedMessage(e){const t=J().transaction("pinnedMessages","readwrite");await D(t,async()=>{await t.store.put(B(e)),await t.store.delete(e.conversationId)})},async removePinnedMessage(e){if("string"!=typeof e)return void await J().delete("pinnedMessages",a(e));const t=(await E(J(),"pinnedMessages")).map(R).filter(t=>t.conversationId===e);T(e,t),void 0!==t[0]&&await J().delete("pinnedMessages",a(n(t[0]))),await J().delete("pinnedMessages",e)},async getMeta(e){const t=await H(J(),"meta",e);return void 0===t?null:t.value},async setMeta(e,t){await J().put("meta",{key:e,value:t})},getUserProfile:async e=>await H(J(),"userProfiles",e)??null,async saveUserProfile(e){await J().put("userProfiles",e)},getGroupMembers:async e=>await H(J(),"groupMembers",e)??null,async saveGroupMembers(e){await J().put("groupMembers",e)},getGroupProfile:async e=>await H(J(),"groupProfiles",e)??null,async saveGroupProfile(e){await J().put("groupProfiles",e)},getChannelProfile:async e=>await H(J(),"channelProfiles",e)??null,getChannelProfiles:async()=>E(J(),"channelProfiles"),async saveChannelProfiles(e){if(0===e.length)return;const t=J().transaction("channelProfiles","readwrite");await D(t,async()=>{await Promise.all(e.map(e=>L(t.store.put(e))))})},async getChannelListVersion(){const e=await H(J(),"meta",v);return"string"==typeof e?.value&&/^\d+$/.test(e.value)?e.value:"0"},async saveChannelListVersion(e){if(!/^\d+$/.test(e))throw new Error(`CHANNEL list version 非法:${e}`);await J().put("meta",{key:v,value:e})},async getChannelMembers(e,t){if(0===t.length)return[];const a=J().transaction("channelMembers");return(await D(a,async()=>await Promise.all(t.map(t=>L(a.store.get([e,t])))))).filter(e=>void 0!==e)},async saveChannelMembers(e){if(0===e.length)return;const t=J().transaction("channelMembers","readwrite");await D(t,async()=>{for(const a of e){const e=await t.store.get([a.channelId,a.userId]);void 0!==e&&S(a.updateVersion,e.updateVersion)<0||await t.store.put(a)}})},async deleteChannelMembers(e){const t=IDBKeyRange.bound([e,""],[e,h]),a=J().transaction("channelMembers","readwrite");await D(a,async()=>{let e=await a.store.openCursor(t);for(;null!==e;)await e.delete(),e=await e.continue()})},getChannelMemberSnapshot:async e=>await H(J(),"channelMemberSnapshots",e)??null,async saveChannelMemberSnapshot(e){await J().put("channelMemberSnapshots",e)},async deleteChannelMemberSnapshot(e){await J().delete("channelMemberSnapshots",e)},getChannelMentionCandidateSnapshot:async e=>await H(J(),"channelMentionCandidateSnapshots",e)??null,async saveChannelMentionCandidateSnapshot(e){await J().put("channelMentionCandidateSnapshots",e)},async deleteChannelMentionCandidateSnapshot(e){await J().delete("channelMentionCandidateSnapshots",e)}}}export{$ as createIndexedDbStorageAdapter,V as deleteIndexedDbNamespace};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createMediaObjectUrlRegistry as e}from"./media-object-url-registry.js";import{validateCachePrefix as
|
|
1
|
+
import{createMediaObjectUrlRegistry as e}from"./media-object-url-registry.js";import{validateCachePrefix as r,createImCacheNamespaceFactory as o}from"../../../im-core/src/cache-namespace.js";import{createAdvancedImClient as t,createProductClientFacade as n}from"../../../im-sdk/src/create-im-client.js";import{createIndexedDbStorageAdapter as i,deleteIndexedDbNamespace as s}from"../../../im-browser/src/storage/indexed-db-storage-adapter.js";import{createDefaultMediaAssetCacheStrategyRegistry as c}from"../../../im-sdk/src/product/media.js";import{createSdkDiagnosticWriter as a}from"../../../im-sdk/src/product/diagnostics.js";function d(){if("undefined"==typeof navigator)return{maxCachedEntries:6,maxCachedBytes:536870912};const e=navigator,r=e.deviceMemory??4,o=/Android|iPhone|iPad|Mobile/i.test(e.userAgent);return!0===e.connection?.saveData||r<=2||navigator.hardwareConcurrency<=2?{maxCachedEntries:2,maxCachedBytes:134217728}:o?{maxCachedEntries:4,maxCachedBytes:268435456}:r>=8&&navigator.hardwareConcurrency>=8?{maxCachedEntries:9,maxCachedBytes:1073741824}:{maxCachedEntries:6,maxCachedBytes:536870912}}function l(e){const r=`message\0${e.conversationType}\0${e.conversationId}\0${e.messageId}`;return void 0===e.itemIndex?r:`${r}\0${e.itemIndex}`}function u(e){return`source\0${e}`}function m(e){if("object"==typeof e&&null!==e&&"code"in e)return"IM_CONNECTION_OWNED_ELSEWHERE"===e.code?"lifecycle.connectionOccupied":"IM_CONNECTION_OWNERSHIP_UNAVAILABLE"===e.code?"lifecycle.connectionCoordinationUnavailable":void 0}function p(p){const f=r(p.cachePrefix),g=o(f),h=p.createClient??t,v=p.createStorage??(e=>"undefined"==typeof indexedDB?void 0:i({...e,mediaAssetCache:{strategies:c()}})),y=p.createProfile,C=p.deleteStorage??(e=>s(e.accountId,{namespaceFactory:e.namespaceFactory}));let k,w,I,b,M,E,P=null,x=null,T=!1,B=0,S=!1,R=!1;const U={wsUrl:"",userId:"",token:"",deviceToken:"",channelType:"0",cmHttpBaseUrl:""},A=a(p.debug,()=>({generation:B,...""===U.userId?{}:{accountId:U.userId}}));function D(){return{generation:B,...""===U.userId?{}:{accountId:U.userId}}}A.record("debug","chat-kit","session","runtime-created");let L={},N={},j={};const O=/* @__PURE__ */new Map;let $=/* @__PURE__ */new WeakMap;const F=e({...d(),maxIdleMs:6048e5}),H=/* @__PURE__ */new Set,K=/* @__PURE__ */new Set,_=/* @__PURE__ */new Set;function V(){for(const e of _)e()}function W(e=!1){const r=D(),o=P,t=void 0!==w||void 0!==I;w?.(),w=void 0,I?.(),I=void 0,t&&A.record("debug","chat-kit","session","client-subscriptions-released",()=>r),e||o?.connection.disconnect("im-chat-auth-changed"),P=null,x=null;const n=k;let i;k=void 0;try{i=null!==o&&b?.uploadRecovery?.enabled&&!e?o.logout({localData:"preserve"}).finally(()=>o.dispose()):Promise.resolve(null!==o?o.dispose():n?.close())}catch(e){i=Promise.reject(e)}const s=i.catch(e=>{R=!0,E=e,A.record("error","chat-kit","session","previous-client-dispose-failed",()=>({...r,error:{message:"旧 IM Client 清理失败,已阻止新账号准备",data:e}}))});M=void 0===M?s:Promise.all([M,s]).then(()=>{}),B+=1,L={},N={},j={},G(),O.clear(),V()}function q(){if(S)throw new Error("ChatRuntime 已 dispose,不能创建/复用 client");if(null===P){const e=v({namespaceFactory:g});k=e;const r=b?.getCoreClient(),o=b?.getCoreApi?.();T=void 0!==r||void 0!==o;const t=b?.clientType??2,n=B,i=b?.onRequestError,s=r&&y?y({client:r,clientType:t,storage:k}):void 0,c={authProvider:{getLoginContext:async()=>{const e=b?.getSession?.(),r=void 0!==b?.getSession,o=(r?e?.userId:U.userId)?.trim()??"",n=(r?e?.token:U.token)?.trim()??"";return""===o||""===n||o!==U.userId?null:{userId:o,token:n,deviceToken:U.deviceToken,clientType:t,channelType:Number(U.channelType)}}},endpointProvider:{getEndpoints:async()=>[{url:U.wsUrl}],getCmHttpBaseUrl:async()=>U.cmHttpBaseUrl},cache:{prefix:f},adapters:{namespaceFactory:g,storage:{create:r=>{if(r.namespaceFactory!==g)throw new Error("ChatRuntime storage namespace factory 不一致");return e},purgeCurrentAccount:e=>C(e)}},profile:s,media:b?.getMediaConfig(),uploadRecovery:b?.uploadRecovery,expressions:b?.getExpressionOptions?.(),coreApi:o,coreClient:r,onRequestError:void 0===i?void 0:e=>S||B!==n?void 0:i(e),debug:p.debug},a=h(c),d=a.events;if(void 0===d&&K.size>0)throw Promise.resolve(k?.close?.()).catch(()=>{}),k=void 0,new Error("IM client 缺少产品事件 API");P=a,w=P.connection.subscribe(e=>{if(("message:updated"===e.type||"message:received"===e.type)&&"failed"===e.message.status&&"media.uploadInterrupted"===e.message.failure?.displayCode&&!1===e.message.failure.retryable){const r=e.message,o=l({conversationType:r.conversationType,conversationId:r.conversationId,messageId:r.id});F.remove(o),F.removeByPrefix(`${o}\0`)}for(const r of H)r(e)}),void 0!==d&&(I=d.subscribe(e=>{for(const r of K)r(e)})),A.record("debug","chat-kit","session","client-subscriptions-established",()=>D())}return P}function z(){const e=q();return x??(x=n(e,{coreApiAvailable:T})),x}function G(){$=/* @__PURE__ */new WeakMap,F.clearAll()}return{getClient:()=>P,getProductClient:()=>null===P?null:z(),ensureProductClient:z,getConnectionState:()=>P?.connection.state??"idle",getGeneration:()=>B,getCredentials:()=>U,getMediaConfig:()=>b?.getMediaConfig(),getDiagnostics:()=>A,configureHost(e){b=e},applySession(e,r,o){const t=e?.userId??"",n=e?.token??"",i=null!==P&&(U.userId!==t||U.token!==n);return i&&W(U.userId===t&&""!==n),U.wsUrl=r.wsUrl,U.cmHttpBaseUrl=r.cmHttpBaseUrl,U.userId=t,U.token=n,U.deviceToken=o,U.channelType="0",A.record("info","chat-kit","session","session-applied",()=>({data:{accountId:t,hasToken:""!==n,didReset:i}})),{didReset:i,hasToken:""!==n}},ensureClient:q,async prepare(){if(S)return{ok:!1,errorKey:"lifecycle.disposed"};if(""===U.userId)return{ok:!1,errorKey:"lifecycle.missingLoginState"};const e=Date.now(),r=D();A.record("info","chat-kit","session","prepare-start",()=>r);try{const o=U.userId,t=U.token;if(void 0!==M&&await M,S||B!==r.generation||U.userId!==o||U.token!==t)throw new Error("IM session 已变化,取消旧 prepare");if(R)throw new Error("旧 IM Client 未能完成清理,请刷新后重试",{cause:E});const n=q();return await n.connection.prepare(),A.record("info","chat-kit","session","prepare-complete",()=>({...r,durationMs:Date.now()-e})),{ok:!0}}catch(o){A.record("error","chat-kit","session","prepare-failed",()=>({...r,durationMs:Date.now()-e,error:{message:"ChatRuntime prepare 失败",data:o}}));const t=m(o);return void 0!==t?{ok:!1,errorKey:t}:{ok:!1,errorKey:"lifecycle.prepareFailed",errorParams:{reason:o instanceof Error?o.message:String(o)}}}},async connect(){if(S)return{ok:!1,errorKey:"lifecycle.disposed"};if(""===U.wsUrl||""===U.userId||""===U.token)return{ok:!1,errorKey:"lifecycle.missingConnectParams"};const e=Date.now(),r=D();A.record("info","chat-kit","connection","connect-start",()=>r);try{const o=U.userId,t=U.token;if(void 0!==M&&await M,S||B!==r.generation||U.userId!==o||U.token!==t)throw new Error("IM session 已变化,取消旧 connect");if(R)throw new Error("旧 IM Client 未能完成清理,请刷新后重试",{cause:E});const n=q();return await n.connection.connect(),A.record("info","chat-kit","connection","connect-complete",()=>({...r,durationMs:Date.now()-e})),{ok:!0}}catch(o){A.record("error","chat-kit","connection","connect-failed",()=>({...r,durationMs:Date.now()-e,error:{message:"ChatRuntime connect 失败",data:o}}));const t=m(o);return void 0!==t?{ok:!1,errorKey:t}:{ok:!1,errorKey:"lifecycle.connectFailed",errorParams:{reason:o instanceof Error?o.message:String(o)}}}},disconnect(){const e=D();A.record("info","chat-kit","connection","disconnect",()=>e),P?.connection.disconnect("im-chat-manual")},async logout(e){const r=Date.now(),o=D();A.record("info","chat-kit","session","logout-start",()=>({...o,data:e}));const t=P;let n,i;if(null!==t)try{i=t.logout(e)}catch(e){n=e}if(U.userId="",U.token="",U.deviceToken="",U.channelType="0",B+=1,void 0!==i)try{await i}catch(e){n=e}if(L={},N={},j={},G(),O.clear(),V(),A.record(void 0===n?"info":"error","chat-kit","session",void 0===n?"logout-complete":"logout-failed",()=>({...o,durationMs:Date.now()-r,...void 0===n?{}:{error:{message:"ChatRuntime logout 失败",data:n}}})),void 0!==n)throw n},resetForAuthChange:W,dispose(){if(S)return;S=!0;const e=D();A.record("info","chat-kit","session","dispose",()=>e),W(!0),H.clear(),K.clear(),_.clear()},subscribeEvents:e=>(H.add(e),()=>{H.delete(e)}),subscribeProductEvents:e=>(K.add(e),()=>{K.delete(e)}),getSenderProfileCache:()=>L,setSenderProfileCache(e){L=e,V()},getGroupMemberNames:()=>N,setGroupMemberNames(e){N=e,V()},getChannelMemberProfiles:()=>j,setChannelMemberProfiles(e){j=e,V()},subscribeProfileChange:e=>(_.add(e),()=>{_.delete(e)}),putSelfVoiceBytes(e,r){for(O.delete(e),O.set(e,r);O.size>20;){const e=O.keys().next().value;if(void 0===e)break;O.delete(e)}},getSelfVoiceBytes:e=>O.get(e),clearSelfVoiceBytes(){O.clear()},rememberLocalVideoPoster(e,r){$.set(e,r)},createLocalMediaPreview(e){const r=URL.createObjectURL(e);return F.register(u(r),r,{byteSize:e.size,evictable:!1,videoPoster:$.get(e)}),r},discardLocalMediaPreview(e){F.remove(u(e))},trackLocalMediaPreview(e,r){F.move(u(r),l(e))},resolveMediaPreviewToRemote(e,r,o,t){const n=l(e);if("image"===r||"video"===r){if(void 0!==t&&!F.bindResource(n,t))return;F.makeEvictable(n,o)}else F.remove(n)},hasMediaBlob:e=>F.has(l(e),e.resourceUrl),acquireMediaBlob:e=>F.acquire(l(e),e.resourceUrl),async clearMediaCache(){const e=P,r=B;if(null===e)throw new Error("IM session is not ready");if(F.clearCached(),await e.media.clearCache(),B!==r||P!==e)throw new Error("IM session changed during media cache cleanup")},cleanupLocalMediaBlobs:G,cleanupConversationMediaBlobs:function(e){F.removeByPrefix(function(e){return`message\0${e.conversationType}\0${e.conversationId}\0`}(e))}}}export{p as createChatRuntime};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e){const t=/* @__PURE__ */new Map,
|
|
1
|
+
function e(e){const t=/* @__PURE__ */new Map,o=/* @__PURE__ */new Set,r=e.revokeObjectUrl??(e=>URL.revokeObjectURL(e)),s=e.now??Date.now,i=e.maxIdleMs;if(!Number.isFinite(i)||i<=0)throw new RangeError("maxIdleMs must be a finite positive number");let n,c;function l(){void 0!==n&&clearTimeout(n),n=void 0,c=void 0}function a(){let e=Number.POSITIVE_INFINITY;for(const o of t.values())o.evictable&&0===o.leases&&(e=Math.min(e,o.lastAccessedAt+i));void 0!==n&&c===e||(l(),Number.isFinite(e)&&(c=e,n=setTimeout(()=>{n=void 0,c=void 0,f()},Math.min(2147483647,Math.max(0,e-s()))),n.unref?.()))}function d(e){e.revoked||(e.revoked=!0,o.delete(e),r(e.url))}function u(e){t.get(e.key)===e&&t.delete(e.key),e.retired=!0,0===e.leases?d(e):o.add(e)}function v(){let e=0,o=0;for(const r of t.values())r.evictable&&(e+=1,o+=r.byteSize+(r.videoPoster?.size??0));return{entries:e,bytes:o}}function f(){{const e=s();for(const o of t.values())o.evictable&&0===o.leases&&e-o.lastAccessedAt>=i&&u(o)}!function(){let o=v();for(;o.entries>e.maxCachedEntries||o.bytes>e.maxCachedBytes;){let e;for(const o of t.values())if(o.evictable&&0===o.leases){e=o;break}if(void 0===e)return;u(e),o=v()}}(),a()}function b(e){const o=t.get(e);void 0!==o&&u(o),f()}return{register:function(e,o,r){const i=r.byteSize??0,n=Number.isFinite(i)&&i>0?Math.floor(i):0,c=t.get(e);if(c?.url===o)return c.byteSize=n,c.videoPoster=r.videoPoster,c.evictable=r.evictable,c.lastAccessedAt=s(),t.delete(e),t.set(e,c),void f();void 0!==c&&u(c),t.set(e,{key:e,url:o,resourceUrl:o,byteSize:n,videoPoster:r.videoPoster,evictable:r.evictable,leases:0,retired:!1,revoked:!1,lastAccessedAt:s()}),f()},move:function(e,o){f();const r=t.get(e);if(void 0===r)return!1;const s=t.get(o);return void 0!==s&&s!==r&&u(s),t.delete(e),r.key=o,t.set(o,r),a(),!0},bindResource:function(e,o){f();const r=t.get(e);return void 0!==r&&(r.resourceUrl===o||(r.resourceUrl.startsWith("blob:")&&/^https?:\/\//i.test(o)?(r.resourceUrl=o,!0):(u(r),f(),!1)))},makeEvictable:function(e,o){f();const r=t.get(e);return void 0!==r&&(void 0!==o&&Number.isFinite(o)&&o>0&&(r.byteSize=Math.floor(o)),r.evictable=!0,r.lastAccessedAt=s(),t.delete(e),t.set(e,r),f(),t.get(e)===r)},acquire:function(e,o){f();const r=t.get(e);if(void 0===r||r.revoked||void 0!==o&&r.resourceUrl!==o)return;r.leases+=1,r.lastAccessedAt=s(),t.delete(e),t.set(e,r),a();let i=!1;return Object.freeze({url:r.url,...void 0===r.videoPoster?{}:{videoPoster:r.videoPoster},release(){i||(i=!0,r.leases=Math.max(0,r.leases-1),0!==r.leases||r.revoked||(r.lastAccessedAt=s()),r.retired&&0===r.leases&&d(r),f())}})},has:(e,o)=>{f();const r=t.get(e);return void 0!==r&&!r.revoked&&(void 0===o||r.resourceUrl===o)},remove:b,removeByPrefix:function(e){for(const o of[...t.keys()])o.startsWith(e)&&b(o)},clearAll:function(){l();const e=[...t.values()];t.clear();for(const t of[...e,...o])d(t);o.clear()},clearCached:function(){for(const e of t.values())e.evictable&&u(e);f()},prune:f,getStats:()=>(f(),Object.freeze({activeEntries:t.size,retiredEntries:o.size,...v()}))}}export{e as createMediaObjectUrlRegistry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e,n){if("supergroup"!==e.conversationType)return{conversation:{conversationType:e.conversationType,conversationId:e.conversationId},messageId:e.id,...void 0===n?{}:{itemIndex:n}}}function n(n,t,i){const o=n.getClient(),r=e(t,i);if(null===o||void 0===r)throw new Error("media download unavailable");o.media.prioritizeDownload(r)}async function t(n,t,i,o,r){const a=n.getClient(),l=e(t,o);if(null===a||void 0===l)throw new Error("media download unavailable");const s=void 0===i?void 0:a.media.subscribe(e=>{const n=e.find(e=>"download"===e.direction&&e.messageId===l.messageId&&e.itemIndex===o&&e.ref.conversationType===l.conversation.conversationType&&e.ref.conversationId===l.conversation.conversationId);void 0!==n&&i(n.percent)});try{return await(void 0===r?a.media.download(l):a.media.download(l,r))}finally{s?.()}}function i(e){return"object"==typeof e&&null!==e&&"code"in e&&"IM_SDK_MEDIA_DOWNLOAD_CANCELED"===e.code}async function o(e,n){const t=e.getClient();if(null===t)return null;const i=e.getGeneration(),o=await t.media.prepareLocalPreview(n);return null===o||e.getGeneration()!==i?null:("video"===n.kind&&"displayPoster"in o&&o.displayPoster&&e.rememberLocalVideoPoster(n.file,o.displayPoster),o)}function r(e){return e.length>=3&&255===e[0]&&216===e[1]&&255===e[2]?"image/jpeg":e.length>=8&&137===e[0]&&80===e[1]&&78===e[2]&&71===e[3]?"image/png":e.length>=6&&71===e[0]&&73===e[1]&&70===e[2]?"image/gif":e.length>=12&&87===e[8]&&69===e[9]&&66===e[10]&&80===e[11]?"image/webp":null}async function a(e){const n=r(new Uint8Array(await e.slice(0,12).arrayBuffer()));return null===n?null:URL.createObjectURL(e.type===n?e:e.slice(0,e.size,n))}function l(e){return e.length>=4&&26===e[0]&&69===e[1]&&223===e[2]&&163===e[3]?"video/webm":(e.length>=8&&102===e[4]&&116===e[5]&&121===e[6]&&e[7],"video/mp4")}function s(e,n,t){return e.acquireMediaBlob({conversationType:n.conversationType,conversationId:n.conversationId,messageId:n.id,...void 0===t?{}:{itemIndex:t}})}async function c(e,n,i){const o=e.getClient(),r=n.body.voice;if(null===o||void 0===r)return null;const a=e.getSelfVoiceBytes(n.id);if(void 0!==a)return a;const l=e.getGeneration();try{const o=new Uint8Array(await(await t(e,n)).arrayBuffer());return 0===o.length?(e.getGeneration()===l&&i.setNote(i.t("media.voiceLoadEmpty")),null):o}catch(n){return e.getGeneration()===l&&i.setNote(i.t("media.voiceLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function u(e,n,o,r){const a=e.getClient(),l=n.body.video;if(null===a||void 0===l)return null;const s=e.getGeneration();try{const i=await t(e,n,r);if(0===i.size)return e.getGeneration()===s&&o.setNote(o.t("media.videoOpenEmpty")),null;const a=URL.createObjectURL(i);return e.getGeneration()!==s?(URL.revokeObjectURL(a),null):a}catch(n){return e.getGeneration()!==s||i(n)||o.setNote(o.t("media.videoLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function d(n,t){const i=n.getClient(),o=e(t);if(null===i||void 0===o||void 0===t.body.video)return null;const r=n.getGeneration();try{const e=await i.media.getCached(o);if(null===e||0===e.size||n.getGeneration()!==r)return null;const t=new Uint8Array(await e.slice(0,12).arrayBuffer()),a=e.type||l(t);return n.getGeneration()!==r?null:URL.createObjectURL(e.type===a?e:e.slice(0,e.size,a))}catch{return null}}async function g(e,n,o,r,l,s){const c=e.getClient(),u=n.body.mediaAlbum?.items[o];if(null===c||void 0===u||s?.signal?.aborted)return null;const d="video"===u.kind,g=e.getGeneration();try{const i=await t(e,n,l,o,s);if(e.getGeneration()!==g||s?.signal?.aborted)return null;if(d&&0===i.size)return e.getGeneration()===g&&r.setNote(r.t("media.videoOpenEmpty")),null;const c=d?URL.createObjectURL(i):await a(i);return e.getGeneration()!==g||s?.signal?.aborted?(null!==c&&URL.revokeObjectURL(c),null):null===c?(e.getGeneration()===g&&r.setNote(r.t("media.imageInvalid",{size:i.size})),null):c}catch(n){return e.getGeneration()!==g||s?.signal?.aborted||i(n)||r.setNote(r.t(d?"media.videoLoadFailed":"media.imageLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function v(n,t,i){const o=n.getClient(),r=t.body.mediaAlbum?.items[i],l=e(t,i);if(null===o||void 0===l||void 0===r||!/^https?:\/\//i.test(r.url))return null;const s=n.getGeneration();try{const e=await o.media.getCached(l);if(null===e||0===e.size||n.getGeneration()!==s)return null;const t="video"===r.kind?URL.createObjectURL(e):await a(e);return null===t?null:n.getGeneration()!==s?(URL.revokeObjectURL(t),null):t}catch{return null}}async function f(e,n,o,r){const l=e.getClient(),s=n.body.image;if(null===l||void 0===s||r?.signal?.aborted)return null;const c=e.getGeneration();try{const i=await t(e,n,void 0,void 0,r);if(e.getGeneration()!==c||r?.signal?.aborted)return null;const l=await a(i);return e.getGeneration()!==c||r?.signal?.aborted?(null!==l&&URL.revokeObjectURL(l),null):null===l?(e.getGeneration()===c&&o.setNote(o.t("media.imageInvalid",{size:i.size})),null):l}catch(n){return e.getGeneration()!==c||r?.signal?.aborted||i(n)||o.setNote(o.t("media.imageLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function m(n,t){const i=n.getClient(),o=e(t);if(null===i||void 0===o||void 0===t.body.image)return null;const r=n.getGeneration();try{const e=await i.media.getCached(o);if(null===e||0===e.size||n.getGeneration()!==r)return null;const t=await a(e);return null===t?null:n.getGeneration()!==r?(URL.revokeObjectURL(t),null):t}catch{return null}}async function y(e,n,o,r,a){const l=e.getClient(),s=void 0===a?n.body.file:n.body.filesAlbum?.items[a];if(null===l||void 0===s)return null;const c=e.getGeneration();try{const i=await t(e,n,r,a);if(0===i.size)return e.getGeneration()===c&&o.setNote(o.t("media.fileDownloadEmpty")),null;const l=URL.createObjectURL(i);return e.getGeneration()!==c?(URL.revokeObjectURL(l),null):l}catch(n){return e.getGeneration()!==c||i(n)||o.setNote(o.t("media.fileDownloadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}export{s as acquireMediaBlob,r as detectImageMime,l as detectVideoMime,m as loadCachedImageObjectUrl,v as loadCachedMediaAlbumItemObjectUrl,d as loadCachedVideoObjectUrl,y as loadFileObjectUrl,f as loadImageObjectUrl,g as loadMediaAlbumItemObjectUrl,u as loadVideoObjectUrl,c as loadVoiceBytes,o as prepareLocalMediaPreview,n as prioritizeMediaDownload};
|
|
1
|
+
function e(e){if(e?.aborted)throw e.reason??new DOMException("媒体显示图准备已取消","AbortError")}async function n(e){try{return await e()}catch(e){if("object"==typeof e&&null!==e&&"code"in e&&"IM_SDK_MEDIA_CACHE_READ_FAILED"===e.code)return null;throw e}}function t(e,n){const t=void 0===n?1:e.body.mediaAlbum?.items.length??1;return t<=1?1440:2===t?1080:768}async function i(t,i,o,r,a){if(!i.startsWith("blob:"))throw new TypeError("气泡显示图只接受本机 blob 地址");e(r);const l=t.getClient();if(null===l)return null;const u=t.getGeneration(),c=void 0===a?void 0:s(a.message,a.itemIndex),d=void 0===a?void 0:void 0===a.itemIndex?a.message.body.image?.url:a.message.body.mediaAlbum?.items[a.itemIndex]?.url,g=()=>t.getGeneration()===u&&t.getClient()===l;if(void 0!==c){const t=await n(()=>l.media.getCachedImageDisplay(c,{maxSize:o,signal:r}));if(e(r),!g())return null;if(null!==t)return URL.createObjectURL(t)}const m=await fetch(i,{signal:r});if(!m.ok)throw new Error("无法读取气泡显示图的本机原文件");const f=await m.blob();if(e(r),!g())return null;const v=await l.media.prepareLocalImageDisplay({file:f,maxSize:o,signal:r,message:c,expectedResourceUrl:d});return e(r),null!==v&&g()?URL.createObjectURL(v):null}async function o(i,o,r,a){e(a);const l=i.getClient(),u=s(o,r),c=void 0===r?o.body.image:o.body.mediaAlbum?.items[r];if(null===l||void 0===u||void 0===c||"kind"in c&&"image"!==c.kind)return null;const d=c.url,g=t(o,r),m=i.getGeneration(),f=()=>i.getGeneration()===m&&i.getClient()===l,v=await n(()=>l.media.getCachedImageDisplay(u,{maxSize:g,signal:a}));if(e(a),!f())return null;if(null!==v)return URL.createObjectURL(v);if(!/^https?:\/\//i.test(d))return null;const b=await l.media.getCached(u);if(e(a),null===b||!f())return null;const y=await l.media.prepareLocalImageDisplay({file:b,maxSize:g,signal:a,message:u,expectedResourceUrl:d});return e(a),null!==y&&f()?URL.createObjectURL(y):null}async function r(n,r,a,l,s){const u=n.getGeneration(),c=n.getClient(),d=await o(n,r,s,l.signal);if(null!==d)return d;if(e(l.signal),n.getGeneration()!==u||n.getClient()!==c)return null;const g=void 0===s?await R(n,r,a,l):await p(n,r,s,a,void 0,l);if(null===g)return null;try{return await i(n,g,t(r,s),l.signal,{message:r,itemIndex:s})}finally{URL.revokeObjectURL(g)}}async function a(t,i,o,r,a){if(!i.startsWith("blob:"))throw new TypeError("视频封面只接受本机 blob 地址");e(o);const l=t.getClient();if(null===l)return null;const u=t.getGeneration(),c=()=>t.getGeneration()===u&&t.getClient()===l,d=void 0===r?void 0:s(r.message,r.itemIndex),g=void 0===r?void 0:void 0===r.itemIndex?r.message.body.video?.url:r.message.body.mediaAlbum?.items[r.itemIndex]?.url;if(void 0!==d){const t=await n(()=>l.media.getCachedVideoPoster(d,{signal:o}));if(e(o),!c())return null;if(null!==t)return URL.createObjectURL(t)}let m;if(void 0===a){const e=await fetch(i,{signal:o});if(!e.ok)throw new Error("无法读取本机视频");m=await e.blob()}if(e(o),!c())return null;const f=await l.media.prepareLocalVideoPoster({file:m,poster:a,signal:o,message:d,expectedResourceUrl:g});return e(o),null!==f&&c()?URL.createObjectURL(f):null}async function l(t,i,o,r){e(r);const a=t.getClient(),l=s(i,o),u=void 0===o?i.body.video:i.body.mediaAlbum?.items[o];if(null===a||void 0===l||void 0===u||"kind"in u&&"video"!==u.kind)return null;const c=u.url,d=t.getGeneration(),g=()=>t.getGeneration()===d&&t.getClient()===a,m=await n(()=>a.media.getCachedVideoPoster(l,{signal:r}));if(e(r),!g())return null;if(null!==m)return URL.createObjectURL(m);if(!/^https?:\/\//i.test(c))return null;const f=await a.media.getCached(l);if(e(r),null===f||!g())return null;const v=await a.media.prepareLocalVideoPoster({file:f,signal:r,message:l,expectedResourceUrl:c});return e(r),null!==v&&g()?URL.createObjectURL(v):null}function s(e,n){if("supergroup"!==e.conversationType)return{conversation:{conversationType:e.conversationType,conversationId:e.conversationId},messageId:e.id,...void 0===n?{}:{itemIndex:n}}}function u(e,n,t){const i=e.getClient(),o=s(n,t);if(null===i||void 0===o)throw new Error("media download unavailable");i.media.prioritizeDownload(o)}async function c(e,n,t,i,o){const r=e.getClient(),a=s(n,i);if(null===r||void 0===a)throw new Error("media download unavailable");const l=void 0===t?void 0:r.media.subscribe(e=>{const n=e.find(e=>"download"===e.direction&&e.messageId===a.messageId&&e.itemIndex===i&&e.ref.conversationType===a.conversation.conversationType&&e.ref.conversationId===a.conversation.conversationId);void 0!==n&&t(n.percent)});try{return await(void 0===o?r.media.download(a):r.media.download(a,o))}finally{l?.()}}function d(e){return"object"==typeof e&&null!==e&&"code"in e&&"IM_SDK_MEDIA_DOWNLOAD_CANCELED"===e.code}async function g(e,n){const t=e.getClient();if(null===t)return null;const i=e.getGeneration(),o=await t.media.prepareLocalPreview(n);return null===o||e.getGeneration()!==i?null:("video"===n.kind&&"displayPoster"in o&&o.displayPoster&&e.rememberLocalVideoPoster(n.file,o.displayPoster),o)}function m(e){return e.length>=3&&255===e[0]&&216===e[1]&&255===e[2]?"image/jpeg":e.length>=8&&137===e[0]&&80===e[1]&&78===e[2]&&71===e[3]?"image/png":e.length>=6&&71===e[0]&&73===e[1]&&70===e[2]?"image/gif":e.length>=12&&87===e[8]&&69===e[9]&&66===e[10]&&80===e[11]?"image/webp":null}async function f(e){const n=m(new Uint8Array(await e.slice(0,12).arrayBuffer()));return null===n?null:URL.createObjectURL(e.type===n?e:e.slice(0,e.size,n))}function v(e){return e.length>=4&&26===e[0]&&69===e[1]&&223===e[2]&&163===e[3]?"video/webm":(e.length>=8&&102===e[4]&&116===e[5]&&121===e[6]&&e[7],"video/mp4")}function b(e,n,t){return e.acquireMediaBlob({conversationType:n.conversationType,conversationId:n.conversationId,messageId:n.id,resourceUrl:void 0===t?n.body.image?.url??n.body.video?.url??n.body.sticker?.url:n.body.mediaAlbum?.items[t]?.url,...void 0===t?{}:{itemIndex:t}})}async function y(e,n,t){const i=e.getClient(),o=n.body.voice;if(null===i||void 0===o)return null;const r=e.getSelfVoiceBytes(n.id);if(void 0!==r)return r;const a=e.getGeneration();try{const i=new Uint8Array(await(await c(e,n)).arrayBuffer());return 0===i.length?(e.getGeneration()===a&&t.setNote(t.t("media.voiceLoadEmpty")),null):i}catch(n){return e.getGeneration()===a&&t.setNote(t.t("media.voiceLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function w(e,n,t,i){const o=e.getClient(),r=n.body.video;if(null===o||void 0===r)return null;const a=e.getGeneration();try{const o=await c(e,n,i);if(0===o.size)return e.getGeneration()===a&&t.setNote(t.t("media.videoOpenEmpty")),null;const r=URL.createObjectURL(o);return e.getGeneration()!==a?(URL.revokeObjectURL(r),null):r}catch(n){return e.getGeneration()!==a||d(n)||t.setNote(t.t("media.videoLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function L(e,n){const t=e.getClient(),i=s(n);if(null===t||void 0===i||void 0===n.body.video)return null;const o=e.getGeneration();try{const n=await t.media.getCached(i);if(null===n||0===n.size||e.getGeneration()!==o)return null;const r=new Uint8Array(await n.slice(0,12).arrayBuffer()),a=n.type||v(r);return e.getGeneration()!==o?null:URL.createObjectURL(n.type===a?n:n.slice(0,n.size,a))}catch{return null}}async function p(e,n,t,i,o,r){const a=e.getClient(),l=n.body.mediaAlbum?.items[t];if(null===a||void 0===l||r?.signal?.aborted)return null;const s="video"===l.kind,u=e.getGeneration();try{const a=await c(e,n,o,t,r);if(e.getGeneration()!==u||r?.signal?.aborted)return null;if(s&&0===a.size)return e.getGeneration()===u&&i.setNote(i.t("media.videoOpenEmpty")),null;const l=s?URL.createObjectURL(a):await f(a);return e.getGeneration()!==u||r?.signal?.aborted?(null!==l&&URL.revokeObjectURL(l),null):null===l?(e.getGeneration()===u&&i.setNote(i.t("media.imageInvalid",{size:a.size})),null):l}catch(n){return e.getGeneration()!==u||r?.signal?.aborted||d(n)||i.setNote(i.t(s?"media.videoLoadFailed":"media.imageLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function U(e,n,t){const i=e.getClient(),o=n.body.mediaAlbum?.items[t],r=s(n,t);if(null===i||void 0===r||void 0===o||!/^https?:\/\//i.test(o.url))return null;const a=e.getGeneration();try{const n=await i.media.getCached(r);if(null===n||0===n.size||e.getGeneration()!==a)return null;const t="video"===o.kind?URL.createObjectURL(n):await f(n);return null===t?null:e.getGeneration()!==a?(URL.revokeObjectURL(t),null):t}catch{return null}}async function R(e,n,t,i){const o=e.getClient(),r=n.body.image;if(null===o||void 0===r||i?.signal?.aborted)return null;const a=e.getGeneration();try{const o=await c(e,n,void 0,void 0,i);if(e.getGeneration()!==a||i?.signal?.aborted)return null;const r=await f(o);return e.getGeneration()!==a||i?.signal?.aborted?(null!==r&&URL.revokeObjectURL(r),null):null===r?(e.getGeneration()===a&&t.setNote(t.t("media.imageInvalid",{size:o.size})),null):r}catch(n){return e.getGeneration()!==a||i?.signal?.aborted||d(n)||t.setNote(t.t("media.imageLoadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}async function G(e,n){const t=e.getClient(),i=s(n);if(null===t||void 0===i||void 0===n.body.image)return null;const o=e.getGeneration();try{const n=await t.media.getCached(i);if(null===n||0===n.size||e.getGeneration()!==o)return null;const r=await f(n);return null===r?null:e.getGeneration()!==o?(URL.revokeObjectURL(r),null):r}catch{return null}}async function h(e,n,t,i,o){const r=e.getClient(),a=void 0===o?n.body.file:n.body.filesAlbum?.items[o];if(null===r||void 0===a)return null;const l=e.getGeneration();try{const r=await c(e,n,i,o);if(0===r.size)return e.getGeneration()===l&&t.setNote(t.t("media.fileDownloadEmpty")),null;const a=URL.createObjectURL(r);return e.getGeneration()!==l?(URL.revokeObjectURL(a),null):a}catch(n){return e.getGeneration()!==l||d(n)||t.setNote(t.t("media.fileDownloadFailed",{reason:n instanceof Error?n.message:String(n)})),null}}export{b as acquireMediaBlob,m as detectImageMime,v as detectVideoMime,o as loadCachedImageDisplayObjectUrl,G as loadCachedImageObjectUrl,U as loadCachedMediaAlbumItemObjectUrl,L as loadCachedVideoObjectUrl,l as loadCachedVideoPosterObjectUrl,h as loadFileObjectUrl,r as loadImageDisplayObjectUrl,R as loadImageObjectUrl,p as loadMediaAlbumItemObjectUrl,w as loadVideoObjectUrl,y as loadVoiceBytes,i as prepareImageDisplayObjectUrl,g as prepareLocalMediaPreview,a as prepareVideoPosterObjectUrl,u as prioritizeMediaDownload,t as resolveImageDisplayMaxSize};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e){const{message:t}=e,i=e=>e.messageId===t.id&&e.ref.conversationId===t.conversationId&&e.ref.conversationType===t.conversationType,n=void 0!==e.uploadTask&&i(e.uploadTask)?e.uploadTask:void 0,s="uploading"===t.status||"failed"===t.status&&(!0===t.failure?.displayCode?.startsWith("media.")||void 0!==n&&"completed"!==n.state),a=s?"upload":"download",d=t.body.mediaAlbum?.items??t.body.filesAlbum?.items,o=void 0===e.aggregateFrom?[e.itemIndex]:(d??[]).map((e,t)=>t).slice(e.aggregateFrom),r=o.map(a=>{const o=void 0===a?t.body.image??t.body.video??t.body.file:d?.[a];if(s){const e=void 0===a?void 0:n?.items?.find(e=>e.itemIndex===a);return{state:"completed"===e?.state?"completed":"failed"===t.status?"failed":"paused"===n?.state?"paused":"running"===(e?.state??n?.state)?"running":"waiting",percent:e?.percent??(void 0===a?n?.percent:void 0),size:e?.bytesTotal??o?.size}}const r=e.downloadTasks.find(e=>i(e)&&e.itemIndex===a&&"download"===e.direction),l="failed"===r?.state?"failed":"running"===r?.state||"queued"===r?.state?"running":"completed"===r?.state&&!e.unavailableItemIndices?.includes(a)||o?.url.startsWith("blob:")||e.availableItemIndices?.includes(a)?"completed":"waiting";return{state:l,percent:"completed"===l?100:"waiting"===l&&"completed"===r?.state?0:r?.percent??0,size:r?.bytesTotal??o?.size}}),l=r.some(e=>"failed"===e.state)?"failed":r.some(e=>"running"===e.state)?"running":r.some(e=>"paused"===e.state)?"paused":r.length>0&&r.every(e=>"completed"===e.state)?"completed":"waiting",c="download"===a&&"waiting"===l&&o.some(t=>e.pendingItemIndices?.includes(t))?{resolving:!0}:{};if(1===r.length)return{direction:a,state:l,percent:r[0].percent,...c};if(0===r.length||r.some(e=>!Number.isFinite(e.size)||e.size<=0||void 0===e.percent))return{direction:a,state:l,...c};const u=r.reduce((e,t)=>e+t.size,0);return{direction:a,state:l,percent:Math.round(r.reduce((e,t)=>e+t.size*t.percent,0)/u),...c}}export{e as resolveMediaTransferPresentation};
|
|
1
|
+
function e(e){const{message:t}=e,i=e=>e.messageId===t.id&&e.ref.conversationId===t.conversationId&&e.ref.conversationType===t.conversationType,n=void 0!==e.uploadTask&&i(e.uploadTask)?e.uploadTask:void 0,s="uploading"===t.status||"failed"===t.status&&(!0===t.failure?.displayCode?.startsWith("media.")||void 0!==n&&"completed"!==n.state),a=s?"upload":"download",d=t.body.mediaAlbum?.items??t.body.filesAlbum?.items,o=void 0===e.aggregateFrom?[e.itemIndex]:(d??[]).map((e,t)=>t).slice(e.aggregateFrom),r=o.map(a=>{const o=void 0===a?t.body.image??t.body.video??t.body.file:d?.[a];if(s){const e=void 0===a?void 0:n?.items?.find(e=>e.itemIndex===a);return{state:"completed"===e?.state?"completed":"failed"===t.status?"failed":"paused"===n?.state?"paused":"running"===(e?.state??n?.state)?"running":"waiting",percent:e?.percent??(void 0===a?n?.percent:void 0),size:e?.bytesTotal??o?.size}}if(e.displayAvailableItemIndices?.includes(a))return{state:"completed",percent:100,size:o?.size};const r=e.downloadTasks.find(e=>i(e)&&e.itemIndex===a&&"download"===e.direction),l="failed"===r?.state?"failed":"running"===r?.state||"queued"===r?.state?"running":"completed"===r?.state&&!e.unavailableItemIndices?.includes(a)||o?.url.startsWith("blob:")||e.availableItemIndices?.includes(a)?"completed":"waiting";return{state:l,percent:"completed"===l?100:"waiting"===l&&"completed"===r?.state?0:r?.percent??0,size:r?.bytesTotal??o?.size}}),l=r.some(e=>"failed"===e.state)?"failed":r.some(e=>"running"===e.state)?"running":r.some(e=>"paused"===e.state)?"paused":r.length>0&&r.every(e=>"completed"===e.state)?"completed":"waiting",c="download"===a&&"waiting"===l&&o.some(t=>e.pendingItemIndices?.includes(t))?{resolving:!0}:{};if(1===r.length)return{direction:a,state:l,percent:r[0].percent,...c};if(0===r.length||r.some(e=>!Number.isFinite(e.size)||e.size<=0||void 0===e.percent))return{direction:a,state:l,...c};const u=r.reduce((e,t)=>e+t.size,0);return{direction:a,state:l,percent:Math.round(r.reduce((e,t)=>e+t.size*t.percent,0)/u),...c}}export{e as resolveMediaTransferPresentation};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{throwIfAborted as e}from"../abort.js";import{createCryptoBatchPreparation as t}from"./crypto-batch-preparation.js";import{mapIncomingGroupChat as s}from"./group-message-mapper.js";import{mapIncomingGroupNotify as r}from"./group-notify-mapper.js";import{fromWireMsgId as o}from"./message-id.js";import{toWireMessageIds as n,fromWireMissingMessageIds as d}from"./messages-by-id.js";import{mapIncomingGroupReaction as c}from"./reaction-mapper.js";import{groupReadAllMsgReqCodec as i,groupReadAllMsgRespCodec as a,getGroupMsgByIdReqCodec as p,getGroupMsgByIdRespCodec as m,offlineGroupSessionReqCodec as g,offlineGroupSessionRespCodec as u,mesGrpChatCodec as I,mesGrpNotifyDeliverCodec as y,bMessageCodec as l,bContentCodec as f,getGroupHistoryMsgReqCodec as h,getGroupHistoryMsgRespCodec as T,offlineGroupMsgReqCodec as E,offlineGroupMsgRespCodec as M}from"../../../im-protocol/src/protobuf/registry.js";import{CmdId as v}from"../../../im-protocol/src/protobuf/gen/im.pub_pb.js";import{isCryptoExecutionError as w}from"../ports/crypto-task-executor.js";const G=/* @__PURE__ */new Set([v.MES_GRPCHAT_DELIVER,v.MES_GRPCHAT_EDIT_MSG_C2C]),C=l.create({contentType:1,content:""});function L(e){return E.encode(E.create({userId:BigInt(e.userId),msgId:"",deliveredMsgIds:e.deliveredMsgIds??[],limit:e.limit??50,clientType:e.clientType??0}))}function D(e){return g.encode(g.create({userId:BigInt(e.userId),clientType:String(e.clientType??0),size:BigInt(e.size??21)}))}function b(e,t,n,d){if(R(e.sGroupId,t.expectedGroupId),e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER){const s=d?.chat??I.decode(e.sMsgData),r={...s,sMsgId:s.sMsgId||e.sMsgId,sFromId:0n===s.sFromId?e.sFromId:s.sFromId,sGrpId:0n===s.sGrpId?e.sGroupId:s.sGrpId,sToId:0n===s.sToId?e.sGroupId:s.sToId,msgTime:0n===s.msgTime?e.msgTime:s.msgTime,parentMsgId:s.parentMsgId||e.parentMsgId};return R(r.sGrpId,t.expectedGroupId),t.onReaction?.(c(r)),null}if(e.cmdId===v.MES_GRPNOTIFY_DELIVER){const s=d?.notify??y.decode(e.sMsgData);return R(s.sGrpId,t.expectedGroupId),r(s,{selfId:t.selfId,cmdId:e.cmdId,receivedAt:t.receivedAt,keepRaw:t.keepRaw})}if(!G.has(e.cmdId))return null;const i=d?.chat??I.decode(e.sMsgData);R(i.sGrpId,t.expectedGroupId);let a=C,p=!1,m=!1;if(0===i.encrypt)try{a=l.decode(i.sContent)}catch{m=!0}else if(1===i.encrypt&&void 0!==n){const e=function(e,t,s,r){const o=void 0===r?s.resolvePrivateKey({groupId:t,msgType:e.msgType,encrypt:e.encrypt,encryptVersion:e.encryptVersion}):null;if("no-key"===r?.kind||void 0===r&&null===o)return s.onDecryptError?.({msgId:e.sMsgId,groupId:t,fromId:String(e.sFromId),msgType:e.msgType,encrypt:e.encrypt,encryptVersion:e.encryptVersion,reason:"no-key"}),null;try{if("plain"===r?.kind)return l.decode(r.plain);if("failed"===r?.kind)throw r.cause;const t=f.decode(e.sContent);if(0===t.secretKey.length||0===t.cipherData.length)throw new Error(`BContent 字段缺失:secretKey=${t.secretKey.length}B cipherData=${t.cipherData.length}B`);const n=s.crypto.decryptEndToEnd({secretKey:t.secretKey,cipherData:t.cipherData,privateKey:o});return l.decode(n)}catch(r){return s.onDecryptError?.({msgId:e.sMsgId,groupId:t,fromId:String(e.sFromId),msgType:e.msgType,encrypt:e.encrypt,encryptVersion:e.encryptVersion,reason:"decrypt-failed",cause:r}),null}}(i,i.sGrpId.toString(),n,d?.content);a=e??C,p=null===e}else p=!0;const g=s(i,a,{selfId:t.selfId,cmdId:e.cmdId,receivedAt:t.receivedAt,keepRaw:t.keepRaw,decryptFailed:p});return m&&(g.contentType="unknown",g.body={unknown:{reason:"malformed-content"}},g.raw={...g.raw,contentDecodeFailure:{codec:"BMessage",byteLength:i.sContent.length}}),p&&1===i.encrypt&&n?.onDecryptRecovery?.({conversation:{conversationType:"group",conversationId:g.conversationId},messageId:g.id,wireEncrypt:1,sContent:i.sContent.slice(),...""===i.encryptVersion?{}:{encryptVersion:i.encryptVersion},cmdId:e.cmdId,source:t.source??"offline",createdAt:Date.now()}),void 0===g.refMessageId&&e.parentMsgId&&(g.refMessageId=o(e.parentMsgId)),1===e.isEdit&&(g.edited=!0),g}function R(e,t){if(void 0!==t&&e.toString()!==t)throw new Error(`group history: 响应群不属于请求(groupId=${e})`)}function S(t,s){e(t.signal),t.assertCurrent?.(void 0===s?void 0:{conversationType:"group",conversationId:s})}async function _(e){S(e),await e.yieldToEventLoop(),S(e)}function x(e,t){R(e.sGroupId,t);if((G.has(e.cmdId)||e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER||e.cmdId===v.MES_GRPNOTIFY_DELIVER)&&e.sGroupId<=0n)throw new Error("group response: 消息缺少有效群身份");const s={...e.sGroupId>0n?{groupId:e.sGroupId.toString()}:{}};if(G.has(e.cmdId)||e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER){s.chat=I.decode(e.sMsgData);R(e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER&&0n===s.chat.sGrpId?e.sGroupId:s.chat.sGrpId,s.groupId)}else e.cmdId===v.MES_GRPNOTIFY_DELIVER&&(s.notify=y.decode(e.sMsgData),R(s.notify.sGrpId,s.groupId));return s}async function A(e,s,r,o,n,d=[],c=!1){const i=await async function(e,s,r,o=[],n=!0){const d=/* @__PURE__ */new Map,c=/* @__PURE__ */new Map,i=new Set(o);for(const e of o)S(r,e);for(const[t,{item:s,expectedGroupId:o}]of e.entries()){let e;S(r),t>0&&t%5==0&&await _(r);try{e=x(s,o)}catch(e){if(!n)throw e;c.set(t,e);continue}S(r,e.groupId),d.set(t,e),void 0===e.groupId||void 0===e.chat&&void 0===e.notify||i.add(e.groupId)}S(r),void 0!==s&&i.size>0&&void 0!==r.prepareKeys&&(await r.prepareKeys([...i]),S(r));const a=t({...r,assertCurrent:()=>S(r)},(e,t)=>{d.get(e).content=t});for(const[t,{item:o}]of e.entries()){S(r),t>0&&t%5==0&&await _(r);const e=d.get(t);if(void 0===e)continue;S(r,e.groupId);const n=e.chat;if(!G.has(o.cmdId)||1!==n?.encrypt||void 0===s)continue;let i;try{const r=s.resolvePrivateKey({groupId:e.groupId,msgType:n.msgType,encrypt:n.encrypt,encryptVersion:n.encryptVersion});if(null===r)e.content={kind:"no-key"};else try{const e=f.decode(n.sContent);if(0===e.secretKey.length||0===e.cipherData.length)throw new Error("BContent secretKey/cipherData missing");i={itemIndex:t,input:{secretKey:e.secretKey,cipherData:e.cipherData,privateKey:r}}}catch(t){e.content={kind:"failed",cause:t}}}catch(e){if(w(e)||e instanceof Error&&"AbortError"===e.name)throw e;c.set(t,e)}void 0!==i&&await a.add(i),S(r,e.groupId)}return await a.finish(),S(r),{rows:d,errors:c}}(e,r,o,d,n),a=[],p=[],m=[];for(const[t,{item:d,expectedGroupId:g}]of e.entries()){S(o),t>0&&t%5==0&&await _(o);const e=i.rows.get(t);S(o,e?.groupId);try{if(i.errors.has(t))throw i.errors.get(t);const o=b(d,{...s,expectedGroupId:g},r,e);null!==o&&(c&&1===d.isCancel&&(o.recalled={by:o.senderId,at:o.serverTime??o.createdAt},o.body={}),a.push(o)),p.push({msgId:d.sMsgId,msgTime:d.msgTime,cmdId:d.cmdId})}catch(e){if(!n||w(e)||e instanceof Error&&"AbortError"===e.name)throw e;m.push({msgId:d.sMsgId,cmdId:d.cmdId,cause:e})}S(o,e?.groupId)}return S(o),{messages:a,deliveredMsgInfos:p,...0===m.length?{}:{itemErrors:m}}}async function V(e,t,s,r){S(r);const o=M.decode(e);return{...await A(o.msgList.map(e=>({item:e,expectedGroupId:t.expectedGroupId})),t,s,r,!0),batchSize:o.msgList.length,responseBytes:e.length}}function B(e,t,s){const r=M.decode(e),o=[],n=[],d=[];for(const e of r.msgList)try{const r=b(e,t,s);null!==r&&o.push(r),n.push({msgId:e.sMsgId,msgTime:e.msgTime,cmdId:e.cmdId})}catch(t){d.push({msgId:e.sMsgId,cmdId:e.cmdId,cause:t})}return{messages:o,deliveredMsgInfos:n,batchSize:r.msgList.length,responseBytes:e.length,...0===d.length?{}:{itemErrors:d}}}function k(e,t,s){const r=u.decode(e),o=[],n=[],d=[];for(const e of r.sessionList){o.push({groupId:e.groupId.toString(),unreadCount:Number(e.unreadCount)});for(const r of e.msgList)try{const e=b(r,t,s);null!==e&&n.push(e)}catch(e){d.push({msgId:r.sMsgId,cmdId:r.cmdId,cause:e})}}return{unreads:o,messages:n,...0===d.length?{}:{itemErrors:d}}}async function K(e,t,s,r){S(r);const o=u.decode(e),n=[],d=[];for(const e of o.sessionList){R(e.groupId,t.expectedGroupId);const s=e.groupId.toString();S(r,s),n.push({groupId:s,unreadCount:Number(e.unreadCount)}),d.push(...e.msgList.map(e=>({item:e,expectedGroupId:s})))}const{messages:c,itemErrors:i}=await A(d,t,s,r,!0,n.map(e=>e.groupId));return{unreads:n,messages:c,...void 0===i?{}:{itemErrors:i}}}function N(e){return h.encode(h.create({userId:BigInt(e.userId),groupId:BigInt(e.groupId),baseTime:BigInt(e.baseTime),direct:e.direct??1,limit:e.limit??50,clientType:e.clientType??0}))}function F(e,t,s){const r=T.decode(e),o=[];for(const e of r.msgList){const r=b(e,t,s);null!==r&&o.push(r)}const n=r.msgList.map(e=>Number(e.msgTime));return{messages:o,batchSize:r.msgList.length,...0===n.length?{}:{oldestEntryTime:Math.min(...n),newestEntryTime:Math.max(...n)}}}async function P(t,s,r,o,n){e(o.signal);const d=T.decode(t);if(200!==d.code)throw new Error(`group history: code=${d.code}`);if(void 0!==n){const t={...n,assertCurrent:t=>{e(o.signal),n.assertCurrent?.(t)}},{messages:c}=await A(d.msgList.map(e=>({item:e,expectedGroupId:s.expectedGroupId})),s,r,t,!1);let i,a;for(const e of d.msgList){const t=Number(e.msgTime);i=void 0===i?t:Math.min(i,t),a=void 0===a?t:Math.max(a,t)}return{messages:c,batchSize:d.msgList.length,...void 0===i?{}:{oldestEntryTime:i,newestEntryTime:a}}}const c=[];let i,a,p=0;for(const t of d.msgList){e(o.signal),p>0&&p%5==0&&(await o.yieldToEventLoop(),e(o.signal));const n=b(t,s,r);null!==n&&c.push(n);const d=Number(t.msgTime);i=void 0===i?d:Math.min(i,d),a=void 0===a?d:Math.max(a,d),p+=1}return e(o.signal),{messages:c,batchSize:d.msgList.length,...void 0===i?{}:{oldestEntryTime:i,newestEntryTime:a}}}function j(e){return p.encode(p.create({userId:BigInt(e.userId),groupId:BigInt(e.groupId),msgIds:n(e.messageIds),clientType:e.clientType??0}))}function z(e,t,s,r){const o=m.decode(e),n=[];for(const e of o.msgList){const r=b(e,t,s);null!==r&&(1===e.isCancel&&(r.recalled={by:r.senderId,at:r.serverTime??r.createdAt},r.body={}),n.push(r))}return{messages:n,missingMessageIds:d(o.missingMsgIds,r),code:o.code}}async function O(e,t,s,r,o){S(o);const n=m.decode(e),c=d(n.missingMsgIds,r);if(200!==n.code)return{messages:[],missingMessageIds:c,code:n.code};const{messages:i}=await A(n.msgList.map(e=>({item:e,expectedGroupId:t.expectedGroupId})),t,s,o,!1,[],!0);return{messages:i,missingMessageIds:c,code:n.code}}function H(e){return i.encode(i.create({userId:BigInt(e.userId),groupId:BigInt(e.groupId)}))}function $(e){return{code:a.decode(e).code}}export{F as decodeGroupHistoryBatch,P as decodeGroupHistoryBatchAsync,z as decodeGroupMessagesByIdResponse,O as decodeGroupMessagesByIdResponseAsync,B as decodeGroupOfflineBatch,V as decodeGroupOfflineBatchAsync,k as decodeGroupOfflineSession,K as decodeGroupOfflineSessionAsync,$ as decodeGroupReadAllResponse,N as encodeGroupHistoryRequest,j as encodeGroupMessagesByIdRequest,L as encodeGroupOfflinePullRequest,D as encodeGroupOfflineSessionRequest,H as encodeGroupReadAllRequest};
|
|
1
|
+
import{throwIfAborted as e}from"../abort.js";import{createCryptoBatchPreparation as t}from"./crypto-batch-preparation.js";import{mapIncomingGroupChat as s}from"./group-message-mapper.js";import{mapIncomingGroupNotify as r}from"./group-notify-mapper.js";import{fromWireMsgId as o}from"./message-id.js";import{toWireMessageIds as n,fromWireMissingMessageIds as d}from"./messages-by-id.js";import{mapIncomingGroupReaction as c}from"./reaction-mapper.js";import{groupReadAllMsgReqCodec as i,groupReadAllMsgRespCodec as a,getGroupMsgByIdReqCodec as p,getGroupMsgByIdRespCodec as m,offlineGroupSessionReqCodec as g,offlineGroupSessionRespCodec as u,mesGrpChatCodec as I,mesGrpNotifyDeliverCodec as y,bMessageCodec as l,bContentCodec as f,getGroupHistoryMsgReqCodec as h,getGroupHistoryMsgRespCodec as T,offlineGroupMsgReqCodec as E,offlineGroupMsgRespCodec as M}from"../../../im-protocol/src/protobuf/registry.js";import{CmdId as v}from"../../../im-protocol/src/protobuf/gen/im.pub_pb.js";import{isCryptoExecutionError as w}from"../ports/crypto-task-executor.js";const G=/* @__PURE__ */new Set([v.MES_GRPCHAT_DELIVER,v.MES_GRPCHAT_EDIT_MSG_C2C]),C=l.create({contentType:1,content:""});function L(e){return E.encode(E.create({userId:BigInt(e.userId),msgId:"",deliveredMsgIds:e.deliveredMsgIds??[],limit:e.limit??100,clientType:e.clientType??0}))}function D(e){return g.encode(g.create({userId:BigInt(e.userId),clientType:String(e.clientType??0),size:BigInt(e.size??21)}))}function b(e,t,n,d){if(R(e.sGroupId,t.expectedGroupId),e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER){const s=d?.chat??I.decode(e.sMsgData),r={...s,sMsgId:s.sMsgId||e.sMsgId,sFromId:0n===s.sFromId?e.sFromId:s.sFromId,sGrpId:0n===s.sGrpId?e.sGroupId:s.sGrpId,sToId:0n===s.sToId?e.sGroupId:s.sToId,msgTime:0n===s.msgTime?e.msgTime:s.msgTime,parentMsgId:s.parentMsgId||e.parentMsgId};return R(r.sGrpId,t.expectedGroupId),t.onReaction?.(c(r)),null}if(e.cmdId===v.MES_GRPNOTIFY_DELIVER){const s=d?.notify??y.decode(e.sMsgData);return R(s.sGrpId,t.expectedGroupId),r(s,{selfId:t.selfId,cmdId:e.cmdId,receivedAt:t.receivedAt,keepRaw:t.keepRaw})}if(!G.has(e.cmdId))return null;const i=d?.chat??I.decode(e.sMsgData);R(i.sGrpId,t.expectedGroupId);let a=C,p=!1,m=!1;if(0===i.encrypt)try{a=l.decode(i.sContent)}catch{m=!0}else if(1===i.encrypt&&void 0!==n){const e=function(e,t,s,r){const o=void 0===r?s.resolvePrivateKey({groupId:t,msgType:e.msgType,encrypt:e.encrypt,encryptVersion:e.encryptVersion}):null;if("no-key"===r?.kind||void 0===r&&null===o)return s.onDecryptError?.({msgId:e.sMsgId,groupId:t,fromId:String(e.sFromId),msgType:e.msgType,encrypt:e.encrypt,encryptVersion:e.encryptVersion,reason:"no-key"}),null;try{if("plain"===r?.kind)return l.decode(r.plain);if("failed"===r?.kind)throw r.cause;const t=f.decode(e.sContent);if(0===t.secretKey.length||0===t.cipherData.length)throw new Error(`BContent 字段缺失:secretKey=${t.secretKey.length}B cipherData=${t.cipherData.length}B`);const n=s.crypto.decryptEndToEnd({secretKey:t.secretKey,cipherData:t.cipherData,privateKey:o});return l.decode(n)}catch(r){return s.onDecryptError?.({msgId:e.sMsgId,groupId:t,fromId:String(e.sFromId),msgType:e.msgType,encrypt:e.encrypt,encryptVersion:e.encryptVersion,reason:"decrypt-failed",cause:r}),null}}(i,i.sGrpId.toString(),n,d?.content);a=e??C,p=null===e}else p=!0;const g=s(i,a,{selfId:t.selfId,cmdId:e.cmdId,receivedAt:t.receivedAt,keepRaw:t.keepRaw,decryptFailed:p});return m&&(g.contentType="unknown",g.body={unknown:{reason:"malformed-content"}},g.raw={...g.raw,contentDecodeFailure:{codec:"BMessage",byteLength:i.sContent.length}}),p&&1===i.encrypt&&n?.onDecryptRecovery?.({conversation:{conversationType:"group",conversationId:g.conversationId},messageId:g.id,wireEncrypt:1,sContent:i.sContent.slice(),...""===i.encryptVersion?{}:{encryptVersion:i.encryptVersion},cmdId:e.cmdId,source:t.source??"offline",createdAt:Date.now()}),void 0===g.refMessageId&&e.parentMsgId&&(g.refMessageId=o(e.parentMsgId)),1===e.isEdit&&(g.edited=!0),g}function R(e,t){if(void 0!==t&&e.toString()!==t)throw new Error(`group history: 响应群不属于请求(groupId=${e})`)}function S(t,s){e(t.signal),t.assertCurrent?.(void 0===s?void 0:{conversationType:"group",conversationId:s})}async function _(e){S(e),await e.yieldToEventLoop(),S(e)}function x(e,t){R(e.sGroupId,t);if((G.has(e.cmdId)||e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER||e.cmdId===v.MES_GRPNOTIFY_DELIVER)&&e.sGroupId<=0n)throw new Error("group response: 消息缺少有效群身份");const s={...e.sGroupId>0n?{groupId:e.sGroupId.toString()}:{}};if(G.has(e.cmdId)||e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER){s.chat=I.decode(e.sMsgData);R(e.cmdId===v.MES_GRPCHAT_REACTION_DELIVER&&0n===s.chat.sGrpId?e.sGroupId:s.chat.sGrpId,s.groupId)}else e.cmdId===v.MES_GRPNOTIFY_DELIVER&&(s.notify=y.decode(e.sMsgData),R(s.notify.sGrpId,s.groupId));return s}async function A(e,s,r,o,n,d=[],c=!1){const i=await async function(e,s,r,o=[],n=!0){const d=/* @__PURE__ */new Map,c=/* @__PURE__ */new Map,i=new Set(o);for(const e of o)S(r,e);for(const[t,{item:s,expectedGroupId:o}]of e.entries()){let e;S(r),t>0&&t%5==0&&await _(r);try{e=x(s,o)}catch(e){if(!n)throw e;c.set(t,e);continue}S(r,e.groupId),d.set(t,e),void 0===e.groupId||void 0===e.chat&&void 0===e.notify||i.add(e.groupId)}S(r),void 0!==s&&i.size>0&&void 0!==r.prepareKeys&&(await r.prepareKeys([...i]),S(r));const a=t({...r,assertCurrent:()=>S(r)},(e,t)=>{d.get(e).content=t});for(const[t,{item:o}]of e.entries()){S(r),t>0&&t%5==0&&await _(r);const e=d.get(t);if(void 0===e)continue;S(r,e.groupId);const n=e.chat;if(!G.has(o.cmdId)||1!==n?.encrypt||void 0===s)continue;let i;try{const r=s.resolvePrivateKey({groupId:e.groupId,msgType:n.msgType,encrypt:n.encrypt,encryptVersion:n.encryptVersion});if(null===r)e.content={kind:"no-key"};else try{const e=f.decode(n.sContent);if(0===e.secretKey.length||0===e.cipherData.length)throw new Error("BContent secretKey/cipherData missing");i={itemIndex:t,input:{secretKey:e.secretKey,cipherData:e.cipherData,privateKey:r}}}catch(t){e.content={kind:"failed",cause:t}}}catch(e){if(w(e)||e instanceof Error&&"AbortError"===e.name)throw e;c.set(t,e)}void 0!==i&&await a.add(i),S(r,e.groupId)}return await a.finish(),S(r),{rows:d,errors:c}}(e,r,o,d,n),a=[],p=[],m=[];for(const[t,{item:d,expectedGroupId:g}]of e.entries()){S(o),t>0&&t%5==0&&await _(o);const e=i.rows.get(t);S(o,e?.groupId);try{if(i.errors.has(t))throw i.errors.get(t);const o=b(d,{...s,expectedGroupId:g},r,e);null!==o&&(c&&1===d.isCancel&&(o.recalled={by:o.senderId,at:o.serverTime??o.createdAt},o.body={}),a.push(o)),p.push({msgId:d.sMsgId,msgTime:d.msgTime,cmdId:d.cmdId})}catch(e){if(!n||w(e)||e instanceof Error&&"AbortError"===e.name)throw e;m.push({msgId:d.sMsgId,cmdId:d.cmdId,cause:e})}S(o,e?.groupId)}return S(o),{messages:a,deliveredMsgInfos:p,...0===m.length?{}:{itemErrors:m}}}async function V(e,t,s,r){S(r);const o=M.decode(e);return{...await A(o.msgList.map(e=>({item:e,expectedGroupId:t.expectedGroupId})),t,s,r,!0),batchSize:o.msgList.length,responseBytes:e.length}}function B(e,t,s){const r=M.decode(e),o=[],n=[],d=[];for(const e of r.msgList)try{const r=b(e,t,s);null!==r&&o.push(r),n.push({msgId:e.sMsgId,msgTime:e.msgTime,cmdId:e.cmdId})}catch(t){d.push({msgId:e.sMsgId,cmdId:e.cmdId,cause:t})}return{messages:o,deliveredMsgInfos:n,batchSize:r.msgList.length,responseBytes:e.length,...0===d.length?{}:{itemErrors:d}}}function k(e,t,s){const r=u.decode(e),o=[],n=[],d=[];for(const e of r.sessionList){o.push({groupId:e.groupId.toString(),unreadCount:Number(e.unreadCount)});for(const r of e.msgList)try{const e=b(r,t,s);null!==e&&n.push(e)}catch(e){d.push({msgId:r.sMsgId,cmdId:r.cmdId,cause:e})}}return{unreads:o,messages:n,...0===d.length?{}:{itemErrors:d}}}async function K(e,t,s,r){S(r);const o=u.decode(e),n=[],d=[];for(const e of o.sessionList){R(e.groupId,t.expectedGroupId);const s=e.groupId.toString();S(r,s),n.push({groupId:s,unreadCount:Number(e.unreadCount)}),d.push(...e.msgList.map(e=>({item:e,expectedGroupId:s})))}const{messages:c,itemErrors:i}=await A(d,t,s,r,!0,n.map(e=>e.groupId));return{unreads:n,messages:c,...void 0===i?{}:{itemErrors:i}}}function N(e){return h.encode(h.create({userId:BigInt(e.userId),groupId:BigInt(e.groupId),baseTime:BigInt(e.baseTime),direct:e.direct??1,limit:e.limit??50,clientType:e.clientType??0}))}function F(e,t,s){const r=T.decode(e),o=[];for(const e of r.msgList){const r=b(e,t,s);null!==r&&o.push(r)}const n=r.msgList.map(e=>Number(e.msgTime));return{messages:o,batchSize:r.msgList.length,...0===n.length?{}:{oldestEntryTime:Math.min(...n),newestEntryTime:Math.max(...n)}}}async function P(t,s,r,o,n){e(o.signal);const d=T.decode(t);if(200!==d.code)throw new Error(`group history: code=${d.code}`);if(void 0!==n){const t={...n,assertCurrent:t=>{e(o.signal),n.assertCurrent?.(t)}},{messages:c}=await A(d.msgList.map(e=>({item:e,expectedGroupId:s.expectedGroupId})),s,r,t,!1);let i,a;for(const e of d.msgList){const t=Number(e.msgTime);i=void 0===i?t:Math.min(i,t),a=void 0===a?t:Math.max(a,t)}return{messages:c,batchSize:d.msgList.length,...void 0===i?{}:{oldestEntryTime:i,newestEntryTime:a}}}const c=[];let i,a,p=0;for(const t of d.msgList){e(o.signal),p>0&&p%5==0&&(await o.yieldToEventLoop(),e(o.signal));const n=b(t,s,r);null!==n&&c.push(n);const d=Number(t.msgTime);i=void 0===i?d:Math.min(i,d),a=void 0===a?d:Math.max(a,d),p+=1}return e(o.signal),{messages:c,batchSize:d.msgList.length,...void 0===i?{}:{oldestEntryTime:i,newestEntryTime:a}}}function j(e){return p.encode(p.create({userId:BigInt(e.userId),groupId:BigInt(e.groupId),msgIds:n(e.messageIds),clientType:e.clientType??0}))}function z(e,t,s,r){const o=m.decode(e),n=[];for(const e of o.msgList){const r=b(e,t,s);null!==r&&(1===e.isCancel&&(r.recalled={by:r.senderId,at:r.serverTime??r.createdAt},r.body={}),n.push(r))}return{messages:n,missingMessageIds:d(o.missingMsgIds,r),code:o.code}}async function O(e,t,s,r,o){S(o);const n=m.decode(e),c=d(n.missingMsgIds,r);if(200!==n.code)return{messages:[],missingMessageIds:c,code:n.code};const{messages:i}=await A(n.msgList.map(e=>({item:e,expectedGroupId:t.expectedGroupId})),t,s,o,!1,[],!0);return{messages:i,missingMessageIds:c,code:n.code}}function H(e){return i.encode(i.create({userId:BigInt(e.userId),groupId:BigInt(e.groupId)}))}function $(e){return{code:a.decode(e).code}}export{F as decodeGroupHistoryBatch,P as decodeGroupHistoryBatchAsync,z as decodeGroupMessagesByIdResponse,O as decodeGroupMessagesByIdResponseAsync,B as decodeGroupOfflineBatch,V as decodeGroupOfflineBatchAsync,k as decodeGroupOfflineSession,K as decodeGroupOfflineSessionAsync,$ as decodeGroupReadAllResponse,N as encodeGroupHistoryRequest,j as encodeGroupMessagesByIdRequest,L as encodeGroupOfflinePullRequest,D as encodeGroupOfflineSessionRequest,H as encodeGroupReadAllRequest};
|