Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API revamp and cleansing #140

Merged
merged 27 commits into from
Jul 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
872284b
documenting new API
pgte Jun 28, 2017
929695b
cleansing and new API
pgte Jun 29, 2017
5bf8ad4
get and set specific parts of the config value
pgte Jun 29, 2017
6029487
small fixes
pgte Jun 29, 2017
85380a5
readme: broke down API into sections
pgte Jun 29, 2017
1c877fa
docs: correcting the blocks API
pgte Jun 29, 2017
13499cd
fixed minor spelling mistake on error message
pgte Jun 29, 2017
210e494
documented repo.exists
pgte Jun 29, 2017
8904d7a
blockstore does not need datastore any more
pgte Jun 29, 2017
7c59443
config.set supports object path key
pgte Jun 30, 2017
87a40b1
docs: corrected config api and added example
pgte Jun 30, 2017
41b021e
fail when config doesnt have the key
pgte Jun 30, 2017
424d0d8
docs: API clarifications and slight changes
pgte Jul 1, 2017
77d1e43
docs: more slight readme changes
pgte Jul 1, 2017
bb6dccd
docs: added link to the the ipfs-blocks repo
pgte Jul 1, 2017
90ae830
fix: docs api and example typo
pgte Jul 1, 2017
25bab69
docs: fixed typos
pgte Jul 1, 2017
1cf93ab
using safe-buffer
pgte Jul 3, 2017
bf82528
succumbing to one liner return callback
pgte Jul 3, 2017
174fff0
DRYer and more elegant error ignoration
pgte Jul 3, 2017
8e8055d
validating arguments and supporting get with undefined key
pgte Jul 4, 2017
40791c5
docs: some README fixes
pgte Jul 4, 2017
a156241
docs: added repo.config.exists
pgte Jul 4, 2017
a9293e2
docs: added a bit of explanation to the meaning of each repo type
pgte Jul 4, 2017
85a2810
tests: new test repo out of go-ipfs v0.4.10
pgte Jul 4, 2017
c5695ed
tests: some more interop tests for blocks and datastore
pgte Jul 4, 2017
bda0e7f
tests: fixed missing level file
pgte Jul 4, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 148 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,154 @@ This now has created the following structure, either on disk or as an in memory

## API

See https://ipfs.github.io/js-ipfs-repo
### Setup

#### `new Repo(path[, options])`

Creates an IPFS Repo.

Arguments:

