@acodeninja/persist 3.0.0-next.2 → 3.0.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/engine/StorageEngine.js +96 -27
package/package.json
CHANGED
@@ -20,34 +20,46 @@ export default class StorageEngine {
|
|
20
20
|
const processedModels = [];
|
21
21
|
const modelsToPut = [];
|
22
22
|
const modelsToReindex = {};
|
23
|
+
const modelsToReindexSearch = {};
|
23
24
|
|
24
25
|
/**
|
25
26
|
* @param {Type.Model} modelToProcess
|
26
27
|
* @return {Promise<void>}
|
27
28
|
*/
|
28
29
|
const processModel = async (modelToProcess) => {
|
29
|
-
if (processedModels.includes(modelToProcess.id))
|
30
|
+
if (processedModels.includes(modelToProcess.id))
|
31
|
+
return;
|
30
32
|
|
31
33
|
processedModels.push(modelToProcess.id);
|
32
34
|
|
33
|
-
if (!Object.keys(this.models).includes(modelToProcess.constructor.name))
|
35
|
+
if (!Object.keys(this.models).includes(modelToProcess.constructor.name))
|
36
|
+
throw new ModelNotRegisteredStorageEngineError(modelToProcess, this);
|
34
37
|
|
35
38
|
modelToProcess.validate();
|
36
39
|
const currentModel = await this.get(modelToProcess.id).catch(() => null);
|
37
40
|
|
38
|
-
const modelToProcessHasChanged =
|
41
|
+
const modelToProcessHasChanged = JSON.stringify(currentModel?.toData() || {}) !== JSON.stringify(modelToProcess.toData());
|
39
42
|
|
40
43
|
if (modelToProcessHasChanged) modelsToPut.push(modelToProcess);
|
41
44
|
|
42
45
|
if (
|
43
46
|
Boolean(modelToProcess.constructor.indexedProperties().length) &&
|
44
|
-
|
47
|
+
indexedFieldsHaveChanged(currentModel, modelToProcess)
|
45
48
|
) {
|
46
49
|
const modelToProcessConstructor = this.getModelConstructorFromId(modelToProcess.id);
|
47
50
|
modelsToReindex[modelToProcessConstructor] = modelsToReindex[modelToProcessConstructor] || [];
|
48
51
|
modelsToReindex[modelToProcessConstructor].push(modelToProcess);
|
49
52
|
}
|
50
53
|
|
54
|
+
if (
|
55
|
+
Boolean(modelToProcess.constructor.searchProperties().length) &&
|
56
|
+
searchableFieldsHaveChanged(currentModel, modelToProcess)
|
57
|
+
) {
|
58
|
+
const modelToProcessConstructor = this.getModelConstructorFromId(modelToProcess.id);
|
59
|
+
modelsToReindexSearch[modelToProcessConstructor] = modelsToReindexSearch[modelToProcessConstructor] || [];
|
60
|
+
modelsToReindexSearch[modelToProcessConstructor].push(modelToProcess);
|
61
|
+
}
|
62
|
+
|
51
63
|
for (const [field, value] of Object.entries(modelToProcess)) {
|
52
64
|
if (Type.Model.isModel(value)) {
|
53
65
|
await processModel(modelToProcess[field]);
|
@@ -57,31 +69,27 @@ export default class StorageEngine {
|
|
57
69
|
|
58
70
|
await processModel(model);
|
59
71
|
|
60
|
-
await Promise.all(
|
61
|
-
|
62
|
-
|
63
|
-
|
72
|
+
await Promise.all([
|
73
|
+
Promise.all(modelsToPut.map(m => this._putModel(m.toData()))),
|
74
|
+
Promise.all(Object.entries(modelsToReindex).map(async ([constructorName, models]) => {
|
75
|
+
const modelConstructor = this.models[constructorName];
|
76
|
+
const index = await this._getIndex(modelConstructor);
|
64
77
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
78
|
+
await this._putIndex(modelConstructor, {
|
79
|
+
...index || {},
|
80
|
+
...Object.fromEntries(models.map(m => [m.id, m.toIndexData()])),
|
81
|
+
});
|
82
|
+
})),
|
83
|
+
Promise.all(Object.entries(modelsToReindexSearch).map(async ([constructorName, models]) => {
|
84
|
+
const modelConstructor = this.models[constructorName];
|
85
|
+
const index = await this._getSearchIndex(modelConstructor);
|
71
86
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
*/
|
79
|
-
_indexedFieldsHaveChanged(currentModel, modelToProcess) {
|
80
|
-
return !currentModel || Boolean(
|
81
|
-
modelToProcess.constructor.indexedProperties()
|
82
|
-
.filter(field => JSON.stringify(_.get(currentModel, field)) !== JSON.stringify(_.get(modelToProcess, field)))
|
83
|
-
.length,
|
84
|
-
);
|
87
|
+
await this._putSearchIndex(modelConstructor, {
|
88
|
+
...index || {},
|
89
|
+
...Object.fromEntries(models.map(m => [m.id, m.toIndexData()])),
|
90
|
+
});
|
91
|
+
})),
|
92
|
+
]);
|
85
93
|
}
|
86
94
|
|
87
95
|
/**
|
@@ -198,6 +206,67 @@ export default class StorageEngine {
|
|
198
206
|
_putIndex(_modelConstructor, _data) {
|
199
207
|
return Promise.reject(new MethodNotImplementedStorageEngineError('_putIndex', this));
|
200
208
|
}
|
209
|
+
|
210
|
+
/**
|
211
|
+
* Get a model's raw search index data
|
212
|
+
* @param {Model.constructor} _modelConstructor
|
213
|
+
* @throws MethodNotImplementedStorageEngineError
|
214
|
+
* @return Promise<void>
|
215
|
+
*/
|
216
|
+
_getSearchIndex(_modelConstructor) {
|
217
|
+
return Promise.reject(new MethodNotImplementedStorageEngineError('_getSearchIndex', this));
|
218
|
+
}
|
219
|
+
|
220
|
+
/**
|
221
|
+
* Get a model's raw search index data
|
222
|
+
* @param {Model.constructor} _modelConstructor
|
223
|
+
* @throws MethodNotImplementedStorageEngineError
|
224
|
+
* @return Promise<void>
|
225
|
+
*/
|
226
|
+
_getSearchIndexCompiled(_modelConstructor) {
|
227
|
+
return Promise.reject(new MethodNotImplementedStorageEngineError('_getSearchIndexCompiled', this));
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
* Put a model's raw and compiled search index data
|
232
|
+
* @param {Model.constructor} _modelConstructor
|
233
|
+
* @param {object} _data
|
234
|
+
* @throws MethodNotImplementedStorageEngineError
|
235
|
+
* @return Promise<void>
|
236
|
+
*/
|
237
|
+
_putSearchIndex(_modelConstructor, _data) {
|
238
|
+
return Promise.reject(new MethodNotImplementedStorageEngineError('_putSearchIndex', this));
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
/**
|
243
|
+
* Decide if two models indexable fields have changed
|
244
|
+
* @param {Type.Model} currentModel
|
245
|
+
* @param {Type.Model} modelToProcess
|
246
|
+
* @return {boolean}
|
247
|
+
* @private
|
248
|
+
*/
|
249
|
+
function indexedFieldsHaveChanged(currentModel, modelToProcess) {
|
250
|
+
return !currentModel || Boolean(
|
251
|
+
modelToProcess.constructor.indexedProperties()
|
252
|
+
.filter(field => JSON.stringify(_.get(currentModel, field)) !== JSON.stringify(_.get(modelToProcess, field)))
|
253
|
+
.length,
|
254
|
+
);
|
255
|
+
}
|
256
|
+
|
257
|
+
/**
|
258
|
+
* Decide if two models searchable fields have changed
|
259
|
+
* @param {Type.Model} currentModel
|
260
|
+
* @param {Type.Model} modelToProcess
|
261
|
+
* @return {boolean}
|
262
|
+
* @private
|
263
|
+
*/
|
264
|
+
function searchableFieldsHaveChanged(currentModel, modelToProcess) {
|
265
|
+
return !currentModel || Boolean(
|
266
|
+
modelToProcess.constructor.searchProperties()
|
267
|
+
.filter(field => JSON.stringify(_.get(currentModel, field)) !== JSON.stringify(_.get(modelToProcess, field)))
|
268
|
+
.length,
|
269
|
+
);
|
201
270
|
}
|
202
271
|
|
203
272
|
/**
|