OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-core / lib / api / v1 / helpers.js

158 lines · javascript ref:
const {
    encodeChatMessage: e,
    encodeReactionsDigest: t,
    encodeMyReactions: s,
    encodeCallRecord: n,
  } = require("./encode"),
  { getMemberForDeviceKey: a } = require("../../core/contract/query"),
  l = require("b4a"),
  {
    contract: {
      hyperschema: { getEnum: o },
    },
  } = require("../../../schema/spec"),
  i = o("@keet/label-type")
async function r(e, t, s, n, a, l) {
  const [o, i] = await Promise.all([s.get("@local/rooms", { roomKey: t }), e()])
  if (!i || !o) return []
  const r = Array.isArray(i) ? i : [i],
    c = []
  for (const e of r) c.push(f(t, n, a, o, l, e))
  return Promise.all(c)
}
async function c({ roomKey: e, local: n, snapshot: a, room: l, oplog: o, msgId: i }) {
  const [r, c] = await Promise.all([
    i ? { id: i } : a.get("@keet/chat-by-message-id", { oplog: o }),
    l || n.get("@local/rooms", { roomKey: e }),
  ])
  if (!r || !c) return null
  const { selfMember: d } = c,
    [m, f] = await Promise.all([
      a.get("@keet/reaction-digests", { id: r.id }),
      d
        ? a
            .find("@keet/reactions", {
              gte: { id: r.id, sender: d.key },
              lte: { id: r.id, sender: d.key },
            })
            .toArray()
        : [],
    ])
  return { digest: t(m), mine: s(f) }
}
async function d({ snapshot: e, msgId: t, localRoom: s }) {
  if (!t || !s) return null
  const { selfMember: n } = s,
    [a, l] = await Promise.all([
      e.get("@keet/chat-label-digests", { id: t }),
      !!n &&
        e.findOne("@keet/chat-labels", {
          gte: { id: t, sender: n.key, label: i.Flag },
          lte: { id: t, sender: n.key, label: i.Flag },
        }),
    ])
  return {
    flags: a?.labels.find((e) => e.label === i.Flag)?.count ?? 0,
    flagged: !!l,
    flagsClock: a?.flagsClock ?? 0,
    editedAt: a?.editedAt ?? 0,
  }
}
function m({ dm: e, readLengths: t, selfMember: s }, n) {
  return (
    !!(e?.length && n && t?.length && s) &&
    !!t.find((e) => !l.equals(e.memberKey, s.key) && n.index < e.length)
  )
}
async function f(t, s, n, l, o, i) {
  const r = a(s, i.oplog.key),
    { filePromises: f, linkFilePromises: y } = g(t, s, n, o, i),
    [u, h, b, k] = await Promise.all([
      r,
      Promise.all(f),
      c({ snapshot: s, room: l, msgId: i.id }),
      d({ snapshot: s, localRoom: l, msgId: i.id }),
      Promise.all(y),
    ])
  return (
    (i.reactions = b),
    (i.labels = k),
    h.length && (i.message.files = h),
    (i.read = m(l, i.id)),
    e({ record: i, member: u, localRoom: l })
  )
}
async function y(e, t, s, n, a) {
  const l = await s.get("@keet/files", { id: a })
  if (!l) return null
  const o = await t.getFileEntryWithPreview(e, l.file, { loadBlob: (e) => n.get(e) })
  return { ...l.file, entry: o }
}
function g(e, t, s, n, a) {
  const l = [],
    o = []
  if (a.message?.files?.length > 0) for (const o of a.message.files) l.push(y(e, n, t, s, o))
  const i = a.message?.display?.httpLink || []
  for (const e of i) c(e)
  const r = a.message?.display?.pearLink || []
  for (const e of r) c(e)
  return { filePromises: l, linkFilePromises: o }
  function c(a) {
    if ((a?.preview?.files || []).length) {
      const l = a.preview.files.map(async (l) => {
        a.preview.file = await y(e, n, t, s, l)
      })
      o.push(...l)
    }
  }
}
async function u(e, t) {
  const s = b(e),
    n = await e.findOne(t)
  return n ? s(n) : null
}
async function h(e, t, s = !0) {
  const n = b(e, s)
  return k(e.find(t), n)
}
function b(e, t) {
  return async function (e) {
    const a = { ...e, members: await s(e) }
    return t ? n(a) : a
  }
  async function s({ callKey: t }) {
    return k(
      e.find("@keet/call-members", { gte: { callKey: t }, lte: { callKey: t } }),
      async (e) => ({ ...e, devices: await a(e) }),
    )
  }
  async function a({ callKey: t, memberKey: s }) {
    const n = { gte: { callKey: t, memberKey: s }, lte: { callKey: t, memberKey: s } }
    return k(e.find("@keet/call-devices-by-member-key", n), async (e) => ({
      ...e,
      streams: await l(e),
    }))
  }
  async function l({ callKey: t, deviceKey: s }) {
    const n = { gte: { callKey: t, deviceKey: s }, lte: { callKey: t, deviceKey: s } },
      a = e.find("@keet/call-streams-by-device-key", n),
      l = []
    for await (const e of a) l.push(e)
    return l
  }
}
async function k(e, t) {
  const s = []
  for await (const n of e) s.push(t(n))
  return Promise.all(s)
}
module.exports = {
  getChatMessages: r,
  getReactions: c,
  getChatLabels: d,
  getChatMessage: f,
  getCalls: h,
  getCall: u,
  isDMRead: m,
}