const fs = require('fs').promises;
import Resolver from './base';
// Maybe this should just be done with arguments passed to Resolver
/** Read and write objects and collections to a JSON file */
class JsonResolver extends Resolver {
constructor(file, appRoot) {
super(appRoot);
this._saveLocation = file;
}
async load() {
let j;
try {
if(this._saving) {
await this._saving;
}
const json = await fs.readFile(this._saveLocation, 'utf8');
j = [this._saveLocation, json];
const { collections, objects } = require(this._saveLocation);
this._storageHandlers._collections = collections;
this._storageHandlers._objects = objects;
} catch(e) {
console.log('Could not parse json', j);
switch(e.code) {
case 'MODULE_NOT_FOUND':
case 'ENOENT':
this._storageHandlers._collections = {};
this._storageHandlers._objects = {};
break;
default:
throw e;
}
}
}
async save(){
if(this._saving) {
await this._saving;
}
this._saving = fs.writeFile(this._saveLocation, JSON.stringify({ collections: this._storageHandlers._collections, objects: this._storageHandlers._objects }));
await this._saving;
this._saving = null;
}
async write(fn){
await this.load();
const r = await fn();
console.log('Write');
await this.save();
console.log('End write');
return r;
}
/**
* Store the object and assign it an ID
* @param {Object} object Created object
*/
async createObject(object){
return this.write(() => super.createObject(object));
}
/**
* Fetch and return an object by its ID
* @param {string} id Object ID
*/
async getObject(id) {
await this.load();
return super.getObject(id);
}
/**
* Update an object and store it
* @param {Object} object Object
*/
async updateObject(object){
// Save the object
return this.write(() => super.updateObject(object));
}
/**
* Delete an object
* @param {Object|string} objectOrId The object or ID to delete
*/
async deleteObject(objectOrId){
return this.write(() => super.deleteObject(objectOrId));
}
/**
* Return items for a collection
* @param {Collection} collection The collection to load for
*/
async collectionLoad(collection) {
await this.load();
console.log(this._)
return super.collectionLoad(collection);
}
/**
* Add an object to a collection and store it
* @param {Collection} collection The collection to add to
* @param {Object} object The object to add
*/
async collectionAdd(collection, object) {
return this.write(() => super.collectionAdd(collection, object));
}
/**
* Remove an object from a collection & persist
* @param {Collection} collection Target collection
* @param {Object|string} objectOrId Item to remove from collection
*/
async collectionRemove(collection, objectOrId) {
return this.write(() => super.collectionRemove(collection, objectOrId));
}
}
export default JsonResolver;