-
-
Notifications
You must be signed in to change notification settings - Fork 632
/
Copy pathStoreRegistry.js
98 lines (85 loc) · 3.32 KB
/
StoreRegistry.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// key = name used by react_on_rails to identify the store
// value = redux store creator, which is a function that takes props and returns a store
const registeredStoreGenerators = new Map();
const hydratedStores = new Map();
export default {
/**
* Register a store generator, a function that takes props and returns a store.
* @param storeGenerators { name1: storeGenerator1, name2: storeGenerator2 }
*/
register(storeGenerators) {
Object.keys(storeGenerators).forEach(name => {
if (registeredStoreGenerators.has(name)) {
console.warn('Called registerStore for store that is already registered', name);
}
const store = storeGenerators[name];
if (!store) {
throw new Error('Called ReactOnRails.registerStores with a null or undefined as a value ' +
`for the store generator with key ${name}.`);
}
registeredStoreGenerators.set(name, store);
});
},
/**
* Used by components to get the hydrated store which contains props.
* @param name
* @param throwIfMissing Defaults to true. Set to false to have this call return undefined if
* there is no store with the given name.
* @returns Redux Store, possibly hydrated
*/
getStore(name, throwIfMissing = true) {
if (hydratedStores.has(name)) {
return hydratedStores.get(name);
}
const storeKeys = Array.from(hydratedStores.keys()).join(', ');
if (storeKeys.length === 0) {
const msg = 'There are no stores hydrated and you are requesting the store ' +
`${name}. This can happen if you are server rendering and either you do not call ` +
"redux_store near the top of your controller action's view (not the layout) " +
'and before any call to react_component or you do not render ' +
'`redux_store_hydration_data` anywhere on your page';
throw new Error(msg);
}
if (throwIfMissing) {
console.log('storeKeys', storeKeys);
throw new Error(`Could not find hydrated store with name '${name}'. ` +
`Hydrated store names include [${storeKeys}].`);
}
return undefined;
},
/**
* Internally used function to get the store creator that was passed to `register`.
* @param name
* @returns storeCreator with given name
*/
getStoreGenerator(name) {
if (registeredStoreGenerators.has(name)) {
return registeredStoreGenerators.get(name);
}
const storeKeys = Array.from(registeredStoreGenerators.keys()).join(', ');
throw new Error(`Could not find store registered with name '${name}'. Registered store ` +
`names include [ ${storeKeys} ]. Maybe you forgot to register the store?`);
},
/**
* Internally used function to set the hydrated store after a Rails page is loaded.
* @param name
* @param store (not the storeGenerator, but the hydrated store)
*/
setStore(name, store) {
hydratedStores.set(name, store);
},
/**
* Get a Map containing all registered store generators. Useful for debugging.
* @returns Map where key is the component name and values are the store generators.
*/
storeGenerators() {
return registeredStoreGenerators;
},
/**
* Get a Map containing all hydrated stores. Useful for debugging.
* @returns Map where key is the component name and values are the hydrated stores.
*/
stores() {
return hydratedStores;
},
};