npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@jimpick/is-peer-pad-fast-yet-pinner

v0.8.0-2

Published

Peer-Star App support for real-time collaborative DApps built on top of IPFS

Downloads

38

Readme

peer-star-app

Peer-Star App support for real-time collaborative DApps built on top of IPFS

Build Status Greenkeeper badge made by Protocol Labs

Documentation

Install

$ npm install peer-star-app

Import

const PeerStar = require('peer-star-app')

API

Create app

const app = PeerStar('app name', options)

app.on('error', (err) => {
  console.error('error in app:', err)
})

Options (are not required):

  • ipfs: object with:
    • repo: IPFS repo path or repo object
    • swarm: ipfs swarm addresses (array of strings)
    • bootstrap: IPFS Bootstrap nodes (array of multiaddresses)
    • relay: an (optional) object containing the following attributes:
      • apiAddr: the multiaddress for the API server of the relay
      • relayWSAddr: the multiaddress for the relay websocket server address
  • samplingIntervalMS: (defaults to 1000): membership gossip frequency heuristic sampling interval
  • targetGlobalMembershipGossipFrequencyMS: (defaults to 1000): target global membership gossip frequency, in ms.
  • urgencyFrequencyMultiplier: (defaults to 10): urgency multiplier when someone is wrong about membership
  • transport: optional object containing:
    • maxThrottleDelayMS: the maximum delay betweeen discovering a new peer and querying it to see whether they're interested in the app.

Start app

await app.start()

js-IPFS node

A peer-star app comes with a js-ipfs node. You can access it through app.ipfs. Example:

console.log(await app.ipfs.id())

Guess peer count

app.peerCountGuess() // returns integer Number >= 0

Keys

Keys can be used to collaborate. If provided, they authenticate changes to the collaboration and encrypts them for transmission and storage. You can either create new keys or parse them from a string.

await Keys.generate()

const Keys = require('peer-star-app').keys

const keys = await Keys.generate()

Keys.uriEncode

Encode keys into a URI-acceptable string:

const Keys = require('peer-star-app').keys
const keys = await Keys.generate()

const string = Keys.uriEncode(keys)

Keys.uriEncodeReadOnly

Encode the read-only key into a URI-acceptable string:

const Keys = require('peer-star-app').keys
const keys = await Keys.generate()

const string = Keys.uriEncodeReadOnly(keys)

await Keys.uriDecode

Decode keys from a string:

const Keys = require('peer-star-app').keys
const keys = await Keys.generate()

const string = Keys.uriEncode(keys)

const decodedKeys = await Keys.uriDecode(string)

Read-only keys

You can distribute a read-only key by using PeerStar.keys.uriEncodeReadOnly(keys):

const Keys = require('peer-star-app').keys
const keys = await Keys.generate()

const string = Keys.uriEncodeReadOnly(keys)

Generate symmetrical key

const Keys = require('peer-star-app').keys

// options are optional. defaults to:
const options = {
  keyLength: 32,
  ivLength: 16
}
const keys = await Keys.generateSymmetrical(options)

key.raw // contains raw key (buffer)
key.key // contains AES key

Returns (asynchronously) a key of type AES, as defined in libp2p-crypto.

Create collaboration

const collaboration = await app.collaborate(collaborationName, type, options)

// stop collaboration
await collaboration.stop()

Arguments:

  • collaborationName: string: should uniquely identify this collaboration in the whole world
  • type: a string, identifying which type of CRDT should be used. Use this reference table in the delta-crdts package.
  • options: object, not required. Can contain the keys:
    • keys: keys, generated or parsed from URL. See keys section
    • maxDeltaRetention: number: maximum number of retained deltas. Defaults to 1000.
    • deltaTrimTimeoutMS: number: after a delta was added to the store, the time it waits before trying to trim the deltas.
    • debounceResetConnectionsMS: (defaults to 1000): debounce membership changes before resetting connections.

Create your own collaboration type

You can create your own collaboration type by registering it:

// useless type here:
const Zero = (id) => ({
  initial: () => 0,
  join: (s1, s2) => 0,
  value: (state) => state
})

PeerStar.collaborationTypes.define('zero', Zero)

Peer count estimate

Returns estimate of peers in app.

app.peerCountEstimate()

Sub-collaborations

You can create sub-collaborations to a given "root" collaboration, with it's separate CRDT type, but that is causally consistent with the root CRDT. Here's how:

const subCollaboration = await collaboration.sub('name', 'type')

A sub-collaboration has the same API as a collaboration.

Collaboration gossip

