Skip to content

Instantly share code, notes, and snippets.

View aigoncharov's full-sized avatar

Andrey Goncharov aigoncharov

View GitHub Profile
@aigoncharov
aigoncharov / selecting-a-reducer-from-an-object-by-key-1.js
Last active February 11, 2019 19:02
Reducer organization - taking a step further
const actionTypeJediCreateInit = 'jedi-app/jedi-create-init'
const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success'
const actionTypeJediCreateError = 'jedi-app/jedi-create-error'
const reducerJediInitialState = {
loading: false,
data: [],
error: undefined,
}
const reducerJediMap = {
@aigoncharov
aigoncharov / selecting-a-reducer-from-an-object-by-key-2.js
Last active February 11, 2019 19:02
Reducer organization - taking a step further
import { createReducer } from 'redux-create-reducer'
const actionTypeJediCreateInit = 'jedi-app/jedi-create-init'
const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success'
const actionTypeJediCreateError = 'jedi-app/jedi-create-error'
const reducerJediInitialState = {
loading: false,
data: [],
error: undefined,
@aigoncharov
aigoncharov / class-based-reducers-1.js
Created February 11, 2019 19:02
Reducer organization - taking a step further
const actionTypeJediCreateInit = 'jedi-app/jedi-create-init'
const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success'
const actionTypeJediCreateError = 'jedi-app/jedi-create-error'
class ReducerJedi {
initialState = {
loading: false,
data: [],
error: undefined,
}
@aigoncharov
aigoncharov / class-based-reducers-2.js
Created February 11, 2019 19:21
Reducer organization - taking a step further
const METADATA_KEY_ACTION = 'reducer-class-action-metadata'
export const Action = (...actionTypes) => (target, propertyKey, descriptor) => {
Reflect.defineMetadata(METADATA_KEY_ACTION, actionTypes, target, propertyKey)
}
@aigoncharov
aigoncharov / class-based-reducers-3.js
Created February 11, 2019 19:34
Reducer organization - taking a step further
const getReducerClassMethodsWthActionTypes = (instance) => {
// Get method names from class' prototype
const proto = Object.getPrototypeOf(instance)
const methodNames = Object.getOwnPropertyNames(proto).filter(
(name) => name !== 'constructor',
)
// We want to get back a collection with action types and corresponding reducers
const res = []
methodNames.forEach((methodName) => {
@aigoncharov
aigoncharov / class-based-reducers-4.js
Created February 11, 2019 19:40
Reducer organization - taking a step further
const getReducerMap = (methodsWithActionTypes) =>
methodsWithActionTypes.reduce((reducerMap, { method, actionType }) => {
reducerMap[actionType] = method
return reducerMap
}, {})
@aigoncharov
aigoncharov / class-based-reducers-5.js
Created February 11, 2019 19:44
Reducer organization - taking a step further
import { createReducer } from 'redux-create-reducer'
const createClassReducer = (ReducerClass) => {
const reducerClass = new ReducerClass()
const methodsWithActionTypes = getReducerClassMethodsWthActionTypes(
reducerClass,
)
const reducerMap = getReducerMap(methodsWithActionTypes)
const initialState = reducerClass.initialState
const reducer = createReducer(initialState, reducerMap)
@aigoncharov
aigoncharov / class-based-reducers-6.js
Created February 11, 2019 19:47
Reducer organization - taking a step further
const reducerJedi = createClassReducer(ReducerJedi)
@aigoncharov
aigoncharov / class-based-reducers-7.js
Created February 11, 2019 19:50
Reducer organization - taking a step further
// We move that generic code to a dedicated module
import { Action, createClassReducer } from 'utils/reducer-class'
const actionTypeJediCreateInit = 'jedi-app/jedi-create-init'
const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success'
const actionTypeJediCreateError = 'jedi-app/jedi-create-error'
class ReducerJedi {
// Take a look at "Class field delcaratrions" proposal, which is now at Stage 3.
// https://github.com/tc39/proposal-class-fields
const cls = require('cls-hooked')
const uuidv4 = require('uuid/v4')
const clsNamespace = cls.createNamespace('app')
const clsMiddleware = (req, res, next) => {
// req and res are event emitters. We want to access CLS context inside of their event callbacks
clsNamespace.bind(req)
clsNamespace.bind(res)