OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-registry-client / lib / stateless-rpc.js

87 lines · javascript ref:
const e = require("ready-resource"),
  s = require("protomux-rpc-client"),
  t = require("hypercore-id-encoding"),
  n = require("safety-catch")
class i {
  constructor(e) {
    ;((this.client = e), (this.lastUsed = Date.now()), (this.refs = 1))
  }
  bumpLastUsed() {
    this.lastUsed = Date.now()
  }
  addRef() {
    this.refs++
  }
  unref() {
    this.refs--
  }
}
class r extends e {
  constructor(e, { msGcInterval: s = 6e4, suspended: t = !1, relayThrough: n = null } = {}) {
    ;(super(),
      (this.dht = e),
      (this.msGcInterval = s),
      (this.relayThrough = n),
      (this.suspended = t),
      (this._clientRefs = new Map()),
      (this._gcInterval = null))
  }
  get nrClients() {
    return this._clientRefs.size
  }
  async _open() {
    this._gcInterval = setInterval(this.gc.bind(this), this.msGcInterval)
  }
  async _close() {
    clearInterval(this._gcInterval)
    const e = []
    for (const { client: s } of this._clientRefs.values()) e.push(s.close())
    await Promise.all(e)
  }
  _getClient(e) {
    if (this.closing) throw new Error("Closing")
    const n = t.normalize(e)
    let r = this._clientRefs.get(n)
    if (r) return (r.bumpLastUsed(), r.refs++, r)
    const c = { relayThrough: this.relayThrough, suspended: this.suspended },
      l = new s(e, this.dht, c)
    return ((r = new i(l)), this._clientRefs.set(n, r), r)
  }
  gc() {
    const e = [],
      s = Date.now() - this.msGcInterval
    for (const [t, { client: i, lastUsed: r, refs: c }] of this._clientRefs)
      c > 0 || r >= s || (e.push(t), i.close().catch(n))
    for (const s of e) this._clientRefs.delete(s)
    e.length > 0 && this.emit("gc", e.length)
  }
  async suspend() {
    if (this.suspended) return
    this.suspended = !0
    const e = []
    for (const s of this._clientRefs.values()) e.push(s.client.suspend())
    await Promise.all(e)
  }
  async resume() {
    if (!this.suspended) return
    this.suspended = !1
    const e = []
    for (const s of this._clientRefs.values()) e.push(s.client.resume())
    await Promise.all(e)
  }
  async makeRequest(e, s, t, { requestEncoding: n, responseEncoding: i, timeout: r } = {}) {
    this.opened || (await this.ready())
    const c = this._getClient(e)
    try {
      return await c.client.makeRequest(s, t, {
        requestEncoding: n,
        responseEncoding: i,
        timeout: r,
      })
    } finally {
      c.unref()
    }
  }
}
module.exports = r