Coder Social home page Coder Social logo

brydzu / algebraic-effects Goto Github PK

View Code? Open in Web Editor NEW

This project forked from phenax/algebraic-effects

0.0 1.0 0.0 1.22 MB

Manage side-effects in your javascript application cleanly with algebraic effects

Home Page: https://phenax.github.io/algebraic-effects

License: MIT License

JavaScript 84.18% TypeScript 10.94% HTML 4.88%

algebraic-effects's Introduction

Algebraic Effects

Define side-effects in a pure and composible way using algebraic effects. https://phenax.github.io/algebraic-effects

CircleCI npm bundle size (minified + gzip) Codecov

Documentation

Install

To add the project to your project

yarn add @algebraic-effects/core

If you want effects like Exception, State, Random, etc.

yarn add @algebraic-effects/core @algebraic-effects/effects

Usage

Import it to your file

import { createEffect, func } from '@algebraic-effects/core';
import { sleep } from '@algebraic-effects/core/generic';

State effect counter example

import { State } from '@algebraic-effects/effects';
import { call, sleep } from '@algebraic-effects/core/generic';

const countdown = function*() {
  const count = yield State.get();

  if(count > 0) {
    yield State.set(count - 1); // Decrement count
    yield sleep(1000); // Add a delay of 1 second
    yield call(countdown); // Recursively call the program again.
  }
}

State.of(10)(countdown)
  .fork(() => {}, () => alert('HAPPY NEW YEAR!!!!'));

Creating your own effects

  • Declare your effects
import { createEffect, func } from '@algebraic-effects/core';

export const ConsoleEffect = createEffect('ConsoleEffect', {
  log: func(['...data']),
});

export const ApiEffect = createEffect('ApiEffect', {
  fetchUser: func(['userid'], 'user'),
  markUserAsViewed: func(['userid']),
});

func function allows you to document the operation signature.

  • Write your program
const fetchProfile = function*(uid) {
  const user = yield ApiEffect.fetchUser(uid);

  yield ConsoleEffect.log('>> Fetched user user', uid);

  if(user.isPublic) {
    yield ApiEffect.markUserAsViewed(user.id);
    yield ConsoleEffect.log('>> Marked', uid, 'as viewed');
    return user;
  }

  return { id: uid, name: user.name, isPrivate: true };
}
  • Implement effect operation behavior
const logger = ConsoleEffect.handler({
  log: ({ resume }) => (...args) => {
    console.log(...args);
    resume();
  },
});

const api = ApiEffect.handler({
  markUserAsViewed: ({ resume, throwError }) =>
    uid => fetchJson(`/user/${uid}/mark-as-viewed`).then(() => resume()).catch(throwError),
  fetchUser: ({ promise }) => uid => promise(fetchJson(`/user/${uid}`)),
});

promise is a shorthand for doing .then(resume).catch(throwError)

  • Calling your program
api.with(logger) // Compose your effect handlers togather and run them
  .run(fetchProfile)
  .fork(
    e => { /* Handle error */ },
    user => { /* Handle success */ }
  )

Multiple continuations

You can call resume multiple times from your operation synchronously.

const ListEffect = createEffect('ListEffect', {
  takeItem: func(['list'], '*', { isMulti: true }), // isMulti flag indicates that this operation resumes multiple times
});

// Program will resolve with [3, 4, 6, 7]
function *program() {
  const item1 = yield ListEffect.takeItem([ 1, 4 ]);
  const item2 = yield ListEffect.takeItem([ 2, 3 ]);

  return item1 + item2;
}

const loopEff = ListEffect.handler({
  takeItem: ({ resume }) => list => list.forEach(resume),
});

// runMulti method will start your program in mutiple continuations mode
loopEff.runMulti(program).fork(
  handleError,
  data => {
    console.log(data); // [3, 4, 6, 7]
  }
);

Contributing

License

Algebraic effects is under MIT licensed.

algebraic-effects's People

Contributors

nertzy avatar phenax avatar

Watchers

 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.