ipfs-pubsub-1on1
Advanced tools
Comparing version 0.0.6 to 0.0.7
{ | ||
"name": "ipfs-pubsub-1on1", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "1-to-1 communication channel over IPFS Pubsub between two peers", | ||
@@ -9,14 +9,14 @@ "license": "MIT", | ||
"dependencies": { | ||
"safe-buffer": "~5.1.2" | ||
"safe-buffer": "~5.2.1" | ||
}, | ||
"devDependencies": { | ||
"ipfs": "~0.35.0", | ||
"mocha": "^6.1.4", | ||
"mocha": "^8.1.3", | ||
"orbit-db-test-utils": "^0.11.1", | ||
"p-map-series": "^2.1.0", | ||
"rimraf": "^2.6.3" | ||
"rimraf": "^3.0.2" | ||
}, | ||
"scripts": { | ||
"test": "mocha --exit", | ||
"test": "TEST=all mocha", | ||
"test:coverage": "istanbul cover _mocha" | ||
} | ||
} |
@@ -5,3 +5,3 @@ # ipfs-pubsub-1on1 | ||
***Work in progress!*** | ||
**_Work in progress!_** | ||
@@ -15,5 +15,5 @@ `ipfs-pubsub-1on1` is a 1-to-1 communication channel over IPFS Pubsub. It enables two peers to exchange messages between each other. Note that the channel is currently not authenticated nor encrypted! | ||
const Channel = require('ipfs-pubsub-1on1') | ||
// Create IPFS instance somewhow | ||
const ipfs = ... | ||
// IPFS peer ID of the peer to connect to | ||
// Create IPFS instance somehow | ||
const ipfs = new IPFS() | ||
// IPFS peer ID of the peer to connect to | ||
const friendId = 'QmP9TWCAsHLs6a3hcCbqE6WZs3VhQF6QsmkFPAFmmcuMa6' | ||
@@ -24,5 +24,7 @@ // Open a channel with the other peer | ||
await channel.connect() | ||
// Send message on the channel | ||
await channel.send('Hello World!') | ||
// Process messages from the other peer | ||
channel.on('message', (message) => { | ||
console.log("Message from", message.from, message) | ||
console.log('Message from', message.from, message) | ||
}) | ||
@@ -29,0 +31,0 @@ ``` |
@@ -76,3 +76,3 @@ 'use strict' | ||
// ID of the channel is "<peer1 id>/<peer 2 id>"" | ||
this._id = '/' + '' + PROTOCOL + '/' + this._peers.join('/') | ||
this._id = '/' + PROTOCOL + '/' + this._peers.join('/') | ||
@@ -79,0 +79,0 @@ // Function to use to handle incoming messages |
@@ -7,8 +7,10 @@ 'use strict' | ||
const pMapSeries = require('p-map-series') | ||
const { | ||
createIpfsTestInstances, | ||
destroyIpfsTestInstances, | ||
connectIpfsInstances, | ||
const { | ||
connectPeers, | ||
startIpfs, | ||
stopIpfs, | ||
getIpfsPeerId, | ||
testAPIs, | ||
waitForPeers, | ||
} = require('./utils/ipfs-utils') | ||
} = require('orbit-db-test-utils') | ||
@@ -26,251 +28,260 @@ const Channel = require('../src/direct-channel') | ||
describe('DirectChannel', function() { | ||
this.timeout(20000) | ||
Object.keys(testAPIs).forEach(API => { | ||
describe(`DirectChannel ${API}`, function() { | ||
this.timeout(5000) | ||
let instances = [] | ||
let ipfs1, ipfs2, ipfs3 | ||
let instances = [] | ||
let ipfsd1, ipfsd2, ipfsd3, ipfs1, ipfs2, ipfs3 | ||
let id1, id2, id3 | ||
let expectedPeerIDs = [] | ||
let id1, id2, id3 | ||
let expectedPeerIDs = [] | ||
before(async () => { | ||
instances = await createIpfsTestInstances(ipfsPaths) | ||
await connectIpfsInstances(instances) | ||
ipfs1 = instances[0] | ||
ipfs2 = instances[1] | ||
ipfs3 = instances[2] | ||
id1 = await getPeerID(ipfs1) | ||
id2 = await getPeerID(ipfs2) | ||
id3 = await getPeerID(ipfs3) | ||
// Note, we only create channels between peer1 and peer2 in these test, | ||
// peer3 is used for "external actor" tests | ||
expectedPeerIDs = Array.from([id1, id2]).sort() | ||
}) | ||
before(async () => { | ||
ipfsd1 = await startIpfs(API) | ||
ipfsd2 = await startIpfs(API) | ||
ipfsd3 = await startIpfs(API) | ||
ipfs1 = ipfsd1.api | ||
ipfs2 = ipfsd2.api | ||
ipfs3 = ipfsd3.api | ||
id1 = await getIpfsPeerId(ipfs1) | ||
id2 = await getIpfsPeerId(ipfs2) | ||
id3 = await getIpfsPeerId(ipfs3) | ||
await connectPeers(ipfs1, ipfs2) | ||
await connectPeers(ipfs1, ipfs3) | ||
await connectPeers(ipfs2, ipfs3) | ||
after(async () => { | ||
await destroyIpfsTestInstances(instances, ipfsPaths) | ||
rmrf.sync('./tmp/') // remove test data directory | ||
}) | ||
describe('create a channel', function() { | ||
it('has two participants', async () => { | ||
const c = await Channel.open(ipfs1, id2) | ||
assert.deepEqual(c.peers, expectedPeerIDs) | ||
c.close() | ||
// Note, we only create channels between peer1 and peer2 in these test, | ||
// peer3 is used for "external actor" tests | ||
expectedPeerIDs = Array.from([id1, id2]).sort() | ||
}) | ||
it('has correct ID', async () => { | ||
const expectedID = path.join('/', PROTOCOL, expectedPeerIDs.join('/')) | ||
const c = await Channel.open(ipfs1, id2) | ||
assert.deepEqual(c.id, expectedID) | ||
c.close() | ||
after(async () => { | ||
await stopIpfs(ipfsd1) | ||
await stopIpfs(ipfsd2) | ||
await stopIpfs(ipfsd3) | ||
rmrf.sync('./tmp/') // remove test data directory | ||
}) | ||
it('has two peers', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
assert.deepEqual(c1.peers, expectedPeerIDs) | ||
assert.deepEqual(c2.peers, expectedPeerIDs) | ||
assert.equal(c1.id, path.join('/', PROTOCOL, expectedPeerIDs.join('/'))) | ||
assert.equal(c2.id, path.join('/', PROTOCOL, expectedPeerIDs.join('/'))) | ||
c1.close() | ||
c2.close() | ||
}) | ||
describe('create a channel', function() { | ||
it('has two participants', async () => { | ||
const c = await Channel.open(ipfs1, id2) | ||
assert.deepEqual(c.peers, expectedPeerIDs) | ||
c.close() | ||
}) | ||
it('can be created with one line', async () => { | ||
const c = await Channel.open(ipfs1, id2) | ||
const topics = await ipfs1.pubsub.ls() | ||
const channelID = topics.find(e => e === c.id) | ||
assert.equal(channelID, c.id) | ||
c.close() | ||
}) | ||
}) | ||
it('has correct ID', async () => { | ||
const expectedID = path.join('/', PROTOCOL, expectedPeerIDs.join('/')) | ||
const c = await Channel.open(ipfs1, id2) | ||
assert.deepEqual(c.id, expectedID) | ||
c.close() | ||
}) | ||
describe('properties', function() { | ||
let c | ||
it('has two peers', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
assert.deepEqual(c1.peers, expectedPeerIDs) | ||
assert.deepEqual(c2.peers, expectedPeerIDs) | ||
assert.equal(c1.id, path.join('/', PROTOCOL, expectedPeerIDs.join('/'))) | ||
assert.equal(c2.id, path.join('/', PROTOCOL, expectedPeerIDs.join('/'))) | ||
c1.close() | ||
c2.close() | ||
}) | ||
beforeEach(async () => { | ||
c = await Channel.open(ipfs1, id2) | ||
}) | ||
afterEach(() => { | ||
if (c) { | ||
it('can be created with one line', async () => { | ||
const c = await Channel.open(ipfs1, id2) | ||
const topics = await ipfs1.pubsub.ls() | ||
const channelID = topics.find(e => e === c.id) | ||
assert.equal(channelID, c.id) | ||
c.close() | ||
} | ||
}) | ||
}) | ||
it('has an id', async () => { | ||
assert.equal(c.id, path.join('/', PROTOCOL, expectedPeerIDs.join('/'))) | ||
}) | ||
describe('properties', function() { | ||
let c | ||
it('has two peers', async () => { | ||
assert.equal(c.peers.length, 2) | ||
assert.deepEqual(c.peers, expectedPeerIDs) | ||
}) | ||
beforeEach(async () => { | ||
c = await Channel.open(ipfs1, id2) | ||
}) | ||
it('has an event emitter for \'message\' event', async () => { | ||
let err | ||
try { | ||
c.on('message', () => {}) | ||
} catch (e) { | ||
err = e | ||
} | ||
assert.equal(err, null) | ||
afterEach(() => { | ||
if (c) { | ||
c.close() | ||
} | ||
}) | ||
it('has an id', async () => { | ||
assert.equal(c.id, path.join('/', PROTOCOL, expectedPeerIDs.join('/'))) | ||
}) | ||
it('has two peers', async () => { | ||
assert.equal(c.peers.length, 2) | ||
assert.deepEqual(c.peers, expectedPeerIDs) | ||
}) | ||
it('has an event emitter for \'message\' event', async () => { | ||
let err | ||
try { | ||
c.on('message', () => {}) | ||
} catch (e) { | ||
err = e | ||
} | ||
assert.equal(err, null) | ||
}) | ||
}) | ||
}) | ||
describe('messaging', function() { | ||
it('sends and receives messages', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
describe('messaging', function() { | ||
it('sends and receives messages', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
await c1.connect() | ||
await c2.connect() | ||
await c1.connect() | ||
await c2.connect() | ||
return new Promise(async (resolve, reject) => { | ||
c1.on('error', reject) | ||
c2.on('error', reject) | ||
return new Promise(async (resolve, reject) => { | ||
c1.on('error', reject) | ||
c2.on('error', reject) | ||
c2.on('message', async (m) => { | ||
assert.notEqual(m, null) | ||
assert.equal(m.from, id1) | ||
assert.equal(m.data.toString(), 'hello1') | ||
assert.equal(m.topicIDs.length, 1) | ||
assert.equal(m.topicIDs[0], c1.id) | ||
assert.equal(m.topicIDs[0], c2.id) | ||
await c2.send(Buffer.from('hello2')) | ||
}) | ||
c2.on('message', async (m) => { | ||
assert.notEqual(m, null) | ||
assert.equal(m.from, id1) | ||
assert.equal(Buffer.from(m.data).toString(), Buffer.from('hello1')) | ||
assert.equal(m.topicIDs.length, 1) | ||
assert.equal(m.topicIDs[0], c1.id) | ||
assert.equal(m.topicIDs[0], c2.id) | ||
await c2.send(Buffer.from('hello2')) | ||
}) | ||
c1.on('message', (m) => { | ||
assert.equal(m.from, id2) | ||
assert.equal(m.data.toString(), Buffer.from('hello2')) | ||
assert.equal(m.topicIDs.length, 1) | ||
assert.equal(m.topicIDs[0], c1.id) | ||
assert.equal(m.topicIDs[0], c2.id) | ||
c1.close() | ||
c2.close() | ||
setTimeout(() => resolve(), 500) | ||
c1.on('message', (m) => { | ||
assert.equal(m.from, id2) | ||
assert.equal(Buffer.from(m.data).toString(), Buffer.from('hello2')) | ||
assert.equal(m.topicIDs.length, 1) | ||
assert.equal(m.topicIDs[0], c1.id) | ||
assert.equal(m.topicIDs[0], c2.id) | ||
c1.close() | ||
c2.close() | ||
setTimeout(() => resolve(), 500) | ||
}) | ||
await c1.send('hello1') | ||
}) | ||
await c1.send('hello1') | ||
}) | ||
}) | ||
}) | ||
describe('connect', function() { | ||
it('connects the peers', async () => { | ||
let c1, c2 | ||
describe('connect', function() { | ||
it('connects the peers', async () => { | ||
let c1, c2 | ||
c1 = await Channel.open(ipfs1, id2) | ||
c2 = await Channel.open(ipfs2, id1) | ||
c1 = await Channel.open(ipfs1, id2) | ||
c2 = await Channel.open(ipfs2, id1) | ||
let peers = await ipfs1.pubsub.peers(c1.id) | ||
assert.deepEqual(peers, []) | ||
let peers = await ipfs1.pubsub.peers(c1.id) | ||
// assert.deepEqual(peers, []) | ||
await c1.connect() | ||
await c1.connect() | ||
peers = await ipfs1.pubsub.peers(c1.id) | ||
assert.deepEqual(peers, [id2]) | ||
peers = await ipfs1.pubsub.peers(c1.id) | ||
assert.deepEqual(peers, [id2]) | ||
c1.close() | ||
c2.close() | ||
c1.close() | ||
c2.close() | ||
}) | ||
}) | ||
}) | ||
describe('disconnecting', function() { | ||
it('closes a channel', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
describe('disconnecting', function() { | ||
it('closes a channel', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
await c1.connect() | ||
await c2.connect() | ||
await c1.connect() | ||
await c2.connect() | ||
return new Promise(async (resolve, reject) => { | ||
c1.close() | ||
const topics1 = await ipfs1.pubsub.ls() | ||
assert.deepEqual(topics1, []) | ||
return new Promise(async (resolve, reject) => { | ||
c1.close() | ||
const topics1 = await ipfs1.pubsub.ls() | ||
assert.deepEqual(topics1, []) | ||
c2.close() | ||
const topics2 = await ipfs2.pubsub.ls() | ||
assert.deepEqual(topics1, []) | ||
c2.close() | ||
const topics2 = await ipfs2.pubsub.ls() | ||
assert.deepEqual(topics1, []) | ||
setTimeout(async () => { | ||
const peers1 = await ipfs1.pubsub.peers(c1.id) | ||
const peers2 = await ipfs2.pubsub.peers(c1.id) | ||
assert.deepEqual(peers1, []) | ||
assert.deepEqual(peers2, []) | ||
resolve() | ||
}, 200) | ||
setTimeout(async () => { | ||
const peers1 = await ipfs1.pubsub.peers(c1.id) | ||
const peers2 = await ipfs2.pubsub.peers(c1.id) | ||
assert.deepEqual(peers1, []) | ||
assert.deepEqual(peers2, []) | ||
resolve() | ||
}, 200) | ||
}) | ||
}) | ||
}) | ||
it('removes event listener upon closing the channel', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
c1.on('message', () => {}) | ||
c2.on('message', () => {}) | ||
await c1.connect() | ||
await c2.connect() | ||
assert.equal(c1.listenerCount('message'), 1) | ||
assert.equal(c2.listenerCount('message'), 1) | ||
c1.close() | ||
c2.close() | ||
assert.equal(c1.listenerCount('message'), 0) | ||
assert.equal(c2.listenerCount('message'), 0) | ||
it('removes event listener upon closing the channel', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
c1.on('message', () => {}) | ||
c2.on('message', () => {}) | ||
await c1.connect() | ||
await c2.connect() | ||
assert.equal(c1.listenerCount('message'), 1) | ||
assert.equal(c2.listenerCount('message'), 1) | ||
c1.close() | ||
c2.close() | ||
assert.equal(c1.listenerCount('message'), 0) | ||
assert.equal(c2.listenerCount('message'), 0) | ||
}) | ||
}) | ||
}) | ||
describe('errors', function() { | ||
it('throws an error if pubsub is not supported by given IPFS instance', async () => { | ||
let c, err | ||
try { | ||
c = await Channel.open({}, id2) | ||
} catch (e) { | ||
err = e | ||
} | ||
describe('errors', function() { | ||
it('throws an error if pubsub is not supported by given IPFS instance', async () => { | ||
let c, err | ||
try { | ||
c = await Channel.open({}, id2) | ||
} catch (e) { | ||
err = e | ||
} | ||
assert.equal(err, 'Error: This IPFS node does not support pubsub.') | ||
}) | ||
assert.equal(err, 'Error: This IPFS node does not support pubsub.') | ||
}) | ||
it('throws an error if receiver ID was not given', async () => { | ||
let c, err | ||
try { | ||
c = await Channel.open(ipfs1) | ||
} catch (e) { | ||
err = e | ||
} | ||
it('throws an error if receiver ID was not given', async () => { | ||
let c, err | ||
try { | ||
c = await Channel.open(ipfs1) | ||
} catch (e) { | ||
err = e | ||
} | ||
assert.equal(err, 'Error: Receiver ID was undefined') | ||
assert.equal(err, 'Error: Receiver ID was undefined') | ||
}) | ||
}) | ||
}) | ||
describe('non-participant peers can\'t send messages', function() { | ||
it('doesn\'t receive unwated messages', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
describe('non-participant peers can\'t send messages', function() { | ||
it('doesn\'t receive unwated messages', async () => { | ||
const c1 = await Channel.open(ipfs1, id2) | ||
const c2 = await Channel.open(ipfs2, id1) | ||
await c1.connect() | ||
await c2.connect() | ||
await c1.connect() | ||
await c2.connect() | ||
c1.on('message', (m) => { | ||
assert.equal(m.from, id2) | ||
assert.equal(m.data.toString(), 'hello1') | ||
assert.equal(m.topicIDs.length, 1) | ||
assert.equal(m.topicIDs[0], c1.id) | ||
assert.equal(m.topicIDs[0], c2.id) | ||
}) | ||
c1.on('message', (m) => { | ||
assert.equal(m.from, id2) | ||
assert.equal(m.data.toString(), 'hello1') | ||
assert.equal(m.topicIDs.length, 1) | ||
assert.equal(m.topicIDs[0], c1.id) | ||
assert.equal(m.topicIDs[0], c2.id) | ||
}) | ||
await ipfs3.pubsub.subscribe(c1.id, () => {}) | ||
await waitForPeers(ipfs1, [id3], c1.id) | ||
await ipfs3.pubsub.publish(c1.id, Buffer.from('OMG!')) | ||
await ipfs3.pubsub.subscribe(c1.id, () => {}) | ||
await waitForPeers(ipfs1, [id3], c1.id) | ||
await ipfs3.pubsub.publish(c1.id, Buffer.from('OMG!')) | ||
return new Promise((resolve, reject) => { | ||
setTimeout(() => { | ||
c2.send('hello1') | ||
return new Promise((resolve, reject) => { | ||
setTimeout(() => { | ||
c1.close() | ||
c2.close() | ||
resolve() | ||
c2.send('hello1') | ||
setTimeout(() => { | ||
c1.close() | ||
c2.close() | ||
resolve() | ||
}, 1000) | ||
}, 1000) | ||
}, 1000) | ||
}) | ||
}) | ||
@@ -277,0 +288,0 @@ }) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
31
13282
9
366
+ Addedsafe-buffer@5.2.1(transitive)
- Removedsafe-buffer@5.1.2(transitive)
Updatedsafe-buffer@~5.2.1