From bc08321fafd1a4065cd145203982fc91af0b9bbd Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 19 Apr 2023 18:23:14 +0200 Subject: [PATCH 1/2] refactor: expose `diff` function types --- src/diff.ts | 88 +++++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/src/diff.ts b/src/diff.ts index 94a51e7..119f1ec 100644 --- a/src/diff.ts +++ b/src/diff.ts @@ -1,67 +1,77 @@ import { objectHash, HashOptions } from "./object-hash"; -export function diff(obj1: any, obj2: any, opts: HashOptions = {}): any[] { +export function diff( + obj1: any, + obj2: any, + opts: HashOptions = {} +): DiffEntry[] { const h1 = _toHashedObject(obj1, opts); const h2 = _toHashedObject(obj2, opts); return _diff(h1, h2, opts); } -function _diff(h1: HashEntry, h2: HashEntry, opts: HashOptions = {}): any[] { +function _diff( + h1: DiffHashedObject, + h2: DiffHashedObject, + opts: HashOptions = {} +): DiffEntry[] { const diffs = []; const allProps = new Set([ - ...Object.keys(h1.$props || {}), - ...Object.keys(h2.$props || {}), + ...Object.keys(h1.props || {}), + ...Object.keys(h2.props || {}), ]); - if (h1.$props && h2.$props) { + if (h1.props && h2.props) { for (const prop of allProps) { - const p1 = h1.$props[prop]; - const p2 = h2.$props[prop]; + const p1 = h1.props[prop]; + const p2 = h2.props[prop]; if (p1 && p2) { - diffs.push(..._diff(h1.$props?.[prop], h2.$props?.[prop], opts)); - } else if (p1) { - diffs.push(new DiffEntry("removed", p1)); - } else if (p2) { - diffs.push(new DiffEntry("added", p2)); + diffs.push(..._diff(h1.props?.[prop], h2.props?.[prop], opts)); + } else if (p1 || p2) { + diffs.push( + new DiffEntry((p2 || p1).key, p1 ? "removed" : "added", p2, p1) + ); } } } - if (allProps.size === 0 && h1.$hash !== h2.$hash) { - diffs.push(new DiffEntry("changed", h1, h2)); + if (allProps.size === 0 && h1.hash !== h2.hash) { + diffs.push(new DiffEntry((h2 || h1).key, "changed", h2, h1)); } return diffs; } -function _toHashedObject(obj, opts: HashOptions, key = ""): HashEntry { +function _toHashedObject(obj, opts: HashOptions, key = ""): DiffHashedObject { if (obj && typeof obj !== "object") { - return new HashEntry(key, obj, objectHash(obj, opts)); + return new DiffHashedObject(key, obj, objectHash(obj, opts)); } - const $props: Record = {}; + const props: Record = {}; const hashes = []; for (const _key in obj) { - $props[_key] = _toHashedObject( + props[_key] = _toHashedObject( obj[_key], opts, key ? `${key}.${_key}` : _key ); - hashes.push($props[_key].$hash); + hashes.push(props[_key].hash); } - return new HashEntry(key, obj, `{${hashes.join(":")}}`, $props); + return new DiffHashedObject(key, obj, `{${hashes.join(":")}}`, props); } // --- Internal classes --- -class DiffEntry { +export class DiffEntry { // eslint-disable-next-line no-useless-constructor - private key: string; constructor( + public key: string, public type: "changed" | "added" | "removed", - public o1: HashEntry, - public o2?: HashEntry - ) { - this.key = o1.$key || "."; + public newValue: DiffHashedObject, + public oldValue?: DiffHashedObject + ) {} + + toString() { + return this.toJSON(); } toJSON() { @@ -73,33 +83,33 @@ class DiffEntry { case "changed": return `[~] Changed ${ this.key - } from ${this.o1.toString()} to ${this.o2.toString()}`; + } from ${this.oldValue.toString()} to ${this.newValue.toString()}`; } } } -class HashEntry { +export class DiffHashedObject { // eslint-disable-next-line no-useless-constructor constructor( - public $key: string, - public $value: any, - public $hash?: string, - public $props?: Record + public key: string, + public value: any, + public hash?: string, + public props?: Record ) {} toString() { - if (!this.$props) { - return JSON.stringify(this.$value); + if (!this.props) { + return JSON.stringify(this.value); } else { - return `{${Object.keys(this.$props).join(",")}}`; + return `{${Object.keys(this.props).join(",")}}`; } } toJSON() { - const k = this.$key || ""; - if (this.$props) { - return `${k}({${Object.keys(this.$props).join(",")}})`; + const k = this.key || "."; + if (this.props) { + return `${k}({${Object.keys(this.props).join(",")}})`; } - return `${k}(${this.$value})`; + return `${k}(${this.value})`; } } From d992f0b440562353366e8b4c50fd4a192ec345b1 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 19 Apr 2023 18:23:24 +0200 Subject: [PATCH 2/2] chore(release): v1.1.1 --- CHANGELOG.md | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a477fa5..04fa74a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## v1.1.1 + +[compare changes](https://github.com/unjs/ohash/compare/v1.1.0...v1.1.1) + + +### 💅 Refactors + + - Expose `diff` function types ([bc08321](https://github.com/unjs/ohash/commit/bc08321)) + +### ❤️ Contributors + +- Pooya Parsa ([@pi0](http://github.com/pi0)) + ## v1.1.0 [compare changes](https://github.com/unjs/ohash/compare/v1.0.0...v1.1.0) diff --git a/package.json b/package.json index d627d56..1aaad3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ohash", - "version": "1.1.0", + "version": "1.1.1", "description": "Super fast hashing library based on murmurhash3 written in Vanilla JS", "repository": "unjs/ohash", "license": "MIT",