Merge branch '91-feat-primitives-add-diffmap-function-to-extmap' into 'development'

Resolve "Feat(Primitives): Add diffMap function to ExtMap"

Closes #91

See merge request GeneralProtocols/xo/stack!129
This commit is contained in:
Emergent Reasons
2025-09-10 23:35:30 +00:00
+55 -1
View File
@@ -2,6 +2,12 @@ import { Transaction } from './transaction.js';
import { binToHex } from '@bitauth/libauth'; import { binToHex } from '@bitauth/libauth';
export type MapDiff<T> = {
added: ExtMap<T>;
removed: ExtMap<T>;
updated: ExtMap<T>;
};
// TODO: The below should probably be moved and renamed. // TODO: The below should probably be moved and renamed.
/** /**
* Sort transactions by the order in which they should be broadcast. * Sort transactions by the order in which they should be broadcast.
@@ -66,7 +72,7 @@ export class ExtMap<T> extends Map<PropertyKey, T> {
static fromObject<T>(object: { [key: PropertyKey]: T }): ExtMap<T> { static fromObject<T>(object: { [key: PropertyKey]: T }): ExtMap<T> {
const collection = new ExtMap<T>(); const collection = new ExtMap<T>();
for (let [key, value] of Object.entries(object)) { for (const [key, value] of Object.entries(object)) {
collection.set(key, value); collection.set(key, value);
} }
return collection; return collection;
@@ -88,6 +94,41 @@ export class ExtMap<T> extends Map<PropertyKey, T> {
return flattened; 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<T>(
prev: ExtMap<T>,
next: ExtMap<T>,
equals: (a: T, b: T) => boolean = (a, b) => a === b,
): MapDiff<T> {
const added = new ExtMap<T>();
const removed = new ExtMap<T>();
const updated = new ExtMap<T>();
// 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 { getOrFail(key: string): T {
const value = this.get(key); const value = this.get(key);
@@ -158,6 +199,19 @@ export class ExtMap<T> extends Map<PropertyKey, T> {
return result; 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<T>,
comparator: (a: T, b: T) => boolean = (a, b) => a === b,
): MapDiff<T> {
return ExtMap.diffMap(this, other, comparator);
}
/** /**
* Converts the collection to a plain object * Converts the collection to a plain object
*/ */