-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
bindAsyncAction
helper for redux-saga
- Loading branch information
Showing
17 changed files
with
2,418 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,6 @@ | |
# NPM | ||
node_modules | ||
npm-*.log | ||
yarn.lock | ||
|
||
tests-build | ||
|
||
# OS X | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,5 +5,5 @@ node_js: | |
|
||
script: | ||
- npm run lint | ||
- npm run build | ||
- npm test | ||
- npm run build |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
export function isType(action, actionCreator) { | ||
return action.type === actionCreator.type; | ||
} | ||
export default function actionCreatorFactory(prefix, defaultIsError = p => p instanceof Error) { | ||
const actionTypes = {}; | ||
const base = prefix ? `${prefix}/` : ""; | ||
function actionCreator(type, commonMeta, isError = defaultIsError) { | ||
const fullType = base + type; | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (actionTypes[fullType]) | ||
throw new Error(`Duplicate action type: ${fullType}`); | ||
actionTypes[fullType] = true; | ||
} | ||
return Object.assign((payload, meta) => { | ||
const action = { | ||
type: fullType, | ||
payload, | ||
}; | ||
if (commonMeta || meta) { | ||
action.meta = Object.assign({}, commonMeta, meta); | ||
} | ||
if (isError && (typeof isError === 'boolean' || isError(payload))) { | ||
action.error = true; | ||
} | ||
return action; | ||
}, { type: fullType }); | ||
} | ||
function asyncActionCreators(type, commonMeta) { | ||
return { | ||
type: base + type, | ||
started: actionCreator(`${type}_STARTED`, commonMeta, false), | ||
done: actionCreator(`${type}_DONE`, commonMeta, false), | ||
failed: actionCreator(`${type}_FAILED`, commonMeta, true), | ||
}; | ||
} | ||
return Object.assign(actionCreator, { async: asyncActionCreators }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { AsyncActionCreators } from "./index"; | ||
import { SagaIterator } from "redux-saga"; | ||
export declare function bindAsyncAction<R>(actionCreators: AsyncActionCreators<void, R, any>): { | ||
(worker: () => Promise<R> | SagaIterator): () => SagaIterator; | ||
(worker: (params: void) => Promise<R> | SagaIterator): (params: void) => SagaIterator; | ||
<A1>(worker: (params: void, arg1: A1) => Promise<R> | SagaIterator): (params: void, arg1: A1) => SagaIterator; | ||
<A1, A2>(worker: (params: void, arg1: A1, arg2: A2) => Promise<R> | SagaIterator): (params: void, arg1: A1, arg2: A2) => SagaIterator; | ||
<A1, A2, A3>(worker: (params: void, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => Promise<R> | SagaIterator): (params: void, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => SagaIterator; | ||
}; | ||
export declare function bindAsyncAction<P, R>(actionCreators: AsyncActionCreators<P, R, any>): { | ||
(worker: (params: P) => Promise<R> | SagaIterator): (params: P) => SagaIterator; | ||
<A1>(worker: (params: P, arg1: A1) => Promise<R> | SagaIterator): (params: P, arg1: A1) => SagaIterator; | ||
<A1, A2>(worker: (params: P, arg1: A1, arg2: A2) => Promise<R> | SagaIterator): (params: P, arg1: A1, arg2: A2) => SagaIterator; | ||
<A1, A2, A3>(worker: (params: P, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => Promise<R> | SagaIterator): (params: P, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => SagaIterator; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { put, call, cancelled } from "redux-saga/effects"; | ||
export function bindAsyncAction(actionCreator) { | ||
return (worker) => { | ||
function* boundAsyncActionSaga(params, ...args) { | ||
yield put(actionCreator.started(params)); | ||
try { | ||
const result = yield call(worker, params, ...args); | ||
yield put(actionCreator.done({ params, result })); | ||
return result; | ||
} | ||
catch (error) { | ||
yield put(actionCreator.failed({ params, error })); | ||
throw error; | ||
} | ||
finally { | ||
if (yield cancelled()) { | ||
yield put(actionCreator.failed({ params, error: 'cancelled' })); | ||
} | ||
} | ||
} | ||
const capName = worker.name.charAt(0).toUpperCase() + | ||
worker.name.substring(1); | ||
return setFunctionName(boundAsyncActionSaga, `bound${capName}(${actionCreator.type})`); | ||
}; | ||
} | ||
/** | ||
* Set function name. | ||
* | ||
* Note that this won't have effect on built-in Chrome stack traces, although | ||
* useful for traces generated by `redux-saga`. | ||
*/ | ||
function setFunctionName(func, name) { | ||
try { | ||
Object.defineProperty(func, 'name', { | ||
value: name, | ||
configurable: true, | ||
}); | ||
} | ||
catch (e) { | ||
} | ||
return func; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { Action as ReduxAction } from "redux"; | ||
export interface Action<P> extends ReduxAction { | ||
type: string; | ||
payload: P; | ||
error?: boolean; | ||
meta?: Object; | ||
} | ||
export interface Success<P, S> { | ||
params: P; | ||
result: S; | ||
} | ||
export interface Failure<P, E> { | ||
params: P; | ||
error: E; | ||
} | ||
export declare function isType<P>(action: ReduxAction, actionCreator: ActionCreator<P>): action is Action<P>; | ||
export interface ActionCreator<P> { | ||
type: string; | ||
(payload: P, meta?: Object): Action<P>; | ||
} | ||
export interface EmptyActionCreator extends ActionCreator<undefined> { | ||
(payload?: undefined, meta?: Object): Action<undefined>; | ||
} | ||
export interface AsyncActionCreators<P, S, E> { | ||
type: string; | ||
started: ActionCreator<P>; | ||
done: ActionCreator<Success<P, S>>; | ||
failed: ActionCreator<Failure<P, E>>; | ||
} | ||
export interface ActionCreatorFactory { | ||
(type: string, commonMeta?: Object, error?: boolean): EmptyActionCreator; | ||
<P>(type: string, commonMeta?: Object, isError?: boolean): ActionCreator<P>; | ||
<P>(type: string, commonMeta?: Object, isError?: (payload: P) => boolean): ActionCreator<P>; | ||
async<P, S>(type: string, commonMeta?: Object): AsyncActionCreators<P, S, any>; | ||
async<P, S, E>(type: string, commonMeta?: Object): AsyncActionCreators<P, S, E>; | ||
} | ||
export default function actionCreatorFactory(prefix?: string, defaultIsError?: (payload: any) => boolean): ActionCreatorFactory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { AsyncActionCreators } from "./index"; | ||
import { SagaIterator } from "redux-saga"; | ||
export declare function bindAsyncAction<R>(actionCreators: AsyncActionCreators<void, R, any>): { | ||
(worker: () => Promise<R> | SagaIterator): () => SagaIterator; | ||
(worker: (params: void) => Promise<R> | SagaIterator): (params: void) => SagaIterator; | ||
<A1>(worker: (params: void, arg1: A1) => Promise<R> | SagaIterator): (params: void, arg1: A1) => SagaIterator; | ||
<A1, A2>(worker: (params: void, arg1: A1, arg2: A2) => Promise<R> | SagaIterator): (params: void, arg1: A1, arg2: A2) => SagaIterator; | ||
<A1, A2, A3>(worker: (params: void, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => Promise<R> | SagaIterator): (params: void, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => SagaIterator; | ||
}; | ||
export declare function bindAsyncAction<P, R>(actionCreators: AsyncActionCreators<P, R, any>): { | ||
(worker: (params: P) => Promise<R> | SagaIterator): (params: P) => SagaIterator; | ||
<A1>(worker: (params: P, arg1: A1) => Promise<R> | SagaIterator): (params: P, arg1: A1) => SagaIterator; | ||
<A1, A2>(worker: (params: P, arg1: A1, arg2: A2) => Promise<R> | SagaIterator): (params: P, arg1: A1, arg2: A2) => SagaIterator; | ||
<A1, A2, A3>(worker: (params: P, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => Promise<R> | SagaIterator): (params: P, arg1: A1, arg2: A2, arg3: A3, ...rest: any[]) => SagaIterator; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
'use strict'; | ||
|
||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.bindAsyncAction = bindAsyncAction; | ||
|
||
var _effects = require('redux-saga/effects'); | ||
|
||
function bindAsyncAction(actionCreator) { | ||
return function (worker) { | ||
var _marked = [boundAsyncActionSaga].map(regeneratorRuntime.mark); | ||
|
||
function boundAsyncActionSaga(params) { | ||
var _len, | ||
args, | ||
_key, | ||
result, | ||
_args = arguments; | ||
|
||
return regeneratorRuntime.wrap(function boundAsyncActionSaga$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.next = 2; | ||
return (0, _effects.put)(actionCreator.started(params)); | ||
|
||
case 2: | ||
_context.prev = 2; | ||
|
||
for (_len = _args.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = _args[_key]; | ||
} | ||
|
||
_context.next = 6; | ||
return _effects.call.apply(undefined, [worker, params].concat(args)); | ||
|
||
case 6: | ||
result = _context.sent; | ||
_context.next = 9; | ||
return (0, _effects.put)(actionCreator.done({ params: params, result: result })); | ||
|
||
case 9: | ||
return _context.abrupt('return', result); | ||
|
||
case 12: | ||
_context.prev = 12; | ||
_context.t0 = _context['catch'](2); | ||
_context.next = 16; | ||
return (0, _effects.put)(actionCreator.failed({ params: params, error: _context.t0 })); | ||
|
||
case 16: | ||
throw _context.t0; | ||
|
||
case 17: | ||
_context.prev = 17; | ||
_context.next = 20; | ||
return (0, _effects.cancelled)(); | ||
|
||
case 20: | ||
if (!_context.sent) { | ||
_context.next = 23; | ||
break; | ||
} | ||
|
||
_context.next = 23; | ||
return (0, _effects.put)(actionCreator.failed({ params: params, error: 'cancelled' })); | ||
|
||
case 23: | ||
return _context.finish(17); | ||
|
||
case 24: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
} | ||
}, _marked[0], this, [[2, 12, 17, 24]]); | ||
} | ||
var capName = worker.name.charAt(0).toUpperCase() + worker.name.substring(1); | ||
return setFunctionName(boundAsyncActionSaga, 'bound' + capName + '(' + actionCreator.type + ')'); | ||
}; | ||
} | ||
/** | ||
* Set function name. | ||
* | ||
* Note that this won't have effect on built-in Chrome stack traces, although | ||
* useful for traces generated by `redux-saga`. | ||
*/ | ||
function setFunctionName(func, name) { | ||
try { | ||
Object.defineProperty(func, 'name', { | ||
value: name, | ||
configurable: true | ||
}); | ||
} catch (e) {} | ||
return func; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.