Merge pull request #726 from orbitdb/feat/offline-mode

Add offline mode
This commit is contained in:
shamb0t 2019-11-14 14:28:24 +00:00 committed by GitHub
commit cb7b0809a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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
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()
})
})
})