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

Implement ImmutableStore (and create js-data-immutable) #57

Open
SimonDegraeve opened this issue Feb 21, 2015 · 20 comments
Open

Implement ImmutableStore (and create js-data-immutable) #57

SimonDegraeve opened this issue Feb 21, 2015 · 20 comments

Comments

@SimonDegraeve
Copy link

I am considering this lib for storing my data in a React app. One of my requirement is to use immutable data for fast comparison. But I don't know if it is possible to do so with a custom adapter since adapters are plugged to the central memory store which cannot manage immutable date itself.
Am I wrong? Should I try do hack into it or do you think the built-in "identity mapping" should be enough?

@jmdobry
Copy link
Member

jmdobry commented Feb 21, 2015

I don't have much experience with React, but it's been on my todo list to investigate how well js-data plays with the Flux architecture, specifically the immutable data and dispatcher stuff. I myself am wondering if js-data can work with React as is or if a React js-data wrapper needs to be written (js-data-react), similar to how there is js-data-angular for using js-data with Angular.

I can't fully answer your question until I do more research. I would have to build a react app myself and see how it integrates with js-data. @mzabriskie spoke to me about using React with js-data, but I don't know what came of it.

I'm in the process of creating example apps that show how to use js-data with various frameworks and adapters, so I'll make it a point to work on a React example next in order to figure this out.

@SimonDegraeve
Copy link
Author

I myself am wondering if js-data can work with React as is...

I don't see why it would not work, I think it is just about the pattern not the technology since React doesn't make any assumptions about your data... But the immutable part indeed, need to be digged.

And second thought, I cannot rely on "identity mapping" since I need to detect if there is change to re-render, if objects are equal cannot trigger.... I will experiment to transform the data to immutable after got them from the store... do know yet the perf impact.

But one point you might consider about the store (if it can manage immutable data) is that we can get all the benefits of lazyness when filtering, finding, etc...

@jmdobry
Copy link
Member

jmdobry commented Feb 21, 2015

I need to detect if there is change

js-data keeps track of a lastModified timestamp for every item in the store as well as a timestamp for each collection as whole. The individual item timestamps change whenever Object.observe (or polyfill) fires for that object. The timestamp for the collection changes whenever the timestamp for any item in the collection changes.

In Angular it's trivial to use a $scope.$watch to watch these timestamps as your "change" event and have it automatically update the view at that time. I don't know if React has a similar capacity to "watch" these timestamps. A js-data-react wrapper might be the kind of thing that could translate these changing timestamps (really just the "change" event) into an actual change event that can be subscribed to.

If you're only ever going to change items in the store by just injecting new items (which happens at the end of a findAll, for example), then the afterInject hook would be a perfect place to fire a "change" event that can be subscribed to. The resource definitions themselves can act as an event bus, as they have event functionality mixed into them.

In pseudo-react code, maybe something like this:

var store = new JSData.DS();
store.registerAdapter('http', new DSHttpAdapter(), { default: true });

var TodoStore = store.defineResource({
  name: 'todo',
  afterInject: function () {
    TodoStore.emit('change');
  }
});

var TodoApp = React.createClass({
  getInitialState: function() {
    return {
      // use getAll for maximum speed
      allTodos: TodoStore.getAll()
    };
  },
  componentDidMount: function() {
    TodoStore.on('change', this._onChange);
  },
  componentWillUnmount: function() {
    TodoStore.off('change', this._onChange);
  },
  _onChange: function() {
    this.setState({
      allTodos: TodoStore.getAll()
    });
  }
  // ...
});

If you modify data using the dot operator, i.e. todo.foo = 'bar', then we either need a way to fire a change event when the timestamp changes or modify js-data to fire a change event whenever Object.observe fires.

EDIT: fixed code

@jmdobry
Copy link
Member

jmdobry commented Feb 23, 2015

@SimonDegraeve Were you able to give my example a try?

@SimonDegraeve
Copy link
Author

Not yet unfortunately...

@mzabriskie
Copy link

I haven't had a chance to use js-data with React yet. Every React project I've been on has already had something in place. I don't see any reason why js-data wouldn't play nicely with React. Heck, on one project I'm on we're using Ember data with React. As for immutability, I would need to play around with it before I could answer.

@jmdobry
Copy link
Member

jmdobry commented Mar 4, 2015

