OverviewFilesCommitsIssuesDocsReleasesPeers

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

55 lines · javascript ref:
const t = require("debounceify"),
  s = require("safety-catch")
function e(t, s) {
  const e = t[s],
    n = t.pop()
  n !== e && ((t[s] = n), (n.index = s))
}
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, n) {
    const { resolve: i, reject: h } = this._listeners[n]
    ;(e(this._listeners, n), t ? h(t) : i(s))
  }
}