From a9faf7b79818f96baecc933d9931c7f527e9faee Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Mon, 8 Apr 2019 14:44:46 +0100 Subject: [PATCH 1/4] fix: remove non default ipld formats in the browser --- README.md | 140 +++++++++++++++++++++++++++++++ package.json | 5 +- src/core/index.js | 44 +--------- src/core/runtime/ipld-browser.js | 15 ++++ src/core/runtime/ipld-nodejs.js | 54 ++++++++++++ 5 files changed, 215 insertions(+), 43 deletions(-) create mode 100644 src/core/runtime/ipld-browser.js create mode 100644 src/core/runtime/ipld-nodejs.js diff --git a/README.md b/README.md index 37629b9486..76bb8a6adb 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,146 @@ Enable and configure experimental features. Modify the default IPFS node config. This object will be *merged* with the default config; it will not replace it. +##### `options.ipld` + + | Type | Default | +|------|---------| +| object | [`ipld-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/ipld-nodejs.js) in Node.js, [`ipld-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/ipld-browser.js) in browsers | + + Modify the default IPLD config. This object will be *merged* with the default config; it will not replace it. Check IPLD [docs](https://github.com/ipld/js-ipld#ipld-constructor) for more information on the available options. + + > Browser config does **NOT** include by default all the IPLD formats. Only `ipld-dag-pb`, `ipld-dag-cbor` and `ipld-raw` are included. + + To add support for other formats we provide two options, one sync and another async. + + Examples for the sync option: + +
ESM Environments + +```js +import ipldGit from 'ipld-git' +import ipldBitcoin from 'ipld-bitcoin' + +const node = new IPFS( + { + ipld: { + formats: [ipldGit, ipldBitcoin] + } + } +) +``` +
+
Commonjs Environments + +```js +const node = new IPFS( + { + ipld: { + formats: [require('ipld-git'), require('ipld-bitcoin')] + } + } +) +``` +
+
Using script tags + +```html + + + + +``` +
+ + Examples for the async option: + + +
ESM Environments + +```js +const node = new IPFS( + { + ipld: { + async loadFormat (codec) { + if (codec === 'git-raw') { + return import('ipld-git') // This is a dynamic import + } else { + throw new Error('unable to load format ' + multicodec.print[codec]) + } + } + } + } +) +``` +> For more information about dynamic imports please check [webpack docs](https://webpack.js.org/guides/code-splitting/#dynamic-imports) or search your bundler documention. + +Using dynamic imports will tell your bundler to create a separate file (normally called *chunk*) that will **only** be request by the browser if it's really needed. This strategy will reduce your bundle size and load times without removing any functionality. + +With Webpack IPLD formats can even be grouped together using magic comments `import(/* webpackChunkName: "ipld-formats" */ 'ipld-git')` to produce a single file with all of them. + +
+
Commonjs Environments + +```js +const node = new IPFS( + { + ipld: { + async loadFormat (codec) { + if (codec === 'git-raw') { + return require('ipld-git') + } else { + throw new Error('unable to load format ' + multicodec.print[codec]) + } + } + } + } +) +``` +
+ +
Using Script tags + +```js + + +``` +
+ + ##### `options.libp2p` | Type | Default | diff --git a/package.json b/package.json index 53dbec020a..fe668f1171 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "./src/core/runtime/libp2p-nodejs.js": "./src/core/runtime/libp2p-browser.js", "./src/core/runtime/preload-nodejs.js": "./src/core/runtime/preload-browser.js", "./src/core/runtime/repo-nodejs.js": "./src/core/runtime/repo-browser.js", + "./src/core/runtime/ipld-nodejs.js": "./src/core/runtime/ipld-browser.js", "./test/utils/create-repo-nodejs.js": "./test/utils/create-repo-browser.js", "stream": "readable-stream", "joi": "joi-browser" @@ -115,9 +116,11 @@ "ipfs-unixfs-importer": "~0.38.5", "ipld": "~0.21.1", "ipld-bitcoin": "~0.1.8", - "ipld-dag-pb": "~0.15.3", + "ipld-dag-cbor": "^0.13.1", + "ipld-dag-pb": "^0.15.3", "ipld-ethereum": "^2.0.1", "ipld-git": "~0.3.0", + "ipld-raw": "^2.0.1", "ipld-zcash": "~0.1.6", "ipns": "~0.5.0", "is-ipfs": "~0.6.0", diff --git a/src/core/index.js b/src/core/index.js index 812043f7ca..d457cb6149 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -25,40 +25,7 @@ const components = require('./components') const defaultRepo = require('./runtime/repo-nodejs') const preload = require('./preload') const mfsPreload = require('./mfs-preload') - -// All known (non-default) IPLD formats -const IpldFormats = { - get 'bitcoin-block' () { - return require('ipld-bitcoin') - }, - get 'eth-account-snapshot' () { - return require('ipld-ethereum').ethAccountSnapshot - }, - get 'eth-block' () { - return require('ipld-ethereum').ethBlock - }, - get 'eth-block-list' () { - return require('ipld-ethereum').ethBlockList - }, - get 'eth-state-trie' () { - return require('ipld-ethereum').ethStateTrie - }, - get 'eth-storage-trie' () { - return require('ipld-ethereum').ethStorageTrie - }, - get 'eth-tx' () { - return require('ipld-ethereum').ethTx - }, - get 'eth-tx-trie' () { - return require('ipld-ethereum').ethTxTrie - }, - get 'git-raw' () { - return require('ipld-git') - }, - get 'zcash-block' () { - return require('ipld-zcash') - } -} +const ipldOptions = require('./runtime/ipld-nodejs') class IPFS extends EventEmitter { constructor (options) { @@ -106,14 +73,7 @@ class IPFS extends EventEmitter { this._peerInfo = undefined this._bitswap = undefined this._blockService = new BlockService(this._repo) - this._ipld = new Ipld({ - blockService: this._blockService, - loadFormat: (codec, callback) => { - this.log('Loading IPLD format', codec) - if (IpldFormats[codec]) return callback(null, IpldFormats[codec]) - callback(new Error(`Missing IPLD format "${codec}"`)) - } - }) + this._ipld = new Ipld(ipldOptions(this._blockService, this._options.ipld, this.log)) this._preload = preload(this) this._mfsPreload = mfsPreload(this) this._ipns = undefined diff --git a/src/core/runtime/ipld-browser.js b/src/core/runtime/ipld-browser.js new file mode 100644 index 0000000000..31c19c141a --- /dev/null +++ b/src/core/runtime/ipld-browser.js @@ -0,0 +1,15 @@ +'use strict' +const mergeOptions = require('merge-options') +const ipldDagCbor = require('ipld-dag-cbor') +const ipldDagPb = require('ipld-dag-pb') +const ipldRaw = require('ipld-raw') + +module.exports = (blockService, options = {}) => { + return mergeOptions.call( + // ensure we have the defaults formats even if the user overrides `formats: []` + { concatArrays: true }, + { + blockService: blockService, + formats: [ipldDagCbor, ipldDagPb, ipldRaw] + }, options) +} diff --git a/src/core/runtime/ipld-nodejs.js b/src/core/runtime/ipld-nodejs.js new file mode 100644 index 0000000000..aa2172fe82 --- /dev/null +++ b/src/core/runtime/ipld-nodejs.js @@ -0,0 +1,54 @@ +'use strict' +const mergeOptions = require('merge-options') +const ipldDagCbor = require('ipld-dag-cbor') +const ipldDagPb = require('ipld-dag-pb') +const ipldRaw = require('ipld-raw') + +// All known (non-default) IPLD formats +const IpldFormats = { + get 'bitcoin-block' () { + return require('ipld-bitcoin') + }, + get 'eth-account-snapshot' () { + return require('ipld-ethereum').ethAccountSnapshot + }, + get 'eth-block' () { + return require('ipld-ethereum').ethBlock + }, + get 'eth-block-list' () { + return require('ipld-ethereum').ethBlockList + }, + get 'eth-state-trie' () { + return require('ipld-ethereum').ethStateTrie + }, + get 'eth-storage-trie' () { + return require('ipld-ethereum').ethStorageTrie + }, + get 'eth-tx' () { + return require('ipld-ethereum').ethTx + }, + get 'eth-tx-trie' () { + return require('ipld-ethereum').ethTxTrie + }, + get 'git-raw' () { + return require('ipld-git') + }, + get 'zcash-block' () { + return require('ipld-zcash') + } +} + +module.exports = (blockService, options = {}, log) => { + return mergeOptions.call( + // ensure we have the defaults formats even if the user overrides `formats: []` + { concatArrays: true }, + { + blockService: blockService, + formats: [ipldDagCbor, ipldDagPb, ipldRaw], + loadFormat: (codec, callback) => { + log('Loading IPLD format', codec) + if (IpldFormats[codec]) return callback(null, IpldFormats[codec]) + callback(new Error(`Missing IPLD format "${codec}"`)) + } + }, options) +} From 69672353dfa2ca13e001430657169ec6758a150c Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Mon, 8 Apr 2019 14:54:35 +0100 Subject: [PATCH 2/4] chore: fix deps linter --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fe668f1171..b2ed25b1d0 100644 --- a/package.json +++ b/package.json @@ -116,8 +116,8 @@ "ipfs-unixfs-importer": "~0.38.5", "ipld": "~0.21.1", "ipld-bitcoin": "~0.1.8", - "ipld-dag-cbor": "^0.13.1", - "ipld-dag-pb": "^0.15.3", + "ipld-dag-cbor": "~0.13.1", + "ipld-dag-pb": "~0.15.3", "ipld-ethereum": "^2.0.1", "ipld-git": "~0.3.0", "ipld-raw": "^2.0.1", From 1c4ec8a4d91830af4eaf4f1303e29bf99e6828fb Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 9 Apr 2019 10:37:12 +0100 Subject: [PATCH 3/4] chore: fix docs Co-Authored-By: hugomrdias --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 76bb8a6adb..a32bf0943e 100644 --- a/README.md +++ b/README.md @@ -407,7 +407,7 @@ const node = new IPFS( ``` > For more information about dynamic imports please check [webpack docs](https://webpack.js.org/guides/code-splitting/#dynamic-imports) or search your bundler documention. -Using dynamic imports will tell your bundler to create a separate file (normally called *chunk*) that will **only** be request by the browser if it's really needed. This strategy will reduce your bundle size and load times without removing any functionality. +Using dynamic imports will tell your bundler to create a separate file (normally called *chunk*) that will **only** be requested by the browser if it's really needed. This strategy will reduce your bundle size and load times without removing any functionality. With Webpack IPLD formats can even be grouped together using magic comments `import(/* webpackChunkName: "ipld-formats" */ 'ipld-git')` to produce a single file with all of them. From 6bfca395e131f49e0c039f379db67b5c952c48e2 Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Fri, 12 Apr 2019 11:19:06 +0100 Subject: [PATCH 4/4] fix: make our bundle include all formats --- .aegir.js | 3 ++- package.json | 3 +++ src/core/runtime/ipld-browser-all.js | 26 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/core/runtime/ipld-browser-all.js diff --git a/.aegir.js b/.aegir.js index c09767c77d..cc10babb26 100644 --- a/.aegir.js +++ b/.aegir.js @@ -10,7 +10,8 @@ const preloadNode = MockPreloadNode.createNode() module.exports = { webpack: { resolve: { - mainFields: ['browser', 'main'] + mainFields: ['browser', 'main'], + aliasFields: ['browser', 'browser-all-ipld-formats'], } }, karma: { diff --git a/package.json b/package.json index b2ed25b1d0..458e70fc4d 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,9 @@ "stream": "readable-stream", "joi": "joi-browser" }, + "browser-all-ipld-formats": { + "./src/core/runtime/ipld-browser.js": "./src/core/runtime/ipld-browser-all.js" + }, "engines": { "node": ">=10.0.0", "npm": ">=6.0.0" diff --git a/src/core/runtime/ipld-browser-all.js b/src/core/runtime/ipld-browser-all.js new file mode 100644 index 0000000000..be618364fa --- /dev/null +++ b/src/core/runtime/ipld-browser-all.js @@ -0,0 +1,26 @@ +'use strict' +const mergeOptions = require('merge-options') + +module.exports = (blockService, options = {}) => { + return mergeOptions.call( + // ensure we have the defaults formats even if the user overrides `formats: []` + { concatArrays: true }, + { + blockService: blockService, + formats: [ + require('ipld-dag-cbor'), + require('ipld-dag-pb'), + require('ipld-raw'), + require('ipld-bitcoin'), + require('ipld-ethereum').ethAccountSnapshot, + require('ipld-ethereum').ethBlock, + require('ipld-ethereum').ethBlockList, + require('ipld-ethereum').ethStateTrie, + require('ipld-ethereum').ethStorageTrie, + require('ipld-ethereum').ethTx, + require('ipld-ethereum').ethTxTrie, + require('ipld-git'), + require('ipld-zcash') + ] + }, options) +}