Skip to content

Commit

Permalink
Merge pull request #6 from lexich/syncing
Browse files Browse the repository at this point in the history
Syncing
  • Loading branch information
lexich committed Sep 2, 2015
2 parents b682d0b + bf9b99c commit 61452bf
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 123 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,26 @@ React.render(
);
```
### Store state schema
```js
const rest = reduxApi({
user: "/user/1"
});
```
```js
// initialState
{
user: {
sync: false, // State was update once
syncing: false, // State syncing is in progress
loading: false, // State updating is in progress
error: null, // responce error
data: [] // responce data
}
}
```
### Url schema
/api/v1/user/:id
```js
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "redux-api",
"version": "0.1.0",
"version": "0.1.1",
"main": "dist/redux-api.min.js",
"dependencies": {}
}
44 changes: 36 additions & 8 deletions dist/redux-api.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/redux-api.js.map

Large diffs are not rendered by default.

152 changes: 76 additions & 76 deletions dist/redux-api.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/redux-api.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "redux-api",
"version": "0.1.0",
"version": "0.1.1",
"author": {
"name": "Efremov Alex",
"email": "lexich121@gmail.com",
Expand Down
20 changes: 14 additions & 6 deletions src/actionFn.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,32 @@
import urlTransform from "./urlTransform";
export default function actionFn(url, name, options, ACTIONS={}, fetch) {
const {actionFetch, actionSuccess, actionFail, actionReset} = ACTIONS;
const fn = (pathvars, params={})=> (dispatch, getState)=> {
const fn = (pathvars, params={}, info={})=> (dispatch, getState)=> {
const state = getState();
const store = state[name];
if (store.loading) { return; }
dispatch({ type: actionFetch });
dispatch({ type: actionFetch, syncing: !!info.syncing });
const _url = urlTransform(url, pathvars);
const opts = { ...options, ...params };
fetch(_url, opts)
.then((resp)=> resp.json())
.then((data)=> dispatch({ type: actionSuccess, data }))
.catch((error)=> dispatch({ type: actionFail, error }));
.then((data)=> dispatch({
type: actionSuccess,
syncing: false,
data
}))
.catch((error)=> dispatch({
type: actionFail,
syncing: false,
error
}));
};
fn.reset = ()=> ({type: actionReset});
fn.sync = (pathvars, params)=> (dispatch, getState)=> {
const state = getState();
const store =state[name];
const store = state[name];
if (store.sync) return;
return fn(pathvars, params)(dispatch, getState);
return fn(pathvars, params, {syncing: true})(dispatch, getState);
};
return fn;
}
7 changes: 6 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ export default function reduxApi(config, fetch) {
{ ...defaultEndpointConfig, ...value } :
{ ...defaultEndpointConfig };
const {transformer, options} = opts;
const initialState = { loading: false, data: transformer() };
const initialState = {
sync: false,
syncing: false,
loading: false,
data: transformer()
};
const ACTIONS = {
actionFetch: `${PREFIX}@${counter}@${keyName}`,
actionSuccess: `${PREFIX}@${counter}@${keyName}_success`,
Expand Down
23 changes: 20 additions & 3 deletions src/reducerFn.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,28 @@ export default function reducerFn(initialState, actions={}, transformer=(d)=> d)
return (state=initialState, action)=> {
switch (action.type) {
case actionFetch:
return {...state, loading: true, error: null};
return {
...state,
loading: true,
error: null,
syncing: !!action.syncing
};
case actionSuccess:
return {...state, loading: false, sync: true, error: null, data: transformer(action.data)};
return {
...state,
loading: false,
sync: true,
syncing: false,
error: null,
data: transformer(action.data)
};
case actionFail:
return {...state, loading: false, error: action.error};
return {
...state,
loading: false,
error: action.error,
syncing: false
};
case actionReset:
return {...initialState};
default:
Expand Down
49 changes: 31 additions & 18 deletions test/actionFn_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function fetchSuccess() {
}

function getState() {
return {test: {loading: false, sync: true, data: {}}};
return {test: {loading: false, syncing: false, sync: false, data: {}}};
}

function fetchFail() {
Expand All @@ -38,23 +38,32 @@ describe("actionFn", function() {
expect(isFunction(api)).to.be.true;
});
it("check sync method", function() {
const api = actionFn("/test", "test", null, ACTIONS, fetchSuccess);
const expectedEvent = [
{
type: ACTIONS.actionFetch
}, {
type: ACTIONS.actionSuccess,
data: {msg: "hello"}
}
];
function dispatch(msg) {
const initialState = getState();
initialState.test.sync = true;
let executeCounter = 0;
const api = actionFn("/test", "test", null, ACTIONS, ()=> {
executeCounter++;
return fetchSuccess();
});
api.sync()(function() {}, ()=> initialState);
expect(executeCounter).to.be.eql(0);

const expectedEvent = [{
type: ACTIONS.actionFetch,
syncing: true
}, {
type: ACTIONS.actionSuccess,
data: {msg: "hello"},
syncing: false
}];
api.sync()((msg)=> {
expect(expectedEvent).to.have.length.above(0);
const exp = expectedEvent.shift();
expect(msg).to.eql(exp);
}
api.sync()(dispatch, getState);
api.sync()(dispatch, getState);
}, getState);
expect(executeCounter).to.be.eql(1);
});

it("check normal usage", function() {
const api = actionFn("/test", "test", null, ACTIONS, fetchSuccess);
expect(api.reset()).to.eql({type: ACTIONS.actionReset });
Expand All @@ -63,10 +72,12 @@ describe("actionFn", function() {

const expectedEvent = [
{
type: ACTIONS.actionFetch
type: ACTIONS.actionFetch,
syncing: false
}, {
type: ACTIONS.actionSuccess,
data: {msg: "hello"}
data: {msg: "hello"},
syncing: false
}
];
function dispatch(msg) {
Expand All @@ -81,10 +92,12 @@ describe("actionFn", function() {

const expectedEvent = [
{
type: ACTIONS.actionFetch
type: ACTIONS.actionFetch,
syncing: false
}, {
type: ACTIONS.actionFail,
error: "Error"
error: "Error",
syncing: false
}
];
function dispatch(msg) {
Expand Down
12 changes: 8 additions & 4 deletions test/index_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ describe("index", function() {
const action = res.actions.test();
const expectedEvent = [
{
type: "@@redux-api@1@test"
type: "@@redux-api@1@test",
syncing: false
}, {
type: "@@redux-api@1@test_success",
data: {msg: "hello"}
data: {msg: "hello"},
syncing: false
}
];
function dispatch(msg) {
Expand Down Expand Up @@ -96,10 +98,12 @@ describe("index", function() {
const action = res.actions.test({id: 1});
const expectedEvent = [
{
type: "@@redux-api@2@test"
type: "@@redux-api@2@test",
syncing: false
}, {
type: "@@redux-api@2@test_success",
data: {msg: "hello"}
data: {msg: "hello"},
syncing: false
}
];
function dispatch(msg) {
Expand Down
6 changes: 3 additions & 3 deletions test/reducerFn_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ describe("reducerFn", function() {
const fn = reducerFn(initialState, actions);
const res1 = fn(initialState, {type: actions.actionFetch});
expect(res1).to.eql({
loading: true, error: null, data: { msg: "Hello" }
loading: true, error: null, data: { msg: "Hello" }, syncing: false
});

const res2 = fn(initialState, {type: actions.actionSuccess, data: true});
expect(res2).to.eql({
loading: false, error: null, data: true, sync: true
loading: false, error: null, data: true, sync: true, syncing: false
});

const res3 = fn(initialState, {type: actions.actionFail, error: "Error"});
expect(res3).to.eql({
loading: false, error: "Error", data: { msg: "Hello" }
loading: false, error: "Error", data: { msg: "Hello" }, syncing: false
});

const res4 = fn(initialState, {type: actions.actionReset});
Expand Down

0 comments on commit 61452bf

Please sign in to comment.