Coder Social home page Coder Social logo

effector / effector Goto Github PK

View Code? Open in Web Editor NEW
4.5K 48.0 218.0 132.72 MB

Business logic with ease ☄️

Home Page: https://effector.dev

License: MIT License

JavaScript 3.88% Dockerfile 0.01% TypeScript 96.11%
state business-logic reactive event-driven effector state-management state-manager

effector's Introduction

Effector Comet Logo


join gitter rate on openbase build status discord chat become a patron

☄️ effector

Business logic with ease

Visit effector.dev for docs, guides and examples

Table of Contents

Introduction

Effector implements business logic with ease for Javascript apps (React/React Native/Vue/Svelte/Node.js/Vanilla), allows you to manage data flow in complex applications. Effector provides best TypeScript support out of the box.

Effector follows five basic principles:

  • Application stores should be as light as possible - the idea of adding a store for specific needs should not be frightening or damaging to the developer.
  • Application stores should be freely combined - data that the application needs can be statically distributed, showing how it will be converted in runtime.
  • Autonomy from controversial concepts - no decorators, no need to use classes or proxies - this is not required to control the state of the application and therefore the api library uses only functions and plain js objects
  • Predictability and clarity of API - a small number of basic principles are reused in different cases, reducing the user's workload and increasing recognition. For example, if you know how .watch works for events, you already know how .watch works for stores.
  • The application is built from simple elements - space and way to take any required business logic out of the view, maximizing the simplicity of the components.

Installation

You can use any package manager

npm add effector

React

To getting started read our article how to write React and Typescript application.

npm add effector effector-react

SolidJS

npm add effector effector-solid

Vue

npm add effector effector-vue

Svelte

Svelte works with effector out of the box, no additional packages needed. See word chain game application written with svelte and effector.

CDN

Documentation

For additional information, guides and api reference visit our documentation site

Packages

Articles

Community

Online playground

You can try effector with online playground

Code sharing, Typescript and react supported out of the box. Playground repository

DevTools

Use effector-logger for printing updates to console, displaying current store values with ui or connecting application to familiar redux devtools


More examples in documentation

Learn more

Support us

Your support allows us to improve the developer experience 🧡.

Contributors

Dmitry/
Dmitry
andretshurotshka/
andretshurotshka
Sova/
Sova
Alexander
Alexander Khoroshikh
popuguy/
popuguy
Igor
Igor Kamyşev
Egor/
Egor
Valeriy
Valeriy Kobzar
Yan/
Yan
Ruslan
Ruslan @doasync
Illia
Illia Osmanov
mg901/
mg901
Igor
Igor Ryzhov
Arthur
Arthur Irgashev
Viktor/
Viktor
Ilya/
Ilya
Ainur/
Ainur
Arutiunian
Arutiunian Artem
Dmitrij
Dmitrij Shuleshov
Nikita
Nikita Nafranets
Ivan
Ivan Savichev
Aleksandr
Aleksandr Osipov
Зухриддин
Зухриддин Камильжанов
bakugod/
bakugod
Victor
Victor Didenko
Viktor
Viktor Pasynok
Kirill
Kirill Mironov
Andrei/
Andrei
Ivan/
Ivan
Bohdan
Bohdan Petrov
sergey20x25/
sergey20x25
Ivanov
Ivanov Vadim
Tauyekel
Tauyekel Kunzhol
Victor/
Victor
Vladimir
Vladimir Ivakin
Aldiyar
Aldiyar Batyrbekov
cqh/
cqh
xaota/
xaota
☃︎/
☃︎
Andrei
Andrei Antropov
Mikhail
Mikhail Kireev
Stanislav/
Stanislav
Sozonov/
Sozonov
Samir/
Samir
Renat
Renat Sagdeev
Kirill/
Kirill
Denis
Denis Sikuler
Arsen-95/
Arsen-95
Anton
Anton Yurovskykh
Aleksandr
Aleksandr Belov
Anton
Anton Kosykh
Usman
Usman Yunusov
vadimfilimonov/
vadimfilimonov
Vasili
Vasili Sviridov
Vasili
Vasili Svirydau
Victor
Victor Kolb
Vladislav
Vladislav Melnikov
Vladislav
Vladislav Botvin
The
The Gitter Badger
Shiyan7/
Shiyan7
Sergey
Sergey Belozyorcev
Satya
Satya Rohith
Roman/
Roman
Robert
Robert Kuzhin
Raman
Raman Aktsisiuk
Rachael
Rachael Dawn
Will
Will Heslam
Rasul
Rasul
Yesset
Yesset Zhussupov
Anatoly
Anatoly Kopyl
ansunrisein/
ansunrisein
Stanislav/
Stanislav
dmitryplyaskin/
dmitryplyaskin
Grigory
Grigory Zaripov
Houston
Houston (Bot)
ilfey/
ilfey
kanno/
kanno
Kirill
Kirill Leushkin
Marina
Marina Miyaoka
roman/
roman
vladthelittleone/
vladthelittleone
xxxxue/
xxxxue
0xflotus/
0xflotus
Abdukerim
Abdukerim Radjapov
7iomka/
7iomka
Abel
Abel Soares Siqueira
Aleksandr
Aleksandr Grigorii
Alex
Alex Arro
Aleksei
Aleksei Pudnikov
Alex
Alex Anokhin
Alexander/
Alexander
Александр/
Александр
Ayu/
Ayu
Dennis
Dennis Maush
Denis
Denis Skiba
Dmitry
Dmitry Dudin
Ed
Ed Prince
Gabriel
Gabriel Husek
Ilya
Ilya Martynov
Infant
Infant Frontender
Ivan/
Ivan
Jan
Jan Keromnes
Jesse
Jesse Jackson
Joel
Joel Bandi
Lebedev
Lebedev Konstantin
Leniorko/
Leniorko
Ludovic
Ludovic Dem
Nikita
Nikita Svoyachenko
Mike
Mike Cann
Oleg/
Oleg
Oleh/
Oleh
Pasha
Pasha Grekovich
bigslycat/
bigslycat

