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
JavaScript
;
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