strux
Version:
Cross-component communication finally made simple.
639 lines (492 loc) • 1.23 MB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _reactRouter = require('react-router');
var _jquery = require('jquery');
var _jquery2 = _interopRequireDefault(_jquery);
require('./state/strux-state');
var _layout = require('./layout/layout');
var _layout2 = _interopRequireDefault(_layout);
var _home = require('./components/home');
var _home2 = _interopRequireDefault(_home);
var _other = require('./components/other');
var _other2 = _interopRequireDefault(_other);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_reactDom2.default.render(_react2.default.createElement(
_reactRouter.Router,
{ history: _reactRouter.browserHistory },
_react2.default.createElement(
_reactRouter.Route,
{ path: '/', component: _layout2.default },
_react2.default.createElement(_reactRouter.IndexRedirect, { to: 'home' }),
_react2.default.createElement(_reactRouter.Route, { path: 'home', component: _home2.default }),
_react2.default.createElement(_reactRouter.Route, { path: 'other', component: _other2.default })
)
), (0, _jquery2.default)('#app')[0]);
},{"./components/home":2,"./components/other":3,"./layout/layout":4,"./state/strux-state":6,"jquery":11,"react":243,"react-dom":12,"react-router":42}],2:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _strux = require('../strux/strux');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Home = function (_Component) {
_inherits(Home, _Component);
function Home() {
_classCallCheck(this, Home);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Home).call(this));
_this.state = {
className: 'Home',
testVal1: 100,
testVal2: 200
};
window.homeComponent = _this;
return _this;
}
_createClass(Home, [{
key: 'componentDidMount',
value: function componentDidMount() {
var _this2 = this;
// Navigation should call componentTakesState and get 2 values in the diff.
console.log(this.state);
this.setState({
testVal1: 15,
testVal2: 3
});
// Navigation should call componentTakesState and get 1 value in the diff.
setTimeout(function () {
_this2.setState({
testVal1: 15,
testVal2: 2
});
});
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'home' },
this.state.testVal1,
' this is the Home View'
);
}
}]);
return Home;
}(_strux.Component);
exports.default = Home;
},{"../strux/strux":9,"react":243}],3:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _strux = require('../strux/strux');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Other = function (_Component) {
_inherits(Other, _Component);
function Other() {
_classCallCheck(this, Other);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Other).call(this));
_this.state = {
className: 'Other',
testVal1: 1,
testVal2: 2
};
window.otherComponent = _this;
return _this;
}
_createClass(Other, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.setState({
testVal1: 100
});
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'other' },
'Other View'
);
}
}]);
return Other;
}(_strux.Component);
exports.default = Other;
},{"../strux/strux":9,"react":243}],4:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _navigation = require('./navigation');
var _navigation2 = _interopRequireDefault(_navigation);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Layout = function (_Component) {
_inherits(Layout, _Component);
function Layout() {
_classCallCheck(this, Layout);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Layout).call(this));
_this.state = {
className: 'Navigation',
testVala: 'a',
testValb: 'b'
};
window.navComponent = _this;
return _this;
}
_createClass(Layout, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'layout' },
_react2.default.createElement(_navigation2.default, null),
this.props.children
);
}
}]);
return Layout;
}(_react.Component);
exports.default = Layout;
},{"./navigation":5,"react":243}],5:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _strux = require('../strux/strux');
var _reactRouter = require('react-router');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Navigation = function (_Component) {
_inherits(Navigation, _Component);
function Navigation() {
_classCallCheck(this, Navigation);
return _possibleConstructorReturn(this, Object.getPrototypeOf(Navigation).call(this));
}
_createClass(Navigation, [{
key: 'componentTakesState',
value: function componentTakesState(appState, classTrigger, diff) {
console.debug('Navigation reacted:', appState, classTrigger, diff);
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'navigation' },
'Navigation',
_react2.default.createElement(
'ul',
null,
_react2.default.createElement(
'li',
null,
_react2.default.createElement(
_reactRouter.Link,
{ to: '/', activeClassName: 'active' },
'Home'
)
),
_react2.default.createElement(
'li',
null,
_react2.default.createElement(
_reactRouter.Link,
{ to: '/other', activeClassName: 'active' },
'Other'
)
)
)
);
}
}]);
return Navigation;
}(_strux.Component);
exports.default = Navigation;
},{"../strux/strux":9,"react":243,"react-router":42}],6:[function(require,module,exports){
'use strict';
var _home = require('../components/home');
var _home2 = _interopRequireDefault(_home);
var _other = require('../components/other');
var _other2 = _interopRequireDefault(_other);
var _navigation = require('../layout/navigation');
var _navigation2 = _interopRequireDefault(_navigation);
var _strux = require('../strux/strux');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
window.store = _strux.store;
_navigation2.default.takesStateWhen({
Home: {
testVal1: function testVal1(newVal) {
return newVal > 10;
},
testVal2: function testVal2(newVal, oldVal) {
return newVal !== oldVal;
}
},
Other: {
testVal1: true
}
});
},{"../components/home":2,"../components/other":3,"../layout/navigation":5,"../strux/strux":9}],7:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
exports.default = reducer;
var _redux = require('redux');
var _utils = require('./utils');
var utils = _interopRequireWildcard(_utils);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
/**
* A reducer for our redux store.
*
* @param {Object} currentState Defaults to our originalState values.
* @param {Object} actionObject Contains data about the state change.
*
* @return {Object} Denotes the new application state.
*/
function reducer() {
var currentState = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var actionObject = arguments[1];
var _ret = function () {
switch (actionObject.type) {
/*
* When we detect a component state change, we want to make sure its
* values are reflected in the global state and that this change is
* tracked as our most recent change.
*/
case utils.STATE_CHANGE:
var newState = Object.assign({}, currentState);
var className = actionObject.className;
var oldVals = actionObject.oldVals;
var newVals = actionObject.newVals;
var update = void 0;
/*
* If the current state is not yet tracking values for the class
* in question, add all the values to the new state and mark them
* all as updated.
*/
if (!currentState[className]) {
newState[className] = newVals;
update = {};
utils.eachKey(newVals, function (val, key) {
return update[key] = [oldVals[key], val];
});
/*
* Otherwise, compare the current state with the new state and
* collect all the values that have changed.
*/
} else {
(function () {
var subState = newState[className];
update = {};
utils.eachKey(newVals, function (val, key) {
update[key] = [oldVals[key], val];
subState[key] = val;
});
})();
}
/*
* Mark which class triggered the most recent change.
* Also attach the update to that record.
*/
utils.mostRecentChange.className = className;
utils.mostRecentChange.update = update;
/*
* Update to the new state.
*/
return {
v: newState
};
default:
return {
v: currentState
};
}
}();
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
}
/*
* Create a redux store using our reducer.
*/
var store = (0, _redux.createStore)(reducer);
exports.default = store;
},{"./utils":8,"redux":249}],8:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.eachKey = eachKey;
exports.isFn = isFn;
exports.caresAboutChange = caresAboutChange;
/*
* connections {
* ObserverClassName: {
* ObservedClassName: {
* observedValueName: [ 'change'|'always', () => {} ]
* }
* }
* }
*/
var connections = exports.connections = {};
var mostRecentChange = exports.mostRecentChange = { className: null, update: null };
var STATE_CHANGE = exports.STATE_CHANGE = '_STATE_CHANGE';
/**
* Performs `forEach` over an object.
*
* @param {Object} object A key/value collection.
* @param {Function} callback The function to run on each pair.
*
* @return {undefined}
*/
function eachKey(object, callback) {
return Object.keys(object).forEach(function (key) {
return callback(object[key], key);
});
}
/**
* Determines whether a value is a function.
*
* @param {Any} val Any value.
*
* @return {Boolean} Whether or not `val` is a function.
*/
function isFn(val) {
return typeof val === 'function';
}
/**
* Determines whether or not an instance of a class cares about any
* changes that have recently occurred.
*
* @param {String} className The name of the class instance in question.
* @param {Object} recentChange Contains information about the most recent
* state change.
*
* @return {Object|undefined} The object contains all values that are
* cared about by the class instance.
*/
function caresAboutChange(className) {
var recentChange = arguments.length <= 1 || arguments[1] === undefined ? mostRecentChange : arguments[1];
var update = recentChange.update;
var mapping = connections[className][recentChange.className];
var output = {};
/*
* If the instance cares about changes coming from this type of class...
*/
if (mapping) {
/*
* Check each of the value names it cares about for that class.
*/
eachKey(mapping, function (validator, valueName) {
/*
* For each of those names found in the update, run the validator
* and determine whether or not we care about the change that
* occurred. If so, add it to the output.
*/
var oldVal = update[valueName][0];
var newVal = update[valueName][1];
var validatorEvt = validator[0];
var validatorCheck = validator[1];
if (validatorEvt === 'change' && oldVal === newVal) return;
if (validatorEvt !== 'change' && validatorEvt !== 'always') {
throw new Error(validatorEvt + ' is not a valid validator event.');
}
if (validatorCheck === true || validatorCheck(newVal, oldVal)) {
output[valueName] = newVal;
}
});
}
return Object.keys(output).length ? output : undefined;
}
},{}],9:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.store = exports.Component = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _react = require('react');
var _store = require('./lib/store');
var _store2 = _interopRequireDefault(_store);
var _utils = require('./lib/utils');
var utils = _interopRequireWildcard(_utils);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
CONCEPT:
Describe redux communications across your app all in one place. This will
eliminate the need to hunt down dispatches and subscriptions.
EXAMPLE:
```
import { Component } from 'strux';
class Comp1 extends Component {
constructor() {
super();
}
componentDidMount() {
this.setState({
foo: 1,
bar: 2
});
}
componentTakesState(state, className, diff) {
doStuff(state);
}
}
class Comp2 extends Component {
constructor() {
super();
}
componentDidMount() {
this.setState({
baz: 3,
qux: 4
});
}
componentTakesState(state, className, diff) {
doStuff(state);
}
}
Comp2.reactsWhen({
Comp1: {
foo: (newVal, oldVal) => newVal > 0,
bar: true
}
});
Comp1.reactsWhen({
Comp2: {
baz: ['always', (newVal, oldVal) => newVal !== oldVal],
qux: ['change', newVal => whatever(newVal)]
}