goatslacker / alt Goto Github PK
View Code? Open in Web Editor NEWIsomorphic flux implementation
Home Page: http://alt.js.org/
Isomorphic flux implementation
Home Page: http://alt.js.org/
Hello!
So, I noticed that in the Alt
class and in the Store
class, you use the normal JS pattern of objects-as-maps. Example would be here:
// from Alt class constructor
this.actions = {}
this.stores = {}
// from Store contstructor
this[LIFECYCLE] = {}
this[LISTENERS] = {}
The use of this
as an overloaded object-as-map seems central to a lot of the code, but for the examples I gave it's not as clear.
Why not use the ES6 Maps for this purpose?
I've looked through your examples, but I haven't found a way to populate a store with existing data. I see you set values in the constructor, but the values are always hard coded.
I'm interested in something like this:
class ProjectStore {
constructor(value) {
self.value = value
}
}
alt.createStore(ProjectStore, {foo: "Bar"})
Is this something that's planned, or is there a preferred way of achieving this same effect?
By the way, awesome job with Alt, I'm really liking it over some of the other Flux implementations I've tried!
I'm able to workaround the scope issue by creating a var outside the class, but it makes me feel dirty. Is there a cleaner way? I know the typical pattern is to call out to another module, which can then create the action as normal. Is there another way?
var self
class TestActions() {
action1() {
//do stuff, maybe talk to an API
self.action2()
}
}
self = alt.createActions(TestActions)
module.exports = self
On the newest version, 0.13.7, I am getting an error when using the listenTo()
function (when using the ListenerMixin
).
The error: Uncaught TypeError: Cannot read property 'bind' of undefined
It is being thrown on fn.bind(context)
here in the add
function:
var MIXIN_REGISTRY = '_alt store listener registry_'
var Subscribe = {
create: function (context) {
context[MIXIN_REGISTRY] = []
},
add: function (context, store, fn) {
var handler = fn.bind(context)
context[MIXIN_REGISTRY].push({ store: store, handler: handler })
store.listen(handler)
},
destroy: function (context) {
context[MIXIN_REGISTRY].forEach(function (x) {
x.store.unlisten(x.handler)
})
context[MIXIN_REGISTRY] = []
}
}
module.exports = Subscribe
I was making a new project when it happened and reverted back to 0.13.2 that I was using on previous projects and it works fine now.
Using saucelabs.com
Supported browsers are:
IE8+
Firefox ??+
Chrome ??+
Safari 5+
and Mobile browsers TBD.
Hi,
I have issue using alt + iso, it keeps throwing me:
TypeError: Cannot read property 'Symbol(1424950030126the state container)' of undefined
at /Users/iam4x/github/es6-react-boilerplate/node_modules/alt/dist/alt.js:224:32
at Array.forEach (native)
at setAppState (/Users/iam4x/github/es6-react-boilerplate/node_modules/alt/dist/alt.js:223:20)
at Alt.bootstrap (/Users/iam4x/github/es6-react-boilerplate/node_modules/alt/dist/alt.js:460:9)
at module.exports (/Users/iam4x/github/es6-react-boilerplate/server/server.router.jsx:14:7)
at Layer.handle [as handle_request] (/Users/iam4x/github/es6-react-boilerplate/node_modules/express/lib/router/layer.js:82:5)
at trim_prefix (/Users/iam4x/github/es6-react-boilerplate/node_modules/express/lib/router/index.js:302:13)
at /Users/iam4x/github/es6-react-boilerplate/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/Users/iam4x/github/es6-react-boilerplate/node_modules/express/lib/router/index.js:321:12)
at next (/Users/iam4x/github/es6-react-boilerplate/node_modules/express/lib/router/index.js:261:10)
And the example https://github.com/goatslacker/iso/tree/master/examples/react-router-flux is doing the same.
How can I help?
Hi, I'm just trying alt's flux instances feature - https://github.com/goatslacker/alt#flux-instances. Unfortunately there is a circular problem:
In order to create actions and stores I need an instance of Alt
class
ArticleActions.js
import flux from '../../flux'; // instance of alt is created here
class ArticleActions {
constructor() {
this.generateActions('requestArticles');
}
}
export default flux.createActions(ArticleActions);
But in order to create alt instance and register stores and actions I need them already created:
flux.js
import Alt from 'alt';
// all of them require this file
import RouterActions from './shared/actions/RouterActions';
import ArticleActions from './pages/actions/articles/ArticleActions';
import ArticleStore from './pages/actions/articles/ArticleStore';
class Flux extends Alt {
constructor() {
super();
// register flux actions and stores
this.addActions('router', RouterActions);
this.addActions('articles', ArticleActions);
this.addStore('articles', ArticleStore);
}
}
export default new Flux();
Original:
With DispatcherRecorder you can replay certain events in your application. It would be cool if there was a util that would allow you to timetravel through your application but also allow you to specify if you'd only like to time travel certain stores.
Update:
I've got a util that lets you TimeTravel through your entire application's state. It uses alt (very meta) for the time travel bit. You have a set of actions: revertTo
, revertStoreTo
, and destroyAll
which will revert to a specific point in time, revert a specific store to a point in time, or destroy all the stored events.
My only concerns at this point are with memory usage. This should probably use something like immutable or some cursors so we can keep memory usage pretty low.
I need help now fleshing out the rest of the API and most importantly if you've got feature requests then send them in :)
Open questions:
I was intrigued by the DispatcherRecorder
, so I went about trying build a debugging tool that would take a snapshot and then record some actions. I would like to be able to serialize the snapshot and events so they could be shared and replayed later or on another machine.
However, in order for this to work, I have to modify this line to use Symbol.for()
instead of Symbol()
so that I can replay the events after unserializing.
I see why you're not using Symbol.for
to avoid conflicts in action classes/names, but I think it could be useful to provide a way to use Symbol.for
.
I'm imagining something like:
const alt = new Alt({ exposeActions : true });
or for each action class
class MyActions { ... }
alt.createActions(MyActions, exports, { expose : true });
Perhaps there's another way to achieve this without modifying alt. Here's my work-in-progress (apologies for the spaghetti code -- it's getting a bit late for me).
I did not notice that there were several other mixins available (other than the ListenerMixin
) until I was going through the source code. Some have helpful inline docs, but a Mixin section in the README would be very helpful in acquainting users with what is available and a quick example of usage.
So I'm trying to follow your example of:
alt.createStore(class MyStore {
constructor() {
this.dispatcher.register(console.log)
}
})
My alt looks like this:
import Alt from 'alt';
var altFlux = new Alt();
export default altFlux;
My store looks like this:
import altFlux from '../altFlux';
import AlertMessageActions from '../actions/AlertMessageActions';
import UserDataActions from '../actions/UserDataActions';
class AlertMessageStore {
constructor() {
this.dispatcher.register(console.log);
this.bindActions(AlertMessageActions);
this.bindAction(UserDataActions.receiveUserDataError, this.onReceiveAlertError);
this.message = null;
this.alertLevel = null;
this.error = null;
this.alertVisible = false;
this.dismissAfter = null;
}
onReceiveAlertSuccess(msg) {
this._initGenericAlert('success', msg);
}
onReceiveAlertError(msg) {
console.log('GOT AN ERR!');
this._initErrorAlert(msg);
}
_initGenericAlert(lvl, msg) {
this.alertLevel = lvl;
this.message = msg;
this.error = false;
this.alertVisible = true;
this.dismissAfter = 15000;
}
_initErrorAlert(msg) {
this.alertLevel = 'danger';
this.message = msg;
this.error = true;
this.alertVisible = true;
this.dismissAfter = null;
}
}
export default altFlux.createStore(AlertMessageStore);
My action:
import altFlux from '../altFlux';
import UserDataAPI from '../utils/api/UserDataAPI';
import ErrorToJSON from '../utils/serializers/ErrorToJSON';
class UserDataActions {
constructor() {
this.generateActions(
'receiveUserData',
'receiveUserDataError'
);
}
getUserData(params = { useCache: true }) {
this.dispatch();
let localData = UserDataAPI.getLocalUserData();
if (localData && params.useCache) {
this.actions.receiveUserData(localData);
} else {
UserDataAPI.getUserData().then((res) => {
this.actions.receiveUserData(res.body.data);
}).catch((err) => {
let error = ErrorToJSON.superagent(err);
this.actions.receiveUserDataError(error);
});
}
}
}
export default altFlux.createActions(UserDataActions);
My view:
import React from 'react';
import { Jumbotron, Button, ButtonToolbar, ModalTrigger } from 'react-bootstrap';
import NewUserHelpModal from './NewUserHelpModal';
import UserDataActions from '../../actions/UserDataActions';
var NewUserMessage = React.createClass({
componentWillReceiveProps(nextProps) {
},
componentDidUpdate(prevProps, prevState) {
console.log('not ready!');
},
_fetchUserData() {
UserDataActions.getUserData({ useCache: false });
},
render() {
return (
<Button bsStyle='success' onClick={this._fetchUserData}>Fetch User Data</Button>
)
}
However, when I click the button to trigger the action, in my console log I get:
Uncaught TypeError: Illegal invocation
Dispatcher.prototype.$Dispatcher_invokeCallback=function(id) {
this.$Dispatcher_isPending[id] = true;
this.$Dispatcher_callbacks[id](this.$Dispatcher_pendingPayload);
this.$Dispatcher_isHandled[id] = true;
};
this.$Dispatcher_callbacks[id](this.$Dispatcher_pendingPayload);
My intention is when the user clicks the button, it calls the UserDataActions.getUserData
and then if it fails, the error is sent to the AlertMessageStore
.
Removing the line this.dispatcher.register(console.log)
, and everything works OK. Any ideas? Am I missing something?
I was looking at the chat example and the pattern of an action calling the webapi which then calls another action after receiving the response from the API. If the web API wants to call an action from the same class as the original action, it results in a circular dependency with the require modules:
ActionClass -> requires WebAPI -> requires ActionClass
Any thoughts on how to structure this better?
This would settle the "how to do async" debate.
I wouldn't want this in core but I'm sure some of core would have to change so this can be supported first-class.
This util can be flexible so async can exists in actions or in stores or it can have a strict opinion.
Perhaps several interfaces can be included so this can all be hooked up easily with popular cloud butt based systems
This looks like a major issue.
I have 2 actions creator classes with same actions generated. These actions receive different data:
// MatchActions.js
export default class MatchActions {
constructor() {
this.generateActions('receiveLeagues');
}
}
// MyClubActions.js
export default class MyClubActions {
constructor() {
this.generateActions('receiveLeagues');
}
}
Both of them are added via Flux instances:
class Flux extends Alt {
constructor() {
super();
this.addActions('matches', MatchActions);
this.addStore('matches', MatchStore);
this.addActions('myclub', MyClubActions);
this.addStore('myclub', MyClubStore);
}
}
The problem is that listen methods of both stores are fired:
// MyClubStore.js
constructor() {
let myClubActions = this.alt.getActions('myclub');
this.bindActions(myClubActions);
}
onReceiveLeagues(leagues) {
// is fired on Match actions as well..
console.log(leagues);
}
// MatchStore.js
constructor() {
let matchActions = this.alt.getActions('matches');
this.bindActions(matchActions);
}
onReceiveLeagues(leagues) {
// is fired on MyClub actions as well..
console.log(leagues);
}
From a Login react component, I have a login action that makes an API request and on successful response, it updates a SessionStore. The Login component sees the value of the session store updated through it's props passed down from the parent component, and in shouldComponentUpdate, it does a transitionTo (using react-router) to an account page. The account page then calls an action to update the SessionStore in ComponentWillMount.
I'm getting this error message:
Uncaught Error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
I believe it's due to the account page trying to update the SessionStore as the result of the SessionStore just getting updated from a previous action. Any suggestions on how to architect this differently?
NOTE: things work when using react-router's HashLocation, but not with the HistoryLocation.
What should the example app be?
I wouldn't like to do a TodoList. Already beaten to death.
The chat is already available as an example.
Email client, perhaps. But there are examples already out there.
Github search? Perhaps, but it's a bit narrow.
HN client. Also probably narrow.
RSS reader?
Music player?
A game?
Ideally this example app would:
waitFor
What do you think about adding store mixins? Mixins would be able to add bindings to actions, and define the functions they get bound to. There would also need to be a way to pass information into the mixins from the store. Although, this could also be achieved through a sort of Mixin Generator.
I've got a certain bit of functionality that I'm having to clone to pretty much every Store I have. It pertains to listing for an action that fires when the app gets new data from a websocket. It needs to grab the data out of the object at the key that matches the store's name TaskStore would grab "tasks", etc. So the mixin would need to be able to get that unique "data_key" that it needs to look for in it's action handler.
Does this sound like a good idea? Or would it be better to just leave it to the user to implement mixins if they need it?
Hey, it would be nice to hear your point of view on the following.
I am using Alt
inside isomorphic app which uses alt's flux instances feature. Currently my actions that deal with API look like:
import { getStats } from '../../../webAPIUtils';
export default class MatchDetailActions {
constructor() {
this.generateActions('receiveStats', 'failReceiveStats');
}
requestStats(requestOptions) {
this.dispatch(requestOptions);
// method just calls superagent with necessary url
getStats(requestOptions, function (err, stats) {
if (err) {
this.actions.failReceiveStats(err);
return;
}
this.actions.receiveStats(stats); // calling actions inside action (bad?)
}.bind(this));
}
}
As you see I'm calling success/error actions inside the initial request action which is considered an anti-pattern. But this allows me to call such actions on the server side without worrying how to pass the flux instance created by request inside web api utils.
What is your approach in similar situation?
This is just to openly discuss any ideas on where you'd like to take alt or what you'd like to do with it. Perhaps actionable tasks can come out of this discussion.
Currently rollback only works if you've recently taken a snapshot. Perhaps there can be a way to enable automatic rollbacks in case something goes wrong. Ideally this would add minimal code.
Have tried including the ListenerMixin, FluxyMixin, and ReactStateMagicMixin, all of which throw the following messages in React v0.12.2:
bind(): You are binding a component method to the component. React does this for you automatically in a high-performance way, so you can safely remove this call. See Header
ReactCompositeComponent.js?cd59:1324 bind(): You are binding a component method to the component. React does this for you automatically in a high-performance way, so you can safely remove this call. See IndexRoute
ReactCompositeComponent.js?cd59:1324 bind(): You are binding a component method to the component. React does this for you automatically in a high-performance way, so you can safely remove this call. See App
These are caused by line 13 of alt/mixins/Subscribe.js
.
add: function (context, store, fn) {
if (!context[MIXIN_REGISTRY]) {
Subscribe.create(context)
}
//
var handler = fn.bind(context) // React v0.12.2 does not like this line.
//
context[MIXIN_REGISTRY].push({ store: store, handler: handler })
store.listen(handler)
},
Important to note that nothing actually breaks, but the messages will turn into a nasty error message saying that there are issues and the unminified code should be inspected when run in production.
Is there any way to send another action as part of the handling of another action inside a store? And maybe this is more of a 'this isn't the flux way' question, but I'm having trouble trying to google for anybody trying to do this sort of thing.
So here's my setup. I'm essentially making a bejeweled clone, and I'm trying to get the cascading clears to work using flux actions. I have a swapTile action, but after every time the board changes as a result of this action, I need to check if any other clears should be happening. I tried sending another action from inside the first swapTile action, but it just hangs. From what I understand (granted this is limited), this is to be expected from the way the dispatcher works.
I had the thought of essentially having the store save some data which would essentially tell the view to trigger the second cascade event, but I'm not sure I really like the fact that the Store (where most of this logic should live) relies on the view to send the next event(s). Is this the only way to do this? Or is there a more flux-y way to do this sort of thing?
You are currently unable to call a store static method from within another static method using this
. This can be limiting in some cases, and the workarounds are ugly. I realize there might be some design challenges, but I'd love to be able to do, e.g.:
static foo(a1) { return this.getState().foo[a1]; }
static bar() { return this.foo('baz'); }
Developer tool (Chrome first) for using Alt.
You can help by discussing things you want to see in it and by contributing that code.
Hey,
I just started using webpack, and it spits out this warning when building:
WARNING in ./
/alt/dist/alt.js/alt/dist/alt.js 3:434-441
Critical dependencies:
3:434-441 This seem to be a pre-built javascript file. Even while this is possible, it's not recommended. Try to require to orginal source to get better results.
@ ./
Not sure if it is a webpack issue, or an alt
issue. I havn't noticed any problems so far, but since it's the only warninig it would be nice to get it fixed ๐
Contributing guide featuring:
How to get setup.
Pull request style.
Code style.
Is it possible to add own properties to the state, if it is managed by the ReactStateMagicMixin? Or should be everything put into stores?
Maybe the need for additional properties also means that one should refactor the component? I'm not sure about this. Would be interested in hearing some opinions.
Hey there,
I am interested in using alt for my current project and at the same time have decided to not use ES6, are there any ES5 examples of using Alt?
Thanks.
WARN: Dropping unused function argument exports [-:1,437]
WARN: Dropping unused function argument module [-:1,430]
I get like a 100 of these warnings when I run the command "npm run build" (obviously I run this only after installing the dependencies) for the chat example. Have any idea of what's going wrong?
I think snapshotting functionality isn't that usable on the client, because snapshots usually should be done at predefined moments in app lifecycle. In Flux this is usually after some action(s) completed. But I wasn't able to find proper hook in the Alt
. It could be better if we could use it like:
alt.actionDispatched = (action) => {
...
}
Or something like this.
actionDispatched
should be called after Dispatcher.dispatch(...)
method completes.
One more question for you.
I'm trying to server-render my Alt-based Flux application, that's very rough example of what I'm doing on server request:
var React = require('react');
var Router = require('react-router');
var routes = require('./src/routes.jsx');
var webAPIUtils = require('./src/webAPIUtils');
app.use('/', function (req, res, next) {
var flux = require('./src/flux');
webAPIUtils.getFeeds(function (err, feeds) {
if (err) {
return next(err);
}
flux.getActions('articles').receiveFeeds(feeds); // sync action
Router.run(routes, req.url, function (Handler) {
var content = React.renderToString(React.createElement(Handler, {flux: flux}));
res.render('base', {
title: title,
content: content,
mainJs: mainJs,
mainCss: mainCss
});
});
});
});
That's client:
import 'babelify/polyfill';
import 'es5-shim';
import 'es5-shim/es5-sham';
import React from 'react';
import router from './router';
import flux from './flux';
window.React = React;
React.initializeTouchEvents(true);
router.run((Handler, state) => {
flux.getActions('router').routeChange(state);
React.render(
React.createElement(Handler, { flux }),
document.getElementById('android-hybrid-app')
);
});
and how flux.js looks like:
import Alt from 'alt';
import RouterActions from './shared/actions/RouterActions';
import ArticleActions from './pages/articles/ArticleActions';
import ArticleStore from './pages/articles/ArticleStore';
class Flux extends Alt {
constructor() {
super();
// register flux actions and stores
this.addActions('router', RouterActions);
this.addActions('articles', ArticleActions);
this.addStore('articles', ArticleStore);
}
}
export default new Flux();
But unfortunately ArticleStore on client doesn't contain the result of action which was fired on server.
How do I implement asynchronous? like this:
var alt = new Alt;
var Actions = alt.createActions(class {
constructor() {
this.generateActions('doSomething');
}
});
var Store = alt.createStore(class Store {
constructor() {
this.bindAction(Actions.doSomething, this.doSomething);
}
doSomething() {
this.done = false;
setTimeout(() => {
this.done = true;
}, 1000);
}
});
Store.listen((data) => {
console.log(data);
});
Actions.doSomething();
The example output to the console only this:
{ done: false }
Using alt with react-hot-loader
loader in webpack, throw me random errors:
Cannot not apply hot update to users.jsx: A store named UserStore already exists, double check your store names or pass in your own custom identifier for each store
I couldn't find what isn't working, went through this issue: moreartyjs/todomvc-moreartyjs#2
Maybe something with the context?
Is there a way to emit a change from within a store? I'll give you an example where this would be helpful:
class TaskStore
constructor: ->
@bindActions(App.Actions)
@collection = []
onSearch: (query) ->
$.ajax
url: '/search/tasks'
method: 'get'
dataType: 'json'
data: {q: query}
success: (results) =>
@collection = @collection + results
# currently not possible
# @emitChange()
# what I have to do instead is access the store from "outside"
App.Stores.TaskStore.emitChange()
false # prevent the default change emit, because nothing has changed until the success callback fires
App.Stores.TaskStore = alt.createStore(TaskStore)
So as you can see, my action runs and triggers an ajax call. The state of the store will not have changed until the ajax call completes. It would be great to be able to emit a change from within that success callback. What do you think?
makeFinalStore
DispatcherRecorder
these need in file documentation on how to use them.
Alt by design implicitly makes class methods immutable/private to everything but actions. This keeps the flow unidirectional. However, alt provides an exception to this functionality by using static
methods. When a method is declared static
, alt magically adds the method to the object returned from alt.createStore()
, giving public
access to the method. This behavior is strange, confusing, and twists the expected behavior of the static
method type. static
methods are meant to be properties of an object, not the properties of an object's instance.
A better solution is to use a mixin that provides the ability to explicity state which methods of a class should be made public in the resultant altStore instance. See PR #66.
I propose this static
method support be dropped from alt and replaced by something akin to what is described above.
There should be a util that hooks into Alt's lifecycle methods to automatically serialize and deserialize any immutablejs props you have defined in the store.
Perhaps this can be useful.
I'm using React 0.13-rc and writing the components in ES6
The problem is that when the callback method is bound to this
in both the listen and unlisten calls the event isn't removed in the "removeListener". So next time the component loads the callback is added again, then again, and...
class MyComponent extends React.Component {
componentDidMount () {
MyStore.listen(this.onStoreChange.bind(this));
}
componentWillUnmount () {
MyStore.unlisten(this.onStoreChange.bind(this));
}
onStoreChange () {
// Event "change" is not removed so on next "onStoreChange"
// it will be called 2, then 3, 4.... Because it was added again in the
// componentDidMount method
}
}
class MyComponent extends React.Component {
componentDidMount () {
MyStore.listen(this.onStoreChange);
}
componentWillUnmount () {
MyStore.unlisten(this.onStoreChange);
}
onStoreChange () {
// This works but "this" is the wrong context so no `this.setState()`
}
}
Any ideas? I'm not really sure why this would be a problem. I'll look into it but hopefully this is something easy and I'm missing something ;)
P.S. Great work! Im loving Alt (used reflux) and tried all the others
Similar issue that you've been working on. Things were working for me with 0.13.9, but with .10 that array creation issue seems to have shifted over to the Subscribe.js mixin. I get: Cannot read property 'push' of undefined
.
Looking through the code, I see where you call add
on the subscribe mixin from within the listener mixin, but I don't see where the create
method was called.
Although we're not in strict semver territory just yet I still want to keep a changelog. This issue is so I can add a changelog to all the previous releases.
The Store class inheritance doesn't work:
class BaseStore {
static doSomethingOnBase() {
console.log('doSomethingOnBase()');
this.emitChange();
}
};
class Store extends BaseStore {
static doSomething() {
console.log('doSomething()');
this.emitChange();
}
}
var storeInstance = alt.createStore(Store);
storeInstance.listen(() => {
console.log('Triggered.');
});
console.log(BaseStore.doSomethingOnBase);
storeInstance.doSomething();
storeInstance.doSomethingOnBase();
BaseStore.doSomethingOnBase
still exists but storeInstance.doSomethingOnBase
is undefined.
This mixin can use something like react-resolver perhaps.
The idea would be that you define data fetching at the component level somehow and the data is fetched and loaded into said store.
If I have a store like this:
module.exports = alt.createStore(class SomeStore {
constructor() {
this.bindActions(SomeActions);
}
onSomeAction(parameter) {
// Code to test...
}
});
How would I test onSomeAction()
?
I can't find a way to call this method from the test as it is not accessible from the outside. I also tried calling SomeActions.someAction()
from the test, but onSomeAction()
didn't end up being called.
What is the recommended way of doing this?
Currently the waitFor
method is pretty much the same as the stock Facebook one:
this.waitFor([ AStore.dispatchToken, OtherStore.dispatchToken ])
I'd like to make the dispatcher entirely an implementation detail. The waitFor
method can extract the dispatcherToken
s itself.
To me, this reads much nicer:
this.waitFor( AStore, OtherStore)
Or, if you feel strongly about passing an array instead of iterating the arguments:
this.waitFor([ AStore, OtherStore ])
What do you think? I'd be happy to create a PR if it's something you think fits with alt's vision of Flux.
Would be nice to see a more complex/realistic example using alt. Showing:
Basically a full app.
Is there perhaps such an example for one of the other flux libs that would easily translate to alt?
Right now takeSnapshot takes the entire application snapshot. It would be nice if you could take a snapshot of a subset of your application.
Alt looks like it's got a lot of good ideas on improving Flux.
The README talks about store immutability, but I don't see much pertaining to that in the code, nor do I see dependencies on e.g. Immutable.js or mori
.
Could you elaborate a bit on this?
Need examples on testing stores with various frameworks: jest, jasmine, qunit, etc.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.