OverviewFilesCommitsIssuesDocsReleasesPeers

holepunchto-deps / @holepunchto / keet-core / lib / core / sync / index.js

1 lines · javascript ref:
const e=require("hypercore-id-encoding"),t=require("ready-resource"),s=require("b4a"),a=require("./updater"),{sameHead:i}=require("../hyperdb/local/local"),r=require("./rooms"),{KeetErrorV2:o}=require("../../errors");module.exports=class extends t{constructor(e,t,s){super(),this.keet=e,this.view=t,this.roomEngine=s,this._events=[],this._swappedId=!1,this._updater=null}get loggingOut(){return!!this._updater?.updates.logout}async _close(){this._updater&&await this._updater.close()}async _save(){const t=await this.keet.internalEnterLocalTransaction();try{const a=this._updater.updates.startIdentitySwap,i=this._updater.updates.finishIdentitySwap;if(a){const e=this._updater.currentIdentityInfo;e.swapV2=a;const i=await t.get("@local/identity");s.equals(i.publicKey,e.publicKey)&&await t.insert("@local/identity",{...i,swapV2:a})}if(i&&(await t.insert("@local/identity",i),this._updater.updates.attemptRecovery&&await t.delete("@local/pending-recovery"),this._swappedId=!0),this._updater.updates.contacts){for(const e of this._updater.updates.contacts)await t.insert("@local/contacts",e);this._events.push({type:"contacts-changed",args:[]})}if(this._updater.updates.sharedPreferences)for(const s of this._updater.updates.sharedPreferences){const a=await t.get("@local/room-preferences",s);await t.insert("@local/room-preferences",s);const i=await t.get("@local/rooms",s);i&&(i.preferences=s.status,await t.insert("@local/rooms",i)),s.status.isActive&&this._events.push({type:"recent-rooms-changed",args:["changed",0,e.encode(s.roomKey)]});const r=!1===a?.status.isFavorite&&s.status.isFavorite,o=!0===a?.status.isFavorite&&!s.status.isFavorite;r||o?this._events.push({type:"favorite-rooms-changed",args:[o?"removed":"added",0,e.encode(s.roomKey)]}):s.status.isFavorite&&s.status.isActive&&this._events.push({type:"favorite-rooms-changed",args:["changed",0,e.encode(s.roomKey)]})}if(this._updater.updates.cache&&!this.keet.debugDisableCacheBump){const e=this._updater.updates.cache;if(e.device&&await t.insert("@local/devices",{roomKey:this.roomEngine.key,device:e.device}),e.member&&await t.insert("@local/members",e.member),e.otherMembers)for(const s of e.otherMembers)await t.insert("@local/members",s)}if(await this.keet.tasks.internalPersistTasks(t,this._updater.updates.tasks),this._updater.processed&&(this._updater.roomInfo.processed=this._updater.processed,await this._clearUpdate(t)),this.keet.debugFailRoomSync&&s.equals(this.keet.debugFailRoomSync,this.roomEngine.key))throw new TypeError("debugFailRoomSync");if(this.keet.debugFailNextRoomSync&&s.equals(this.keet.debugFailNextRoomSync,this.roomEngine.key))throw this.keet.debugFailNextRoomSync=null,new TypeError("debugFailNextRoomSync");await r(t,this._updater.roomInfo),await t.flush()}finally{await this.keet.internalExitLocalTransaction()}}async _clearUpdate(e){const t=this._updater.currentUpdate;if(!t)return;const s=await e.get("@local/room-updates",t);i(s?.head,this._updater.processed)&&await e.delete("@local/room-updates",t)}async _dispatch(){const e=this._updater.updates.dispatches;if(e&&0!==e.length)try{await this.keet.dispatchBatch(this.roomEngine.id,e)}catch(e){this.keet.onerror(e)}}async _profileDispatch(){if(!this._updater.currentIdentityInfo)return;const t=this._updater.updates.profileDispatches;if(t&&0!==t.length)try{const s=e.encode(this._updater.currentIdentityInfo.privateProfileKey);await this.keet.dispatchBatch(s,t)}catch(e){this.keet.onerror(e)}}_generateEvents(){this._events.push({type:"room-changed",args:[this.roomEngine.id]});const{roomKey:t,discoveryKey:s,timestamps:a}=this._updater.roomInfo,i=a.latestChatMessage||a.latestSync,r=this._updater.roomInfo&&!this._updater.currentRoomInfo,o=!this._updater.roomInfo.status.isRemoved&&this._updater.currentRoomInfo?.status.isRemoved,n=this._updater.roomInfo.status.isRemoved&&!this._updater.currentRoomInfo?.status.isRemoved,h=this._updater.roomInfo.status.isRemoved,d=!!this._updater.roomInfo.dm,c=!(h||n||r||o);if((r||o||n)&&(this._events.push({type:"recent-rooms-changed",args:[n?"removed":"added",i,this.roomEngine.id]}),this._updater.roomInfo.preferences?.isFavorite&&this._events.push({type:"favorite-rooms-changed",args:[n?"removed":"added",i,this.roomEngine.id]}),(r||o)&&this._events.push({type:"room-preferences-changed",args:["join",t,s]}),n&&this._events.push({type:"room-preferences-changed",args:["leave",t,s]}),r&&d&&this._events.push({type:"dm-rooms-changed",args:[]})),(this._updater.updates.chat||this._updater.updates.labels)&&(c&&(this._events.push({type:"recent-rooms-changed",args:["changed",i,this.roomEngine.id]}),this._updater.roomInfo.preferences?.isFavorite&&this._events.push({type:"favorite-rooms-changed",args:["changed",i,this.roomEngine.id]})),this._updater.updates.chat&&!h&&this._events.push({type:"chat-changed",args:[this.roomEngine.id,this._updater.updates.chat.id.index]})),this._updater.isCurrentPrivateProfile&&this._events.push({type:"identity-changed",args:[]}),this._updater.updates.sharedPreferences)for(const{roomKey:t,status:s}of this._updater.updates.sharedPreferences)s.isFullyMuted&&this._events.push({type:"room-preferences-changed",args:["mute",t]}),s.isFullyMuted||this._events.push({type:"room-preferences-changed",args:["unmute",t]}),s.roomSnoozeTime&&this._events.push({type:"room-preferences-changed",args:["roomSnoozeTime",t]}),this._events.push({type:"room-changed",args:[e.encode(t)]});if(this._updater.updates.activeCallSynced){const e=this._updater.updates.activeCall,t=this._updater.updates.activeCallDevice;(!e||e&&1===e.version)&&this._events.push({type:"call-changed",args:[this.roomEngine.id,e,t]}),(!e||e&&3===e.version)&&this._events.push({type:"call-changed-v3",args:[this.roomEngine.id,e,t]})}}async postUpdate(){try{if(await this.roomEngine.update(),this.keet.closing)return;if(await this._dispatch(),this.keet.closing)return;if(await this._profileDispatch(),this.keet.closing)return;if(this._updater.updates.shouldUpgrade){const t=e.encode(this._updater.roomInfo.roomKey);await this.keet.internalDispatchUpgrade(t,this.keet.abi.autoupgrade)}if(this._updater.updates.tasks)for(const e of this._updater.updates.tasks)e.runBackground();for(const{type:e,args:t}of this._events)this.keet.emit(e,...t);this._updater.updates.logout&&await this.keet.logout(),this._updater.updates.unreadKeys&&await this.keet.internalRefreshUnreads();for(const{type:e,value:t}of this._updater.events){const s={roomKey:this.roomEngine.key,roomId:this.roomEngine.id,roomInfo:this._updater.roomInfo,value:t};this.keet.emit(e,s)}}catch(e){this.keet.onerror(e)}}async run(){let e=null;try{await this._run()}catch(t){e=t}finally{await this.close()}if(this.keet.closing||this.keet.debugClosing){if(e)throw e;return!0}if(!e)return!0;const t=await this.keet.internalEnterLocalTransaction();try{await t.delete("@local/room-updates",{roomKey:this.roomEngine.key}),await t.flush()}finally{await this.keet.internalExitLocalTransaction()}return this.keet.onerror(e,{roomKey:this.roomEngine.key}),!1}async _run(){if(await this.roomEngine.ensureMigratedViews(),this.closing||this.keet.debugClosing)throw o.KEET_IS_CLOSING();this._updater=new a(this.keet,this.view,this.roomEngine);const e=await this._updater.run();if(this.closing||this.keet.debugClosing)throw o.KEET_IS_CLOSING();if(e){if(await this._save(),this.closing)throw o.KEET_IS_CLOSING();this._swappedId&&this.keet.internalSafeSwapPrivateProfiles(),this._generateEvents()}}};