const e = require("b4a"),
{ MailboxSchema: i } = require("@holepunchto/keet-core-schemas"),
{ FEATURES: t } = require("@holepunchto/keet-core-api"),
{
AddDmRequestOperation: a,
RemoveDmRequestOperation: s,
OldOpenMailboxOperation: o,
OpenMailboxOperation: r,
AddMailboxRecordOperation: l,
RemoveMailboxRecordOperation: n,
} = i.Operations
module.exports = class {
static Operations = new Set([a.TYPE, s.TYPE, o.TYPE, r.TYPE, l.TYPE, n.TYPE])
constructor(e) {
;((this.view = e),
(this.members = null),
(this.mailbox = null),
(this.openMailboxes = null),
(this.mailboxV2 = null),
(this.mailboxCounter = null),
(this.mailByMessageId = null))
}
initialize() {
;((this.members = this.view.members),
(this.mailbox = this.view.collections.mailbox),
(this.openMailboxes = this.view.collections.openMailboxes),
(this.mailboxV2 = this.view.collections.mailboxV2),
(this.mailboxCounter = this.view.indexes.mailboxCounter),
(this.mailByMessageId = this.view.indexes.mailByMessageId))
}
async _applyAddDmRequestOperation(e, { id: i, timestamp: t }) {
const a = await this.members.getMemberForDeviceKey(i.key)
if (!a) return
const { value: s } = e,
o = [s.receiver, a.key]
return (await this.openMailboxes.get(s.receiver))
? (await this.mailbox.get(o)) || (await this.mailbox.get([o[1], o[0]]))
? null
: void (await this.mailbox.update(o, { timestamp: t, link: s.link }, { upsert: !0 }))
: null
}
async _applyRemoveDmRequestOperation(e, { id: i }) {
const t = await this.members.getMemberForDeviceKey(i.key)
if (!t) return
const { value: a } = e,
[s, o] = await Promise.all([
this.mailbox.get([a.receiver, t.key]),
this.mailbox.get([t.key, a.receiver]),
])
;(s && (await this.mailbox.delete([a.receiver, t.key])),
o && (await this.mailbox.delete([t.key, a.receiver])))
}
async _applyOpenMailboxOperation(e, { id: i }) {
const t = await this.members.getMemberForDeviceKey(i.key)
if (!t) return
const { value: a } = e,
s = t.key
if (await this.openMailboxes.get(s)) return null
await this.openMailboxes.update(s, { blindingKey: a.blindingKey }, { upsert: !0 })
}
async _applyAddMailboxRecordOperation(e, { id: i }) {
if (!(await this.members.getMemberForDeviceKey(i.key))) return
const { value: t } = e,
{ receiver: a, data: s } = t,
o = a,
r = [o, await this.getNextMailboxId()]
if (!(await this.openMailboxes.get(o))) return null
await this.mailboxV2.update(r, { id: i, data: s }, { upsert: !0 })
}
async _applyRemoveMailboxRecordOperation(i, { id: t }) {
const a = await this.members.getMemberForDeviceKey(t.key)
if (!a) return
const { value: s } = i,
o = s.id,
r = await this.mailByMessageId.get([o.key, o.seq])
if (!r) return
const { value: l } = r,
n = [l.key, l.seq]
;(await this.mailboxV2.get(n)) && e.equals(l.key, a.key) && (await this.mailboxV2.delete(n))
}
async _indexCounter(e, i, t) {
i &&
!e &&
(await this.mailboxCounter.insert(t[1]),
await this.mailByMessageId.insert([i.id.key, i.id.seq], { key: t[0], seq: t[1] }))
}
async getNextMailboxId() {
const e = await this.mailboxCounter.peek({ reverse: !0 })
return e ? e.key + 1 : 0
}
async autobaseApply(e, i) {
if (!(await this.view.isFeatureSupported(t.DMS))) return null
switch (e.type) {
case a.TYPE:
return this._applyAddDmRequestOperation(e, i)
case s.TYPE:
return this._applyRemoveDmRequestOperation(e, i)
case r.TYPE:
return this._applyOpenMailboxOperation(e, i)
case l.TYPE:
return this._applyAddMailboxRecordOperation(e, i)
case n.TYPE:
return this._applyRemoveMailboxRecordOperation(e, i)
}
}
async autobaseIndex({ prev: e, next: i, id: t }) {
await this._indexCounter(e, i, t)
}
}