Tested with browserstack

effector's People

Contributors

abliarsar avatar ainursharaev avatar alexandrhoroshih avatar artalar avatar bakugod avatar binjospookie avatar bloadvenro avatar dependabot[bot] avatar dimensi avatar doasync avatar dpr-dev avatar drevoed avatar egorguscha avatar github-actions[bot] avatar goodmind avatar hexagon141 avatar igorkamyshev avatar ilajosmanov avatar kobzarvs avatar komar0ff avatar mg901 avatar oas89 avatar popuguytheparrot avatar sergeysova avatar tehsly avatar victordidenko avatar yanlobat avatar zarabotaet avatar zerobias avatar zukhrik avatar

Stargazers

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

Watchers

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

effector's Issues

How to subscribe to a Promise result?

// like that...
        function sleep(): Promise<string> {
            return new Promise<string>(resolve => setTimeout(() => 'on', 1000));
        }

        const turnOn = domain.effect<void, string, Error>()
            .use(async  _ => await sleep());

         // subscribe to Promise
        const status = domain.store<string>('off')
            .on(turnOn, (state, payload, result, error) => result);

        turnOn();

What's the most convenient way to get Promise Result?

Describe motivation for creating or using this library

Currently README.md doesn't answer the most important questions:

  1. What could be the user's motivation for using this library?
  2. What's the difference between this library and a very similar (at a glance) and extremely popular library MobX?
  3. (optional) What was the author's motivation for creating this library? For example, Redux was created to support middleware and time-travel, MobX was inspired by Proxy API, etc.

So far, all I see are code examples, that look very similar to MobX

Future doesn't extends Promise

Code to reproduce the issue:

const m = createDomain()
const eff = m.effect('1')
const eff2 = m.effect('2')

eff.use(() => eff2())
eff2.use(() => Promise.resolve())

eff().promise() // future
eff().promise().promise() // promise

https://codesandbox.io/s/54kvmqk43x

Expected behavior:

  • Future extends Promise
  • .promise() returns real Promise (or becomes obsolete)

Actual behavior:

  • Future doesn't extends Promise
  • .promise() doesn't return real Promise, but thenable
  • Future is just thenable

Versions of packages used:

"effector": "^0.18.0-beta.11",
"effector-react": "^0.18.0-beta.11",

Add real world examples

Examples - is the best way to understand the library.
Some examples already could be found in readme or in tests(🤓) but could be better.

Gate default state is {}, but i can create non-object Gate

It's possible to create non-object Gate:

const NumberGate = createGate<number>('number');
...
const Component = () => {
  useGate(NumberGate, 1)
}

and receive some runtime error after that,

NumberGate.state.watch((value) => {
  console.log(value * 2);
})

which will not be detected with type-checking, because value type is number | null and value can be {}.

Missing/Incorrect APIs

Relevant documentation

createGate

website: JSON linting

Expected behavior:
Valid JSON should not be highlighted as invalid.
Actual behavior:
JSON is validated as JavaScript which produces a syntax error.