You can have collaboration-level private gossip like this:

const gossip = await collaboration.gossip('gossip name')

gossip.on('message', (message, fromPeer) => {
  console.log('got message from peer ${fromPeer}: ${JSON.stringify(message)}')
})

const message = ['any', 'JSON', 'object']

gossip.broadcast(message)

Collaboration stats

You can observe some collaboration traffic and topology statistics by doing:

collaboration.stats.on('peer updated', (peerId, stats) => {
  console.log('peer %s updated its stats to:', peerId, stats)
})

The stats object looks something like this:

{
  connections: {
    inbound: new Set(<peerId>),
    outbound: new Set(<peerId>)
  },
  traffic: {
    total: {
      in: <number>,
      out: <number>
    },
    perPeer: new Map(
      <peerId => {
        in: <number>,
        out: <number>
      }>)
  },
  messages: {
    total: {
      in: <number>,
      out: <number>
    },
    perPeer: new Map(
      <peerId => {
        in: <number>,
        out: <number>
      }>)
  }
}

App Events

app.emit('error', err)

app.emit('peer connected', (peerInfo) => {})

When a peer connects.

app.emit('outbound peer connected', (peerInfo) => {})

When a push connection is created.

app.emit('inbound peer connected', (peerInfo) => {})

When a pull connection is created.

app.emit('peer disconnected', (peerInfo) => {})

When a peer disconnects.

app.emit('outbound peer disconnected', (peerInfo) => {})

When a push connection ends.

app.emit('inbound peer disconnected', (peerInfo) => {})

When a pull connection ends.

Collaboration

collaboration.peers()

Returns the peers of the collaboration, a Set of peer ids (string).

Array.from(collaboration.peers()).forEach((peer) => {
  console.log('member peer: %s', peer)
})

collaboration.outboundConnectionCount()

Returns the number of peers this peer is pushing data to.

collaboration.inboundConnectionCount()

Returns the number of peers this peer is pulling data from.

Events:

"membership changed" (peers: Set<peer id>)

collaboration.on('membership changed', (peers) => {
  Array.from(peers).forEach((peer) => {
    console.log('member peer: %s', peer)
  })
})

"state changed"

Emitted every time the state changes. Has one argument, a boolean, saying true if and only if the change came from this peer. This is emitted immediately after a change is applied on the CRDT state.

collaboration.on('state changed', (fromSelf) => {
  console.log('state changed. New collaboration value is: %j', collaboration.shared.value())
})

NOTE: When receiving remote updates, this event may fire many times per second. You may want to use a debounce or a throttle mechanism when handling this event. If you do that, beware that the state in your UI may be out of sync with the state of the CRDT.

collaboration.shared

The shared data in this collaboration.

shared.value()

Returns the CRDT view value.

shared mutators

Each shared document has document-specific mutators. See the delta-crdts documentation for these.

Example:

collaboration.shared.push('some element')

Stop collaboration

await collaboration.stop()

Stop app

await app.stop()

IPFS Circuit Relay support

Peer-star-app supports using a circuit relay peer. For that you need to set up a go-ipfs node with circuit relay enabled. On your peer-star-app options, you can then pass in options.ipfs.relay with an object with the following attributes:

  • relayWSAddr: the multiaddress for the websocket server of the relay server
  • apiAddr: the multiaddress for the relay server API address (which we need for polling the known peers)

Pinner

You can pin collaborations for peer-* apps without delegating keys. To install a pinner you can:

$ npm install -g peer-star-app
$ pinner "app name" ["swarm address"]

Run example app

Clone this repo.

$ cd peer-star-app
$ cd examples/react-app
$ npm install

In a different window, on the same dir, start the rendezvous server:

$ npm run start:rv

In a different window, on the same dir, run the app server:

$ npm start

Open http://localhost:3000 and test the app.

Tests

Clone this repo and run:

$ npm install
$ npm test

Debug

You can activate the debugging logs by manipulating the DEBUG environment variable. Example:

$ DEBUG=peer-star:* npm test

For file-specific DEBUG values, see the source code and look for usages of the debug package.

Contribute

Peer-star app and the IPFS implementation in JavaScript is a work in progress. As such, there's a few things you can do right now to help out:

  • Check out existing issues. This would be especially useful for modules in active development. Some knowledge of IPFS may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically.
  • Perform code reviews. More eyes will help (a) speed the project along, (b) ensure quality, and (c) reduce possible future bugs.
  • Add tests. There can never be enough tests.

Want to hack on peer-star-app?

License

MIT