Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define and create Application State #118

Open
chrisinajar opened this issue Feb 28, 2016 · 2 comments
Open

Define and create Application State #118

chrisinajar opened this issue Feb 28, 2016 · 2 comments
Labels
0.4 updates for @fabric/core

Comments

@chrisinajar
Copy link
Collaborator

As per #117, we need an Application State layer in the Maki stack.

This is the state of the instanced application being run by an Identity. The state can be any arbitrary tree of values, all of which are observable and evented. You can bind any attribute or sub-tree to an addressable object from the Data Layer which then synchronizes two way using the events from either layer.

Discuss libraries and techniques to use, as well as the rigid interfaces in which it communicates.

@chrisinajar
Copy link
Collaborator Author

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.

@chrisinajar
Copy link
Collaborator Author

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.

Root App

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))
  });
}

Posts

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));
}

Comment

module.exports = Comment;

function Comment(data) {
  return ObservStruct({
    body: Observ(data.body)
  })
}

Settings

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);
}

What this results in

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);

@martindale martindale added this to the 0.4: Implementation milestone Aug 13, 2018
@martindale martindale added the 0.4 updates for @fabric/core label Jan 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.4 updates for @fabric/core
Projects
None yet
Development

No branches or pull requests

2 participants