const e = require("ready-resource"),
t = require("safety-catch"),
i = require("b4a"),
o = require("./view"),
{ ConfigKey: s } = require("./constants"),
n = require("../../schema/spec"),
a = n.api.hrpc
module.exports = class extends e {
static View = o
static ConfigKey = s
static Schemas = {
Contract: n.contract.hyperschema,
Local: n.local.hyperschema,
Api: n.api.hyperschema,
Config: n.config.hyperschema,
}
constructor(e, i) {
;(super(),
(this.rpc = new a(e)),
(this.view = new o()),
(this.opts = i),
(this._wantClock = 0),
(this._haveClock = 0),
(this._unwants = new Map()),
(this._gcInterval = setInterval(() => this._gc(), 1e3)),
this.rpc.onCoreHaveIdentity(this._handleHaveIdentity.bind(this)),
this.rpc.onCoreHavePairing(this._handleHavePairing.bind(this)),
this.rpc.onCoreHaveLobby(this._handleHaveLobby.bind(this)),
this.rpc.onCoreHaveChat(this._handleHaveChat.bind(this)),
this.rpc.onCoreHaveMembers(this._handleHaveMembers.bind(this)),
this.rpc.onCoreHaveRoomInfo(this._handleHaveRoomInfo.bind(this)),
this.rpc.onCoreIdentityReset(this._handleIdentityReset.bind(this)),
this.rpc.onCoreIdentityMember(this._handleIdentityMember.bind(this)),
this.rpc.onCoreIdentityDevice(this._handleIdentityDevice.bind(this)),
this.rpc.onCorePairingReset(this._handlePairingReset.bind(this)),
this.rpc.onCoreLobbyReset(this._handleLobbyReset.bind(this)),
this.rpc.onCoreLobbyRoom(this._handleLobbyRoom.bind(this)),
this.rpc.onCoreChatReset(this._handleChatReset.bind(this)),
this.rpc.onCoreRoomInfo(this._handleRoomInfo.bind(this)),
this.rpc.onCoreRoomInfoRole(this._handleRoomInfoRole.bind(this)),
this.rpc.onCoreRoomInfoDigest(this._handleRoomInfoDigest.bind(this)),
this.rpc.onCoreRoomInfoConfig(this._handleRoomInfoConfig.bind(this)),
this.rpc.onCoreRoomInfoLastMessage(this._handleRoomInfoLastMessage.bind(this)),
this.rpc.onCoreMessageInfo(this._handleMessageInfo.bind(this)),
this.rpc.onCoreMessageInfoChat(this._handleMessageInfoChat.bind(this)),
this.rpc.onCoreMessageInfoRole(this._handleMessageInfoRole.bind(this)),
this.rpc.onCoreMessageInfoMember(this._handleMessageInfoMember.bind(this)),
this.rpc.onCoreMessageInfoReactions(this._handleMessageInfoReactions.bind(this)),
this.rpc.onCoreMemberListAdd(this._handleMemberListAdd.bind(this)),
this.rpc.onCoreMemberListRemove(this._handleMemberListRemove.bind(this)),
this.rpc.onCoreMember(this._handleMember.bind(this)),
this.rpc.onCoreDevice(this._handleDevice.bind(this)),
this.ready().catch(t))
}
_makeRequest(e) {
return { header: { timestamp: Date.now() }, ...e }
}
_makeWant(e) {
const t = { clock: ++this._wantClock, ...e }
return { want: t, unwant: { clock: t.clock } }
}
_awaitHave(e, t) {
return new Promise((i) => {
const o = (s) => {
s === t && (e.off("have", o), i(t))
}
e.on("have", o)
})
}
_open() {}
_close() {
clearInterval(this._gcInterval)
}
_gc() {
this._haveClock < this._wantClock ||
(this.view.members.maybeGC(),
this.view.devices.maybeGC(),
this.view.reactions.maybeGC(),
this.view.messages.maybeGC(),
this.view.rooms.maybeGC())
}
_handleIdentityReset(e) {
this.view.identity.onReset(e)
}
_handleIdentityMember(e) {
this.view.identity.onMemberChanged(e)
}
_handleIdentityDevice(e) {
this.view.identity.onDeviceChanged(e)
}
_handlePairingReset(e) {
this.view.pairing.onReset(e)
}
_handleLobbyReset(e) {
this.view.lobby.onReset(e)
}
_handleLobbyRoom(e) {
this.view.lobby.onRoom(e)
}
_handleRoomInfo(e) {
this.view.roomInfo.onAdd(e)
}
_handleRoomInfoRole(e) {
const t = i.toString(e.id, "hex")
this.view.roomInfo.onRoleChanged({ id: t, role: e.role })
}
_handleRoomInfoDigest(e) {
const t = i.toString(e.id, "hex")
this.view.roomInfo.onDigestChanged({ id: t, digest: e.digest })
}
_handleRoomInfoConfig(e) {
const t = i.toString(e.id, "hex")
this.view.roomInfo.onConfigChanged({ id: t, config: e.config })
}
_handleRoomInfoLastMessage(e) {
const t = i.toString(e.id, "hex")
this.view.roomInfo.onLastMessageChanged({ id: t, messageId: e.lastMessage })
}
_handleMessageInfo(e) {
this.view.messageInfo.onAdd(e)
}
_handleMessageInfoChat(e) {
this.view.messageInfo.onChatChanged(e)
}
_handleMessageInfoRole(e) {
this.view.messageInfo.onRoleChanged(e)
}
_handleMessageInfoMember(e) {
this.view.messageInfo.onMemberChanged(e)
}
_handleMessageInfoReactions(e) {
this.view.messageInfo.onReactionsChanged(e)
}
_handleChatReset(e) {
this.view.chat.onReset(e)
}
_handleMemberListAdd() {}
_handleMemberListRemove() {}
_handlePairingChanged() {}
_handleMessage(e) {
this.view.messages.add(e)
}
_handleReactions(e) {
this.view.reactions.add(e)
}
_handleMember(e) {
this.view.members.add(e)
}
_handleDevice(e) {
this.view.devices.add(e)
}
_handleHaveIdentity({ clock: e }) {
;((this._haveClock = Math.max(this._haveClock, e)), this.view.identity.onHave(e))
}
_handleHavePairing({ clock: e }) {
;((this._haveClock = Math.max(this._haveClock, e)), this.view.pairing.onHave(e))
}
_handleHaveLobby({ clock: e }) {
;((this._haveClock = Math.max(this._haveClock, e)), this.view.lobby.onHave(e))
}
_handleHaveRoomInfo({ clock: e }) {
;((this._haveClock = Math.max(this._haveClock, e)), this.view.rooms.onHave(e))
}
_handleHaveChat({ clock: e }) {
;((this._haveClock = Math.max(this._haveClock, e)), this.view.chat.onHave(e))
}
_handleHaveMembers({ clock: e }) {
;((this._haveClock = Math.max(this._haveClock, e)), this.view.members.onHave(e))
}
viewIdentity() {
const { want: e, unwant: t } = this._makeWant()
return (
this.view.identity.onWant(e.clock),
this.rpc.coreWantIdentity(e),
this._unwants.set(e.clock, () => {
;(this.view.identity.onCancel(e.clock), this.rpc.coreUnwantIdentity(t))
}),
this._awaitHave(this.view.identity, e.clock)
)
}
viewPairing() {
const { want: e, unwant: t } = this._makeWant()
return (
this.view.pairing.onWant(e.clock),
this.rpc.coreWantPairing(e),
this._unwants.set(e.clock, () => {
;(this.view.pairing.onCancel(e.clock), this.rpc.coreUnwantPairing(t))
}),
this._awaitHave(this.view.pairing, e.clock)
)
}
viewLobby({ start: e = 0, end: t = 0 } = {}) {
const { want: i, unwant: o } = this._makeWant({ start: e, end: t })
return (
this.view.lobby.onWant(i.clock, e, t),
this.rpc.coreWantLobby(i),
this._unwants.set(i.clock, () => {
;(this.view.lobby.onCancel(i.clock), this.rpc.coreUnwantLobby(o))
}),
this._awaitHave(this.view.lobby, i.clock)
)
}
viewChat({ roomKey: e, start: t = 0, size: i = 0, isBottom: o = !1 } = {}) {
const { want: s, unwant: n } = this._makeWant({ roomKey: e, start: t, size: i, isBottom: o })
return (
this.view.chat.onWant(s.clock, e, t, i, o),
this.rpc.coreWantChat(s),
this._unwants.set(s.clock, () => {
;(this.view.chat.onCancel(s.clock), this.rpc.coreUnwantChat(n))
}),
this._awaitHave(this.view.chat, s.clock)
)
}
viewMembers(e, t, i) {
this.rpc.coreWantMembers(this._makeWant({ roomKey: e, offset: t, count: i }))
}
viewReactions(e, t, i, o) {
this.rpc.coreWantReactions(this._makeWant({ roomKey: e, messageId: t, offset: i, count: o }))
}
cancel(e) {}
async boot() {
await this.rpc.boot(this._makeRequest(this.opts))
}
async createRoom(e = {}) {
const t = await this.rpc.coreCreateRoom(this._makeRequest(e))
return { roomKey: t.roomKey, roomId: i.toString(t.roomKey, "hex") }
}
leaveRoom(e) {
return this.rpc.coreLeaveRoom(this._makeRequest({ roomKey: e }))
}
activateRoom(e) {
return this.rpc.coreActivateRoom(this._makeRequest({ roomKey: e }))
}
deactivateRoom(e) {
return this.rpc.coreDeactivateRoom(this._makeRequest({ roomKey: e }))
}
updateRoomConfig(e, t, i) {
return this.rpc.coreUpdateRoomConfig(this._makeRequest({ roomKey: e, key: t, config: i }))
}
async startPairingRoom(e) {
return this.rpc.coreStartPairing(this._makeRequest({ invitation: e, isIdentity: !1 }))
}
async startPairingIdentity(e) {
return this.rpc.coreStartPairing(this._makeRequest({ invitation: e, isIdentity: !0 }))
}
createRoomInvitation(e, t = {}) {
return this.rpc.coreCreateRoomInvitation(
this._makeRequest({ roomKey: e, permissions: t, expiration: t.expiration }),
)
}
createIdentityInvitation() {
return this.rpc.coreCreateIdentityInvitation(this._makeRequest())
}
acceptJoinRequest(e, t) {
return this.rpc.coreAcceptJoinRequest(this._makeRequest({ roomKey: e, request: t }))
}
rejectJoinRequest(e, t) {
return this.rpc.coreRejectJoinRequest(this._makeRequest({ roomKey: e, request: t }))
}
stopPairing(e) {
return this.rpc.coreStopPairing(this._makeRequest({ id: e }))
}
addChatMessage(e, t) {
return this.rpc.coreAddChatMessage(this._makeRequest({ roomKey: e, message: t }))
}
editChatMessage(e, t, i) {
return this.rpc.coreEditChatMessage(this._makeRequest({ roomKey: e, id: t, message: i }))
}
removeChatMessage(e, t) {
return this.rpc.coreRemoveChatMessage(this._makeRequest({ roomKey: e, id: t }))
}
addChatReaction(e, t, i) {
return this.rpc.coreAddChatReaction(this._makeRequest({ roomKey: e, id: t, reaction: i }))
}
removeChatReaction(e, t, i) {
return this.rpc.coreRemoveChatReaction(this._makeRequest({ roomKey: e, id: t, reaction: i }))
}
updateProfile(e) {
return this.rpc.coreUpdateProfile(this._makeRequest(e))
}
}