Coder Social home page Coder Social logo

capacitor.js's Introduction

Introduction

WARNING: Still being documented.

Capacitor.js is a well tested implementation of facebook's flux architecture written in CoffeeScript, which aims to do the following things:

  • Be as close to the official definition of flux as possible, only making optimizations/features where there's too much boilerplate.
  • Be easy to use, even for beginners, which means it should be easy to do it right, hard to do it wrong.
    • An example is the ActionCreators, which is the only way to dispatch an action without going out of your way.
  • Have all stores be comprised of immutable data with immutable.js
  • Handle relationships between stores with ease, without the boilerplate
  • Be easy to extend, where extensions make sense.
  • Scale well when used in teams by heavily encouraging thought before code, and try to minize how many ways you can solve a single problem.
  • Feel great to use in CoffeeScript
  • Feel just as great to use in TypeScript/ES6
  • Support all the loaders, AMD/CommonJS/ES6/Globals whatever you need.

Features

  • The dispatcher is an implementation detail, you never interact with it manually.
  • Actions are class instances, no giant switch statements needed.
  • Stores listen for actions by using the action classes.
  • Four types of stores to model your data:
    • Store (generic state)
    • EntityStore (anything with an id)
    • ListStore (a list of entities)
    • IndexedListStore (a map from an entity id to a list of entity ids)
  • With these four stores you can model the following:
    • one to one (Entity/Store -> Entity)
    • one to many (Entity/Store -> List -> Entity)
    • many to many (Entity/Store -> IndexedList -> Entity)
  • ActionCreators dispatch actions.
  • Batch change events on stores within a dispatch iteration to simplify store interactions.

Features we'd like to add

  • Webpack Hot Loader
  • Chrome Devtools Extension(s)
  • State snapshots
  • Replayable action logs

Dependencies

  • lodash
  • immutable-js

NOTE: Upgrading to capacitor > 0.2.x from capacitor < 0.2.x

Stores now use immutable js for the data. The API is still the same but the data returned is now instances of immutable's classes. See https://github.com/facebook/immutable-js for usage. Unfortunately this completely breaks backwards compatibility.

capacitor.js's People

Contributors

miklschmidt avatar bondo avatar kastermester avatar

Stargazers

Vinod S Pattar avatar Mehmet Ali SAHINOGULLARI avatar  avatar Ali MHZ avatar  avatar  avatar  avatar Julian Hovmand avatar

Watchers

 avatar  avatar James Cloos avatar

capacitor.js's Issues

Use Immutable records in actions and EntityStores.

The stupid strings are starting to bother me, they aren't used for anything else than checking for uniqueness. I'd like to solve a couple of problems around dealing with actions:

  • It should not be possible to change the payload after a dispatch. With mutable payloads (objects) and many stores listening to the same action, one accidental change of the payload will create a bug that'll take some time to track down.
  • It would be nice to know exactly what data a store expects without having to look through every single store that handles that action and looking through the code, to find out how the structure of the payload should look.
  • You can't search for a specific string to find everywhere that action is used

I propose the following:

module.exports = actionManager.create
    fetchUserArticles: null
    fetchUserArticlesSuccess: new Immutable.Record 
        userId: null, 
        items: Immutable.List()
    fetchUserArticlesFail: new Immutable.Record error: null

This would use the key in the action definition object as the unique string. That means the name for that action, has to be unique across all defined actions. Now you can actually search for that name across your entire code base. You know fetchUserArticles doesn't take a payload, and you'll get an error if you try. You know fetchUserArticlesSuccess takes a list of items and a userId, and you can't change any of them in your action handlers.

actionManager.create() would return an object, with the instantiated actions corresponding to each key. Just like it is now.

Further more we should require entity store's to have a Record defined. So each item has to satisfy that record. It could be nice to extend/wrap Immutable.Record so we can define nested properties and maybe even specify types as well.

Store::set and friends deep clone the properties set is a bit of an issue

Ie. I want to store a React component in my store and now my entire component is borked.

Could a different strategy perhaps instead be to utilize the react immutability helpers and then add a guideline that says that you cannot alter what is stored inside the store after a store? It seems a bit odd that my data gets altered just because I want to store it in my store.

Optimize add() in ListStore and IndexedListStore

The problem: in an action handler for an indexed list store i might add items this way:

@add data.index, id for id in data.ids

This will create a new list in each iteration, which is terrible for performance. Instead if we automatically duplicated the stores @_properties as a mutable temporary value within an action handler, we could avoid the cost of creating all these temporary immutable's. Another option is to add a withMutations method to the store, to reflect the ImmutableJS API.

Add something like putItems to EntityStore

It would be nice to have a method for adding/updating an array of items on an EntityStore. E.g.

putItems: (items) ->
    newItems = items.reduce (map, item) ->
        map.set item.get('id'), item
    , @getRawItems()
    @setItems newItems

remove get() and getIn() from the store's interface object

When switching to immutable-js, we found several places in our code where a store might dereference an object by using another content store, this is pretty hard to do and ends up being ugly (too magical) if done in get() and getIn(). This way the user is forced to implement property accessors which can then properly handle the data. Takes a little extra time but pays off when refactoring. Breaks backwards compatibility.

Transactional boundaries for changed events on stores.

When a store dispatches a changed event, don't dispatch it till the end of the loop. This way we avoid meaningless computations in between state transitions, which in some cases can lead to inconsistent state and errors.

Ie. mark the store as changed instead of dispatching the event, and make the dispatcher handle the actual dispatching of the changed event. Furthermore, we need a seperate way to immediately know when related stores are changed, so the dependent stores can mark themselves as changed.

Proposal: Generalize ListStore and IndexedListStore

It would be very convenient to have types like SetStore and IndexedSetStore, for the many cases where you only want to store distinct values. Currently, you need to write all @add(id) in such situations as @add(id) unless @getKeys().contains(id) or likewise. Using immutable sets would presumably also have better performance characteristics.
One way to achieve this would be to generalize ListStore to CollectionStore and IndexedListStore to IndexedCollectionStore. These would then take an Immutable.js type, like Immutable.List or Immutable.Set. Maybe it will be enough to require an Immutable.Iterable, and have abstract methods for insertion/deletion.

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.