From 8066d5e61996d66da3b5f5c2395fd7188ce89230 Mon Sep 17 00:00:00 2001 From: Harvey Zuccon Date: Wed, 10 Sep 2025 23:35:30 +0000 Subject: [PATCH] Resolve "Feat(Primitives): Add diffMap function to ExtMap" --- packages/primitives/src/utils.ts | 56 +++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/packages/primitives/src/utils.ts b/packages/primitives/src/utils.ts index ec35829..5710451 100644 --- a/packages/primitives/src/utils.ts +++ b/packages/primitives/src/utils.ts @@ -2,6 +2,12 @@ import { Transaction } from './transaction.js'; import { binToHex } from '@bitauth/libauth'; +export type MapDiff = { + added: ExtMap; + removed: ExtMap; + updated: ExtMap; +}; + // TODO: The below should probably be moved and renamed. /** * Sort transactions by the order in which they should be broadcast. @@ -66,7 +72,7 @@ export class ExtMap extends Map { static fromObject(object: { [key: PropertyKey]: T }): ExtMap { const collection = new ExtMap(); - for (let [key, value] of Object.entries(object)) { + for (const [key, value] of Object.entries(object)) { collection.set(key, value); } return collection; @@ -88,6 +94,41 @@ export class ExtMap extends Map { return flattened; } + /** + * Diff two maps and return a map of added, removed and updated items. + * @param prev - The original map + * @param next - The map to diff against the original map + * @param equals - Optional function to determine if two items are equal. Default is to use strict equality comparison of the values. + * @returns A map of added, removed and updated items + */ + static diffMap( + prev: ExtMap, + next: ExtMap, + equals: (a: T, b: T) => boolean = (a, b) => a === b, + ): MapDiff { + const added = new ExtMap(); + const removed = new ExtMap(); + const updated = new ExtMap(); + + // Detect additions & updates + next.forEach((value, key) => { + if (!prev.has(key)) { + added.set(key, value); + } else if (!equals(value, prev.get(key)!)) { + updated.set(key, value); + } + }); + + // Detect removals + prev.forEach((value, key) => { + if (!next.has(key)) { + removed.set(key, value); + } + }); + + return { added, removed, updated }; + } + getOrFail(key: string): T { const value = this.get(key); @@ -158,6 +199,19 @@ export class ExtMap extends Map { return result; } + /** + * Diff this map against another map and return a map of added, removed and updated items. + * @param other - The map to diff against this one + * @param comparator - Optional function to determine if two items are equal. Default is to use strict equality comparison of the values. + * @returns A map of added, removed and updated items + */ + diff( + other: ExtMap, + comparator: (a: T, b: T) => boolean = (a, b) => a === b, + ): MapDiff { + return ExtMap.diffMap(this, other, comparator); + } + /** * Converts the collection to a plain object */