1 | import {
|
2 | Action,
|
3 | ModelEffects,
|
4 | ModelEffectsCreator,
|
5 | Models,
|
6 | NamedModel,
|
7 | RematchBag,
|
8 | RematchDispatcher,
|
9 | RematchStore,
|
10 | } from './types'
|
11 | import { validateModelEffect, validateModelReducer } from './validate'
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | const createActionDispatcher = <
|
20 | TModels extends Models<TModels>,
|
21 | TExtraModels extends Models<TModels>
|
22 | >(
|
23 | rematch: RematchStore<TModels, TExtraModels>,
|
24 | modelName: string,
|
25 | actionName: string,
|
26 | isEffect: boolean
|
27 | ): RematchDispatcher<boolean> => {
|
28 | return Object.assign(
|
29 | (payload?: any, meta?: any): Action => {
|
30 | const action: Action = { type: `${modelName}/${actionName}` }
|
31 |
|
32 | if (typeof payload !== 'undefined') {
|
33 | action.payload = payload
|
34 | }
|
35 |
|
36 | if (typeof meta !== 'undefined') {
|
37 | action.meta = meta
|
38 | }
|
39 |
|
40 | return rematch.dispatch(action)
|
41 | },
|
42 | {
|
43 | isEffect,
|
44 | }
|
45 | )
|
46 | }
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | export const createReducerDispatcher = <
|
53 | TModels extends Models<TModels>,
|
54 | TExtraModels extends Models<TModels>,
|
55 | TModel extends NamedModel<TModels>
|
56 | >(
|
57 | rematch: RematchStore<TModels, TExtraModels>,
|
58 | model: TModel
|
59 | ): void => {
|
60 | const modelDispatcher = rematch.dispatch[model.name]
|
61 |
|
62 |
|
63 | const modelReducersKeys = Object.keys(model.reducers)
|
64 | modelReducersKeys.forEach((reducerName) => {
|
65 | validateModelReducer(model.name, model.reducers, reducerName)
|
66 |
|
67 | modelDispatcher[reducerName] = createActionDispatcher(
|
68 | rematch,
|
69 | model.name,
|
70 | reducerName,
|
71 | false
|
72 | )
|
73 | })
|
74 | }
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 | export const createEffectDispatcher = <
|
81 | TModels extends Models<TModels>,
|
82 | TExtraModels extends Models<TModels>,
|
83 | TModel extends NamedModel<TModels>
|
84 | >(
|
85 | rematch: RematchStore<TModels, TExtraModels>,
|
86 | bag: RematchBag<TModels, TExtraModels>,
|
87 | model: TModel
|
88 | ): void => {
|
89 | const modelDispatcher = rematch.dispatch[model.name]
|
90 | let effects: ModelEffects<TModels> = {}
|
91 |
|
92 |
|
93 | if (model.effects) {
|
94 | effects =
|
95 | typeof model.effects === 'function'
|
96 | ? (model.effects as ModelEffectsCreator<TModels>)(rematch.dispatch)
|
97 | : model.effects
|
98 | }
|
99 |
|
100 |
|
101 | const effectKeys = Object.keys(effects)
|
102 | effectKeys.forEach((effectName) => {
|
103 | validateModelEffect(model.name, effects, effectName)
|
104 |
|
105 | bag.effects[`${model.name}/${effectName}`] =
|
106 | effects[effectName].bind(modelDispatcher)
|
107 |
|
108 | modelDispatcher[effectName] = createActionDispatcher(
|
109 | rematch,
|
110 | model.name,
|
111 | effectName,
|
112 | true
|
113 | )
|
114 | })
|
115 | }
|