JSPM

  • Created
  • Published
  • Downloads 311
  • Score
    100M100P100Q97491F
  • License MIT

Sneaky equality check between objects using proxies

Package Exports

  • @indutny/sneequals
  • @indutny/sneequals/dist/src/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@indutny/sneequals) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@indutny/sneequals

npm size CI Status

Sneaky equals comparison between objects that checks only the properties that were touched.

Inspired by proxy-compare.

Installation

npm install @indutny/sneequals

Usage

One object comparison

import { watch } from '@indutny/sneequals';

const originalData = {
  nested: {
    prop: 1,
  },
  avatar: {
    src: 'image.png',
  },
};

const { proxy, watcher } = watch(originalData);

function doSomethingWithData(data) {
  return {
    prop: data.nested.prop,
    x: data.avatar,
  };
}

const result = watcher.unwrap(doSomethingWithData(proxy));

// Prevent further access to proxy
watcher.stop();

const sneakyEqualData = {
  nested: {
    prop: 1,
    other: 'ignored',
  },
  avatar: original.avatar,
};

console.log(watcher.isChanged(originalData, sneakyEqualData)); // false

const sneakyDifferentData = {
  nested: {
    prop: 2,
  },
  avatar: {
    ...original.avatar,
  },
};

console.log(watcher.isChanged(originalData, sneakyDifferentData)); // true

Multi object comparison

import { watchAll } from '@indutny/sneequals';

const inputA = { a: 1 };
const inputB = { b: 2 };

const { proxies, watcher } = watchAll([inputA, inputB]);

function fn(a, b) {
  return a.a + a.b;
}

const result = watcher.unwrap(fn(...proxies));

// Prevent further access to proxies
watcher.stop();

console.log(watcher.isChanged(inputA, { a: 1 })); // false
console.log(watcher.isChanged(inputB, { b: 3 })); // true

Memoization

memoize() is provided as a convenience API method. It has a simple WeakMap-based cache that keys by first object argument of the function and/or global internal key.

import { memoize } from '@indutny/sneequals';

const fn = memoize((a, b) => {
  return a.a + a.b;
});

Benchmarks

On M1 Macbook Pro 13:

$ npm run bench
watch+unwrap: 554431.062 operations/second
isChanged: 4575487.253 operations/second
memoize: 4070533.538 operations/second

Credits

Name coined by Scott Nonnenberg.

LICENSE

This software is licensed under the MIT License.