@rpcbase/client 0.106.0 → 0.110.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/hashState.js +3 -2
- package/isEqualValues.js +47 -0
- package/package.json +1 -1
- package/rts/{getUseQuery.js → getUseQuery/index.js} +10 -30
- package/rts/getUseQuery/useData.js +55 -0
package/hashState.js
CHANGED
|
@@ -3,7 +3,8 @@ import {useState, useEffect, createContext, useContext, useCallback} from "react
|
|
|
3
3
|
import LZString from "lz-string"
|
|
4
4
|
import _isNil from "lodash/isNil"
|
|
5
5
|
import _omitBy from "lodash/omitBy"
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import isEqualValues from "./isEqualValues"
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
const PAGE_NAVIGATION_EVENT = "RB_PAGE_NAVIGATION"
|
|
@@ -87,7 +88,7 @@ export const HashStateProvider = ({children}) => {
|
|
|
87
88
|
...parsed,
|
|
88
89
|
}
|
|
89
90
|
// apply only if changed
|
|
90
|
-
if (!
|
|
91
|
+
if (!isEqualValues(hashState, newState)) {
|
|
91
92
|
setHashState(newState)
|
|
92
93
|
}
|
|
93
94
|
}
|
package/isEqualValues.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
const isEqual = require("fast-deep-equal/react")
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const isPlainObject = (obj) => {
|
|
6
|
+
return Object.prototype.toString.call(obj) === "[object Object]"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const sortValuesConsideringObjects = (values) => {
|
|
10
|
+
return values
|
|
11
|
+
.map(val => (isPlainObject(val) ? sortValuesConsideringObjects(Object.values(val)) : val))
|
|
12
|
+
.sort()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const isEqualValues = (a, b) => {
|
|
16
|
+
// Extract values and sort them if they belong to plain objects
|
|
17
|
+
const valsA = isPlainObject(a) ? sortValuesConsideringObjects(Object.values(a)) : a
|
|
18
|
+
const valsB = isPlainObject(b) ? sortValuesConsideringObjects(Object.values(b)) : b
|
|
19
|
+
|
|
20
|
+
if (valsA === null && valsB === null) {
|
|
21
|
+
return true
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (Array.isArray(valsA) || Array.isArray(valsB)) {
|
|
25
|
+
return isEqual(valsA, valsB)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check value count
|
|
29
|
+
if (valsA.length !== valsB.length) return false
|
|
30
|
+
|
|
31
|
+
// Compare the sorted arrays of values
|
|
32
|
+
for (let i = 0; i < valsA.length; i++) {
|
|
33
|
+
if (typeof valsA[i] === "object" && typeof valsB[i] === "object") {
|
|
34
|
+
if (!isEqualValues(valsA[i], valsB[i])) {
|
|
35
|
+
return false
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
if (!isEqual(valsA[i], valsB[i])) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
module.exports = isEqualValues
|
package/package.json
CHANGED
|
@@ -3,10 +3,13 @@ import assert from "assert"
|
|
|
3
3
|
import {Platform} from "react-native"
|
|
4
4
|
import {useCallback, useEffect, useState, useMemo, useId, useRef} from "react"
|
|
5
5
|
import debug from "debug"
|
|
6
|
-
import isEqual from "fast-deep-equal/react"
|
|
7
6
|
import _omit from "lodash/omit"
|
|
7
|
+
import LZString from "lz-string"
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import isEqualValues from "../../isEqualValues"
|
|
10
|
+
import get_uid from "../../auth/get_uid"
|
|
11
|
+
|
|
12
|
+
import useData from "./useData"
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
const log = debug("rb:rts:useQuery")
|
|
@@ -27,6 +30,7 @@ const getUseQuery = (register_query) => (
|
|
|
27
30
|
return _uid
|
|
28
31
|
}, [])
|
|
29
32
|
|
|
33
|
+
// used to track if data was loaded synchronously (no need to show any loader)
|
|
30
34
|
const hasInitiallySetFromStorage = useRef(false)
|
|
31
35
|
const hasFirstReply = useRef(false)
|
|
32
36
|
const hasNetworkReply = useRef(false)
|
|
@@ -46,31 +50,7 @@ const getUseQuery = (register_query) => (
|
|
|
46
50
|
|
|
47
51
|
const [source, setSource] = useState()
|
|
48
52
|
|
|
49
|
-
const [data, setData] =
|
|
50
|
-
if (!useStorage) {
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (Platform.OS === "web") {
|
|
55
|
-
const item = localStorage.getItem(storageKey)
|
|
56
|
-
if (!item) return
|
|
57
|
-
|
|
58
|
-
hasInitiallySetFromStorage.current = true
|
|
59
|
-
|
|
60
|
-
let parsedItem
|
|
61
|
-
try {
|
|
62
|
-
parsedItem = JSON.parse(item)
|
|
63
|
-
} catch (err) {
|
|
64
|
-
//
|
|
65
|
-
}
|
|
66
|
-
if (parsedItem) {
|
|
67
|
-
return parsedItem
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
// TODO: fast storage not implemented on mobile
|
|
71
|
-
console.log("fast storage mobile nOT IMPLEMENTED")
|
|
72
|
-
}
|
|
73
|
-
})
|
|
53
|
+
const [data, setData] = useData({useStorage, storageKey, hasInitiallySetFromStorage})
|
|
74
54
|
|
|
75
55
|
const [error, setError] = useState()
|
|
76
56
|
|
|
@@ -93,7 +73,7 @@ const getUseQuery = (register_query) => (
|
|
|
93
73
|
// we only save network queries
|
|
94
74
|
if (useStorage && context.source === "network") {
|
|
95
75
|
if (Platform.OS === "web") {
|
|
96
|
-
localStorage.setItem(storageKey, JSON.stringify(newData))
|
|
76
|
+
localStorage.setItem(storageKey, LZString.compressToUTF16(JSON.stringify(newData)))
|
|
97
77
|
} else {
|
|
98
78
|
// TODO: rn fast storage async
|
|
99
79
|
}
|
|
@@ -162,7 +142,7 @@ const getUseQuery = (register_query) => (
|
|
|
162
142
|
hasFirstReply.current = true
|
|
163
143
|
|
|
164
144
|
// skip if we already have the data
|
|
165
|
-
if (
|
|
145
|
+
if (isEqualValues(data, newData)) {
|
|
166
146
|
applyContext(context)
|
|
167
147
|
return
|
|
168
148
|
}
|
|
@@ -178,7 +158,7 @@ const getUseQuery = (register_query) => (
|
|
|
178
158
|
return
|
|
179
159
|
}
|
|
180
160
|
|
|
181
|
-
if (!
|
|
161
|
+
if (!isEqualValues(data, newData)) {
|
|
182
162
|
applyContext(context)
|
|
183
163
|
applyNewData(newData, context)
|
|
184
164
|
} else {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
import {useState} from "react"
|
|
3
|
+
import {Platform} from "react-native"
|
|
4
|
+
import LZString from "lz-string"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const useData = ({useStorage, storageKey, hasInitiallySetFromStorage}) => {
|
|
8
|
+
const [data, setData] = useState(() => {
|
|
9
|
+
if (!useStorage) {
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (Platform.OS === "web") {
|
|
14
|
+
const itemStr = localStorage.getItem(storageKey)
|
|
15
|
+
if (!itemStr) return
|
|
16
|
+
|
|
17
|
+
let decompressedItem
|
|
18
|
+
try {
|
|
19
|
+
decompressedItem = LZString.decompressFromUTF16(itemStr)
|
|
20
|
+
} catch (err) {
|
|
21
|
+
//
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!decompressedItem) {
|
|
25
|
+
localStorage.removeItem(storageKey)
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
let parsedItem
|
|
31
|
+
try {
|
|
32
|
+
parsedItem = JSON.parse(decompressedItem)
|
|
33
|
+
} catch (err) {
|
|
34
|
+
//
|
|
35
|
+
}
|
|
36
|
+
//
|
|
37
|
+
if (!parsedItem) {
|
|
38
|
+
localStorage.removeItem(storageKey)
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// success
|
|
43
|
+
hasInitiallySetFromStorage.current = true
|
|
44
|
+
return parsedItem
|
|
45
|
+
|
|
46
|
+
} else {
|
|
47
|
+
// TODO: fast storage not implemented on mobile
|
|
48
|
+
console.log("fast storage mobile nOT IMPLEMENTED")
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
return [data, setData]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default useData
|