UNPKG

domain-objects

Version:

A simple, convenient way to represent domain objects, leverage domain knowledge, and add runtime validation in your code base.

67 lines 3.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dedupe = void 0; const error_fns_1 = require("@ehmpathy/error-fns"); const DomainEntity_1 = require("../../instantiation/DomainEntity"); const DomainObject_1 = require("../../instantiation/DomainObject"); const getUniqueIdentifier_1 = require("../getUniqueIdentifier"); const omitMetadataValues_1 = require("../omitMetadataValues"); const serialize_1 = require("../serde/serialize"); // define how to get the dedupe identity key for any object const toDedupeIdentity = (obj) => (0, serialize_1.serialize)(obj instanceof DomainObject_1.DomainObject ? (0, getUniqueIdentifier_1.getUniqueIdentifier)(obj) : obj); const toVersionIdentity = (obj) => obj instanceof DomainEntity_1.DomainEntity ? (0, serialize_1.serialize)((0, omitMetadataValues_1.omitMetadataValues)(obj)) : undefined; // if not an entity, there is no version identity /** * a method which deduplicates objects by their identity from within an array * * note * - when it operates on dobj instances, it extracts their identity via getUniqueIdentifier * - when it operates on anything else, it simply serializes the object */ const dedupe = (objs, options) => { // track the objects we have seen const objsSeenMetadata = {}; // track the ordered, deduped objs array, which we will build const objsDedupedList = []; // define how to check whether an obj has been seen already const getObjSeenMetadata = (obj) => { var _a; return (_a = objsSeenMetadata[toDedupeIdentity(obj)]) !== null && _a !== void 0 ? _a : null; }; // define how to add a new distinct item const addNewDistinctObj = (obj) => { // add to the objs seen lookup table objsSeenMetadata[toDedupeIdentity(obj)] = { seen: true, version: toVersionIdentity(obj), }; // add to the objs deduped list objsDedupedList.push(obj); }; // iterate through each object and add it to the deduped list as needed objs.forEach((thisObj) => { // determine if its been seen before const prevSeenMetadata = getObjSeenMetadata(thisObj); const hasBeenPrevSeen = prevSeenMetadata !== null; // if it has been seen, is an entity, and the caller didn't ask to CHOOSE_FIRST_OCCURRENCE, then check whether we should fail fast if (hasBeenPrevSeen && thisObj instanceof DomainEntity_1.DomainEntity && (options === null || options === void 0 ? void 0 : options.onMultipleEntityVersions) !== 'CHOOSE_FIRST_OCCURRENCE') { const versionPrevSeen = prevSeenMetadata.version; if (!versionPrevSeen) throw new error_fns_1.UnexpectedCodePathError('should have had prev seen metadata declared for a domain entity', { thisObj }); const versionCurrSeen = toVersionIdentity(thisObj); if (versionCurrSeen !== versionPrevSeen) throw new error_fns_1.BadRequestError(`Two different versions of the same entity were asked to be deduped. Options.onMultipleEntityVersions !== 'CHOOSE_FIRST_OCCURRENCE', so we're failing fast here, since we don't know which version should be kept.`, { thisObj, versionCurrSeen, versionPrevSeen, }); } // if it's been previously seen otherwise, then we can exit here as its a dupe if (hasBeenPrevSeen) return; // otherwise, since its not been previously seen, add it as a new distinct obj addNewDistinctObj(thisObj); }); // return all the distinct objs return objsDedupedList; }; exports.dedupe = dedupe; //# sourceMappingURL=dedupe.js.map