gun-edge
v0.8.8
Published
Gun chain extensions for a higher level DSL and API
Downloads
14
Maintainers
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 (seetimed-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 thepath
(no meta).valAt(path, cb, opt)
: get value at thepath
.setAt(path, cb, opt)
: set value at thepath
.putAt(path, cb, opt)
: put value at thepath
.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 setGun.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 thepath
(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)
orlink
- 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