Merge pull request #181 from haadcode/0.16.0-beta.1

0.16.0
This commit is contained in:
Haad 2017-01-17 09:40:43 +01:00 committed by GitHub
commit a2a9546458
20 changed files with 1831 additions and 1603 deletions

19
Makefile Normal file
View File

@ -0,0 +1,19 @@
all: build
deps:
npm install
test: deps
npm run test
build: test
npm run build
@echo "Build success!"
@echo "Output: 'dist/', 'examples/browser/'"
clean:
rm -rf orbit-db/
rm -rf ipfs/
rm -rf node_modules/
.PHONY: test build

View File

@ -31,26 +31,28 @@ This is the Javascript implementation and it works both in **Node.js** and **Bro
## Usage ## Usage
*Note that to run this example, you need to have an [IPFS daemon](https://dist.ipfs.io/go-ipfs/floodsub-2), started with --enable-pubsub-experiment, running at localhost:5001*
``` ```
npm install orbit-db ipfs-api@https://github.com/haadcode/js-ipfs-api.git npm install orbit-db ipfs-daemon
``` ```
```javascript ```javascript
const IpfsApi = require('ipfs-api') const IPFS = require('ipfs-daemon/src/ipfs-node-daemon')
const OrbitDB = require('orbit-db') const OrbitDB = require('orbit-db')
const ipfs = IpfsApi('localhost', '5001') const ipfs = new IPFS()
const orbitdb = new OrbitDB(ipfs)
const db = orbitdb.eventlog("feed name") ipfs.on('error', (e) => console.error(e))
ipfs.on('ready', (e) => {
const orbitdb = new OrbitDB(ipfs)
db.add("hello world") const db = orbitdb.eventlog("feed name")
db.add("hello world")
.then(() => { .then(() => {
const latest = db.iterator({ limit: 5 }).collect() const latest = db.iterator({ limit: 5 }).collect()
console.log(JSON.stringify(latest, null, 2)) console.log(JSON.stringify(latest, null, 2))
}) })
})
``` ```
*For more details, see examples for [kvstore](https://github.com/haadcode/orbit-db-kvstore#usage), [eventlog](https://github.com/haadcode/orbit-db-eventstore#usage), [feed](https://github.com/haadcode/orbit-db-feedstore#usage), [docstore](https://github.com/shamb0t/orbit-db-docstore#usage) and [counter](https://github.com/haadcode/orbit-db-counterstore#usage).* *For more details, see examples for [kvstore](https://github.com/haadcode/orbit-db-kvstore#usage), [eventlog](https://github.com/haadcode/orbit-db-eventstore#usage), [feed](https://github.com/haadcode/orbit-db-feedstore#usage), [docstore](https://github.com/shamb0t/orbit-db-docstore#usage) and [counter](https://github.com/haadcode/orbit-db-counterstore#usage).*

View File

@ -9,6 +9,10 @@ module.exports = {
filename: './dist/orbitdb.js' filename: './dist/orbitdb.js'
}, },
devtool: 'sourcemap', devtool: 'sourcemap',
stats: {
colors: true,
cached: false
},
node: { node: {
console: false, console: false,
process: 'mock', process: 'mock',

View File

@ -9,6 +9,10 @@ module.exports = {
filename: './dist/orbitdb.min.js' filename: './dist/orbitdb.min.js'
}, },
devtool: 'sourcemap', devtool: 'sourcemap',
stats: {
colors: true,
cached: false
},
node: { node: {
console: false, console: false,
process: 'mock', process: 'mock',

View File

@ -7,6 +7,10 @@ module.exports = {
filename: './examples/browser/bundle.js' filename: './examples/browser/bundle.js'
}, },
devtool: 'sourcemap', devtool: 'sourcemap',
stats: {
colors: true,
cached: false
},
node: { node: {
console: false, console: false,
process: 'mock', process: 'mock',
@ -20,38 +24,37 @@ module.exports = {
], ],
resolve: { resolve: {
modules: [ modules: [
path.join(__dirname, '../node_modules') 'node_modules',
] path.resolve(__dirname, '../node_modules')
],
alias: {
// These are needed because node-libs-browser depends on outdated
// versions
//
// Can be dropped once https://github.com/devongovett/browserify-zlib/pull/18
// is shipped
zlib: 'browserify-zlib',
// Can be dropped once https://github.com/webpack/node-libs-browser/pull/41
// is shipped
http: 'stream-http'
}
},
resolveLoader: {
modules: [
'node_modules',
path.resolve(__dirname, '../node_modules')
],
moduleExtensions: ['-loader']
}, },
module: { module: {
loaders: [ rules: [{
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: require.resolve('babel-preset-es2015'),
plugins: require.resolve('babel-plugin-transform-runtime')
}
},
{
test: /\.js$/,
include: /node_modules\/(hoek|qs|wreck|boom|ipfs.+|orbit.+|logplease|crdts|promisify-es|whatwg-fetch|node-fetch|isomorphic-fetch|db\.js)/,
loader: 'babel-loader',
query: {
presets: require.resolve('babel-preset-es2015'),
plugins: require.resolve('babel-plugin-transform-runtime')
}
},
{
test: /\.json$/, test: /\.json$/,
loader: 'json-loader' loader: 'json-loader'
} }]
]
}, },
externals: { node: {
net: '{}', Buffer: true
tls: '{}', },
'require-dir': '{}' plugins: [],
} target: 'web'
} }

2563
dist/orbitdb.js vendored

File diff suppressed because it is too large Load Diff

28
dist/orbitdb.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
'use strict' 'use strict'
const IpfsDaemon = require('ipfs-daemon') const IpfsDaemon = require('ipfs-daemon/src/ipfs-node-daemon')
const OrbitDB = require('../src/OrbitDB') const OrbitDB = require('../src/OrbitDB')
// Metrics // Metrics
@ -11,19 +11,25 @@ let lastTenSeconds = 0
// Main loop // Main loop
const queryLoop = (db) => { const queryLoop = (db) => {
db.add(totalQueries).then(() => { db.add(totalQueries)
.then(() => {
totalQueries ++ totalQueries ++
lastTenSeconds ++ lastTenSeconds ++
queriesPerSecond ++ queriesPerSecond ++
process.nextTick(() => queryLoop(db)) process.nextTick(() => queryLoop(db))
}) })
.catch((e) => console.error(e))
} }
// Start // Start
let run = (() => { console.log("Starting IPFS daemon...")
IpfsDaemon({ IpfsDataDir: '/tmp/orbit-db-benchmark' })
.then((res) => { const ipfs = new IpfsDaemon()
const orbit = new OrbitDB(res.ipfs, 'benchmark')
ipfs.on('error', (err) => console.error(err))
ipfs.on('ready', () => {
const orbit = new OrbitDB(ipfs, 'benchmark')
const db = orbit.eventlog('orbit-db.benchmark') const db = orbit.eventlog('orbit-db.benchmark')
// Metrics output // Metrics output
@ -41,8 +47,4 @@ let run = (() => {
// Start the main loop // Start the main loop
queryLoop(db) queryLoop(db)
}) })
.catch((e) => console.error(e))
})()
module.exports = run

View File

@ -6,18 +6,30 @@
<div id="result">Loading...</div> <div id="result">Loading...</div>
<script type="text/javascript" src="../../dist/orbitdb.min.js" charset="utf-8"></script> <script type="text/javascript" src="../../dist/orbitdb.min.js" charset="utf-8"></script>
<script type="text/javascript" src="../../node_modules/ipfs-api/dist/index.min.js" charset="utf-8"></script> <script type="text/javascript" src="../../node_modules/ipfs-daemon/dist/ipfs-browser-daemon.min.js" charset="utf-8"></script>
<script type="text/javascript"> <script type="text/javascript">
const username = new Date().getTime() const username = new Date().getTime()
const channel = 'browser-example' const channel = 'orbitdb-browser-examples'
const key = 'greeting' const key = 'greeting'
try {
const elm = document.getElementById("result") const elm = document.getElementById("result")
const ipfs = IpfsApi('localhost', '5001')
const orbit = new OrbitDB(ipfs, username) const ipfs = new IpfsDaemon({
// dev server: webrtc-star-signalling.cloud.ipfs.team
SignalServer: '188.166.203.82:20000',
})
function handleError(e) {
console.error(e.stack)
elm.innerHTML = e.message
}
ipfs.on('error', (e) => handleError(e))
ipfs.on('ready', () => {
const orbit = new OrbitDB(ipfs, username, { maxHistory: 5 })
const db = orbit.kvstore(channel) const db = orbit.kvstore(channel)
const log = orbit.eventlog(channel + ".log") const log = orbit.eventlog(channel + ".log")
@ -27,17 +39,12 @@
let count = 1 let count = 1
const query = () => { const query = () => {
const startTime = new Date().getTime()
const idx = Math.floor(Math.random() * creatures.length) const idx = Math.floor(Math.random() * creatures.length)
const creature = creatures[idx] + " " + creatures[idx] const creature = creatures[idx] + " " + creatures[idx]
// Set a key-value pair // Set a key-value pair
db.put(key, "db.put #" + count + " - GrEEtinGs to " + creature) db.put(key, "db.put #" + count + " - GrEEtinGs from " + creature)
.then((res) => { .then((res) => count ++)
const endTime = new Date().getTime()
console.log(`db.put (#${count}) took ${(endTime - startTime)} ms\n`)
count ++
})
.then(() => counter.inc()) // Increase the counter by one .then(() => counter.inc()) // Increase the counter by one
.then(() => log.add(creature)) // Add an event to 'latest visitors' log .then(() => log.add(creature)) // Add an event to 'latest visitors' log
.then(() => { .then(() => {
@ -45,8 +52,8 @@
const latest = log.iterator({ limit: 5 }).collect() const latest = log.iterator({ limit: 5 }).collect()
const count = counter.value const count = counter.value
const output = const output = `
`<b>Key-Value Store</b> <b>Key-Value Store</b>
------------------------------------------------------- -------------------------------------------------------
Key | Value Key | Value
------------------------------------------------------- -------------------------------------------------------
@ -66,21 +73,12 @@
` `
elm.innerHTML = output.split("\n").join("<br>") elm.innerHTML = output.split("\n").join("<br>")
}) })
.catch((e) => { .catch((e) => handleError(e))
elm.innerHTML = "<i>" + e.message + "</i><br><br>" + "Waiting for IPFS daemon to start..."
console.error(e.stack)
})
} }
// Start query loop when the databse has loaded its history // Start query loop when the databse has loaded its history
db.events.on('ready', () => setInterval(query, 1000)) db.events.on('ready', () => setInterval(query, 1000))
})
} catch(e) {
console.error(e.stack)
elm.innerHTML = e.message
}
</script> </script>
</body> </body>
</html> </html>

View File

@ -1,16 +1,28 @@
'use strict' 'use strict'
const IpfsApi = require('exports-loader?IpfsApi!ipfs-api/dist/index.js') const IPFS = require('ipfs-daemon/src/ipfs-browser-daemon')
const OrbitDB = require('../../src/OrbitDB') const OrbitDB = require('../../src/OrbitDB')
const username = new Date().getTime() const username = new Date().getTime()
const channel = 'browser-example' const channel = 'orbitdb-browser-examples'
const key = 'greeting' const key = 'greeting'
try { const elm = document.getElementById("result")
const elm = document.getElementById("result")
const ipfs = IpfsApi('localhost', '5001') const ipfs = new IPFS({
const orbit = new OrbitDB(ipfs, username) // dev server: webrtc-star-signalling.cloud.ipfs.team
SignalServer: '188.166.203.82:20000',
})
function handleError(e) {
console.error(e.stack)
elm.innerHTML = e.message
}
ipfs.on('error', (e) => handleError(e))
ipfs.on('ready', () => {
const orbit = new OrbitDB(ipfs, username, { maxHistory: 5 })
const db = orbit.kvstore(channel) const db = orbit.kvstore(channel)
const log = orbit.eventlog(channel + ".log") const log = orbit.eventlog(channel + ".log")
@ -20,16 +32,11 @@ try {
let count = 1 let count = 1
const query = () => { const query = () => {
const startTime = new Date().getTime()
const idx = Math.floor(Math.random() * creatures.length) const idx = Math.floor(Math.random() * creatures.length)
// Set a key-value pair // Set a key-value pair
db.put(key, "db.put #" + count + " - GrEEtinGs to " + creatures[idx]) db.put(key, "db.put #" + count + " - GrEEtinGs to " + creatures[idx])
.then((res) => { .then((res) => count ++)
const endTime = new Date().getTime()
console.log(`db.put (#${count}) took ${(endTime - startTime)} ms\n`)
count ++
})
.then(() => counter.inc()) // Increase the counter by one .then(() => counter.inc()) // Increase the counter by one
.then(() => log.add(creatures[idx])) // Add an event to 'latest visitors' log .then(() => log.add(creatures[idx])) // Add an event to 'latest visitors' log
.then(() => { .then(() => {
@ -37,37 +44,30 @@ try {
const latest = log.iterator({ limit: 5 }).collect() const latest = log.iterator({ limit: 5 }).collect()
const count = counter.value const count = counter.value
const output = const output = `
`<b>Key-Value Store</b> <b>Key-Value Store</b>
------------------------------------------------------- -------------------------------------------------------
Key | Value Key | Value
------------------------------------------------------- -------------------------------------------------------
${key} | ${result} ${key} | ${result}
------------------------------------------------------- -------------------------------------------------------
<b>Eventlog</b> <b>Eventlog</b>
------------------------------------------------------- -------------------------------------------------------
Latest Visitors Latest Visitors
------------------------------------------------------- -------------------------------------------------------
${latest.reverse().map((e) => e.payload.value + " at " + new Date(e.payload.meta.ts).toISOString()).join('\n')} ${latest.reverse().map((e) => e.payload.value + " at " + new Date(e.payload.meta.ts).toISOString()).join('\n')}
<b>Counter</b> <b>Counter</b>
------------------------------------------------------- -------------------------------------------------------
Visitor Count: ${count} Visitor Count: ${count}
------------------------------------------------------- -------------------------------------------------------
` `
elm.innerHTML = output.split("\n").join("<br>") elm.innerHTML = output.split("\n").join("<br>")
}) })
.catch((e) => { .catch((e) => handleError(e))
elm.innerHTML = "<i>" + e.message + "</i><br><br>" + "Waiting for IPFS daemon to start..."
console.error(e.stack)
})
} }
// Start query loop when the databse has loaded its history // Start query loop when the databse has loaded its history
db.events.on('ready', () => setInterval(query, 1000)) db.events.on('ready', () => setInterval(query, 1000))
})
} catch(e) {
console.error(e.stack)
elm.innerHTML = e.message
}

View File

@ -4,6 +4,7 @@ const IpfsDaemon = require('ipfs-daemon')
const OrbitDB = require('../src/OrbitDB') const OrbitDB = require('../src/OrbitDB')
const userId = Math.floor(Math.random() * 1000) const userId = Math.floor(Math.random() * 1000)
const conf = { const conf = {
IpfsDataDir: '/tmp/' + userId, IpfsDataDir: '/tmp/' + userId,
Addresses: { Addresses: {
@ -15,9 +16,12 @@ const conf = {
console.log("Starting...") console.log("Starting...")
IpfsDaemon(conf) const ipfs = new IpfsDaemon(conf)
.then((res) => {
const orbitdb = new OrbitDB(res.ipfs) ipfs.on('error', (err) => console.error(err))
ipfs.on('ready', () => {
const orbitdb = new OrbitDB(ipfs, userId)
const db = orbitdb.eventlog("|orbit-db|examples|eventlog-example") const db = orbitdb.eventlog("|orbit-db|examples|eventlog-example")
const creatures = ['🐙', '🐷', '🐬', '🐞', '🐈', '🙉', '🐸', '🐓'] const creatures = ['🐙', '🐷', '🐬', '🐞', '🐈', '🙉', '🐸', '🐓']
@ -40,5 +44,4 @@ IpfsDaemon(conf)
} }
setInterval(query, 1000) setInterval(query, 1000)
}) })
.catch((err) => console.error(err))

View File

@ -4,6 +4,7 @@ const IpfsDaemon = require('ipfs-daemon')
const OrbitDB = require('../src/OrbitDB') const OrbitDB = require('../src/OrbitDB')
const userId = Math.floor(Math.random() * 1000) const userId = Math.floor(Math.random() * 1000)
const conf = { const conf = {
IpfsDataDir: '/tmp/' + userId, IpfsDataDir: '/tmp/' + userId,
Addresses: { Addresses: {
@ -15,9 +16,12 @@ const conf = {
console.log("Starting...") console.log("Starting...")
IpfsDaemon(conf) const ipfs = new IpfsDaemon(conf)
.then((res) => {
const orbitdb = new OrbitDB(res.ipfs) ipfs.on('error', (err) => console.error(err))
ipfs.on('ready', () => {
const orbitdb = new OrbitDB(ipfs, userId)
const db = orbitdb.kvstore("|orbit-db|examples|kvstore-example") const db = orbitdb.kvstore("|orbit-db|examples|kvstore-example")
const creatures = ['🐙', '🐬', '🐋', '🐠', '🐡', '🦀', '🐢', '🐟', '🐳'] const creatures = ['🐙', '🐬', '🐋', '🐠', '🐡', '🦀', '🐢', '🐟', '🐳']
@ -43,5 +47,4 @@ IpfsDaemon(conf)
} }
setInterval(query, 1000) setInterval(query, 1000)
}) })
.catch((err) => console.error(err))

View File

@ -1,14 +0,0 @@
const IpfsDaemon = require('ipfs-daemon')
module.exports = IpfsDaemon({
IpfsDataDir: '/tmp/orbit-db-examples',
API: {
HTTPHeaders: {
"Access-Control-Allow-Origin": ['*'],
"Access-Control-Allow-Methods": ["PUT", "GET", "POST"],
"Access-Control-Allow-Credentials": ["true"]
}
}
})
.then((res) => console.log("Started IPFS daemon"))
.catch((err) => console.error(err))

View File

@ -1,6 +1,6 @@
{ {
"name": "orbit-db", "name": "orbit-db",
"version": "0.15.2", "version": "0.16.0",
"description": "Distributed p2p database on IPFS", "description": "Distributed p2p database on IPFS",
"author": "Haad", "author": "Haad",
"license": "MIT", "license": "MIT",
@ -18,16 +18,14 @@
"dependencies": { "dependencies": {
"fs-pull-blob-store": "^0.4.1", "fs-pull-blob-store": "^0.4.1",
"idb-pull-blob-store": "^0.5.1", "idb-pull-blob-store": "^0.5.1",
"ipfs-log": "^1.5.2",
"lock": "^0.1.3", "lock": "^0.1.3",
"logplease": "^1.2.9", "logplease": "^1.2.9",
"orbit-db-counterstore": "0.1.7", "orbit-db-counterstore": "^0.1.8",
"orbit-db-docstore": "0.0.8", "orbit-db-docstore": "haadcode/orbit-db-docstore",
"orbit-db-eventstore": "0.1.8", "orbit-db-eventstore": "^0.1.8",
"orbit-db-feedstore": "0.1.7", "orbit-db-feedstore": "^0.1.7",
"orbit-db-kvstore": "0.1.6", "orbit-db-kvstore": "^0.1.6",
"orbit-db-pubsub": "0.0.6", "orbit-db-pubsub": "^0.1.4",
"orbit-db-store": "^0.1.9",
"pull-stream": "^3.4.5" "pull-stream": "^3.4.5"
}, },
"devDependencies": { "devDependencies": {
@ -38,25 +36,23 @@
"babel-polyfill": "^6.16.0", "babel-polyfill": "^6.16.0",
"babel-preset-es2015": "^6.18.0", "babel-preset-es2015": "^6.18.0",
"bluebird": "^3.4.6", "bluebird": "^3.4.6",
"exports-loader": "^0.6.3", "ipfs-daemon": "^0.3.0-beta.16",
"ipfs-daemon": "0.1.1",
"ipfs-test-apis": "0.0.6",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"lodash": "^4.16.4", "lodash": "^4.16.4",
"mocha": "^3.1.2", "mocha": "^3.1.2",
"stream-http": "^2.4.1", "rimraf": "^2.5.4",
"webpack": "^2.1.0-beta.25" "stream-http": "^2.5.0",
"webpack": "^2.1.0-beta.28"
}, },
"scripts": { "scripts": {
"examples": "npm run examples:node", "examples": "npm run examples:node",
"examples:node": "node examples/eventlog.js", "examples:node": "node examples/eventlog.js",
"examples:browser": "open examples/browser/index.html && LOG=debug node examples/start-daemon.js", "examples:browser": "open examples/browser/index.html && LOG=debug node examples/start-daemon.js",
"postinstall": "./scripts/post_install.sh",
"test": "mocha", "test": "mocha",
"build": "npm run build:dist && npm run build:minified && npm run build:examples", "build": "npm run build:dist && npm run build:minified && npm run build:examples",
"build:dist": "./node_modules/.bin/webpack --config conf/webpack.config.js", "build:dist": "webpack --config conf/webpack.config.js",
"build:minified": "./node_modules/.bin/webpack --config conf/webpack.config.minified.js", "build:minified": "webpack --config conf/webpack.config.minified.js",
"build:examples": "./node_modules/.bin/webpack --config conf/webpack.example.config.js", "build:examples": "webpack --config conf/webpack.example.config.js",
"stats": "./node_modules/.bin/webpack --json > stats.json" "stats": "webpack --json > stats.json"
} }
} }

View File

@ -12,6 +12,9 @@ const lock = new Lock()
class Cache { class Cache {
static set(key, value) { static set(key, value) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (cache[key] === value)
return resolve()
cache[key] = value cache[key] = value
if(filePath && store) { if(filePath && store) {
lock(filePath, (release) => { lock(filePath, (release) => {

View File

@ -105,10 +105,10 @@ class OrbitDB {
Cache.set(dbname, hash) Cache.set(dbname, hash)
} }
_onData(dbname, item) { _onData(dbname, items) {
// 'New database entry...', after a new entry was added to the database // 'New database entry...', after a new entry was added to the database
// console.log(".SYNCED", dbname, items.length) // console.log(".SYNCED", dbname, items.length)
this.events.emit('data', dbname, item) this.events.emit('data', dbname, items)
} }
_onClose(dbname) { _onClose(dbname) {

View File

@ -7,43 +7,64 @@ const assert = require('assert')
const async = require('asyncawait/async') const async = require('asyncawait/async')
const await = require('asyncawait/await') const await = require('asyncawait/await')
const Promise = require('bluebird') const Promise = require('bluebird')
const IpfsApis = require('ipfs-test-apis') // const IpfsApis = require('ipfs-test-apis')
const OrbitDB = require('../src/OrbitDB') const OrbitDB = require('../src/OrbitDB')
const rmrf = require('rimraf')
const IpfsNodeDaemon = require('ipfs-daemon/src/ipfs-node-daemon')
const IpfsNativeDaemon = require('ipfs-daemon/src/ipfs-native-daemon')
if (typeof window !== 'undefined')
window.LOG = 'ERROR'
// Data directories
const defaultIpfsDirectory = './ipfs'
const defaultOrbitDBDirectory = './orbit-db'
// Orbit // Orbit
const username = 'testrunner' const username = 'testrunner'
let ipfs const hasIpfsApiWithPubsub = (ipfs) => {
return ipfs.object.get !== undefined
&& ipfs.object.put !== undefined
&& ipfs.pubsub.publish !== undefined
&& ipfs.pubsub.subscribe !== undefined
}
IpfsApis.forEach(function(ipfsApi) { [IpfsNativeDaemon, IpfsNodeDaemon].forEach((IpfsDaemon) => {
// [IpfsNodeDaemon].forEach((IpfsDaemon) => {
// IpfsApis.forEach(function(ipfsApi) {
describe('Orbit Client with ' + ipfsApi.name, function() { describe('orbit-db client', function() {
this.timeout(20000) this.timeout(40000)
let client, client2, db let ipfs, client, client2, db
let channel = 'abcdefghijklmn' let channel = 'abcdefghijklmn'
before(function (done) { before(function (done) {
ipfsApi.start({ IpfsDataDir: '/tmp/orbit-db-tests' }) rmrf.sync(defaultIpfsDirectory)
.then((res) => { rmrf.sync(defaultOrbitDBDirectory)
ipfs = res ipfs = new IpfsDaemon()
ipfs.on('error', done)
ipfs.on('ready', () => {
assert.equal(hasIpfsApiWithPubsub(ipfs), true)
client = new OrbitDB(ipfs, username) client = new OrbitDB(ipfs, username)
client2 = new OrbitDB(ipfs, username + '2') client2 = new OrbitDB(ipfs, username + '2')
done() done()
}) })
.catch(done)
}) })
after((done) => { after(() => {
if(db) db.delete() if(db) db.delete()
if(client) client.disconnect() if(client) client.disconnect()
if(client2) client2.disconnect() if(client2) client2.disconnect()
ipfsApi.stop().then(() => done()) ipfs.stop()
rmrf.sync(defaultOrbitDBDirectory)
rmrf.sync(defaultIpfsDirectory)
}) })
describe('Add events', function() { describe('Add events', function() {
beforeEach(() => { beforeEach(() => {
db = client.eventlog(channel, { subscribe: false }) db = client.eventlog(channel, { subscribe: false, maxHistory: 0 })
db.delete() db.delete()
}) })
@ -69,15 +90,12 @@ IpfsApis.forEach(function(ipfsApi) {
it('adds five items', async(() => { it('adds five items', async(() => {
for(let i = 1; i <= 5; i ++) for(let i = 1; i <= 5; i ++)
await(db.add('hello' + i)); await(db.add('hello' + i))
// const items = [1, 2, 3, 4, 5]
// return Promise.map(items, (i) => db.add('hello' + i), { concurrency: 1 })
// .then((res) => {
const items = db.iterator({ limit: -1 }).collect() const items = db.iterator({ limit: -1 }).collect()
assert.equal(items.length, 5) assert.equal(items.length, 5)
assert.equal(_.first(items.map((f) => f.payload.value)), 'hello1') assert.equal(_.first(items.map((f) => f.payload.value)), 'hello1')
assert.equal(_.last(items.map((f) => f.payload.value)), 'hello5') assert.equal(_.last(items.map((f) => f.payload.value)), 'hello5')
// })
})) }))
it('adds an item that is > 256 bytes', () => { it('adds an item that is > 256 bytes', () => {
@ -94,7 +112,7 @@ IpfsApis.forEach(function(ipfsApi) {
describe('Delete events (Feed)', function() { describe('Delete events (Feed)', function() {
beforeEach(() => { beforeEach(() => {
db = client.feed(channel, { subscribe: false }) db = client.feed(channel, { subscribe: false, maxHistory: 0 })
db.delete() db.delete()
}) })
@ -134,7 +152,7 @@ IpfsApis.forEach(function(ipfsApi) {
beforeEach(async(() => { beforeEach(async(() => {
items = [] items = []
db = client.eventlog(channel, { subscribe: false }) db = client.eventlog(channel, { subscribe: false, maxHistory: 0 })
db.delete() db.delete()
for(let i = 0; i < itemCount; i ++) { for(let i = 0; i < itemCount; i ++) {
const hash = await(db.add('hello' + i)) const hash = await(db.add('hello' + i))
@ -437,7 +455,7 @@ IpfsApis.forEach(function(ipfsApi) {
describe('Key-Value Store', function() { describe('Key-Value Store', function() {
beforeEach(() => { beforeEach(() => {
db = client.kvstore(channel, { subscribe: false }) db = client.kvstore(channel, { subscribe: false, maxHistory: 0 })
db.delete() db.delete()
}) })
@ -527,7 +545,7 @@ IpfsApis.forEach(function(ipfsApi) {
describe('Document Store - default index \'_id\'', function() { describe('Document Store - default index \'_id\'', function() {
beforeEach(() => { beforeEach(() => {
db = client.docstore(channel, { subscribe: false }) db = client.docstore(channel, { subscribe: false, maxHistory: 0 })
db.delete() db.delete()
}) })
@ -589,7 +607,7 @@ IpfsApis.forEach(function(ipfsApi) {
describe('Document Store - specified index', function() { describe('Document Store - specified index', function() {
beforeEach(() => { beforeEach(() => {
db = client.docstore(channel, { subscribe: false, indexBy: 'doc' }) db = client.docstore(channel, { subscribe: false, indexBy: 'doc', maxHistory: 0 })
db.delete() db.delete()
}) })

View File

@ -13,32 +13,47 @@
// const username2 = 'rennurtset' // const username2 = 'rennurtset'
// const cacheFile = path.join(process.cwd(), '/tmp/orbit-db-tests/cache.json') // const cacheFile = path.join(process.cwd(), '/tmp/orbit-db-tests/cache.json')
// const daemonConfs = require('./ipfs-daemons.conf.js')
// const waitForPeers = (ipfs, peersToWait, topic, callback) => {
// const i = setInterval(() => {
// ipfs.pubsub.peers(topic, (err, peers) => {
// if (err) {
// return callback(err)
// }
// const hasAllPeers = peersToWait.map((e) => peers.includes(e)).filter((e) => e === false).length === 0
// if (hasAllPeers) {
// clearInterval(i)
// callback(null)
// }
// })
// }, 1000)
// }
// IpfsApis.forEach(function(ipfsApi) { // IpfsApis.forEach(function(ipfsApi) {
// let ipfs, ipfsDaemon // let ipfs, ipfsDaemon
// describe('CounterStore with ' + ipfsApi.name, function() { // describe('CounterStore with ' + ipfsApi.name, function() {
// this.timeout(40000) // this.timeout(20000)
// let client1, client2 // let client1, client2
// let daemon1, daemon2 // let daemon1, daemon2
// before((done) => { // before((done) => {
// // rimraf.sync('./orbit-db-cache.json') // // rimraf.sync('./orbit-db-cache.json')
// daemon1 // daemon1 = new IpfsDaemon(daemonConfs.daemon1)
// Promise.all([ // daemon1.on('ready', () => {
// IpfsDaemon({ IpfsDataDir: '/tmp/daemon1' }), // daemon2 = new IpfsDaemon(daemonConfs.daemon2)
// IpfsDaemon({ IpfsDataDir: '/tmp/daemon2' }) // daemon2.on('ready', () => {
// ]) // ipfs = [daemon1, daemon2]
// .then((res) => {
// ipfs = [res[0].ipfs, res[1].ipfs]
// daemon1 = res[0].daemon
// daemon2 = res[1].daemon
// done() // done()
// }) // })
// }) // })
// })
// after((done) => { // after((done) => {
// daemon1.stopDaemon() // daemon1.stop()
// daemon2.stopDaemon() // daemon2.stop()
// done() // done()
// }) // })
@ -86,17 +101,23 @@
// const numbers = [[13, 10], [2, 5]] // const numbers = [[13, 10], [2, 5]]
// // const res1 = ([13, 10]).map((f) => counter1.inc(f))//, { concurrency: 1 }) // // const res1 = ([13, 10]).map((f) => counter1.inc(f))//, { concurrency: 1 })
// // const res2 = ([2, 5]).map((f) => counter2.inc(f))//, { concurrency: 1 }) // // const res2 = ([2, 5]).map((f) => counter2.inc(f))//, { concurrency: 1 })
// Promise.map([counter1, counter2], (counter, i) => numbers[i].map((e) => counter.inc(e)) , { concurrency: 1 })
// waitForPeers(daemon1, [daemon2.PeerId], name, (err, res) => {
// waitForPeers(daemon2, [daemon1.PeerId], name, (err, res) => {
// const increaseCounter = (counter, i) => numbers[i].map((e) => counter.inc(e))
// Promise.map([counter1, counter2], increaseCounter, { concurrency: 1 })
// .then((res) => { // .then((res) => {
// // wait for a while to make sure db's have been synced // // wait for a while to make sure db's have been synced
// setTimeout(() => { // setTimeout(() => {
// assert.equal(counter2.value(), 30) // assert.equal(counter2.value, 30)
// assert.equal(counter1.value(), 30) // assert.equal(counter1.value, 30)
// done() // done()
// }, 10000) // }, 2000)
// }) // })
// .catch(done) // .catch(done)
// }) // })
// })
// })
// }) // })
// }) // })

20
test/ipfs-daemons.conf.js Normal file
View File

@ -0,0 +1,20 @@
module.exports = {
daemon1: {
IpfsDataDir: '/tmp/orbit-db-tests-1',
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',
Swarm: ['/ip4/0.0.0.0/tcp/0'],
Gateway: '/ip4/0.0.0.0/tcp/0'
},
// Bootstrap: []
},
daemon2: {
IpfsDataDir: '/tmp/orbit-db-tests-2',
Addresses: {
API: '/ip4/127.0.0.1/tcp/0',
Swarm: ['/ip4/0.0.0.0/tcp/0'],
Gateway: '/ip4/0.0.0.0/tcp/0'
},
// Bootstrap: []
},
}

127
test/replicate.test.js Normal file
View File

@ -0,0 +1,127 @@
'use strict'
const _ = require('lodash')
const fs = require('fs')
const path = require('path')
const assert = require('assert')
const async = require('asyncawait/async')
const await = require('asyncawait/await')
const OrbitDB = require('../src/OrbitDB')
const rmrf = require('rimraf')
const IpfsNodeDaemon = require('ipfs-daemon/src/ipfs-node-daemon')
const IpfsNativeDaemon = require('ipfs-daemon/src/ipfs-native-daemon')
if (typeof window !== 'undefined')
window.LOG = 'ERROR'
// Data directories
const defaultIpfsDirectory = './ipfs'
const defaultOrbitDBDirectory = './orbit-db'
// Daemon settings
const daemonsConf = require('./ipfs-daemons.conf.js')
const databaseName = 'oribt-db-tests'
const hasIpfsApiWithPubsub = (ipfs) => {
return ipfs.object.get !== undefined
&& ipfs.object.put !== undefined
&& ipfs.pubsub.publish !== undefined
&& ipfs.pubsub.subscribe !== undefined
}
const waitForPeers = (ipfs, channel) => {
return new Promise((resolve) => {
console.log("Waiting for peers...")
const interval = setInterval(() => {
ipfs.pubsub.peers(channel)
.then((peers) => {
if (peers.length > 0) {
clearInterval(interval)
resolve()
}
})
}, 1000)
})
}
// [IpfsNativeDaemon, IpfsNodeDaemon].forEach((IpfsDaemon) => {
[IpfsNativeDaemon].forEach((IpfsDaemon) => {
describe('orbit-db replication', function() {
this.timeout(40000)
let ipfs1, ipfs2, client1, client2, db1, db2
const removeDirectories= () => {
rmrf.sync(daemonsConf.daemon1.IpfsDataDir)
rmrf.sync(daemonsConf.daemon2.IpfsDataDir)
rmrf.sync(defaultIpfsDirectory)
rmrf.sync(defaultOrbitDBDirectory)
}
before(function (done) {
removeDirectories()
ipfs1 = new IpfsDaemon(daemonsConf.daemon1)
ipfs1.on('error', done)
ipfs1.on('ready', () => {
assert.equal(hasIpfsApiWithPubsub(ipfs1), true)
ipfs2 = new IpfsDaemon(daemonsConf.daemon2)
ipfs2.on('error', done)
ipfs2.on('ready', () => {
assert.equal(hasIpfsApiWithPubsub(ipfs2), true)
client1 = new OrbitDB(ipfs1, databaseName)
client2 = new OrbitDB(ipfs2, databaseName + '2')
done()
})
})
})
after(() => {
ipfs1.stop()
ipfs2.stop()
removeDirectories()
})
describe('two peers', function() {
beforeEach(() => {
db1 = client1.eventlog(databaseName, { maxHistory: 0 })
db2 = client2.eventlog(databaseName, { maxHistory: 0 })
})
it('replicates database of 1 entry', (done) => {
waitForPeers(ipfs1, databaseName + '2')
.then(async(() => {
db2.events.on('history', (db, data) => {
const items = db2.iterator().collect()
assert.equal(items.length, 1)
assert.equal(items[0].payload.value, 'hello')
done()
})
db1.add('hello')
}))
})
it('replicates database of 100 entries', (done) => {
const entryCount = 100
waitForPeers(ipfs1, databaseName + '2')
.then(async(() => {
let count = 0
db2.events.on('history', (db, data) => {
count ++
if (count === entryCount) {
const items = db2.iterator({ limit: 100 }).collect()
assert.equal(items.length, entryCount)
assert.equal(items[0].payload.value, 'hello0')
assert.equal(_.last(items).payload.value, 'hello99')
done()
}
})
for(let i = 0; i < entryCount; i ++)
await(db1.add('hello' + i))
}))
})
})
})
})