Skip to content

Commit

Permalink
fix(use-data-query): use local stable value hashing function
Browse files Browse the repository at this point in the history
  • Loading branch information
ismay committed Aug 10, 2021
1 parent 524eb3e commit 147ba28
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 10 deletions.
1 change: 0 additions & 1 deletion services/data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
"coverage": "yarn test --coverage"
},
"dependencies": {
"fast-safe-stringify": "^2.0.8",
"react-query": "^3.13.11"
}
}
40 changes: 40 additions & 0 deletions services/data/src/react/hooks/stableValueHash.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { stableValueHash } from './stableValueHash'

describe('stableValueHash', () => {
it('sorts objects before hashing', () => {
const one = {
a: {
one: 1,
two: 2,
three: 3,
},
b: [1, 2, 3],
c: 'c',
}
const two = {
c: 'c',
b: [1, 2, 3],
a: {
three: 3,
two: 2,
one: 1,
},
}

expect(stableValueHash(one)).toEqual(stableValueHash(two))
})

it('can handle primitives', () => {
const one = undefined
const two = 'string'
const three = 3
const four = null
const five = true

expect(stableValueHash(one)).toMatchInlineSnapshot(`undefined`)
expect(stableValueHash(two)).toMatchInlineSnapshot(`"\\"string\\""`)
expect(stableValueHash(three)).toMatchInlineSnapshot(`"3"`)
expect(stableValueHash(four)).toMatchInlineSnapshot(`"null"`)
expect(stableValueHash(five)).toMatchInlineSnapshot(`"true"`)
})
})
48 changes: 48 additions & 0 deletions services/data/src/react/hooks/stableValueHash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function hasObjectPrototype(o: any): boolean {
return Object.prototype.toString.call(o) === '[object Object]'
}

// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/explicit-module-boundary-types
export function isPlainObject(o: any): o is Object {
if (!hasObjectPrototype(o)) {
return false
}

// If has modified constructor
const ctor = o.constructor
if (typeof ctor === 'undefined') {
return true
}

// If has modified prototype
const prot = ctor.prototype
if (!hasObjectPrototype(prot)) {
return false
}

// If constructor does not have an Object-specific method
if (!Object.prototype.hasOwnProperty.call(prot, 'isPrototypeOf')) {
return false
}

// Most likely a plain Object
return true
}

/**
* Hashes the value into a stable hash.
*/

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function stableValueHash(value: any): string {
return JSON.stringify(value, (_, val) =>
isPlainObject(val)
? Object.keys(val)
.sort()
.reduce((result, key) => {
result[key] = val[key]
return result
}, {} as any)
: val
)
}
2 changes: 1 addition & 1 deletion services/data/src/react/hooks/useDataQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ describe('useDataQuery', () => {
})

act(() => {
result.current.refetch({ variables })
result.current.refetch(variables)
})

await waitForNextUpdate()
Expand Down
5 changes: 2 additions & 3 deletions services/data/src/react/hooks/useDataQuery.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import stringify from 'fast-safe-stringify'
import { useState, useRef } from 'react'
import { useQuery, setLogger } from 'react-query'
import { Query, QueryOptions } from '../../engine'
import { FetchError } from '../../engine/types/FetchError'
import { QueryRenderInput, QueryRefetchFunction } from '../../types'
import { stableValueHash } from './stableValueHash'
import { useDataEngine } from './useDataEngine'
import { useStaticInput } from './useStaticInput'

Expand Down Expand Up @@ -106,8 +106,7 @@ export const useDataQuery = (
if (newVariables) {
const merged = { ...variables, ...newVariables }
const identical =
stringify.stableStringify(variables) ===
stringify.stableStringify(merged)
stableValueHash(variables) === stableValueHash(merged)

setVariables(merged)

Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6434,11 +6434,6 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=

fast-safe-stringify@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz#dc2af48c46cf712b683e849b2bbd446b32de936f"
integrity sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==

fastq@^1.6.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
Expand Down

0 comments on commit 147ba28

Please sign in to comment.