Spraypaint the isomorphic, framework-agnostic Graphiti ORM

State Syncing

You may have encountered state management libraries like Flux, Redux or Vuex. These are fantastic libraries, but their usefulness is lessened with Spraypaint. As a full-fledged model layer, Spraypaint manages state for you, automatically.

If you opt-in to this feature:

ApplicationRecord.sync = true

Instances will sync up whenever the server tells us about updated state. Consider the scenario where an instance is initially loaded, then separately polled in the background:

Typescript
Javascript
  let person = (await Person.find(1)).data

  let poll = () => {
    await Person.find(1)
    setTimeout(poll, 1000)
  }
  poll()
  
  Person.find(1).then(function(response) {
    var person = response.data;
  });

  var poll = function() {
    Person.find(1);
    setTimeout(poll, 1000);
  }
  poll()
  

Note that our poll() function never assigns or updates person. But if the server returns an updated name attribute, person.name will be automatically updated. This is true even if person.name is bound in 17 different nested components.

Instances can still update their attributes independently - we only sync when the server returns updated data:

Typescript
Javascript
  let instanceA = (await Person.find(1)).data
  let instanceB = (await Person.find(1)).data

  instanceA.name // "Jane"
  instanceB.name // "Jane"

  instanceB.name = "Silvia"
  instanceA.name // "Jane"
  instanceB.name // "Silvia"

  await instanceB.save()
  instanceA.name // "Silvia"
  instanceB.name // "Silvia"
  
  var instanceA, instanceB;
  Person.find(1).then(function(response) {
    instanceA = response.data;
  });
  Person.find(1).then(function(response) {
    instanceB = response.data;
  });

  instanceA.name // "Jane"
  instanceB.name // "Jane"

  instanceB.name = "Silvia"
  instanceA.name // "Jane"
  instanceB.name // "Silvia"

  instanceB.save().then(function() {
    instanceA.name // "Silvia"
    instanceB.name // "Silvia"
  });
  

Gotchas

Under the hood, instances are listening for updates from a central data store. This means that you’ll want to remove listeners whenever you no longer need the instance - otherwise it will never be garbage collected properly. To remove a listener:

instance.unlisten()

In practice, when developing in a SPA, you’ll want to #unlisten() whenever a view is destroyed and model instances no longer need to be referenced. If you are using VueJS, this is done automatically by adding spraypaint-vue to your application.