0.1.0 • Public • Published

Bacon.decorate NPM version Build Status Dependency Status

Unify your API and abstract time using Functional Reactive Programming (FRP) and Bacon.js

APIs are hard. Sometimes they can have you provide a callback, other times they return a promise or be synchronous. You can unify the usage of your API and abstract concepts like sync or async, by using the paradigm Functional Reactive Programming with the help of a implementation called Bacon.js.

The result of function calls will be reactive data types from Bacon.js. If you are unsure how to use Bacon or what FRP is, the Bacon.js README is very helpful and has a comprehensive introduction.


var decorate = require('./');
var Q = require('q');
var API = {
  // Async values using promises
  get: decorate.promise(function (arg1, arg2) {
    // Could be something like $.ajax aswell
    var def = Q.defer();
    setTimeout(function () {
    }, 1000);
    return def.promise;
  // Async values using callbacks
  getAnother: decorate.callback(function (a, b, callback) {
    setTimeout(function () {
      callback(+ "" + b)
    }, 1000);
  // Regular sync values
  sync: decorate.value(function (a, b) {
    return a + "" + b;
  // Or using events
  // This is an Event Stream of body content
  // triggered on click
  event: decorate.event('click', function () {
    return document.body;
  }, '.currentTarget.innerHTML')

By adding decorator to all methods, we can access them without thinking about if it's async or sync and we can easily combine them in different ways.

Example of waiting for multiple data inputs:

// Waiting for multiple values (example)
API.get('foo', 'bar')
  .combine(m.getAnother('Foo', 'Bar'), function (a, b) {
    return a + "" + b;
  .combine(m.sync('Baz', 'Qux'), function (a, b) {
    return a + "" + b;
  .onValue(function (value) {
    console.log('val', value);
    //=> val Async?: Foo, Bar, Baz, Qux



Automaticly choose wrapping type based on type of value returned from function. Only works on value type wrapping functions including: event, promise, value and array.

This is useful when you return different types of data in a function.


var someAPI = decorate.autoValue(function(a) {
  if (someCondintional) {
    return 42;
  if (Array.isArray(a)) {
    return a;
  if (someOtherConditional) {
    // 'click' is passed as event type
    // through second argument to autoValue
    return document.body;
  return $.ajax({
    url: '/async/call/here?' + $.params(a)
}, 'click');
// Logs the result of an ajax call.
// No need to check for sync values
someApi({ id : 1 }).log();


More info soon

See Bacon.js .fromCallback()


More info soon

See Bacon.js .fromNodeCallback()

decorate.event(fn, eventName[, transformFunction])

Wraps event returned from fn on eventName channel. You can pass in an optional transform function to transform the event object returned from the fn function.

See Bacon.js .fromEventTarget()

decorate.promise(fn, abort)

Wraps promise returned from fn as a reactive data type. abort defines if .abort method should be called on promise when all subscribers of event stream is removed.

See Bacon.js .fromPromise()


Wraps primitive value returned from fn as a reactive data type.

See Bacon.js .once()


Wraps an array returned from fn as a reactive data type. The result is an event stream that gives a value for each of the entries in the array.

See Bacon.js .fromArray()

decorate.interval(interval, fn)

Wraps to an event stream that gives value returned from fn every ms defined by interval.

See Bacon.js .interval()

decorate.sequentially(interval, fn)

Wraps to an event stream that gives value for each item every ms defined by interval from an array returned from fn.

See Bacon.js .sequentially()

decorate.repeatedly(interval, fn)

Same as decorate.sequentially(interval, fn), but starting from first item in the returned array when the end is reached, instead of ending.

See Bacon.js .repeatedly()

decorate.later(delay, fn)

Gives an event stream that gives a value returned from fn after delay milliseconds.

See Bacon.js .later()

decorate.poll(interval, fn)

Returns an event stream with values from polling fn every interval milliseconds.

See Bacon.js .fromPoll()


MIT License

NPM downloads

Package Sidebar


npm i bacon.decorate

Weekly Downloads






Last publish


  • mikaelb