diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 14f1c64f..91820656 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,6 +1,9 @@ # Release Notes -## v1.10.7 - 2019-08-22 +## v1.10.9 - 2019-09-10 +* fix: allow multiple tab connections (support) + +## v1.10.8 - 2019-08-22 * fix: ensureConnected consume db adddress, reconnect ## v1.10.7 - 2019-08-17 diff --git a/package.json b/package.json index 11d0bbcd..baa37a8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "3box", - "version": "1.10.8", + "version": "1.10.9", "description": "Interact with user data", "main": "lib/3box.js", "directories": { @@ -52,7 +52,7 @@ "events": "^3.0.0", "graphql-request": "^1.8.2", "https-did-resolver": "^0.1.0", - "ipfs": "^0.36.3", + "ipfs": "^0.36.4", "ipfs-did-document": "^1.2.3", "ipfs-mini": "^1.1.5", "ipfs-postmsg-proxy": "^3.1.1", diff --git a/src/3box.js b/src/3box.js index 236db775..297ff7ac 100644 --- a/src/3box.js +++ b/src/3box.js @@ -23,6 +23,8 @@ const utils = require('./utils/index') const idUtils = require('./utils/id') const config = require('./config.js') const API = require('./api') +const IPFSRepo = require('ipfs-repo') +const LevelStore = require('datastore-level') const ACCOUNT_TYPES = { ethereum: 'ethereum', @@ -723,6 +725,26 @@ class Box { } } +function initIPFSRepo () { + let repoOpts = {} + let ipfsRootPath + + // if in browser, create unique root storage, and ipfs id on each instance + if (window && window.indexedDB) { + const sessionID = utils.randInt(10000) + ipfsRootPath = 'ipfs/root/' + sessionID + const levelInstance = new LevelStore(ipfsRootPath) + repoOpts = { storageBackends: { root: () => levelInstance } } + } + + const repo = new IPFSRepo('ipfs', repoOpts) + + return { + repo, + rootPath: ipfsRootPath + } +} + async function initIPFS (ipfs, iframeStore, ipfsOptions) { // if (!ipfs && !ipfsProxy) throw new Error('No IPFS object configured and no default available for environment') if (!!ipfs && iframeStore) console.log('Warning: iframeStore true, orbit db cache in iframe, but the given ipfs object is being used, and may not be running in same iframe.') @@ -731,13 +753,24 @@ async function initIPFS (ipfs, iframeStore, ipfsOptions) { } else { // await iframeLoadedPromise // return ipfsProxy + let ipfsRepo + if (!ipfsOptions) { + ipfsRepo = initIPFSRepo() + ipfsOptions = Object.assign(IPFS_OPTIONS, { repo: ipfsRepo.repo }) + } return new Promise((resolve, reject) => { - ipfs = new IPFS(ipfsOptions || IPFS_OPTIONS) + ipfs = new IPFS(ipfsOptions) ipfs.on('error', error => { console.error(error) reject(error) }) - ipfs.on('ready', () => resolve(ipfs)) + ipfs.on('ready', () => { + resolve(ipfs) + if (ipfsRepo && window && window.indexedDB) { + // deletes once db is closed again + window.indexedDB.deleteDatabase(ipfsRepo.rootPath) + } + }) }) } } diff --git a/src/utils/index.js b/src/utils/index.js index 7de30db3..7202acd0 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -131,5 +131,8 @@ module.exports = { const digest = Buffer.from(sha256.digest(str)) return Multihash.encode(digest, 'sha2-256').toString('hex') }, + + randInt: max => Math.floor(Math.random() * max), + sha256 }