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
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
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
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
// 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
// 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 | |
// ... 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
function stepA(options) { | |
return (next) => async (pctx) => { | |
// Do stuff, allowing any errors to reject this promise, | |
// passing them back to previous steps. | |
const result = await doSomething(pctx.foo); | |
const nextPctx = { ...pctx, bar: result }; | |
try { | |
// NOTE: Technically, you could further process the result | |
// before returning it. |
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 processFoo = | |
stepA(optionsA)( | |
stepB(optionsB)( | |
stepC(optionsC)( | |
// A SACRIFICE TO THE PYRAMID OF DOOM | |
// On a more serious note, since each step function requires | |
// a next function, we need to pass in a "return" function which | |
// doesn't expect a next function to complete the chain. | |
// If we didn't do this, stepC would return a function expecting a next | |
// function... passing that function an object doesn't cause an error, |
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 processFoo = compose( | |
stepA(optionsA), | |
stepB(optionsB), | |
stepC(optionsC) | |
)(res => res); | |
async function handleSomeThing(ctx) { | |
// Create a pctx with the original ctx and whatever else we want. | |
// NOTE: in this case, we're trying to not pollute the original ctx, | |
// which might be something like a Koa Context. |