OverviewFilesCommitsIssuesDocsReleasesPeers

holepunchto-deps / @holepunchto / keet-registry / lib / watcher.js

1 lines · javascript ref:
const t=require("debounceify"),s=require("safety-catch");module.exports=class{constructor(s,e){this.db=s,this.collection=e,this._listeners=[],this.onchange=t(this._onchange.bind(this)),this.watching=!1}add(t,s=null){const e=new Promise((e,n)=>{const i={target:t,condition:s,resolve:e,reject:n,index:-1};i.index=this._listeners.push(i)-1});return this._watch(),e}_watch(){this.onchange().catch(s),this.watching||this.db.watch(this.onchange),this.watching=!0}_unwatch(){this.watching&&this.db.unwatch(this.onchange),this.watching=!1}async _onchange(){const t=this.db.snapshot();try{const s=[];for(const{target:e}of this._listeners)s.push(t.get(this.collection,e));const e=await Promise.all(s);for(let t=0;t<this._listeners.length;t++){if(!e[t])continue;const{condition:s}=this._listeners[t];s&&!s(e[t])||this._settle(null,e[t],t)}}catch(t){this.destroy(t)}finally{t.close()}}destroy(t){this._unwatch();for(let s=0;s<this._listeners.length;s++)this._settle(t,null,s)}_settle(t,s,e){const{resolve:n,reject:i}=this._listeners[e];!function(t,s){const e=t[s],n=t.pop();n!==e&&(t[s]=n,n.index=s)}(this._listeners,e),t?i(t):n(s)}};