Comparing version 0.5.2 to 0.5.3
# Change Log | ||
## 0.5.3 | ||
### Features | ||
* [#263] Action tracing: added `actionContext.id` and `actionContext.stack` | ||
## 0.5.2 | ||
@@ -4,0 +10,0 @@ |
@@ -9,2 +9,3 @@ /** | ||
var isPromise = require('is-promise'); | ||
var objectAssign = require('object-assign'); | ||
var PromiseLib = (global && global.Promise) || require('es6-promise').Promise; | ||
@@ -106,22 +107,29 @@ var React = require('react'); | ||
* due to the try/catch | ||
* @param {Object} context FluxContext object | ||
* @param {Object} actionContext FluxContext object | ||
* @param {Function} action Action to call | ||
* @param {Object} payload Payload for the action | ||
* @param {Function} resolve function to call on success | ||
* @param {Function} reject function to call on failure | ||
* @private | ||
*/ | ||
function executeActionInternal(context, action, payload, resolve, reject) { | ||
var syncResult = action(context.getActionContext(), payload, function (err, result) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
function callAction(actionContext, action, payload) { | ||
var Promise = FluxContext.Promise; | ||
return new Promise(function (resolve, reject) { | ||
setImmediate(function () { | ||
try { | ||
var syncResult = action(actionContext, payload, function (err, result) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
}); | ||
if (isPromise(syncResult)) { | ||
syncResult.then(resolve, reject); | ||
} else if (action.length < 3) { | ||
resolve(syncResult); | ||
} | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
}); | ||
if (isPromise(syncResult)) { | ||
syncResult.then(resolve, reject); | ||
} else if (action.length < 3) { | ||
resolve(syncResult); | ||
} | ||
} | ||
@@ -135,2 +143,4 @@ | ||
* If the action throws an error, the promise will be rejected with the thrown value | ||
* @param {Object} context The current FluxibleContext | ||
* @param {Object} actionContext The current action context | ||
* @param {Function} action An action creator function that receives actionContext, payload, | ||
@@ -142,11 +152,9 @@ * and done as parameters | ||
*/ | ||
FluxContext.prototype.executeAction = function executeAction(action, payload, done) { | ||
var self = this; | ||
function executeActionProxy(context, actionContext, action, payload, done) { | ||
payload = (undefined !== payload) ? payload : {}; | ||
var displayName = action.displayName || action.name; | ||
var Promise = FluxContext.Promise; | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (this._dispatcher && this._dispatcher.currentAction) { | ||
var currentActionDisplayName = this._dispatcher.currentAction.displayName || | ||
this._dispatcher.currentAction.name; | ||
if (context._dispatcher && context._dispatcher.currentAction) { | ||
var currentActionDisplayName = context._dispatcher.currentAction.displayName || | ||
context._dispatcher.currentAction.name; | ||
@@ -160,12 +168,21 @@ console.warn('Warning: executeAction for `' + displayName + '` was called, but `' + | ||
var executeActionPromise = new Promise(function executeActionPromise(resolve, reject) { | ||
debug('Executing action ' + displayName + ' with payload', payload); | ||
setImmediate(function () { | ||
try { | ||
executeActionInternal(self, action, payload, resolve, reject); | ||
} catch (err) { | ||
reject(err); | ||
} | ||
}); | ||
/* | ||
* We store the action's stack array on the `stack` property | ||
* of the actionContext interface. | ||
* You can access this in your actions with `context.stack`. | ||
* Use the `displayName` property on your actions for better | ||
* action tracing when your code gets minified in prod. | ||
* One action can execute multiple actions, so we need to create a shallow | ||
* clone with a new stack & new id every time getActionContext is called. | ||
* We expect next to be defined in most cases (by callAction) | ||
* unless the user calls `getActionContext` manually. | ||
*/ | ||
var newActionContext = objectAssign({}, actionContext, { | ||
stack: (actionContext.stack || []).concat([displayName]), | ||
rootId: (actionContext.rootId) || generateUUID() | ||
}); | ||
if (debug.enabled) { | ||
debug('Executing action ' + newActionContext.stack.join('.') + ' with payload', payload); | ||
} | ||
var executeActionPromise = callAction(newActionContext, action, payload); | ||
@@ -184,2 +201,15 @@ if (done) { | ||
return executeActionPromise; | ||
} | ||
/** | ||
* Proxy function for executing an action. | ||
* @param {Function} action An action creator function that receives actionContext, payload, | ||
* and done as parameters | ||
* @param {Object} payload The action payload | ||
* @param {Function} [done] Method to be called once action execution has completed | ||
* @return {Promise} executeActionPromise Resolved with action result or rejected with action error | ||
*/ | ||
FluxContext.prototype.executeAction = function executeAction(action, payload, done) { | ||
return executeActionProxy(this, this.getActionContext(), action, payload, done); | ||
}; | ||
@@ -202,25 +232,27 @@ | ||
FluxContext.prototype.getActionContext = function getActionContext() { | ||
if (this._actionContext) { | ||
return this._actionContext; | ||
} | ||
var self = this; | ||
if (!self._dispatcher) { | ||
self._initializeDispatcher(); | ||
} | ||
if (!self._actionContext) { | ||
if (!self._dispatcher) { | ||
self._initializeDispatcher(); | ||
} | ||
var actionContext = { | ||
dispatch: this._dispatcher.dispatch.bind(this._dispatcher), | ||
executeAction: this.executeAction.bind(this), | ||
getStore: this._dispatcher.getStore.bind(this._dispatcher) | ||
}; | ||
var actionContext = { | ||
dispatch: self._dispatcher.dispatch.bind(self._dispatcher), | ||
executeAction: function actionExecuteAction (action, payload, callback) { | ||
// `this` will be the current action context | ||
return executeActionProxy(self, this, action, payload, callback); | ||
}, | ||
getStore: self._dispatcher.getStore.bind(self._dispatcher) | ||
}; | ||
self._plugins.forEach(function pluginsEach(plugin) { | ||
var actionContextPlugin = plugin.plugActionContext; | ||
if (actionContextPlugin) { | ||
actionContextPlugin(actionContext, self, self._app); | ||
} | ||
}); | ||
self._plugins.forEach(function pluginsEach(plugin) { | ||
var actionContextPlugin = plugin.plugActionContext; | ||
if (actionContextPlugin) { | ||
actionContextPlugin(actionContext, self, self._app); | ||
} | ||
}); | ||
self._actionContext = actionContext; | ||
self._actionContext = actionContext; | ||
} | ||
@@ -230,2 +262,12 @@ return self._actionContext; | ||
/* | ||
* Generate a GUID for keeping track of a | ||
* transaction of actions and dispatches. | ||
* Reference: https://github.com/facebook/react/blob/a48ffb04dcfe4d6f832207618a8b39e3034bd413/src/renderers/dom/server/ServerReactRootIndex.js | ||
*/ | ||
var GLOBAL_UUID_MAX = Math.pow(2, 53); | ||
function generateUUID () { | ||
return Math.ceil(Math.random() * GLOBAL_UUID_MAX); | ||
} | ||
/** | ||
@@ -232,0 +274,0 @@ * Returns the context for action controllers |
{ | ||
"name": "fluxible", | ||
"version": "0.5.2", | ||
"version": "0.5.3", | ||
"description": "A pluggable container for isomorphic flux applications", | ||
@@ -25,2 +25,3 @@ "main": "index.js", | ||
"devDependencies": { | ||
"async": "^1.4.2", | ||
"babel": "^5.0.2", | ||
@@ -27,0 +28,0 @@ "chai": "^3.2.0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44258
769
12