Nighttime Peanut Migrations

    coroutiner

    0.3.3 • Public • Published

    Coroutiner

    A convenience transformer to turn every GeneratorFunction into a Promise.coroutine.

    coroutiner = require('coroutiner')
    
    obj = {
    	fn: function*() {
    		yield Promise.delay(500)
    		return new Promise(function(resolve) { resolve(1000) })
    	}
    	
    	normalFn: function() { return 5 }
    }
    
    coroutiner( obj )
    
    obj.fn().then(function(number) {
    	number // returns 1000
    })
    
    
    Promise.coroutine(function*() {
    	yield obj.fn() // returns 1000
    }
    
    obj.normalFn() // returns 5

    Why?

    Instead of calling Promise.coroutine on every generator function, just call coroutiner on a parent object. This allows one to build an application utilizing yield much more conveniently when every generator is already promisified.

    Just be careful what you run this over. When prototype: true (default) is enabled this will work on class (){}.prototype, function(){}.prototype and {}.__proto__, which includes instances of classes.

    You can also do it recursively.

    // Create a new coroutiner, which also enumerates over a functions prototype
    coroutiner = require('coroutiner')
    
    fn = function*() {}
    fn.prop = 1
    
    obj = {
    	fn: fn
    	anArray: [
    		{
    			fn: function*(){} // coroutined, due to { array: true }
    		}
    	]
    	klass: class Class {
    		fn: function*() {} // coroutined, due to { prototype: true }
    	}
    }
    
    // This is run on every matched GeneratorFunction
    // Returning `false` will skip it from being transformed
    validatorFunction = function(key, value, parent) {
    	if ( key.match(/idontwantyou/) ) {
    		return false // skipping
    	}
    }
    
    coroutiner.all(obj, validatorFunction)
    
    // Properties of GeneratorFunctions will be copied over
    obj.fn.prop // returns 1

    Caveats and Warnings

    Coroutiner will behave weirdly in this CoffeeScript example

    class Test
    	fn: => 
    		# A bound function!
    		yield return
    		
    class NewTest extends Test
    	newFn: -> yield return
    
    test = new NewTest()
    
    coroutiner { test, NewTest }
    
    yield test.fn() # Error, because .fn() never got coroutined before being extended
    yield test.newFn() # Works because it was defined in NewTest's prototype
    yield new NewTest().fn() # Works because the instance was created with the coroutined prototype

    The transformer

    Make sure require('bluebird') works if you aren't specifying your own transformer. Bluebird's Promise.coroutine is used as a transformer by default, but by creating your own coroutiner instance that can change.

    coroutiner( obj, ?validatorFn?, ?types? )

    Returned by require('coroutiner').

    Transforms GeneratorFunctions within the obj with the transformer. Will also enumerate over the fn.prototype if prototypes are enabled.

    This is not recursive.

    coroutiner.all( obj, ?validator?, ?depth?, ?types? )

    Recursively transforms properties, like coroutiner(). Be careful with this. Only run it over an object that exposes your generators. If this touches a library that expects generators then things will break.

    coroutiner.Coroutiner( options )

    Creates a new coroutiner instance.

    options {Object}

    • validator {Function} A default validator function
    • transformer {Function} A default transformer instead of Promise.coroutine
    • array {Boolean} true Whether to iterate over arrays items
    • object {Boolean} true Whether to iterate over object properties
    • function {Boolean} true Whether to iterate over function properties
    • prototype {Boolean} true Whether to iterate over function/object prototypes

    This controls which properties are enumerated over to look for transformable properties.

    coroutiner.create( fn, ?types? )

    Create a coroutined function and copies over its properties into a new returned function. This is called by coroutiner() and coroutiner.all()

    coroutiner.types

    {
    	object: true, function: true, array: true
    	prototype: true, unowned: true, circular: false
    }
    

    unowned as false if you only want .hasOwnProperty properties circular as true will remove cyclic recursion protection

    Keywords

    none

    Install

    npm i coroutiner

    DownloadsWeekly Downloads

    6

    Version

    0.3.3

    License

    none

    Last publish

    Collaborators

    • nfour