image

Add more sugar for store composition (combining)

Combine function looks very ugly when you need to compose some stuff into another store, usually you just need to combine two or more stores into another object.
I suggest the following api

function compute<A, B, C, ...>(storeA: A, StoreB: B, storeC: C, aggregateObject: //aggregated type );
const data = computed(todosLen, {
  completedTodoCount,
 // this is computed value where todos len is value from the store in first argument
// all the next  passed  stores will be passed as next arguments as well
  isLenEvent: (todosLen) => todosLen%2 === 0
});

function compute takes stores as arguments and aggregate object as last argument.
This object takes either store, either function for computed value

const filterItems = (entities, search) => {
  return filter(entities, item => item && item.name
}

computed(entities, searchText, {
  filteredItems: filterItems
})

createEffect doesn't resolve void Params

Issuehunt badges

I have this code:

const handler = () => console.log();

const effect = createEffect('', {handler});

effect();

I got TS2554: Expected 1 arguments, but got 0. An argument for payload was not provided

So, I have to manually declare effect typings like this:

const effect = createEffect<void, void, any>('', {handler});

Or write wrappers:

const createBetterEffect = <Params = void, Done = any>(
  name?: string,
  options?: {handler?: (() => Done | Promise<Done>) | ((p: Params) => Done | Promise<Done>)},
) =>
  createEffect<Params, Done, string>(name, options);

I want createEffect to correctly infer void type of Params


IssueHunt Summary

goodmind goodmind has been rewarded.

Backers (Total: $40.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Nicer typings for createApi()

For now createApi() doesn't let you to work with events without payload or with optional payload:

const api = createApi(store, {
    increment: (count) => count + 1,
    decrement: (count) => count - 1,
    double: (count) => count * 2,
    multiply: (count, mp = 2) => count * mp,

});

api.double(); // Expected 1 arguments, but got 0.
api.multiply(); // Expected 1 arguments, but got 0.

How i can load previously saved state snapshot?

For example, I saved the current state of the repository in localStorage, and I want to restore the state after the user push button "restore last state". I do not understand from the documentation, is it possible?

Selector own props

I know you can use $store.map to select part of a store but what if I need to select a part of a store using a parameter. Example:

const $data = createStore({"alex": {age: 20, name: "Alex}, "john": {age: 30, name: "John"}})

if I have and cont id = "alex" in a component somewhere is there a use to select only alex data and get the update if that is changing ?

Using reselect I could do something like:

const getVisibilityFilter = (state, props) => state.todoLists[props.listId].visibilityFilter

Improve createComponent

Please, add optional initial callback to createComponent

Example:

createComponent(
  initialProps => store.map(state => state[initialProps.id]),
  Component
)

event.prepend(...) doesn't work with undefined

Code to reproduce the issue:

import { createEvent } from 'effector'

const click = createEvent()
click.watch(console.log)

const preclick = click.prepend(n => n)

preclick()

Expected behavior:

undefined in console

Actual behavior:

click.watch doesn't get called

Versions of packages used:

0.18.1

Effector size

The current Effector size is 5 KB.

It is a lot 100 ms just to download (and about 100 ms to parse and execute JS).

Especially, when Redux is 2 KB and other Redux-like stores could be 200-600 B.

Diamond problem with subscribers

const clickButton = createEvent()
const closeModal = createEvent()

forward({
  from: clickButton,
  to: closeModal,
})

const lastEvent = createStore(null)
  .on(clickButton, () => 'click')
  .on(closeModal, () => 'modal')

lastEvent.watch(data => {
  // here we need everything
  sendAnalytics(data)
})

lastEvent.watch(data => {
  //here we need only final value
  render(data)
})

Here we are expecting two different behaviours: sendAnalytics need updates about both events calls, but render expect only last relative data.

Usage with NextJS SSR

Hi there,

Unfortunately, I am still kinda new when it comes to SSR and I was wondering if you have any examples/extensions/ideas on how to use Effector(-React) with NextJS.

I would appreciate any support.

Thank you!

Add Vue bindings

I can help with Vue bindings 'cause I want to try it on my side-projects (:

Remove broken link to Unit in sample documentation

Issuehunt badges

Link to Unit page in the documentation leads to nowhere and has been added by mistake, we need to remove it


IssueHunt Summary

satyarohith satyarohith has been rewarded.

Backers (Total: $6.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Compatibility with TV browser (Chrome 47)

Issuehunt badges

Hi,
crafting an application with create-react-app, and installing effector/effector-react, in the main file and importing any effector/effector-react functions, the live preview in dev mode returns the following on Chrome 47:

Unexpected token {

effector 20.0.0/effector-react 20.0.4

Thank you


IssueHunt Summary

zerobias zerobias has been rewarded.

Backers (Total: $40.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Typescript typings for sample

Sample typings is incomplete for config case.

const source = createStore<string>('')
const event = createEvent<number>()

const target = createEvent<number>()

// Fine
const case1 = sample(source, event, (a, b) => 1)

const store = createStore<number>()
const event2 = createEvent<string>()
// Should be Event<number>, not Event<string>
const case1bug = sample(event2, store, (a,b) => 1)

// No errors, but case2 should be Event, not Unit
// It doesn't matter tho, because we can use methods of target
const case2 = sample({
  source,
  clock: event,
  fn: (a, b) => 1,
  target
})
// TS complains about arguments of fn
// TS7006: Parameter 'a' implicitly has an 'any' type.
// TS7006: Parameter 'b' implicitly has an 'any' type.
const case3 = sample({
  source,
  clock: event,
  fn: (a, b) => 1
})

// And case3 is completely useless, because it has Unit type
// TS2339: Property 'filterMap' does not exist on type 'Unit<number>'.
case3.filterMap(a => a === 1 ? a : undefined)
// Can't cast it
// TS2740: Type 'Unit<number>' is missing the following properties from type 'Event<number>': watch, map, filter, filterMap, and 5 more.
const t: Event<number> = case3

restore function doesn't work in REPL

Issuehunt badges

Code to reproduce the issue:

const foo = createEvent()
const bar = restore(foo, null)

Expected behavior:

No errors

Actual behavior:

Try Effector crashes

Versions of packages used: master

https://effector.now.sh/try/

To reset saved code remove it from localStorage


IssueHunt Summary

laiff laiff has been rewarded.

Backers (Total: $40.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

An unsubscribed event may change store state

Code to reproduce the issue:
state changes even after the event was unsubscribed

Expected behavior:
If you do store.off(event) it should unsubscribe any handlers for the event

Actual behavior:
If you subscribed a store to the same event more than once using .on(event, handler),
calling .off(event) does not guarantee that the event won't affect store again.
If you call the event, the state of the store may be changed, because only the very last event handler (reducer) is unsubscribed. It wouldn't be an issue if a new reducer replaced the previous one for the same event (#8)

Versions of packages used:
Effector v0.18.4

Throw in reducer is not cancel computation of other reducers

If someone forwarded you here, this is an outdated discussion which can not and must not be used as proof of the issues of any kind.

Calling of pure function cannot be detected by definition, thereby preventing from using them in a suggested way
That is, the inability to throw an exception is what make functions pure.
And that is what effects were being made for: effect is a function, which might throw an exception, which triggers a fail branch, which you can subscribe on.

Reducers in .on, functions in .map are pure. You shall not branch them by throwing exceptions. This is not an issue, this is what makes computations predictable and stable.

Original issue:

Code to reproduce the issue:
repl

Expected behavior:
Throw all computation

Actual behavior:
Receive wrong data

Versions of packages used:
0.18.16

Visualization for stores, events and relationships

Issuehunt badges

Do you have some library for visualization store in browser, like redux-devtools-extensions or like desktop Reactotron


IssueHunt Summary

Backers (Total: $100.00)

Become a backer now!

Or submit a pull request to get the deposits!

Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Better Try Effector experience on mobile devices

Issuehunt badges

https://effector.now.sh/try
https://github.com/zerobias/effector/tree/master/website/editor

iOS is priority


IssueHunt Summary

Backers (Total: $40.00)

Become a backer now!

Or submit a pull request to get the deposits!

Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

An effect handler is not called when you use `forward`

Code to reproduce the issue:
try

Expected behavior:
I expect an effect handler to be called when you forward to the effect

Actual behavior:
The effect is called itself but not the handler when foward is used

Versions of packages used:
Effector v0.18.4

ERROR Compiled - Cannot find name 'E' in effector/index.d.ts

Code to reproduce the issue:

57:57 Cannot find name 'E'.
    55 |     handler: (state: State, payload: E) => State | void,
    56 |   ): this
  > 57 |   off(event: Event<any> | Effect<any, any, any> | Store<E>): void
       |                                                         ^
    58 |   subscribe(listner: any): Subscription
    59 |   watch<E>(
    60 |     watcher: (state: State, payload: E, type: string) => any,

Versions of packages used: 0.18.2

? maybe =>

export type E = any;

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.