UNPKG

@dolittle/sdk.common

Version:

Dolittle is a decentralized, distributed, event-driven microservice platform built to harness the power of events.

204 lines 21.4 kB
"use strict"; // Copyright (c) Dolittle. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. Object.defineProperty(exports, "__esModule", { value: true }); exports.ModelBuilder = void 0; const CannotUnbindIdentifierFromProcessorBuilderThatIsNotBound_1 = require("./CannotUnbindIdentifierFromProcessorBuilderThatIsNotBound"); const CannotUnbindIdentifierFromTypeThatIsNotBound_1 = require("./CannotUnbindIdentifierFromTypeThatIsNotBound"); const IModelBuilder_1 = require("./IModelBuilder"); const Model_1 = require("./Model"); /** * Represents an implementation of {@link IModelBuilder}. */ class ModelBuilder extends IModelBuilder_1.IModelBuilder { constructor() { super(...arguments); this._typesByIdentifier = new Map(); this._processorBuildersByIdentifier = new Map(); } /** @inheritdoc */ bindIdentifierToType(identifier, type) { const types = this.getMapList(this._typesByIdentifier, identifier); types.push([identifier, type]); } /** @inheritdoc */ unbindIdentifierFromType(identifier, type) { const types = this.getMapList(this._typesByIdentifier, identifier); const foundIndex = this.findListIndex(types, identifier, type); if (foundIndex < 0) { throw new CannotUnbindIdentifierFromTypeThatIsNotBound_1.CannotUnbindIdentifierFromTypeThatIsNotBound(identifier, type); } types.splice(foundIndex, 1); } /** @inheritdoc */ bindIdentifierToProcessorBuilder(identifier, processorBuilder) { const processorBuilders = this.getMapList(this._processorBuildersByIdentifier, identifier); processorBuilders.push([identifier, processorBuilder]); } /** @inheritdoc */ unbindIdentifierFromProcessorBuilder(identifier, processorBuilder) { const processorBuilders = this.getMapList(this._processorBuildersByIdentifier, identifier); const foundIndex = this.findListIndex(processorBuilders, identifier, processorBuilder); if (foundIndex < 0) { throw new CannotUnbindIdentifierFromProcessorBuilderThatIsNotBound_1.CannotUnbindIdentifierFromProcessorBuilderThatIsNotBound(identifier, processorBuilder); } processorBuilders.splice(foundIndex, 1); } /** @inheritdoc */ build(buildResults) { const deduplicatedTypes = this.deduplicateBindings(this._typesByIdentifier, (left, right) => left === right, (identifier, type, duplicates) => { buildResults.addInformation(`Type binding from ${identifier.constructor.name} to ${type.name} appeared ${duplicates} times`); }); const deduplicatedProcessorBuilders = this.deduplicateBindings(this._processorBuildersByIdentifier, (left, right) => left.equals(right), (identifier, processorBuilder, duplicates) => { buildResults.addInformation(`Processor binding from ${identifier.constructor.name} to ${processorBuilder.constructor.name} appeared ${duplicates} times`); }); const singlyBoundTypes = this.singlyBoundValues(deduplicatedTypes, (left, right) => left === right, (type, identifiers) => { buildResults.addFailure(`Type ${type.name} is bound to multiple identifiers:`); for (const identifier of identifiers) { buildResults.addFailure(`\t ${identifier}. This binding will be ignored`); } }); const singlyProcessorBuilders = this.singlyBoundValues(deduplicatedProcessorBuilders, (left, right) => left.equals(right), (processorBuilder, identifiers) => { buildResults.addFailure(`Type ${processorBuilder.constructor.name} is bound to multiple identifiers:`); for (const identifier of identifiers) { buildResults.addFailure(`\t ${identifier}. This binding will be ignored`); } }); const validTypeBindings = []; const validProcessorBuilderBindings = []; const ids = new Set([...singlyBoundTypes.keys(), ...singlyProcessorBuilders.keys()]); for (const id of ids) { const [coexistentTypes, conflictingTypes] = this.splitCoexistingAndConflictingBindings(singlyBoundTypes, id, (left, right) => left === right); const [coexistentProcessorBuilders, conflictingProcessorBuilders] = this.splitCoexistingAndConflictingBindings(deduplicatedProcessorBuilders, id, (left, right) => left.equals(right)); if (conflictingTypes.length === 0 && conflictingProcessorBuilders.length === 0) { validTypeBindings.push(...coexistentTypes); validProcessorBuilderBindings.push(...coexistentProcessorBuilders); continue; } const conflicts = []; if (conflictingTypes.length > 0) conflicts.push('types'); if (conflictingProcessorBuilders.length > 0) conflicts.push('processors'); buildResults.addFailure(`The identifier ${id} was bound to conflicting ${conflicts.join(' and ')}:`); for (const [identifier, type] of conflictingTypes) { buildResults.addFailure(`\t ${identifier} was bound to ${type.name}. This binding will be ignored`); } for (const [identifier, processorBuilder] of conflictingProcessorBuilders) { buildResults.addFailure(`\t ${identifier} was bound to ${processorBuilder.constructor.name}. This binding will be ignored`); } if (coexistentTypes.length > 0 || coexistentProcessorBuilders.length > 0) { buildResults.addFailure(`The identifier ${id} was also bound to:`); } for (const [identifier, type] of coexistentTypes) { buildResults.addFailure(`\t ${identifier} binding to ${type.name}. This binding will be ignored`); } for (const [identifier, processorBuilder] of coexistentProcessorBuilders) { buildResults.addFailure(`\t ${identifier} binding to ${processorBuilder.constructor.name}. This binding will be ignored`); } } for (const [identifier, type] of validTypeBindings) { buildResults.addInformation(`${identifier} will be bound to type ${type.name}`); } for (const [identifier, processorBuilder] of validProcessorBuilderBindings) { buildResults.addInformation(`${identifier} will be bound to processor builder ${processorBuilder.constructor.name}`); } return new Model_1.Model(validTypeBindings, validProcessorBuilderBindings); } getMapList(map, identifier) { const key = identifier.id.value.toString(); if (!map.has(key)) { const list = []; map.set(key, list); return list; } else { return map.get(key); } } ; findListIndex(list, identifier, value) { return list.findIndex(([existingIdentifier, existingValue]) => { return existingIdentifier.equals(identifier) && existingValue === value; }); } ; deduplicateBindings(map, comparer, callback) { const filteredMap = new Map(); for (const [key, bindings] of map.entries()) { const countedBindings = []; counting: for (const [identifier, value] of bindings) { for (const existing of countedBindings) { const [existingIdentifier, existingValue, duplicates] = existing; if (existingIdentifier.equals(identifier) && comparer(existingValue, value)) { existing[2] = duplicates + 1; continue counting; } } countedBindings.push([identifier, value, 1]); } const filteredBindings = []; for (const [identifier, value, duplicates] of countedBindings) { if (duplicates > 1) { callback(identifier, value, duplicates); } filteredBindings.push([identifier, value]); } filteredMap.set(key, filteredBindings); } return filteredMap; } singlyBoundValues(map, comparer, callback) { const groupedValues = []; const allValues = Array.from(map.values()).flat(); grouping: for (const [identifier, value] of allValues) { for (const [groupedValue, groupedIdentifiers] of groupedValues) { if (comparer(value, groupedValue)) { groupedIdentifiers.push(identifier); continue grouping; } } groupedValues.push([value, [identifier]]); } const singlyBoundMap = new Map(); for (const [value, identifiers] of groupedValues) { if (identifiers.length === 1) { const identifier = identifiers[0]; singlyBoundMap.set(identifier.id.value.toString(), [[identifier, value]]); } else { callback(value, identifiers); } } return singlyBoundMap; } splitCoexistingAndConflictingBindings(map, key, comparer) { if (!map.has(key)) return [[], []]; const bindings = map.get(key); const conflicts = new Set(); for (const [identifier, value] of bindings) { for (const [otherIdentifier, otherValue] of bindings) { const canCoexist = (identifier.equals(otherIdentifier) && comparer(value, otherValue)) || (identifier.canCoexistWith(otherIdentifier) && !comparer(value, otherValue)); if (!canCoexist) { conflicts.add(identifier); conflicts.add(otherIdentifier); } } } const coexisting = []; const conflicting = []; for (const [identifier, value] of bindings) { if (conflicts.has(identifier)) { conflicting.push([identifier, value]); } else { coexisting.push([identifier, value]); } } return [coexisting, conflicting]; } } exports.ModelBuilder = ModelBuilder; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTW9kZWxCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6Ii4uLyIsInNvdXJjZXMiOlsiTW9kZWwvTW9kZWxCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0MscUdBQXFHOzs7QUFLckcseUlBQXNJO0FBQ3RJLGlIQUE4RztBQUk5RyxtREFBZ0Q7QUFDaEQsbUNBQWdDO0FBS2hDOztHQUVHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsNkJBQWE7SUFBL0M7O1FBQ3FCLHVCQUFrQixHQUFvQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2hFLG1DQUE4QixHQUFvQyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBb09qRyxDQUFDO0lBbE9HLGtCQUFrQjtJQUNsQixvQkFBb0IsQ0FBQyxVQUF5QixFQUFFLElBQXNCO1FBQ2xFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ25FLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLHdCQUF3QixDQUFDLFVBQXlCLEVBQUUsSUFBc0I7UUFDdEUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDbkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELElBQUksVUFBVSxHQUFHLENBQUMsRUFBRTtZQUNoQixNQUFNLElBQUksMkZBQTRDLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQzVFO1FBQ0QsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixn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