Skip to content

Commit

Permalink
feat: add handler map factory
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohammad Hasani committed Jan 18, 2019
1 parent 5da4b52 commit 279e517
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`createHandlerMap handle([increment, increase], (state: number) => state + 1) (type) should match snapshot: createHandlerMap handle([increment, increase], (state: number) => state + 1) 1`] = `"import(\\"/Users/brodmann/Projects/@thebrodmann/deox/src/create-handler-map\\").HandlerMap<number, { type: \\"[Counter] increment\\"; } | { type: \\"[Counter] increase\\"; }>"`;

exports[`createHandlerMap handle(increment, (state: number) => state + 1) (type) should match snapshot: createHandlerMap handle(increment, (state: number) => state + 1) 1`] = `"import(\\"/Users/brodmann/Projects/@thebrodmann/deox/src/create-handler-map\\").HandlerMap<number, { type: \\"[Counter] increment\\"; }>"`;
14 changes: 14 additions & 0 deletions src/__tests__/__snapshots__/create-handler-map.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`createHandlerMap should belong multiple actions to one handler 1`] = `
Object {
"[Counter] increase": [Function],
"[Counter] increment": [Function],
}
`;

exports[`createHandlerMap should belong one action to one handler 1`] = `
Object {
"[Counter] increment": [Function],
}
`;
13 changes: 13 additions & 0 deletions src/__tests__/create-handler-map.dts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createAction } from '../create-action'
import { createHandlerMap as handle } from '../create-handler-map'

// @dts-jest:group createHandlerMap

const increment = createAction('[Counter] increment')
const increase = createAction('[Counter] increase')

// @dts-jest:pass:snap
handle(increment, (state: number) => state + 1)

// @dts-jest:pass:snap
handle([increment, increase], (state: number) => state + 1)
19 changes: 19 additions & 0 deletions src/__tests__/create-handler-map.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createAction } from '../create-action'
import { createHandlerMap as handle } from '../create-handler-map'

describe('createHandlerMap', () => {
it('should belong one action to one handler', () => {
const increment = createAction('[Counter] increment')

expect(handle(increment, (state: number) => state + 1)).toMatchSnapshot()
})

it('should belong multiple actions to one handler', () => {
const increment = createAction('[Counter] increment')
const increase = createAction('[Counter] increase')

expect(
handle([increment, increase], (state: number) => state + 1)
).toMatchSnapshot()
})
})
41 changes: 41 additions & 0 deletions src/create-handler-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ActionCreator } from './create-action'
import { AnyAction } from './action'
import { getType } from './get-type'

export type HandlerMap<State, Actions extends AnyAction> = {
[key in Actions['type']]: Reducer<State, Actions>
}

export type CreateHandlerMap<State> = <
AC extends ActionCreator<string>,
Actions extends AnyAction = AC extends (...args: any[]) => infer T ? T : never
>(
actionCreators: AC | AC[],
handler: Reducer<State, Actions>
) => HandlerMap<State, Actions>

/**
* Handler map factory
* @description create an action(s) to reducer map
* @example
* createHandlerMap(increment, (state: number) => state + 1)
* @example
* createHandlerMap([increment, increase], (state: number) => state + 1)
*/
export const createHandlerMap = <
AC extends ActionCreator<string>,
State,
Actions extends AnyAction = AC extends (...args: any[]) => infer T ? T : never
>(
actionCreators: AC | AC[],
reducer: Reducer<State, Actions>
) =>
(Array.isArray(actionCreators) ? actionCreators : [actionCreators])
.map(getType)
.reduce<HandlerMap<State, Actions>>(
(acc, type) => {
acc[type] = reducer
return acc
},
{} as any
)
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type Reducer<State, Actions> = (prevState: State, action: Actions) => State
2 changes: 1 addition & 1 deletion tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": "./tsconfig.json",
"include": ["./src/**/__tests__/*"],
"include": ["./src/**/__tests__/*", "./src/types.d.ts"],
"compilerOptions": {
"target": "esnext",
"esModuleInterop": true
Expand Down

0 comments on commit 279e517

Please sign in to comment.