@mzabriskie @SimonDegraeve I made a demo app that uses js-data js-data-firebase React. Disclaimer: I have no idea what I'm doing when it comes to React.

@jmdobry jmdobry added the v2 label Apr 7, 2015
@jmdobry jmdobry added this to the 2.0.0 milestone May 27, 2015
@jmdobry
Copy link
Member

jmdobry commented Jun 10, 2015

I know a little bit better now what I'm doing with React, so here's an example project that uses React js-data to great effect: https://github.com/jmdobry/RequelPro/tree/master/src/RequelPro

@jmdobry jmdobry removed the v2 label Jul 2, 2015
@jmdobry
Copy link
Member

jmdobry commented Jul 9, 2015

Playing around with this idea here: https://github.com/js-data/js-data/tree/swappable-store

Most of the tests pass even when using ImmutableJS as the internal in-memory store. Need to figure out what to do about js-data's change detection. Turn it off?

@udfalkso
Copy link

Have you put any more thought into an immutable version of the store? I'd love use js-data along with react-native/redux, but it seems incompatible as is. In particular with Redux, there would ideally be a simple way to serialize the models/store.

@elado
Copy link

elado commented Nov 25, 2015

Sounds like it can be achieved with another adapter, no? A new adapter can own one root object, { modelName1: { id1: {}, id2: {} }, modelName2: { id20: {}, id21: {} } }.
Then, all methods (create/inject etc) change it.
If multiple adapter are supported it can be combined with the other adapters too.

@jmdobry
Copy link
Member

jmdobry commented Nov 25, 2015

Yeah, something like this might work

@jmdobry
Copy link
Member

jmdobry commented Feb 21, 2016

v3 is much more flexible, with functionality split into various components. This makes it much easier to create say, an ImmutableStore class as an alternative to v3's DataStore class, which is an Identity Map. Once I've released v3 itself, I will explore creating a js-data-immutable project.

@yrik
Copy link

yrik commented Mar 6, 2016

also interested in it..

@jmdobry
Copy link
Member

jmdobry commented Apr 6, 2016

I'm changing this issue's scope to:

Create a js-data-immutable project which would essentially be:

import {Container} from 'js-data'
import Immutable from 'immutable'

export default Container.extend({
  constructor: function ImmutableStore (...) {
    // TODO: implement
  },
  // TODO: implement
})

Then you your app:

import ImmutableStore from 'js-data-immutable'

const store = new ImmutableStore(...)

// ...

@jmdobry jmdobry added the backlog label Apr 6, 2016
@jmdobry jmdobry removed this from the 3.0 milestone Apr 6, 2016
@jmdobry jmdobry changed the title Is it possible to handle immutable data in the store? Implement ImmutableStore (and create js-data-immutable) Apr 6, 2016
@jmdobry jmdobry added this to the 3.x Future milestone Jul 2, 2016
@AlexandreBonaventure
Copy link

Hey folks, I published a package to make jsdata work along vuex as a vuex plugin (redux-style store for vue.js) : https://www.npmjs.com/package/vuex-plugin-jsdata
I hope it will help some of you. Cheers

@jmdobry
Copy link
Member

jmdobry commented Oct 5, 2016

@AlexandreBonaventure That's really cool! I was just talking with @yyx990803 about creating something like this a couple weeks ago at UtahJS Conf!

@tribou
Copy link

tribou commented Oct 24, 2016

@jmdobry I'm completely new to js-data, but I've been looking for a good solution to use ImmutableJS-based models for a Google Cloud Datastore project. Would your proposal above enable this?

To help me get a better perspective, if this was implemented, would the js-data model give me access to the Immutable collection API, or would it just be using Immutable under the hood?

@jmdobry
Copy link
Member

jmdobry commented Oct 24, 2016

@tribou I can't give a definitive answer just yet. I would need to familiarize myself with ImmutableJS and actually take a crack at implementing js-data-immutable before I knew.

p.s. We also have js-data-cloud-datastore, don't know if you've seen that.

@r14c
Copy link

r14c commented Dec 12, 2017

@AlexandreBonaventure @jmdobry we are taking a slightly different approach with vdata, which is more similar to graphQL than redux. nice to see other vue.js js-data people around!

i still have some benchmarking to do, but i'm hoping that we can use the structural sharing in seamless-immutable to improve the performance of some of the patterns that we use. it isn't a huge bottleneck, but i'd like to use as little memory and cpu as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants