proxy-compare
Compare two objects using accessed properties with Proxy
Introduction
This is an internal library used in React Tracked.
Install
npm install proxy-compare
Usage
$ node
> const { createProxy, isChanged } = require('proxy-compare')
undefined
> state = { a: 1, b: 2 }
{ a: 1, b: 2 }
> affected = new WeakMap()
WeakMap { [items unknown] }
> proxy = createProxy(state, affected)
Proxy [ { a: 1, b: 2 },
{ r: [Function],
u: [Function],
get: [Function],
has: [Function],
ownKeys: [Function],
p: Proxy [ [Object], [Circular] ],
o: { a: 1, b: 2 },
t: false,
a: WeakMap { [items unknown] },
c: undefined } ]
> proxy.a
1
> isChanged(state, { a: 1, b: 22 }, affected)
false
> isChanged(state, { a: 11, b: 2 }, affected)
true
API
createProxy
Create a proxy.
This function will create a proxy at top level and proxy nested objects as you access them,
in order to keep track of which properties were accessed via get/has proxy handlers:
NOTE: Printing of WeakMap is hard to inspect and not very readable
for this purpose you can use the affectedToPathList
helper.
Parameters
obj
object Object that will be wrapped on the proxy.affected
WeakMap<object, unknown> WeakMap that will hold the tracking of which properties in the proxied object were accessed.proxyCache
WeakMap<object, unknown>? WeakMap that will help keep referential identity for proxies.
Examples
import { createProxy } from 'proxy-compare';
const original = { a: "1", c: "2", d: { e: "3" } };
const affected = new WeakMap();
const proxy = createProxy(original, affected);
proxy.a
proxy.d
Returns Proxy<object> Object wrapped in a proxy.
isChanged
Compare changes on objects.
This will compare the affected properties on tracked objects inside the proxy
to check if there were any changes made to it,
by default if no property was accessed on the proxy it will attempt to do a
reference equality check for the objects provided (Object.is(a, b)). If you access a property
on the proxy, then isChanged will only compare the affected properties.
Parameters
origObj
object The original object to compare.nextObj
object Object to compare with the original one.affected
WeakMap<object, unknown> WeakMap that holds the tracking of which properties in the proxied object were accessed.cache
WeakMap<object, unknown>? WeakMap that holds a cache of the comparisons for better performance with repetitive comparisons,
and to avoid infinite loop with circular structures.
Examples
import { createProxy, isChanged } from 'proxy-compare';
const original = { a: "1", c: "2", d: { e: "3" } };
const affected = new WeakMap();
const proxy = createProxy(original, affected);
proxy.a
isChanged(original, { a: "1" }, affected)
proxy.a = "2"
isChanged(original, { a: "1" }, affected)
Returns boolean Boolean indicating if the affected property on the object has changed.
getUntracked
Unwrap proxy to get the original object.
Used to retrieve the original object used to create the proxy instance with createProxy
.
Parameters
obj
Proxy<object> The proxy wrapper of the originial object.
Examples
import { createProxy, getUntracked } from 'proxy-compare';
const original = { a: "1", c: "2", d: { e: "3" } };
const affected = new WeakMap();
const proxy = createProxy(original, affected);
const originalFromProxy = getUntracked(proxy)
Obejct.is(original, originalFromProxy)
isChanged(original, originalFromProxy, affected)
Returns (object | null) Return either the unwrapped object if exists.
markToTrack
Mark object to be tracked.
This function marks an object that will be passed into createProxy
as marked to track or not. By default only Array and Object are marked to track,
so this is useful for example to mark a class instance to track or to mark a object
to be untracked when creating your proxy.
Parameters
obj
object Object to mark as tracked or not.mark
(optional, default true
)boolean
mark Boolean indicating whether you want to track this object or not.
Examples
import { createProxy, markToTrack, isChanged } from 'proxy-compare';
const nested = { e: "3" }
markToTrack(nested, false)
const original = { a: "1", c: "2", d: nested };
const affected = new WeakMap();
const proxy = createProxy(original, affected);
proxy.d.e
isChanged(original, { d: { e: "3" } }, affected)
Returns undefined No return.
Projects using this library
Similar libraries