Skip to content

Commit

Permalink
Merge pull request #26 from wacii/alternative-api
Browse files Browse the repository at this point in the history
Alternative API
  • Loading branch information
sorodrigo authored Oct 30, 2017
2 parents 0c2e1ce + ef52804 commit 3a0684a
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 9 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,21 @@ If you use Immutable in the rest of your store, but the root object, you should
[Contributions welcome](#contributing).
#### Choose where the offline middleware is added
By default, the offline middleware is inserted right before the offline store enhancer as part of its own middleware chain. If you want more control over where the middleware is inserted, consider using the alternative api, `createOffline()`.
```js
import { createOffline } from "@redux-offline/redux-offline";
const { middleware, enhanceReducer, enhanceStore } = createOffline(config);
const store = createStore(
enhanceReducer(rootReducer),
initialStore,
compose(applyMiddleware(middleware), enhanceStore)
);
```
## Contributing
Improvements and additions welcome. For large changes, please submit a discussion issue before jumping to coding; we'd hate you to waste the effort.
Expand Down
1 change: 1 addition & 0 deletions examples/basic/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"scripts": {
"start": "react-scripts start",
"alternative": "REACT_APP_OFFLINE_API=alternative react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
Expand Down
23 changes: 17 additions & 6 deletions examples/basic/client/src/store.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { applyMiddleware, compose, createStore } from 'redux';
import { offline } from '@redux-offline/redux-offline';
import { offline, createOffline } from '@redux-offline/redux-offline';
import defaultConfig from '@redux-offline/redux-offline/lib/defaults';

const initialState = {
Expand Down Expand Up @@ -28,7 +28,7 @@ const config = {
}
};

function middleware(store) {
function tickMiddleware(store) {
return next => action => {
if (action.type === 'Offline/SCHEDULE_RETRY') {
const intervalId = setInterval(() => {
Expand All @@ -40,9 +40,20 @@ function middleware(store) {
};
}
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
composeEnhancers(offline(config), applyMiddleware(middleware))
);

let store;
if (process.env.REACT_APP_OFFLINE_API === 'alternative') {
const { middleware, enhanceReducer, enhanceStore } = createOffline(config);
store = createStore(
enhanceReducer(reducer),
undefined,
composeEnhancers(applyMiddleware(middleware, tickMiddleware), enhanceStore)
);
} else {
store = createStore(
reducer,
composeEnhancers(offline(config), applyMiddleware(tickMiddleware))
);
}

export default store;
18 changes: 15 additions & 3 deletions src/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { compose, createStore } from "redux";
import { applyMiddleware, compose, createStore } from "redux";
import { KEY_PREFIX } from "redux-persist/lib/constants"
import { AsyncNodeStorage } from "redux-persist-node-storage";
import instrument from "redux-devtools-instrument";
import { offline } from "../index";
import { createOffline, offline } from "../index";
import { applyDefaults } from "../config";

const storage = new AsyncNodeStorage("/tmp/storageDir");
Expand Down Expand Up @@ -35,14 +35,26 @@ function defaultReducer(state = {
return state;
}

test("creates storeEnhancer", () => {
test("offline() creates storeEnhancer", () => {
const storeEnhancer = offline(defaultConfig);

const store = storeEnhancer(createStore)(defaultReducer);
expect(store.dispatch).toEqual(expect.any(Function));
expect(store.getState).toEqual(expect.any(Function));
});

test("createOffline() creates storeEnhancer", () => {
const { middleware, enhanceReducer, enhanceStore } =
createOffline(defaultConfig);
const reducer = enhanceReducer(defaultReducer);
const store = createStore(reducer, compose(
applyMiddleware(middleware),
enhanceStore
));
expect(store.dispatch).toEqual(expect.any(Function));
expect(store.getState).toEqual(expect.any(Function));
});

// see https://github.com/redux-offline/redux-offline/issues/31
test("supports HMR by overriding `replaceReducer()`", () => {
const store = offline(defaultConfig)(createStore)(defaultReducer);
Expand Down
53 changes: 53 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,56 @@ export const offline = (userConfig: $Shape<Config> = {}) => (

return store;
};

export const createOffline = (userConfig: $Shape<Config> = {}) => {
const config = applyDefaults(userConfig);

warnIfNotReduxAction(config, 'defaultCommit');
warnIfNotReduxAction(config, 'defaultRollback');

const enhanceStore = (next: any) => (
reducer: any,
preloadedState: any,
enhancer: any
) => {
// create autoRehydrate enhancer if required
const createStore =
config.persist && config.rehydrate && config.persistAutoRehydrate
? config.persistAutoRehydrate()(next)
: next;

// create store
const store = createStore(reducer, preloadedState, enhancer);

const baseReplaceReducer = store.replaceReducer.bind(store);
store.replaceReducer = function replaceReducer(nextReducer) {
return baseReplaceReducer(enhanceReducer(nextReducer, config));
};

// launch store persistor
if (config.persist) {
persistor = config.persist(
store,
config.persistOptions,
config.persistCallback
);
}

// launch network detector
if (config.detectNetwork) {
config.detectNetwork(online => {
store.dispatch(networkStatusChanged(online));
});
}

return store;
};

return {
middleware: createOfflineMiddleware(config),
enhanceReducer(reducer) {
return enhanceReducer(reducer, config);
},
enhanceStore
};
};

0 comments on commit 3a0684a

Please sign in to comment.