* `path` (string, mandatory): the path for this repo
* `options` (object, optional): may contain the following values
* `lock` (string, defaults to `"fs"` in Node.js, `"memory"` in the browser): what type of lock to use. Lock has to be acquired when opening.
* `storageBackends` (object, optional): may contain the following values, which should each be a class implementing the [datastore interface](https://github.com/ipfs/interface-datastore#readme):
* `root` (defaults to [`datastore-fs`](https://github.com/ipfs/js-datastore-fs#readme) in Node.js and [`datastore-level`](https://github.com/ipfs/js-datastore-level#readme) in the browser). Defines the back-end type used for gets and puts of values at the root (`repo.set()`, `repo.get()`)
* `blocks` (defaults to [`datastore-fs`](https://github.com/ipfs/js-datastore-fs#readme) in Node.js and [`datastore-level`](https://github.com/ipfs/js-datastore-level#readme) in the browser). Defines the back-end type used for gets and puts of values at `repo.blocks`.
* `datastore` (defaults to [`datastore-level`](https://github.com/ipfs/js-datastore-level#readme)). Defines the back-end type used as the key-valye store used for gets and puts of values at `repo.datastore`.

```js
const repo = new Repo('path/to/repo')
```

#### `repo.init (callback)`

Creates the necessary folder structure inside the repo.

#### `repo.open (callback)`

Locks the repo.

#### `repo.close (callback)`

Unlocks the repo.

#### `repo.exists (callback)`

Tells whether this repo exists or not. Calls back with `(err, bool)`.

### Repos

Root repo:

#### `repo.put (key, value:Buffer, callback)`

Put a value at the root of the repo.

* `key` can be a buffer, a string or a [Key](https://github.com/ipfs/interface-datastore#keys).

#### `repo.get (key, callback)`

Get a value at the root of the repo.

* `key` can be a buffer, a string or a [Key](https://github.com/ipfs/interface-datastore#keys).
* `callback` is a callback function `function (err, result:Buffer)`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add a line here saying "blocks/blockstore" and link it to the ipfs-block class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

[Blocks](https://github.com/ipfs/js-ipfs-block#readme):

#### `repo.blocks.put (block:Block, callback)`

* `block` should be of type [Block](https://github.com/ipfs/js-ipfs-block#readme).

#### `repo.blocks.putMany (blocks, callback)`

Put many blocks.

* `block` should be an array of type [Block](https://github.com/ipfs/js-ipfs-block#readme).

#### `repo.blocks.get (cid, callback)`

Get block.

* `cid` is the content id of [type CID](https://github.com/ipld/js-cid#readme).
* `callback` is a callback function `function (err, result:Buffer)`

Datastore:

#### `repo.datastore`

This is contains a full implementation of [the `interface-datastore` API](https://github.com/ipfs/interface-datastore#api).


### Utils

#### `repo.config`

Instead of using `repo.set('config')` this exposes an API that allows you to set and get a decoded config object, as well as, in a safe manner, change any of the config values individually.

##### `repo.config.set(key:string, value, callback)`

Set a config value. `value` can be any object that is serializable to JSON.

* `key` is a string specifying the object path. Example:

```js
repo.config.set('a.b.c', 'c value', (err) => {
if (err) { throw err }
repo.config.get((err, config) => {
if (err) { throw err }
assert.equal(config.a.b.c, 'c value')
})
})
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra \n

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

##### `repo.config.get(value, callback)`

Set the whole config value. `value` can be any object that is serializable to JSON.

##### `repo.config.get(key:string, callback)`

Get a config value. `callback` is a function with the signature: `function (err, value)`, wehre the `
value` is of the same type that was set before.

* `key` is a string specifying the object path. Example:

```js
repo.config.get('a.b.c', (err, value) => {
if (err) { throw err }
console.log('config.a.b.c = ', value)
})
```

##### `repo.config.get(callback)`

Get the entire config value. `callback` is a function with the signature: `function (err, configValue:Object)`.

#### `repo.config.exists(callback)`

Whether the config sub-repo exists. Calls back with `(err, bool)`.

#### `repo.version`

##### `repo.version.get (callback)`

Gets the repo version.

##### `repo.version.set (version:number, callback)`

Sets the repo version

#### `repo.apiAddr`

#### `repo.apiAddr.get (callback)`

Gets the API address.

#### `repo.apiAddr.set (value, callback)`

Sets the API address.

* `value` should be a [Multiaddr](https://github.com/multiformats/js-multiaddr) or a String representing a valid one.

## Notes

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
"level-js": "timkuijsten/level.js#idbunwrapper",
"leveldown": "^1.7.2",
"lock-me": "^1.0.2",
"lodash.get": "^4.4.2",
"lodash.has": "^4.5.2",
"lodash.set": "^4.3.2",
"multiaddr": "^2.3.0",
"safe-buffer": "^5.1.1"
},
Expand All @@ -85,4 +88,4 @@
"nginnever <ginneversource@gmail.com>",
"npmcdn-to-unpkg-bot <npmcdn-to-unpkg-bot@users.noreply.github.com>"
]
}
}
39 changes: 39 additions & 0 deletions src/api-addr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict'

const Key = require('interface-datastore').Key
const Buffer = require('safe-buffer').Buffer

const apiFile = new Key('api')

module.exports = (store) => {
return {
/**
* Get the current configuration from the repo.
*
* @param {function(Error, Object)} callback
* @returns {void}
*/
get (callback) {
store.get(apiFile, (err, value) => callback(err, value && value.toString()))
},
/**
* Set the current configuration for this repo.
*
* @param {Object} value - the api address to be written
* @param {function(Error)} callback
* @returns {void}
*/
set (value, callback) {
store.put(apiFile, Buffer.from(value.toString()), callback)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buffer.from is not available in node@4 you will need to include safe-buffer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

},
/**
* Deletes api file
*
* @param {function(Error, bool)} callback
* @returns {void}
*/
delete (callback) {
store.delete(apiFile, callback)
}
}
}
7 changes: 7 additions & 0 deletions src/backends.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

exports.create = function createBackend (name, path, options) {
const Ctor = options.storageBackends[name]
const backendOptions = Object.assign({}, options.storageBackendOptions[name] || {})
return new Ctor(path, backendOptions)
}
41 changes: 27 additions & 14 deletions src/blockstore.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
'use strict'

const NamespaceStore = require('datastore-core').NamespaceDatastore
const core = require('datastore-core')
const ShardingStore = core.ShardingDatastore
const Key = require('interface-datastore').Key
const base32 = require('base32.js')
const Block = require('ipfs-block')
const setImmediate = require('async/setImmediate')
const reject = require('async/reject')
const CID = require('cids')

const blockPrefix = new Key('blocks')

/**
* Transform a raw buffer to a base32 encoded key.
*
Expand All @@ -31,8 +30,24 @@ const cidToDsKey = (cid) => {
return keyFromBuffer(cid.buffer)
}

module.exports = (repo) => {
const store = new NamespaceStore(repo.store, blockPrefix)
module.exports = (filestore, options, callback) => {
maybeWithSharding(filestore, options, (err, store) => {
if (err) { return callback(err) }

callback(null, createBaseStore(store))
})
}

function maybeWithSharding (filestore, options, callback) {
if (options.sharding) {
const shard = new core.shard.NextToLast(2)
ShardingStore.createOrOpen(filestore, shard, callback)
} else {
setImmediate(() => callback(null, filestore))
}
}

function createBaseStore (store) {
return {
/**
* Get a single block by CID.
Expand All @@ -50,9 +65,7 @@ module.exports = (repo) => {

const k = cidToDsKey(cid)
store.get(k, (err, blockData) => {
if (err) {
return callback(err)
}
if (err) { return callback(err) }

callback(null, new Block(blockData, cid))
})
Expand All @@ -67,12 +80,8 @@ module.exports = (repo) => {
const k = cidToDsKey(block.cid)

store.has(k, (err, exists) => {
if (err) {
return callback(err)
}
if (exists) {
return callback()
}
if (err) { return callback(err) }
if (exists) { return callback() }

store.put(k, block.data, callback)
})
Expand Down Expand Up @@ -134,6 +143,10 @@ module.exports = (repo) => {
}

store.delete(cidToDsKey(cid), callback)
},

close (callback) {
store.close(callback)
}
}
}
Loading