UNPKG

domain-objects

Version:

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

69 lines 3.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dedupe = void 0; const helpful_errors_1 = require("helpful-errors"); const isOfDomainEntity_1 = require("../../instantiation/inherit/isOfDomainEntity"); const isOfDomainObject_1 = require("../../instantiation/inherit/isOfDomainObject"); const getUniqueIdentifier_1 = require("../../manipulation/getUniqueIdentifier"); const omitMetadata_1 = require("../../manipulation/omitMetadata"); const serialize_1 = require("../../manipulation/serde/serialize"); // define how to get the dedupe identity key for any object const toDedupeIdentity = (obj) => (0, serialize_1.serialize)((0, isOfDomainObject_1.isOfDomainObject)(obj) ? (0, getUniqueIdentifier_1.getUniqueIdentifier)(obj) : obj); const toVersionIdentity = (obj) => (0, isOfDomainEntity_1.isOfDomainEntity)(obj) ? (0, serialize_1.serialize)((0, omitMetadata_1.omitMetadata)(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) => objsSeenMetadata[toDedupeIdentity(obj)] ?? 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 && (0, isOfDomainEntity_1.isOfDomainEntity)(thisObj) && options?.onMultipleEntityVersions !== 'CHOOSE_FIRST_OCCURRENCE') { const versionPrevSeen = prevSeenMetadata.version; if (!versionPrevSeen) throw new helpful_errors_1.UnexpectedCodePathError('should have had prev seen metadata declared for a domain entity', { thisObj }); const versionCurrSeen = toVersionIdentity(thisObj); if (versionCurrSeen !== versionPrevSeen) throw new helpful_errors_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