From 0c7925ccfd6fe2dc6d895f6e97376c10e1fab122 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 26 Jul 2019 10:07:35 +0100 Subject: [PATCH 1/5] docs: add browser pubsub example License: MIT Signed-off-by: Alan Shaw --- examples/pubsub/index.html | 194 +++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 examples/pubsub/index.html diff --git a/examples/pubsub/index.html b/examples/pubsub/index.html new file mode 100644 index 000000000..b6e8e0876 --- /dev/null +++ b/examples/pubsub/index.html @@ -0,0 +1,194 @@ + + + + Pubsub in the browser + + + + +
+ + + +

Pubsub

+
+
+
API URL
+ + +
+
+
Connect to peer
+ + +
+
+
Subscribe to pubsub topic
+ + +
+
+
Send pubsub message
+ + +
+
+
Console
+
+
+
+ + + + From 356a430e3076890622f5e946c7f0cb7561b85873 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 28 Aug 2019 18:08:13 +0100 Subject: [PATCH 2/5] feat: add build and serve step and wip instructions --- examples/browser-pubsub/.gitignore | 1 + examples/browser-pubsub/README.md | 62 +++++++++ examples/browser-pubsub/index.html | 42 ++++++ examples/browser-pubsub/index.js | 154 +++++++++++++++++++++ examples/browser-pubsub/package.json | 20 +++ examples/pubsub/index.html | 194 --------------------------- package.json | 3 +- 7 files changed, 281 insertions(+), 195 deletions(-) create mode 100644 examples/browser-pubsub/.gitignore create mode 100644 examples/browser-pubsub/README.md create mode 100644 examples/browser-pubsub/index.html create mode 100644 examples/browser-pubsub/index.js create mode 100644 examples/browser-pubsub/package.json delete mode 100644 examples/pubsub/index.html diff --git a/examples/browser-pubsub/.gitignore b/examples/browser-pubsub/.gitignore new file mode 100644 index 000000000..0e804e3a5 --- /dev/null +++ b/examples/browser-pubsub/.gitignore @@ -0,0 +1 @@ +bundle.js diff --git a/examples/browser-pubsub/README.md b/examples/browser-pubsub/README.md new file mode 100644 index 000000000..5a494aa9a --- /dev/null +++ b/examples/browser-pubsub/README.md @@ -0,0 +1,62 @@ +# Pubsub in the browser + +> Use pubsub in the browser! + +This example is a demo web application that allows you to connect to an IPFS node, subscribe to a pubsub topic and send/receive messages. + +## Getting started + +With Node.js and git installed, clone the repo and install the project dependencies: + +```sh +git clone https://github.com/ipfs/js-ipfs-http-client.git +cd js-ipfs-http-client +npm install # Installs ipfs-http-client dependencies +cd examples/browser-pubsub +npm install # Installs browser-pubsub app dependencies +``` + +Start the example application: + +```sh +npm start +``` + +You should see something similar to the following in your terminal and the web app should now be available if you navigate to http://127.0.0.1:8888 using your browser: + +```sh +Starting up http-server, serving ./ +Available on: + http://127.0.0.1:8888 +``` + +## Start two IPFS nodes + +Right now the easiest way to do this is to install and start a `js-ipfs` and `go-ipfs` node. + +### Install and start the JS IPFS node + +```sh +npm install -g ipfs +jsipfs init +# Configure CORS to allow ipfs-http-client to access this IPFS node +jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://127.0.0.1:8888"]' +# Start the IPFS node, enabling pubsub +jsipfs daemon --enable-pubsub-experiment +``` + +### Install and start the Go IPFS node + +Head over to https://dist.ipfs.io/#go-ipfs and hit the "Download go-ipfs" button. Extract the archive and read the instructions to install. + +After installation: + +```sh +ipfs init +# Configure CORS to allow ipfs-http-client to access this IPFS node +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://127.0.0.1:8888"]' +# Start the IPFS node, enabling pubsub +ipfs daemon --enable-pubsub-experiment +``` + +## diff --git a/examples/browser-pubsub/index.html b/examples/browser-pubsub/index.html new file mode 100644 index 000000000..edd765aea --- /dev/null +++ b/examples/browser-pubsub/index.html @@ -0,0 +1,42 @@ + + + + Pubsub in the browser + + + + +
+ + + +

