Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔬 Make useRawLogs more efficient and responsive #1151

Merged
merged 25 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5b4f0fd
Make useRawLogs more efficient and responsive
TylerEther Apr 21, 2024
620bdba
Improve useRawLogs
TylerEther Apr 30, 2024
5e10010
Fix and simplify nullish checking in deepEqual
TylerEther May 9, 2024
0611e13
Remove comment in deepEqual
TylerEther May 9, 2024
9450e66
Cleanup useResolvedFilter
TylerEther May 9, 2024
2617464
Move isPrimitive and deepEqual to common helper
TylerEther May 9, 2024
33d7551
Fix bug in deepEqual
TylerEther May 9, 2024
1bade54
Add comment to deepEqual
TylerEther May 9, 2024
5526c85
Make slight deepEqual performance improvement
TylerEther May 9, 2024
68a2aec
Add tests for deepEqual and isPrimitive
TylerEther May 9, 2024
cc92969
Export common in helpers
TylerEther May 9, 2024
3fdef33
Extract useResolvedFilter to useResolvedPromise
TylerEther May 9, 2024
5287f89
Add tests for useResolvedPromise
TylerEther May 9, 2024
adb11a6
Remove unused import
TylerEther May 9, 2024
7c429dd
Fix code smell
TylerEther May 9, 2024
3e05b97
Disable unused var linting
TylerEther May 9, 2024
99c4639
Improve performance of useResolvedPromise
TylerEther May 9, 2024
7447756
Fix staleness issue
TylerEther May 9, 2024
8501c3e
Fix bugs in useResolvedPromise
TylerEther May 9, 2024
53c335b
Disable buggy optimization
TylerEther May 9, 2024
548d973
Merge branch 'TrueFiEng:master' into use-raw-logs-improvements
TylerEther May 13, 2024
2363153
Merge branch 'master' into use-raw-logs-improvements
JustynaBroniszewska May 15, 2024
17d24e4
Merge branch 'master' into use-raw-logs-improvements
nezouse May 17, 2024
3371c32
Create hot-pots-tap.md
nezouse May 17, 2024
af09026
Merge branch 'master' into use-raw-logs-improvements
nezouse May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
269 changes: 269 additions & 0 deletions packages/core/src/helpers/common.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
import { expect } from 'chai'
import { deepEqual, isPrimitive } from './common'
import { Filter } from '@ethersproject/abstract-provider'

describe('common', function () {
describe('isPrimitive', function () {
it('Returns true for 0', function () {
expect(isPrimitive(0)).to.equal(true)
})

it('Returns true for 1', function () {
expect(isPrimitive(1)).to.equal(true)
})

it("Returns true for 'a'", function () {
expect(isPrimitive('a')).to.equal(true)
})

it("Returns true for ''", function () {
expect(isPrimitive('')).to.equal(true)
})

it('Returns true for undefined', function () {
expect(isPrimitive(undefined)).to.equal(true)
})

it('Returns true for null', function () {
expect(isPrimitive(null)).to.equal(true)
})

it('Returns true for true', function () {
expect(isPrimitive(true)).to.equal(true)
})

it('Returns true for false', function () {
expect(isPrimitive(false)).to.equal(true)
})

it('Returns false for []', function () {
expect(isPrimitive([])).to.equal(false)
})

it('Returns false for {}', function () {
expect(isPrimitive({})).to.equal(false)
})
})

describe('deepEqual', function () {
it('Returns true for 0 and 0', function () {
expect(deepEqual(0, 0)).to.equal(true)
})

it('Returns true for 1 and 1', function () {
expect(deepEqual(1, 1)).to.equal(true)
})

it("Returns true for 'a' and 'a'", function () {
expect(deepEqual('a', 'a')).to.equal(true)
})

it("Returns true for '' and ''", function () {
expect(deepEqual('', '')).to.equal(true)
})

it('Returns true for undefined and undefined', function () {
expect(deepEqual(undefined, undefined)).to.equal(true)
})

it('Returns true for null and null', function () {
expect(deepEqual(null, null)).to.equal(true)
})

it('Returns true for true and true', function () {
expect(deepEqual(true, true)).to.equal(true)
})

it('Returns true for false and false', function () {
expect(deepEqual(false, false)).to.equal(true)
})

it('Returns true for [] and []', function () {
expect(deepEqual([], [])).to.equal(true)
})

it('Returns true for undefined and null', function () {
expect(deepEqual(undefined, null)).to.equal(true)
})

it('Returns true for null and undefined', function () {
expect(deepEqual(null, undefined)).to.equal(true)
})

it('Returns true for two block filters with different property orderings', function () {
const filter1: Filter = {
fromBlock: 1,
toBlock: 2,
}

const filter2: Filter = {
toBlock: 2,
fromBlock: 1,
}

expect(deepEqual(filter1, filter2)).to.equal(true)
})

it('Returns false for two block filters with different property counts (one has less than two)', function () {
const filter1: Filter = {
fromBlock: 1,
}

const filter2: Filter = {
fromBlock: 1,
toBlock: 2,
}

expect(deepEqual(filter1, filter2)).to.equal(false)
})

it('Returns false for two block filters with different property counts (one has more than two)', function () {
const filter1: Filter = {
fromBlock: 1,
toBlock: 2,
}

const filter2: Filter = {
fromBlock: 1,
}

expect(deepEqual(filter1, filter2)).to.equal(false)
})

it('Returns false for two block filters with different addresses', function () {
const filter1: Filter = {
address: '0x0000000000000000000000000000000000000000',
}

const filter2: Filter = {
address: '0x0000000000000000000000000000000000000001',
}

expect(deepEqual(filter1, filter2)).to.equal(false)
})

it("Returns false for 0 and '0'", function () {
expect(deepEqual(0, '0')).to.equal(false)
})

it("Returns false for '0' and 0", function () {
expect(deepEqual('0', 0)).to.equal(false)
})

it('Returns false for false and 0', function () {
expect(deepEqual(false, 0)).to.equal(false)
})

it('Returns false for 0 and false', function () {
expect(deepEqual(0, false)).to.equal(false)
})

it('Returns false for 0 and null', function () {
expect(deepEqual(0, null)).to.equal(false)
})

it('Returns false for null and 0', function () {
expect(deepEqual(null, 0)).to.equal(false)
})

it('Returns false for 0 and undefined', function () {
expect(deepEqual(0, undefined)).to.equal(false)
})

it('Returns false for undefined and 0', function () {
expect(deepEqual(undefined, 0)).to.equal(false)
})

it("Returns false for '' and null", function () {
expect(deepEqual('', null)).to.equal(false)
})

it("Returns false for null and ''", function () {
expect(deepEqual(null, '')).to.equal(false)
})

it("Returns false for '' and undefined", function () {
expect(deepEqual('', undefined)).to.equal(false)
})

it("Returns false for undefined and ''", function () {
expect(deepEqual(undefined, '')).to.equal(false)
})

it('Returns false for {} and {}', function () {
expect(deepEqual({}, {})).to.equal(true)
})

it('Returns false for 0 and 1', function () {
expect(deepEqual(0, 1)).to.equal(false)
})

it('Returns false for 1 and 0', function () {
expect(deepEqual(1, 0)).to.equal(false)
})

it("Returns false for 'a' and 'b'", function () {
expect(deepEqual('a', 'b')).to.equal(false)
})

it("Returns false for 'b' and 'a'", function () {
expect(deepEqual('b', 'a')).to.equal(false)
})

it("Returns false for '' and 'a'", function () {
expect(deepEqual('', 'a')).to.equal(false)
})

it("Returns false for 'a' and ''", function () {
expect(deepEqual('a', '')).to.equal(false)
})

it('Retuens false for [0] and [0, 0]', function () {
expect(deepEqual([0], [0, 0])).to.equal(false)
})

it('Returns false for [0, 0] and [0]', function () {
expect(deepEqual([0, 0], [0])).to.equal(false)
})

it('Returns false for [0] and [1]', function () {
expect(deepEqual([0], [1])).to.equal(false)
})

it('Returns false for [1] and [0]', function () {
expect(deepEqual([1], [0])).to.equal(false)
})

it('Returns false for [0] and [null]', function () {
expect(deepEqual([0], [null])).to.equal(false)
})

it('Returns false for [null] and [0]', function () {
expect(deepEqual([null], [0])).to.equal(false)
})

it('Returns false for [0] and [undefined]', function () {
expect(deepEqual([0], [undefined])).to.equal(false)
})

it('Returns false for [undefined] and [0]', function () {
expect(deepEqual([undefined], [0])).to.equal(false)
})

it('Returns false for [0] and [{}]', function () {
expect(deepEqual([0], [{}])).to.equal(false)
})

it('Returns false for [{}] and [0]', function () {
expect(deepEqual([{}], [0])).to.equal(false)
})

it('Returns false for [0, 1] and [1, 0]', function () {
expect(deepEqual([0, 1], [1, 0])).to.equal(false)
})

it('Returns false for [1, 0] and [0, 1]', function () {
expect(deepEqual([1, 0], [0, 1])).to.equal(false)
})
})
})
44 changes: 44 additions & 0 deletions packages/core/src/helpers/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
export function shortenString(str: string) {
return str.substring(0, 6) + '...' + str.substring(str.length - 4)
}

/**
* Determines whether two objects are equal using a deep comparison. Null and undefined are considered equal. Arrays
* with the same elements are not considered equal if they are in different orders. Objects with the same properties
* can have different property orderings and still be considered equal.
* @param obj1 The first object to compare.
* @param obj2 The second object to compare.
* @returns True if the objects are deep equal, false otherwise.
*/
export function deepEqual(obj1: any, obj2: any) {
if (obj1 === obj2) return true

if (obj1 == null || obj2 == null) return obj1 == obj2

const obj1Primitive = isPrimitive(obj1)
const obj2Primitive = isPrimitive(obj2)
if (obj1Primitive || obj2Primitive)
// compare primitives
return obj1Primitive === obj2Primitive && obj1 === obj2

let obj1KeyCount = 0
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _ in obj1) obj1KeyCount++

let obj2KeyCount = 0
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _ in obj2) {
if (++obj2KeyCount > obj1KeyCount) return false
}

if (obj1KeyCount !== obj2KeyCount) return false

// compare objects with same number of keys
for (const key in obj1) {
if (!(key in obj2)) return false //other object doesn't have this prop
if (!deepEqual(obj1[key], obj2[key])) return false
}

return true
}

export function isPrimitive(obj: any) {
return obj !== Object(obj)
}
1 change: 1 addition & 0 deletions packages/core/src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './eip1193'
export * from './logs'
export * from './isWebSocketProvider'
export * from './event'
export * from './common'
1 change: 1 addition & 0 deletions packages/core/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ export * from './useRawLogs'
export * from './useRawCalls'
export * from './useResolveName'
export * from './useSigner'
export * from './useResolvedPromise'
Loading
Loading