Skip to content

Commit 5d2fd58

Browse files
committed
[release] 1.1.0
1 parent 6685c12 commit 5d2fd58

File tree

4 files changed

+91
-43
lines changed

4 files changed

+91
-43
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
## 1.1.0 (proposed)
1+
## 1.1.0
22

33
- **[NEW]** added `Reactor#serialize`, `Reactor#loadState`, `Store#serialize` and `Store#deserialize` methods
44
- **[NEW]** added `Reactor#batch` to allow batch dispatches before notify observers
5+
- **[NEW]** throw error when trying to dispatch within a dispatch
56
- **[FIXED]** fix Evaluator locking if getter evaluation errors
67

78
### API Additions

dist/nuclear.js

+85-38
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ return /******/ (function(modules) { // webpackBootstrap
108108

109109
/**
110110
* Returns true if the value is an ImmutableJS data structure
111-
* or a javascript primitive that is immutable (stirng, number, etc)
111+
* or a JavaScript primitive that is immutable (string, number, etc)
112112
* @param {*} obj
113113
* @return {boolean}
114114
*/
@@ -124,7 +124,7 @@ return /******/ (function(modules) { // webpackBootstrap
124124
* Can be called on any type
125125
*/
126126
function toJS(arg) {
127-
// arg instanceof Immutable.Sequence is unreleable
127+
// arg instanceof Immutable.Sequence is unreliable
128128
return (isImmutable(arg))
129129
? arg.toJS()
130130
: arg
@@ -5100,7 +5100,7 @@ return /******/ (function(modules) { // webpackBootstrap
51005100
return objectToString(val) === '[object Array]'
51015101
}
51025102

5103-
// taken from underscore source to account for browser descrepency
5103+
// taken from underscore source to account for browser discrepancy
51045104
/* istanbul ignore if */
51055105
if (typeof /./ !== 'function' && typeof Int8Array !== 'object') {
51065106
/**
@@ -5123,7 +5123,7 @@ return /******/ (function(modules) { // webpackBootstrap
51235123
}
51245124

51255125
/**
5126-
* Checks if the passed in value is af type Object
5126+
* Checks if the passed in value is of type Object
51275127
* @param {*} val
51285128
* @return {boolean}
51295129
*/
@@ -5274,7 +5274,7 @@ return /******/ (function(modules) { // webpackBootstrap
52745274

52755275

52765276
/**
5277-
* In Nuclear Reactors are where state is stored. Reactors
5277+
* State is stored in NuclearJS Reactors. Reactors
52785278
* contain a 'state' object which is an Immutable.Map
52795279
*
52805280
* The only way Reactors can change state is by reacting to
@@ -5308,8 +5308,13 @@ return /******/ (function(modules) { // webpackBootstrap
53085308
*/
53095309
this.__changeObserver = new ChangeObserver(this.state, this.__evaluator)
53105310

5311-
this.__isBatching = false;
5312-
this.__batchDispatchCount = 0;
5311+
// keep track of the depth of batch nesting
5312+
this.__batchDepth = 0
5313+
// number of dispatches in the top most batch cycle
5314+
this.__batchDispatchCount = 0
5315+
5316+
// keep track if we are currently dispatching
5317+
this.__isDispatching = false
53135318
}
53145319

53155320
/**
@@ -5363,13 +5368,36 @@ return /******/ (function(modules) { // webpackBootstrap
53635368
* @param {object|undefined} payload
53645369
*/
53655370
Object.defineProperty(Reactor.prototype,"dispatch",{writable:true,configurable:true,value:function(actionType, payload) {"use strict";
5371+
if (this.__batchDepth === 0) {
5372+
if (this.__isDispatching) {
5373+
this.__isDispatching = false
5374+
throw new Error('Dispatch may not be called while a dispatch is in progress')
5375+
}
5376+
this.__isDispatching = true
5377+
}
5378+
53665379
var prevState = this.state
5367-
this.state = this.__handleAction(prevState, actionType, payload)
53685380

5369-
if (this.__isBatching) {
5381+
try {
5382+
this.state = this.__handleAction(prevState, actionType, payload)
5383+
} catch (e) {
5384+
this.__isDispatching = false
5385+
throw e
5386+
}
5387+
5388+
5389+
if (this.__batchDepth > 0) {
53705390
this.__batchDispatchCount++
5371-
} else if (this.state !== prevState) {
5372-
this.__notify()
5391+
} else {
5392+
if (this.state !== prevState) {
5393+
try {
5394+
this.__notify()
5395+
} catch (e) {
5396+
this.__isDispatching = false
5397+
throw e
5398+
}
5399+
}
5400+
this.__isDispatching = false
53735401
}
53745402
}});
53755403

@@ -5429,7 +5457,10 @@ return /******/ (function(modules) { // webpackBootstrap
54295457
var serialized = {}
54305458
this.__stores.forEach(function(store, id) {
54315459
var storeState = this.state.get(id)
5432-
serialized[id] = store.serialize(storeState)
5460+
var serializedState = store.serialize(storeState)
5461+
if (serializedState !== undefined) {
5462+
serialized[id] = serializedState
5463+
}
54335464
}.bind(this))
54345465
return serialized
54355466
}});
@@ -5442,7 +5473,10 @@ return /******/ (function(modules) { // webpackBootstrap
54425473
each(state, function(serializedStoreState, storeId) {
54435474
var store = this.__stores.get(storeId)
54445475
if (store) {
5445-
stateToLoad.set(storeId, store.deserialize(serializedStoreState))
5476+
var storeState = store.deserialize(serializedStoreState)
5477+
if (storeState !== undefined) {
5478+
stateToLoad.set(storeId, storeState)
5479+
}
54465480
}
54475481
}.bind(this))
54485482
}.bind(this))
@@ -5484,7 +5518,6 @@ return /******/ (function(modules) { // webpackBootstrap
54845518
this.__changeObserver.notifyObservers(this.state)
54855519
}});
54865520

5487-
54885521
/**
54895522
* Reduces the current state to the new state given actionType / message
54905523
* @param {string} actionType
@@ -5497,15 +5530,23 @@ return /******/ (function(modules) { // webpackBootstrap
54975530
logging.dispatchStart(actionType, payload)
54985531
}
54995532

5500-
// let each core handle the message
5533+
// let each store handle the message
55015534
this.__stores.forEach(function(store, id) {
55025535
var currState = state.get(id)
5503-
var newState = store.handle(currState, actionType, payload)
5536+
var newState
5537+
5538+
try {
5539+
newState = store.handle(currState, actionType, payload)
5540+
} catch(e) {
5541+
// ensure console.group is properly closed
5542+
logging.dispatchError(e.message)
5543+
throw e
5544+
}
55045545

55055546
if (this.debug && newState === undefined) {
5506-
var error = 'Store handler must return a value, did you forget a return statement'
5507-
logging.dispatchError(error)
5508-
throw new Error(error)
5547+
var errorMsg = 'Store handler must return a value, did you forget a return statement'
5548+
logging.dispatchError(errorMsg)
5549+
throw new Error(errorMsg)
55095550
}
55105551

55115552
state.set(id, newState)
@@ -5522,19 +5563,24 @@ return /******/ (function(modules) { // webpackBootstrap
55225563
}});
55235564

55245565
Object.defineProperty(Reactor.prototype,"__batchStart",{writable:true,configurable:true,value:function() {"use strict";
5525-
if (this.__isBatching) {
5526-
throw new Error('Reactor already in batch mode')
5527-
}
5528-
this.__isBatching = true
5566+
this.__batchDepth++
55295567
}});
55305568

55315569
Object.defineProperty(Reactor.prototype,"__batchEnd",{writable:true,configurable:true,value:function() {"use strict";
5532-
if (!this.__isBatching) {
5533-
throw new Error('Reactor is not in batch mode')
5534-
}
5535-
5536-
if (this.__batchDispatchCount > 0) {
5537-
this.__notify()
5570+
this.__batchDepth--
5571+
5572+
if (this.__batchDepth <= 0) {
5573+
if (this.__batchDispatchCount > 0) {
5574+
// set to true to catch if dispatch called from observer
5575+
this.__isDispatching = true
5576+
try {
5577+
this.__notify()
5578+
} catch (e) {
5579+
this.__isDispatching = false
5580+
throw e
5581+
}
5582+
this.__isDispatching = false
5583+
}
55385584
this.__batchDispatchCount = 0
55395585
}
55405586
}});
@@ -5644,7 +5690,7 @@ return /******/ (function(modules) { // webpackBootstrap
56445690
}});
56455691

56465692
/**
5647-
* Specify an getter and a change handler fn
5693+
* Specify a getter and a change handler function
56485694
* Handler function is called whenever the value of the getter changes
56495695
* @param {Getter} getter
56505696
* @param {function} handler
@@ -5900,9 +5946,10 @@ return /******/ (function(modules) { // webpackBootstrap
59005946
throw new Error('Evaluate may not be called within a Getters computeFn')
59015947
}
59025948

5949+
var evaluatedValue
59035950
__applyingComputeFn = true
59045951
try {
5905-
var evaluatedValue = getComputeFn(keyPathOrGetter).apply(null, args)
5952+
evaluatedValue = getComputeFn(keyPathOrGetter).apply(null, args)
59065953
__applyingComputeFn = false
59075954
} catch (e) {
59085955
__applyingComputeFn = false
@@ -5962,7 +6009,7 @@ return /******/ (function(modules) { // webpackBootstrap
59626009
* @param {Getter}
59636010
*/
59646011
Object.defineProperty(Evaluator.prototype,"untrack",{writable:true,configurable:true,value:function(getter) {"use strict";
5965-
// TODO: untrack all depedencies
6012+
// TODO: untrack all dependencies
59666013
}});
59676014

59686015
Object.defineProperty(Evaluator.prototype,"reset",{writable:true,configurable:true,value:function() {"use strict";
@@ -6053,7 +6100,7 @@ return /******/ (function(modules) { // webpackBootstrap
60536100
}
60546101

60556102
/**
6056-
* This method is overriden by extending classses to setup message handlers
6103+
* This method is overridden by extending classes to setup message handlers
60576104
* via `this.on` and to set up the initial state
60586105
*
60596106
* Anything returned from this function will be coerced into an ImmutableJS value
@@ -6086,7 +6133,7 @@ return /******/ (function(modules) { // webpackBootstrap
60866133

60876134
/**
60886135
* Pure function taking the current state of store and returning
6089-
* the new state after a Nuclear reactor has been reset
6136+
* the new state after a NuclearJS reactor has been reset
60906137
*
60916138
* Overridable
60926139
*/
@@ -6102,23 +6149,23 @@ return /******/ (function(modules) { // webpackBootstrap
61026149
}});
61036150

61046151
/**
6105-
* Serializes store state to plain JSON serializable javascript
6152+
* Serializes store state to plain JSON serializable JavaScript
61066153
* Overridable
61076154
* @param {*}
61086155
* @return {*}
61096156
*/
61106157
Object.defineProperty(Store.prototype,"serialize",{writable:true,configurable:true,value:function(state) {"use strict";
6111-
return toJS(state);
6158+
return toJS(state)
61126159
}});
61136160

61146161
/**
6115-
* Deserializes plain javascript to store state
6162+
* Deserializes plain JavaScript to store state
61166163
* Overridable
61176164
* @param {*}
61186165
* @return {*}
61196166
*/
61206167
Object.defineProperty(Store.prototype,"deserialize",{writable:true,configurable:true,value:function(state) {"use strict";
6121-
return toImmutable(state);
6168+
return toImmutable(state)
61226169
}});
61236170

61246171

dist/nuclear.min.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nuclear-js",
3-
"version": "1.0.5",
3+
"version": "1.1.0",
44
"description": "Immutable, reactive Flux architecture. UI Agnostic.",
55
"main": "dist/nuclear.js",
66
"scripts": {

0 commit comments

Comments
 (0)