GithubHelp home page GithubHelp logo

sg's Introduction

hackday Archived Repository
The code of this repository was written during a Hack Day by a Marmelab developer. It's part of the distributed R&D effort at Marmelab, where each developer spends 2 days a month for learning and experimentation.
This code is not intended to be used in production, and is not maintained.

SG

Utility to handle side effects with generators. Inspired by redux-saga and co.

An effect is an object that describe a task, but do not execute it. This allows to separate the tasks scheduling from the tasks themself.

install

npm install

Introduction

The sg function takes a generator yielding effect and returns a function which return a promise.

import { call } from 'sg/effects';
function* gen(name) {
    //...
    yield call(console.log, `hello ${name}`);

    return 'done';
}

const func = sg(gen);

func('world')
.then((result) => {
    console.log(result); // done
});

effects

The effects are helper functions which return an object describing what to do.

const effect = call(console.log, 'hello world');
// effect:
{
    type: 'call',
    handler: // function that will execute the effect: called with arg, and returning a promise
    args: [console.log, 'hello world'], // args passed to the effect function
}

call

Calls a function (normal, async or returning a promise) or a generator yielding effect and either returns the value or throws an error.

const add = (a, b) => a + b;
const addPromise = (a, b) => new Promise((resolve, reject) => {
    try {
        resolve(a + b);
    } catch (error) {
        reject(error);
    }
})
const addAsync = async (a, b) => await Promise.resolve(a + b);
function* addGenerator(a, b) {
    const c = yield call(add, a, b);
    const d = yield call(addPromise, a, c);
    return yield call(addAsync, b, d);
}

thunk

Calls a thunk function and either returns the value or throws an error. A thunk function is a function that returns an asynchronous function taking a callback.

const add = (a, b) => cb => cb(null, a + b);

co

Calls a co style generator (yielding promise or thunk, not effect).

function* add(a, b) {
    return yield Promise.resolve(a + b);
}

cps

Calls a continuation passing style function.

const add = (a, b, cb) => cb(null, a + b);

put

emit an event

yield put('my event', { payload: data });

take

Waits for event sent by put and return its payload

const payload = yield take('my event'); // { payload: data }

spawn

Launches another sg generator, but do not wait for it to end, returning a task object.

const task = yield spawn(sgGenerator);

fork

Same as spawn, but errors from the forked generator will bubble up to the parent generator making it fail. Also the parent generator will wait for the forked generator to end before resolving.

const task = yield fork(sgGenerator);

cancel

takes a task returned by fork or spawn, and cancels it, ending it and its children.

yield cancel(task);

join

takes a task returned by fork or spawn, and joins it, waiting for the task to end or throw an error.

const result = yield join(task);

race

yields several effect simultaneously in a literal and returns only the result of the first completed effect, or its error if it failed.

const { user, cancel } = yield race({
    user: yield call(fetchUser),
    cancel: yield take('CANCEL'),
});

takeEvery

forks given generator each time given event is triggered. It is the same as forking the following generator:

function* takeEverySaga(type, gen, ...args) {
    while (true) {
        const action = yield take(type);
        yield fork(gen, ...args.concat(action));
    }
}

task

Object returned by fork and spawn. It has a done and cancel method.

  • done: returns a promise, which resolves with task result or rejects with task error.
  • cancel: Cancels the task if it is still running. This in turn will also cancel all children of this task.

Adding your own custom effects with createEffect

You can create your own effect with createEffect. It takes a type, and an handler.

  • Type: A string with the effect name
  • Handler: a function returning a promise and that receives three arguments:
    • effect parameters: an array with the list of argument passed to the effect function
    • emitter An event emitter used internally for the take and put effects.
    • id The internal id of the current saga. You will probably never need this.

Example of custom effect:

import sg, { createEffect } from 'sg.js';
import { createEffect } from 'sg.js/effects';

function handleSql([sql, parameter]) {
    return executeQueryAndReturnAPromise(sql, parameter);
}

const sqlEffect = createEffect('sql', handleSql);

sqlEffect('query', 'parameter'); give

{
    type: 'sql',
    handle: handleSql,
    args: ['query', 'parameter'],
}

Our sqlEffect can be used in a generator like this.

sg(function* (userData) {
    yield sqlEffect('INSERT ... INTO user', userData);
})({ name: 'john' });

During execution handleSql will get called like so

handleSql(['INSERT ... INTO user', userData]);

Injecting Custom EventEmitter

Sg use an eventEmitter internally to handle take and put effects. It is possible to pass your own eventEmitter to sg. This allows to take events from this event emitter. Your event emitter must extends node event emitter.

sg's People

Contributors

alexisjanvier avatar djhi avatar fzaninotto avatar jpetitcolas avatar sedy-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.