mirror of https://codeberg.org/pzp/pzp-goals.git
correct semantics for getRecordPurpose ghost logic
This commit is contained in:
parent
ca8f2ceed1
commit
ba364192ce
37
lib/index.js
37
lib/index.js
|
@ -188,9 +188,9 @@ function initGoals(peer, config) {
|
|||
/**
|
||||
* @public
|
||||
* @param {RecPresent} rec
|
||||
* @param {CB<Purpose>} cb
|
||||
* @returns {Purpose}
|
||||
*/
|
||||
function getRecordPurpose(rec, cb) {
|
||||
function getRecordPurpose(rec) {
|
||||
assertDBPlugin(peer)
|
||||
let servesAsTrail = false
|
||||
|
||||
|
@ -202,13 +202,13 @@ function initGoals(peer, config) {
|
|||
if (!tangle) break asRoot
|
||||
const [min, max] = crossGoalWithTangle(goal, tangle)
|
||||
if (min > max) break asRoot
|
||||
if (min === 0) return cb(null, 'goal')
|
||||
if (min === 0) return 'goal'
|
||||
if (min > 0) servesAsTrail = true
|
||||
}
|
||||
|
||||
// Check whether this record is a goalful affix of some tangle:
|
||||
const validTangles =
|
||||
/** @type {Array<[DBTangle, number, number, number]>} */ ([])
|
||||
/** @type {Array<[DBTangle, number, number, number, GoalType]>} */ ([])
|
||||
asAffix: for (const tangleID in rec.msg.metadata.tangles) {
|
||||
if (!goals.has(tangleID)) continue asAffix
|
||||
const goal = /** @type {GoalImpl} */ (goals.get(tangleID))
|
||||
|
@ -219,15 +219,15 @@ function initGoals(peer, config) {
|
|||
if (min > max) continue asAffix
|
||||
const recDepth = tangle.getDepth(rec.id)
|
||||
if (recDepth < 0) continue asAffix
|
||||
validTangles.push([tangle, min, max, recDepth])
|
||||
validTangles.push([tangle, min, max, recDepth, goal.type])
|
||||
}
|
||||
// (Loop over once without heavy computations and maybe return early:)
|
||||
for (const [, min, max, recDepth] of validTangles) {
|
||||
if (min <= recDepth && recDepth <= max) return cb(null, 'goal')
|
||||
if (min <= recDepth && recDepth <= max) return 'goal'
|
||||
}
|
||||
// At this point we know that the record *cannot* serve as 'goal',
|
||||
// so if it serves as trail, that'll do:
|
||||
if (servesAsTrail) return cb(null, 'trail')
|
||||
if (servesAsTrail) return 'trail'
|
||||
// Check whether this record is a trail affix of some tangle:
|
||||
// (Loop again with heavy computations now that it's inevitable:)
|
||||
for (const [tangle, min] of validTangles) {
|
||||
|
@ -235,27 +235,20 @@ function initGoals(peer, config) {
|
|||
.topoSort()
|
||||
.filter((msgID) => tangle.getDepth(msgID) === min)
|
||||
const { erasables } = tangle.getDeletablesAndErasables(...minMsgIDs)
|
||||
if (erasables.has(rec.id)) return cb(null, 'trail')
|
||||
if (erasables.has(rec.id)) return 'trail'
|
||||
}
|
||||
|
||||
// Check whether this record is a ghost affix of some tangle:
|
||||
if (validTangles.length > 0) {
|
||||
const done = /** @type {Multicb<Array<MsgID>>} */ (multicb({ pluck: 1 }))
|
||||
for (const [tangle] of validTangles) {
|
||||
peer.db.ghosts.get(tangle.id, done())
|
||||
}
|
||||
done((err, allGhosts) => {
|
||||
// prettier-ignore
|
||||
if (err) return cb(new Error('getRecordPurpose() failed to get ghosts', {cause: err}))
|
||||
for (const ghosts of allGhosts) {
|
||||
if (ghosts.includes(rec.id)) return cb(null, 'ghost')
|
||||
for (const [tangle, , , , goalType] of validTangles) {
|
||||
if (goalType === 'record') {
|
||||
assertRecordPlugin(peer)
|
||||
if (peer.record.isGhostable(rec.id, tangle.id)) {
|
||||
return 'ghost'
|
||||
}
|
||||
cb(null, 'none')
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
cb(null, 'none')
|
||||
return 'none'
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,7 +34,7 @@ test('set, getByID, list, listen', async (t) => {
|
|||
}
|
||||
|
||||
{
|
||||
const purpose = await p(alice.goals.getRecordPurpose)(aliceAccountRoot)
|
||||
const purpose = alice.goals.getRecordPurpose(aliceAccountRoot)
|
||||
assert.equal(purpose, 'goal', 'rec purpose is "goal"')
|
||||
}
|
||||
|
||||
|
@ -91,17 +91,46 @@ test('getRecordPurpose', async (t) => {
|
|||
const gottenGoal = alice.goals.get(feedID)
|
||||
assert.strictEqual(gottenGoal.id, feedID, 'gotten goal id is correct')
|
||||
|
||||
const purpose = await p(alice.goals.getRecordPurpose)(post2)
|
||||
const purpose = alice.goals.getRecordPurpose(post2)
|
||||
assert.equal(purpose, 'goal', 'purpose is "goal"')
|
||||
|
||||
alice.goals.set(feedID, 'newest-1')
|
||||
assert('set goal to newest-1')
|
||||
const purpose2 = await p(alice.goals.getRecordPurpose)(post2)
|
||||
const purpose2 = alice.goals.getRecordPurpose(post2)
|
||||
assert.equal(purpose2, 'none', 'purpose2 is "none"')
|
||||
|
||||
await p(alice.db.ghosts.add)({ msg: post2.id, tangle: feedID, max: 5 })
|
||||
const purpose3 = await p(alice.goals.getRecordPurpose)(post2)
|
||||
assert.equal(purpose3, 'ghost', 'purpose3 is "ghost"')
|
||||
|
||||
await p(alice.close)(true)
|
||||
})
|
||||
|
||||
test('getRecordPurpose ghost', async (t) => {
|
||||
const alice = createPeer({ name: 'alice', record: {ghostSpan: 3} })
|
||||
|
||||
await alice.db.loaded()
|
||||
const aliceID = await p(alice.db.account.create)({
|
||||
domain: 'account',
|
||||
_nonce: 'alice',
|
||||
})
|
||||
|
||||
await p(alice.record.load)(aliceID)
|
||||
await p(alice.record.update)('profile', { name: 'alice' })
|
||||
await p(alice.record.update)('profile', { name: 'Alice' })
|
||||
await p(alice.record.update)('profile', { name: 'Alicia' })
|
||||
await p(alice.record.update)('profile', { name: 'ALICIA' })
|
||||
await p(alice.record.update)('profile', { name: 'ALICIAA' })
|
||||
|
||||
const feedID = alice.record.getFeedID('profile')
|
||||
const tangle = alice.db.getTangle(feedID)
|
||||
|
||||
const msgIDs = tangle.topoSort()
|
||||
assert.equal(msgIDs.length, 6, 'tangle has root+5 messages')
|
||||
const recs = msgIDs.map(id => alice.db.getRecord(id))
|
||||
|
||||
alice.goals.set(feedID, 'record')
|
||||
assert.equal(alice.goals.getRecordPurpose(recs[1]), 'none')
|
||||
assert.equal(alice.goals.getRecordPurpose(recs[2]), 'ghost')
|
||||
assert.equal(alice.goals.getRecordPurpose(recs[3]), 'trail')
|
||||
assert.equal(alice.goals.getRecordPurpose(recs[4]), 'trail')
|
||||
assert.equal(alice.goals.getRecordPurpose(recs[5]), 'goal')
|
||||
|
||||
await p(alice.close)(true)
|
||||
})
|
||||
|
|
|
@ -18,6 +18,7 @@ function createPeer(opts) {
|
|||
.use(require('secret-stack/plugins/net'))
|
||||
.use(require('secret-handshake-ext/secret-stack'))
|
||||
.use(require('ppppp-db'))
|
||||
.use(require('ppppp-record'))
|
||||
.use(require('ssb-box'))
|
||||
.use(require('../lib'))
|
||||
.call(null, {
|
||||
|
|
Loading…
Reference in New Issue