UNPKG

2.42 kBPlain TextView Raw
1import { InitConfig, Config, Models } from './types'
2import { validateConfig, validatePlugin } from './validate'
3
4let count = 0
5
6/**
7 * Builds complete Rematch config using default values for properties not
8 * supplied by the user. Additionally, applies changes to the config made by
9 * the plugins selected by the user.
10 */
11export default function createConfig<
12 TModels extends Models<TModels>,
13 TExtraModels extends Models<TModels>
14>(
15 initConfig: InitConfig<TModels, TExtraModels>
16): Config<TModels, TExtraModels> {
17 const storeName = initConfig.name ?? `Rematch Store ${count}`
18
19 count += 1
20
21 const config = {
22 name: storeName,
23 models: initConfig.models || {},
24 plugins: initConfig.plugins || [],
25 redux: {
26 reducers: {},
27 rootReducers: {},
28 enhancers: [],
29 middlewares: [],
30 ...initConfig.redux,
31 devtoolOptions: {
32 name: storeName,
33 ...(initConfig.redux?.devtoolOptions ?? {}),
34 },
35 },
36 } as Config<TModels, TExtraModels>
37
38 validateConfig(config)
39
40 // Apply changes to the config required by plugins
41 config.plugins.forEach((plugin) => {
42 if (plugin.config) {
43 // Collect new models
44 config.models = merge(config.models, plugin.config.models)
45
46 // Collect redux configuration changes
47 if (plugin.config.redux) {
48 config.redux.initialState = merge(
49 config.redux.initialState,
50 plugin.config.redux.initialState
51 )
52
53 config.redux.reducers = merge(
54 config.redux.reducers,
55 plugin.config.redux.reducers
56 )
57
58 config.redux.rootReducers = merge(
59 config.redux.rootReducers,
60 plugin.config.redux.reducers
61 )
62
63 config.redux.enhancers = [
64 ...config.redux.enhancers,
65 ...(plugin.config.redux.enhancers || []),
66 ]
67
68 config.redux.middlewares = [
69 ...config.redux.middlewares,
70 ...(plugin.config.redux.middlewares || []),
71 ]
72
73 config.redux.combineReducers =
74 config.redux.combineReducers || plugin.config.redux.combineReducers
75
76 config.redux.createStore =
77 config.redux.createStore || plugin.config.redux.createStore
78 }
79 }
80
81 validatePlugin(plugin)
82 })
83
84 return config as Config<TModels, TExtraModels>
85}
86
87/**
88 * Shallow merges original object with the extra object, giving the precedence
89 * to the original object.
90 */
91function merge<
92 T extends Record<string, unknown>,
93 U extends Record<string, unknown> = T
94>(original: T, extra?: U): T | (T & U) {
95 return extra ? { ...extra, ...original } : original
96}