From c4faaf27cee7169dcaa77e277dbd5c3931fffd13 Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Tue, 19 Dec 2023 15:31:26 +0200 Subject: [PATCH] add watch() API --- lib/index.js | 9 +++++++ package.json | 1 + test/index.test.js | 58 ++++++++++++++++++---------------------------- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/lib/index.js b/lib/index.js index 084a899..24c488b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,3 +1,5 @@ +// @ts-ignore +const Obz = require('obz') const MsgV3 = require('ppppp-db/msg-v3') const PREFIX = 'set_v1__' @@ -23,6 +25,9 @@ const PREFIX = 'set_v1__' * supersedes: Array, * }} SetMsgData * @typedef {{ + * set: (ev: { event: 'add' | 'del', subdomain: string, value: string }) => void + * }} ObzType + * @typedef {{ * set?: { * ghostSpan?: number * } @@ -92,6 +97,7 @@ function initSet(peer, config) { let accountID = /** @type {string | null} */ (null) let loadPromise = /** @type {Promise | null} */ (null) let cancelOnRecordAdded = /** @type {CallableFunction | null} */ (null) + const watch = /**@type {ObzType}*/ (Obz()) const tangles = /** @type {Map} */ (new Map()) const itemRoots = { @@ -374,6 +380,7 @@ function initSet(peer, config) { } // @ts-ignore 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 })) // @ts-ignore cb(null, true) + watch.set({ event: 'del', subdomain, value }) }) }) } @@ -570,6 +578,7 @@ function initSet(peer, config) { del, has, values, + watch, getDomain: fromSubdomain, getFeedID, isGhostable, diff --git a/package.json b/package.json index 7100b93..57a6275 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "devDependencies": { "bs58": "^5.0.0", "c8": "7", + "obz": "~1.1.0", "ppppp-db": "github:staltz/ppppp-db", "ppppp-caps": "github:staltz/ppppp-caps", "ppppp-keypair": "github:staltz/ppppp-keypair", diff --git a/test/index.test.js b/test/index.test.js index 3665155..806ddd7 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -18,7 +18,7 @@ let aliceID test('setup', async (t) => { peer = createPeer({ keypair: aliceKeypair, - db: {path: DIR}, + db: { path: DIR }, set: { ghostSpan: 4 }, }) @@ -42,13 +42,17 @@ function lastMsgID() { } 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 - assert.equal( - peer.set.has('follows', '1st'), - false, - 'doesnt have 1st' - ) + assert.equal(peer.set.has('follows', '1st'), false, 'doesnt have 1st') assert(await p(peer.set.add)('follows', '1st'), 'add 1st') assert.equal(peer.set.has('follows', '1st'), true, 'has 1st') add1 = lastMsgID() @@ -59,11 +63,7 @@ test('Set add(), del(), has()', async (t) => { ) // Add 2nd - assert.equal( - peer.set.has('follows', '2nd'), - false, - 'doesnt have 2nd' - ) + assert.equal(peer.set.has('follows', '2nd'), false, 'doesnt have 2nd') assert(await p(peer.set.add)('follows', '2nd'), 'add 2nd') assert.equal(peer.set.has('follows', '2nd'), true, 'has 2nd') add2 = lastMsgID() @@ -76,11 +76,7 @@ test('Set add(), del(), has()', async (t) => { // Del 1st assert.equal(peer.set.has('follows', '1st'), true, 'has 1st') assert(await p(peer.set.del)('follows', '1st'), 'del 1st') - assert.equal( - peer.set.has( 'follows', '1st'), - false, - 'doesnt have 1st' - ) + assert.equal(peer.set.has('follows', '1st'), false, 'doesnt have 1st') del1 = lastMsgID() assert.deepEqual( peer.set._getItemRoots('follows'), @@ -88,14 +84,14 @@ test('Set add(), del(), has()', async (t) => { 'itemRoots' ) + // Check `watch()` results + stopWatch() + assert.deepEqual(actualWatch, expectedWatch, 'watch() events') + // Add 3rd - assert.equal( - peer.set.has( 'follows', '3rd'), - false, - 'doesnt have 3rd' - ) + assert.equal(peer.set.has('follows', '3rd'), false, 'doesnt have 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() assert.deepEqual( peer.set._getItemRoots('follows'), @@ -104,13 +100,9 @@ test('Set add(), del(), has()', async (t) => { ) // 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.equal( - peer.set.has( 'follows', '2nd'), - false, - 'doesnt have 2nd' - ) + assert.equal(peer.set.has('follows', '2nd'), false, 'doesnt have 2nd') del2 = lastMsgID() assert.deepEqual( peer.set._getItemRoots('follows'), @@ -124,11 +116,7 @@ test('Set add(), del(), has()', async (t) => { false, 'del 2nd idempotent' ) - assert.equal( - peer.set.has( 'follows', '2nd'), - false, - 'doesnt have 2nd' - ) + assert.equal(peer.set.has('follows', '2nd'), false, 'doesnt have 2nd') assert.deepEqual( peer.set._getItemRoots('follows'), { '3rd': [add3], '2nd': [del2] }, @@ -144,7 +132,7 @@ test('Set values()', async (t) => { add5 = lastMsgID() 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') expected.delete(item) }