@node-elion/syncron
Version:
Provides a simple way to delivery models between sender and receiver
121 lines • 4.42 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModelEventConstructor = void 0;
const lodash_merge_1 = __importDefault(require("lodash.merge"));
const types_1 = require("./types");
class ModelEventConstructor {
constructor(config) {
this.modelState = new Map();
this.metadataState = new Map();
this.modelIndexMap = [];
this.config = {
onUpdate: config.onUpdate || (() => { }),
onMetaUpdate: config.onMetaUpdate || (() => { }),
onModelUpdate: config.onModelUpdate || (() => { }),
onSystemEvent: config.onSystemEvent || (() => { }),
};
}
onEvent(events) {
let updateMetadata = false;
let updateModels = false;
const systemEvent = [];
events.forEach((event) => {
switch (event.action) {
case types_1.ModelEventAction.UPDATE:
this.onUpdate.bind(this)(event);
updateModels = true;
break;
case types_1.ModelEventAction.UPDATE_INDEX:
// TODO: Check if index the same
this.onUpdateIndex.bind(this)(event);
updateModels = true;
break;
case types_1.ModelEventAction.DELETE:
this.onDelete.bind(this)(event);
updateModels = true;
break;
case types_1.ModelEventAction.META:
updateMetadata = true;
this.onMeta.bind(this)(event);
break;
case types_1.ModelEventAction.MANUAL_UPDATE:
systemEvent.push(event);
break;
default:
throw new Error(`Unknown action "${event.action}"`);
}
});
if (systemEvent.length) {
this.config.onSystemEvent(systemEvent);
}
if (updateMetadata || updateModels) {
this.updateInnerState.bind(this)();
}
if (updateModels) {
this.updateModelsState.bind(this)();
}
if (updateMetadata) {
this.updateMetadataState.bind(this)();
}
}
cleanModelFromIndexList(id, cleanMap = false) {
const oldIndexes = this.modelIndexMap
.map((item, index) => [item, index])
.filter(([itemId]) => itemId === id)
.map(([, index]) => index);
if (oldIndexes.length) {
if (cleanMap) {
this.modelState.delete(id);
}
oldIndexes.forEach((index) => {
this.modelIndexMap.splice(index, 1);
});
return true;
}
return false;
}
onUpdateIndex(event) {
const { id, index } = event.data;
this.cleanModelFromIndexList(id);
this.modelIndexMap.splice(index, 0, id);
}
onUpdate(event) {
const { data, index, id, updateStrategy } = event.data;
if (updateStrategy === "replace") {
this.modelState.set(id, data);
this.cleanModelFromIndexList(id);
this.modelIndexMap.splice(index, 0, id);
}
else {
this.modelState.set(id, (0, lodash_merge_1.default)(this.modelState.get(id) || {}, data));
this.cleanModelFromIndexList(id);
this.modelIndexMap.splice(index, 0, id);
}
}
onDelete(event) {
const { id } = event.data;
this.modelState.delete(id);
this.cleanModelFromIndexList(id, true);
}
onMeta(event) {
const { data, id } = event.data;
this.metadataState.set(id, data);
}
updateInnerState() {
this.config.onUpdate({
models: this.modelIndexMap.map((id) => this.modelState.get(id)),
metadataState: Object.fromEntries(this.metadataState),
});
}
updateMetadataState() {
this.config.onMetaUpdate(Object.fromEntries(this.metadataState));
}
updateModelsState() {
this.config.onModelUpdate(this.modelIndexMap.map((id) => this.modelState.get(id)));
}
}
exports.ModelEventConstructor = ModelEventConstructor;
//# sourceMappingURL=constructor.js.map