diff --git a/README.md b/README.md index 2157fb0..de288c8 100644 --- a/README.md +++ b/README.md @@ -15,46 +15,121 @@ Base class for [orbit-db](https://github.com/orbitdb/orbit-db) data stores. You - Node.js >= 8.0.0 -### API +## Table of Contents + + + +- [API](#api) + * [constructor(ipfs, identity, address, options)](#constructoripfs-identity-address-options) + * [Public methods](#public-methods) + + [load([amount], [opts])](#loadamount-opts) + + [loadMoreFrom(amount, entries)](#loadmorefromamount-entries) + + [setIdentity (identity)](#setidentity-identity) + + [saveSnapshot()](#savesnapshot) + + [loadFromSnapshot()](#loadfromsnapshot) + + [close()](#close) + + [drop()](#drop) + + [sync(heads)](#syncheads) + * [Properties](#properties) + + [address](#address) + + [identity](#identity) + + [all](#all) + + [type](#type) + + [replicationStatus](#replicationstatus) + * [Events](#events) + * [Private methods](#private-methods) + + [_addOperation(data, [options])](#_addoperationdata-options) + * [Creating Custom Data Stores](#creating-custom-data-stores) +- [Contributing](#contributing) +- [License](#license) + + + +## API + +### constructor(ipfs, identity, address, options) + +**ipfs** can be an [IPFS](https://github.com/ipfs/js-ipfs) instance or an [IPFS-API](https://github.com/ipfs/js-ipfs) instance. **identity** is an instance of [Identity](https://github.com/orbitdb/orbit-db-identity-provider/). **address** is the OrbitDB address to be used for the store. + +`options` is an object with the following required properties: + +- `cache`: A [Cache](https://github.com/orbitdb/orbit-db-cache) instance to use for storing heads and snapshots. +- `Index` : By default it uses an instance of [Index](https://github.com/orbitdb/orbit-db-store/blob/master/src/Index.js). + +the following properties are optional: + +- `maxHistory` (Integer): The number of entries to load (Default: `-1`). +- `syncLocal` (Boolean): Load local database before performing any append operations. (Default: `false`). +- `fetchEntryTimeout` (Integer): The number in `ms` specifying a timeout when fetching entries from IPFS. (Default: `null`). +- `referenceCount` (Integer): The number of previous ipfs-log entries a new entry should reference (Default: `64`). +- `replicationConcurrency` (Integer): The number of concurrent replication processes (Default: `128`). +- `accessController` (Object): An instance of AccessController with the following [interface](https://github.com/orbitdb/orbit-db-access-controllers/blob/master/src/access-controller-interface.js). See [orbit-db-access-controllers](https://github.com/orbitdb/orbit-db-access-controllers) for more information on how to create custom access controllers. By default only the owner will have write access. +- `sortFn` (Function): A function used to sort ipfs-log entries (Default: `undefined`). +- `onClose` (Function): A function to be called with a string of the OrbitDB address of the database that is closing. +- `onDrop` (Function): A function to be called with the orbit-db-store instance when the database is being removed. +- `onLoad` (Function): A function to be called with the orbit-db-store instance when the database is being loaded. + +### Public methods + +#### load([amount], [opts]) +> Load the database using locally persisted state. + +Returns a **Promise** that resolves once complete. Provide an optional `amount` argument to specify how many entries to load. By default the `maxHistory` option is used. Provide an optional `options` object with a `fetchEntryTimeout` property to be used when loading entries from IPFS. + +#### loadMoreFrom(amount, entries) +> TODO -#### Public methods +```javascript +//TODO +db.loadMoreFrom() +``` -##### `load(amount)` +#### setIdentity (identity) +> Set the identity for the database -Load the database using locally persisted state. Can specify how many entries to load with `amount` argument. -##### `saveSnapshot()` +#### saveSnapshot() +> Save the current state of the database locally. -Save the current state of the database locally. Returns a *Promise* that resolves to a IPFS Multihash as a Base58 encoded string. The the database can be loaded using this hash. +Returns a **Promise** that resolves to an array containing an object with the following properties: -##### `loadFromSnapshot(hash, onProgressCallback)` +- `path` of the snapshot file +- `hash` representing the IPFS Multihash (as a Base58 encoded string) of the snapshot file +- `size` of the snapshot file -Load the state of the database from a snapshot. *hash* is the IPFS Multihash of the snapshot data. Returns a *Promise* that resolves when the database has been loaded. +#### loadFromSnapshot() +> Load the state of the database from a snapshot. -##### `close()` +Returns a **Promise** that resolves to a store instance once it has been loaded. -Uninitialize the store. Emits `close` after the store has been uninitialized. +#### close() +> Uninitialize the store. -##### `drop()` +Returns a **promise** that resolves once complete. Emits `close` after the store has been uninitialized. -Remove the database locally. This doesn't remove or delete the database from peers who have replicated the database. +#### drop() +> Remove the database locally. -##### `sync(heads)` +Returns a **promise** that resolves once complete. This doesn't remove or delete the database from peers who have replicated the database. -Sync this database with entries from *heads* where *heads* is an array of ipfs-log Entries. Usually, you don't need to call this method manually as OrbitDB takes care of this for you. +#### sync(heads) +> Sync this database with entries from **heads** where **heads** is an array of ipfs-log Entries. -#### Properties +Usually, you don't need to call this method manually as OrbitDB takes care of this for you. -##### `address` +### Properties -Get the address of this database. Returns an object `{ root: , path: }`. Convert to a string with `db.address.toString()`. +#### address +> Get the address of this database. + +Returns an object `{ root: , path: }`. Convert to a string with `db.address.toString()`. ```javascript console.log(db.address.toString()) // /orbitdb/zdpuB383kQWjyCd5nv4FKqZwe2FH4nqxBBE7kzoDrmdtZ6GPu/databaseName ``` -##### `identity` +#### identity Each store has an `identity` property containing the public key used with this store to sign and access entries. This `publicKey` property of `identity` is the peer/node/user key. @@ -63,17 +138,28 @@ console.log(db.identity.publicKey) // 042c07044e7ea51a489c02854db5e09f0191690dc59db0afd95328c9db614a2976e088cab7c86d7e48183191258fc59dc699653508ce25bf0369d67f33d5d77839 ``` -##### `type` +#### all +> Get all of the entries in the store index -The type of datastore model of the current instance. +Returns an array of all store entries within the index. + +```javascript +db.all +``` + +#### type +> Get the store type + +Returns a string of the type of datastore model of the current instance. ```javascript console.log(db.type) // "eventlog" ``` -##### `replicationStatus` +#### replicationStatus +> Get database replication status information such as total number of entries and loading progress. -Get database replication status information such as total number of entries and loading progress. +Returns an instance of [ReplicationInfo](https://github.com/orbitdb/orbit-db-store/blob/master/src/replication-info.js). ```javascript console.log(db.replicationStatus) @@ -84,56 +170,83 @@ console.log(db.replicationStatus) Store has an `events` ([EventEmitter](https://nodejs.org/api/events.html)) object that emits events that describe what's happening in the database. - - `load` - (dbname, hash) + - `load` - (address, heads) - Emitted before loading the database history. *hash* is the hash from which the history is loaded. + Emitted before loading the database history. **address** is a string of the OrbitDB address being loaded. **heads** is an array of ipfs-log Entries from which the history is loaded from. **heads** is omitted when this event is emitted as a result of `loadFromSnapshot`. ```javascript - db.events.on('load', (id, hash) => ... ) + db.events.on('load', (address, heads) => ... ) db.load() ``` - - `ready` - (dbname) + - `ready` - (address, heads) - Emitted after fully loading the database history. + Emitted after fully loading the database history. **address** is a string of the OrbitDB address that emitted the event. **heads** is an array of ipfs-log Entries. ```javascript - db.events.on('ready', (id) => ... ) + db.events.on('ready', (address, heads) => ... ) db.load() ``` - - `load.progress` - (id, hash, entry, progress, total) - - Emitted for each entry during load. + - `load.progress` - (address, hash, entry, progress, total) - *Progress* is the current load count. *Total* is the maximum load count (ie. length of the full database). These are useful eg. for displaying a load progress percentage. + Emitted for each entry during load. **address** is a string of the OrbitDB address that emitted the event. **hash** is the multihash of the entry that was just loaded. **entry** is the ipfs-log Entry that was loaded. **Progress** is the current load count. **Total** is the maximum load count (ie. length of the full database). These are useful eg. for displaying a load progress percentage. ```javascript - db.events.on('load.progress', (id, hash, entry, progress, total) => ... ) + db.events.on('load.progress', (address, hash, entry, progress, total) => ... ) db.load() ``` - - `replicated` - (dbname) + - `replicate` - (address, entry) - Emitted after the database was synced with an update from a peer database. + Emitted before replicating a part of the database. **address** is a string of the OrbitDB address that emitted the event. **entry** is the ipfs-log Entry that is being processed. ```javascript - db.events.on('replicated', (id, length) => ... ) + db.events.on('replicate', (address, entry) => ... ) ``` - - `write` - (id, hash, entry) + - `replicate.progress` - (address, hash, entry, progress, total) - Emitted after an entry was added locally to the database. *hash* is the IPFS hash of the latest state of the database. *entry* is the Entry that was added. + Emitted while replicating a database. **address** is a string of the OrbitDB address of the database that emitted the event. **hash** is the multihash of the entry that was just replicated. **entry** is the ipfs-log Entry that was replicated. **progress** is an integer representing the current progress. **total** is an integer representing the remaining operations. ```javascript - db.events.on('write', (id, hash, entry) => ... ) + db.events.on('replicate.progress', (address, hash, entry, progress, total) => ... ) ``` -#### Private methods + - `replicated` - (address, count) + + Emitted after the database was synced with an update from a peer database. **address** is a string of the OrbitDB address that emitted the event. **count** number of items replicated. **count** is omitted when this event is emitted as a result of `loadFromSnapshot`. + + ```javascript + db.events.on('replicated', (address, count) => ... ) + ``` + + - `write` - (address, entry, heads) + + Emitted after an entry was added locally to the database. **address** is a string of the OrbitDB address that emitted the event. **entry** is the Entry that was added. **heads** is an array of ipfs-log Entries. + + ```javascript + db.events.on('write', (address, entry, heads) => ... ) + ``` + + - `closed` - (address) + + Emitted once the database has finished closing. **address** is a string of the OrbitDB address that emitted the event. + + ```javascript + db.events.on('closed', (address) => ... ) + db.close() + ``` + +### Private methods + +#### `_addOperation(data, [options])` +> Add an entry to the store. -##### `_addOperation(data)` +Returns a **Promise** that resolves to the IPFS Multihash of the added entry. Takes `data` as a parameter which can be of any type. Provide an optional `options` arguement, which is an object with the following properties: -Add an entry to the store. Takes `data` as a parameter which can be of any type. +- `onProgressCallback` (Function): To be called once the data is appended. +- `pin` (Boolean): To specify whether or not to pin the entry in IPFS. (Default: `false`). ```javascript this._addOperation({ @@ -153,9 +266,9 @@ const Store = require('orbit-db-store'); const KeyValueIndex = require('./KeyValueIndex'); class KeyValueStore extends Store { - constructor(ipfs, identity, dbname, options) { + constructor(ipfs, identity, address, options) { Object.assign(options || {}, { Index: KeyValueIndex }); - super(ipfs, identity, dbname, options) + super(ipfs, identity, address, options) } get(key) { diff --git a/package.json b/package.json index e410f2e..c8a7130 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "test:browser": "npm run build:tests && mocha-headless-chrome -f ./test/browser/index.html -a no-sandbox", "build": "npm run build:dist", "build:dist": "webpack --config ./conf/webpack.config.js --display-modules --sort-modules-by size --mode production", + "build:docs": "markdown-toc --no-first1 -i README.md", "build:tests": "webpack --config ./conf/webpack.tests.config.js --mode production", "lint": "standard" }, @@ -45,6 +46,7 @@ "@babel/runtime": "^7.4.5", "babel-loader": "~8.0.4", "json-loader": "~0.5.7", + "markdown-toc": "^1.2.0", "mocha": "^6.2.0", "mocha-headless-chrome": "^2.0.3", "orbit-db-cache": "~0.3.0", diff --git a/src/Store.js b/src/Store.js index 134b2b7..1f8d791 100644 --- a/src/Store.js +++ b/src/Store.js @@ -21,7 +21,6 @@ const DefaultOptions = { Index: Index, maxHistory: -1, fetchEntryTimeout: null, - replicate: true, referenceCount: 32, replicationConcurrency: 128, syncLocal: false, @@ -227,9 +226,13 @@ class Store { this._cache = this.options.cache } - async load (amount, { fetchEntryTimeout } = {}) { + async load (amount, opts = {}) { + if (typeof amount === 'object') { + opts = amount + amount = undefined + } amount = amount || this.options.maxHistory - fetchEntryTimeout = fetchEntryTimeout || this.options.fetchEntryTimeout + const fetchEntryTimeout = opts.fetchEntryTimeout || this.options.fetchEntryTimeout if (this.options.onLoad) { await this.options.onLoad(this) @@ -380,7 +383,7 @@ class Store { await this.options.onLoad(this) } - this.events.emit('load', this.address.toString()) + this.events.emit('load', this.address.toString()) // TODO emits inconsistent params, missing heads param const maxClock = (res, val) => Math.max(res, val.clock.time) @@ -476,7 +479,7 @@ class Store { const log = await Log.fromJSON(this._ipfs, this.identity, snapshotData, { access: this.access, sortFn: this.options.sortFn, length: -1, timeout: 1000, onProgressCallback: onProgress }) await this._oplog.join(log) await this._updateIndex() - this.events.emit('replicated', this.address.toString()) + this.events.emit('replicated', this.address.toString()) // TODO: inconsistent params, count param not emited } this.events.emit('ready', this.address.toString(), this._oplog.heads) } else {