Comparing version 0.16.7 to 0.16.8
# Changelog | ||
## 0.16.8 | ||
### Added | ||
* `preventDefault` to stop a store from emitting a change. [commit](https://github.com/goatslacker/alt/commit/1635589) | ||
* `observe()` a way for POJOs to observe for changes. [commit](https://github.com/goatslacker/alt/commit/1635589) | ||
* `otherwise()` listen to all dispatches that have not been bound in your stores. [commit](https://github.com/goatslacker/alt/commit/1635589) | ||
* `reduce()` listen to all dispatches in a store and return the new state. [commit](https://github.com/goatslacker/alt/commit/1635589) | ||
* `output()` transform the output that is emitted from the stores. [commit](https://github.com/goatslacker/alt/commit/1635589) | ||
* Proper server rendering resolving all data at the component level before rendering. [commit](https://github.com/goatslacker/alt/commit/4cf98e3) | ||
* Batched dispatches to avoid having componentWillMount cause a cannot dispatch while dispatching error when it loses context. [commit](https://github.com/goatslacker/alt/commit/907c94c) | ||
* Alt.debug for registering your alt instance with chrome dev tools. [commit](https://github.com/goatslacker/alt/commit/5b6d78c) | ||
* Function utils for transforming store state. [commit](https://github.com/goatslacker/alt/commit/e3564d6) | ||
* Able to return from an action to dispatch rather than calling this.dispatch yourself. [commit](https://github.com/goatslacker/alt/commit/460a749) | ||
## 0.16.7 | ||
@@ -4,0 +28,0 @@ |
151
dist/alt.js
@@ -724,2 +724,6 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Alt = f()}})(function(){var define,module,exports;return (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){ | ||
var _utilsFunctions = require('../../utils/functions'); | ||
var fn = _interopRequireWildcard(_utilsFunctions); | ||
var _symbolsSymbols = require('../symbols/symbols'); | ||
@@ -742,2 +746,3 @@ | ||
this.alt = alt; | ||
this.dispatched = false; | ||
} | ||
@@ -748,2 +753,3 @@ | ||
value: function dispatch(data) { | ||
this.dispatched = true; | ||
this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails); | ||
@@ -772,5 +778,8 @@ } | ||
var dispatch = function dispatch(payload) { | ||
return alt.dispatch(actionSymbol, payload, data); | ||
}; | ||
// the action itself | ||
var action = newAction[Sym.ACTION_HANDLER]; | ||
action.defer = function () { | ||
var action = function action() { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
@@ -780,2 +789,18 @@ args[_key] = arguments[_key]; | ||
newAction.dispatched = false; | ||
var result = newAction[Sym.ACTION_HANDLER].apply(newAction, args); | ||
if (!newAction.dispatched) { | ||
if (fn.isFunction(result)) { | ||
result(dispatch); | ||
} else { | ||
dispatch(result); | ||
} | ||
} | ||
return result; | ||
}; | ||
action.defer = function () { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
setTimeout(function () { | ||
@@ -798,3 +823,3 @@ newAction[Sym.ACTION_HANDLER].apply(null, args); | ||
},{"../symbols/symbols":10,"../utils/AltUtils":11,"es-symbol":1}],7:[function(require,module,exports){ | ||
},{"../../utils/functions":13,"../symbols/symbols":10,"../utils/AltUtils":11,"es-symbol":1}],7:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -843,2 +868,3 @@ | ||
this.preventDefault = false; | ||
this._storeName = model._storeName; | ||
@@ -848,2 +874,23 @@ this.boundListeners = model[Sym.ALL_LISTENERS]; | ||
var output = model.output || function (x) { | ||
return x; | ||
}; | ||
this.emitChange = function () { | ||
_this[EE].emit('change', output.call(model, _this[Sym.STATE_CONTAINER])); | ||
}; | ||
var handleDispatch = function handleDispatch(f, payload) { | ||
try { | ||
return f(); | ||
} catch (e) { | ||
if (model[Sym.HANDLING_ERRORS]) { | ||
_this[Sym.LIFECYCLE].emit('error', e, payload, _this[Sym.STATE_CONTAINER]); | ||
return false; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
}; | ||
fn.assign(this, model[Sym.PUBLIC_METHODS]); | ||
@@ -853,22 +900,23 @@ | ||
this.dispatchToken = alt.dispatcher.register(function (payload) { | ||
_this.preventDefault = false; | ||
_this[Sym.LIFECYCLE].emit('beforeEach', payload, _this[Sym.STATE_CONTAINER]); | ||
if (model[Sym.LISTENERS][payload.action]) { | ||
var result = false; | ||
var actionHandler = model[Sym.LISTENERS][payload.action] || model.otherwise; | ||
try { | ||
result = model[Sym.LISTENERS][payload.action](payload.data); | ||
} catch (e) { | ||
if (model[Sym.HANDLING_ERRORS]) { | ||
_this[Sym.LIFECYCLE].emit('error', e, payload, _this[Sym.STATE_CONTAINER]); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
if (actionHandler) { | ||
var result = handleDispatch(function () { | ||
return actionHandler.call(model, payload.data, payload.action); | ||
}, payload); | ||
if (result !== false) { | ||
_this.emitChange(); | ||
} | ||
if (result !== false && !_this.preventDefault) _this.emitChange(); | ||
} | ||
if (model.reduce) { | ||
handleDispatch(function () { | ||
model.setState(model.reduce(_this[Sym.STATE_CONTAINER], payload)); | ||
}, payload); | ||
if (!_this.preventDefault) _this.emitChange(); | ||
} | ||
_this[Sym.LIFECYCLE].emit('afterEach', payload, _this[Sym.STATE_CONTAINER]); | ||
@@ -886,7 +934,2 @@ }); | ||
}, { | ||
key: 'emitChange', | ||
value: function emitChange() { | ||
this[EE].emit('change', this[Sym.STATE_CONTAINER]); | ||
} | ||
}, { | ||
key: 'listen', | ||
@@ -999,2 +1042,14 @@ value: function listen(cb) { | ||
var makeActionHandler = function makeActionHandler(action) { | ||
return function (x) { | ||
var fire = function fire() { | ||
loadCounter -= 1; | ||
action(intercept(x, action, args)); | ||
}; | ||
return typeof window === 'undefined' ? function () { | ||
return fire(); | ||
} : fire(); | ||
}; | ||
}; | ||
// if we don't have it in cache then fetch it | ||
@@ -1005,9 +1060,3 @@ if (shouldFetch) { | ||
if (spec.loading) spec.loading(intercept(null, spec.loading, args)); | ||
spec.remote.apply(spec, [state].concat(args)).then(function (v) { | ||
loadCounter -= 1; | ||
spec.success(intercept(v, spec.success, args)); | ||
})['catch'](function (v) { | ||
loadCounter -= 1; | ||
spec.error(intercept(v, spec.error, args)); | ||
}); | ||
return spec.remote.apply(spec, [state].concat(args)).then(makeActionHandler(spec.success))['catch'](makeActionHandler(spec.error)); | ||
} else { | ||
@@ -1194,3 +1243,6 @@ // otherwise emit the change now | ||
alt: alt, | ||
dispatcher: alt.dispatcher | ||
dispatcher: alt.dispatcher, | ||
preventDefault: function preventDefault() { | ||
this.getInstance().preventDefault = true; | ||
} | ||
}, extras); | ||
@@ -1231,2 +1283,6 @@ } | ||
} | ||
/* istanbul ignore else */ | ||
if (StoreProto.observe) { | ||
_StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.observe(alt)); | ||
} | ||
@@ -1242,3 +1298,3 @@ // bind the lifecycle events | ||
// create the instance and fn.assign the public methods to the instance | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, StoreProto, StoreProto.state, StoreModel), StoreProto.publicMethods, { displayName: key }); | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, StoreProto, StoreProto.state || {}, StoreModel), StoreProto.publicMethods, { displayName: key }); | ||
@@ -1287,10 +1343,5 @@ return storeInstance; | ||
if (config.bindListeners) { | ||
store.bindListeners(config.bindListeners); | ||
} | ||
if (config.bindListeners) store.bindListeners(config.bindListeners); | ||
if (config.datasource) store.registerAsync(config.datasource); | ||
if (config.datasource) { | ||
store.exportAsync(config.datasource); | ||
} | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, store, store[alt.config.stateKey] || store[config.stateKey] || null, StoreModel), utils.getInternalMethods(StoreModel), config.publicMethods, { displayName: key }); | ||
@@ -1526,2 +1577,3 @@ | ||
},{}],14:[function(require,module,exports){ | ||
/*global window*/ | ||
'use strict'; | ||
@@ -1582,2 +1634,5 @@ | ||
this.dispatcher = config.dispatcher || new _flux.Dispatcher(); | ||
this.batchingFunction = config.batchingFunction || function (callback) { | ||
return callback(); | ||
}; | ||
this.actions = { global: {} }; | ||
@@ -1594,3 +1649,7 @@ this.stores = {}; | ||
value: function dispatch(action, data, details) { | ||
this.dispatcher.dispatch({ action: action, data: data, details: details }); | ||
var _this = this; | ||
this.batchingFunction(function () { | ||
return _this.dispatcher.dispatch({ action: action, data: data, details: details }); | ||
}); | ||
} | ||
@@ -1663,3 +1722,3 @@ }, { | ||
var _this = this; | ||
var _this2 = this; | ||
@@ -1718,3 +1777,3 @@ var exportObj = arguments[1] === undefined ? {} : arguments[1]; | ||
// create the action | ||
exportObj[actionName] = (0, _actions2['default'])(_this, key, actionName, action, exportObj); | ||
exportObj[actionName] = (0, _actions2['default'])(_this2, key, actionName, action, exportObj); | ||
@@ -1816,2 +1875,12 @@ // generate a constant | ||
} | ||
}], [{ | ||
key: 'debug', | ||
value: function debug(name, alt) { | ||
var key = 'alt.js.org'; | ||
if (typeof window !== 'undefined') { | ||
window[key] = window[key] || []; | ||
window[key].push({ name: name, alt: alt }); | ||
} | ||
return alt; | ||
} | ||
}]); | ||
@@ -1818,0 +1887,0 @@ |
@@ -308,1 +308,23 @@ --- | ||
This is a reference to the store's internal name. This is either the identifier you provided to `createStore` or StoreModel's class name. | ||
## StoreModel#otherwise | ||
> otherwise(data, action) | ||
This is a method you can implement in your store in order to receive all dispatches that are not currently being handled in your store explicitly via bindActions, bindAction, or bindListeners. This is similar to guards matching in Haskell. | ||
## StoreModel#reduce | ||
> reduce(state, { action, data }): {} | ||
Another method you can implement in your store. This method receives all dispatches and the result that is returned is then set as the new state of your store. This way you can write your stores as reducers of dispatches. | ||
## StoreModel#preventDefault | ||
Rather than returning false to suppress a change event from your store you may call this method and the change event will not happen. | ||
## StoreModel#observe | ||
> observe(alt): {} | ||
A method you can implment in your stores, mostly useful when using plain objects to create a store. This method will receive the current alt instance and returns an object containing the methods/actions it'll handle. |
@@ -74,2 +74,3 @@ (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){ | ||
},{"../utils/AltUtils":6}],2:[function(require,module,exports){ | ||
/*global window*/ | ||
'use strict'; | ||
@@ -126,2 +127,5 @@ | ||
this.dispatcher = config.dispatcher || new _flux.Dispatcher(); | ||
this.batchingFunction = config.batchingFunction || function (callback) { | ||
return callback(); | ||
}; | ||
this.actions = { global: {} }; | ||
@@ -138,3 +142,7 @@ this.stores = {}; | ||
value: function dispatch(action, data, details) { | ||
this.dispatcher.dispatch({ action: action, data: data, details: details }); | ||
var _this = this; | ||
this.batchingFunction(function () { | ||
return _this.dispatcher.dispatch({ action: action, data: data, details: details }); | ||
}); | ||
} | ||
@@ -207,3 +215,3 @@ }, { | ||
var _this = this; | ||
var _this2 = this; | ||
@@ -262,3 +270,3 @@ var exportObj = arguments[1] === undefined ? {} : arguments[1]; | ||
// create the action | ||
exportObj[actionName] = (0, _actions2['default'])(_this, key, actionName, action, exportObj); | ||
exportObj[actionName] = (0, _actions2['default'])(_this2, key, actionName, action, exportObj); | ||
@@ -360,2 +368,12 @@ // generate a constant | ||
} | ||
}], [{ | ||
key: 'debug', | ||
value: function debug(name, alt) { | ||
var key = 'alt.js.org'; | ||
if (typeof window !== 'undefined') { | ||
window[key] = window[key] || []; | ||
window[key].push({ name: name, alt: alt }); | ||
} | ||
return alt; | ||
} | ||
}]); | ||
@@ -404,2 +422,3 @@ | ||
this.preventDefault = false; | ||
this.displayName = model.displayName; | ||
@@ -409,2 +428,27 @@ this.boundListeners = model.boundListeners; | ||
var output = model.output || function (a, b) { | ||
return b; | ||
}; | ||
this.emitChange = function () { | ||
return _this.transmitter.push(output(alt, _this.state)); | ||
}; | ||
var handleDispatch = function handleDispatch(f, payload) { | ||
try { | ||
return f(); | ||
} catch (e) { | ||
if (model.handlesOwnErrors) { | ||
_this.lifecycle('error', { | ||
error: e, | ||
payload: payload, | ||
state: _this.state | ||
}); | ||
return false; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
}; | ||
fn.assign(this, model.publicMethods); | ||
@@ -414,2 +458,4 @@ | ||
this.dispatchToken = alt.dispatcher.register(function (payload) { | ||
_this.preventDefault = false; | ||
_this.lifecycle('beforeEach', { | ||
@@ -420,24 +466,20 @@ payload: payload, | ||
if (model.actionListeners[payload.action]) { | ||
var result = false; | ||
var actionHandler = model.actionListeners[payload.action] || model.otherwise; | ||
try { | ||
result = model.actionListeners[payload.action](payload.data); | ||
} catch (e) { | ||
if (model.handlesOwnErrors) { | ||
_this.lifecycle('error', { | ||
error: e, | ||
payload: payload, | ||
state: _this.state | ||
}); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
if (actionHandler) { | ||
var result = handleDispatch(function () { | ||
return actionHandler.call(model, payload.data); | ||
}, payload); | ||
if (result !== false) { | ||
_this.emitChange(); | ||
} | ||
if (result !== false && !_this.preventDefault) _this.emitChange(); | ||
} | ||
if (model.reduce) { | ||
handleDispatch(function () { | ||
model.setState(model.reduce(alt, _this.state, payload.data)); | ||
}, payload); | ||
if (!_this.preventDefault) _this.emitChange(); | ||
} | ||
_this.lifecycle('afterEach', { | ||
@@ -453,7 +495,2 @@ payload: payload, | ||
_createClass(AltStore, [{ | ||
key: 'emitChange', | ||
value: function emitChange() { | ||
this.transmitter.push(this.state); | ||
} | ||
}, { | ||
key: 'listen', | ||
@@ -556,3 +593,3 @@ value: function listen(cb) { | ||
var value = spec.local && spec.local.apply(spec, [state].concat(args)); | ||
var shouldFetch = spec.shouldFetch ? spec.shouldFetch.apply(spec, [state].concat(args)) : !value; | ||
var shouldFetch = spec.shouldFetch ? spec.shouldFetch.apply(spec, [state].concat(args)) : value == null; | ||
var intercept = spec.interceptResponse || function (x) { | ||
@@ -562,2 +599,14 @@ return x; | ||
var makeActionHandler = function makeActionHandler(action) { | ||
return function (x) { | ||
var fire = function fire() { | ||
loadCounter -= 1; | ||
action(intercept(x, action, args)); | ||
}; | ||
return typeof window === 'undefined' ? function () { | ||
return fire(); | ||
} : fire(); | ||
}; | ||
}; | ||
// if we don't have it in cache then fetch it | ||
@@ -567,10 +616,4 @@ if (shouldFetch) { | ||
/* istanbul ignore else */ | ||
if (spec.loading) spec.loading(intercept(null, spec.loading)); | ||
spec.remote.apply(spec, [state].concat(args)).then(function (v) { | ||
loadCounter -= 1; | ||
spec.success(intercept(v, spec.success)); | ||
})['catch'](function (v) { | ||
loadCounter -= 1; | ||
spec.error(intercept(v, spec.error)); | ||
}); | ||
if (spec.loading) spec.loading(intercept(null, spec.loading, args)); | ||
return spec.remote.apply(spec, [state].concat(args)).then(makeActionHandler(spec.success))['catch'](makeActionHandler(spec.error)); | ||
} else { | ||
@@ -699,6 +742,6 @@ // otherwise emit the change now | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
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'); } } | ||
@@ -708,6 +751,2 @@ | ||
var _transmitter = require('transmitter'); | ||
var _transmitter2 = _interopRequireDefault(_transmitter); | ||
var _utilsAltUtils = require('../utils/AltUtils'); | ||
@@ -755,3 +794,6 @@ | ||
alt: alt, | ||
dispatcher: alt.dispatcher | ||
dispatcher: alt.dispatcher, | ||
preventDefault: function preventDefault() { | ||
this.getInstance().preventDefault = true; | ||
} | ||
}, extras); | ||
@@ -775,62 +817,36 @@ } | ||
function createStoreFromObject(context, model, name) { | ||
var state = model.state; | ||
var bus = (0, _transmitter2['default'])(); | ||
function createStoreFromObject(alt, StoreModel, key) { | ||
var storeInstance = undefined; | ||
var observables = model.observe(context, state); | ||
var signalKeys = keys(observables); | ||
// setup the dependencies and signals | ||
var dependencies = signalKeys.map(function (key) { | ||
return observables[key].dispatchToken; | ||
}).filter(Boolean); | ||
var dispatchToken = context.dispatcher.register(function (payload) { | ||
var action = payload.action; | ||
var data = payload.data; | ||
// bootstrap state | ||
if (action === BOOTSTRAP && data[name]) { | ||
return state = data[name]; | ||
var StoreProto = createPrototype({}, alt, key, fn.assign({ | ||
getInstance: function getInstance() { | ||
return storeInstance; | ||
}, | ||
setState: function setState(nextState) { | ||
doSetState(this, storeInstance, nextState); | ||
} | ||
}, StoreModel)); | ||
// pull the signals from the action | ||
var signals = signalKeys.reduce(function (arr, key) { | ||
var value = observables[key]; | ||
var list = Array.isArray(value) ? value : [value]; | ||
list.forEach(function (observable) { | ||
if (observable === action) arr.push([key, data]);else if (observable.dispatchToken) arr.push([key, observable.get()]); | ||
}); | ||
return arr; | ||
}, []); | ||
// bind the store listeners | ||
/* istanbul ignore else */ | ||
if (StoreProto.bindListeners) { | ||
_StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.bindListeners); | ||
} | ||
/* istanbul ignore else */ | ||
if (StoreProto.observe) { | ||
_StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.observe(alt)); | ||
} | ||
var emitChange = signals.length; | ||
// bind the lifecycle events | ||
/* istanbul ignore else */ | ||
if (StoreProto.lifecycle) { | ||
fn.eachObject(function (eventName, event) { | ||
_StoreMixin2['default'].on.call(StoreProto, eventName, event); | ||
}, [StoreProto.lifecycle]); | ||
} | ||
// wait for any derived data | ||
context.dispatcher.waitFor(dependencies); | ||
// create the instance and fn.assign the public methods to the instance | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, StoreProto, StoreProto.state, StoreModel), StoreProto.publicMethods, { displayName: key }); | ||
// reduce and output | ||
if (emitChange) { | ||
var nextState = model.reduce(context, state, signals.reduce(function (o, x) { | ||
return (o[x[0]] = x[1], o); | ||
}, {})); | ||
var output = model.output ? model.output(context, state, nextState) : nextState; | ||
state = nextState; | ||
// if no output, no push | ||
if (output !== undefined) bus.push(output); | ||
} | ||
}); | ||
var statics = model.statics ? model.statics(context) : {}; | ||
return keys(statics).reduce(function (obj, key) { | ||
obj[key] = statics[key]; | ||
return obj; | ||
}, { | ||
dispatchToken: dispatchToken, | ||
subscribe: bus.subscribe, | ||
get: function get() { | ||
return state; | ||
} | ||
}); | ||
return storeInstance; | ||
} | ||
@@ -877,10 +893,5 @@ | ||
if (config.bindListeners) { | ||
store.bindListeners(config.bindListeners); | ||
} | ||
if (config.bindListeners) store.bindListeners(config.bindListeners); | ||
if (config.datasource) store.registerAsync(config.datasource); | ||
if (config.datasource) { | ||
store.exportAsync(config.datasource); | ||
} | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, store, typeof store.state === 'object' ? store.state : null, StoreModel), utils.getInternalMethods(StoreModel), config.publicMethods, { displayName: key }); | ||
@@ -890,3 +901,3 @@ | ||
} | ||
},{"../../utils/functions":12,"../utils/AltUtils":6,"./AltStore":3,"./StoreMixin":4,"transmitter":11}],6:[function(require,module,exports){ | ||
},{"../../utils/functions":12,"../utils/AltUtils":6,"./AltStore":3,"./StoreMixin":4}],6:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -893,0 +904,0 @@ |
@@ -51,2 +51,8 @@ --- | ||
}); | ||
this.exportPublicMethods({ | ||
hasFood: function() { | ||
return !!this.getState().foods.length; | ||
} | ||
}); | ||
} | ||
@@ -76,2 +82,8 @@ | ||
}, | ||
pubilcMethods: { | ||
hasFood: function () { | ||
return !!this.getState().foods.length; | ||
} | ||
}, | ||
@@ -109,2 +121,7 @@ addItem: function (item) { | ||
}, | ||
pubilcMethods: { | ||
hasFood: function () { | ||
return foods.length; | ||
} | ||
}, | ||
@@ -126,2 +143,9 @@ addItem: function (item) { | ||
A less explicit way of creating a public method is to statically define it as property of the store constructor function: | ||
``` | ||
FoodStore.hasFood = function() { | ||
return !!this.getState().length; | ||
} | ||
``` | ||
## Instances | ||
@@ -128,0 +152,0 @@ |
@@ -21,2 +21,6 @@ 'use strict'; | ||
var _utilsFunctions = require('../../utils/functions'); | ||
var fn = _interopRequireWildcard(_utilsFunctions); | ||
var _symbolsSymbols = require('../symbols/symbols'); | ||
@@ -39,2 +43,3 @@ | ||
this.alt = alt; | ||
this.dispatched = false; | ||
} | ||
@@ -45,2 +50,3 @@ | ||
value: function dispatch(data) { | ||
this.dispatched = true; | ||
this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails); | ||
@@ -69,5 +75,8 @@ } | ||
var dispatch = function dispatch(payload) { | ||
return alt.dispatch(actionSymbol, payload, data); | ||
}; | ||
// the action itself | ||
var action = newAction[Sym.ACTION_HANDLER]; | ||
action.defer = function () { | ||
var action = function action() { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
@@ -77,2 +86,18 @@ args[_key] = arguments[_key]; | ||
newAction.dispatched = false; | ||
var result = newAction[Sym.ACTION_HANDLER].apply(newAction, args); | ||
if (!newAction.dispatched) { | ||
if (fn.isFunction(result)) { | ||
result(dispatch); | ||
} else { | ||
dispatch(result); | ||
} | ||
} | ||
return result; | ||
}; | ||
action.defer = function () { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
setTimeout(function () { | ||
@@ -79,0 +104,0 @@ newAction[Sym.ACTION_HANDLER].apply(null, args); |
@@ -0,1 +1,2 @@ | ||
/*global window*/ | ||
'use strict'; | ||
@@ -56,2 +57,5 @@ | ||
this.dispatcher = config.dispatcher || new _flux.Dispatcher(); | ||
this.batchingFunction = config.batchingFunction || function (callback) { | ||
return callback(); | ||
}; | ||
this.actions = { global: {} }; | ||
@@ -68,3 +72,7 @@ this.stores = {}; | ||
value: function dispatch(action, data, details) { | ||
this.dispatcher.dispatch({ action: action, data: data, details: details }); | ||
var _this = this; | ||
this.batchingFunction(function () { | ||
return _this.dispatcher.dispatch({ action: action, data: data, details: details }); | ||
}); | ||
} | ||
@@ -137,3 +145,3 @@ }, { | ||
var _this = this; | ||
var _this2 = this; | ||
@@ -192,3 +200,3 @@ var exportObj = arguments[1] === undefined ? {} : arguments[1]; | ||
// create the action | ||
exportObj[actionName] = (0, _actions2['default'])(_this, key, actionName, action, exportObj); | ||
exportObj[actionName] = (0, _actions2['default'])(_this2, key, actionName, action, exportObj); | ||
@@ -290,2 +298,12 @@ // generate a constant | ||
} | ||
}], [{ | ||
key: 'debug', | ||
value: function debug(name, alt) { | ||
var key = 'alt.js.org'; | ||
if (typeof window !== 'undefined') { | ||
window[key] = window[key] || []; | ||
window[key].push({ name: name, alt: alt }); | ||
} | ||
return alt; | ||
} | ||
}]); | ||
@@ -292,0 +310,0 @@ |
@@ -44,2 +44,3 @@ 'use strict'; | ||
this.preventDefault = false; | ||
this._storeName = model._storeName; | ||
@@ -49,2 +50,23 @@ this.boundListeners = model[Sym.ALL_LISTENERS]; | ||
var output = model.output || function (x) { | ||
return x; | ||
}; | ||
this.emitChange = function () { | ||
_this[EE].emit('change', output.call(model, _this[Sym.STATE_CONTAINER])); | ||
}; | ||
var handleDispatch = function handleDispatch(f, payload) { | ||
try { | ||
return f(); | ||
} catch (e) { | ||
if (model[Sym.HANDLING_ERRORS]) { | ||
_this[Sym.LIFECYCLE].emit('error', e, payload, _this[Sym.STATE_CONTAINER]); | ||
return false; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
}; | ||
fn.assign(this, model[Sym.PUBLIC_METHODS]); | ||
@@ -54,22 +76,23 @@ | ||
this.dispatchToken = alt.dispatcher.register(function (payload) { | ||
_this.preventDefault = false; | ||
_this[Sym.LIFECYCLE].emit('beforeEach', payload, _this[Sym.STATE_CONTAINER]); | ||
if (model[Sym.LISTENERS][payload.action]) { | ||
var result = false; | ||
var actionHandler = model[Sym.LISTENERS][payload.action] || model.otherwise; | ||
try { | ||
result = model[Sym.LISTENERS][payload.action](payload.data); | ||
} catch (e) { | ||
if (model[Sym.HANDLING_ERRORS]) { | ||
_this[Sym.LIFECYCLE].emit('error', e, payload, _this[Sym.STATE_CONTAINER]); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
if (actionHandler) { | ||
var result = handleDispatch(function () { | ||
return actionHandler.call(model, payload.data, payload.action); | ||
}, payload); | ||
if (result !== false) { | ||
_this.emitChange(); | ||
} | ||
if (result !== false && !_this.preventDefault) _this.emitChange(); | ||
} | ||
if (model.reduce) { | ||
handleDispatch(function () { | ||
model.setState(model.reduce(_this[Sym.STATE_CONTAINER], payload)); | ||
}, payload); | ||
if (!_this.preventDefault) _this.emitChange(); | ||
} | ||
_this[Sym.LIFECYCLE].emit('afterEach', payload, _this[Sym.STATE_CONTAINER]); | ||
@@ -87,7 +110,2 @@ }); | ||
}, { | ||
key: 'emitChange', | ||
value: function emitChange() { | ||
this[EE].emit('change', this[Sym.STATE_CONTAINER]); | ||
} | ||
}, { | ||
key: 'listen', | ||
@@ -94,0 +112,0 @@ value: function listen(cb) { |
@@ -72,3 +72,6 @@ 'use strict'; | ||
alt: alt, | ||
dispatcher: alt.dispatcher | ||
dispatcher: alt.dispatcher, | ||
preventDefault: function preventDefault() { | ||
this.getInstance().preventDefault = true; | ||
} | ||
}, extras); | ||
@@ -109,2 +112,6 @@ } | ||
} | ||
/* istanbul ignore else */ | ||
if (StoreProto.observe) { | ||
_StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.observe(alt)); | ||
} | ||
@@ -120,3 +127,3 @@ // bind the lifecycle events | ||
// create the instance and fn.assign the public methods to the instance | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, StoreProto, StoreProto.state, StoreModel), StoreProto.publicMethods, { displayName: key }); | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, StoreProto, StoreProto.state || {}, StoreModel), StoreProto.publicMethods, { displayName: key }); | ||
@@ -165,10 +172,5 @@ return storeInstance; | ||
if (config.bindListeners) { | ||
store.bindListeners(config.bindListeners); | ||
} | ||
if (config.bindListeners) store.bindListeners(config.bindListeners); | ||
if (config.datasource) store.registerAsync(config.datasource); | ||
if (config.datasource) { | ||
store.exportAsync(config.datasource); | ||
} | ||
storeInstance = fn.assign(new _AltStore2['default'](alt, store, store[alt.config.stateKey] || store[config.stateKey] || null, StoreModel), utils.getInternalMethods(StoreModel), config.publicMethods, { displayName: key }); | ||
@@ -175,0 +177,0 @@ |
@@ -79,2 +79,14 @@ 'use strict'; | ||
var makeActionHandler = function makeActionHandler(action) { | ||
return function (x) { | ||
var fire = function fire() { | ||
loadCounter -= 1; | ||
action(intercept(x, action, args)); | ||
}; | ||
return typeof window === 'undefined' ? function () { | ||
return fire(); | ||
} : fire(); | ||
}; | ||
}; | ||
// if we don't have it in cache then fetch it | ||
@@ -85,9 +97,3 @@ if (shouldFetch) { | ||
if (spec.loading) spec.loading(intercept(null, spec.loading, args)); | ||
spec.remote.apply(spec, [state].concat(args)).then(function (v) { | ||
loadCounter -= 1; | ||
spec.success(intercept(v, spec.success, args)); | ||
})['catch'](function (v) { | ||
loadCounter -= 1; | ||
spec.error(intercept(v, spec.error, args)); | ||
}); | ||
return spec.remote.apply(spec, [state].concat(args)).then(makeActionHandler(spec.success))['catch'](makeActionHandler(spec.error)); | ||
} else { | ||
@@ -94,0 +100,0 @@ // otherwise emit the change now |
{ | ||
"name": "alt", | ||
"version": "0.16.7", | ||
"version": "0.16.8", | ||
"description": "A flux implementation", | ||
@@ -30,2 +30,3 @@ "main": "lib", | ||
"mocha": "^2.2.4", | ||
"object-assign": "^2.0.0", | ||
"react": "^0.13.3", | ||
@@ -45,18 +46,17 @@ "rimraf": "^2.3.2", | ||
"scripts": { | ||
"build": "npm run clean && npm run build-alt && npm run build-utils && npm run build-alt-browser && npm run build-alt-browser-with-addons", | ||
"build-alt": "babel src/alt --out-dir lib --stage 0", | ||
"build-utils": "babel src/utils --out-dir utils --stage 0", | ||
"build": "npm run clean && npm run transpile && npm run build-alt-browser && npm run build-alt-browser-with-addons", | ||
"build-alt": "babel src/alt --out-dir lib", | ||
"build-alt-browser": "browserify src/alt -t [envify --NODE_ENV production ] -t babelify --outfile dist/alt.js --standalone Alt", | ||
"build-alt-browser-with-addons": "browserify src/alt/addons.js -t [envify --NODE_ENV production ] -t babelify -t browserify-shim --outfile dist/alt-with-addons.js --standalone Alt", | ||
"build-test": "babel src/alt --out-dir lib -r --stage 0 && babel src/utils --out-dir utils -r --stage 0", | ||
"coverage": "npm run build-test && istanbul cover node_modules/mocha/bin/_mocha -- -u exports -R tap --require ./test/babel test", | ||
"coverage": "npm run transpile-cover && istanbul cover node_modules/mocha/bin/_mocha -- -u exports -R tap --require ./test/babel test", | ||
"clean": "rimraf lib && rimraf utils", | ||
"lint": "eslint src components", | ||
"posttest": "npm run build-alt", | ||
"prepublish": "npm run lint && npm run test && npm run build", | ||
"pretest": "npm run clean && npm run build-test", | ||
"pretest": "npm run clean && npm run transpile", | ||
"size": "npm run build-alt; browserify flux.js > flux-build.js; uglifyjs -m -c 'comparisons=false,keep_fargs=true,unsafe=true,unsafe_comps=true,warnings=false' flux-build.js > flux-build.min.js", | ||
"test": "npm run tests-node", | ||
"test": "npm run test-node", | ||
"test-browser": "browserify test/browser/index.js -t babelify --outfile test/browser/tests.js", | ||
"tests-node": "mocha -u exports -R nyan --require ./test/babel test" | ||
"test-node": "mocha -u exports -R nyan --require ./test/babel test", | ||
"transpile": "babel src/alt --out-dir lib && babel src/utils --out-dir utils", | ||
"transpile-cover": "babel src/alt --out-dir lib -r && babel src/utils --out-dir utils -r" | ||
}, | ||
@@ -63,0 +63,0 @@ "browserify-shim": { |
@@ -90,2 +90,4 @@ # alt | ||
* [Typeahead](https://github.com/timtyrrell/alt-typeahead) | ||
* [Maple.js Webcomponents](https://github.com/Wildhoney/Maple.js/tree/master/example/app) | ||
* [Jumar's Tindahan](https://github.com/srph/jumars-tindahan) | ||
@@ -130,3 +132,3 @@ ### Boilerplates | ||
Check out the [API Reference](http://alt.js.org/docs/) for full in-depth docs. | ||
Check out the [API Reference](http://alt.js.org/docs/) for full in-depth docs. For a high-level walk-through, take a look at the [Getting Started](http://alt.js.org/guide/) guide. | ||
@@ -133,0 +135,0 @@ First we install alt through npm. Although alt is also available through bower. |
@@ -77,3 +77,2 @@ import Alt from '../' | ||
@createStore(alt) | ||
@datasource(StargazerSource) | ||
class StargazerStore { | ||
@@ -93,2 +92,4 @@ static config = { | ||
this.registerAsync(StargazerSource) | ||
this.bindListeners({ | ||
@@ -117,2 +118,4 @@ loading: StargazerActions.fetchingUsers, | ||
beforeEach() { | ||
global.window = {} | ||
alt.recycle() | ||
@@ -123,2 +126,6 @@ local.reset() | ||
afterEach() { | ||
delete global.window | ||
}, | ||
'methods are available'() { | ||
@@ -218,4 +225,4 @@ assert.isFunction(StargazerStore.fetchUsers) | ||
StargazerStore.alwaysFetchUsers() | ||
assert.ok(StargazerStore.isLoading()) | ||
assert.ok(remote.calledOnce) | ||
assert.ok(StargazerStore.isLoading(), 'i am loading') | ||
assert.ok(remote.calledOnce, 'remote was called once') | ||
}, | ||
@@ -225,4 +232,4 @@ | ||
StargazerStore.neverFetchUsers() | ||
assert.notOk(StargazerStore.isLoading()) | ||
assert(remote.callCount === 0) | ||
assert.notOk(StargazerStore.isLoading(), 'loading now') | ||
assert(remote.callCount === 0, 'remote was not called') | ||
}, | ||
@@ -249,5 +256,8 @@ | ||
@datasource(FauxSource) | ||
class FauxStore { | ||
static displayName = 'FauxStore' | ||
constructor() { | ||
this.exportAsync(FauxSource) | ||
} | ||
} | ||
@@ -271,3 +281,2 @@ | ||
@datasource(PojoSource) | ||
class MyStore { | ||
@@ -277,3 +286,3 @@ static displayName = 'MyStore' | ||
const store = alt.createStore(MyStore) | ||
const store = alt.createStore(datasource(PojoSource)(MyStore)) | ||
@@ -283,3 +292,42 @@ assert.isFunction(store.justTesting) | ||
}, | ||
'server rendering'(done) { | ||
delete global.window | ||
const actions = alt.generateActions('test') | ||
const PojoSource = { | ||
justTesting: { | ||
remote() { | ||
return Promise.resolve(true) | ||
}, | ||
success: actions.test, | ||
error: actions.test, | ||
} | ||
} | ||
@datasource(PojoSource) | ||
class MyStore { | ||
static displayName = 'ServerRenderingStore' | ||
} | ||
const spy = sinon.spy() | ||
const dispatchToken = alt.dispatcher.register(spy) | ||
const store = alt.createStore(MyStore) | ||
store.justTesting().then((value) => { | ||
assert.isFunction(value) | ||
assert(spy.callCount === 0, 'the dispatcher was never called') | ||
value() | ||
assert.ok(spy.calledOnce, 'the dispatcher was flushed') | ||
alt.dispatcher.unregister(dispatchToken) | ||
done() | ||
}) | ||
}, | ||
} | ||
} |
@@ -48,3 +48,3 @@ import Alt from '../dist/alt-with-runtime' | ||
const storePrototype = Object.getPrototypeOf(myStore) | ||
const assertMethods = ['constructor', 'getEventEmitter', 'emitChange', 'listen', 'unlisten', 'getState'] | ||
const assertMethods = ['constructor', 'getEventEmitter', 'listen', 'unlisten', 'getState'] | ||
assert.deepEqual(Object.getOwnPropertyNames(storePrototype), assertMethods, 'methods exist for store') | ||
@@ -51,0 +51,0 @@ assert.isUndefined(myStore.addListener, 'event emitter methods not present') |
@@ -392,3 +392,3 @@ import Alt from '../' | ||
const storePrototype = Object.getPrototypeOf(myStore) | ||
const assertMethods = ['constructor', 'getEventEmitter', 'emitChange', 'listen', 'unlisten', 'getState'] | ||
const assertMethods = ['constructor', 'getEventEmitter', 'listen', 'unlisten', 'getState'] | ||
assert.deepEqual(Object.getOwnPropertyNames(storePrototype), assertMethods, 'methods exist for store') | ||
@@ -439,7 +439,5 @@ assert.isUndefined(myStore.addListener, 'event emitter methods not present') | ||
assert.isFunction(myActions.callInternalMethod, 'shorthand function created with createActions exists') | ||
assert(myActions.callInternalMethod.length === 1, 'shorthand function is an id function') | ||
assert.isFunction(myActions.updateName, 'prototype defined actions exist') | ||
assert.isFunction(myActions.updateTwo, 'prototype defined actions exist') | ||
assert.isFunction(myActions.updateThree, 'prototype defined actions exist') | ||
assert(myActions.updateTwo.length === 2, 'actions can have > 1 arity') | ||
assert.isFunction(myShorthandActions.actionOne, 'action created with shorthand createActions exists') | ||
@@ -446,0 +444,0 @@ assert.isFunction(myShorthandActions.actionTwo, 'other action created with shorthand createActions exists') |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
570869
123
11835
2
840
6
22
1