Re-use your schema definitions to derive super fast, in-memory deep equal functions (with even faster compiled deep equal functions coming soon!)
An "deep equal" function" is a function that accepts 2 values, and returns a boolean indicating whether the values are made up of the same component parts.
The @traversable/schema-deep-equal
package can be used in 2 ways:
As a side-effect import, which will install a .equals
method to all schemas.
To derive a deep equal function from a schema recursively, by walking the schema's AST
Derived deep equal functions are "isomorphic" -- JS-speak for "works on both the client and on the server".
That means you can use @traversable/schema-deep-equal
anywhere: in the browser (they work great with state
libraries that use an equality function to determine when to re-render!), in a BFF-architecture, with
CloudFlare workers -- anywhere.
Our deep equal functions are:
node:assert/deepStrictEqual
, andlodash.deepEqual
If you'd like to check our math, the benchmarks are public and available here.
@traversable/schema-deep-equal
have been thoroughly
fuzz-tested against millions of randomly generated inputs
(via fast-check
) to make the transition
seamless for our usersYou can install .equals
on all schemas with a single line:
import { t } from '@traversable/schema'
import '@traversable/schema-deep-equal/install'
// ↑↑ importing `@traversable/schema-deep-equal/install` installs `.equal` on all schemas
const Schema = t.object({
abc: t.boolean,
def: t.optional(t.number.min(3)),
})
let x = { abc: true, def: 10 }
let y = { ...x }
let z = { ...x, abc: false }
console.log(Object.is(x, y)) // => false 😭
console.log(Schema.equals(x, y)) // => true 😌
console.log(Schema.equals(y, z)) // => false 😌
If you'd prefer not to install .equals
to all schemas, use Eq.fromSchema
(or you can import fromSchema
directly, if you're bundle-phobic).
import { t } from '@traversable/schema'
import { Eq } from '@traversable/schema-deep-equal'
const Schema = t.object({
abc: t.boolean,
def: t.optional(t.number.min(3)),
})
const equalsFn = Eq.fromSchema(Schema)
let x = { abc: true, def: 10 }
let y = { ...x }
let z = { ...x, abc: false }
console.log(Object.is(x, y)) // => false 😭
console.log(equalsFn(x, y)) // => true 😌
console.log(equalsFn(y, z)) // => false 😌