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

getjs

v2.0.0

Published

JavaScript library to express concurrency patterns

Downloads

22

Readme

#Getjs

badge

JavaScript library to express concurrency patterns.

Getjs is a control flow library based in generators to simplify the development of concurrent solutions for JavaScript. It works in both nodejs and the browser, allowing you to deal with the JavaScript asynchronous nature by writting sequential code.

Getjs implements Communicating Sequential Process(CSP) by emulating Golang concurrency primitives as much as possible with few deviations to fit in the JavaScript ecosystem. It works with every library based on Promises.

Pingpong example (ported from Go)

var player = get(function*(name, table) {
    var ball
    while (true) {
        ball = yield get(table)
        if (table.closed) {
            console.log(name, 'table is gone')
            return
        }
        ball.hits += 1

        console.log(name, ball.hits)
        yield get.timeout(100)

        if (table.opened) {
            yield get.send(table, ball)
        }
    }
})

get.go(function*() {
    var
    table = get.chan()

    player('Ping', table)
    player('Pong', table)
    
    yield get.send(table, {hits: 0})
    yield get.timeout(1000)

    get.close(table)
})

More examples

Documentation

  1. Installation
  2. Coroutines
  3. Channels
  4. Parallel Resolution
  5. Race Resolution
  6. Pausing Coroutines
  7. Promisifying
  8. Idiomatic Getjs
  9. Debugging

Installation

Browser

<script src="get.js"></script>

Nodejs

var get = require('getjs')

Coroutines

Coroutines are functions that runs asynchronously. The body of coroutines are generator functions, each time a promise is yielded inside a coroutine it blocks until the promise is resolved or rejected. Each coroutine execution returns a promise that is resolve when the coroutine returns, or rejected if an error occurs.

Spawning a coroutine.

get.go(function *() {
    console.log('executed')
})

// with arguments
get.go(function *(name, age) {
    console.log(name, age)
}, ['john', 30])

In many occasions you may need to declare coroutines to spawn it on demmand.

var worker = get.wrap(function *(time) {
    console.log(time)
})

worker(100)
worker(500)

Waiting for a promise.

get.go(function *() {
    var n = yield Promise.resolve(1)
})

Promise flow.

get.go(function *() {
    return 5
}).then(function(v) {
    console.log(v)
}).catch(function(e) {
    console.log(e.stack)
})

Channels

Channels are structures used to communicate and synchronize coroutines. The behavior is exactly like in Go language.

Channels can be buffered or unbuffered. When sending data through unbuffered channels it always blocks the sender until some other process receives. Once the data has been received, the sender will be unblocked and the receptor will be blocked until new data is received. Unbuffered channels are also known as synchronic channels.

// create new channel
var ch = get.chan()

get.go(function *() {
    // send 'message' to a `ch`
    yield get.send(ch, 'message')

    // close the channel
    get.close(ch)
})

get.go(function *() {
    // receive from `ch`
    var msg = yield get.recv(ch)

    console.log(msg)
})

get.send and get.recv operations must preceded by the yield keyword.

When some data is sent to a buffered channel it only blocks the coroutine if the buffer is full. The receiver only blocks if there is no data in the buffer.

var bufferSize = 20
var ch = get.chan(bufferSize)

Values passed through channels can be tranformed before to be delivered.

function trans(x) {
    return x*2
}

// provide a transformer
var ch = chan(null, trans)

Channels can be closed using get.close function, sending to a closed channel will throw an error. ch.closed and ch.opened allows to know whether a channel is closed or not.

while(ch.opened) {
    yield get.send(ch)
}

// close it somewhere in your code
get.close(ch)

Parallel Resolution

You can wait for many tasks executed in parallel by using get.all.

// proding an array of promises
var result = yield get.all([
    $.get('http://api.com/books'),
    $.get('http://api.com/authors')
]);

var books   = result[0];
var authors = result[1];

You can cast by keys by using objects.

// roviding an object
var result = yield get.all({
    books:   $.get('http://api.com/books'),
    authors: $.get('http://api.com/authors')
});

var books   = result.books;
var authors = result.authors;

Race Resolution

get.race returns promise that resolves once one of them has been resolved. The returned promise resolves with an object whith the format {which: key, value: value}.

get.go(function *() {
    var result = yield get.race([$.get('http://api.com/books'), timeout(500)])

    // found books
    if (result.which === 0) {
        var books = result.value;
    } else {
        // timed out
    }
})

Also support objects.

get.go(function *() {
    var result = yield get.race({
        books   : $.get('http://api.com/books'),
        timeout : timeout(500)
    })

    // found books
    if (result.which === 'books') {
        var books = result.value;
    } else {
        // timed out
    }
})

Pausing Coroutines

Some times you want to block a couroutine a span of time.

// stop by 20 milliseconds
yield get.timeout(20)

Promisifying

It is possible to adapt callback-based API to be used with Getjs.

var fs = require('fs')

// make the callback-based function returns a promise
var stat = get.promisify(fs.stat)


get.go(function *() {
    var stats = yield get(stat('path/to/file'))
    console.log(stats)
})

Also you can promisify the entire module.

var fs = get.promisify(require('fs'))

get.go(function *() {
    var stats = yield fs.stat('path/to/file')
})

Idiomatic Getjs

The get function is overloaded, making possible to write more succint code. If the first parametter is a generator function it will relay on get.wrap else it will try to convert the value to a promise through get.recv if channel, or get.all is object or array is provided.

// wrapped coroutine
func = get(function *() {})

// receive from a channel
yield get(channel)

// parallel resolution
yield get([a, b, c])

Debugging

Coroutine errors are easy to handle because the promise catch function. During development all coroutine errors are logged to the console. For production you should avoid this behaviour by turning get.debug to false.

get.debug = false

(c) 2016 Yosbel Marín