Skip to content

Commit

Permalink
feat: add support for black and white lists of sb instances in bucket
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobbubu committed Mar 4, 2020
1 parent 90e50f5 commit 59be164
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 11 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@
],
"coverageThreshold": {
"global": {
"branches": 55,
"functions": 95,
"lines": 95,
"statements": 95
"branches": 65,
"functions": 90,
"lines": 90,
"statements": 90
}
},
"collectCoverage": true
Expand Down
33 changes: 29 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ export enum ScuttlebucketValueItems {
OriginalValue
}

export interface ScuttlebucketAccept {
whitelist?: string[]
blacklist?: string[]
}

function setId(obj: Scuttlebutt, id: string) {
obj.setId(id)
return obj
Expand Down Expand Up @@ -63,6 +68,24 @@ export class Scuttlebucket extends Scuttlebutt {
return this
}

_isAcceptedName(peerAccept: ScuttlebucketAccept, name: string) {
const { blacklist, whitelist } = peerAccept
if (blacklist && Array.isArray(blacklist)) {
if (blacklist.includes(name)) {
return false
}
}
if (whitelist && Array.isArray(whitelist)) {
return whitelist.includes(name) ? true : false
}
return true
}

isAccepted(peerAccept: ScuttlebucketAccept, update: Update) {
const name = update[UpdateItems.Data][ScuttlebucketValueItems.Name]
return this._isAcceptedName(peerAccept, name)
}

applyUpdate(update: Update) {
const newUpdate = [...update] as Update

Expand All @@ -84,13 +107,15 @@ export class Scuttlebucket extends Scuttlebutt {
return true
}

history(sources: Sources) {
history(sources: Sources, peerAccept?: ScuttlebucketAccept) {
const h: Update[] = []
const self = this
for (let name in this._parts) {
this._parts[name].history(sources).forEach(function(update: Update) {
h.push(self._wrap(name, update))
})
if (!peerAccept || this._isAcceptedName(peerAccept, name)) {
this._parts[name].history(sources).forEach(function(update: Update) {
h.push(self._wrap(name, update))
})
}
}
return h.sort(function(a, b) {
return (
Expand Down
61 changes: 58 additions & 3 deletions test/scuttlebucket-pull.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Model, ReliableEvent, link } from '@jacobbubu/scuttlebutt-pull'
import { Model, ReliableEvent, link, ScuttlebuttOptions } from '@jacobbubu/scuttlebutt-pull'
import { Scuttlebucket } from '../src/'
import { delay } from './utils'

Expand All @@ -9,8 +9,11 @@ describe('Scuttlebucket', () => {
value2: 'bar2'
}

function create() {
return new Scuttlebucket().add('meta', new Model()).add('event', new ReliableEvent())
function create(opts?: ScuttlebuttOptions) {
return new Scuttlebucket(opts)
.add('meta', new Model())
.add('event', new ReliableEvent())
.add('config', new Model())
}

it('bucket with model', async () => {
Expand Down Expand Up @@ -119,4 +122,56 @@ describe('Scuttlebucket', () => {
expect(aFired).toHaveBeenCalledTimes(1)
expect(bFired).toHaveBeenCalledTimes(1)
})

it('accepted with whitelist', async () => {
const accept = { whitelist: ['meta'] }
const bucketA = create()
const bucketB = create({ accept })

const metaAtA: Model = bucketA.get('meta') as Model
const configAtA: Model = bucketA.get('config') as Model
const metaAtB: Model = bucketB.get('meta') as Model
const configAtB: Model = bucketB.get('config') as Model

metaAtA.set(expected.key, expected.value)
configAtA.set(expected.key, expected.value)

const s1 = bucketA.createStream()
const s2 = bucketB.createStream()

link(s1, s2)

await delay(10)

expect(metaAtA.get(expected.key)).toBe(expected.value)
expect(configAtA.get(expected.key)).toBe(expected.value)
expect(metaAtB.get(expected.key)).toBe(expected.value)
expect(configAtB.get(expected.key)).toBeUndefined()
})

it('accepted with blacklist', async () => {
const accept = { blacklist: ['config'] }
const bucketA = create()
const bucketB = create({ accept })

const metaAtA: Model = bucketA.get('meta') as Model
const configAtA: Model = bucketA.get('config') as Model
const metaAtB: Model = bucketB.get('meta') as Model
const configAtB: Model = bucketB.get('config') as Model

metaAtA.set(expected.key, expected.value)
configAtA.set(expected.key, expected.value)

const s1 = bucketA.createStream()
const s2 = bucketB.createStream()

link(s1, s2)

await delay(10)

expect(metaAtA.get(expected.key)).toBe(expected.value)
expect(configAtA.get(expected.key)).toBe(expected.value)
expect(metaAtB.get(expected.key)).toBe(expected.value)
expect(configAtB.get(expected.key)).toBeUndefined()
})
})

0 comments on commit 59be164

Please sign in to comment.