add watch() API

This commit is contained in:
Andre Staltz 2023-12-19 15:31:26 +02:00
parent 25cd72aee7
commit c4faaf27ce
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
3 changed files with 33 additions and 35 deletions

View File

@ -1,3 +1,5 @@
// @ts-ignore
const Obz = require('obz')
const MsgV3 = require('ppppp-db/msg-v3') const MsgV3 = require('ppppp-db/msg-v3')
const PREFIX = 'set_v1__' const PREFIX = 'set_v1__'
@ -23,6 +25,9 @@ const PREFIX = 'set_v1__'
* supersedes: Array<MsgID>, * supersedes: Array<MsgID>,
* }} SetMsgData * }} SetMsgData
* @typedef {{ * @typedef {{
* set: (ev: { event: 'add' | 'del', subdomain: string, value: string }) => void
* }} ObzType
* @typedef {{
* set?: { * set?: {
* ghostSpan?: number * ghostSpan?: number
* } * }
@ -92,6 +97,7 @@ function initSet(peer, config) {
let accountID = /** @type {string | null} */ (null) let accountID = /** @type {string | null} */ (null)
let loadPromise = /** @type {Promise<void> | null} */ (null) let loadPromise = /** @type {Promise<void> | null} */ (null)
let cancelOnRecordAdded = /** @type {CallableFunction | null} */ (null) let cancelOnRecordAdded = /** @type {CallableFunction | null} */ (null)
const watch = /**@type {ObzType}*/ (Obz())
const tangles = /** @type {Map<Subdomain, MsgV3.Tangle>} */ (new Map()) const tangles = /** @type {Map<Subdomain, MsgV3.Tangle>} */ (new Map())
const itemRoots = { const itemRoots = {
@ -374,6 +380,7 @@ function initSet(peer, config) {
} }
// @ts-ignore // @ts-ignore
cb(null, true) cb(null, true)
watch.set({ event: 'add', subdomain, value })
}) })
}) })
} }
@ -410,6 +417,7 @@ function initSet(peer, config) {
if (err) return cb(new Error(`Failed to create msg when deleting from Set "${subdomain}"`, { cause: err })) if (err) return cb(new Error(`Failed to create msg when deleting from Set "${subdomain}"`, { cause: err }))
// @ts-ignore // @ts-ignore
cb(null, true) cb(null, true)
watch.set({ event: 'del', subdomain, value })
}) })
}) })
} }
@ -570,6 +578,7 @@ function initSet(peer, config) {
del, del,
has, has,
values, values,
watch,
getDomain: fromSubdomain, getDomain: fromSubdomain,
getFeedID, getFeedID,
isGhostable, isGhostable,

View File

@ -29,6 +29,7 @@
"devDependencies": { "devDependencies": {
"bs58": "^5.0.0", "bs58": "^5.0.0",
"c8": "7", "c8": "7",
"obz": "~1.1.0",
"ppppp-db": "github:staltz/ppppp-db", "ppppp-db": "github:staltz/ppppp-db",
"ppppp-caps": "github:staltz/ppppp-caps", "ppppp-caps": "github:staltz/ppppp-caps",
"ppppp-keypair": "github:staltz/ppppp-keypair", "ppppp-keypair": "github:staltz/ppppp-keypair",

View File

@ -18,7 +18,7 @@ let aliceID
test('setup', async (t) => { test('setup', async (t) => {
peer = createPeer({ peer = createPeer({
keypair: aliceKeypair, keypair: aliceKeypair,
db: {path: DIR}, db: { path: DIR },
set: { ghostSpan: 4 }, set: { ghostSpan: 4 },
}) })
@ -42,13 +42,17 @@ function lastMsgID() {
} }
let add1, add2, del1, add3, del2 let add1, add2, del1, add3, del2
test('Set add(), del(), has()', async (t) => { test('Set add(), del(), has(), watch()', async (t) => {
const expectedWatch = [
{ event: 'add', subdomain: 'follows', value: '1st' },
{ event: 'add', subdomain: 'follows', value: '2nd' },
{ event: 'del', subdomain: 'follows', value: '1st' },
]
const actualWatch = []
const stopWatch = peer.set.watch((ev) => actualWatch.push(ev))
// Add 1st // Add 1st
assert.equal( assert.equal(peer.set.has('follows', '1st'), false, 'doesnt have 1st')
peer.set.has('follows', '1st'),
false,
'doesnt have 1st'
)
assert(await p(peer.set.add)('follows', '1st'), 'add 1st') assert(await p(peer.set.add)('follows', '1st'), 'add 1st')
assert.equal(peer.set.has('follows', '1st'), true, 'has 1st') assert.equal(peer.set.has('follows', '1st'), true, 'has 1st')
add1 = lastMsgID() add1 = lastMsgID()
@ -59,11 +63,7 @@ test('Set add(), del(), has()', async (t) => {
) )
// Add 2nd // Add 2nd
assert.equal( assert.equal(peer.set.has('follows', '2nd'), false, 'doesnt have 2nd')
peer.set.has('follows', '2nd'),
false,
'doesnt have 2nd'
)
assert(await p(peer.set.add)('follows', '2nd'), 'add 2nd') assert(await p(peer.set.add)('follows', '2nd'), 'add 2nd')
assert.equal(peer.set.has('follows', '2nd'), true, 'has 2nd') assert.equal(peer.set.has('follows', '2nd'), true, 'has 2nd')
add2 = lastMsgID() add2 = lastMsgID()
@ -76,11 +76,7 @@ test('Set add(), del(), has()', async (t) => {
// Del 1st // Del 1st
assert.equal(peer.set.has('follows', '1st'), true, 'has 1st') assert.equal(peer.set.has('follows', '1st'), true, 'has 1st')
assert(await p(peer.set.del)('follows', '1st'), 'del 1st') assert(await p(peer.set.del)('follows', '1st'), 'del 1st')
assert.equal( assert.equal(peer.set.has('follows', '1st'), false, 'doesnt have 1st')
peer.set.has( 'follows', '1st'),
false,
'doesnt have 1st'
)
del1 = lastMsgID() del1 = lastMsgID()
assert.deepEqual( assert.deepEqual(
peer.set._getItemRoots('follows'), peer.set._getItemRoots('follows'),
@ -88,14 +84,14 @@ test('Set add(), del(), has()', async (t) => {
'itemRoots' 'itemRoots'
) )
// Check `watch()` results
stopWatch()
assert.deepEqual(actualWatch, expectedWatch, 'watch() events')
// Add 3rd // Add 3rd
assert.equal( assert.equal(peer.set.has('follows', '3rd'), false, 'doesnt have 3rd')
peer.set.has( 'follows', '3rd'),
false,
'doesnt have 3rd'
)
assert(await p(peer.set.add)('follows', '3rd'), 'add 3rd') assert(await p(peer.set.add)('follows', '3rd'), 'add 3rd')
assert.equal(peer.set.has( 'follows', '3rd'), true, 'has 3rd') assert.equal(peer.set.has('follows', '3rd'), true, 'has 3rd')
add3 = lastMsgID() add3 = lastMsgID()
assert.deepEqual( assert.deepEqual(
peer.set._getItemRoots('follows'), peer.set._getItemRoots('follows'),
@ -104,13 +100,9 @@ test('Set add(), del(), has()', async (t) => {
) )
// Del 2nd // Del 2nd
assert.equal(peer.set.has( 'follows', '2nd'), true, 'has 2nd') assert.equal(peer.set.has('follows', '2nd'), true, 'has 2nd')
assert(await p(peer.set.del)('follows', '2nd'), 'del 2nd') // msg seq 4 assert(await p(peer.set.del)('follows', '2nd'), 'del 2nd') // msg seq 4
assert.equal( assert.equal(peer.set.has('follows', '2nd'), false, 'doesnt have 2nd')
peer.set.has( 'follows', '2nd'),
false,
'doesnt have 2nd'
)
del2 = lastMsgID() del2 = lastMsgID()
assert.deepEqual( assert.deepEqual(
peer.set._getItemRoots('follows'), peer.set._getItemRoots('follows'),
@ -124,11 +116,7 @@ test('Set add(), del(), has()', async (t) => {
false, false,
'del 2nd idempotent' 'del 2nd idempotent'
) )
assert.equal( assert.equal(peer.set.has('follows', '2nd'), false, 'doesnt have 2nd')
peer.set.has( 'follows', '2nd'),
false,
'doesnt have 2nd'
)
assert.deepEqual( assert.deepEqual(
peer.set._getItemRoots('follows'), peer.set._getItemRoots('follows'),
{ '3rd': [add3], '2nd': [del2] }, { '3rd': [add3], '2nd': [del2] },
@ -144,7 +132,7 @@ test('Set values()', async (t) => {
add5 = lastMsgID() add5 = lastMsgID()
const expected = new Set(['3rd', '4th', '5th']) const expected = new Set(['3rd', '4th', '5th'])
for (const item of peer.set.values( 'follows')) { for (const item of peer.set.values('follows')) {
assert.equal(expected.has(item), true, 'values() item') assert.equal(expected.has(item), true, 'values() item')
expected.delete(item) expected.delete(item)
} }