Skip to content
Permalink
Browse files

feat(action-creator): Pass the only function when the asynchronous pr…

…ocessing
  • Loading branch information...
rymizuki committed Mar 25, 2016
1 parent bbf1cdf commit 1efcb26b57618c25905f333514c647ea35273bac
Showing with 78 additions and 49 deletions.
  1. +3 −3 README.md
  2. +3 −3 examples/todo/js/todo.js
  3. +15 −9 script/syntagme/action-creator.js
  4. +18 −9 syntagme.js
  5. +39 −25 test/syntagme-ac-spec.js
@@ -19,15 +19,15 @@ import syntagme from 'syntagme'
syntagme.reducer(function counterReducer (payload, previous_state={}) {
switch (payload.action.type) {
case 'INCREMENT':
return Object.assign({}, previous_state, { count: (previous_state.count || 0) + 1 })
return Object.assign({}, previous_state, { count: payload.action.value + 1 })
}
})
syntagme.subscribe(function listener (state) {
console.log('count:', state.count)
})
syntagme.ac('INCREMENT') // count: 1
syntagme.ac('INCREMENT', {value: 1}) // count: 2
```

### Promise on ActionCreator
@@ -65,7 +65,7 @@ syntagme.ac('FETCH', function createAction () {

### syntagme.reducer(reducer)

### syntagme.ac(action_type [, fn])
### syntagme.ac(action_type [, object|promisify])

## License

@@ -27,13 +27,13 @@ flux.reducer(function textReducer (payload, previous) {

var ac = (function () {
function add (text) {
flux.ac('ADD_TODO', function () { return {item: {title: text}} })
flux.ac('ADD_TODO', {item: {title: text}})
}
function edit (value) {
flux.ac('INPUT_TEXT', function () { return {text: value} })
flux.ac('INPUT_TEXT', {text: value})
}
function toggle (item) {
flux.ac('TOGGLE_STATE', function () { return {item: item} })
flux.ac('TOGGLE_STATE', {item: item})
}
return { add: add, edit: edit, toggle: toggle, }
}())
@@ -1,33 +1,39 @@
export default function actionCreator (type, fn) {
var result = fn()
if (result && 'function' == typeof result.then) {
export default function actionCreator (type, stuff) {
if ('function' === typeof stuff) {
this.dispatch({
source: 'ACTION',
source: 'ASYNC_ACTION',
action: { type }
})
var result = stuff()
if (null == result || 'function' !== typeof result.then) {
throw new Error('Action must be return promise object.')
}
return result
.then((action) => {
if (null == action.type) {
action.type = (type + this.config.prefix.RESOLVE)
}
this.dispatch({
source: 'ACTION_RESOLVE',
source: 'ASYNC_ACTION_RESOLVE',
action,
})
return action
})
.catch((rejection) => {
this.dispatch({
source: 'ACTION_REJECT',
source: 'ASYNC_ACTION_REJECT',
action: { type: (type + this.config.prefix.REJECT), rejection }
})
return rejection
})
} else {
if (null == result.type) {
result.type = type
if ('object' !== typeof stuff || Array.isArray(stuff)) {
throw new Error('Action must be Object or Function.')
}
if (null == stuff.type) {
stuff.type = type
}
this.dispatch({ source: 'ACTION', action: result, })
this.dispatch({ source: 'ACTION', action: stuff, })
}
return result
}
@@ -334,37 +334,46 @@ return /******/ (function(modules) { // webpackBootstrap
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 = actionCreator;
function actionCreator(type, fn) {
function actionCreator(type, stuff) {
var _this = this;

var result = fn();
if (result && 'function' == typeof result.then) {
if ('function' === typeof stuff) {
this.dispatch({
source: 'ACTION',
source: 'ASYNC_ACTION',
action: { type: type }
});
var result = stuff();
if (null == result || 'function' !== typeof result.then) {
throw new Error('Action must be return promise object.');
}
return result.then(function (action) {
if (null == action.type) {
action.type = type + _this.config.prefix.RESOLVE;
}
_this.dispatch({
source: 'ACTION_RESOLVE',
source: 'ASYNC_ACTION_RESOLVE',
action: action
});
return action;
}).catch(function (rejection) {
_this.dispatch({
source: 'ACTION_REJECT',
source: 'ASYNC_ACTION_REJECT',
action: { type: type + _this.config.prefix.REJECT, rejection: rejection }
});
return rejection;
});
} else {
if (null == result.type) {
result.type = type;
if ('object' !== (typeof stuff === 'undefined' ? 'undefined' : _typeof(stuff)) || Array.isArray(stuff)) {
throw new Error('Action must be Object or Function.');
}
if (null == stuff.type) {
stuff.type = type;
}
this.dispatch({ source: 'ACTION', action: result });
this.dispatch({ source: 'ACTION', action: stuff });
}
return result;
}
@@ -8,30 +8,45 @@ describe('syntagme.ac', function () {
sinon.stub(this.syntagme, 'dispatch')
})

describe('single action', function () {
describe('styntagme.dispatch', function () {
beforeEach(function () {
this.syntagme.ac('TEST', function () {
return {name: 'a'}
})
})
it('should be true', function () {
assert.ok(this.syntagme.dispatch.calledOnce)
})

describe('action.type', function () {
it('should be "TEST"', function () {
assert.equal('TEST', this.syntagme.dispatch.args[0][0].action.type)
})
describe('args typeof string', function () {
it('should be throws', function () {
assert.throws(() => {
this.syntagme.ac('TEST', 'action')
}, /Action must be Object or Function/)
})
})
describe('args typeof array', function () {
it('should be throws', function () {
assert.throws(() => {
this.syntagme.ac('TEST', [{name: 'a'}])
}, /Action must be Object or Function/)
})
})
describe('args object', function () {
beforeEach(function () {
this.syntagme.ac('TEST', {name: 'a'})
})
it('should be true', function () {
assert.ok(this.syntagme.dispatch.calledOnce)
})
describe('action.type', function () {
it('should be "TEST"', function () {
assert.equal('TEST', this.syntagme.dispatch.args[0][0].action.type)
})

describe('action.name', function () {
it('should be "a"', function () {
assert.equal('a', this.syntagme.dispatch.args[0][0].action.name)
})
})
describe('action.name', function () {
it('should be "a"', function () {
assert.equal('a', this.syntagme.dispatch.args[0][0].action.name)
})
})
})
describe('args not promisify function', function () {
it('should be throws', function () {
assert.throws(() => {
this.syntagme.ac('TEST', function () { return null })
}, /Action must be return promise object/)
})
})
describe('promise action', function () {
describe('syntagme.dispatch', function () {
describe('resolved', function () {
@@ -42,7 +57,6 @@ describe('syntagme.ac', function () {
})
})
})

describe('called twice', function () {
it('should be true', function () {
assert.equal(2, this.syntagme.dispatch.callCount)
@@ -52,7 +66,7 @@ describe('syntagme.ac', function () {
describe('action', function () {
it('should be "TEST"', function () {
assert.deepEqual({
source: "ACTION",
source: "ASYNC_ACTION",
action: { type: "TEST" }
}, this.syntagme.dispatch.args[0][0])
})
@@ -62,7 +76,7 @@ describe('syntagme.ac', function () {
describe('action', function () {
it('should be "TEST"', function () {
assert.deepEqual({
source: "ACTION_RESOLVE",
source: "ASYNC_ACTION_RESOLVE",
action: {
type: "TEST_RESOLVE",
name: "a",
@@ -88,15 +102,15 @@ describe('syntagme.ac', function () {
describe('initial action', function () {
it('should be "TEST"', function () {
assert.deepEqual({
source: 'ACTION',
source: 'ASYNC_ACTION',
action: { type: 'TEST' },
}, this.syntagme.dispatch.args[0][0])
})
})
describe('reject action', function () {
it('should be TEST_REJECT', function () {
assert.deepEqual({
source: 'ACTION_REJECT',
source: 'ASYNC_ACTION_REJECT',
action: {
type: 'TEST_REJECT',
rejection: { name: 'a' },

0 comments on commit 1efcb26

Please sign in to comment.
You can’t perform that action at this time.