improved received requests

This commit is contained in:
Daniel Lugo 2020-02-13 16:11:43 -04:00
parent 45aa0831e4
commit 21210694d5
2 changed files with 67 additions and 62 deletions

View file

@ -1,128 +1,138 @@
/** @format */ /** @format */
const debounce = require('lodash/debounce')
const Key = require('../key') const Key = require('../key')
const Schema = require('../schema') const Schema = require('../schema')
const Streams = require('../streams') const Streams = require('../streams')
/**
* @typedef {import('../schema').HandshakeRequest} HandshakeRequest
* @typedef {import('../schema').SimpleReceivedRequest} SimpleReceivedRequest
*/
/** /**
* @typedef {(reqs: SimpleReceivedRequest[]) => void} Listener * @typedef {Readonly<Schema.SimpleReceivedRequest>} SimpleReceivedRequest
* @typedef {(reqs: ReadonlyArray<SimpleReceivedRequest>) => void} Listener
*/ */
/** @type {Set<Listener>} */ /** @type {Set<Listener>} */
const listeners = new Set() const listeners = new Set()
/** @type {SimpleReceivedRequest[]} */
let currentReqs = []
/** @type {string|null} */ /** @type {string|null} */
let currentAddress = null let currentAddress = null
/** @type {Record<string, HandshakeRequest>} */ /** @type {Record<string, SimpleReceivedRequest>} */
let currentNode = {} let currReceivedReqsMap = {}
const react = () => { /**
/** @type {SimpleReceivedRequest[]} */ * Unprocessed requests in current handshake node.
const finalReqs = [] * @type {Record<string, Schema.HandshakeRequest>}
const pubToIncoming = Streams.getPubToIncoming() */
let currAddressData = {}
/** @returns {SimpleReceivedRequest[]} */
const getReceivedReqs = () => Object.values(currReceivedReqsMap)
/** @param {Record<string, SimpleReceivedRequest>} reqs */
const setReceivedReqsMap = reqs => {
currReceivedReqsMap = reqs
listeners.forEach(l => l(getReceivedReqs()))
}
const react = debounce(() => {
/** @type {Record<string, SimpleReceivedRequest>} */
const newReceivedReqsMap = {}
const pubToFeed = Streams.getPubToFeed()
const pubToAvatar = Streams.getPubToAvatar() const pubToAvatar = Streams.getPubToAvatar()
const pubToDn = Streams.getPubToDn() const pubToDn = Streams.getPubToDn()
for (const [id, req] of Object.entries(currentNode)) { for (const [id, req] of Object.entries(currAddressData)) {
// HERE const inContact = Array.isArray(pubToFeed[req.from])
const notAccepted = typeof pubToIncoming[req.from] === 'undefined'
if (notAccepted) { if (typeof pubToAvatar[req.from] === 'undefined') {
if (typeof pubToAvatar[req.from] === 'undefined') { // eslint-disable-next-line no-empty-function
// eslint-disable-next-line no-empty-function Streams.onAvatar(() => {}, req.from)()
Streams.onAvatar(() => {}, req.from)() }
} if (typeof pubToDn[req.from] === 'undefined') {
if (typeof pubToDn[req.from] === 'undefined') { // eslint-disable-next-line no-empty-function
// eslint-disable-next-line no-empty-function Streams.onDisplayName(() => {}, req.from)()
Streams.onDisplayName(() => {}, req.from)() }
}
finalReqs.push({ if (!inContact) {
newReceivedReqsMap[req.from] = {
id, id,
requestorAvatar: pubToAvatar[req.from] || null, requestorAvatar: pubToAvatar[req.from] || null,
requestorDisplayName: pubToDn[req.from] || null, requestorDisplayName: pubToDn[req.from] || null,
requestorPK: req.from, requestorPK: req.from,
response: req.response,
timestamp: req.timestamp timestamp: req.timestamp
}) }
} }
} }
currentReqs = finalReqs setReceivedReqsMap(newReceivedReqsMap)
}, 750)
listeners.forEach(l => l(currentReqs))
}
/** /**
* @param {string} addr * @param {string} addr
* @returns {(data: import('../SimpleGUN').OpenListenerData) => void} * @returns {(data: import('../SimpleGUN').OpenListenerData) => void}
*/ */
const listenerForAddr = addr => data => { const listenerForAddr = addr => data => {
// did invalidate
if (addr !== currentAddress) { if (addr !== currentAddress) {
return return
} }
if (typeof data === 'object' && data !== null) { if (typeof data !== 'object' || data === null) {
currAddressData = {}
} else {
for (const [id, req] of Object.entries(data)) { for (const [id, req] of Object.entries(data)) {
if (!Schema.isHandshakeRequest(req)) { // no need to update them just write them once
return if (Schema.isHandshakeRequest(req) && !currAddressData[id]) {
currAddressData[id] = req
} }
currentNode[id] = req
} }
react()
} }
react()
} }
let subbed = false let subbed = false
/** /**
* Massages all of the more primitive data structures into a more manageable
* 'Chat' paradigm.
* @param {Listener} cb * @param {Listener} cb
* @returns {() => void} * @returns {() => void}
*/ */
const onReceivedReqs = cb => { const onReceivedReqs = cb => {
listeners.add(cb) listeners.add(cb)
cb(getReceivedReqs())
if (!subbed) { if (!subbed) {
require('./index').onCurrentHandshakeAddress(addr => { require('./index').onCurrentHandshakeAddress(addr => {
if (currentAddress !== addr) { if (currentAddress === addr) {
currentAddress = addr return
currentNode = {} }
if (typeof addr === 'string') { currentAddress = addr
require('../../Mediator') currAddressData = {}
.getGun() setReceivedReqsMap({})
.get(Key.HANDSHAKE_NODES)
.get(addr)
.open(listenerForAddr(addr))
}
react() if (typeof addr === 'string') {
require('../../Mediator')
.getGun()
.get(Key.HANDSHAKE_NODES)
.get(addr)
.open(listenerForAddr(addr))
} }
}, require('../../Mediator').getUser()) }, require('../../Mediator').getUser())
Streams.onAvatar(react) Streams.onAvatar(react)
Streams.onDisplayName(react) Streams.onDisplayName(react)
Streams.onIncoming(react) Streams.onPubToFeed(react)
subbed = true subbed = true
} }
cb(currentReqs)
return () => { return () => {
listeners.delete(cb) listeners.delete(cb)
} }
} }
module.exports = onReceivedReqs module.exports = {
getReceivedReqs,
onReceivedReqs
}

View file

@ -213,7 +213,6 @@ exports.isSimpleSentRequest = item => {
* @prop {string|null} requestorAvatar * @prop {string|null} requestorAvatar
* @prop {string|null} requestorDisplayName * @prop {string|null} requestorDisplayName
* @prop {string} requestorPK * @prop {string} requestorPK
* @prop {string} response
* @prop {number} timestamp * @prop {number} timestamp
*/ */
@ -251,10 +250,6 @@ exports.isSimpleReceivedRequest = item => {
return false return false
} }
if (typeof obj.response !== 'string') {
return false
}
if (typeof obj.timestamp !== 'number') { if (typeof obj.timestamp !== 'number') {
return false return false
} }