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

gun-edge

v0.8.8

Published

Gun chain extensions for a higher level DSL and API

Downloads

14

Readme

Gun edge

Extra DSL extensions for Gun.js

Many of the snippets were extracted from Gun Snippets 0.3.x and upgraded to work with Gun +0.6

Some extra chain methods have been added, such as mapReduce and iterator.

Most async methods now come with a ES6 Promises or async/await (ES7) variant. The Promise methods are prefixed with $.

Maturity

As of version 0.8.x, not all of the chain methods have been fully tested yet. Please help test them out and/or add more tests. Thanks.

Install

npm i -S gun-edge

Use

Assuming Babel or similar transpiler setup (2017)

To add all chain methods:

import Gun from 'gun/gun'
import chain from 'gun-edge'
chain(Gun)

To control which chain methods to add:

import {
  add
} from 'gun-edge'
add(Gun, 'date', 'fields')

Import individual chain modules

import {
  inspect,
  addInspect
} from 'gun-edge/edge/inspect'
addInspect(Gun.chain)

Require (Node.js)

Using require

const Gun = require('gun/gun')
require('gun-edge')(Gun)

API extensions

Chain methods available:

Iteration

  • .each() - see each
  • .timed(opts) - interval based recursive iteration on node (see timed-iterator.test.js)
  • .mapReduce(options, cb, putCb, opt) - mapReduce on a bucket (see below)
  • .recurse(cb, filter) - recursively navigate bucket graph/tree structure

Operations

  • .count(numFun) - create a CRDT counter, see counter
  • .copy(val) - make a copy/clone of a value
  • .date(dateValue) - date field, see date
  • .local(data, cb, opt) - store locally only, no peer sync
  • .no(cb) - see no
  • .value(cb, opt) - get the node value (no meta)
  • .valueAt(path, cb, opt) : get value at the path (no meta)
  • .valAt(path, cb, opt) : get value at the path
  • .setAt(path, cb, opt) : set value at the path
  • .putAt(path, cb, opt) : put value at the path
  • .localFields() - get list of local field names (keys) in the bucket
  • .fields(cb) - return fields to cb
  • .soul() - return the soul (id) of the node
  • .print(label) - print value to console (no meta). Note: You can set Gun.log, by default: console.log

Promise enabled methods

ES6 Promise or ES7 async/await), always prefixed with $

  • .$fields(opt) - get fields (ie. property names)
  • .$iterate(opts) - iterate
  • .$mapReduce(options, putCb, opt) - map/reduce
  • .$no(opt) - blocks if no data, see no
  • .$val(opt) - full value (with meta)
  • .$value(opt) - get value (no meta)
  • .$valueAt(path, opt) - get value at the path (no meta)
  • .$recurse(filter) - recursive filter
  • .$timed(opts) - timed recursion

Observable streams for superior Async flow control

Observable methods are also (currently) prefixed with $

Observable stream support is included for:

Example: Rx.js

// optional
let options = {
  log: true,
  op: 'live'
}

// or simply $rx(node) or even node.$rx()
let obs = $rx(node, options)

let subscription = obs
  .subscribe(x => {
    console.log({received: x})
  })

Useful internal Gun functions

Gun.obj.copy(val) - copy a value Gun.obj.map(data, function(val, field){ ... } - map over a node Gun.fn.is - check if something is a function Gun.text.random() - generate random text Gun.is.node.soul(data) - test if data has a soul (ie. is a Gun node) Gun.node.soul(data) - return id of Gun node

Please add more internal Gun functions to this list for reference ;)

Useful chain methods

node.back() - go one level back/up in the graph

WIP

  • .out(navOpts, cb) - traverse edge (WIP)
  • .edge(navOpts/data) or link - for linking nodes and traversing links/edges
  • .filter(filterFun, cb) - filter fields

CSP Channels: WIP

CSP channel also included :)

The main idea is outlined here

CSP learning resources:

To start a process just pass a generator as a parameter to the go function. By using the yield keyword, you can pause a process, freeing the main thread Channels are queues. Whenever a process calls take on a channel, it pauses until a value is put into that channel.

Processes that put a value on a channel also pause until some other process uses take. Because channels are queues, when a process takes from a channel, the value will not be available for other processes to take. One process puts, one process takes. A channel can be buffered, which means that, for a given number of puts, a put will not make the process pause.

If the channel has a buffer of size 2, the third put will block the process, until someone takes from it.

See the test/channel/ folder for some test examples:

let size = 2
let buffer = csp.buffers.fixed(size)
// let buffer = csp.buffers.sliding(size)
// let buffer = csp.buffers.dropping(size)
// const promiseCh = csp.promiseChan();

// NOTE: optionally customize channel and buffer used
// let promiseCh = csp.chan(buffer)

promiseCh = $csp(node, {
  // channel: promiseCh, // will use fixed(2) buffer by default
  // log: true,
  op: 'live',
  // only put on channel when node value has a num field
  condition: (val) => val.num
})

node.timed({
  maxNum,
  logging: true,
  cb: resolve
})

let num = 0
let condition = () => num < 5

// Please help improved this!!!
csp.go(function* () {
  while (condition()) {
    const value = yield csp.take(promiseCh)
    console.log('value', value)
  }
})

mapReduce

See full mapReduce guide

Contributing

Compile/Build

The project includes a gulpfile configured to use Babel 6. All /src files are compiled to /dist including source maps.

Scripts:

  • start: npm start
  • build: npm run build (ie. compile)
  • watch and start: npm run watch
  • watch and build: npm run watch:b

Run Tests

npm test or simply ava test

Examples

The /examples folder will at some point include some example projects, including a web page (with live reload)

Sandbox

For playing around...

Docs

Various ideas sketched out in /docs

License

MIT Kristian Mandrup