Open chrisinajar opened 8 years ago
I propose we use http://github.com/raynos/observ along with the array, struct, and assorted helper projects and http://github.com/bendrucker/dover for giving events access to the application state statelessly.
Components of the application can define their local state and event handlers like this
var state = Dover({
enabled: Observ(false),
channels: {
toggle: toggle
}
});
function toggle(state) {
state.enabled.set(!state.enabled());
}
and then the rendered state will contain the toggle
methods which will pass the state back in to the handlers. This can either be run as the handler itself for a UI event or called as part of one.
This makes the whole thing totally stateless with no need to actually expose a special Application State API to the UI components. It also defines static channels in which the state can be mutated from.
Example external API
Here's a little app with posts which have comments, and a modal settings window. I only show the includes for relative files and assume Observ, ObservStruct, ObservArray, and Dover all exist. This also doesn't show any of the data binding, only the schema definition of the Application State.
var Post = require('./post');
var Settings = require('./settings');
module.exports = App;
function App(initialState) {
return ObservStruct({
settings: Settings(initialState.settings)
posts: ObservArray((initialState.posts || initialState.posts = []).map(Post))
});
}
var Comment = require('./comment');
module.exports = Post;
function Post(data) {
return Dover({
title: Observ(data.title),
body: Observ(data.body),
comments: ObservArray(data.comments.map(Comment)),
channels: {
leaveComment: leaveComment
}
})
}
function leaveComment(state, data) {
state.comments.push(Comment(data));
}
module.exports = Comment;
function Comment(data) {
return ObservStruct({
body: Observ(data.body)
})
}
module.exports = Settings;
function Settings(data) {
return Dover({
modalVisible: Observ(false),
favoriteColor: Observ(data.favoriteColor)
channels: {
toggleModal: toggleModal,
changeFavoriteColor: changeFavoriteColor
}
});
}
// presumably from a UI event to open the modal
// the change events cause the UX and UI to update to show it
function toggleModal(state) {
state.modalVisible.set(!state.modalVisible());
}
// presumable from a UI event from inside the modal
function changeFavoriteColor(state, newColor) {
state.favoriteColor.set(newColor);
}
This code would not be in your maki app, but instead here to show how this layer will communicate with the UX
var App = require('./app');
var app = App();
// this is a JSON blob with all channels referencing usable javascript functions
var myCurrentState = app();
app(function() {
// This is a change event handler for something change in the app.
// In the Application State implementation, this is where I would grab
// a reference to the latest app() JSON and send it to the UX layer
});
// data binding would be implemented basically like this
// read in and set all changes from the network
myPostsDataStore.onChange(app.posts.set);
// whenever we edit the posts locally then we try to get the network to agree with our patch
app.posts(myPostsDataStore.proposeChange);
As per #117, we need an Application State layer in the Maki stack.
Discuss libraries and techniques to use, as well as the rigid interfaces in which it communicates.