diff --git a/lib/index.js b/lib/index.js index 8cafa66..766c9b7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,18 +3,22 @@ const Obz = require('obz') /** * @typedef {import('ppppp-db/msg-v3').RecPresent} RecPresent + * @typedef {import('ppppp-db').Tangle} Tangle * + * @typedef {'none'} GoalNone * @typedef {'all'} GoalAll * @typedef {`newest-${number}`} GoalNewest * @typedef {`oldest-${number}`} GoalOldest - * @typedef {GoalAll|GoalNewest|GoalOldest} GoalDSL + * @typedef {GoalNone|GoalAll|GoalNewest|GoalOldest} GoalDSL + * + * @typedef {[number, number]} Range */ class Goal { /** @type {string} */ #id - /** @type {'all' | 'newest' | 'oldest'} */ + /** @type {'none' | 'all' | 'newest' | 'oldest'} */ #type /** @type {number} */ @@ -27,6 +31,13 @@ class Goal { */ constructor(tangleID, goalDSL) { this.#id = tangleID + + if (goalDSL === 'none') { + this.#type = 'all' + this.#count = 0 + return + } + if (goalDSL === 'all') { this.#type = 'all' this.#count = Infinity @@ -79,7 +90,33 @@ module.exports = { const goals = new Map() const listen = Obz() + /** @type {Range} */ + const EMPTY_RANGE = [1, 0] + /** + * @private + * @param {Goal} goal + * @param {Tangle} tangle + * @returns {Range} + */ + function crossGoalWithTangle(goal, tangle) { + const maxDepth = tangle.maxDepth + switch (goal.type) { + case 'none': + return EMPTY_RANGE + case 'all': + return [0, maxDepth] + case 'newest': + const start = Math.max(0, maxDepth - goal.count) + return [start, maxDepth] + case 'oldest': + const end = Math.min(maxDepth, goal.count) + return [0, end] + } + } + + /** + * @public * @param {string} tangleID * @param {GoalDSL} goalDSL * @returns {void} @@ -114,7 +151,12 @@ module.exports = { for (const tangleID in rec.msg.metadata.tangles) { if (goals.has(tangleID)) { const goal = /** @type {Goal} */ (goals.get(tangleID)) - arr.push(goal) + const tangle = peer.db.getTangle(tangleID) + if (tangle) { + const [min, max] = crossGoalWithTangle(goal, tangle) + const depth = tangle.getDepth(rec.id) + if (depth >= 0 && min <= depth && depth <= max) arr.push(goal) + } } } } diff --git a/test/goals.test.js b/test/goals.test.js index bebb8b5..96daf25 100644 --- a/test/goals.test.js +++ b/test/goals.test.js @@ -89,11 +89,17 @@ test('getByRec', async (t) => { const gottenGoal = alice.goals.getByID(feedID) assert.strictEqual(gottenGoal.id, feedID, 'gotten goal id is correct') - const recGoals = alice.goals.getByRec(post1) + const recGoals = alice.goals.getByRec(post2) assert(Array.isArray(recGoals), 'recGoals is an array') assert.strictEqual(recGoals.length, 1, 'recGoals has one item') const recGoal = recGoals[0] assert.strictEqual(recGoal.id, feedID, 'recGoal id is correct') + alice.goals.set(feedID, 'oldest-1') + assert('set goal to oldest-1') + const recGoals2 = alice.goals.getByRec(post2) + assert(Array.isArray(recGoals2), 'recGoals is an array') + assert.strictEqual(recGoals2.length, 0, 'recGoals2 has zero items') + await p(alice.close)(true) })