OverviewFilesCommitsIssuesDocsReleasesPeers

holepunchto-deps / @holepunchto / keet-core / lib / api / v1 / index.js

1 lines · javascript ref:
const e=require("path"),t=require("ready-resource"),s=require("hypercore-id-encoding"),i=require("hypercore-crypto"),o=require("debounceify"),a=require("safety-catch"),n=require("b4a"),r=require("uncaughts"),{Readable:c,Transform:l,pipeline:h}=require("streamx"),{Session:d,HeapSnapshot:u}=require("bare-inspector"),m=require("bare-fs"),p=require("process-top")(),g=require("tiny-preferences"),b=require("@holepunchto/keet-call/server"),{contract:{hyperschema:{getEnum:y}},local:{hyperschema:{getEnum:f}}}=require("../../../schema/spec"),{encodeRoomRecord:k,encodeConfig:_,encodeDevice:w,encodeMemberRecord:v,encodeInvitationRecord:R,encodeFile:S,encodeIdentityPairingRequest:C,encodeDmRequest:I,encodeReaction:M,encodeUser:K,encodeContactInfo:P,encodeImageFile:q,encodeReservation:D,encodeFileEntry:E,encodeUserSettings:x,encodeErrorRecord:A,encodeNotification:F,encodeHyperDHTSettings:B,encodeSwarmSettings:L,encodeCallRecord:T,encodeLocalActiveCall:U,encodeContact:N,encodePublicRoom:O}=require("./encode.js"),{decodeChatRangeOptions:j,decodeChatMessage:V,decodeMessageId:H,decodeKeyRangeOptions:z,decodeFile:G,decodeConfig:W,decodeImageFile:J,decodeFileRangeOptions:Y,decodeUserSettings:$}=require("./decode.js"),X=y("@keet/build-type"),Q=y("@keet/room-type"),Z=y("@keet/display-type"),ee=y("@keet/label-type"),te=y("@keet/member-label-type"),{ContactRequestStatus:se,RoomStatus:ie}=require("../../core/contract/identity/private.js"),{Config:oe,CONFIG_INDEX_TO_KEY:ae}=require("../../core/contract/config"),{Settings:ne}=require("../../core/contract/internal"),{getChatMessages:re,getChatMessage:ce,getReactions:le,isDMRead:he,roomHasUnread:de,getCalls:ue,loadBlob:me,parallel:pe}=require("./helpers.js"),{MemberStatus:ge}=require("../../core/contract/members/index.js"),{MemberRoles:be,DM_STATUSES:ye,isValidPreferenceKey:fe,getPreferenceKeyName:ke,CHAT_MESSAGE_REPORT_COUNT:_e,GENERIC_EVENTS:we}=require("@holepunchto/keet-core-api"),{restoreAvatar:ve}=require("../../core/contract/avatars.js"),{getMemberForDeviceKey:Re}=require("../../core/contract/query.js"),Se=require("compact-encoding"),{DEBUG_FLAG_INDEX_BY_KEY:Ce,DHT_SETTINGS:Ie,SWARM_SETTINGS:Me}=require("../../core/debug/debugging.js"),{KeetErrorV2:Ke}=require("../../errors"),Pe=require("./inspector.js"),{FEATURES:qe}=require("../../../schema/versions"),{constants:De}=require("rocksdb-native"),Ee=f("@local/keet-state"),xe="recent-rooms",Ae="favorite-rooms",Fe="dm-rooms",Be="chat-changed",Le="identity",Te="private-profile",Ue="members",Ne="migration-status",Oe="room-preferences",je="unreads",Ve="unread-rooms",He="errors",ze="force-updates",Ge="all-active-calls",We={"keet-core":require("../../../package.json").version,autobee:require("autobee/package.json").version,hypercore:require("hypercore/package.json").version,hyperbee:require("hyperbee/package.json").version,hyperbee2:require("hyperbee2/package.json").version,"keet-identity-key":require("keet-identity-key/package.json").version,"keet-push":require("@holepunchto/keet-push/package.json").version,corestore:require("corestore/package.json").version};class Je{constructor(e,t){this.api=e,this.id=t,this.subscriptions=[]}destroy(){for(const{stream:e}of this.subscriptions)e.destroy()}refresh(e){for(const t of this.subscriptions)e&&e.name&&e.name!==t.name||t.query&&t.query()}push(e,t){for(const s of this.subscriptions)t&&t.name&&t.name!==s.name||s.map&&s.stream.push(s.map(e))}_onDestroy(e,t){const s=this.subscriptions.pop();s!==e&&(this.subscriptions[e.idx]=s,s.idx=e.idx),0===this.subscriptions.length&&this.api._subscriptions.get(this.id)===this&&this.api._subscriptions.delete(this.id),t(null)}_create(e){const t={name:e||null,stream:null,query:null,map:null,idx:0};return t.stream=new c({destroy:e=>this._onDestroy(t,e)}),t.idx=this.subscriptions.push(t)-1,t}add({query:e,map:t,name:s}){if(!e&&!t)throw new Error("Must have either a query or a map");const i=this._create(s);return e&&(i.query=o(async()=>{try{const t=await e();null!==t&&i.stream.push(t)}catch(e){i.stream.destroy(e)}}),i.query()),i.map=t,i.stream}}class Ye{constructor(e){this.keet=e}create(e,t){return async(s,...i)=>{if(this.keet.closing)return null;const o=["files","engine","drive","db","snapshot","blobs","blobsSnapshot"],a=!!t.find(e=>o.includes(e));if(a&&!s)throw new Error("Room ID is required for methods that require room resources");("object"==typeof s&&null!==s||!a)&&(i=[s,...i],s=null);const n=s?this.keet.internalOpenExistingRoom(s):null;if(n&&(await n.ready(),await n.engine.flush()),this.keet.closing)return null;const r={roomId:s,roomKey:n?.key||null,discoveryKey:n?.discoveryKey||null};let c=null;try{for(const e of t)n&&"db"===e&&(r.db=n.db),n&&"snapshot"===e&&(r.snapshot=n.db.snapshot()),n&&"blobsSnapshot"===e&&(r.blobsSnapshot=n.blobs?n.blobs.snapshot():null),n&&"engine"===e&&(r.engine=n.engine),n&&"drive"===e&&(r.drive=n.drive),"local"===e&&(r.local=this.keet.local),"localSnapshot"===e&&(r.localSnapshot=this.keet.local.snapshot()),"files"===e&&(r.files=this.keet.files),"myKey"===e&&(this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),r.localSnapshot||(r.localSnapshot=this.keet.local.snapshot()),r.id=await r.localSnapshot.get("@local/identity"),r.profileInfo=await r.localSnapshot.get("@local/rooms",{roomKey:r.id.privateProfileKey}),r.myKey=r.profileInfo?.selfMember?.key||null),"profile"===e&&(this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),r.localSnapshot||(r.localSnapshot=this.keet.local.snapshot()),r.id||(r.id=await r.localSnapshot.get("@local/identity")),r.profileInfo||(r.profileInfo=await r.localSnapshot.get("@local/rooms",{roomKey:r.id.privateProfileKey})),r.profile=this.keet.internalOpenExistingRoom(r.id.privateProfileKey),await r.profile.ready()),r.profile&&"profileDb"===e&&(r.profileDb=r.profile.db),r.profile&&"profileSnapshot"===e&&(r.profileSnapshot=r.profile.db.snapshot()),r.profile&&"profileBlobs"===e&&(r.profileBlobs=r.profile.profileBlobs);const s=Date.now();return c=await e(r,...i),this.keet.logger.debug("[Keet API]",e.name,"duration:",Date.now()-s,"args:",i),c}catch(e){if(this.keet.closing)return null;const t=n?.engine.getLastError();if(t)throw t;throw this.keet.onerror(e),e}finally{r.snapshot&&await r.snapshot.close(),r.blobsSnapshot&&await r.blobsSnapshot.close(),r.localSnapshot&&await r.localSnapshot.close(),r.profileSnapshot&&await r.profileSnapshot.close(),r.profile&&await this.keet.internalReleaseRoom(r.profile),n&&await this.keet.internalReleaseRoom(n)}}}}class $e{constructor(e,{onerror:t=a}={}){this.keet=e,this.context=new Ye(this.keet),this._onerror=t,this._subscriptions=new Map,this._profileSubscriptions=new Je(this,null,{isProfileSub:!0}),this._activeCallStates=new Map,this.keet.on("room-interrupted",this._handleRoomInterrupted.bind(this)),this.keet.on("room-changed",this._handleRoomChanged.bind(this)),this.keet.on("identity-changed",this._handleIdentityChanged.bind(this)),this.keet.on("recent-rooms-changed",this._handleRecentRoomsChanged.bind(this)),this.keet.on("dm-rooms-changed",this._handleDmRoomsChanged.bind(this)),this.keet.on("chat-changed",this._handleChatChanged.bind(this)),this.keet.on("identity-pairing-request",this._handleIdentityPairingRequest.bind(this)),this.keet.on("migration-status",this._handleMigrationStatus.bind(this)),this.keet.on("room-preferences-changed",this._handleRoomPreferencesChanged.bind(this)),this.keet.on("unread-anchors-changed",this._handleUnreadAnchorsChanged.bind(this)),this.keet.on("room-sent-message",this._handleRoomSentMessageLengthChanged.bind(this)),this.keet.on("caught-error",this._handleKeetError.bind(this)),this.keet.on("force-update",this._handleForceUpdate.bind(this)),this.keet.on("verified-rooms-changed",this._handleVerifiedRoomsChanged.bind(this)),this.keet.on("local-files-changed",this._handleLocalFilesChanged.bind(this)),this.keet.on("favorite-rooms-changed",this._handleFavoriteRoomsChanged.bind(this)),this.keet.on("contacts-changed",this._handleContactsChanged.bind(this)),this.keet.on("call-changed",this._handleAllActiveCallsChanged.bind(this)),this.keet.on("call-changed-v3",this._handleAllActiveCallsChanged.bind(this)),this.boot=this._timed(this._boot.bind(this)),this.createInvitation=this._timed(this._createInvitation.bind(this)),this.confirmPairingRequest=this._timed(this._confirmPairingRequest.bind(this)),this.startPairingRoom=this._timed(this._startPairingRoom.bind(this)),this.stopPairingRoom=this.context.create(this._stopPairingRoom.bind(this),["profile"]),this.searchRooms=this.context.create(this._searchRooms.bind(this),["local"]),this.getRoomInfo=this.context.create(this._getRoomInfo.bind(this),["localSnapshot"]),this.getRecentRooms=this.context.create(this._getRecentRooms.bind(this),["local"]),this.getPendingRooms=this.context.create(this._getPendingRooms.bind(this),["profile"]),this.getLocalRoomMetadata=this.context.create(this._getLocalRoomMetadata.bind(this),["local"]),this.getConfig=this.context.create(this._getConfig.bind(this),["snapshot","local"]),this.updateRoomSettings=this._updateRoomSettings.bind(this),this.getChatMessage=this.context.create(this._getChatMessage.bind(this),["snapshot","blobsSnapshot","files","local"]),this.getChatMessageById=this.context.create(this._getChatMessageById.bind(this),["snapshot","blobsSnapshot","files","local"]),this.getChatMessages=this.context.create(this._getChatMessages.bind(this),["snapshot","blobsSnapshot","files","local"]),this.getChatLength=this.context.create(this._getChatLength.bind(this),["db"]),this.removeChatMessage=this.context.create(this._removeChatMessage.bind(this),["snapshot","blobsSnapshot","files","local"]),this.searchChatMessages=this.context.create(this._searchChatMessages.bind(this),["local","snapshot","blobsSnapshot","files"]),this.addChatMessage=this._timed(this._addChatMessage.bind(this)),this.updateChatMessage=this._timed(this._updateChatMessage.bind(this)),this.addFilePreview=this._timed(this._addFilePreview.bind(this)),this.removeFilePreview=this._timed(this._removeFilePreview.bind(this)),this.addLinkPreview=this._timed(this._addLinkPreview.bind(this)),this.removeLinkPreview=this._timed(this._removeLinkPreview.bind(this)),this.forwardChatMessage=this.context.create(this._forwardChatMessage.bind(this),["snapshot","blobsSnapshot","files","local"]),this.pinChatMessage=this._timed(this._pinChatMessage.bind(this)),this.unpinChatMessage=this._timed(this._unpinChatMessage.bind(this)),this.addCallStartedEvent=this._timed(this._addCallStartedEvent.bind(this)),this.addCallHangupEvent=this._timed(this._addCallHangupEvent.bind(this)),this.addCallMissedEvent=this._timed(this._addCallMissedEvent.bind(this)),this.addLocationSharedEvent=this._timed(this._addLocationSharedEvent.bind(this)),this.getActiveCalls=this.context.create(this._getActiveCalls.bind(this),["engine","snapshot"]),this.getAllActiveCalls=this.context.create(this._getAllActiveCalls.bind(this),["localSnapshot"]),this.getCalls=this.context.create(this._getCalls.bind(this),["snapshot"]),this.getReactions=this.context.create(this._getReactions.bind(this),["snapshot","local"]),this.getLatestReactions=this.context.create(this._getLatestReactions.bind(this),["snapshot"]),this.addReaction=this._timed(this._addReaction.bind(this)),this.removeReaction=this._timed(this._removeReaction.bind(this)),this.getReportedMembers=this.context.create(this._getReportedMembers.bind(this),["snapshot","blobsSnapshot","localSnapshot"]),this.addChatReport=this._timed(this._addChatReport.bind(this)),this.removeChatReport=this._timed(this._removeChatReport.bind(this)),this.dismissChatReports=this._timed(this._dismissChatReports.bind(this)),this.getReportedMessages=this.context.create(this._getReportedMessages.bind(this),["roomKey","local","snapshot","blobsSnapshot","files"]),this.getPinnedChatMessages=this.context.create(this._getPinnedChatMessages.bind(this),["local","snapshot","blobsSnapshot","files"]),this.getActiveMember=this.context.create(this._getActiveMember.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.getActiveMembers=this.context.create(this._getActiveMembers.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.getMembers=this.context.create(this._getMembers.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.getMember=this.context.create(this._getMember.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.getMemberCount=this.context.create(this._getMemberCount.bind(this),["db"]),this.getMemberBySwarmId=this.context.create(this._getMemberBySwarmId.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.getMemberByDeviceId=this.context.create(this._getMemberByDeviceId.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.isMemberMuted=this.context.create(this._isMemberMuted.bind(this),["db"]),this.getSearchMembers=this.context.create(this._getSearchMembers.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.updateMember=this._timed(this._updateMember.bind(this)),this.removeMember=this._timed(this._removeMember.bind(this)),this.changeMemberRole=this._timed(this._changeMemberRole.bind(this)),this.muteMember=this._timed(this._muteMember.bind(this)),this.unmuteMember=this._timed(this._unmuteMember.bind(this)),this.blockMember=this._timed(this._blockMember.bind(this)),this.unblockMember=this._timed(this._unblockMember.bind(this)),this.getDevices=this.context.create(this._getDevices.bind(this),["db"]),this.getDevice=this.context.create(this._getDevice.bind(this),["db"]),this.getDevicesByMemberId=this.context.create(this._getDevicesByMemberId.bind(this),["db"]),this.getModerators=this.context.create(this._getModerators.bind(this),["snapshot","blobsSnapshot","localSnapshot","myKey"]),this.saveFile=this.context.create(this._saveFile.bind(this),["files"]),this.saveFileBlob=this.context.create(this._saveFileBlob.bind(this),["files"]),this.getFileEntry=this.context.create(this._getFileEntry.bind(this),["files"]),this.getFileCleared=this.context.create(this._getFileCleared.bind(this),["files"]),this.clearFile=this.context.create(this._clearFile.bind(this),["files"]),this.unclearFile=this.context.create(this._unclearFile.bind(this),["files"]),this.clearAllFiles=this.context.create(this._clearAllFiles.bind(this),["files"]),this.clearOldFiles=this._timed(this._clearOldFiles.bind(this)),this.getLocalFiles=this.context.create(this._getLocalFiles.bind(this),["files","snapshot","blobsSnapshot"]),this.getFiles=this.context.create(this._getFiles.bind(this),["files","snapshot","blobsSnapshot"]),this.startDownload=this.context.create(this._startDownload.bind(this),["files"]),this.cancelDownload=this.context.create(this._cancelDownload.bind(this),["files"]),this.saveToDisk=this.context.create(this._saveToDisk.bind(this),["files"]),this.sendFile=this._timed(this._sendFile.bind(this)),this.sendFiles=this._timed(this._sendFiles.bind(this)),this.refreshFileLinks=this._timed(this._refreshFileLinks.bind(this)),this.createRoom=this._timed(this._createRoom.bind(this)),this.leaveRoom=this._timed(this._leaveRoom.bind(this)),this.getSystemDigest=this.context.create(this._getSystemDigest.bind(this),["db"]),this.getTipSize=this.context.create(this._getTipSize.bind(this),["engine"]),this.getRoomKeys=this._timed(this._getRoomKeys.bind(this)),this.resyncPrivateProfile=this._timed(this._resyncPrivateProfile.bind(this)),this.restoreIdentity=this._timed(this._restoreIdentity.bind(this)),this.getRecoveryPhrase=this._timed(this._getRecoveryPhrase.bind(this)),this.getEncryptedRecoveryPhrase=this._timed(this._getEncryptedRecoveryPhrase.bind(this)),this.decryptEncryptedRecoveryPhrase=this._timed(this._decryptEncryptedRecoveryPhrase.bind(this)),this.freeRecoveryPhrase=this._timed(this._freeRecoveryPhrase.bind(this)),this.confirmRecoveryPhrase=this._timed(this._confirmRecoveryPhrase.bind(this)),this.storeRecoveryPhrase=this._timed(this._storeRecoveryPhrase.bind(this)),this.getIdentity=this.context.create(this._getIdentity.bind(this),["local","profile","profileSnapshot"]),this.getSelfContactInfo=this.context.create(this._getSelfContactInfo.bind(this),["local","profile"]),this.removeIdentityDevice=this.context.create(this._removeIdentityDevice.bind(this),["profile"]),this.createIdentityInvitation=this._timed(this._createIdentityInvitation.bind(this)),this.startPairingIdentity=this._timed(this._startPairingIdentity.bind(this)),this.updateIdentityProfile=this._timed(this._updateIdentityProfile.bind(this)),this.updateIdentityDevice=this._timed(this._updateIdentityDevice.bind(this)),this.getIdentityPairingRequest=this._timed(this._getIdentityPairingRequest.bind(this)),this.updateUserSettings=this._timed(this._updateUserSettings.bind(this)),this.updateDHTSettings=this._timed(this._updateDHTSettings.bind(this)),this.getDHTSettings=this._timed(this._getDHTSettings.bind(this)),this.getSwarmSettings=this._timed(this._getSwarmSettings.bind(this)),this.updateSwarmSettings=this._timed(this._updateSwarmSettings.bind(this)),this.addContact=this._timed(this._addContact.bind(this)),this.setContactAlias=this._timed(this._setContactAlias.bind(this)),this.removeContact=this._timed(this._removeContact.bind(this)),this.getActiveContacts=this.context.create(this._getActiveContacts.bind(this),["localSnapshot"]),this.getContactInfo=this.context.create(this._getContactInfo.bind(this),["local","profile"]),this.getBlockedMembers=this.context.create(this._getBlockedMembers.bind(this),["localSnapshot"]),this.getDmRequestsByStatus=this.context.create(this._getDmRequestsByStatus.bind(this),["localSnapshot","profile","profileDb"]),this.sendDMFromContact=this._timed(this._sendDMFromContact.bind(this)),this.sendDMRequest=this._timed(this._sendDMRequest.bind(this)),this.sendInvitations=this._timed(this._sendInvitations.bind(this)),this.updatePrivateMailboxRecord=this._timed(this._updatePrivateMailboxRecord.bind(this)),this.acceptDmRequest=this._timed(this._acceptDmRequest.bind(this)),this.rejectDmRequest=this._timed(this._rejectDmRequest.bind(this)),this.getRoomPreferences=this.context.create(this._getRoomPreferences.bind(this),["local"]),this.updateRoomPreferences=this.context.create(this._updateRoomPreferences.bind(this),["profile"]),this.snoozeRoom=this.context.create(this._snoozeRoom.bind(this),["profile"]),this.updateConfig=this._timed(this._updateConfig.bind(this)),this.disableMembershipEvents=this._timed(this._disableMembershipEvents.bind(this)),this.enableMembershipEvents=this._timed(this._enableMembershipEvents.bind(this)),this.setRoomUnread=this._timed(this._setRoomUnread.bind(this)),this.getLinkInfo=this._timed(this._getLinkInfo.bind(this)),this.lookupUsername=this._timed(this._lookupUsername.bind(this)),this.lookupUserByMemberId=this._timed(this._lookupUserByMemberId.bind(this)),this.registerUsername=this._timed(this._registerUsername.bind(this)),this.updateUsername=this._timed(this._updateUsername.bind(this)),this.searchUsername=this._timed(this._searchUsername.bind(this)),this.getReservationsByKey=this._timed(this._getReservationsByKey.bind(this)),this.checkUsername=this._timed(this._checkUsername.bind(this)),this.repair=this._timed(this._repair.bind(this)),this.rotateWriter=this._timed(this._rotateWriter.bind(this)),this.audit=this._timed(this._audit.bind(this)),this.setUnread=this._setUnread.bind(this),this.getUnread=this._getUnread.bind(this),this.setUnreadAnchor=this._setUnreadAnchor.bind(this),this.getUnreadAnchor=this._getUnreadAnchor.bind(this),this.subscribeUnreadAnchor=this._subscribeUnreadAnchor.bind(this),this.getUnreadRooms=this.context.create(this._getUnreadRooms.bind(this),["local"]),this.subscribeUnreadRooms=this._subscribeUnreadRooms.bind(this),this.updateTypingIndicator=this.context.create(this._updateTypingIndicator.bind(this),["db"]),this.getTypingIndicator=this.context.create(this._getTypingIndicator.bind(this),["db"]),this.subscribeTypingIndicator=this._subscribeTypingIndicator.bind(this),this.setRoomFavorite=this._setRoomFavorite.bind(this)}_timed(e){return async function(...t){const s=Date.now();try{const i=await e(...t);return this.keet.logger.debug("[Keet API]",e.name,"duration:",Date.now()-s,"args:",t),i}catch(e){throw this.keet.onerror(e),e}}}_boot(){return this.keet.backendReady()}_disableMembershipEvents(e){return this.keet.dispatch(e,"@keet/update-system-settings",{key:ne.IsMembershipEventsDisabled,settings:{isMembershipEventsDisabled:!0}})}_enableMembershipEvents(e){return this.keet.dispatch(e,"@keet/update-system-settings",{key:ne.IsMembershipEventsDisabled,settings:{isMembershipEventsDisabled:!1}})}_addKeetSubscription(e="keet",t){return this._addRoomSubscription(e,t)}_addRoomSubscription(e,t,{isProfileSub:s=!1,_isRoomSub:i=!0}={}){if(null===e&&s)return this._profileSubscriptions.add(t);let o=this._subscriptions.get(e);return o||(o=new Je(this,e),this._subscriptions.set(e,o)),o.add(t)}_refreshSubscriptionsById(e){const t=e===this.keet.privateProfile?.id?this._subscriptions.get(Te):this._subscriptions.get(e);t&&t.refresh()}_handleIdentityPairingRequest(e){this._identityPairingRequestsByDeviceId.set(s.encode(e.deviceKey),e),this._refreshSubscriptionsById("identity-pairing-requests")}_handleRoomInterrupted(e,{unsupportedABI:t,digest:s}){const i=this._subscriptions.get(e);if(i)for(const e of i.subscriptions)"room-version"===e.name&&e.stream.push({version:t,experimental:s&&s.settings.isExperimental})}async _handleRoomChanged(e){try{this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),this._refreshSubscriptionsById(e),this._refreshSubscriptionsById(Ve)}catch(e){this.keet.onerror(e)}}_handleRecentRoomsChanged(...e){const t=this._subscriptions.get(xe);t&&t.push(e)}_handleDmRoomsChanged(){const e=this._subscriptions.get(Fe);e&&e.refresh()}_handleRoomPreferencesChanged(...e){const t=this._subscriptions.get(Oe);t&&(t.push(e),this._refreshSubscriptionsById(Ve))}_handleUnreadAnchorsChanged(){this._refreshSubscriptionsById(je),this._refreshSubscriptionsById(Ve)}_handleAllActiveCallsChanged(e,t,i){let o=null;t&&(o={callId:s.encode(t.callKey),joined:!!i});if(n=o,(a=this._activeCallStates.get(e)||null)&&n?a.callId===n.callId&&a.joined===n.joined:a===n)return;var a,n;o?this._activeCallStates.set(e,o):this._activeCallStates.delete(e);const r=this._subscriptions.get(Ge);r&&r.refresh()}_handleRoomSentMessageLengthChanged(e){const t=this._subscriptions.get(e);t&&t.refresh({name:"room-info"})}_handleIdentityChanged(){this._refreshSubscriptionsById(Le)}async _handleChatChanged(...e){try{this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const t=this._subscriptions.get(Be);if(!t)return;const[s,i]=e;if(s===this.keet.privateProfile.id)return;t.push({roomId:s,index:i})}catch(e){this.keet.onerror(e)}}_handleMigrationStatus(e){const t=this._subscriptions.get(Ne);t&&t.push(e)}_handleKeetError(e){const t=this._subscriptions.get(He);t&&t.push(e)}_handleForceUpdate(){const e=this._subscriptions.get(ze);e&&e.refresh()}_handleVerifiedRoomsChanged(){for(const e of this._subscriptions.values())e.refresh({name:"room-info"})}_handleLocalFilesChanged(e){const t=this._subscriptions.get(e);t&&t.refresh({name:"room-info"})}_handleFavoriteRoomsChanged(...e){const t=this._subscriptions.get(Ae);t&&t.push(e)}_handleContactsChanged(){for(const e of this._subscriptions.values())e.refresh({name:Ue})}getVersion(){return{buildType:this.keet.buildType,abi:this.keet.abi,modules:We}}async _getSystemDigest({db:e}){return await e.get("@keet/system-digest")}subscribeSentLength(e){return this._addRoomSubscription(e,{query:async()=>{const t=this.keet.internalOpenExistingRoom(e);await t.ready();const s={deviceId:t.engine.local.id,length:t.engine.local.remoteContiguousLength};return this.keet.internalReleaseRoom(t),s},name:"room-sent-message"})}subscribeRoomVersion(e){return this._addRoomSubscription(e,{query:async()=>{const t=await this.getSystemDigest(e);return{version:t.abi.version,experimental:t.settings.isExperimental}},name:"room-version"})}subscribeForceUpdates(){return this._addKeetSubscription(ze,{query:()=>({showBanner:this.keet.shouldForceUpdate()})})}async upgradeRoom(e){this.keet.opened||await this.keet.ready();const t=this.keet.isNightly?this.keet.abi.max:this.keet.abi.production;await this.keet.internalDispatchUpgrade(e,t)}async _getLinkInfo(e){const t=this.keet.internalGetLinkInfo(e);if(!t)return null;if(t.identity)return{isIdentityInvitation:!0,memberId:s.encode(t.identity.identityPublicKey),invitationSeed:s.encode(t.identity.invitationSeed),additionalNodes:t.additionalNodes};if(t.room){const e={capabilities:{mailboxKeyPair:{publicKey:t.room.mailbox}}},i=await this.keet.local.get("@local/rooms-by-mailbox",e);return{isRoomInvitation:!0,roomId:i?s.encode(i.roomKey):null,title:i?i.config.title:null,description:i?i.config.description:null,avatar:i?q(i.config.avatar):null,invitationSeed:s.encode(t.room.invitationSeed),additionalNodes:t.additionalNodes}}return t.profile?{isContactInfo:!0,memberId:s.encode(t.attestation.memberKey),displayName:t.profile.displayName,username:t.profile.username,additionalNodes:t.additionalNodes}:t.readonly||t["readonly-v2"]?{isReadOnly:!0,additionalNodes:t.additionalNodes}:void 0}async _getSelfContactInfo({id:e,profileInfo:t}){const s=this.keet.internalCreateContactInfoStruct(e,t,{avatar:null,timestamp:0});return n.toString(s,"base64")}async _getIdentity({id:e,profile:t,profileSnapshot:i,profileInfo:o}){const[a,n]=await Promise.all([i.find("@keet/devices").toArray(),i.get("@keet-private-id/settings")]),r=[];for(const e of a)e.status.isActive&&r.push({...w(e),confirmed:!0});const c=v(o.selfMember,o.selfMember.key);return c.hasDiscoveryKey=!!o.identity.discoveryCoreKey,c.anonymous=!1,c.confirmed=e.status.isConfirmed,c.devices=r,c.profileId=t.id,c.profileDiscoveryId=t.discoveryId,c.local={deviceId:s.encode(t.deviceKey)},c.settings=x(n),c.isLoggedOut=o.selfDevice&&!o.selfDevice.status.isActive,c.version=o?.digest.abi.version,c}_removeIdentityDevice({profile:e},t){return e.dispatch("@keet/remove-device",{key:s.decode(t)})}subscribeIdentity(){return this._addKeetSubscription(Le,{query:()=>this.getIdentity()})}async _restoreIdentity(e,t={}){await this.keet.restoreIdentity(e,t)}_getRecoveryPhrase(){return this.keet.getRecoveryPhrase()}_getEncryptedRecoveryPhrase(e){return this.keet.getEncryptedRecoveryPhrase(e)}_decryptEncryptedRecoveryPhrase(e,t){return this.keet.decryptEncryptedRecoveryPhrase(e,t)}_freeRecoveryPhrase(e){return this.keet.freeRecoveryPhrase(e)}_confirmRecoveryPhrase(e){return this.keet.confirmRecoveryPhrase(e)}_storeRecoveryPhrase(e){return this.keet.storeRecoveryPhrase(e)}confirmIdentity(...e){throw console.log("confirmIdentity",...e),new Error("Missing required method: confirmIdentity")}async _confirmPairingRequest({deviceId:e},t=!0){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const i=this.keet.privateProfile.key,o=s.decode(e);return t?this.keet.acceptJoinRequest(i,o):this.keet.rejectJoinRequest(i,o)}async _getIdentityPairingRequest(){const e=await this.keet.internalOpenPrivateProfile(),t=await e.db.find("@keet/join-requests").toArray();return this.keet.internalReleaseRoom(e),0===t.length?null:C(t[0])}subscribeIdentityPairingRequests(...e){return this._addKeetSubscription(Le,{query:()=>this.getIdentityPairingRequest()})}async _updateIdentityProfile({displayName:e,avatar:t}){await this.updateMember(e,t)}_updateIdentityDevice(e){return this.keet.updateDevice(e)}_startPairingIdentity(e){return this.keet.startPairingIdentity(e)}pairIdentity(...e){throw console.log("pairIdentity",...e),new Error("Missing required method: pairIdentity")}async _updateUserSettings(e,t){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const s={[e]:t};return this.keet.privateProfile.dispatch("@keet-private-id/update-settings",{key:e,settings:$(s)})}async _getDHTSettings(){const e=await this.keet.getDHTSettings();return B(e)}async _updateDHTSettings(e,t){if(!(e in Ie))throw Ke.INVALID_SETTINGS_KEY(`Invalid DHT settings key: ${e}`);const s=await this.keet.internalEnterLocalTransaction();try{const i=await this.keet.getDHTSettings();i[e]=t,await s.insert("@local/hyperdht",i),await s.flush()}finally{await this.keet.internalExitLocalTransaction()}}async _getSwarmSettings(){const e=await this.keet.getSwarmSettings();return L(e)}async _updateSwarmSettings(e,t){if(!(e in Me))throw Ke.INVALID_SETTINGS_KEY(`Invalid swarm settings key: ${e}`);const s=await this.keet.internalEnterLocalTransaction();try{const i=await this.keet.getSwarmSettings();i[e]=t,await s.insert("@local/hyperswarm",i),await s.flush()}finally{await this.keet.internalExitLocalTransaction()}}async _createRoom(e={}){const t=await this.keet.createRoom(function(e={}){return{config:{title:e.config?.title,description:e.config?.description},settings:{roomType:at(e.config?.roomType),isCallingDisabled:"false"===e.config?.canCall}}}(e));return s.encode(t)}_pairRoom(...e){throw console.log("pairRoom",...e),new Error("Missing required method: pairRoom")}_leaveRoom(e,t={}){return this.keet.leaveRoom(s.decode(e))}async _startPairingRoom(e,t={}){return await this.keet.startPairingRoom(e,t)}async _stopPairingRoom({profile:e},t){const i=s.decode(t),o=await e.db.find("@keet-private-id/pending-invitations").toArray();for(const e of o)if(n.equals(e.invitationSeed,i)){await this.keet.stopPairing(e.id);break}}subscribePendingRooms(){return this._addKeetSubscription(Le,{query:()=>this.getPendingRooms()})}subscribePushNotificationChanges(){return this._addKeetSubscription(Oe,{map:function(e){const[t,o,a]=e,n=a||i.discoveryKey(o);return{type:t,roomId:s.encode(o),discoveryId:s.encode(n)}}})}subscribeActivateRoom(e){const t=s.decode(e);return new c({eagerOpen:!0,open:async e=>{let s=null;try{await this.keet.activateRoom(t)}catch(e){s=e}e(s)},destroy:async e=>{let s=null;try{await this.keet.deactivateRoom(t)}catch(e){s=e}e(s)}})}_getRoomKeys(e){try{const t=s.decode(e);return{discoveryKey:n.toString(i.discoveryKey(t),"hex")}}catch{return{discoveryKey:""}}}_getTipSize({engine:e}){return e.tipSize}async _resyncPrivateProfile(){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),await this.keet.internalResyncPrivateProfile()}bookmark(...e){throw console.log("bookmark",...e),new Error("Missing required method: bookmark")}unbookmark(...e){throw console.log("unbookmark",...e),new Error("Missing required method: unbookmark")}subscribeBookmarks(...e){return console.log("subscribeBookmarks",...e),new c}async _loadRecents(e,t={}){const{index:s,range:i}=function(e){return e.favorites?{index:"@local/rooms-by-favorite-and-timestamp",range:{}}:e.default||e.dms||e.broadcast?{index:"@local/rooms-by-type-and-timestamp",range:{lte:{type:n(e)},gte:{type:n(e)}}}:{index:"@local/rooms-by-timestamp",range:{}}}(t),o=await e.find(s,{...t,...i,reverse:!0}).toArray(),a=await Promise.all(o.map(t=>e.get("@local/room-preferences",{roomKey:t.roomKey})));for(let e=0;e<a.length;e++){const t=a[e];t&&!t.status.isActive&&(o[e]=null)}return o;function n(e){return e.default?Q.Default:e.dms?Q.DirectMessage:e.broadcast?Q.Broadcast:void 0}}async _getRoomInfo({localSnapshot:e},t){const o=s.decode(t),a=await e.get("@local/rooms",{roomKey:o});if(!a)return null;let n=v(a.lastMember);const[r,c,l]=await Promise.all([e.get("@local/room-preferences",{roomKey:a.roomKey}),a.lastMessage&&!n?e.get("@local/devices",{device:{key:a.lastMessage.oplog.key}}):null,e.get("@local/file-stats",{roomKey:a.roomKey})]);if(c){const t=await e.get("@local/members",{key:c.device.memberKey});t&&(n={id:s.encode(t.key),memberId:s.encode(t.key),displayName:t.profile.displayName})}if(a.lastMessage){const e=he(a,a.lastMessage.id);a.lastMessage.read=e}if(a.lastMessage?.event?.memberRemoved){const t=await e.get("@local/members",{key:a.lastMessage.event.memberRemoved.memberKey}),s=t?.profile?.displayName;a.lastMessage.event.memberRemoved.displayName=s}const h=a.selfDevice?i.discoveryKey(a.selfDevice.key):null,d=h?await this.keet.storage.getInfo(h,{hints:!0,auth:!1,head:!1}):null,u=k({roomInfo:a,preferences:r,lastMessageMember:n,storageInfo:d,fileStats:l});return u.isVerified=this.keet.isRoomVerified(t),u}async _searchRooms({local:e}){const t=await this._loadRecents(e),i=[];for(const e of t)e&&i.push({title:e.config.title,roomId:s.encode(e.roomKey)});return i}searchPublicRooms(e,t){return c.from(this._searchPublicRooms(e,t))}async*_searchPublicRooms(e=[],t={}){if(!this.keet.roomRegistry)return;const s=this.keet.local.snapshot();try{for await(const s of this.keet.roomRegistry.search(e)){const e=await i(s.roomKey);t.unjoined&&e||(this.keet.buildType===X.Nightly&&(s.invitation=null),yield O(s,e))}}finally{await s.close()}async function i(e){const t=await s.get("@local/rooms",{roomKey:e});return!!t&&!t.status.isRemoved}}async _getRecentRooms({local:e},t){const[i,o]=await Promise.all([this._loadRecents(e,t),e.get("@local/stats")]),a=[];for(const e of i)e&&a.push({timestamp:e.timestamps.latestChatMessage||e.timestamps.latestSync,roomId:s.encode(e.roomKey)});return{type:"all",total:o?o.activeRooms:0,rooms:a}}async _getPendingRooms({profile:e}){return(await e.db.find("@keet-private-id/pending-invitations").toArray()).map(R)}_getLocalRoomMetadata({local:e},t){return e.get("@local/rooms",{discoveryKey:s.decode(t)})}subscribeRecentRooms(e){return this._addKeetSubscription(xe,{map:function(e){const[t,s,i]=e;return{type:t,timestamp:s,roomId:i}},query:()=>this.getRecentRooms(e)})}subscribeFavoriteRooms(){return this._addKeetSubscription(Ae,{map:function(e){const[t,s,i]=e;return{type:t,timestamp:s,roomId:i}},query:()=>this.getRecentRooms({favorites:!0})})}subscribeRoomInfo(e,t){return this._addRoomSubscription(e,{query:()=>this.getRoomInfo(e,t),name:"room-info"})}subscribeUnreadActivity(e={}){return this._addKeetSubscription(Be,{map:({roomId:t,index:s})=>t?e.includeLength||e.includeIndex?{roomId:t,index:s}:{roomId:t}:null})}subscribeErrors(){return this._addKeetSubscription(He,{map:e=>A(e)})}subscribeNotifications(){const e=this.subscribeUnreadActivity({includeIndex:!0}),t=c.from(this._subscribeNotifications(e));return t.once("close",()=>{e.destroy()}),t}setCallRingingId(e){this._callRingingRoomId=e}setProcessingNotifications(e){this._processingNotifications=e}async*_subscribeNotifications(e){for await(const{roomId:i,index:o}of e){if(this.keet.closing)return;if(this._callRingingRoomId){if(i!==this._callRingingRoomId)continue;const e=await this.getChatMessage(i,o);if(this.keet.closing)return;e?.event?.type===we.CALL_HANGUP&&(yield{type:we.CALL_HANGUP})}if(this._processingNotifications)continue;const e=await this.keet.local.get("@local/room-preferences",{roomKey:s.decode(i)});if(this.keet.closing)return;const a=e?.status.isFullyMuted||!1,n=(e?.status.roomSnoozeTime||0)>Date.now();if(a||n||this._processingNotifications)continue;const[r,c,l]=await Promise.all([this.getConfig(i),this.getChatMessage(i,o),this.keet.local.get("@local/identity")]);if(this.keet.closing)return;if(!c||Math.abs(Date.now()-c.timestamp)>6e5)continue;const h=await this.getBlockedMembers();if(this.keet.closing)return;if(h.some(e=>e.memberId===c.memberId)||this._processingNotifications)continue;if(l&&s.encode(l.publicKey)===c.memberId)continue;const{settings:d}=await this.keet.local.get("@local/rooms",{roomKey:l.privateProfileKey});if(this.keet.closing)return;if((d?.profileSnoozeTime||0)>Date.now())continue;const u=`${c.id.deviceId}/b${c.id.seq}`,m=t(c),p=c.files.length>0&&c.files[0].metadata?.mimetype||"",g=await this.getMember(i,c.memberId);if(this.keet.closing)return;const b=c.chat?.text||"",y=at(r.roomType)===Q.DirectMessage;if(!this._processingNotifications&&(b||m)){if(y&&"call"===m){if(Math.abs(Date.now()-c.timestamp)>2e4)continue;if(!(await this.getActiveCalls(i)).length)continue;yield{type:we.CALL_STARTED}}const e=await this.getRoomInfo(i);if(this.keet.closing)return;const t=e?.config?.avatar?.small?.pointer?.inlined??"",s=c.message?.generic?.locationShared;yield F({messageId:u,roomId:i,avatar:t,location:s,messageText:b,messageType:m,fileType:p},r,g)}}function t(e){return e.event?.type===we.CALL_STARTED?"call":e.files?.length>0?"file":e.message?.generic?.locationShared?"location":""}}async _setRoomUnread(e,t=!0){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const{privateProfileKey:i}=await this.keet.local.get("@local/identity");await this.keet.local.get("@local/rooms",{roomKey:i})&&await this.keet.privateProfile.dispatch("@keet-private-id/update-room-status",{roomKey:s.decode(e),key:ie.IsUnread,status:{isUnread:t}})}async _snoozeRoom({profile:e},t,i=0){await e.dispatch("@keet-private-id/update-room-status",{roomKey:s.decode(t),key:ie.RoomSnoozeTime,status:{roomSnoozeTime:i}})}bumpRoomPriority(...e){throw console.log("bumpRoomPriority",...e),new Error("Missing required method: bumpRoomPriority")}addDevice(...e){throw console.log("addDevice",...e),new Error("Missing required method: addDevice")}removeDevice(...e){throw console.log("removeDevice",...e),new Error("Missing required method: removeDevice")}async _getDevice({db:e},t){const s=await e.findOne("@keet/devices",z({gte:t,lte:t}));return s?w(s):null}async _getDevices({db:e},t){return(await e.find("@keet/devices",z(t)).toArray()).map(e=>w(e))}async moveIndexer(e,t,i){const o=s.decode(t),a=s.decode(i);return this.keet.dispatch(e,"@keet/move-indexer",{deviceKey:o,fromDeviceKey:a})}subscribeDevice(e,...t){return this._addRoomSubscription(e,{query:()=>this.getDevice(e,...t)})}subscribeDevices(e,...t){return this._addRoomSubscription(e,{query:()=>this.getDevices(e,...t)})}async _createIdentityInvitation(){return this.keet.createIdentityInvitation()}_createInvitation(e,t={}){return!0===t.canIndex&&(t.canAdmin=!0),this.keet.createRoomInvitation(s.decode(e),t)}async _updateMember(e,t){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const i=await this.keet.local.get("@local/identity");if(i&&s.encode(i.privateProfileKey))return t=J(t),this.keet.updateProfile({displayName:e,avatar:t})}async _muteMember(e,t){const i=s.decode(t);return this.keet.dispatch(e,"@keet/change-member-status",{memberKey:i,key:ge.IsMuted,status:{isMuted:!0}})}async _unmuteMember(e,t){const i=s.decode(t);return this.keet.dispatch(e,"@keet/change-member-status",{memberKey:i,key:ge.IsMuted,status:{isMuted:!1}})}async _isMemberMuted({db:e},t){const i=s.decode(t);return!!await e.get("@keet/muted-members",{key:i})}async _getMemberByDeviceId({myKey:e,snapshot:t,blobsSnapshot:i,localSnapshot:o},a){const n=await Re(t,s.decode(a));if(!n)return null;const r=!!await o.get("@local/active-contacts",{memberKey:n.key});return await ve(t,i,n.profile.avatar),await ct(t,n),v(n,e,r)}async _getMemberBySwarmId({myKey:e,snapshot:t,blobsSnapshot:i,localSnapshot:o},a){const n=s.decode(a),r=await t.get("@keet/devices-by-swarm-key",{profile:{swarmKey:n}});if(!r)return null;const c=await Re(t,r.key);if(!c)return null;const l=!!await o.get("@local/active-contacts",{memberKey:c.key});return await ve(t,i,c.profile.avatar),await ct(t,c),v(c,e,l)}async _getMemberCount({db:e}){const t=await e.get("@keet/threads",{id:0});return t?t.stats.members.active:0}async _getDevicesByMemberId({db:e},t){const i=[],o=s.decode(t),a={gte:{memberKey:o},lte:{memberKey:o}};for await(const t of e.find("@keet/devices-by-member-key",a))i.push(w(t));return i}getCurrentDeviceId(e){const t=this.keet.internalOpenExistingRoom(e);try{return t.deviceId}finally{this.keet.internalReleaseRoom(t)}}async _getMember({roomId:e,myKey:t,snapshot:i,blobsSnapshot:o,localSnapshot:a},n,r={}){const c=s.decode(n);if(!0===r.swarmId)return this.getMemberBySwarmId(e,n);const l=await i.get("@keet/members",{key:c});if(!l)return null;const h=!!await a.get("@local/active-contacts",{memberKey:l.key});return await ve(i,o,l.profile.avatar),await ct(i,l),v(l,t,h)}async _getActiveMember({myKey:e,snapshot:t,blobsSnapshot:i,localSnapshot:o},a){const n=await t.get("@keet/active-members",{key:s.decode(a)});if(!n)return null;const r=!!await o.get("@local/active-contacts",{memberKey:n.key});return await ve(t,i,n.profile.avatar),await ct(t,n),v(n,e,r)}async _removeMember(e,t){const i=s.decode(e);if(await this.keet.local.get("@local/rooms",{roomKey:i}))return this.keet.dispatch(e,"@keet/remove-member",{key:s.decode(t)})}async _getMembers({myKey:e,snapshot:t,blobsSnapshot:s,localSnapshot:i},o={}){const a=await t.find("@keet/members",z(o)).toArray();return Promise.all(a.map(async o=>{const a=!!await i.get("@local/active-contacts",{memberKey:o.key});return await ve(t,s,o.profile.avatar),await ct(t,o),v(o,e,a)}))}async _getActiveMembers({myKey:e,snapshot:t,blobsSnapshot:s,localSnapshot:i},o={}){const a=await t.find("@keet/active-members",z(o)).toArray();return Promise.all(a.map(async o=>{const a=!!await i.get("@local/active-contacts",{memberKey:o.key});return await ve(t,s,o.profile.avatar),await ct(t,o),v(o,e,a)}))}async _getModerators({myKey:e,snapshot:t,blobsSnapshot:s,localSnapshot:i},o={}){const a=await t.find("@keet/moderators",z(o)).toArray();return Promise.all(a.map(async o=>{const a=!!await i.get("@local/active-contacts",{memberKey:o.key});return await ve(t,s,o.profile.avatar),await ct(t,o),v(o,e,a)}))}getMemberForDevice(...e){throw console.log("getMemberForDevice",...e),new Error("Missing required method: getMemberForDevice")}subscribeMemberCount(e,...t){return this._addRoomSubscription(e,{query:()=>this.getMemberCount(e,...t),name:Ue})}subscribeMember(e,...t){return this._addRoomSubscription(e,{query:()=>this.getMember(e,...t),name:Ue})}subscribeActiveMember(e,...t){return this._addRoomSubscription(e,{query:()=>this.getActiveMember(e,...t),name:Ue})}subscribeActiveMembers(e,...t){return this._addRoomSubscription(e,{query:()=>this.getActiveMembers(e,...t),name:Ue})}subscribeMembers(e,...t){return this._addRoomSubscription(e,{query:()=>this.getMembers(e,...t),name:Ue})}subscribeModerators(e,...t){return this._addRoomSubscription(e,{query:()=>this.getModerators(e,...t),name:Ue})}subscribeMemberForDevice(e,...t){return this._addRoomSubscription(e,{query:()=>this.getMemberByDeviceId(e,...t),name:Ue})}_changeMemberRole(e,{memberId:t,role:i}){return this.keet.dispatch(e,"@keet/change-member-role",{key:s.decode(t),isAdmin:i===be.ADMIN,isModerator:i===be.ADMIN||i===be.MODERATOR})}async _getSearchMembers({myKey:e,snapshot:t,blobsSnapshot:s,localSnapshot:i},o,{limit:a=50}={}){o=o.toLowerCase();const n=await t.find("@keet/members-by-member-name",{gte:{name:o},limit:a}).toArray();return(await Promise.all(n.map(async o=>{const a=!!await i.get("@local/active-contacts",{memberKey:o.key});return await ve(t,s,o.profile.avatar),await ct(t,o),v(o,e,a)}))).filter(e=>e.name.startsWith(o))}getPushNotificationMembers(...e){throw console.log("getPushNotificationMembers",...e),new Error("Missing required method: getPushNotificationMembers")}subscribeSearchMembers(...e){return console.log("subscribeSearchMembers",...e),new c}subscribePushNotificationMembers(...e){return console.log("subscribePushNotificationMembers",...e),new c}async _addContact(e,t,i){const o=s.decode(e);await this.keet.addContact(o,t,i)}async _setContactAlias(e,t){const i=s.decode(e);await this.keet.setContactAlias(i,t)}async _removeContact(e){const t=s.decode(e);await this.keet.removeContact(t)}async _getActiveContacts({localSnapshot:e}){return pe(e.find("@local/active-contacts"),async t=>{const s=await e.get("@local/members",{key:t.memberKey});return N(t,s)})}subscribeActiveContacts(){return this._addRoomSubscription(Te,{query:()=>this.getActiveContacts()})}async _getContactInfo({local:e,profile:t},i){const o=s.decode(i),[a,n,r]=await Promise.all([e.get("@local/contacts",{memberKey:o}),e.findOne("@local/rooms-by-contact",{gte:{contact:o},lte:{contact:o}}),t.db.findOne("@keet-private-id/pending-contact-requests-by-member",{gte:{memberKey:o},lte:{memberKey:o}})]);return P(i,a,n,r)}subscribeContactInfo(e){return this._addRoomSubscription(Fe,{query:async()=>{const t=this.keet.local.snapshot();try{const i=s.decode(e),[o,a]=await Promise.all([t.get("@local/contacts",{memberKey:i}),t.findOne("@local/rooms-by-contact",{gte:{contact:i},lte:{contact:i}})]);return P(e,o,a,null)}finally{await t.close()}}})}async _blockMember(e,t){const i=s.decode(t);return this.keet.blockContact(i)}async _unblockMember(e,t){const i=s.decode(t);return this.keet.unblockContact(i)}async _getBlockedMembers({localSnapshot:e}){return pe(e.find("@local/blocked-contacts"),async e=>N(e))}subscribeBlockedMembers(){return this._addRoomSubscription(Te,{query:()=>this.getBlockedMembers()})}getConnectedMembers(...e){throw console.log("getConnectedMembers",...e),new Error("Missing required method: getConnectedMembers")}subscribeConnectedMembers(...e){return console.log("subscribeConnectedMembers",...e),new c}async _updateConfig(e,t,s){const i=function(e){switch(e){case"title":return oe.Title;case"avatar":return oe.Avatar;case"description":return oe.Description;case"supportedLanguages":return oe.SupportedLanguages;case"blindPeers":return oe.BlindPeers;default:return 0}}(t);if(0!==i){const t={[ae[i-1]]:s};await this.keet.dispatch(e,"@keet/update-room-config",{key:i,config:W(t)})}else if("roomType"===t){const t=at(s);if(0===t)throw new Error("Invalid room type");await this.keet.dispatch(e,"@keet/update-system-settings",{key:ne.RoomType,settings:{roomType:t}})}else{if("canCall"!==t)throw new Error("Invalid config key");await this.keet.dispatch(e,"@keet/update-system-settings",{key:ne.IsCallingDisabled,settings:{isCallingDisabled:"false"===s}})}}async _updateRoomPreferences({profile:e},t,i,o){if(!fe(i))throw new Error(`invalid preference key: ${i}`);const a=s.decode(t);await this.keet.dispatch(e.id,"@keet-private-id/update-room-status",{roomKey:a,key:ot(i),status:{[ke(i)]:o}})}async _updateRoomSettings(e,t,i){const o=s.decode(e);return this.keet.dispatch(o,"@keet/update-system-settings",{key:t,settings:i})}async _getRoomSettings(e){const t=s.decode(e),i=this.keet.internalOpenExistingRoom(t);try{return(await i.db.get("@keet/system-digest")).settings}finally{this.keet.internalReleaseRoom(i)}}async _getRoomPreferences({local:e},t,i){const o=s.decode(t),a=await e.get("@local/room-preferences",{roomKey:o});if(!a)return null;const{status:n}=a;return fe(i)?i?n[ke(i)]:n:null}async _getConfig({roomKey:e,local:t},s){const i=await t.get("@local/rooms",{roomKey:e});if(!i)return null;const{config:o,digest:a}=i,n=_(o,a)||{};return s?n[s]:n}subscribeConfig(e){return this._addRoomSubscription(e,{query:()=>this.getConfig(e)})}async _addChatMessage(e,t,i={}){const o=s.decode(e);if(!await this.keet.local.get("@local/rooms",{roomKey:o}))return;const a=V(t,i),n=nt(a),r=this.keet.batch(e);return 0!==await r.dispatch("@keet/add-chat-message",{timestamp:Date.now(),message:a})?((n.files.length||n.pearLink.length||n.httpLink.length)&&await rt(r,n),await r.flush()):void 0}async _updateChatMessage(e,t,i,o={}){const a=s.decode(e);if(!await this.keet.local.get("@local/rooms",{roomKey:a}))return;const n=H(t),r=V(i,o),c=nt(r),l=this.keet.batch(e);0!==await l.dispatch("@keet/update-chat-message",{oplog:n,message:r})&&((c.files.length||c.pearLink.length||c.httpLink.length)&&await rt(l,c,n),await l.flush())}async _addFilePreview(e,t,s,i,o={}){const a=J(i);if(a)return this.keet.dispatch(e,"@keet/add-file-preview",{oplog:H(t),index:s,preview:a,displayType:o.displayType})}async _removeFilePreview(e,t,s,i={}){if(!await this.keet.internalFeatureSupported(e,qe.PREVIEWS))throw new Error("Removing file previews not supported");return this.keet.dispatch(e,"@keet/remove-file-preview",{oplog:H(t),index:s,displayType:i.displayType})}async _addLinkPreview(e,t,s,i,o){if(s&&o){if(!await this.keet.internalFeatureSupported(e,qe.PREVIEWS))throw new Error("Adding link previews not supported");return this.keet.dispatch(e,"@keet/add-link-preview",{oplog:H(t),displayType:s,index:i,preview:{title:o.title,description:o.description,file:G(o.file)}})}}async _removeLinkPreview(e,t,s,i){if(s){if(!await this.keet.internalFeatureSupported(e,qe.PREVIEWS))throw new Error("Removing link previews not supported");return this.keet.dispatch(e,"@keet/remove-link-preview",{oplog:H(t),displayType:s,index:i})}}async _removeChatMessage({roomKey:e,local:t,roomId:s,snapshot:i,blobsSnapshot:o,files:a},n){const r=await this._getChatMessageById({roomKey:e,local:t,snapshot:i,blobsSnapshot:o,files:a},n);if(!r)return null;if(r.files.length){const t=[];for(const s of r.files)t.push(this._clearFile({roomKey:e,files:a},s));await Promise.all(t)}return this.keet.dispatch(s,"@keet/remove-chat-message",{oplog:H(n)})}async _forwardChatMessage({roomKey:e,local:t,roomId:i,snapshot:o,blobsSnapshot:a,files:n},r,c){const[l,h]=await Promise.all([this.keet.local.get("@local/rooms",{roomKey:e}),this.keet.local.get("@local/rooms",{roomKey:s.decode(c)})]);if(!l||!h)return;const d=await o.get("@keet/chat-by-message-id",{oplog:H(r)});if(!d)throw new Error("Source message not found");if(!d.message.text)throw new Error("Source message has no text");const u=d.message.display||{};for(const e of u.httpLink||[])e.preview=null;for(const e of u.pearLink||[])e.preview=null;const m={text:d.message.text,forwarded:!0,files:[],display:u,replyTo:null,event:null};return this.keet.dispatch(c,"@keet/add-chat-message",{timestamp:Date.now(),message:m})}_pinChatMessage(e,t){return this.keet.dispatch(e,"@keet/pin-chat-message",{oplog:H(t),isPinned:!0})}_unpinChatMessage(e,t){return this.keet.dispatch(e,"@keet/pin-chat-message",{oplog:H(t),isPinned:!1})}async startCall(e,t={}){if(!await this.keet.internalFeatureSupported(e,qe.CALLS_V2))return this.addCallStartedEvent(e);if(3!==t.version)throw new Error("Only calls v3 is supported");if(!t.streams)throw new Error("Streams are required");if((await this._getRoomSettings(e)).isCallingDisabled)throw Ke.CALL_DISABLED();if(!await this.keet.internalFeatureSupported(e,qe.CALLS_V3))throw new Error("Calls v3 is not supported");return this.keet.internalStartCall(e,t.streams)}async joinCall(e,t,{version:s,streams:i=[]}={}){if(await this.keet.internalFeatureSupported(e,qe.CALLS_V2)){if(3!==s)throw new Error("Only calls v3 is supported");if(!i.length)throw new Error("Streams are required");if(!await this.keet.internalFeatureSupported(e,qe.CALLS_V3))throw new Error("Calls v3 is not supported");return this.keet.internalJoinCall(e,t,i)}}async leaveCall(e,t){if(await this.keet.internalFeatureSupported(e,qe.CALLS_V2))return this.keet.internalLeaveCall(e,t)}async endCall(e,t){if(!await this.keet.internalFeatureSupported(e,qe.CALLS_V2)){const t=s.decode(e);if(!(await this.keet.local.get("@local/rooms",{roomKey:t})).dm)return;return this.addCallHangupEvent(e)}return this.keet.internalEndCall(e,t)}async addCallStream(e,t,o){if(!await this.keet.internalFeatureSupported(e,qe.CALLS_V2))throw new Error("Calls v2 is not supported");return this.keet.dispatch(e,"@keet/add-call-stream",{callKey:s.decode(t),streamKey:o.id?s.decode(o.id):i.randomBytes(32),mediaStreamId:o.mediaStreamId,type:o.type,muted:o.muted??!1})}async updateCallStream(e,t,i,{muted:o}){if(!await this.keet.internalFeatureSupported(e,qe.CALL_STREAM_STATUS))throw new Error("Call stream status is not supported");return this.keet.dispatch(e,"@keet/update-call-stream",{callKey:s.decode(t),streamKey:s.decode(i),muted:o})}async removeCallStream(e,t,i){if(!await this.keet.internalFeatureSupported(e,qe.CALLS_V2))throw new Error("Calls v2 is not supported");return this.keet.dispatch(e,"@keet/remove-call-stream",{callKey:s.decode(t),streamKey:s.decode(i)})}async startCallRecording(e,t){return this.keet.dispatch(e,"@keet/start-call-recording",{callKey:s.decode(t)})}async stopCallRecording(e,t){return this.keet.dispatch(e,"@keet/stop-call-recording",{callKey:s.decode(t)})}async _getActiveCalls({engine:e,snapshot:t},s={}){return(await ue(t,"@keet/active-calls-by-timestamp")).map(t=>T(t,{...s,deviceKey:e.local.key}))}async _getCalls({snapshot:e},t={}){return(await ue(e,"@keet/calls-by-timestamp")).map(e=>T(e,t))}async _getAllActiveCalls({localSnapshot:e},t={}){if(!0===t.rejoin){const t=e.find("@local/rooms-by-active-call",{reverse:!0});for await(const e of t)if(e.activeCall.selfDeviceKey)return lt(e);return null}const s=[];for await(const t of e.find("@local/rooms-by-active-call"))s.push(lt(t));return s}subscribeAllActiveCalls(e){return this._addKeetSubscription(Ge,{query:()=>this.getAllActiveCalls(e)})}subscribeActiveCalls(e,...t){return this._addRoomSubscription(e,{query:()=>this.getActiveCalls(e,...t)})}subscribeCalls(e,...t){return this._addRoomSubscription(e,{query:()=>this.getCalls(e,...t)})}subscribeCallProxy(e){const t=this.keet.callProxy.getCallById(e);if(!t)throw Ke.CALL_NOT_ACTIVE("",{callId:e});const s=new c,i=({swarmId:e,proxyPort:t})=>s.push({type:"peer",swarmId:e,proxyPort:t}),o=({swarmId:e,data:t})=>s.push({type:"signal",swarmId:e,data:t}),a=({swarmId:e})=>s.push({type:"peer-close",swarmId:e});t.on("peer",i),t.on("signal",o),t.on("peer-close",a);for(const[e,i]of t.openPeers())s.push({type:"peer",swarmId:e,proxyPort:i});return s.once("close",()=>{t.off("peer",i),t.off("signal",o),t.off("peer-close",a)}),s}signalCallPeer(e,t,s){const i=this.keet.callProxy.getCallById(e);if(!i)throw Ke.CALL_NOT_ACTIVE("",{callId:e});i.signal(t,s)}_addCallStartedEvent(e){return this.addChatMessage(e,null,{callStarted:!0})}_addCallHangupEvent(e){return this.addChatMessage(e,null,{callHangup:!0})}_addCallMissedEvent(e){return this.addChatMessage(e,null,{callMissed:!0})}_addLocationSharedEvent(e,t,{locationShared:{latitude:s,longitude:i}}){return this.addChatMessage(e,t,{locationShared:{latitude:s,longitude:i}})}addRoomAvatarChangedEvent(...e){console.log("addRoomAvatarChangedEvent",...e),console.warn("Missing required method: addRoomAvatarChangedEvent")}addEvent(...e){console.log("addEvent",...e),console.warn("Missing required method: addEvent")}removeEvent(...e){console.log("removeEvent",...e),console.warn("Missing required method: removeEvent")}async _getChatMessage({roomKey:e,local:t,snapshot:s,blobsSnapshot:i,files:o},a){return(await re(async function(){const t=j(e,{gte:a,lte:a});return await s.findOne("@keet/chat",t)},e,t,s,i,o))[0]}async _getChatMessageById({roomKey:e,local:t,snapshot:s,blobsSnapshot:i,files:o},a){return(await re(async function(){return await s.get("@keet/chat-by-message-id",{oplog:H(a)})},e,t,s,i,o))[0]}async _getChatMessages({roomKey:e,local:t,snapshot:s,blobsSnapshot:i,files:o},a){return await re(async function(){const t=j(e,a);return await s.find("@keet/chat",t).toArray()},e,t,s,i,o)}async _getPinnedChatMessages({roomKey:e,local:t,snapshot:s,blobsSnapshot:i,files:o},a){return await re(async function(){return await s.find("@keet/pinned-chat-messages",a).toArray()},e,t,s,i,o)}async _getChatLength({db:e}){const t=await e.get("@keet/threads",{id:0});return{length:t?t.count:0}}subscribeChatMessages(e,...t){return this._addRoomSubscription(e,{query:()=>this.getChatMessages(e,...t)})}subscribeChatLength(e,t){let s=null;return this._addRoomSubscription(e,{query:async()=>{if(!t||!t.reorders)return this.getChatLength(e);if(this.keet.closing)return null;const i=this.keet.internalOpenExistingRoom(e);try{const{length:t}=await this.getChatLength(e),{undos:o,fastForwards:a}=i.engine.stats,n=null!==s&&(o!==s.undos||a!==s.fastForwards);return s={undos:o,fastForwards:a},{length:t,reordered:n}}finally{this.keet.internalReleaseRoom(i)}}})}async _searchChatMessages({snapshot:e,roomKey:t,local:s,blobsSnapshot:i,files:o},n,{limit:r=1e3,reverse:c=!0}={}){if(!n||!n.length)return[];const l=await s.get("@local/rooms",{roomKey:t});if(!l)return[];if(!(n=n.map(e=>e.replace(/\s/g,"").toLowerCase()).filter(e=>e)).length)return[];const h=[];for await(const s of e.find("@keet/chat",{limit:r,reverse:c})){if(!s.message?.text)continue;const r=s.message.text.replace(/\s/g,"").toLowerCase();if(n.every(e=>r.indexOf(e)>-1)){const n=ce(t,e,i,l,o,s);n.catch(a),h.push(n)}}return Promise.all(h)}createChatSearchStream(e,t,s){return c.from(this._createChatSearchGenerator(e,t,s))}async*_createChatSearchGenerator(e,t,{limit:i=1e3,reverse:o=!0}={}){if(!t||!t.length)return;if(!(t=t.map(e=>e.replace(/\s/g,"").toLowerCase()).filter(e=>e)).length)return;const a=s.decode(e),n=await this.keet.local.get("@local/rooms",{roomKey:a});if(!n)return;const r=this.keet.internalOpenExistingRoom(a);await r.ready();const c=r.db.snapshot(),l=r.blobs?r.blobs.snapshot():null,h=this.keet.local.snapshot(),d=this.keet.files,u=c.find("@keet/chat",{limit:i,reverse:o});try{for await(const e of u){const t=await m(e);t&&(yield t)}}catch(e){this.keet.onerror(e)}finally{await h.close(),await c.close(),l&&await l.close(),this.keet.internalReleaseRoom(r)}async function m(e){const t=p(e.message?.text);let i=!1;if(e&&e.message&&e.message.files&&(i=!!e.message.files.length),!i&&!g(t))return;const o=await ce(a,c,l,n,d,e);if(i&&!g(t)&&!function(e){return e.files.some(e=>g(p(e.metadata?.name)))}(o))return;if(o.labels.flagged||o.labels.flags>=_e)return;const r=s.decode(o.memberId);return await h.get("@local/blocked-contacts",{memberKey:r})||await c.get("@keet/muted-members",{key:r})||o.reactions.digest.reactions.find(e=>"⚠️"===e.text)?void 0:o}function p(e){return e?e.replace(/\s/g,"").toLowerCase():""}function g(e){return!!e&&t.every(t=>e.indexOf(t)>-1)}}_sendDMFromContact(e,{message:t=null}={}){return this.keet.sendContactRequestFromContact(e,{message:t})}_sendDMRequest(e,t,{message:s=null}={}){return this.sendInvitations(e,{receivers:[t],message:s})}async _sendInvitations(e,{receivers:t,message:i}){const o=s.decode(e),a=Array.isArray(t)?t[0]:t,n=s.decode(a);await this.keet.sendContactRequest(o,n,{message:i})}async _updatePrivateMailboxRecord({memberId:e,roomId:t},i={}){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const o=i.isSeen||1===i.seen;return this.keet.privateProfile.dispatch("@keet-private-id/update-contact-request-status",{memberKey:s.decode(e),roomKey:s.decode(t),key:se.IsSeen,status:{isSeen:o}})}async _getDmRequestsByStatus({localSnapshot:e,profileDb:t},s,{reverse:i=!0,limit:o=50}={}){if(!t)return[];const a={[ye.ACCEPTED]:"@keet-private-id/accepted-contact-requests-v2",[ye.REJECTED]:"@keet-private-id/rejected-contact-requests-v2",[ye.PENDING]:"@keet-private-id/pending-contact-requests-v2",[ye.DISCARDED]:"@keet-private-id/discarded-contact-requests-v2"}[s]||"@keet-private-id/pending-contact-requests-v2",n=t.find(a,{reverse:i,limit:o});return pe(n,async t=>{const s=await e.get("@local/active-contacts",{memberKey:t.memberKey});return I(t,s)})}subscribeDmRequestsByStatus(e,t={}){return this._addRoomSubscription(Te,{query:()=>this.getDmRequestsByStatus(e,t)})}async _getPrivateMailboxRecords({profile:e},t={}){console.warn("Deprecated: getPrivateMailboxRecords")}subscribePrivateMailbox(){return console.warn("Deprecated: subscribePrivateMailbox"),new c}getSentPrivateMailboxRecords(...e){console.warn("Deprecated: getSentPrivateMailboxRecords")}subscribeSentPrivateMailbox(...e){return console.warn("Deprecated: subscribeSentPrivateMailbox"),new c}async _getDmByMemberId({profileSnapshot:e},t){const o=s.decode(t),[a,n]=await Promise.all([e.get("@keet-private-id/contacts",{memberKey:o}),e.get("@keet-private-id/contact-requests",{memberKey:o})]);let r=null;return a&&a.roomKey?r=a.roomKey:n&&(r=n.keys.key),{roomId:r?s.encode(r):null,discoveryId:r?s.encode(i.discoveryKey(r)):null,dmMemberId:t,recipient:t}}async updateRoomInvitationSeenStatus({discoveryId:e,invitationId:t},i){return this.keet.updateRoomInvitationSeenStatus(s.decode(e),s.decode(t),i)}async _acceptDmRequest({memberId:e,roomId:t}){return this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),this.keet.privateProfile.dispatch("@keet-private-id/update-contact-request-status",{memberKey:s.decode(e),roomKey:s.decode(t),key:se.IsAccepted,status:{isAccepted:!0}})}async _rejectDmRequest({memberId:e,roomId:t}){return this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),this.keet.privateProfile.dispatch("@keet-private-id/update-contact-request-status",{memberKey:s.decode(e),roomKey:s.decode(t),key:se.IsRejected,status:{isRejected:!0}})}async discardDmRequest({memberId:e,roomId:t}){return this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),this.keet.privateProfile.dispatch("@keet-private-id/update-contact-request-status",{memberKey:s.decode(e),roomKey:s.decode(t),key:se.IsDiscarded,status:{isDiscarded:!0}})}_addReaction(e,t,i){return this.keet.dispatch(e,"@keet/add-reaction",{oplog:{key:s.decode(t.deviceId),seq:t.seq},reaction:i})}_removeReaction(e,t,i){return this.keet.dispatch(e,"@keet/remove-reaction",{oplog:{key:s.decode(t.deviceId),seq:t.seq},reaction:i})}async _getLatestReactions({snapshot:e},t,s,{limit:i}={}){const{id:o}=await e.get("@keet/chat-by-message-id",{oplog:H(t)});return(await e.find("@keet/reactions-by-clock",{gte:{id:o,reaction:s},lte:{id:o,reaction:s},limit:i,reverse:!0}).toArray()).map(e=>M(e))}async _getReactions({roomKey:e,snapshot:t,local:s},i){const o=H(i);return le({roomKey:e,snapshot:t,local:s,oplog:o})}subscribeReactions(e,t){return this._addRoomSubscription(e,{query:()=>this.getReactions(e,t)})}subscribeReportedMessages(e,...t){return this._addRoomSubscription(e,{query:()=>this.getReportedMessages(e,...t)})}subscribeReportedMembers(e,...t){return this._addRoomSubscription(e,{query:()=>this.getReportedMembers(e,...t),name:Ue})}async _getReportedMembers({snapshot:e,blobsSnapshot:t,localSnapshot:i},{clock:o,limit:a=50}={}){const n=await e.find("@keet/member-label-digests-by-clock",{gte:{label:te.Flag},lte:{label:te.Flag,clock:o},limit:a<=50?a:50,reverse:!0}),r=[];for await(const e of n){const t=c.bind(this);r.push(t(e))}return await Promise.all(r);async function c(o){const{key:a,total:n,flagsClock:r}=o,c=await this._getMember({snapshot:e,blobsSnapshot:t,localSnapshot:i},s.encode(a));return c.labels={total:n,flagsClock:r},c}}reportMember(e,t){return this.keet.dispatch(e,"@keet/add-member-label",{key:s.decode(t),label:te.Flag})}async _getReportedMessages({roomKey:e,local:t,snapshot:s,blobsSnapshot:i,files:o},{clock:a,limit:n=50}={}){const r=await t.get("@local/rooms",{roomKey:e});if(!r)return;const c=await s.find("@keet/chat-label-digests-by-clock",{gte:{label:ee.Flag},lte:{label:ee.Flag,clock:a},limit:n<=50?n:50,reverse:!0}),l=[];for await(const{id:e}of c)l.push(h(e));return await Promise.all(l);async function h(t){const a=await s.findOne("@keet/chat",{gte:{id:t},lte:{id:t}});return ce(e,s,i,r,o,a)}}_addChatReport(e,t){const s=H(t);return this.keet.dispatch(e,"@keet/add-chat-label",{oplog:s,label:ee.Flag})}_removeChatReport(e,t){const s=H(t);return this.keet.dispatch(e,"@keet/remove-chat-label",{oplog:s,label:ee.Flag})}async _dismissChatReports(e,t){const s=H(t);return this.keet.dispatch(e,"@keet/dismiss-chat-reports",{oplog:s})}addFileBlob(...e){throw console.log("addFileBlob",...e),new Error("Missing required method: addFileBlob")}addFile(...e){throw console.log("addFile",...e),new Error("Missing required method: addFile")}async _saveFileBlob({roomKey:e,files:t},s,i){const o=await t.saveFileBlob(e,s,i);return S(o)}async _saveFile({roomKey:e,files:t},s,i){const o=await t.saveFile(e,s,i);return S(o)}subscribeAddFile(e,t,i){const o=s.decode(e);return h(this.keet.files.subscribeAddFile(o,t,i),new l({transform(e,t){t(null,{...e,result:S(e.result)})}}))}async _sendFile(e,t){const s=t.preview;t.preview=null;const i=this.keet.batch(e),o=await i.dispatch("@keet/add-chat-message",{timestamp:Date.now(),message:V(null,{files:[t]})});0!==o&&(s&&await i.dispatch("@keet/add-file-preview",{oplog:{key:i.key,seq:o-1},index:0,preview:J(s)},{dryRun:!1}),await i.flush())}async _sendFiles(e,t=[]){const s=[];for(const e of t)s.push(e.preview),e.preview=null;const i=this.keet.batch(e),o=await i.dispatch("@keet/add-chat-message",{timestamp:Date.now(),message:V(null,{files:t})});if(0===o)return;const a={key:i.key,seq:o-1};for(let e=0;e<s.length;e++){const t=s[e];t&&await i.dispatch("@keet/add-file-preview",{oplog:a,index:e,preview:J(t)},{dryRun:!1})}await i.flush()}removeFile(...e){throw console.log("removeFile",...e),new Error("Missing required method: removeFile")}subscribeFileInfo(e,t){const i=s.decode(e),o=this;let a=null;return new c({async open(e){let s=null;try{a=await o.keet.files.monitor(i,G(t)),a.on("update",e=>{this.push(a.stats)})}catch(e){s=e}e(s)},async destroy(e){a&&a.close(),e(null)}})}async _clearAllFiles({roomId:e,roomKey:t,files:s},i){const o=await s.clearAllFiles(t,i);return this.keet.emit("local-files-changed",e),o}async _clearOldFiles(){return this.keet.files.clearOldFiles()}async _getFileEntry({roomKey:e,files:t},s){const i=await t.getFileEntry(e,G(s));return E(i)}async _getLocalFiles({roomKey:e,files:t,snapshot:s,blobsSnapshot:i}){const o=await t.getLocalFiles(e);return Promise.all(o.map(async o=>{const a=await t.getFileEntryWithPreview(e,o.file,{loadBlob:e=>me(e,s,i)});return{...S(a.file),entry:E(a)}}))}async _getFiles({roomKey:e,files:t,snapshot:i,blobsSnapshot:o},a={}){const n=Y(a),r=await i.find(a.type?"@keet/files-by-major-type":"@keet/active-files",n).toArray();return Promise.all(r.map(async a=>{const n=await t.getFileEntryWithPreview(e,a.file,{loadBlob:e=>me(e,i,o)});return{...S(n.file),id:a.id,messageId:{deviceId:s.encode(a.oplog.key),seq:a.oplog.seq},entry:E(n)}}))}_startDownload({roomKey:e,files:t},s){return t.startDownload(e,G(s))}_cancelDownload({roomKey:e,files:t},s){return t.cancelDownload(e,s)}readFileStream(e,t,i){const o=s.decode(e);return this.keet.files.readFileStream(o,G(t),i)}subscribeSaveToDisk(e,t,i,o={}){const a=s.decode(e);return this.keet.files.subscribeSaveToDisk(a,G(t),i,o)}_saveToDisk({roomKey:e,files:t},s,i){return t.saveToDisk(e,G(s),i)}async _clearFile({roomId:e,roomKey:t,files:s},i){i.preview?.large?.pointer?.externalBlob&&await s.clearFile(t,G(i.preview.large)),await s.clearFile(t,G(i)),this.keet.emit("local-files-changed",e)}async _unclearFile({roomId:e,roomKey:t,files:s},i){i.preview?.large?.pointer?.externalBlob&&await s.unclearFile(t,G(i.preview.large)),await s.unclearFile(t,G(i)),this.keet.emit("local-files-changed",e)}_getFileCleared({roomKey:e,files:t},s){return t.getFileCleared(e,G(s))}_refreshFileLinks(e){return this.keet.files.refreshLinks(e)}subscribeFileCleared(e,t){return this._addRoomSubscription(e,{query:()=>this.getFileCleared(e,t)})}subscribeFiles(e,...t){return this._addRoomSubscription(e,{query:async()=>this.getFiles(e,...t)})}getStats(){return{suspended:this.keet.state===Ee.SUSPEND,onlineBoot:this.keet.onlineBoot.opened,connections:this.keet.swarm.connections.size,openRooms:this.keet.rooms.size,openRoomIds:[...this.keet.rooms.keys()],openCores:this.keet.store.cores.size,blindPeering:this.keet.blindPeering?.stats??null,activeRooms:this.keet.activeRooms.size,roomSubscriptions:[...this._subscriptions.values()].filter(e=>e.isRoomSub).size,backgroundSwarmingRooms:[...this.keet.swarmWorker.sessions.keys()],dht:this.keet.swarm.dht.stats,swarm:this.keet.swarm.stats,ops:this.keet.stats.ops,uploaded:this.keet.stats.uploaded,bytesUploaded:this.keet.stats.bytesUploaded,downloaded:this.keet.stats.downloaded,bytesDownloaded:this.keet.stats.bytesDownloaded,appends:this.keet.stats.appends,bytesAppended:this.keet.stats.bytesAppended,ipc:{sent:0,recv:0},threads:[]}}async getRoomStats(e){const t=this.keet.internalOpenExistingRoom(s.decode(e));try{return await t.getStats()}finally{this.keet.internalReleaseRoom(t)}}async _lookupUsername(e){if(!e)return;const t=await this.keet.userRegistry.lookup(e);return K(t)}async _lookupUserByMemberId(e){if(!e)return;const t=s.decode(e),i=await this.keet.userRegistry.lookupByKey(t);return K(i)}async _searchUsername(e,{limit:t=20}={}){return(await this.keet.userRegistry.search(e,{limit:t})).map(K)}_registerUsername(e){return this.keet.userRegistry.update(e)}_updateUsername(e){return this.keet.userRegistry.update(e)}async _getReservationsByKey(e){if(!e)return;const t=s.decode(e),i=await this.keet.userRegistry.getReservationsByKey(t);if(!i||!i.length)return null;const o=i[0];return D(o)}subscribeUsername(){const e=this.keet.userRegistry.subscribeUsername();return h(e,new l({transform(e,t){if(!e)return t(null);t(null,{status:e.status,reservation:D(e.reservation),record:K(e.record),error:e.error})}}))}_checkUsername(e){return this.keet.userRegistry.isAvailable(e)}subscribeSystemUpdateRequest(){return this._addKeetSubscription(Ne,{query:()=>this.keet.migrationStatus||{remaining:0}})}async autobeeLogs(e){const t=this.keet.internalOpenExistingRoom(s.decode(e));try{await t.ready(),await t.engine.logs()}finally{this.keet.internalReleaseRoom(t)}}close(){return this.keet.close()}suspend(){return this.keet.suspend()}resume(){return this.keet.resume()}async getDebugFlags(){const e=await this.keet.local.get("@local/debug");return e?.flags||[]}async updateDebugFlag(e,t){const s=Ce.get(e);if(!(s>=0))return;const i=await this.keet.internalEnterLocalTransaction();try{const e=await i.get("@local/debug");e.flags[s].value=!0===t,await i.insert("@local/debug",e),await i.flush()}finally{await this.keet.internalExitLocalTransaction()}}createErrorStream(){return h(this.keet.local.find("@local/errors"),new l({transform(e,t){t(null,A(e))}}))}async _repair(e){const t=this.keet.internalOpenExistingRoom(s.decode(e));try{await t.ready(),await t.engine.repair()}finally{this.keet.internalReleaseRoom(t)}}async _audit(e){const t=this.keet.rootCorestore.audit(e),s=[];for await(const e of t)s.push(e);return s}async _rotateWriter(e){return this.keet.rotateWriter(s.decode(e))}compact(e=!1){return e?this.keet.storage.compact({blobGarbageCollectionPolicy:De.garbageCollectionPolicy.FORCE,blobGarbageCollectionAgeCutoff:1,bottommostLevelCompaction:De.bottommostLevelCompaction.FORCE}):this.keet.storage.compact()}async _setUnread(e,t){const i=s.decode(e),o=await this.keet.internalEnterLocalTransaction();try{await o.insert("@local/unreads",{roomKey:i,count:t}),await o.flush()}finally{await this.keet.internalExitLocalTransaction()}}async _getUnread(e){const t=s.decode(e),i=await this.keet.local.get("@local/unreads",{roomKey:t});return i?i.count:0}async _setUnreadAnchor(e,t){const i=s.decode(e);this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),this.keet.unreads&&(await this.keet.unreads.put(i,{timestamp:Date.now(),length:t}),this.keet.emit("unread-anchors-changed"));const o=await this.keet.local.get("@local/rooms",{roomKey:i});if(!o?.dm?.length)return;const a=await this.keet.internalOpenPrivateProfile();try{const s=await a.db.get("@keet-private-id/settings");if(s?.disableReadReceipts)return;await this.keet.dispatch(e,"@keet/update-read-length",{length:t})}finally{this.keet.internalReleaseRoom(a)}}async _getUnreadAnchor(e){if(this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),!this.keet.unreads)return null;const t=s.decode(e);return this.keet.unreads.get(t)}_subscribeUnreadAnchor(e){return this._addKeetSubscription(je,{query:async()=>{const t=await this.getUnreadAnchor(e);return null!==t?t:{length:0,timestamp:0}}})}async _getUnreadRooms({local:e}){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const t=this.keet.unreads,i=[],o=[];for await(const t of e.find("@local/rooms-by-timestamp"))o.push(a(t));return await Promise.all(o),{rooms:i};async function a(e){const o=t?await t.get(e.roomKey):null;de(e,e.preferences,o)&&i.push({id:s.encode(e.roomKey),isFullyMuted:!!e.preferences?.isFullyMuted,roomSnoozeTime:e.preferences?.roomSnoozeTime??0})}}_subscribeUnreadRooms(){return this._addKeetSubscription(Ve,{query:()=>this.getUnreadRooms()})}async _updateTypingIndicator({roomId:e,db:t}){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),(await t.get("@keet/system-digest")).settings.roomType===Q.DirectMessage&&await this.keet.dispatch(e,"@keet/update-typing-indicator",{})}async _getTypingIndicator({db:e},t){const i=s.decode(t),o=await e.get("@keet/typing-indicators",{memberKey:i});return o?{memberId:t,timestamp:o.timestamp}:null}_subscribeTypingIndicator(e,t){return this._addRoomSubscription(e,{query:()=>this.getTypingIndicator(e,t),name:"typing-indicator"})}async _setRoomFavorite(e,t=!0){this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready();const{privateProfileKey:i}=await this.keet.local.get("@local/identity");await this.keet.local.get("@local/rooms",{roomKey:i})&&await this.keet.privateProfile.dispatch("@keet-private-id/update-room-status",{roomKey:s.decode(e),key:ie.IsFavorite,status:{isFavorite:t}})}}class Xe{constructor(e){this.keet=e}async ready(){return await this.keet.ready(),s.encode(this.keet.swarm.keyPair.publicKey)}}class Qe{constructor(t){this.keet=t,this.preferences=new g(e.join(t.dir,"preferences_v1.json")),this._subs=[]}async _bump(){const e=await this.preferences.list();for(const t of this._subs)t.push(e)}async update(e,t){await this.preferences.set(e,t),await this._bump()}query(){return this.preferences.list()}subscribe(){const e=this,t=new c({async open(e){let t=null;try{await this._bump()}catch(e){t=e}e(t)},destroy(t){const s=e._subs.indexOf(this);-1!==s&&e._subs.splice(s,1),t(null)}});return this._subs.push(t),t}}class Ze{constructor(e,{onerror:t=a}={}){this.keet=e,this._status=null,this._subs=[],this.keet.swarm.on("update",this._handleUpdate.bind(this)),this.keet.swarm.dht.on("network-update",this._handleUpdate.bind(this)),this.keet.bluetooth&&this.keet.bluetooth.on("update",this._handleUpdate.bind(this))}_handleUpdate(){this._status=this.query();for(const e of this._subs)e.push(this._status)}query(){const e=[];for(const[t,i]of this.keet.swarm.peers)e.push(s.encode(i.publicKey));return{host:this.keet.swarm.dht.host,port:this.keet.swarm.dht.port,online:this.keet.swarm.dht.online,degraded:this.keet.swarm.dht.degraded,connections:this.keet.swarm.connections.size,dhtPublicKey:s.encode(this.keet.swarm.dht.defaultKeyPair.publicKey),swarmPublicKey:s.encode(this.keet.swarm.keyPair.publicKey),peers:e,bluetooth:this.keet.bluetooth?this.keet.bluetooth.status():{state:"unsupported",enabled:!1,peers:0,nearby:{sharing:!1,changes:0}}}}async setBluetoothEnabled(e){return!0===e?await this.keet.internalEnableBluetooth():await this.keet.internalDisableBluetooth(),this.query().bluetooth}async setNearbyContactInfo(e,t){return await this.keet.bluetooth.setNearbyContactInfo(e,t),this.keet.bluetooth.status()}async clearNearbyContactInfo(){return await this.keet.bluetooth.clearNearbyContactInfo(),this.keet.bluetooth.status()}async getNearbyContactInfos(){return this.keet.bluetooth.nearby.contactInfos()}subscribe(){const e=this,t=new c({open(t){e._status&&this.push(e._status),t(null)},destroy(t){const s=e._subs.indexOf(this);-1!==s&&e._subs.splice(s,1),t(null)}});return this._subs.push(t),t}subscribeDebug(e=5e3,t=0){const s=this;let i=null,o=0;const a=new c({open(t){n(),i=setInterval(()=>{n()},e),t(null)},destroy(e){i&&(clearInterval(i),i=null),e(null)}});return a;async function n(){const e=await s.debug();a.push(e),o+=1,t&&o>=t&&a.push(null)}}async debug(){return{tick:this.keet.swarm.dht._tick,localAddress:this.keet.swarm.dht.localAddress(),remoteAddress:this.keet.swarm.dht.remoteAddress(),connection:this.query(),stats:this.keet.swarm.dht.stats,health:this.keet.swarm.dht.health.stats,nodes:this.keet.swarm.dht.nodes.length,config:this.keet.swarm.dht.config,rttStats:await this.keet.swarm.dht.rttStats()}}}class et{constructor(e,{onerror:t=a}={}){this.keet=e,this._status=null,this._subs=[],this.swarm=null,this._onupdate=this._handleUpdate.bind(this),this.keet.on("call-swarm-changed",this._handleCallSwarmChanged.bind(this))}_handleCallSwarmChanged(e,t){this.swarm&&this.swarm.dht.removeListener("network-update",this._onupdate),this.swarm=t,this.swarm&&this.swarm.dht.on("network-update",this._onupdate),this._handleUpdate()}_handleUpdate(){this._status=this.query();for(const e of this._subs)e.push(this._status)}query(){if(!this.swarm)return{active:!1,host:null,port:0,online:!1,degraded:!1,connections:0,peers:[]};const e=[];for(const t of this.swarm.peers.values())e.push(s.encode(t.publicKey));return{active:!0,host:this.swarm.dht.host,port:this.swarm.dht.port,online:this.swarm.dht.online,degraded:this.swarm.dht.degraded,connections:this.swarm.connections.size,peers:e}}subscribe(){const e=this,t=new c({open(t){e._status&&this.push(e._status),t(null)},destroy(t){const s=e._subs.indexOf(this);-1!==s&&e._subs.splice(s,1),t(null)}});return this._subs.push(t),t}subscribeDebug(e=5e3,t=0){const s=this;let i=null,o=0;const a=new c({open(t){n(),i=setInterval(()=>{n()},e),t(null)},destroy(e){i&&(clearInterval(i),i=null),e(null)}});return a;async function n(){const e=await s.debug();a.push(e),o+=1,t&&o>=t&&a.push(null)}}async debug(){return this.swarm?{active:!0,tick:this.swarm.dht._tick,localAddress:this.swarm.dht.localAddress(),remoteAddress:this.swarm.dht.remoteAddress(),connection:this.query(),stats:this.swarm.dht.stats,health:this.swarm.dht.health.stats,nodes:this.swarm.dht.nodes.length,config:this.swarm.dht.config,rttStats:await this.swarm.dht.rttStats()}:{active:!1}}}class tt{constructor(){this.subscriptions=[],this._handleError=this._handleError.bind(this),this._listenersAttached=!1}_handleError(e){console.error("uncaught on worker",e);for(const t of this.subscriptions)t.push({message:e.message,stack:e.stack+""})}subscribe(e){const t=this;this._listenersAttached||(r.on(this._handleError),this._listenersAttached=!0);const s=new c({...e,destroy(e){const s=t.subscriptions.indexOf(this);-1!==s&&t.subscriptions.splice(s,1),e(null)}});return this.subscriptions.push(s),s}}class st{constructor(e){this.keet=e,this.inspector=new Pe}_getCurrentRoom(){let e=null;for(const t of this.keet.rooms.values())(!e||t.refs>e.refs)&&(e=t);return e}async getCurrentRoomStats(){const e=this._getCurrentRoom();return{hash:(await(e?.engine.core.treeHash())).toString("hex"),length:e?.engine.length}}enableInspector(){return this.inspector?.enable()}disableInspector(){return this.inspector?.disable()}getInspectorKey(){return this.inspector?.key}processTop(){return p.toJSON()}hash(e){return i.hash(e)}generateSyntheticError(e,t={}){const s=new Error(t.message??t.code??"KEET_SYNTHETIC_ERROR");if(s.code=t.code??s.message,Object.assign(s,t),!e)throw s;this.keet.onerror(s)}async getAccumulatedBytes(){let e=0;for await(const{value:t}of this.keet.rootCorestore.storage.db.iterator()){if(this.keet.closing)return e;e+=t.byteLength}return e}async heapSnapshot(e="/tmp/keet-heapsnapshot-"+Bare.pid+"."+Date.now()+".heapsnapshot"){const t=new d;t.connect();const s=new u(t),i=m.createWriteStream(e);return s.pipe(i),await new Promise(e=>i.once("close",e)),t.destroy(),e}async resetUnreads(){if(this.keet.onlineBoot.opened||await this.keet.onlineBoot.ready(),!this.keet.unreads)return null;await this.keet.unreads.reset()}}class it{constructor(e){this._rpcClient=e.rpcClient,this.keet=e}send(e){if(this.keet.buildType===X.Production)return this._rpcClient.makeRequest(this.keet.config.services.feedback,"send",e,{requestEncoding:Se.json})}}function ot(e){switch(e){case 1:return ie.IsFullyMuted;case 2:return ie.IsMentionsOnlyMuted;default:return 0}}function at(e){switch(e){case"0":default:return Q.Default;case"1":return Q.Broadcast;case"2":return Q.DirectMessage}}function nt(e){const t={files:[],httpLink:[],pearLink:[]},s=e.files||[];for(let e=0;e<s.length;e++){const i=s[e].preview;i&&(s[e].preview=null,t.files.push({index:e,preview:i}))}const i=e.display?.httpLink||[];for(let e=0;e<i.length;e++){const s=a(i[e]);s&&t.httpLink.push({index:e,preview:s})}const o=e.display?.pearLink||[];for(let e=0;e<o.length;e++){const s=a(o[e]);s&&t.pearLink.push({index:e,preview:s})}return t;function a(e){if(!e.preview?.file?.preview)return null;const t=e.preview.file.preview;return e.preview.file.preview=null,t}}async function rt(e,{files:t,httpLink:s,pearLink:i},o=null){const a=o||{key:e.key,seq:e.length-1};if(t.length)for(const{index:s,preview:i}of t)await e.dispatch("@keet/add-file-preview",{oplog:a,index:s,preview:J(i)},{dryRun:!1});if(s.length)for(const{index:t,preview:i}of s)await e.dispatch("@keet/add-file-preview",{oplog:a,index:t,preview:J(i),displayType:Z.HttpLink},{dryRun:!1});if(i.length)for(const{index:t,preview:s}of i)await e.dispatch("@keet/add-file-preview",{oplog:a,index:t,preview:J(s),displayType:Z.PearLink},{dryRun:!1})}async function ct(e,t){t.proofs=await e.get("@keet/member-proofs",{key:t.key})}function lt(e){const t=U(e.activeCall);return{roomId:s.encode(e.roomKey),callId:t.callId,selfDeviceId:t.selfDeviceId,createdAt:t.createdAt}}module.exports=class extends t{constructor(e,t){super(),this.keet=e,this.opts=t,this.api={core:new $e(e,t),swarm:null,preferences:null,network:null,error:null,debug:null,console:null,call:null,pear:{teardown:()=>{console.log("[api] teardown initiated");const t=this.keet.close();return t.catch(e.onerror),t},selfDestruct:e=>this.keet.selfDestruct(e)}},this._callBootstraps=null,this.ready().catch(t?.onerror||a)}async _open(){await this.keet.ready(),this.api.swarm=new Xe(this.keet,this.opts),this.api.preferences=new Qe(this.keet,this.opts),this.api.network=new Ze(this.keet,this.opts),this.api.callNetwork=new et(this.keet,this.opts),this.api.error=new tt(this.keet,this.opts),this.api.debug=new st(this.keet,this.opts),this.api.feedback=new it(this.keet),this.call=this.api.call=new b(this.keet.swarm,{skipJoinLeave:!0}),this.keet.on("call-changed-v3",this._handleCallChangedV3.bind(this))}async _close(){this.call&&this.call.close(),await this.api.debug.disableInspector()}async closeActiveCalls(){if(!this.keet.activeCall)return;const{roomId:e,callKey:t}=this.keet.activeCall,i=await this.keet.local.get("@local/rooms",{roomKey:s.decode(e)});if(!i)return;const o=this.keet.rooms.get(e);if(!o)return;const a=i.dm?"@keet/end-call":"@keet/leave-call";await o.dispatch(a,{callKey:t},{dryRun:!1}),await new Promise(e=>setTimeout(e,1500))}_handleCallChangedV3(e){this.keet.internalSyncActiveCall(e)}async suspend(){await this.keet.suspend()}async resume(){await this.keet.resume()}};