UNPKG

@ssb-graphql/whakapapa

Version:

GraphQL types and resolvers for the ssb-whakapapa plugin

97 lines (81 loc) 2.96 kB
const pull = require('pull-stream') const paraMap = require('pull-paramap') const flatMap = require('pull-flatmap') const { promisify: p } = require('util') const CHILD_LINK = require('ssb-whakapapa/spec/link/profile-profile/child').type const PARTNER_LINK = require('ssb-whakapapa/spec/link/profile-profile/partner').type const State = require('../link-state-helper') module.exports = function LoadFamilyOfPerson (getLinks) { const mapLinks = { fromParentId () { return pull( paraMap((parentId, cb) => getLinks({ type: CHILD_LINK, parentId }, cb), 5), flatMap(links => links) ) }, fromChildId () { return pull( paraMap((childId, cb) => getLinks({ type: CHILD_LINK, childId }, cb), 5), flatMap(links => links) ) }, fromPartnerId () { return pull( paraMap((id, cb) => getLinks({ type: PARTNER_LINK, parentId: id, childId: id }, cb), 5), // NOTE - setting parentId = childId = id means "look up links which have // EITHER parentId === id OR childId === id flatMap(links => links) ) } } return function loadFamilyOfPerson (targetId, { extended }, cb) { if (cb === undefined) return p(loadFamilyOfPerson)(targetId, { extended }) // NOTE this currently doesn't have a way to check for tombstoned profiles const state = State(targetId) process(state, [targetId], (err) => { if (err) return cb(err) cb(null, state.output) }) function process (state, parentIds, cb) { state.resetNewAdults() pull( // for the parents pull.values(parentIds), // load the links from those parents to children, register them mapLinks.fromParentId(), pull.through(state.addChildLink), // for the children we discovered pull.map(link => link.child), // load the link from those children to parents, register them mapLinks.fromChildId(), // in default mode, only include birth-links of children up to parents // in extended mode, include all birth-links !extended ? pull.filter(isBirthLink) : null, pull.drain( state.addChildLink, (err) => { if (err) return cb(err) // now load up the partnerLinks from the initial parents pull( pull.values(parentIds), mapLinks.fromPartnerId(), pull.drain( state.addPartnerLink, (err) => { if (err) return cb(err) // decide if we're going around for another round! if (!extended) return cb(null) if (!state.newAdults.length) return cb(null) process(state, state.newAdults, cb) } ) ) } ) ) } } } function isBirthLink (link) { return link.relationshipType === 'birth' }