Skip to content

Commit

Permalink
A wild Promise Dispatcher appears
Browse files Browse the repository at this point in the history
  • Loading branch information
goatslacker committed May 25, 2015
1 parent e45c615 commit bd434f3
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 29 deletions.
37 changes: 25 additions & 12 deletions dist/alt-with-addons.js
Expand Up @@ -1020,7 +1020,7 @@ var AltAction = (function () {
_createClass(AltAction, [{
key: 'dispatch',
value: function dispatch(data) {
this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails);
return this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails);
}
}]);

Expand Down Expand Up @@ -1134,7 +1134,7 @@ var Alt = (function () {
_createClass(Alt, [{
key: 'dispatch',
value: function dispatch(action, data, details) {
this.dispatcher.dispatch({ action: action, data: data, details: details });
return this.dispatcher.dispatch({ action: action, data: data, details: details });
}
}, {
key: 'createUnsavedStore',
Expand Down Expand Up @@ -1395,6 +1395,10 @@ var fn = _interopRequireWildcard(_utilsFunctions);
// event emitter instance
var EE = (0, _esSymbol2['default'])();

function isPromise(obj) {
return obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
}

var AltStore = (function () {
function AltStore(alt, model, state, StoreModel) {
var _this = this;
Expand All @@ -1415,9 +1419,8 @@ var AltStore = (function () {
this.dispatchToken = alt.dispatcher.register(function (payload) {
_this[Sym.LIFECYCLE].emit('beforeEach', payload, _this[Sym.STATE_CONTAINER]);

var result = false;
if (model[Sym.LISTENERS][payload.action]) {
var result = false;

try {
result = model[Sym.LISTENERS][payload.action](payload.data);
} catch (e) {
Expand All @@ -1429,11 +1432,17 @@ var AltStore = (function () {
}

if (result !== false) {
_this.emitChange();
if (isPromise(result)) {
result.then(_this.emitChange.bind(_this));
} else {
_this.emitChange();
}
}
}

_this[Sym.LIFECYCLE].emit('afterEach', payload, _this[Sym.STATE_CONTAINER]);

return result;
});

this[Sym.LIFECYCLE].emit('init');
Expand Down Expand Up @@ -1996,13 +2005,17 @@ function setAppState(instance, data, onStore) {
fn.eachObject(function (key, value) {
var store = instance.stores[key];
if (store) {
var config = store.StoreModel.config;

if (config.onDeserialize) {
obj[key] = config.onDeserialize(value) || value;
}
fn.assign(store[Sym.STATE_CONTAINER], obj[key]);
onStore(store);
(function () {
var config = store.StoreModel.config;

var state = store[Sym.STATE_CONTAINER];
if (config.onDeserialize) obj[key] = config.onDeserialize(value) || value;
fn.eachObject(function (k) {
return delete state[k];
}, [state]);
fn.assign(state, obj[key]);
onStore(store);
})();
}
}, [obj]);
}
Expand Down
37 changes: 25 additions & 12 deletions dist/alt.js
Expand Up @@ -743,7 +743,7 @@ var AltAction = (function () {
_createClass(AltAction, [{
key: 'dispatch',
value: function dispatch(data) {
this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails);
return this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails);
}
}]);

Expand Down Expand Up @@ -824,6 +824,10 @@ var fn = _interopRequireWildcard(_utilsFunctions);
// event emitter instance
var EE = (0, _esSymbol2['default'])();

function isPromise(obj) {
return obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
}

var AltStore = (function () {
function AltStore(alt, model, state, StoreModel) {
var _this = this;
Expand All @@ -844,9 +848,8 @@ var AltStore = (function () {
this.dispatchToken = alt.dispatcher.register(function (payload) {
_this[Sym.LIFECYCLE].emit('beforeEach', payload, _this[Sym.STATE_CONTAINER]);

var result = false;
if (model[Sym.LISTENERS][payload.action]) {
var result = false;

try {
result = model[Sym.LISTENERS][payload.action](payload.data);
} catch (e) {
Expand All @@ -858,11 +861,17 @@ var AltStore = (function () {
}

if (result !== false) {
_this.emitChange();
if (isPromise(result)) {
result.then(_this.emitChange.bind(_this));
} else {
_this.emitChange();
}
}
}

_this[Sym.LIFECYCLE].emit('afterEach', payload, _this[Sym.STATE_CONTAINER]);

return result;
});

this[Sym.LIFECYCLE].emit('init');
Expand Down Expand Up @@ -1425,13 +1434,17 @@ function setAppState(instance, data, onStore) {
fn.eachObject(function (key, value) {
var store = instance.stores[key];
if (store) {
var config = store.StoreModel.config;

if (config.onDeserialize) {
obj[key] = config.onDeserialize(value) || value;
}
fn.assign(store[Sym.STATE_CONTAINER], obj[key]);
onStore(store);
(function () {
var config = store.StoreModel.config;

var state = store[Sym.STATE_CONTAINER];
if (config.onDeserialize) obj[key] = config.onDeserialize(value) || value;
fn.eachObject(function (k) {
return delete state[k];
}, [state]);
fn.assign(state, obj[key]);
onStore(store);
})();
}
}, [obj]);
}
Expand Down Expand Up @@ -1569,7 +1582,7 @@ var Alt = (function () {
_createClass(Alt, [{
key: 'dispatch',
value: function dispatch(action, data, details) {
this.dispatcher.dispatch({ action: action, data: data, details: details });
return this.dispatcher.dispatch({ action: action, data: data, details: details });
}
}, {
key: 'createUnsavedStore',
Expand Down
2 changes: 1 addition & 1 deletion src/alt/actions/index.js
Expand Up @@ -13,7 +13,7 @@ class AltAction {
}

dispatch(data) {
this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails)
return this.alt.dispatch(this[Sym.ACTION_UID], data, this.actionDetails)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/alt/index.js
Expand Up @@ -22,7 +22,7 @@ class Alt {
}

dispatch(action, data, details) {
this.dispatcher.dispatch({ action, data, details })
return this.dispatcher.dispatch({ action, data, details })
}

createUnsavedStore(StoreModel, ...args) {
Expand Down
17 changes: 14 additions & 3 deletions src/alt/store/AltStore.js
Expand Up @@ -7,6 +7,12 @@ import * as fn from '../../utils/functions'
// event emitter instance
const EE = Symbol()

/*istanbul ignore next*/
function isPromise(obj) {
return obj && (typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
}

class AltStore {
constructor(alt, model, state, StoreModel) {
this[EE] = new EventEmitter()
Expand All @@ -27,9 +33,8 @@ class AltStore {
this[Sym.STATE_CONTAINER]
)

let result = false
if (model[Sym.LISTENERS][payload.action]) {
let result = false

try {
result = model[Sym.LISTENERS][payload.action](payload.data)
} catch (e) {
Expand All @@ -46,7 +51,11 @@ class AltStore {
}

if (result !== false) {
this.emitChange()
if (isPromise(result)) {
result.then(this.emitChange.bind(this))
} else {
this.emitChange()
}
}
}

Expand All @@ -55,6 +64,8 @@ class AltStore {
payload,
this[Sym.STATE_CONTAINER]
)

return result
})

this[Sym.LIFECYCLE].emit('init')
Expand Down
61 changes: 61 additions & 0 deletions src/utils/PromiseDispatcher.js
@@ -0,0 +1,61 @@
import Symbol from 'es-symbol'

const ID = Symbol()
const FNS = Symbol()

class PromiseDispatcher {
constructor() {
this.dispatching = false
this[ID] = 0
this[FNS] = {}
}

register(promise) {
const id = `token#${this[ID]++}`
this[FNS][id] = promise
return id
}

unregister(id) {
delete this[FNS][id]
}

waitFor(context, ids) {
return new Promise((resolve) => {
// defer the resolution to make sure all the promises are in context
setTimeout(() => {
resolve(Promise.all(ids.map((id) => {
return context[id]
})))
})
})
}

dispatch(payload) {
this.dispatching = true

// evaluate all promises
const promises = Object.keys(this[FNS]).reduce((obj, id) => {
obj[id] = this[FNS][id](payload, obj)
return obj
}, {})

// aggregate them
const all = Object.keys(promises).reduce((arr, id) => {
const value = promises[id]
return arr.concat(value)
}, [])

// dispatch
return Promise.all(all).then((value) => {
this.dispatching = false
return value
})
}

isDispatching() {
return this.dispatching
}
}

export default PromiseDispatcher

0 comments on commit bd434f3

Please sign in to comment.