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

Init ipfs-api or js-ipfs #320

Merged
merged 20 commits into from
Dec 12, 2017
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
34 changes: 34 additions & 0 deletions add-on/src/lib/ipfs-client/embedded.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict'

const Ipfs = require('ipfs')

let node = null

exports.init = function init () {
console.log('[ipfs-companion] Embedded ipfs init')

node = new Ipfs({
config: {
Addresses: {
Swarm: []
}
}
})

if (node.isOnline()) {
return Promise.resolve(node)
}

return new Promise((resolve, reject) => {
// TODO: replace error listener after a 'ready' event.
node.once('error', (err) => reject(err))
node.once('ready', () => resolve(node))
})
}

exports.destroy = async function () {
if (!node) return

await node.stop()
node = null
}
12 changes: 12 additions & 0 deletions add-on/src/lib/ipfs-client/external.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'
/* eslint-env browser */

const IpfsApi = require('ipfs-api')

exports.init = async function (opts) {
console.log('[ipfs-companion] External ipfs init')

const url = new URL(opts.ipfsApiUrl)
const api = IpfsApi({host: url.hostname, port: url.port, procotol: url.protocol})
return api
}
20 changes: 20 additions & 0 deletions add-on/src/lib/ipfs-client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

const embedded = require('./embedded')
Copy link
Member

Choose a reason for hiding this comment

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

Some feedback from the last IPFS all hands was that embedded might confuse devs to think that know there is a window.ipfs in every page. Is that one of the goals too? It would be a good feature to have (optionally)

Copy link
Member Author

@olizilla olizilla Dec 12, 2017

Choose a reason for hiding this comment

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

I think that would be simple to add. Is the idea that users would write scripts against window.ipfs but not bundle it with their script? It sounds a little bit like those browser extensions that add jquery to every page, so you can noodle around in the dev console.

Do people have a use-case in mind? T feel like we should be directing devs to the js-ipfs examples, to show them how to bundle it.

Copy link
Member

Choose a reason for hiding this comment

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

The difference between adding jquery and ipfs is that on one you would be just packing more code, the second you are opening more ports and doing more crypto which are both expensive operations.

The Metamask team has been injecting Web3 to every page to let devs use Ethereum directly if WebPages are there.

I feel this should be one of the options for the extension and until we have concrete use cases, just refer to an example on how to use it to seed it to developers.

Copy link
Member

Choose a reason for hiding this comment

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

Lots of benefits for embedding an already running IPFS node in webpages, too many to list here, but for starter, it makes startup times a lot better as nothing has to initialized, just start using it directly (node in background is already running so!). Performance of loading pages and loading content will be faster as well. Things can be shared via MFS between applications, as long as they agree on a standard structure. ID can follow between applications as well. Just a few reasons.

Copy link
Member Author

Choose a reason for hiding this comment

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

Very cool! I like the idea of making ipfs available to webapps and seeing what people do with it.

Copy link
Member

Choose a reason for hiding this comment

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

See #330, I created it to track window.ipfs effort :)

Copy link
Member Author

Choose a reason for hiding this comment

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

const external = require('./external')

let client = null

exports.initIpfsClient = async function (opts) {
if (client && client.destroy) {
await client.destroy()
}

if (opts.ipfsNodeType === 'embedded') {
client = await embedded.init(opts)
} else {
client = await external.init(opts)
}

return client
}
16 changes: 6 additions & 10 deletions add-on/src/lib/ipfs-companion.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const browser = require('webextension-polyfill')
const { optionDefaults, storeMissingOptions } = require('./options')
const { initState } = require('./state')
const IsIpfs = require('is-ipfs')
const IpfsApi = require('ipfs-api')
const { createIpfsPathValidator, safeIpfsPath, urlAtPublicGw } = require('./ipfs-path')
const createDnsLink = require('./dns-link')
const { createRequestModifier } = require('./ipfs-request')
const { initIpfsClient } = require('./ipfs-client')