Pubsub

+
+
+
API URL
+ + +
+
+
Connect to peer
+ + +
+
+
Subscribe to pubsub topic
+ + +
+
+
Send pubsub message
+ + +
+
+
Console
+
+
+
+ + + diff --git a/examples/browser-pubsub/index.js b/examples/browser-pubsub/index.js new file mode 100644 index 000000000..8eb207fb3 --- /dev/null +++ b/examples/browser-pubsub/index.js @@ -0,0 +1,154 @@ +'use strict' +const IpfsHttpClient = require('ipfs-http-client') + +async function main () { + const apiUrlInput = document.getElementById('api-url') + const nodeConnectBtn = document.getElementById('node-connect') + + const peerAddrInput = document.getElementById('peer-addr') + const peerConnectBtn = document.getElementById('peer-connect') + + const topicInput = document.getElementById('topic') + const subscribeBtn = document.getElementById('subscribe') + + const messageInput = document.getElementById('message') + const sendBtn = document.getElementById('send') + + const consoleEl = document.getElementById('console') + + function log (message) { + const container = document.createElement('div') + container.innerHTML = message + consoleEl.appendChild(container) + consoleEl.scrollTop = consoleEl.scrollHeight + } + + function clear () { + consoleEl.innerHTML = '' + } + + let topic + let peerId + + async function nodeConnect (url) { + clear() + log(`Connecting to ${url}`) + window.ipfs = IpfsHttpClient(url) + const { id, agentVersion } = await window.ipfs.id() + peerId = id + log(`Success!`) + log(`Version ${agentVersion}`) + log(`Peer ID ${id}`) + } + + const sleep = (ms = 1000) => new Promise(resolve => setTimeout(resolve, ms)) + + async function peerConnect (addr) { + if (!addr) throw new Error('Missing peer multiaddr') + if (!window.ipfs) throw new Error('Connect to a node first') + log(`Connecting to peer ${addr}`) + await window.ipfs.swarm.connect(addr) + log(`Success!`) + log('Listing swarm peers...') + await sleep() + const peers = await window.ipfs.swarm.peers() + peers.forEach(peer => { + const fullAddr = `${peer.addr}/ipfs/${peer.peer.toB58String()}` + log(`${fullAddr}`) + }) + log(`(${peers.length} peers total)`) + } + + async function subscribe (nextTopic) { + if (!nextTopic) throw new Error('Missing topic name') + if (!window.ipfs) throw new Error('Connect to a node first') + + const lastTopic = topic + + if (topic) { + topic = null + log(`Unsubscribing from topic ${lastTopic}`) + await window.ipfs.pubsub.unsubscribe(lastTopic) + } + + log(`Subscribing to ${nextTopic}...`) + + await window.ipfs.pubsub.subscribe(nextTopic, msg => { + const from = msg.from + const seqno = msg.seqno.toString('hex') + if (from === peerId) return log(`Ignoring message ${seqno} from self`) + log(`Message ${seqno} from ${from}:`) + try { + log(JSON.stringify(msg.data.toString(), null, 2)) + } catch (_) { + log(msg.data.toString('hex')) + } + }, { + onError: (err, fatal) => { + if (fatal) { + console.error(err) + log(`${err.message}`) + topic = null + log('Resubscribing in 5s...') + setTimeout(catchLog(() => subscribe(nextTopic)), 5000) + } else { + console.warn(err) + } + } + }) + + topic = nextTopic + log(`Success!`) + } + + async function send (msg) { + if (!msg) throw new Error('Missing message') + if (!topic) throw new Error('Subscribe to a topic first') + if (!window.ipfs) throw new Error('Connect to a node first') + + log(`Sending message to ${topic}...`) + await window.ipfs.pubsub.publish(topic, msg) + log(`Success!`) + } + + function catchLog (fn) { + return async (...args) => { + try { + await fn(...args) + } catch (err) { + console.error(err) + log(`${err.message}`) + } + } + } + + const createOnEnterPress = fn => { + return e => { + if (event.which == 13 || event.keyCode == 13) { + e.preventDefault() + fn() + } + } + } + + const onNodeConnectClick = catchLog(() => nodeConnect(apiUrlInput.value)) + apiUrlInput.addEventListener('keydown', createOnEnterPress(onNodeConnectClick)) + nodeConnectBtn.addEventListener('click', onNodeConnectClick) + + const onPeerConnectClick = catchLog(() => peerConnect(peerAddrInput.value)) + peerAddrInput.addEventListener('keydown', createOnEnterPress(onPeerConnectClick)) + peerConnectBtn.addEventListener('click', onPeerConnectClick) + + const onSubscribeClick = catchLog(() => subscribe(topicInput.value)) + topicInput.addEventListener('keydown', createOnEnterPress(onSubscribeClick)) + subscribeBtn.addEventListener('click', onSubscribeClick) + + const onSendClick = catchLog(async () => { + await send(messageInput.value) + messageInput.value = '' + }) + messageInput.addEventListener('keydown', createOnEnterPress(onSendClick)) + sendBtn.addEventListener('click', onSendClick) +} + +main() diff --git a/examples/browser-pubsub/package.json b/examples/browser-pubsub/package.json new file mode 100644 index 000000000..c4c6e2727 --- /dev/null +++ b/examples/browser-pubsub/package.json @@ -0,0 +1,20 @@ +{ + "name": "browser-pubsub-example", + "version": "0.0.0", + "description": "An example demonstrating pubsub in the browser", + "private": true, + "main": "index.js", + "scripts": { + "start": "npm run build && npm run serve", + "build": "browserify index.js > bundle.js", + "serve": "http-server -a 127.0.0.1 -p 8888", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Alan Shaw", + "license": "MIT", + "dependencies": { + "browserify": "^16.5.0", + "http-server": "^0.11.1", + "ipfs-http-client": "../../" + } +} diff --git a/examples/pubsub/index.html b/examples/pubsub/index.html deleted file mode 100644 index b6e8e0876..000000000 --- a/examples/pubsub/index.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - Pubsub in the browser - - - - -
- - - -

Pubsub

-
-
-
API URL
- - -
-
-
Connect to peer
- - -
-
-
Subscribe to pubsub topic
- - -
-
-
Send pubsub message
- - -
-
-
Console
-
-
-
- - - - diff --git a/package.json b/package.json index e86c4c6be..d07df478c 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "browser": { "glob": false, "fs": false, - "stream": "readable-stream" + "stream": "readable-stream", + "ky-universal": "ky/umd" }, "repository": "github:ipfs/js-ipfs-http-client", "scripts": { From e14c4619208b890fee24fbb815dc5053d7129887 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 29 Aug 2019 10:07:17 +0100 Subject: [PATCH 3/5] docs: complete documentation License: MIT Signed-off-by: Alan Shaw --- examples/browser-pubsub/README.md | 42 ++++++++++++++++++++++++++---- examples/browser-pubsub/index.html | 8 +++--- examples/browser-pubsub/index.js | 9 ++++--- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/examples/browser-pubsub/README.md b/examples/browser-pubsub/README.md index 5a494aa9a..abe6a21f9 100644 --- a/examples/browser-pubsub/README.md +++ b/examples/browser-pubsub/README.md @@ -2,9 +2,29 @@ > Use pubsub in the browser! -This example is a demo web application that allows you to connect to an IPFS node, subscribe to a pubsub topic and send/receive messages. +This example is a demo web application that allows you to connect to an IPFS node, subscribe to a pubsub topic and send/receive messages. We'll start two IPFS nodes and two browsers and use the `ipfs-http-client` to instruct each node to listen to a pubsub topic and send/receive pubsub messages to/from each other. We're aiming for something like this: -## Getting started +``` + +-----------+ +-----------+ + | +-------------------> | + | js-ipfs | pubsub | go-ipfs | + | <-------------------+ | + +-----^-----+ +-----^-----+ + | | + | HTTP API | HTTP API + | | ++-------------------+ +-------------------+ ++-------------------+ +-------------------+ +| | | | +| | | | +| Browser 1 | | Browser 2 | +| | | | +| | | | +| | | | ++-------------------+ +-------------------+ +``` + +## 1. Get started With Node.js and git installed, clone the repo and install the project dependencies: @@ -30,9 +50,11 @@ Available on: http://127.0.0.1:8888 ``` -## Start two IPFS nodes +## 2. Start two IPFS nodes -Right now the easiest way to do this is to install and start a `js-ipfs` and `go-ipfs` node. +To demonstrate pubsub we need two nodes running so pubsub messages can be passed between them. + +Right now the easiest way to do this is to install and start a `js-ipfs` and `go-ipfs` node. There are other ways to do this, see [this document on running multiple nodes](https://github.com/ipfs/js-ipfs/tree/master/examples/running-multiple-nodes) for details. ### Install and start the JS IPFS node @@ -59,4 +81,14 @@ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://127.0.0 ipfs daemon --enable-pubsub-experiment ``` -## +## 3. Open two browsers and connect to each node + +Now, open up **two** browser windows. This could be two tabs in the same browser or two completely different browsers, it doesn't matter. Navigate to http://127.0.0.1:8888 in both. + +In the "API ADDR" field enter `/ip4/127.0.0.1/tcp/5001` in one browser and `/ip4/127.0.0.1/tcp/5002` in the other and hit the "Connect" button. + +This connects each browser to an IPFS node and now from the comfort of our browser we can instruct each node to listen to a pubsub topic and send/receive pubsub messages to each other. + +> N.B. Since our two IPFS nodes are running on the same network they should have already found each other by MDNS. So you probably won't need to use the "CONNECT TO PEER" field. If you find your pubsub messages aren't getting through, check the output from your `jsipfs daemon` command and find the first address listed in "Swarm listening on" - it'll look like `/ip4/127.0.0.1/tcp/4002/ipfs/Qm...`. Paste this address into the "CONNECT TO PEER" field for the browser that is connected to your go-ipfs node and hit connect. + +Finally, use the "SUBSCRIBE TO PUBSUB TOPIC" and "SEND MESSAGE" fields to do some pubsub-ing, you should see messages sent from one browser appear in the log of the other (provided they're both subscribed to the same topic). diff --git a/examples/browser-pubsub/index.html b/examples/browser-pubsub/index.html index edd765aea..d5d84d564 100644 --- a/examples/browser-pubsub/index.html +++ b/examples/browser-pubsub/index.html @@ -13,18 +13,18 @@

Pubsub

-
API URL
- +
API Addr
+
Connect to peer
- +
Subscribe to pubsub topic
- +
diff --git a/examples/browser-pubsub/index.js b/examples/browser-pubsub/index.js index 8eb207fb3..c32029e34 100644 --- a/examples/browser-pubsub/index.js +++ b/examples/browser-pubsub/index.js @@ -1,4 +1,5 @@ 'use strict' + const IpfsHttpClient = require('ipfs-http-client') async function main () { @@ -23,13 +24,15 @@ async function main () { consoleEl.scrollTop = consoleEl.scrollHeight } + let topic + let peerId + function clear () { consoleEl.innerHTML = '' + topic = null + peerId = null } - let topic - let peerId - async function nodeConnect (url) { clear() log(`Connecting to ${url}`) From 1c3eb5dbe77f469d4a998697f702670035604b61 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 29 Aug 2019 10:32:27 +0100 Subject: [PATCH 4/5] fix: tweaks and simplifications License: MIT Signed-off-by: Alan Shaw --- examples/browser-pubsub/index.js | 86 ++++++++++++-------------------- examples/browser-pubsub/util.js | 31 ++++++++++++ 2 files changed, 63 insertions(+), 54 deletions(-) create mode 100644 examples/browser-pubsub/util.js diff --git a/examples/browser-pubsub/index.js b/examples/browser-pubsub/index.js index c32029e34..eae1dab17 100644 --- a/examples/browser-pubsub/index.js +++ b/examples/browser-pubsub/index.js @@ -1,6 +1,7 @@ 'use strict' const IpfsHttpClient = require('ipfs-http-client') +const { sleep, Logger, onEnterPress, catchAndLog } = require('./util') async function main () { const apiUrlInput = document.getElementById('api-url') @@ -15,46 +16,43 @@ async function main () { const messageInput = document.getElementById('message') const sendBtn = document.getElementById('send') - const consoleEl = document.getElementById('console') - - function log (message) { - const container = document.createElement('div') - container.innerHTML = message - consoleEl.appendChild(container) - consoleEl.scrollTop = consoleEl.scrollHeight - } - + let log = Logger(document.getElementById('console')) + let ipfs let topic let peerId - function clear () { - consoleEl.innerHTML = '' + async function reset () { + if (ipfs && topic) { + log(`Unsubscribing from topic ${topic}`) + await ipfs.pubsub.unsubscribe(topic) + } + log = Logger(document.getElementById('console')) + topicInput.value = '' topic = null peerId = null + ipfs = null } async function nodeConnect (url) { - clear() + await reset() log(`Connecting to ${url}`) - window.ipfs = IpfsHttpClient(url) - const { id, agentVersion } = await window.ipfs.id() + ipfs = IpfsHttpClient(url) + const { id, agentVersion } = await ipfs.id() peerId = id log(`Success!`) log(`Version ${agentVersion}`) log(`Peer ID ${id}`) } - const sleep = (ms = 1000) => new Promise(resolve => setTimeout(resolve, ms)) - async function peerConnect (addr) { if (!addr) throw new Error('Missing peer multiaddr') - if (!window.ipfs) throw new Error('Connect to a node first') + if (!ipfs) throw new Error('Connect to a node first') log(`Connecting to peer ${addr}`) - await window.ipfs.swarm.connect(addr) + await ipfs.swarm.connect(addr) log(`Success!`) log('Listing swarm peers...') await sleep() - const peers = await window.ipfs.swarm.peers() + const peers = await ipfs.swarm.peers() peers.forEach(peer => { const fullAddr = `${peer.addr}/ipfs/${peer.peer.toB58String()}` log(`${fullAddr}`) @@ -64,19 +62,19 @@ async function main () { async function subscribe (nextTopic) { if (!nextTopic) throw new Error('Missing topic name') - if (!window.ipfs) throw new Error('Connect to a node first') + if (!ipfs) throw new Error('Connect to a node first') const lastTopic = topic if (topic) { topic = null log(`Unsubscribing from topic ${lastTopic}`) - await window.ipfs.pubsub.unsubscribe(lastTopic) + await ipfs.pubsub.unsubscribe(lastTopic) } log(`Subscribing to ${nextTopic}...`) - await window.ipfs.pubsub.subscribe(nextTopic, msg => { + await ipfs.pubsub.subscribe(nextTopic, msg => { const from = msg.from const seqno = msg.seqno.toString('hex') if (from === peerId) return log(`Ignoring message ${seqno} from self`) @@ -93,7 +91,7 @@ async function main () { log(`${err.message}`) topic = null log('Resubscribing in 5s...') - setTimeout(catchLog(() => subscribe(nextTopic)), 5000) + setTimeout(catchAndLog(() => subscribe(nextTopic), log), 5000) } else { console.warn(err) } @@ -107,50 +105,30 @@ async function main () { async function send (msg) { if (!msg) throw new Error('Missing message') if (!topic) throw new Error('Subscribe to a topic first') - if (!window.ipfs) throw new Error('Connect to a node first') + if (!ipfs) throw new Error('Connect to a node first') log(`Sending message to ${topic}...`) - await window.ipfs.pubsub.publish(topic, msg) + await ipfs.pubsub.publish(topic, msg) log(`Success!`) } - function catchLog (fn) { - return async (...args) => { - try { - await fn(...args) - } catch (err) { - console.error(err) - log(`${err.message}`) - } - } - } - - const createOnEnterPress = fn => { - return e => { - if (event.which == 13 || event.keyCode == 13) { - e.preventDefault() - fn() - } - } - } - - const onNodeConnectClick = catchLog(() => nodeConnect(apiUrlInput.value)) - apiUrlInput.addEventListener('keydown', createOnEnterPress(onNodeConnectClick)) + const onNodeConnectClick = catchAndLog(() => nodeConnect(apiUrlInput.value), log) + apiUrlInput.addEventListener('keydown', onEnterPress(onNodeConnectClick)) nodeConnectBtn.addEventListener('click', onNodeConnectClick) - const onPeerConnectClick = catchLog(() => peerConnect(peerAddrInput.value)) - peerAddrInput.addEventListener('keydown', createOnEnterPress(onPeerConnectClick)) + const onPeerConnectClick = catchAndLog(() => peerConnect(peerAddrInput.value), log) + peerAddrInput.addEventListener('keydown', onEnterPress(onPeerConnectClick)) peerConnectBtn.addEventListener('click', onPeerConnectClick) - const onSubscribeClick = catchLog(() => subscribe(topicInput.value)) - topicInput.addEventListener('keydown', createOnEnterPress(onSubscribeClick)) + const onSubscribeClick = catchAndLog(() => subscribe(topicInput.value), log) + topicInput.addEventListener('keydown', onEnterPress(onSubscribeClick)) subscribeBtn.addEventListener('click', onSubscribeClick) - const onSendClick = catchLog(async () => { + const onSendClick = catchAndLog(async () => { await send(messageInput.value) messageInput.value = '' - }) - messageInput.addEventListener('keydown', createOnEnterPress(onSendClick)) + }, log) + messageInput.addEventListener('keydown', onEnterPress(onSendClick)) sendBtn.addEventListener('click', onSendClick) } diff --git a/examples/browser-pubsub/util.js b/examples/browser-pubsub/util.js new file mode 100644 index 000000000..e6aada61f --- /dev/null +++ b/examples/browser-pubsub/util.js @@ -0,0 +1,31 @@ +exports.sleep = (ms = 1000) => new Promise(resolve => setTimeout(resolve, ms)) + +exports.Logger = outEl => { + outEl.innerHTML = '' + return message => { + const container = document.createElement('div') + container.innerHTML = message + outEl.appendChild(container) + outEl.scrollTop = outEl.scrollHeight + } +} + +exports.onEnterPress = fn => { + return e => { + if (event.which == 13 || event.keyCode == 13) { + e.preventDefault() + fn() + } + } +} + +exports.catchAndLog = (fn, log) => { + return async (...args) => { + try { + await fn(...args) + } catch (err) { + console.error(err) + log(`${err.message}`) + } + } +} From e257b9b01f36f56ab7ffc1b6c3c3e42de76e4660 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 29 Aug 2019 10:36:54 +0100 Subject: [PATCH 5/5] docs: remove pubsub caveat License: MIT Signed-off-by: Alan Shaw --- README.md | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c93113485..def4b05e5 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ const ipfs = ipfsClient({ - [`ipfs.lsPullStream(ipfsPath)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#lspullstream) - [`ipfs.lsReadableStream(ipfsPath)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#lsreadablestream) - [MFS (mutable file system) specific](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#mutable-file-system) - + _Explore the Mutable File System through interactive coding challenges in our [ProtoSchool tutorial](https://proto.school/#/mutable-file-system/)._ - [`ipfs.files.cp([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescp) - [`ipfs.files.flush([path], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesflush) @@ -233,7 +233,7 @@ const ipfs = ipfsClient({ #### Graph - [dag](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md) - + _Explore the DAG API through interactive coding challenges in our [ProtoSchool tutorial](https://proto.school/#/basics)._ - [`ipfs.dag.get(cid, [path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md#dagget) - [`ipfs.dag.put(dagNode, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md#dagput) @@ -339,28 +339,6 @@ const ipfs = ipfsClient({ - [`ipfs.key.rename(oldName, newName, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrename) - [`ipfs.key.rm(name, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrm) -#### Pubsub Caveat - -**Currently, the [PubSub API only works in Node.js environment](https://github.com/ipfs/js-ipfs-http-client/issues/518)** - -We currently don't support pubsub when run in the browser, and we test it with separate set of tests to make sure if it's being used in the browser, pubsub errors. - -More info: https://github.com/ipfs/js-ipfs-http-client/issues/518 - -This means: -- You can use pubsub from js-ipfs-http-client in Node.js -- You can use pubsub from js-ipfs-http-client in Electron - (when js-ipfs-http-client is ran in the main process of Electron) -- You can't use pubsub from js-ipfs-http-client in the browser -- You can't use pubsub from js-ipfs-http-client in Electron's - renderer process -- You can use pubsub from js-ipfs in the browsers -- You can use pubsub from js-ipfs in Node.js -- You can use pubsub from js-ipfs in Electron - (in both the main process and the renderer process) -- See https://github.com/ipfs/js-ipfs for details on - pubsub in js-ipfs - #### Instance utils - `ipfs.getEndpointConfig()`