replace ppppp-record with ppppp-dict

This commit is contained in:
Andre Staltz 2023-10-26 13:27:23 +03:00
parent 0bc405739e
commit 4c29073028
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
5 changed files with 39 additions and 40 deletions

View File

@ -5,7 +5,7 @@ const { EMPTY_RANGE, isEmptyRange, estimateMsgCount } = require('./range')
/** /**
* @typedef {ReturnType<import('ppppp-db').init>} PPPPPDB * @typedef {ReturnType<import('ppppp-db').init>} PPPPPDB
* @typedef {ReturnType<import('ppppp-record').init>} PPPPPRecord * @typedef {ReturnType<import('ppppp-dict').init>} PPPPPDict
* @typedef {import('ppppp-db/msg-v3').Msg} Msg * @typedef {import('ppppp-db/msg-v3').Msg} Msg
* @typedef {import('ppppp-goals').Goal} Goal * @typedef {import('ppppp-goals').Goal} Goal
* @typedef {import('./range').Range} Range * @typedef {import('./range').Range} Range
@ -22,20 +22,20 @@ function countIter(iter) {
} }
/** /**
* @param {{ record: PPPPPRecord | null }} peer * @param {{ dict: PPPPPDict | null }} peer
* @returns {asserts peer is { record: PPPPPRecord }} * @returns {asserts peer is { dict: PPPPPDict }}
*/ */
function assertRecordPlugin(peer) { function assertDictPlugin(peer) {
if (!peer.record) { if (!peer.dict) {
throw new Error('tanglesync plugin requires ppppp-record plugin') throw new Error('tanglesync plugin requires ppppp-dict plugin')
} }
} }
class Algorithm { class Algorithm {
/** @type {{ db: PPPPPDB, record: PPPPPRecord | null }} */ /** @type {{ db: PPPPPDB, dict: PPPPPDict | null }} */
#peer #peer
/** @param {{ db: PPPPPDB, record: PPPPPRecord | null }} peer */ /** @param {{ db: PPPPPDB, dict: PPPPPDict | null }} peer */
constructor(peer) { constructor(peer) {
this.#peer = peer this.#peer = peer
} }
@ -97,7 +97,7 @@ class Algorithm {
* @param {Range} remoteHaveRange * @param {Range} remoteHaveRange
* @returns {Range} * @returns {Range}
*/ */
#wantRecordRange(minGhostDepth, remoteHaveRange) { #wantDictRange(minGhostDepth, remoteHaveRange) {
const [minRemoteHave, maxRemoteHave] = remoteHaveRange const [minRemoteHave, maxRemoteHave] = remoteHaveRange
if (maxRemoteHave < minGhostDepth) return EMPTY_RANGE if (maxRemoteHave < minGhostDepth) return EMPTY_RANGE
const maxWant = maxRemoteHave const maxWant = maxRemoteHave
@ -119,10 +119,10 @@ class Algorithm {
case 'all': case 'all':
return this.#wantAllRange(localHave, remoteHave) return this.#wantAllRange(localHave, remoteHave)
case 'record': case 'dict':
assertRecordPlugin(this.#peer) assertDictPlugin(this.#peer)
const minGhostDepth = this.#peer.record.minGhostDepth(goal.id) const minGhostDepth = this.#peer.dict.minGhostDepth(goal.id)
return this.#wantRecordRange(minGhostDepth, remoteHave) return this.#wantDictRange(minGhostDepth, remoteHave)
case 'set': case 'set':
throw new Error('Not implemented') // TODO throw new Error('Not implemented') // TODO

View File

@ -26,7 +26,6 @@
"dependencies": { "dependencies": {
"bloom-filters": "^3.0.0", "bloom-filters": "^3.0.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"multicb": "1.2.2",
"promisify-4loc": "^1.0.0", "promisify-4loc": "^1.0.0",
"pull-stream": "^3.7.0", "pull-stream": "^3.7.0",
"push-stream": "^11.2.0", "push-stream": "^11.2.0",
@ -40,6 +39,7 @@
"bs58": "^5.0.0", "bs58": "^5.0.0",
"c8": "7", "c8": "7",
"ppppp-db": "github:staltz/ppppp-db", "ppppp-db": "github:staltz/ppppp-db",
"ppppp-dict": "github:staltz/ppppp-dict",
"ppppp-caps": "github:staltz/ppppp-caps", "ppppp-caps": "github:staltz/ppppp-caps",
"ppppp-goals": "github:staltz/ppppp-goals", "ppppp-goals": "github:staltz/ppppp-goals",
"ppppp-keypair": "github:staltz/ppppp-keypair", "ppppp-keypair": "github:staltz/ppppp-keypair",

View File

@ -12,36 +12,36 @@ const aliceKeypair = Keypair.generate('ed25519', 'alice')
// \ // \
// o // o
// //
// where "o" is a record update and "?" is a ghost // where "o" is a dict update and "?" is a ghost
test('sync goal=record with ghostSpan=2', async (t) => { test('sync goal=dict with ghostSpan=2', async (t) => {
const SPAN = 5 const SPAN = 5
const alice = createPeer({ const alice = createPeer({
name: 'alice', name: 'alice',
keypair: aliceKeypair, keypair: aliceKeypair,
record: { ghostSpan: SPAN }, dict: { ghostSpan: SPAN },
}) })
const bob = createPeer({ name: 'bob' }) const bob = createPeer({ name: 'bob' })
await alice.db.loaded() await alice.db.loaded()
await bob.db.loaded() await bob.db.loaded()
// Alice sets up an account and a record // Alice sets up an account and a dict
const aliceID = await p(alice.db.account.create)({ const aliceID = await p(alice.db.account.create)({
domain: 'account', domain: 'account',
_nonce: 'alice', _nonce: 'alice',
}) })
await p(alice.record.load)(aliceID) await p(alice.dict.load)(aliceID)
const aliceAccountRoot = alice.db.get(aliceID) const aliceAccountRoot = alice.db.get(aliceID)
// Bob knows Alice // Bob knows Alice
await p(bob.db.add)(aliceAccountRoot, aliceID) await p(bob.db.add)(aliceAccountRoot, aliceID)
// Alice constructs a record // Alice constructs a dict
await p(alice.record.update)('profile', { name: 'alice' }) await p(alice.dict.update)('profile', { name: 'alice' })
await p(alice.record.update)('profile', { age: 24 }) await p(alice.dict.update)('profile', { age: 24 })
await p(alice.record.update)('profile', { name: 'Alice' }) await p(alice.dict.update)('profile', { name: 'Alice' })
await p(alice.record.update)('profile', { age: 25 }) await p(alice.dict.update)('profile', { age: 25 })
await p(alice.record.update)('profile', { name: 'ALICE' }) await p(alice.dict.update)('profile', { name: 'ALICE' })
let moot let moot
let rec1 let rec1
let rec2 let rec2
@ -57,7 +57,7 @@ test('sync goal=record with ghostSpan=2', async (t) => {
if (rec.msg.data?.update?.name === 'ALICE') rec5 = rec if (rec.msg.data?.update?.name === 'ALICE') rec5 = rec
} }
// Bob knows the whole record // Bob knows the whole dict
await p(bob.db.add)(moot.msg, moot.id) await p(bob.db.add)(moot.msg, moot.id)
await p(bob.db.add)(rec1.msg, moot.id) await p(bob.db.add)(rec1.msg, moot.id)
await p(bob.db.add)(rec2.msg, moot.id) await p(bob.db.add)(rec2.msg, moot.id)
@ -72,7 +72,7 @@ test('sync goal=record with ghostSpan=2', async (t) => {
tangle.add(rec1.id, rec1.msg) tangle.add(rec1.id, rec1.msg)
const msg = MsgV3.create({ const msg = MsgV3.create({
keypair: aliceKeypair, keypair: aliceKeypair,
domain: 'record_v1__profile', domain: 'dict_v1__profile',
account: aliceID, account: aliceID,
accountTips: [aliceID], accountTips: [aliceID],
data: { update: { gender: 'w' }, supersedes: [] }, data: { update: { gender: 'w' }, supersedes: [] },
@ -80,16 +80,15 @@ test('sync goal=record with ghostSpan=2', async (t) => {
[moot.id]: tangle, [moot.id]: tangle,
}, },
}) })
const recX = await p(bob.db.add)(msg, moot.id) await p(bob.db.add)(msg, moot.id)
assert.equal(recX.id, 'Pd8e1aMN7yFWSr7yc1qycr', 'msg ID')
} }
// Simulate Alice garbage collecting part of the record // Simulate Alice garbage collecting part of the dict
{ {
const fieldRoots = alice.record._getFieldRoots('profile') const fieldRoots = alice.dict._getFieldRoots('profile')
assert.deepEqual(fieldRoots.age, [rec4.id]) assert.deepEqual(fieldRoots.age, [rec4.id])
assert.deepEqual(fieldRoots.name, [rec5.id]) assert.deepEqual(fieldRoots.name, [rec5.id])
const tangle = alice.db.getTangle(alice.record.getFeedID('profile')) const tangle = alice.db.getTangle(alice.dict.getFeedID('profile'))
const { deletables, erasables } = tangle.getDeletablesAndErasables(rec4.id) const { deletables, erasables } = tangle.getDeletablesAndErasables(rec4.id)
assert.equal(deletables.size, 2) assert.equal(deletables.size, 2)
assert.equal(erasables.size, 2) assert.equal(erasables.size, 2)
@ -114,13 +113,13 @@ test('sync goal=record with ghostSpan=2', async (t) => {
.map((msg) => msg.data?.update) .map((msg) => msg.data?.update)
.filter((x) => !!x) .filter((x) => !!x)
.map((x) => x.age ?? x.name ?? x.gender) .map((x) => x.age ?? x.name ?? x.gender)
assert.deepEqual(arr, [25, 'ALICE'], 'alice has age+name record') assert.deepEqual(arr, [25, 'ALICE'], 'alice has age+name dict')
} }
assert.deepEqual(alice.db.ghosts.get(moot.id), [rec1.id, rec2.id]) assert.deepEqual(alice.db.ghosts.get(moot.id), [rec1.id, rec2.id])
// Trigger tangleSync // Trigger tangleSync
alice.goals.set(moot.id, 'record') alice.goals.set(moot.id, 'dict')
bob.goals.set(moot.id, 'record') bob.goals.set(moot.id, 'dict')
const remoteAlice = await p(bob.connect)(alice.getAddress()) const remoteAlice = await p(bob.connect)(alice.getAddress())
assert('bob connected to alice') assert('bob connected to alice')
bob.tangleSync.initiate() bob.tangleSync.initiate()
@ -136,7 +135,7 @@ test('sync goal=record with ghostSpan=2', async (t) => {
assert.deepEqual( assert.deepEqual(
arr, arr,
[25, 'ALICE', 'w'], [25, 'ALICE', 'w'],
'alice has age+name+gender record' 'alice has age+name+gender dict'
) )
} }
assert.deepEqual(alice.db.ghosts.get(moot.id), [rec2.id]) assert.deepEqual(alice.db.ghosts.get(moot.id), [rec2.id])

View File

@ -19,7 +19,7 @@ function createPeer(opts) {
.use(require('secret-stack/plugins/net')) .use(require('secret-stack/plugins/net'))
.use(require('secret-handshake-ext/secret-stack')) .use(require('secret-handshake-ext/secret-stack'))
.use(require('ppppp-db')) .use(require('ppppp-db'))
.use(require('ppppp-record')) .use(require('ppppp-dict'))
.use(require('ppppp-goals')) .use(require('ppppp-goals'))
.use(require('ssb-box')) .use(require('ssb-box'))
.use(require('../lib')) .use(require('../lib'))

View File

@ -30,9 +30,9 @@ test('want-range for goal=all', (t) => {
assert.deepStrictEqual(algo.wantRange([1, 3], [6, 7], goal), [6, 7]) assert.deepStrictEqual(algo.wantRange([1, 3], [6, 7], goal), [6, 7])
}) })
test('want-range for goal=record', (t) => { test('want-range for goal=dict', (t) => {
const algo = new Algorithm({ db: null, record: { minGhostDepth: () => 3 } }) const algo = new Algorithm({ db: null, dict: { minGhostDepth: () => 3 } })
const goal = { type: 'record' } const goal = { type: 'dict' }
assert.deepStrictEqual(algo.wantRange([2, 4], [1, 3], goal), [3, 3]) assert.deepStrictEqual(algo.wantRange([2, 4], [1, 3], goal), [3, 3])
assert.deepStrictEqual(algo.wantRange([2, 4], [1, 5], goal), [3, 5]) assert.deepStrictEqual(algo.wantRange([2, 4], [1, 5], goal), [3, 5])