const t=require("ready-resource"),e=require("scope-lock"),{KeetContractError:r}=require("../core/contract/errors"),_={INVALID_INVITATION_TYPE:"INVALID_INVITATION_TYPE",UNKNOWN_EXPIRATION:"UNKNOWN_EXPIRATION",INVALID_INVITE:"INVALID_INVITE",INVALID_CONTACT_INFO:"INVALID_CONTACT_INFO",MODERATORS_ONLY:"MODERATORS_ONLY",UNEXPECTED_ERROR:"UNEXPECTED_ERROR",INVALID_BUILD_TYPE:"INVALID_BUILD_TYPE",KEET_IS_CLOSING:"KEET_IS_CLOSING",INVALID_SETTINGS_KEY:"INVALID_SETTINGS_KEY",INVALID_ROOM_TYPE:"INVALID_ROOM_TYPE",INVALID_FILE_PATH:"INVALID_FILE_PATH",ROOM_DISABLED:"ROOM_DISABLED",UPDATE_DEVICE_FAILED:"UPDATE_DEVICE_FAILED",CALL_DISABLED:"CALL_DISABLED",MEMBER_REMOVED:"MEMBER_REMOVED",CALL_SWARM_ACTIVE:"CALL_SWARM_ACTIVE",CALL_SWARM_SUSPENDED:"CALL_SWARM_SUSPENDED",CALL_NOT_ACTIVE:"CALL_NOT_ACTIVE",CALL_DISPATCH_REJECTED:"CALL_DISPATCH_REJECTED"};class E extends Error{constructor(t,e,r={},_){super(e?`${t}: ${e}`:t),this.isKeetError=!0,this.code=t,this.details=r,this.timestamp=Date.now(),Error.captureStackTrace&&Error.captureStackTrace(this,_??this.constructor)}static isKeetError(t){return t?.isKeetError}static fromError(t,e={}){if(E.isKeetError(t))return t;const r=function(t,e){return t.cause?.code?t.cause.code:e.prefix?e.prefix:e.roomKey?"UNEXPECTED_ROOM_ERROR":"UNEXPECTED_ERROR"}(t,e),_={};e.roomKey&&(_.roomKey=e.roomKey),e.coreKey&&(_.coreKey=e.coreKey);const s=new E(r,t.message,_);return s.cause=t,s.stack=t.stack,s}static INVALID_INVITATION_TYPE(t="Attempting to use a device sync invitation as a room invitation",e={}){return new E(_.INVALID_INVITATION_TYPE,t,e,E.INVALID_INVITATION_TYPE)}static UNKNOWN_EXPIRATION(t="Unknown expiration",e={}){return new E(_.UNKNOWN_EXPIRATION,t,e,E.UNKNOWN_EXPIRATION)}static INVALID_INVITE(t="Invalid invite",e={}){return new E(_.INVALID_INVITE,t,e,E.INVALID_INVITE)}static INVALID_CONTACT_INFO(t="Invalid contact info",e={}){return new E(_.INVALID_CONTACT_INFO,t,e,E.INVALID_CONTACT_INFO)}static MODERATORS_ONLY(t="",e={}){return new E(_.MODERATORS_ONLY,t,e,E.MODERATORS_ONLY)}static UNEXPECTED_ERROR(t="",e={}){return new E(_.UNEXPECTED_ERROR,t,e,E.UNEXPECTED_ERROR)}static INVALID_BUILD_TYPE(t="",e={}){return new E(_.INVALID_BUILD_TYPE,t,e,E.INVALID_BUILD_TYPE)}static KEET_IS_CLOSING(t="",e={}){return new E(_.KEET_IS_CLOSING,t,e,E.KEET_IS_CLOSING)}static INVALID_SETTINGS_KEY(t="Invalid settings key",e={}){return new E(_.INVALID_SETTINGS_KEY,t,e,E.INVALID_SETTINGS_KEY)}static INVALID_ROOM_TYPE(t="Invalid room type",e={}){return new E(_.INVALID_ROOM_TYPE,t,e,E.INVALID_ROOM_TYPE)}static INVALID_FILE_PATH(t="Invalid file path",e={}){return new E(_.INVALID_FILE_PATH,t,e,E.INVALID_FILE_PATH)}static ROOM_DISABLED(t="Room is disabled",e={}){return new E(_.ROOM_DISABLED,t,e,E.ROOM_DISABLED)}static UPDATE_DEVICE_FAILED(t="Failed to update device",e={}){return new E(_.UPDATE_DEVICE_FAILED,t,e,E.UPDATE_DEVICE_FAILED)}static CALL_DISABLED(t="",e={}){return new E(_.CALL_DISABLED,t,e,E.CALL_DISABLED)}static MEMBER_REMOVED(t="",e={}){return new E(_.MEMBER_REMOVED,t,e,E.MEMBER_REMOVED)}static CALL_SWARM_ACTIVE(t="",e={}){return new E(_.CALL_SWARM_ACTIVE,t,e,E.CALL_SWARM_ACTIVE)}static CALL_SWARM_SUSPENDED(t="",e={}){return new E(_.CALL_SWARM_SUSPENDED,t,e,E.CALL_SWARM_SUSPENDED)}static CALL_NOT_ACTIVE(t="",e={}){return new E(_.CALL_NOT_ACTIVE,t,e,E.CALL_NOT_ACTIVE)}static CALL_DISPATCH_REJECTED(t="",e={}){return new E(_.CALL_DISPATCH_REJECTED,t,e,E.CALL_DISPATCH_REJECTED)}}module.exports={ERRORS:_,KeetErrorV2:E,KeetErrorManager:class extends t{constructor(t,r){super(),this.keet=t,this.errors=[],this._flushLock=new e({debounce:!0}),this._flushInterval=r.errorFlushInterval||1e4,this._flushTimerDisabled=null===r.errorFlushTimer,this._flushTimer=null,this._gcMaxAge=r.errorGcMaxAge||12096e5,this.ready().catch(t.onerror)}async _open(){await this.keet.ready(),await this._gc()}async _close(){this._flushTimerDisabled=!0,this._resetTimeout(),await this._flush()}add(t){this.errors.push(t),this.keet.emit("caught-error",t),this._flushTimerDisabled||this._scheduleFlush()}normalize(t,e={}){return E.isKeetError(t)?t:r.isContractError(t)?(t.timestamp=Date.now(),t):E.fromError(t,e)}_scheduleFlush(){this._flushTimer||(this._flushTimer=setTimeout(this._flush.bind(this),this._flushInterval))}_resetTimeout(){this._flushTimer&&(clearTimeout(this._flushTimer),this._flushTimer=null)}debugPauseFlush(){this._resetTimeout()}debugResumeFlush(){this._scheduleFlush()}async _flush(){if(!this.keet.readOnly&&await this._flushLock.lock())try{const t=await this.keet.internalEnterLocalTransaction();try{const e=[...this.errors];this.errors=[];for(const r of e)await t.insert("@local/errors",{code:r.code,message:r.message,stack:r.stack,details:r.details,timestamp:r.timestamp});await t.flush()}finally{await this.keet.internalExitLocalTransaction()}}finally{this._flushLock.unlock(),this._resetTimeout()}}async _gc(){if(this.closing)return;const t=Date.now()-this._gcMaxAge,e=await this.keet.local.find("@local/errors",{lte:{timestamp:t}}).toArray(),r=await this.keet.internalEnterLocalTransaction();try{for(const t of e)await r.delete("@local/errors",t);await r.flush()}finally{await this.keet.internalExitLocalTransaction()}}}};