// INIT
// ===================================================================
Expand All @@ -23,7 +23,8 @@ module.exports = async function init () {
try {
const options = await browser.storage.local.get(optionDefaults)
state = window.state = initState(options)
ipfs = window.ipfs = initIpfsApi(options.ipfsApiUrl)
ipfs = window.ipfs = await initIpfsClient(options)
console.log('[ipfs-companion] ipfs init complete')
dnsLink = createDnsLink(getState)
ipfsPathValidator = createIpfsPathValidator(getState, dnsLink)
modifyRequest = createRequestModifier(getState, dnsLink, ipfsPathValidator)
Expand All @@ -50,11 +51,6 @@ function getState () {
return state
}

function initIpfsApi (ipfsApiUrl) {
const url = new URL(ipfsApiUrl)
return IpfsApi({host: url.hostname, port: url.port, procotol: url.protocol})
}

function registerListeners () {
browser.webRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, {urls: ['<all_urls>']}, ['blocking', 'requestHeaders'])
browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, {urls: ['<all_urls>']}, ['blocking'])
Expand Down Expand Up @@ -249,7 +245,7 @@ async function addFromURL (info) {
const response = await fetch(srcUrl, fetchOptions)
const reader = new FileReader()
reader.onloadend = () => {
const buffer = ipfs.Buffer.from(reader.result)
const buffer = Buffer.from(reader.result)
ipfs.add(buffer, uploadResultHandler)
}
reader.readAsArrayBuffer(await response.blob())
Expand Down Expand Up @@ -590,7 +586,7 @@ function updateAutomaticModeRedirectState (oldPeerCount, newPeerCount) {
}
}

function onStorageChange (changes, area) {
async function onStorageChange (changes, area) {
for (let key in changes) {
let change = changes[key]
if (change.oldValue !== change.newValue) {
Expand All @@ -599,7 +595,7 @@ function onStorageChange (changes, area) {
if (key === 'ipfsApiUrl') {
state.apiURL = new URL(change.newValue)
state.apiURLString = state.apiURL.toString()
ipfs = window.ipfs = initIpfsApi(state.apiURLString)
ipfs = window.ipfs = await initIpfsClient(state)
apiStatusUpdate()
} else if (key === 'ipfsApiPollMs') {
setApiStatusUpdateInterval(change.newValue)
Expand Down
1 change: 1 addition & 0 deletions add-on/src/lib/options.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const optionDefaults = Object.freeze({
ipfsNodeType: 'external',
publicGatewayUrl: 'https://ipfs.io',
useCustomGateway: true,
automaticMode: true,
Expand Down
1 change: 1 addition & 0 deletions add-on/src/lib/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ function initState (options) {
const state = {}
// we store the most used values in optimized form
// to minimize performance impact on overall browsing experience
state.ipfsNodeType = options.ipfsNodeType
state.pubGwURL = new URL(options.publicGatewayUrl)
state.pubGwURLString = state.pubGwURL.toString()
state.redirect = options.useCustomGateway
Expand Down
2 changes: 1 addition & 1 deletion add-on/src/popup/quick-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function quickUploadStore (state, emitter) {
let reader = new FileReader()
reader.onloadend = () => {
const buffer = Buffer.from(reader.result)
bg.ipfs.add(buffer, (err, result) => {
bg.ipfs.files.add(buffer, (err, result) => {
if (err || !result) {
// keep upload tab and display error message in it
state.message = `Unable to upload to IPFS API: ${err}`
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
"build:copy": "run-s build:copy:*",
"build:copy:src": "shx mkdir -p add-on/dist && shx cp -R add-on/src/* add-on/dist",
"build:copy:wx-polyfill-lib": "shx cp node_modules/webextension-polyfill/dist/browser-polyfill.min.js add-on/dist/contentScripts/browser-polyfill.min.js",
"build:js": "browserify -t [ browserify-package-json --global ] add-on/src/background/background.js add-on/src/options/options.js add-on/src/popup/browser-action/index.js add-on/src/popup/quick-upload.js -p [ factor-bundle -o add-on/dist/background/background.js -o add-on/dist/options/options.js -o add-on/dist/popup/browser-action/browser-action.js -o add-on/dist/popup/quick-upload.js ] -o add-on/dist/ipfs-companion-common.js",
"build:js": "browserify -p prundupify -t [ browserify-package-json --global ] add-on/src/background/background.js add-on/src/options/options.js add-on/src/popup/browser-action/index.js add-on/src/popup/quick-upload.js -p [ factor-bundle -o add-on/dist/background/background.js -o add-on/dist/options/options.js -o add-on/dist/popup/browser-action/browser-action.js -o add-on/dist/popup/quick-upload.js ] -o add-on/dist/ipfs-companion-common.js",
"build:minimize-dist": "shx rm -rf add-on/dist/lib",
"build:bundle-extension": "web-ext build -s add-on/ -i src/ -a build/",
"watch": "run-p watch:*",
"watch:js": "watchify add-on/src/background/background.js add-on/src/options/options.js add-on/src/popup/browser-action/index.js add-on/src/popup/quick-upload.js -p [ factor-bundle -o add-on/dist/background/background.js -o add-on/dist/options/options.js -o add-on/dist/popup/browser-action/browser-action.js -o add-on/dist/popup/quick-upload.js ] -o add-on/dist/ipfs-companion-common.js -v",
"watch:js": "watchify -p prundupify -t [ browserify-package-json --global ] add-on/src/background/background.js add-on/src/options/options.js add-on/src/popup/browser-action/index.js add-on/src/popup/quick-upload.js -p [ factor-bundle -o add-on/dist/background/background.js -o add-on/dist/options/options.js -o add-on/dist/popup/browser-action/browser-action.js -o add-on/dist/popup/quick-upload.js ] -o add-on/dist/ipfs-companion-common.js -v",
"test": "run-s test:*",
"test:functional": "mocha test/functional/**/*.test.js",
"lint": "run-s lint:*",
Expand Down Expand Up @@ -68,9 +68,11 @@
},
"dependencies": {
"choo": "6.6.0",
"ipfs": "^0.26.0",
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 try to keep all versions locked, so that we don't have big divergence between npm and yarn, at least on the direct dependency level.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, for IPFS land, always use ~ at least. A minor version might have a breaking change (0.27 will)

"ipfs-api": "17.1.3",
"is-ipfs": "0.3.2",
"lru_map": "0.3.3",
"prundupify": "^1.0.0",
"webextension-polyfill": "0.1.2"
}
}