@tucmc/hazel
Version:
Clubs Data Processing Framework
189 lines (188 loc) • 8.09 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimulatedCollection = void 0;
const crypto = __importStar(require("crypto"));
const fs_1 = __importDefault(require("fs"));
const node_object_hash_1 = require("node-object-hash");
const process = __importStar(require("process"));
const DMap_1 = require("../../util/data/DMap");
const FieldDelete_1 = require("../../util/data/FieldDelete");
const LiveDMap_1 = require("../../util/data/LiveDMap");
const ReferableEntity_1 = require("../../util/data/ReferableEntity");
const Collection_1 = require("../../util/database/Collection");
const Colour_1 = require("../../util/debugger/Colour");
const Files_1 = require("../../util/io/Files");
class SimulatedCollection extends Collection_1.Collection {
simulatedContent;
constructor(name, preset, instructor) {
super(name);
const MODE = process.env.RUNTIME_MODE;
if (MODE === 'PROD') {
throw Error(`${Colour_1.ConsoleColour.RED}Simulated collection must not be used on PRODUCTION runtime.${Colour_1.ConsoleColour.RESET}`);
}
const buildCache = this.loadBuildCache();
if (buildCache) {
this.simulatedContent = new DMap_1.DMap(buildCache.content);
return;
}
this.simulatedContent = new DMap_1.DMap(preset);
instructor && instructor(this.simulatedContent);
this.saveBuildCache();
}
async handleChanges(changes) {
const object = new DMap_1.DMap(this.simulatedContent.getRecord());
changes.forEach((v) => {
if (!v._docID) {
v._docID = `simulated-${crypto.randomUUID()}`;
}
switch (v.type) {
case 'create':
object.set(v._docID, v.to);
break;
case 'delete':
object.remove(v._docID);
break;
case 'update': {
const parsedTo = {};
const original = object.get(v._docID);
if (!original)
break;
Object.keys(v.to).forEach((k) => {
const d = v.to[k];
if (d instanceof FieldDelete_1.FieldDelete) {
delete original[k];
return;
}
parsedTo[k] = d;
});
object.set(v._docID, { ...original, ...parsedTo });
}
}
});
this.debug.info(`${Colour_1.ConsoleColour.BGYELLOW}pushing changes to the database...`);
Files_1.Files.writeFile(object.getRecord(), `resource/collection/simulated/${this.name}`);
return changes;
}
initInstance(collectionName) {
return null;
}
retrieveCollection() {
return Promise.resolve(new DMap_1.DMap({}));
}
collectionMutator = (d) => d.getRecord();
async verifyChanges(changes) {
const data = this.loadBuildCache();
if (!data) {
return false;
}
const allDocs = new DMap_1.DMap(data.content).map((k, v) => {
return {
id: k,
...v
};
});
const evalResult = changes.map((v) => {
const possibleDbDoc = allDocs.filter((d) => d.id === v._docID);
const dbDoc = possibleDbDoc[0];
if (!dbDoc) {
if (v.type === 'delete') {
return { id: v._docID, report: [], reference: '--deleted--' };
}
return {
id: v._docID,
report: [{ present: '--document-not-existed--', expect: v.to }],
reference: '--document-not-existed--'
};
}
const mismatch = [];
Object.keys(v.to).forEach((k) => {
const refVal = v.to[k];
const dbD = dbDoc[k];
if (refVal instanceof FieldDelete_1.FieldDelete) {
if (!dbD)
return;
}
const refValHash = (0, node_object_hash_1.hasher)().hash(refVal);
const dbDHash = (0, node_object_hash_1.hasher)().hash(dbD);
if (dbDHash !== refValHash) {
mismatch.push({ key: k, present: dbD, expect: refVal });
}
});
return { id: v._docID, report: mismatch, reference: dbDoc };
});
const total = changes.length;
const missing = evalResult.filter((d) => d === null).length;
const passed = evalResult.filter((d) => d !== null && d.report.length === 0).length;
const failed = evalResult.filter((d) => d !== null && d.report.length > 0);
this.debug.info(`changes verified successfully (total ${total} entities)`);
this.debug.info(`${Colour_1.ConsoleColour.GREEN}passed ${passed}, ${Colour_1.ConsoleColour.RED}failed ${failed.length},${Colour_1.ConsoleColour.RESET} missing ${missing}`);
if (failed.length > 0) {
this.debug.warn(`${failed.length} changes results were found not updated. \nPlease check ${Colour_1.ConsoleColour.BOLD}./review/DEV/.verify_log.json${Colour_1.ConsoleColour.RESET}`);
fs_1.default.writeFileSync(`review/${process.env.RUNTIME_MODE}/.verify_log.json`, JSON.stringify(failed, null, 4));
}
return total === passed;
}
loadBuildCache() {
return Files_1.Files.readFile(`resource/collection/simulated/${this.name}`);
}
saveBuildCache() {
Files_1.Files.writeFile(this.simulatedContent.getRecord(), `resource/collection/simulated/${this.name}`);
}
buildRef() {
const mutated = this.collectionMutator(this.simulatedContent);
const refMap = new DMap_1.DMap(mutated);
const nMap = new LiveDMap_1.LiveDMap({});
refMap.iterateSync((k, v) => {
let id = k;
if (v._docID) {
id = v._docID;
}
const entity = new ReferableEntity_1.ReferableMapEntity(v, id);
entity.setSynthesized(false);
nMap.set(k, entity);
});
return nMap;
}
async readFromCache(autoFetch = false) {
return this.fetch();
}
async fetch() {
const loader = this.debug.loadingInfo('fetching collection from database.');
loader.succeed();
return this.buildRef();
}
async fetchNoRef() {
const loader = this.debug.loadingInfo('fetching collection from database.');
loader.succeed();
const mutated = this.collectionMutator(this.simulatedContent);
console.log(Object.keys(mutated));
return new DMap_1.DMap(this.clearEntityReference(mutated));
}
}
exports.SimulatedCollection = SimulatedCollection;