This file contains hidden or 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
// my-app/api/thunk-utils.js | |
// ... other decorators and such. | |
export function mapResolution(mapResFn) { | |
return (createThunk) => (params, meta) => async (dispatch, getState) => { | |
const res = await dispatch(createThunk(params, meta)); | |
if (res.error) return res; | |
return { | |
...res, |
This file contains hidden or 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
// my-app/api/thunk-utils.js | |
// ... previous decorators. | |
export function then(mapResToCreateNextThunk) { | |
return (createThunk) => (params, meta) => async (dispatch, getState) => { | |
const res = await dispatch(createThunk(params, meta)); | |
if (res.error) return res; | |
return dispatch(mapResToCreateNextThunk(res, getState())(params, meta)); | |
}; |
This file contains hidden or 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
// my-app/api/thunk-utils.js | |
// Used to dispatch the thunk. | |
// Rather boring compared to the rest. | |
export function map(fn) { | |
return (createThunk) => (params, meta) => fn(createThunk(params, meta)); | |
} | |
// These params are enforced. | |
export function withParams(overrideParams) { |
This file contains hidden or 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
import { myEndpoint } from 'my-app/api/thunks'; | |
// ... other sundry imports. | |
export default compose( | |
connect( | |
null, | |
(dispatch, ownProps) => ({ | |
getMyResource: dispatch(myEndpoint({ | |
name: ownProps.name, | |
order: 'asc', |
This file contains hidden or 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
import { resource } from 'my-app/api/resource'; | |
export const myEndpoint = resource('myEndpoint', (params, meta) => ({ | |
uri: `myservice.example.com/v1/my-endpoint?${querystring.stringify(params)}`, | |
headers: DEFAULT_HEADERS, | |
// ...etc. | |
})); |
This file contains hidden or 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
export function resource(resourceName, mapArgs) { | |
return (params, meta) => async (getState, dispatch) => { | |
const fetchOptions = mapArgs(params, meta); | |
dispatch(resourceActions.requestResource({ | |
name: resourceName, | |
params, | |
meta, | |
})); |
This file contains hidden or 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
// Simple single-value store. | |
// Setting a KV pair overwrites the last. | |
// Follows a get/set/has interface similar to Maps. | |
function singleValueStore() { | |
let key; | |
let value; | |
let isSet = false; | |
function get(givenKey) { | |
if (!isSet) return undefined; |
This file contains hidden or 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
// Simple naive single-param single-memo. | |
function singleMemo(fn) { | |
let calledAtLeastOnce = false; | |
let prevArg; | |
let value; | |
return function singleMemoizedFn(arg) { | |
if (arg !== prevArg || !calledAtLeastOnce) { | |
calledAtLeastOnce = true; | |
prevArg = arg; |
This file contains hidden or 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
const reselect = require('reselect'); | |
const createSelectorCreator = passSelectorCountToMemoizer(reselect.createSelectorCreator); | |
const createSelector = createSelectorCreator(createTieredMemoizer({ memoizers: [multiMemo] })); | |
const getFooBy = (state, id) => state.foos.byId[id]; | |
const getBar = state => state.bar; | |
const getBaz = state => state.baz; | |
const getStuff = createSelector( | |
getFooBy, getBar, getBaz, |
This file contains hidden or 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
// A simple enhancer to use on reselect's createSelectorCreator that makes it | |
// pass the number of selectors received as the first option (after the calculator) | |
// to the memoizer. | |
function passSelectorCountToMemoizer(baseCreateSelectorCreator) { | |
return function selectorPassingSelectorCreator(memoize, ...memoizeOptions) { | |
return function createActualSelector(...args) { | |
const calculator = args.pop(); | |
const selectors = Array.isArray(args[0]) ? args[0] : args; | |
return baseCreateSelectorCreator(memoize, selectors.length, ...memoizeOptions)(selectors, calculator); |