@acodeninja/persist 2.2.1 → 2.2.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.
@@ -3,43 +3,120 @@ import Type from '../type/index.js';
3
3
  import lunr from 'lunr';
4
4
 
5
5
  /**
6
+ * The `Engine` class provides a base interface for implementing data storage and retrieval engines.
7
+ * It includes methods for handling models, indexes, and search functionality.
8
+ *
6
9
  * @class Engine
7
10
  */
8
- export default class Engine {
9
- static _configuration = undefined;
10
-
11
- static async getById(_id) {
12
- throw new NotImplementedError(`${this.name} must implement .getById()`);
11
+ class Engine {
12
+ static configuration = undefined;
13
+
14
+ /**
15
+ * Retrieves a model by its ID. This method must be implemented by subclasses.
16
+ *
17
+ * @param {string} _id - The ID of the model to retrieve.
18
+ * @throws {NotImplementedError} Throws if the method is not implemented.
19
+ * @returns {Promise<Object>} - Returns a promise resolving to the raw data of the requested model.
20
+ * @abstract
21
+ */
22
+ static getById(_id) {
23
+ return Promise.reject(new NotImplementedError(`${this.name} must implement .getById()`));
13
24
  }
14
25
 
15
- static async putModel(_data) {
16
- throw new NotImplementedError(`${this.name} must implement .putModel()`);
26
+ /**
27
+ * Saves a model to the data store. This method must be implemented by subclasses.
28
+ *
29
+ * @param {Model} _data - The model data to save.
30
+ * @throws {NotImplementedError} Throws if the method is not implemented.
31
+ * @returns {Promise<void>}
32
+ * @abstract
33
+ */
34
+ static putModel(_data) {
35
+ return Promise.reject(new NotImplementedError(`${this.name} must implement .putModel()`));
17
36
  }
18
37
 
19
- static async getIndex(_model) {
20
- throw new NotImplementedError(`${this.name} does not implement .getIndex()`);
38
+ /**
39
+ * Retrieves the index for a given model. This method must be implemented by subclasses.
40
+ *
41
+ * @param {Model.constructor} _model - The model to retrieve the index for.
42
+ * @throws {NotImplementedError} Throws if the method is not implemented.
43
+ * @returns {Promise<Object>} - Returns a promise resolving to the model index.
44
+ * @abstract
45
+ */
46
+ static getIndex(_model) {
47
+ return Promise.reject(new NotImplementedError(`${this.name} does not implement .getIndex()`));
21
48
  }
22
49
 
23
- static async putIndex(_index) {
24
- throw new NotImplementedError(`${this.name} does not implement .putIndex()`);
50
+ /**
51
+ * Saves the index for a given model. This method must be implemented by subclasses.
52
+ *
53
+ * @param {Object} _index - The index data to save.
54
+ * @throws {NotImplementedError} Throws if the method is not implemented.
55
+ * @returns {Promise<void>}
56
+ * @abstract
57
+ */
58
+ static putIndex(_index) {
59
+ return Promise.reject(new NotImplementedError(`${this.name} does not implement .putIndex()`));
25
60
  }
26
61
 
27
- static async getSearchIndexCompiled(_model) {
28
- throw new NotImplementedError(`${this.name} does not implement .getSearchIndexCompiled()`);
62
+ /**
63
+ * Retrieves the compiled search index for a model. This method must be implemented by subclasses.
64
+ *
65
+ * @param {Model.constructor} _model - The model to retrieve the compiled search index for.
66
+ * @throws {NotImplementedError} Throws if the method is not implemented.
67
+ * @returns {Promise<Object>} - Returns a promise resolving to the compiled search index.
68
+ * @abstract
69
+ */
70
+ static getSearchIndexCompiled(_model) {
71
+ return Promise.reject(new NotImplementedError(`${this.name} does not implement .getSearchIndexCompiled()`));
29
72
  }
30
73
 
31
- static async getSearchIndexRaw(_model) {
32
- throw new NotImplementedError(`${this.name} does not implement .getSearchIndexRaw()`);
74
+ /**
75
+ * Retrieves the raw search index for a model. This method must be implemented by subclasses.
76
+ *
77
+ * @param {Model.constructor} _model - The model to retrieve the raw search index for.
78
+ * @throws {NotImplementedError} Throws if the method is not implemented.
79
+ * @returns {Promise<Object>} - Returns a promise resolving to the raw search index.
80
+ * @abstract
81
+ */
82
+ static getSearchIndexRaw(_model) {
83
+ return Promise.reject(new NotImplementedError(`${this.name} does not implement .getSearchIndexRaw()`));
33
84
  }
34
85
 
35
- static async putSearchIndexCompiled(_model, _compiledIndex) {
36
- throw new NotImplementedError(`${this.name} does not implement .putSearchIndexCompiled()`);
86
+ /**
87
+ * Saves the compiled search index for a model. This method must be implemented by subclasses.
88
+ *
89
+ * @param {Model.constructor} _model - The model for which the compiled search index is saved.
90
+ * @param {Object} _compiledIndex - The compiled search index data.
91
+ * @throws {NotImplementedError} Throws if the method is not implemented.
92
+ * @returns {Promise<void>}
93
+ * @abstract
94
+ */
95
+ static putSearchIndexCompiled(_model, _compiledIndex) {
96
+ return Promise.reject(new NotImplementedError(`${this.name} does not implement .putSearchIndexCompiled()`));
37
97
  }
38
98
 
39
- static async putSearchIndexRaw(_model, _rawIndex) {
40
- throw new NotImplementedError(`${this.name} does not implement .putSearchIndexRaw()`);
99
+ /**
100
+ * Saves the raw search index for a model. This method must be implemented by subclasses.
101
+ *
102
+ * @param {Model.constructor} _model - The model for which the raw search index is saved.
103
+ * @param {Object} _rawIndex - The raw search index data.
104
+ * @throws {NotImplementedError} Throws if the method is not implemented.
105
+ * @returns {Promise<void>}
106
+ * @abstract
107
+ */
108
+ static putSearchIndexRaw(_model, _rawIndex) {
109
+ return Promise.reject(new NotImplementedError(`${this.name} does not implement .putSearchIndexRaw()`));
41
110
  }
42
111
 
112
+ /**
113
+ * Performs a search query on a model's index and returns the matching models.
114
+ *
115
+ * @param {Model.constructor} model - The model class.
116
+ * @param {object} query - The search query string.
117
+ * @returns {Array<Model>} An array of models matching the search query.
118
+ * @throws {EngineError} Throws if the search index is not available for the model.
119
+ */
43
120
  static async search(model, query) {
44
121
  this.checkConfiguration();
45
122
 
@@ -55,6 +132,7 @@ export default class Engine {
55
132
  for (const result of results) {
56
133
  output.push({
57
134
  ...result,
135
+ score: Number(result.score.toFixed(4)),
58
136
  model: await this.get(model, result.ref),
59
137
  });
60
138
  }
@@ -62,6 +140,13 @@ export default class Engine {
62
140
  return output;
63
141
  }
64
142
 
143
+ /**
144
+ * Finds models that match a query in the model's index.
145
+ *
146
+ * @param {Model.constructor} model - The model class to search.
147
+ * @param {object} query - The query object containing search criteria.
148
+ * @returns {Array<Model>} An array of models matching the query.
149
+ */
65
150
  static async find(model, query) {
66
151
  this.checkConfiguration();
67
152
  const index = await this.getIndex(model);
@@ -69,50 +154,57 @@ export default class Engine {
69
154
  return new Query(query).execute(model, index);
70
155
  }
71
156
 
157
+ /**
158
+ * Stores a model and its associated index data into the system.
159
+ *
160
+ * @param {Model} model - The model to store.
161
+ * @throws {EngineError} Throws if the model fails to validate or index fails to save.
162
+ */
72
163
  static async put(model) {
73
164
  this.checkConfiguration();
74
165
  const uploadedModels = [];
75
166
  const indexUpdates = {};
76
167
 
77
- const processModel = async (model) => {
78
- if (uploadedModels.includes(model.id)) return false;
79
- model.validate();
168
+ const processModel = async (m) => {
169
+ if (!uploadedModels.includes(m.id)) {
170
+ m.validate();
80
171
 
81
- await this.putModel(model);
172
+ await this.putModel(m);
82
173
 
83
- uploadedModels.push(model.id);
84
- indexUpdates[model.constructor.name] = (indexUpdates[model.constructor.name] ?? []).concat([model]);
174
+ uploadedModels.push(m.id);
175
+ indexUpdates[m.constructor.name] = (indexUpdates[m.constructor.name] ?? []).concat([m]);
85
176
 
86
- if (model.constructor.searchProperties().length > 0) {
87
- const rawSearchIndex = {
88
- ...await this.getSearchIndexRaw(model.constructor),
89
- [model.id]: model.toSearchData(),
90
- };
177
+ if (m.constructor.searchProperties().length > 0) {
178
+ const rawSearchIndex = {
179
+ ...await this.getSearchIndexRaw(m.constructor),
180
+ [m.id]: m.toSearchData(),
181
+ };
91
182
 
92
- await this.putSearchIndexRaw(model.constructor, rawSearchIndex);
183
+ await this.putSearchIndexRaw(m.constructor, rawSearchIndex);
93
184
 
94
- const compiledIndex = lunr(function () {
95
- this.ref('id');
185
+ const compiledIndex = lunr(function () {
186
+ this.ref('id');
96
187
 
97
- for (const field of model.constructor.searchProperties()) {
98
- this.field(field);
99
- }
188
+ for (const field of m.constructor.searchProperties()) {
189
+ this.field(field);
190
+ }
100
191
 
101
- Object.values(rawSearchIndex).forEach(function (doc) {
102
- this.add(doc);
103
- }, this);
104
- });
192
+ Object.values(rawSearchIndex).forEach(function (doc) {
193
+ this.add(doc);
194
+ }, this);
195
+ });
105
196
 
106
- await this.putSearchIndexCompiled(model.constructor, compiledIndex);
107
- }
108
-
109
- for (const [_, property] of Object.entries(model)) {
110
- if (Type.Model.isModel(property)) {
111
- await processModel(property);
197
+ await this.putSearchIndexCompiled(m.constructor, compiledIndex);
112
198
  }
113
- if (Array.isArray(property) && Type.Model.isModel(property[0])) {
114
- for (const subModel of property) {
115
- await processModel(subModel);
199
+
200
+ for (const [_, property] of Object.entries(m)) {
201
+ if (Type.Model.isModel(property)) {
202
+ await processModel(property);
203
+ }
204
+ if (Array.isArray(property) && Type.Model.isModel(property[0])) {
205
+ for (const subModel of property) {
206
+ await processModel(subModel);
207
+ }
116
208
  }
117
209
  }
118
210
  }
@@ -122,6 +214,14 @@ export default class Engine {
122
214
  await this.putIndex(indexUpdates);
123
215
  }
124
216
 
217
+ /**
218
+ * Retrieves a model by its ID and converts it to its data representation.
219
+ *
220
+ * @param {Model.constructor} model - The model class to retrieve.
221
+ * @param {string} id - The ID of the model to retrieve.
222
+ * @returns {Model} The found model.
223
+ * @throws {NotFoundEngineError} Throws if the model is not found.
224
+ */
125
225
  static async get(model, id) {
126
226
  this.checkConfiguration();
127
227
 
@@ -134,6 +234,12 @@ export default class Engine {
134
234
  }
135
235
  }
136
236
 
237
+ /**
238
+ * Hydrates a model by populating its related properties (e.g., submodels) from stored data.
239
+ *
240
+ * @param {Model} model - The model to hydrate.
241
+ * @returns {Model} The hydrated model.
242
+ */
137
243
  static async hydrate(model) {
138
244
  this.checkConfiguration();
139
245
  const hydratedModels = {};
@@ -189,53 +295,122 @@ export default class Engine {
189
295
 
190
296
  function getSubModelClass(modelToProcess, name, isArray = false) {
191
297
  const constructorField = modelToProcess.constructor[name];
298
+
192
299
  if (constructorField instanceof Function && !constructorField.prototype) {
193
300
  return isArray ? constructorField()._items : constructorField();
194
301
  }
302
+
195
303
  return isArray ? constructorField._items : constructorField;
196
304
  }
197
305
 
198
306
  return await hydrateModel(await this.get(model.constructor, model.id));
199
307
  }
200
308
 
309
+ /**
310
+ * Configures the engine with specific settings.
311
+ *
312
+ * @param {Object} configuration - The configuration settings for the engine.
313
+ * @returns {Engine} A new engine instance with the applied configuration.
314
+ */
201
315
  static configure(configuration) {
202
316
  class ConfiguredStore extends this {
203
- static _configuration = configuration;
317
+ static configuration = configuration;
204
318
  }
205
319
 
206
- Object.defineProperty(ConfiguredStore, 'name', {value: `${this.toString()}`});
320
+ Object.defineProperty(ConfiguredStore, 'name', { value: `${this.toString()}` });
207
321
 
208
322
  return ConfiguredStore;
209
323
  }
210
324
 
325
+ /**
326
+ * Checks if the engine is properly configured.
327
+ *
328
+ * @throws {MissConfiguredError} Throws if the engine is misconfigured.
329
+ * @abstract
330
+ */
211
331
  static checkConfiguration() {
212
-
332
+ // Implemented in extending Engine class
213
333
  }
214
334
 
335
+ /**
336
+ * Returns the name of the engine class.
337
+ *
338
+ * @returns {string} The name of the engine class.
339
+ */
215
340
  static toString() {
216
341
  return this.name;
217
342
  }
218
- };
343
+ }
219
344
 
345
+ /**
346
+ * Represents a general error that occurs within the engine.
347
+ * Extends the built-in `Error` class.
348
+ */
220
349
  export class EngineError extends Error {
350
+ /**
351
+ * The underlying error that caused this engine error, if available.
352
+ * @type {Error|undefined}
353
+ */
221
354
  underlyingError;
355
+
356
+ /**
357
+ * Creates an instance of `EngineError`.
358
+ *
359
+ * @param {string} message - The error message.
360
+ * @param {Error} [error] - An optional underlying error that caused this error.
361
+ */
222
362
  constructor(message, error = undefined) {
223
363
  super(message);
224
364
  this.underlyingError = error;
225
365
  }
226
366
  }
227
367
 
368
+ /**
369
+ * Represents an error that occurs when a requested resource or item is not found in the engine.
370
+ * Extends the `EngineError` class.
371
+ */
228
372
  export class NotFoundEngineError extends EngineError {
373
+ /**
374
+ * Creates an instance of `NotFoundEngineError`.
375
+ *
376
+ * @param {string} message - The error message.
377
+ * @param {Error} [error] - An optional underlying error that caused this error.
378
+ */
229
379
  }
230
380
 
381
+ /**
382
+ * Represents an error indicating that a certain method or functionality is not implemented in the engine.
383
+ * Extends the `EngineError` class.
384
+ */
231
385
  export class NotImplementedError extends EngineError {
386
+ /**
387
+ * Creates an instance of `NotImplementedError`.
388
+ *
389
+ * @param {string} message - The error message.
390
+ * @param {Error} [error] - An optional underlying error that caused this error.
391
+ */
232
392
  }
233
393
 
394
+ /**
395
+ * Represents an error indicating that the engine is misconfigured.
396
+ * Extends the `EngineError` class.
397
+ */
234
398
  export class MissConfiguredError extends EngineError {
399
+ /**
400
+ * The configuration that led to the misconfiguration error.
401
+ * @type {Object}
402
+ */
235
403
  configuration;
236
404
 
405
+ /**
406
+ * Creates an instance of `MissConfiguredError`.
407
+ *
408
+ * @param {Object} configuration - The configuration object that caused the misconfiguration.
409
+ */
237
410
  constructor(configuration) {
238
411
  super('Engine is miss-configured');
239
412
  this.configuration = configuration;
240
413
  }
241
414
  }
415
+
416
+ export default Engine;
@@ -1,16 +1,36 @@
1
- import Engine, {EngineError, MissConfiguredError} from './Engine.js';
2
- import {dirname, join} from 'node:path';
1
+ import Engine, { EngineError, MissConfiguredError } from './Engine.js';
2
+ import { dirname, join } from 'node:path';
3
3
  import fs from 'node:fs/promises';
4
4
 
5
+ /**
6
+ * Custom error class for FileEngine-related errors.
7
+ * Extends the base `EngineError` class.
8
+ */
5
9
  class FileEngineError extends EngineError {}
6
10
 
11
+ /**
12
+ * Error thrown when writing to a file fails in `FileEngine`.
13
+ * Extends the `FileEngineError` class.
14
+ */
7
15
  class FailedWriteFileEngineError extends FileEngineError {}
8
16
 
9
17
  /**
18
+ * `FileEngine` class extends the base `Engine` class to implement
19
+ * file system-based storage and retrieval of model data.
20
+ *
10
21
  * @class FileEngine
11
22
  * @extends Engine
12
23
  */
13
- export default class FileEngine extends Engine {
24
+ class FileEngine extends Engine {
25
+ /**
26
+ * Configures the FileEngine with a given configuration object.
27
+ * Adds default `filesystem` configuration if not provided.
28
+ *
29
+ * @param {Object} configuration - Configuration settings for FileEngine.
30
+ * @param {Object} [configuration.filesystem] - Custom filesystem module (default: Node.js fs/promises).
31
+ * @param {Object} [configuration.path] - The absolute path on the filesystem to write models to.
32
+ * @returns {FileEngine} A configured instance of FileEngine.
33
+ */
14
34
  static configure(configuration) {
15
35
  if (!configuration.filesystem) {
16
36
  configuration.filesystem = fs;
@@ -18,42 +38,77 @@ export default class FileEngine extends Engine {
18
38
  return super.configure(configuration);
19
39
  }
20
40
 
41
+ /**
42
+ * Checks if the FileEngine has been configured correctly.
43
+ * Ensures that `path` and `filesystem` settings are present.
44
+ *
45
+ * @throws {MissConfiguredError} Throws if required configuration is missing.
46
+ */
21
47
  static checkConfiguration() {
22
- if (
23
- !this._configuration?.path ||
24
- !this._configuration?.filesystem
25
- ) throw new MissConfiguredError(this._configuration);
48
+ if (!this.configuration?.path || !this.configuration?.filesystem) {
49
+ throw new MissConfiguredError(this.configuration);
50
+ }
26
51
  }
27
52
 
28
- static async getById(id) {
29
- const filePath = join(this._configuration.path, `${id}.json`);
30
-
31
- return JSON.parse(await this._configuration.filesystem.readFile(filePath).then(f => f.toString()));
53
+ /**
54
+ * Retrieves a model by its ID from the file system.
55
+ *
56
+ * @param {string} id - The ID of the model to retrieve.
57
+ * @returns {Promise<Object>} The parsed model data.
58
+ * @throws {Error} Throws if the file cannot be read or parsed.
59
+ */
60
+ static getById(id) {
61
+ return this.configuration.filesystem
62
+ .readFile(join(this.configuration.path, `${id}.json`))
63
+ .then((b) => b.toString())
64
+ .then(JSON.parse);
32
65
  }
33
66
 
34
- static async getIndex(model) {
35
- return JSON.parse((await this._configuration.filesystem.readFile(join(this._configuration.path, model.name, '_index.json')).catch(() => '{}')).toString());
67
+ /**
68
+ * Retrieves the index for a given model from the file system.
69
+ *
70
+ * @param {Model.constructor?} model - The model for which the index is retrieved.
71
+ * @returns {Promise<Object>} The parsed index data.
72
+ * @throws {Error} Throws if the file cannot be read.
73
+ */
74
+ static getIndex(model) {
75
+ return this.configuration.filesystem
76
+ .readFile(join(this.configuration.path, model.toString(), '_index.json'))
77
+ .then((b) => b.toString())
78
+ .catch(() => '{}')
79
+ .then(JSON.parse);
36
80
  }
37
81
 
82
+ /**
83
+ * Saves a model to the file system.
84
+ *
85
+ * @param {Model} model - The model to save.
86
+ * @throws {FailedWriteFileEngineError} Throws if the model cannot be written to the file system.
87
+ */
38
88
  static async putModel(model) {
39
- const filePath = join(this._configuration.path, `${model.id}.json`);
40
-
89
+ const filePath = join(this.configuration.path, `${model.id}.json`);
41
90
  try {
42
- await this._configuration.filesystem.mkdir(dirname(filePath), {recursive: true});
43
- await this._configuration.filesystem.writeFile(filePath, JSON.stringify(model.toData()));
91
+ await this.configuration.filesystem.mkdir(dirname(filePath), { recursive: true });
92
+ await this.configuration.filesystem.writeFile(filePath, JSON.stringify(model.toData()));
44
93
  } catch (error) {
45
94
  throw new FailedWriteFileEngineError(`Failed to put file://${filePath}`, error);
46
95
  }
47
96
  }
48
97
 
98
+ /**
99
+ * Saves the index for multiple models to the file system.
100
+ *
101
+ * @param {Object} index - An object where keys are locations and values are arrays of models.
102
+ * @throws {FailedWriteFileEngineError} Throws if the index cannot be written to the file system.
103
+ */
49
104
  static async putIndex(index) {
50
105
  const processIndex = async (location, models) => {
51
- const modelIndex = Object.fromEntries(models.map(m => [m.id, m.toIndexData()]));
52
- const filePath = join(this._configuration.path, location, '_index.json');
53
- const currentIndex = JSON.parse((await this._configuration.filesystem.readFile(filePath).catch(() => '{}')).toString());
106
+ const modelIndex = Object.fromEntries(models.map((m) => [m.id, m.toIndexData()]));
107
+ const filePath = join(this.configuration.path, location, '_index.json');
108
+ const currentIndex = JSON.parse((await this.configuration.filesystem.readFile(filePath).catch(() => '{}')).toString());
54
109
 
55
110
  try {
56
- await this._configuration.filesystem.writeFile(filePath, JSON.stringify({
111
+ await this.configuration.filesystem.writeFile(filePath, JSON.stringify({
57
112
  ...currentIndex,
58
113
  ...modelIndex,
59
114
  }));
@@ -69,35 +124,66 @@ export default class FileEngine extends Engine {
69
124
  await processIndex('', Object.values(index).flat());
70
125
  }
71
126
 
72
- static async getSearchIndexCompiled(model) {
73
- return await this._configuration.filesystem.readFile(join(this._configuration.path, model.name, '_search_index.json'))
74
- .then(b => b.toString())
127
+ /**
128
+ * Retrieves the compiled search index for a model from the file system.
129
+ *
130
+ * @param {Model.constructor} model - The model for which the search index is retrieved.
131
+ * @returns {Promise<Object>} The parsed compiled search index.
132
+ * @throws {Error} Throws if the file cannot be read.
133
+ */
134
+ static getSearchIndexCompiled(model) {
135
+ return this.configuration.filesystem
136
+ .readFile(join(this.configuration.path, model.toString(), '_search_index.json'))
137
+ .then((b) => b.toString())
75
138
  .then(JSON.parse);
76
139
  }
77
140
 
78
- static async getSearchIndexRaw(model) {
79
- return await this._configuration.filesystem.readFile(join(this._configuration.path, model.name, '_search_index_raw.json'))
80
- .then(b => b.toString())
141
+ /**
142
+ * Retrieves the raw search index for a model from the file system.
143
+ *
144
+ * @param {Model.constructor} model - The model for which the raw search index is retrieved.
145
+ * @returns {Promise<Object>} The parsed raw search index.
146
+ * @throws {Error} Throws if the file cannot be read.
147
+ */
148
+ static getSearchIndexRaw(model) {
149
+ return this.configuration.filesystem
150
+ .readFile(join(this.configuration.path, model.toString(), '_search_index_raw.json'))
151
+ .then((b) => b.toString())
81
152
  .then(JSON.parse)
82
153
  .catch(() => ({}));
83
154
  }
84
155
 
156
+ /**
157
+ * Saves the compiled search index for a model to the file system.
158
+ *
159
+ * @param {Model.constructor} model - The model for which the compiled search index is saved.
160
+ * @param {Object} compiledIndex - The compiled search index to save.
161
+ * @throws {FailedWriteFileEngineError} Throws if the compiled index cannot be written to the file system.
162
+ */
85
163
  static async putSearchIndexCompiled(model, compiledIndex) {
86
- const filePath = join(this._configuration.path, model.name, '_search_index.json');
87
-
164
+ const filePath = join(this.configuration.path, model.toString(), '_search_index.json');
88
165
  try {
89
- await this._configuration.filesystem.writeFile(filePath, JSON.stringify(compiledIndex));
166
+ await this.configuration.filesystem.writeFile(filePath, JSON.stringify(compiledIndex));
90
167
  } catch (error) {
91
168
  throw new FailedWriteFileEngineError(`Failed to put file://${filePath}`, error);
92
169
  }
93
170
  }
94
171
 
172
+ /**
173
+ * Saves the raw search index for a model to the file system.
174
+ *
175
+ * @param {Model.constructor} model - The model for which the raw search index is saved.
176
+ * @param {Object} rawIndex - The raw search index to save.
177
+ * @throws {FailedWriteFileEngineError} Throws if the raw index cannot be written to the file system.
178
+ */
95
179
  static async putSearchIndexRaw(model, rawIndex) {
96
- const filePath = join(this._configuration.path, model.name, '_search_index_raw.json');
180
+ const filePath = join(this.configuration.path, model.toString(), '_search_index_raw.json');
97
181
  try {
98
- await this._configuration.filesystem.writeFile(filePath, JSON.stringify(rawIndex));
182
+ await this.configuration.filesystem.writeFile(filePath, JSON.stringify(rawIndex));
99
183
  } catch (error) {
100
184
  throw new FailedWriteFileEngineError(`Failed to put file://${filePath}`, error);
101
185
  }
102
186
  }
103
187
  }
188
+
189
+ export default FileEngine;