const { InternalSchema: e } = require("@holepunchto/keet-core-schemas"),
{
InternalOperation: t,
UpgradeOperation: i,
GenesisOperation: n,
AddPluginOperation: a,
} = e.Operations,
{
FEATURES: s,
isFeatureSupported: r,
CURRENT_ABI: o,
MIN_ABIS: l,
} = require("@holepunchto/keet-core-api")
module.exports = class {
static Operations = new Set([t.TYPE])
constructor(e) {
;((this.view = e), (this.members = null), (this.config = null), (this._bee = null))
}
initialize() {
;((this.members = this.view.members),
(this.config = this.view.config),
(this._bee = this.view.bee))
}
async _getCodeVersion(t) {
const i = await t.get(e.CodeVersionKey, e.UpgraderEncoding)
return i ? i.value : 0
}
async getCodeVersion(e = -1) {
if (-1 === e) return this._getCodeVersion(this._bee)
const t = this._bee.checkout(e)
try {
return await this._getCodeVersion(t)
} finally {
await t.close()
}
}
updateCodeVersion(t) {
return this._bee.put(e.CodeVersionKey, t, e.UpgraderEncoding)
}
setExperimentalMode() {
return this._bee.put(e.ExperimentalModeKey, 1, e.UpgraderEncoding)
}
getExperimentalMode() {
return this._bee.get(e.ExperimentalModeKey, e.UpgraderEncoding)
}
async isExperimentalMode() {
const e = await this.getExperimentalMode()
return !!e && 1 === e.value
}
async listPlugins() {
const t = []
for await (const { value: i } of this._bee.createReadStream(e.PluginsEncoding)) t.push(i)
return t
}
async updatePlugin(t, { key: i, length: n, fork: a }) {
const s = await this.listPlugins()
let r = -1
for (let e = 0; e < s.length; e++)
if (s[e].name === t) {
r = e
break
}
if (-1 === r) {
const t = { ...e.PluginsEncoding.keyEncoding.encodeRange({}), reverse: !0 },
i = await this._bee.peek(t)
r = i ? e.PluginsEncoding.keyEncoding.decode(i.key) + 1 : 0
}
await this._bee.put(r, { name: t, key: i, length: n, fork: a }, e.PluginsEncoding)
}
async _applyGenesisOperation(e, { id: t }) {
if (this.view.core.length > 0) return
const { experimental: i, bootstrap: n, version: a } = e.value.value
;(await this.view.devices.addBootstrapMember(t.key, n.noisePublicKey),
await this.updateCodeVersion(a),
i && (await this.setExperimentalMode()))
}
async _applyUpgradeOperation(e) {
const { version: t } = e.value.value,
i = await this.getCodeVersion()
t > ((await this.isExperimentalMode()) ? o.EXPERIMENTAL : o.STABLE) ||
(i && i >= t) ||
(i < l[s.V2_CONFIG] && r(t, s.V2_CONFIG) && (await this.config.migrate()),
i < l[s.V2_PRIVATE_PROFILE] &&
r(t, s.V2_PRIVATE_PROFILE) &&
(await this.view.privateProfile.migrate()),
await this.updateCodeVersion(t))
}
async _applyAddPluginOperation(e, { id: t }) {
const { name: i, key: n, length: a, fork: s } = e.value.value
;(await this.members.isModerator(t.key)) &&
(await this.updatePlugin(i, { key: n, length: a, fork: s }))
}
async autobaseApply(e, t) {
switch (e.value.subtype) {
case n.SUBTYPE:
return this._applyGenesisOperation(e, t)
case i.SUBTYPE:
return this._applyUpgradeOperation(e, t)
case a.SUBTYPE:
return this._applyAddPluginOperation(e, t)
}
}
}