Skip to content

Instantly share code, notes, and snippets.

@MitMaro
Created February 2, 2015 17:19
Show Gist options
  • Save MitMaro/4f1cf7e56c0cb56c639c to your computer and use it in GitHub Desktop.
Save MitMaro/4f1cf7e56c0cb56c639c to your computer and use it in GitHub Desktop.
Fluxxor Local Storage
var localStorageActionCreator = function(flux, store) {
var _timerId = null;
// only way I can think to get the dispatcher into the timer actions
// which are not real actions
var _dispatch = flux.dispatchBinder.dispatch;
// force save every little bit in case this storage object doesn't get a chance
// to save
setInterval(_persistData, 60 * 1000);
// start write timeout when store changes and is dirty
store.on('change', function() {
if (store.isDirty()) {
_startWriteTimeout();
}
});
function _startWriteTimeout() {
clearTimeout(_timerId);
_timerId = setTimeout(_persistData, 1000);
}
function _persistData() {
// don't write if data is clean
if (!store.isDirty()) {
return;
}
_dispatch('LOCAL_STORAGE_PERSIST', {id: store.getId()});
this._localStorage.setItem(store.getId(), JSON.stringify({
state: store.getState(),
data: store.getData()
}));
_dispatch('LOCAL_STORAGE_PERSIST_SUCCESS', {id: store.getId()});
}
function loadData() {
var payload = JSON.parse(this._localStorage.getItem(store.getId()));
_dispatch('LOCAL_STORAGE_DATA', payload);
}
return {
persistData: _persistData,
loadData: loadData
};
};
module.exports = localStorageActionCreator;
var Fluxxor = require('fluxxor');
var spec = {
initialize: function(options) {
this._dirty = false;
this._persisting = false;
this._store = options.store;
this.bindActions(
'LOCAL_STORAGE_DATA', this._onLoad,
'LOCAL_STORAGE_PERSIST', this._onPersistStart,
'LOCAL_STORAGE_PERSIST_SUCCESS', this._onPersist
);
// link the local cache store with the data store
options.store.on('change', this._onDataChanged);
},
_onDataChanged: function() {
this._dirty = true;
this._committed = false;
this.emit('change');
},
_onLoad: function(payload) {
this._changeState({
dirty: false,
committed: payload.state.committed
});
},
_onPersistStart: function() {
this._changeState({
persisting: true
});
},
_onPersist: function() {
this._changeState({
dirty: false,
persisting: false
});
},
_changeState: function(payload) {
var changed = false;
if ('dirty' in payload && payload.dirty !== this._dirty) {
this._dirty = payload.dirty;
changed = true;
}
if ('persisting' in payload && payload.persisting !== this._persisting) {
this._persisting = payload.persisting;
changed = true;
}
if (changed) {
this.emit('change');
}
},
// the next two wouldn't be needed with a mixin
getId: function() {
return this._store.getId();
},
getData: function() {
return this._store.getData();
},
getState: function() {
return {
persisting: this._persisting,
dirty: this._dirty
};
},
isDirty: function() {
return this._dirty;
}
};
module.exports = Fluxxor.createStore(spec);
// example usage
var localCacheStore = new LocalStorageStore({store: store});
flux.addStore(store.getId() + '-localCache', localCacheStore);
var localActions = localStorageActionCreator(flux, localCacheStore);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment