Skip to content

Instantly share code, notes, and snippets.

@bryanbraun
Last active September 1, 2019 02:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryanbraun/a5782ca8aed8283a1c2a99d92f58744f to your computer and use it in GitHub Desktop.
Save bryanbraun/a5782ca8aed8283a1c2a99d92f58744f to your computer and use it in GitHub Desktop.
Alt React - Core files
export class Store {
constructor(initialState) {
this.events = {};
this.state = initialState || {};
}
/**
* setState works like a simplified version of lodash's _.set(),
* only it sets this.state instead of an arbitrary object.
*
* Usage example: setState('city.street[0].color', 'brown');
*/
setState(propertyString, value) {
// This Regex was borrowed from https://github.com/lodash/lodash/blob/4.17.15-es/_stringToPath.js
const propertyNameMatcher = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
const propertyArray = [];
// Split our propertyString into an array of values
propertyString.replace(propertyNameMatcher, (match, number) => {
propertyArray.push(number || match);
});
// Use the propertyArray to traverse our state object and set the value.
propertyArray.reduce((accumulator, currentVal, index, array) => {
if (index + 1 === array.length) {
accumulator[currentVal] = value; // Set our property!
return true;
}
return accumulator && accumulator[currentVal] ? accumulator[currentVal] : null;
}, this.state);
this.publish('state', this.state); // Announce that 'state' was updated.
this.publish(propertyString, value); // Announce the specific property that was updated.
}
publish(event, data = {}) {
if (!this.events.hasOwnProperty(event)) {
return [];
}
return this.events[event].map(callback => callback(data));
}
subscribe(event, callback) {
if (!this.events.hasOwnProperty(event)) {
this.events[event] = [];
}
return this.events[event].push(callback);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment