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

Init ipfs-api or js-ipfs #320

merged 20 commits into from
Dec 12, 2017

Conversation

olizilla
Copy link
Member

@olizilla olizilla commented Nov 28, 2017

Provide a mechanism for swapping between embedded and external ipfs nodes.

Adds ipfsNodeType as an option which is expected to be either embedded or external for use in the proposed UI in #319

To allow js-ipfs and ipfs-api to be used interchangeably, I've tweaked add-on code to use global Buffer impl povided by browserify, and use ipfs.files.add instead of ipfs.add. Intialisation is pulled into there own modules so we've got the flexibility to tweak the returned objects in the future if we find we need to bridge temporary api divergence, or customise anything.

Fixes a bundling issue by adding prundupify as a browserify plugin... due to browserify/factor-bundle#51 (factor-bundle and regular browserify de-duping don't play well together, which became an issue when bundling js-ipfs)

This is bite-size chunk of a bigger change, so I figured, best to get your thoughts on it early. I'm looking at pulling the external api polling from ipfs-companion.js to the external.js wrapper, so it'll become more similar to the embeded.js wrapper, as both will have some clean up to do in the destroy function.

@olizilla olizilla mentioned this pull request Nov 28, 2017
Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

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

Very exciting! :-)

FYSA API polling logic was ported from legacy addon. It just gets and caches current peer count under state.peerCount. There was no better way to to infer Node state at a time than to write simple heuristic around this single metric (fetch fail → offline, 0 → no peers, > 0 → online etc).

As long as you keep this stuff working in some form:

function updatePeerCountDependentStates (oldPeerCount, newPeerCount) {
updateAutomaticModeRedirectState(oldPeerCount, newPeerCount)
updateBrowserActionBadge()
updateContextMenus()
}

It should be safe to do even a heavy refactor.

package.json Outdated
@@ -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)

@olizilla
Copy link
Member Author

olizilla commented Nov 29, 2017

Toggling ipfs node type works in Brave!

js-ipfs-companion

Still need to re-work the offlne detection, but is 🚀

@daviddias
Copy link
Member

🎆🎇 THAT IS SO RAD!!!!! 🎆🎇
👏🏽👏🏽👏🏽👏🏽

Is the ipfs-companion also capturing ipfs://?

@olizilla
Copy link
Member Author

@diasdavid
soon

@olizilla
Copy link
Member Author

@diasdavid was there a trick to getting the chrome.protocol apis to be available in ipfs-inactive/browser-laptop#1 ? I've tried adding it as a requested permission, but I'm now seeing chrome.protocol as undefined, and trying to track down why.

@daviddias
Copy link
Member

@olizilla it might have been to how the extension was being loaded internally. Could you check with the Brave team?

@daviddias daviddias mentioned this pull request Nov 30, 2017
11 tasks
@olizilla
Copy link
Member Author

@alanshaw solved it!

Needed manifestLocation set to component. I think https://github.com/brave/muon/blob/1fd29625480ea3a7b66bd71da11f7bcc49daf420/brave/common/extensions/api/_api_features.json#L35-L42 restricts the protocol api to this.

For future explorers, you have to load the plugin programatically in brave and pass in an additional arg to get access to privileged apis like chrome.protocol

In brave/browser-laptop you link the add-on into your app/extensions dir add the following to app/extensions.js

  // Enable IPFS
  extensionInfo.setState('ipfs', extensionStates.REGISTERED)
  loadExtension('ipfs', getExtensionsPath('ipfs'), undefined, 'component')

it's the component arg that gives it super powers.

@olizilla
Copy link
Member Author

olizilla commented Dec 1, 2017

TODOs plucked from #310 (comment)

  • it should have analogous, well-documented checkbox in the Preferences
  • short description of Embedded option in a tool-tip when user hovers cursor on it.
  • explicitly list "API" address (under "HTTP GATEWAY").

Add a quick fix to handle the stream/buffer return type discrepancy between js-ipfs-api and js-ipfs.
@olizilla olizilla changed the title Init ipfs-api or js-ipfs [WIP] Init ipfs-api or js-ipfs Dec 1, 2017
@hacdias hacdias mentioned this pull request Dec 1, 2017
20 tasks
Currently a peerCount of -1 means we couldn't connect to the external ipfs proc.
This updates the automatic gateway switching logic to use that signalling value
to decide whether to switch to the public gateway. Zero peers means we're
initialising, rather than we'er offline.

This improves the ux when switching between embedded and external nodes.

A more extensive change can be done later, wrapping the ipfs-api client with a
cache, and emitting events for when ipfs state changes.
@olizilla
Copy link
Member Author

Ok, i've made a smaller change around

refactor offline check

Currently a peerCount of -1 means we couldn't connect to the external ipfs proc.
This updates the automatic gateway switching logic to use that signalling value
to decide whether to switch to the public gateway. Zero peers means we're
initialising, rather than we're offline.

This improves the ux when switching between embedded and external nodes.

A more extensive change can be done later, wrapping the ipfs-api client with a
cache, and emitting events for when ipfs state changes.

I'm planning on adding a feature flag of some sort, so we can merge this PR without exposing the js-ipfs option to existing users just yet. I'm focused on getting this PR mergable, before tackling any more changes.

@lidel
Copy link
Member

lidel commented Dec 11, 2017

@olizilla thank you! The "0 == initializing rather than offline" change sounds good.

As soon we have the flag I'll do my best to find time to smoke-test and merge it. 👌

Allows us to merge and release new versions while we iterate on embedded ipfs.
const external = require('./external')
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.

@olizilla
Copy link
Member Author

olizilla commented Dec 12, 2017

I've added a minimal feature flag for the embedded ipfs work. Marking ipfs: false in the browser section of the package.json, causes browserify to stub out require('ipfs'), returning an empty object instead of js-ipfs. I've added an isJsIpfsEnabled test that checks for that, and used it to hide the fieldset in the options page, and the toggle switch in the browser action menu. It will also cause js-ipfs to be excluded from the bundle, which is nice.

Ideally this would be controlled by an env var like JS-IPFS-ENABLED=true. I'll make that work in a future PR, if it's needed. To make that work we'd need to extract the browserify build process to a js file and use the browserify api, so we can then parameterise the excludes option based on env...

@alanshaw
Copy link
Member

👓

Copy link
Member

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

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

Can't wait for this to land!

"panel_quickUpload": {
"message": "Quick Upload",
"message": "Share files via IPFS",
Copy link
Member

Choose a reason for hiding this comment

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

@lidel what's the workflow for language changes like this, should we change back to English in the other language files to denote that it needs to be re-translated?

Copy link
Member

@lidel lidel Dec 12, 2017

Choose a reason for hiding this comment

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

@alanshaw Yes, this is what should be done, but I think this step can be skipped now that we use Crowdin.

Crowdin will change them back to english after I upload new version of source locale (en), at least that is what happened when I've added new keys (other locales automatically got english stubs).

(I manually sync github<->crowdin before releases)

@olizilla olizilla changed the title [WIP] Init ipfs-api or js-ipfs Init ipfs-api or js-ipfs Dec 12, 2017
@alanshaw
Copy link
Member

@lidel I think this PR is ready to merge if you'd like to take a final look? If we can get this in I'll rebase #323 and it'll also be ready for review & merge.

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

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

LGTM!

Upload screen looks neat!

2017-12-13-000355_842x462_scrot

@lidel lidel merged commit 85106e9 into ipfs:master Dec 12, 2017
@lidel
Copy link
Member

lidel commented Dec 12, 2017

Firefox users can try v2.1.1beta5, which includes these changes. 👍

@daviddias
Copy link
Member

Woooooot! :D

@daviddias
Copy link
Member

How can I switch to a js-ipfs node?

image

I don't see an option on preferences.

@lidel
Copy link
Member

lidel commented Dec 13, 2017

@diasdavid Oops, should've stated it more clearly: embedded js-ipfs it is Brave-only for now 🙂 (disabled in default build). Firefox beta is mostly for testing any regressions.
To enable it, you need to mark ipfs: true in the browser section of the package.json and rebuild via npm run yarn-build, then load it into Brave.
(Thanks to this build flag Firefox/Chrome versions do not need to ship with unused codebase of js-ipfs)

@alanshaw
Copy link
Member

@diasdavid @lidel you have to remove "ipfs": false from the package.json, setting it to true won't work! We'll add a note to the README.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants