mirror of https://codeberg.org/pzp/pzp-goals.git
getMsgPurpose returns also details alongside purpose tag
This commit is contained in:
parent
e14fd87658
commit
c4fd63239f
22
lib/index.js
22
lib/index.js
|
@ -13,6 +13,7 @@ const Obz = require('obz')
|
||||||
* @typedef {'none'|'all'|'newest'|'record'|'set'} GoalType
|
* @typedef {'none'|'all'|'newest'|'record'|'set'} GoalType
|
||||||
* @typedef {[number, number]} Range
|
* @typedef {[number, number]} Range
|
||||||
* @typedef {{ id: string, type: GoalType, count: number }} Goal
|
* @typedef {{ id: string, type: GoalType, count: number }} Goal
|
||||||
|
* @typedef {{ tangleID: MsgID, span: number }} GhostDetails
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +40,11 @@ const Obz = require('obz')
|
||||||
* These tags are ordered, "none" < "ghost" < "trail" < "goal", meaning that a
|
* These tags are ordered, "none" < "ghost" < "trail" < "goal", meaning that a
|
||||||
* msg with purpose "goal" may *also* fulfill the purpose of "trail", and a
|
* msg with purpose "goal" may *also* fulfill the purpose of "trail", and a
|
||||||
* "trail" also prevents accidental re-request like "ghost" does.
|
* "trail" also prevents accidental re-request like "ghost" does.
|
||||||
* @typedef {'none' | 'ghost' | 'trail' | 'goal'} Purpose
|
* @typedef {['none']
|
||||||
|
* | ['ghost', GhostDetails]
|
||||||
|
* | ['trail']
|
||||||
|
* | ['goal']
|
||||||
|
* } PurposeWithDetails
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,7 +199,7 @@ function initGoals(peer, config) {
|
||||||
* @public
|
* @public
|
||||||
* @param {MsgID} msgID
|
* @param {MsgID} msgID
|
||||||
* @param {Msg} msg
|
* @param {Msg} msg
|
||||||
* @returns {Purpose}
|
* @returns {PurposeWithDetails}
|
||||||
*/
|
*/
|
||||||
function getMsgPurpose(msgID, msg) {
|
function getMsgPurpose(msgID, msg) {
|
||||||
assertDBPlugin(peer)
|
assertDBPlugin(peer)
|
||||||
|
@ -208,7 +213,7 @@ function initGoals(peer, config) {
|
||||||
if (!tangle) break asRoot
|
if (!tangle) break asRoot
|
||||||
const [min, max] = crossGoalWithTangle(goal, tangle)
|
const [min, max] = crossGoalWithTangle(goal, tangle)
|
||||||
if (min > max) break asRoot
|
if (min > max) break asRoot
|
||||||
if (min === 0) return 'goal'
|
if (min === 0) return ['goal']
|
||||||
if (min > 0) servesAsTrail = true
|
if (min > 0) servesAsTrail = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,11 +234,11 @@ function initGoals(peer, config) {
|
||||||
}
|
}
|
||||||
// (Loop over once without heavy computations and maybe return early:)
|
// (Loop over once without heavy computations and maybe return early:)
|
||||||
for (const [, min, max, recDepth] of validTangles) {
|
for (const [, min, max, recDepth] of validTangles) {
|
||||||
if (min <= recDepth && recDepth <= max) return 'goal'
|
if (min <= recDepth && recDepth <= max) return ['goal']
|
||||||
}
|
}
|
||||||
// At this point we know that the record *cannot* serve as 'goal',
|
// At this point we know that the record *cannot* serve as 'goal',
|
||||||
// so if it serves as trail, that'll do:
|
// so if it serves as trail, that'll do:
|
||||||
if (servesAsTrail) return 'trail'
|
if (servesAsTrail) return ['trail']
|
||||||
// Check whether this record is a trail affix of some tangle:
|
// Check whether this record is a trail affix of some tangle:
|
||||||
// (Loop again with heavy computations now that it's inevitable:)
|
// (Loop again with heavy computations now that it's inevitable:)
|
||||||
for (const [tangle, min] of validTangles) {
|
for (const [tangle, min] of validTangles) {
|
||||||
|
@ -241,20 +246,21 @@ function initGoals(peer, config) {
|
||||||
.topoSort()
|
.topoSort()
|
||||||
.filter((msgID) => tangle.getDepth(msgID) === min)
|
.filter((msgID) => tangle.getDepth(msgID) === min)
|
||||||
const { erasables } = tangle.getDeletablesAndErasables(...minMsgIDs)
|
const { erasables } = tangle.getDeletablesAndErasables(...minMsgIDs)
|
||||||
if (erasables.has(msgID)) return 'trail'
|
if (erasables.has(msgID)) return ['trail']
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether this record is a ghost affix of some tangle:
|
// Check whether this record is a ghost affix of some tangle:
|
||||||
for (const [tangle, , , , goalType] of validTangles) {
|
for (const [tangle, , , , goalType] of validTangles) {
|
||||||
if (goalType === 'record') {
|
if (goalType === 'record') {
|
||||||
assertRecordPlugin(peer)
|
assertRecordPlugin(peer)
|
||||||
|
const span = peer.record.getGhostSpan()
|
||||||
if (peer.record.isGhostable(msgID, tangle.id)) {
|
if (peer.record.isGhostable(msgID, tangle.id)) {
|
||||||
return 'ghost'
|
return ['ghost', {tangleID: tangle.id, span }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'none'
|
return ['none']
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,7 +34,10 @@ test('set, getByID, list, listen', async (t) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const purpose = alice.goals.getMsgPurpose(aliceAccountRoot.id, aliceAccountRoot.msg)
|
const [purpose] = alice.goals.getMsgPurpose(
|
||||||
|
aliceAccountRoot.id,
|
||||||
|
aliceAccountRoot.msg
|
||||||
|
)
|
||||||
assert.equal(purpose, 'goal', 'rec purpose is "goal"')
|
assert.equal(purpose, 'goal', 'rec purpose is "goal"')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,12 +94,12 @@ test('getMsgPurpose', async (t) => {
|
||||||
const gottenGoal = alice.goals.get(feedID)
|
const gottenGoal = alice.goals.get(feedID)
|
||||||
assert.strictEqual(gottenGoal.id, feedID, 'gotten goal id is correct')
|
assert.strictEqual(gottenGoal.id, feedID, 'gotten goal id is correct')
|
||||||
|
|
||||||
const purpose = alice.goals.getMsgPurpose(post2.id, post2.msg)
|
const [purpose] = alice.goals.getMsgPurpose(post2.id, post2.msg)
|
||||||
assert.equal(purpose, 'goal', 'purpose is "goal"')
|
assert.equal(purpose, 'goal', 'purpose is "goal"')
|
||||||
|
|
||||||
alice.goals.set(feedID, 'newest-1')
|
alice.goals.set(feedID, 'newest-1')
|
||||||
assert('set goal to newest-1')
|
assert('set goal to newest-1')
|
||||||
const purpose2 = alice.goals.getMsgPurpose(post2.id, post2.msg)
|
const [purpose2] = alice.goals.getMsgPurpose(post2.id, post2.msg)
|
||||||
assert.equal(purpose2, 'none', 'purpose2 is "none"')
|
assert.equal(purpose2, 'none', 'purpose2 is "none"')
|
||||||
|
|
||||||
await p(alice.close)(true)
|
await p(alice.close)(true)
|
||||||
|
@ -123,14 +126,18 @@ test('getMsgPurpose ghost', async (t) => {
|
||||||
|
|
||||||
const msgIDs = tangle.topoSort()
|
const msgIDs = tangle.topoSort()
|
||||||
assert.equal(msgIDs.length, 6, 'tangle has root+5 messages')
|
assert.equal(msgIDs.length, 6, 'tangle has root+5 messages')
|
||||||
const recs = msgIDs.map(id => alice.db.getRecord(id))
|
const recs = msgIDs.map((id) => alice.db.getRecord(id))
|
||||||
|
|
||||||
alice.goals.set(feedID, 'record')
|
alice.goals.set(feedID, 'record')
|
||||||
assert.equal(alice.goals.getMsgPurpose(recs[1].id, recs[1].msg), 'none')
|
assert.equal(alice.goals.getMsgPurpose(recs[1].id, recs[1].msg)[0], 'none')
|
||||||
assert.equal(alice.goals.getMsgPurpose(recs[2].id, recs[2].msg), 'ghost')
|
assert.equal(alice.goals.getMsgPurpose(recs[2].id, recs[2].msg)[0], 'ghost')
|
||||||
assert.equal(alice.goals.getMsgPurpose(recs[3].id, recs[3].msg), 'trail')
|
assert.equal(alice.goals.getMsgPurpose(recs[3].id, recs[3].msg)[0], 'trail')
|
||||||
assert.equal(alice.goals.getMsgPurpose(recs[4].id, recs[4].msg), 'trail')
|
assert.equal(alice.goals.getMsgPurpose(recs[4].id, recs[4].msg)[0], 'trail')
|
||||||
assert.equal(alice.goals.getMsgPurpose(recs[5].id, recs[5].msg), 'goal')
|
assert.equal(alice.goals.getMsgPurpose(recs[5].id, recs[5].msg)[0], 'goal')
|
||||||
|
|
||||||
|
const [purpose, details] = alice.goals.getMsgPurpose(recs[2].id, recs[2].msg)
|
||||||
|
assert.equal(purpose, 'ghost')
|
||||||
|
assert.deepEqual(details, { tangleID: feedID, span: 3 })
|
||||||
|
|
||||||
await p(alice.close)(true)
|
await p(alice.close)(true)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue