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