|
|
@@ -52,6 +52,8 @@ class PersistenceRegistry {
|
|
52
|
52
|
let persistedState = window.localStorage.getItem(PERSISTED_STATE_NAME);
|
|
53
|
53
|
|
|
54
|
54
|
if (persistedState) {
|
|
|
55
|
+ // This is the legacy implementation,
|
|
|
56
|
+ // must be removed in a later version.
|
|
55
|
57
|
try {
|
|
56
|
58
|
persistedState = JSON.parse(persistedState);
|
|
57
|
59
|
} catch (error) {
|
|
|
@@ -64,8 +66,37 @@ class PersistenceRegistry {
|
|
64
|
66
|
|
|
65
|
67
|
filteredPersistedState
|
|
66
|
68
|
= this._getFilteredState(persistedState);
|
|
|
69
|
+
|
|
|
70
|
+ // legacy values must be written to the new store format and
|
|
|
71
|
+ // old values to be deleted, so then it'll never be used again.
|
|
|
72
|
+ this.persistState(filteredPersistedState);
|
|
|
73
|
+ window.localStorage.removeItem(PERSISTED_STATE_NAME);
|
|
|
74
|
+ } else {
|
|
|
75
|
+ // new, split-keys implementation
|
|
|
76
|
+ for (const subtreeName of Object.keys(this._elements)) {
|
|
|
77
|
+ /*
|
|
|
78
|
+ * this assumes that the persisted value is stored under the
|
|
|
79
|
+ * same key as the feature's redux state name.
|
|
|
80
|
+ * We'll need to introduce functions later that can control
|
|
|
81
|
+ * the persist key's name. Similar to control serialization
|
|
|
82
|
+ * and deserialization.
|
|
|
83
|
+ * But that should be a straightforward change.
|
|
|
84
|
+ */
|
|
|
85
|
+ const persistedSubtree
|
|
|
86
|
+ = this._getPersistedSubtree(
|
|
|
87
|
+ subtreeName,
|
|
|
88
|
+ this._elements[subtreeName]
|
|
|
89
|
+ );
|
|
|
90
|
+
|
|
|
91
|
+ if (persistedSubtree !== undefined) {
|
|
|
92
|
+ filteredPersistedState[subtreeName] = persistedSubtree;
|
|
|
93
|
+ }
|
|
|
94
|
+ }
|
|
67
|
95
|
}
|
|
68
|
96
|
|
|
|
97
|
+ // initialize checksum
|
|
|
98
|
+ this._checksum = this._calculateChecksum(filteredPersistedState);
|
|
|
99
|
+
|
|
69
|
100
|
this._checksum = this._calculateChecksum(filteredPersistedState);
|
|
70
|
101
|
logger.info('redux state rehydrated as', filteredPersistedState);
|
|
71
|
102
|
|
|
|
@@ -84,17 +115,23 @@ class PersistenceRegistry {
|
|
84
|
115
|
const newCheckSum = this._calculateChecksum(filteredState);
|
|
85
|
116
|
|
|
86
|
117
|
if (newCheckSum !== this._checksum) {
|
|
87
|
|
- try {
|
|
88
|
|
- window.localStorage.setItem(
|
|
89
|
|
- PERSISTED_STATE_NAME,
|
|
90
|
|
- JSON.stringify(filteredState));
|
|
91
|
|
- logger.info(
|
|
92
|
|
- `redux state persisted. ${this._checksum} -> ${
|
|
93
|
|
- newCheckSum}`);
|
|
94
|
|
- this._checksum = newCheckSum;
|
|
95
|
|
- } catch (error) {
|
|
96
|
|
- logger.error('Error persisting redux state', error);
|
|
|
118
|
+ for (const subtreeName of Object.keys(filteredState)) {
|
|
|
119
|
+ try {
|
|
|
120
|
+ window.localStorage.setItem(
|
|
|
121
|
+ subtreeName,
|
|
|
122
|
+ JSON.stringify(filteredState[subtreeName]));
|
|
|
123
|
+ } catch (error) {
|
|
|
124
|
+ logger.error('Error persisting redux subtree',
|
|
|
125
|
+ subtreeName,
|
|
|
126
|
+ filteredState[subtreeName],
|
|
|
127
|
+ error
|
|
|
128
|
+ );
|
|
|
129
|
+ }
|
|
97
|
130
|
}
|
|
|
131
|
+ logger.info(
|
|
|
132
|
+ `redux state persisted. ${this._checksum} -> ${
|
|
|
133
|
+ newCheckSum}`);
|
|
|
134
|
+ this._checksum = newCheckSum;
|
|
98
|
135
|
}
|
|
99
|
136
|
}
|
|
100
|
137
|
|
|
|
@@ -130,6 +167,39 @@ class PersistenceRegistry {
|
|
130
|
167
|
}
|
|
131
|
168
|
}
|
|
132
|
169
|
|
|
|
170
|
+ /**
|
|
|
171
|
+ * Retreives a persisted subtree from the storage.
|
|
|
172
|
+ *
|
|
|
173
|
+ * @private
|
|
|
174
|
+ * @param {string} subtreeName - The name of the subtree.
|
|
|
175
|
+ * @param {Object} subtreeConfig - The config of the subtree
|
|
|
176
|
+ * from this._elements.
|
|
|
177
|
+ * @returns {Object}
|
|
|
178
|
+ */
|
|
|
179
|
+ _getPersistedSubtree(subtreeName, subtreeConfig) {
|
|
|
180
|
+ let persistedSubtree = window.localStorage.getItem(subtreeName);
|
|
|
181
|
+
|
|
|
182
|
+ if (persistedSubtree) {
|
|
|
183
|
+ try {
|
|
|
184
|
+ persistedSubtree = JSON.parse(persistedSubtree);
|
|
|
185
|
+ const filteredSubtree
|
|
|
186
|
+ = this._getFilteredSubtree(persistedSubtree, subtreeConfig);
|
|
|
187
|
+
|
|
|
188
|
+ if (filteredSubtree !== undefined) {
|
|
|
189
|
+ return filteredSubtree;
|
|
|
190
|
+ }
|
|
|
191
|
+ } catch (error) {
|
|
|
192
|
+ logger.error(
|
|
|
193
|
+ 'Error parsing persisted subtree',
|
|
|
194
|
+ subtreeName,
|
|
|
195
|
+ persistedSubtree,
|
|
|
196
|
+ error);
|
|
|
197
|
+ }
|
|
|
198
|
+ }
|
|
|
199
|
+
|
|
|
200
|
+ return null;
|
|
|
201
|
+ }
|
|
|
202
|
+
|
|
133
|
203
|
/**
|
|
134
|
204
|
* Prepares a filtered state from the actual or the persisted redux state,
|
|
135
|
205
|
* based on this registry.
|