Skip to content

Instantly share code, notes, and snippets.

View joedski's full-sized avatar
💭
Ætheric

Joe joedski

💭
Ætheric
View GitHub Profile
@joedski
joedski / hof-thunks-0-mapres-decorator.js
Last active September 23, 2017 03:11
hof thunks: mapping resolutions
// 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,
@joedski
joedski / hof-thunks-0-then-decorators.js
Last active September 23, 2017 02:34
hof thunks: chaining
// 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));
};
@joedski
joedski / hof-thunks-0-params-decorators.js
Last active September 23, 2017 01:57
hof thunks: first decorator
// 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) {
@joedski
joedski / hof-thunks-connected-component.jsx
Last active September 19, 2017 01:54
hof thunks: A connected component
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',
@joedski
joedski / hof-thunks-0-my-endpoint.js
Last active September 19, 2017 02:28
hof thunks: simple endpoint example
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.
}));
@joedski
joedski / hof-thunks-resource-thunk.js
Last active September 19, 2017 01:51
hof thunks: resource thunk creator
export function resource(resourceName, mapArgs) {
return (params, meta) => async (getState, dispatch) => {
const fetchOptions = mapArgs(params, meta);
dispatch(resourceActions.requestResource({
name: resourceName,
params,
meta,
}));
@joedski
joedski / tieredMemoizer.storesOnly.js
Created July 16, 2017 23:35
The simplest case, which doesn't allow you to use existing memoizers, though you can use their stores if they expose that.
// 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;
@joedski
joedski / tieredMemoize.arbitraryArity.js
Created July 15, 2017 03:49
Tierd Memoization of Functions of Arbitrary Arites (also fixed the single memo)
// 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;
@joedski
joedski / tieredMemoize.example.js
Created July 14, 2017 00:10
Multiparameter Memoization: Example
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,
@joedski
joedski / passSelectorCountToMemoizer.js
Created July 14, 2017 00:07
Multiparameter Memoization: The whole shebang
// 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);