UNPKG

@inversifyjs/core

Version:

InversifyJs core package

100 lines 3.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OneToManyMapStar = void 0; const NOT_FOUND_INDEX = -1; /** * Data structure able to efficiently manage a set of models related to a set of properties in a one to many relation. */ class OneToManyMapStar { #modelToRelationMap; #relationToModelsMaps; #spec; constructor(spec) { this.#modelToRelationMap = new Map(); this.#relationToModelsMaps = {}; for (const specProperty of Reflect.ownKeys(spec)) { this.#relationToModelsMaps[specProperty] = new Map(); } this.#spec = spec; } add(model, relation) { this.#buildOrGetModelArray(model).push(relation); for (const relationKey of Reflect.ownKeys(relation)) { this.#buildOrGetRelationModels(relationKey, relation[relationKey]).push(model); } } clone() { const properties = Reflect.ownKeys(this.#spec); const clone = new OneToManyMapStar(this.#spec); this.#pushEntriesIntoMap(this.#modelToRelationMap, clone.#modelToRelationMap); for (const property of properties) { this.#pushEntriesIntoMap(this.#relationToModelsMaps[property], clone.#relationToModelsMaps[property]); } return clone; } get(key, value) { return this.#relationToModelsMaps[key].get(value); } getAllKeys(key) { return this.#relationToModelsMaps[key].keys(); } removeByRelation(key, value) { const models = this.get(key, value); if (models === undefined) { return; } const uniqueModelsSet = new Set(models); for (const model of uniqueModelsSet) { const relations = this.#modelToRelationMap.get(model); if (relations === undefined) { throw new Error('Expecting model relation, none found'); } for (const relation of relations) { if (relation[key] === value) { this.#removeModelFromRelationMaps(model, relation); } } this.#modelToRelationMap.delete(model); } } #buildOrGetModelArray(model) { let relations = this.#modelToRelationMap.get(model); if (relations === undefined) { relations = []; this.#modelToRelationMap.set(model, relations); } return relations; } #buildOrGetRelationModels(relationKey, relationValue) { let models = this.#relationToModelsMaps[relationKey].get(relationValue); if (models === undefined) { models = []; this.#relationToModelsMaps[relationKey].set(relationValue, models); } return models; } #pushEntriesIntoMap(source, target) { for (const [key, value] of source) { target.set(key, [...value]); } } #removeModelFromRelationMaps(model, relation) { for (const relationKey of Reflect.ownKeys(relation)) { this.#removeModelFromRelationMap(model, relationKey, relation[relationKey]); } } #removeModelFromRelationMap(model, relationKey, relationValue) { const relationModels = this.#relationToModelsMaps[relationKey].get(relationValue); if (relationModels !== undefined) { const index = relationModels.indexOf(model); if (index !== NOT_FOUND_INDEX) { relationModels.splice(index, 1); } if (relationModels.length === 0) { this.#relationToModelsMaps[relationKey].delete(relationValue); } } } } exports.OneToManyMapStar = OneToManyMapStar; //# sourceMappingURL=OneToManyMapStar.js.map