choojs / choo-handbook

🚂✋📖 - Learn the choo framework through a set of exercises
https://handbook.choo.io
Other
268 stars 26 forks source link

vector clocks for choo v5 #61

Open yoshuawuyts opened 7 years ago

yoshuawuyts commented 7 years ago
03:25 <yoshuawuyts> oh super cool pattern for choo v5 btw: equality checks by creating a modified timestamp on individual items using an internal vector clock
03:25 <yoshuawuyts> will work real well for caching
03:26 <yoshuawuyts> (didn't come up with this btw, but yeah I just remembered discussing this last week)
03:27 <yoshuawuyts> e.g. rather than comparing properties on an object, you can check if the new timestamp on the incoming data is a newer version than the timestamp on the existing copy - if it's newer you re-render the element. If it's not you return the cached DOM node
03:28 <yoshuawuyts> circumvents creating new objects all the time just to satisfy triple equals checks, and removes the need to compare all properties
bcomnes commented 7 years ago

Whoa sounds neat. Any examples of this somewhere?

yoshuawuyts commented 7 years ago

@bcomnes not yet, but this is the gist I think:

// Each application gets a global clock that's updated on each "render" call to
// the current value of the unix timestamp (e.g. Date.now())

var state = {
  clock: Date.now(), // generated by window.performance.now() or Date.now()
  items: [ ]
}

// Whenever a value is created, we associate the current value of "clock" with
// it
state.items.push({
  id: 1,
  first: 'hello',
  second: 'world',
  timestamp: state.clock
})

state.items.push({
  id: 2,
  first: 'hello',
  second: 'planet',
  timestamp: state.clock
})

// Whenever emitter.emit('render') is called, we update the clock
state.clock = Date.now()

// Whenever an item is updated, we modify the timestamp
state.items[0] = {
  id: 1,
  first: 'hello',
  second: 'saturn',
  timestamp: state.clock
}

// Determining if data has changed now becomes constant time, is less prone to
// errors and decoupled from the shape of the data itself.
component.on('update', function (props) {
  return this.props.timestamp < props.timestamp
})