Add offline mode option

This commit is contained in:
haad 2019-11-14 13:17:42 +02:00
parent 183f72be84
commit de6cfdb1da
3 changed files with 91 additions and 5 deletions

4
API.md
View File

@ -81,10 +81,12 @@ Creates and returns an instance of OrbitDB. Use the optional `options` argument
- `keystore` (Keystore Instance) : By default creates an instance of [Keystore](https://github.com/orbitdb/orbit-db-keystore). A custom keystore instance can be used, see [this](https://github.com/orbitdb/orbit-db/blob/master/test/utils/custom-test-keystore.js) for an example.
- 'cache' (Cache Instance) : By default creates an instance of [Cache](https://github.com/orbitdb/orbit-db-cache). A custom cache instance can also be used.
- `cache` (Cache Instance) : By default creates an instance of [Cache](https://github.com/orbitdb/orbit-db-cache). A custom cache instance can also be used.
- `identity` (Identity Instance): By default it creates an instance of [Identity](https://github.com/orbitdb/orbit-db-identity-provider/blob/master/src/identity.js)
- `offline` (boolean): Start the OrbitDB instance in offline mode. Databases are not be replicated when the instance is started in offline mode. If the OrbitDB instance was started offline mode and you want to start replicating databases, the OrbitDB instance needs to be re-created. Default: `false`.
After creating an `OrbitDB` instance, you can access the different data stores. Creating a database instance, eg. with `orbitdb.keyvalue(...)`, returns a *Promise* that resolves to a [database instance](#store-api). See the [Store](#store-api) section for details of common methods and properties.
*For further details, see usage for [kvstore](https://github.com/orbitdb/orbit-db-kvstore#usage), [eventlog](https://github.com/orbitdb/orbit-db-eventstore#usage), [feed](https://github.com/orbitdb/orbit-db-feedstore#usage), [docstore](https://github.com/orbitdb/orbit-db-docstore#usage) and [counter](https://github.com/orbitdb/orbit-db-counterstore#usage).*

View File

@ -40,9 +40,11 @@ class OrbitDB {
this._ipfs = ipfs
this.identity = identity
this.id = options.peerId
this._pubsub = options && options.broker
? new options.broker(this._ipfs) // eslint-disable-line
: new Pubsub(this._ipfs, this.id)
this._pubsub = !options.offline
? options.broker
? new options.broker(this._ipfs) // eslint-disable-line
: new Pubsub(this._ipfs, this.id)
: null
this.directory = options.directory || './orbitdb'
this.storage = options.storage
this._directConnections = {}
@ -110,6 +112,10 @@ class OrbitDB {
options.cache = new Cache(cacheStorage)
}
if (options.offline === undefined) {
options.offline = false
}
const finalOptions = Object.assign({}, options, { peerId: id })
return new OrbitDB(ipfs, options.identity, finalOptions)
}
@ -228,7 +234,7 @@ class OrbitDB {
// Subscribe to pubsub to get updates from peers,
// this is what hooks us into the message propagation layer
// and the p2p network
if (opts.replicate && this._pubsub) { this._pubsub.subscribe(addr, this._onMessage.bind(this), this._onPeerConnected.bind(this)) }
if (opts.replicate && this._pubsub) { await this._pubsub.subscribe(addr, this._onMessage.bind(this), this._onPeerConnected.bind(this)) }
return store
}

78
test/offline-mode.js Normal file
View File

@ -0,0 +1,78 @@
'use strict'
const fs = require('fs')
const path = require('path')
const assert = require('assert')
const mapSeries = require('p-map-series')
const rmrf = require('rimraf')
const IPFS = require('ipfs')
const OrbitDB = require('../src/OrbitDB')
const Identities = require('orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const leveldown = require('leveldown')
const storage = require('orbit-db-storage-adapter')(leveldown)
// Include test utilities
const {
config,
startIpfs,
stopIpfs,
testAPIs,
} = require('./utils')
const dbPath1 = './orbitdb/tests/offline/db1'
const dbPath2 = './orbitdb/tests/offline/db2'
const ipfsPath = './orbitdb/tests/offline/ipfs'
Object.keys(testAPIs).forEach(API => {
describe(`orbit-db - Offline mode (${API})`, function() {
this.timeout(config.timeout)
let ipfsd1, ipfsd2, ipfs1, ipfs2, orbitdb, db, keystore
let identity1, identity2
let localDataPath
before(async () => {
config.daemon1.repo = path.join(ipfsPath, '/1')
config.daemon2.repo = path.join(ipfsPath, '/2')
rmrf.sync(config.daemon1.repo)
rmrf.sync(config.daemon2.repo)
rmrf.sync(path.join(ipfsPath, '/2'))
rmrf.sync('./orbitdb/tests/offline')
rmrf.sync(dbPath1)
rmrf.sync(dbPath2)
ipfsd1 = await startIpfs(API, config.daemon1)
ipfsd2 = await startIpfs(API, config.daemon2)
ipfs1 = ipfsd1.api
ipfs2 = ipfsd2.api
})
after(async () => {
if(orbitdb)
await orbitdb.stop()
if (ipfsd1)
await stopIpfs(ipfsd1)
if (ipfsd2)
await stopIpfs(ipfsd2)
})
it('starts in offline mode', async () => {
orbitdb = await OrbitDB.createInstance(ipfs1, { offline: true, directory: dbPath1 })
assert.equal(orbitdb._pubsub, null)
await orbitdb.stop()
})
it('does not start in offline mode', async () => {
orbitdb = await OrbitDB.createInstance(ipfs1, { offline: false, directory: dbPath1 })
assert.notEqual(orbitdb._pubsub, null)
await orbitdb.stop()
})
it('does not start in offline mode - default', async () => {
orbitdb = await OrbitDB.createInstance(ipfs1, { directory: dbPath1 })
assert.notEqual(orbitdb._pubsub, null)
await orbitdb.stop()
})
})
})