@rpcbase/client 0.227.0 → 0.231.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/package.json +11 -113
- package/src/apiClient/getServerApiClient.ts +131 -0
- package/src/apiClient/index.ts +86 -0
- package/src/index.ts +3 -0
- package/src/initClient.ts +32 -0
- package/src/types.ts +7 -0
- package/AppProvider/AnalyticsContainer.js +0 -56
- package/AppProvider/debug.js +0 -4
- package/AppProvider/index.tsx +0 -79
- package/access-control/ACLForm/components/GrantField/OpSelector.tsx +0 -129
- package/access-control/ACLForm/components/GrantField/ResourceSelector.tsx +0 -86
- package/access-control/ACLForm/components/GrantField/UsersSelector.tsx +0 -96
- package/access-control/ACLForm/components/GrantField/grant-field.scss +0 -26
- package/access-control/ACLForm/components/GrantField/icons/CheckMark.tsx +0 -16
- package/access-control/ACLForm/components/GrantField/icons/CollapseArrow.tsx +0 -14
- package/access-control/ACLForm/components/GrantField/icons/ExpandArrow.tsx +0 -14
- package/access-control/ACLForm/components/GrantField/index.tsx +0 -91
- package/access-control/ACLForm/components/GrantsList.tsx +0 -48
- package/access-control/ACLForm/components/RoleForm.tsx +0 -134
- package/access-control/ACLForm/components/RoleView.tsx +0 -115
- package/access-control/ACLForm/components/RolesList.tsx +0 -79
- package/access-control/ACLForm/components/constants.tsx +0 -1
- package/access-control/ACLForm/components/resolver.ts +0 -57
- package/access-control/ACLForm/components/role-form.scss +0 -19
- package/access-control/ACLForm/index.tsx +0 -48
- package/access-control/ACLModal/acl-modal.scss +0 -7
- package/access-control/ACLModal/index.tsx +0 -66
- package/access-control/PolicyEditor/TargetSelector/QueryBuilder.tsx +0 -48
- package/access-control/PolicyEditor/TargetSelector/index.tsx +0 -5
- package/access-control/PolicyEditor/TargetSelector/query-builder.scss +0 -9
- package/access-control/PolicyEditor/index.tsx +0 -165
- package/access-control/index.ts +0 -3
- package/apiClient.js +0 -15
- package/auth/authProps.js +0 -8
- package/auth/components/AccountsList/AccountListItem.js +0 -61
- package/auth/components/AccountsList/account-list-item.scss +0 -5
- package/auth/components/AccountsList/index.js +0 -17
- package/auth/components/Footer/index.js +0 -11
- package/auth/components/ForgotPassword/forgot-password.scss +0 -37
- package/auth/components/ForgotPassword/index.js +0 -114
- package/auth/components/SetNewPassword/index.js +0 -130
- package/auth/components/SetNewPassword/set-new-password.scss +0 -47
- package/auth/components/SignIn/SignInEmailForm.tsx +0 -115
- package/auth/components/SignIn/index.js +0 -69
- package/auth/components/SignIn/sign-in.scss +0 -56
- package/auth/components/SignOut/index.js +0 -144
- package/auth/components/SignOut/sign-out.scss +0 -34
- package/auth/components/SignUp/SignUpEmailForm.tsx +0 -98
- package/auth/components/SignUp/index.js +0 -66
- package/auth/components/SignUp/sign-up.scss +0 -56
- package/auth/getTenantId.js +0 -12
- package/auth/getUid.js +0 -11
- package/auth/helpers/redirectSignIn.native.js +0 -9
- package/auth/helpers/redirectSignIn.web.js +0 -7
- package/auth/index.js +0 -146
- package/auth/signOut.js +0 -20
- package/auth/useAuthRouter.js +0 -56
- package/env.d.ts +0 -3
- package/firebase/index.js +0 -1
- package/firebase/sw.js +0 -1
- package/form/FileInput/FileUploadContext.tsx +0 -162
- package/form/FileInput/FileUploadForm/index.tsx +0 -139
- package/form/FileInput/FileUploadForm/usePreventUnload.js +0 -21
- package/form/FileInput/UploadButton.tsx +0 -23
- package/form/FileInput/constants.ts +0 -16
- package/form/FileInput/file-input.scss +0 -1
- package/form/FileInput/index.tsx +0 -21
- package/form/FileInput/upload-worker/get_file_hash.js +0 -63
- package/form/FileInput/upload-worker/index.js +0 -16
- package/form/FileInput/upload-worker/no_compress_exts.ts +0 -33
- package/form/FileInput/upload-worker/upload_file.js +0 -129
- package/form/Form.tsx +0 -23
- package/form/Input.tsx +0 -62
- package/form/SubmitButton/index.tsx +0 -58
- package/form/hook-form.tsx +0 -7
- package/form/index.tsx +0 -5
- package/getBaseUrl.js +0 -14
- package/getObjectId.ts +0 -31
- package/hashState.js +0 -158
- package/helpers/createBatcher/index.js +0 -36
- package/helpers/getInitials.js +0 -39
- package/helpers/onReady.js +0 -15
- package/helpers/post.js +0 -18
- package/helpers/postRPC.js +0 -42
- package/helpers/useRPC.js +0 -41
- package/helpers/useStoredValue/batchedGetStoredValues.js +0 -30
- package/helpers/useStoredValue/index.js +0 -107
- package/helpers/useStoredValue/setStoredValues.js +0 -14
- package/i18n/en/rb.nav.json +0 -13
- package/i18n/en/rb.sign_in.json +0 -11
- package/i18n/en/rb.sign_out.json +0 -5
- package/i18n/fr/rb.sign_in.json +0 -11
- package/i18n/fr/rb.sign_out.json +0 -5
- package/i18n/index.js +0 -63
- package/index.js +0 -6
- package/isEqualValues.js +0 -47
- package/jest.config.js +0 -16
- package/notifications/Notification/index.js +0 -36
- package/notifications/Notification/notification.scss +0 -1
- package/notifications/NotificationItem/HeaderStatus.js +0 -93
- package/notifications/NotificationItem/index.js +0 -65
- package/notifications/NotificationItem/notification-item.scss +0 -25
- package/notifications/NotificationsContainer/index.js +0 -37
- package/notifications/NotificationsContainer/notifications-container.scss +0 -38
- package/notifications/NotificationsContainer/useLLTs.js +0 -28
- package/notifications/NotificationsContext/index.js +0 -71
- package/notifications/NotificationsContext/useNotificationsList.js +0 -75
- package/notifications/NotificationsSettingsModal/SettingsForm.js +0 -52
- package/notifications/NotificationsSettingsModal/index.js +0 -48
- package/notifications/NotificationsSettingsModal/notifications-settings.scss +0 -1
- package/notifications/config.js +0 -1
- package/notifications/index.js +0 -4
- package/page.js +0 -9
- package/publish-output.txt +0 -0
- package/rpc.js +0 -32
- package/rr-trace/get_fingerprint.js +0 -10
- package/rr-trace/get_perf_vitals.js +0 -24
- package/rr-trace/get_session_id.js +0 -29
- package/rr-trace/index.js +0 -138
- package/rr-trace/write_session_data.js +0 -86
- package/rts/boot.js +0 -3
- package/rts/getUseDocument.js +0 -21
- package/rts/getUseQuery/index.js +0 -233
- package/rts/getUseQuery/useData.js +0 -55
- package/rts/index.js +0 -10
- package/rts/rts.js +0 -243
- package/rts/signout.ts +0 -8
- package/rts/store/constants.js +0 -3
- package/rts/store/debug.js +0 -24
- package/rts/store/get_collection.js +0 -55
- package/rts/store/index.js +0 -100
- package/rts/store/replace_query_keys.js +0 -30
- package/rts/store/satisfies_projection.js +0 -32
- package/rts/store/update_docs.js +0 -47
- package/storage/index.jest.js +0 -15
- package/storage/index.native.js +0 -38
- package/storage/index.web.js +0 -25
- package/types.ts +0 -6
- package/ui/ActivityIndicator/index.js +0 -113
- package/ui/Avatar/index.native.js +0 -31
- package/ui/Avatar/index.web.js +0 -37
- package/ui/Avatar/styles.js +0 -41
- package/ui/ErrorBoundary/index.js +0 -12
- package/ui/ExpandableFloatView/exp.scss +0 -15
- package/ui/ExpandableFloatView/index.tsx +0 -123
- package/ui/ExpandableFloatView/useBackdrop.js +0 -45
- package/ui/LottiePlayer/LottiePlayer.js +0 -4
- package/ui/LottiePlayer/index.js +0 -8
- package/ui/Modal/HashStateModal.js +0 -30
- package/ui/Modal/Modal.js +0 -93
- package/ui/Modal/ModalForm/AlertBanner.js +0 -82
- package/ui/Modal/ModalForm/index.js +0 -188
- package/ui/Modal/ModalForm/modal-form.scss +0 -63
- package/ui/Modal/index.js +0 -10
- package/ui/Modal/modal.scss +0 -101
- package/ui/Modal/withHashStateModal.js +0 -24
- package/ui/RedboxError/index.js +0 -3
- package/ui/Search/SearchHistory/index.js +0 -45
- package/ui/Search/SearchHistory/search-history.scss +0 -9
- package/ui/Search/SearchHistory/useSearchHistory.tsx +0 -57
- package/ui/Search/SearchResults/index.tsx +0 -90
- package/ui/Search/index.tsx +0 -298
- package/ui/Search/search.scss +0 -0
- package/ui/SelectPills/index.tsx +0 -96
- package/ui/SelectPills/select-pills.scss +0 -66
- package/ui/Tabs/index.tsx +0 -161
- package/ui/Tabs/tabs.scss +0 -53
- package/ui/Tree/index.js +0 -257
- package/ui/Tree/model.js +0 -71
- package/ui/Tree/node.js +0 -112
- package/ui/Tree/tree.scss +0 -98
- package/ui/UserAvatar/default_colors.json +0 -82
- package/ui/UserAvatar/index.js +0 -55
- package/ui/View/index.tsx +0 -17
- package/ui/View/index.web.js +0 -44
- package/ui/animations/checkmark.json +0 -1
- package/ui/helpers/SizeContext/index.tsx +0 -11
- package/ui/helpers/helpers.scss +0 -61
- package/ui/helpers/index.ts +0 -6
- package/ui/helpers/stopEventPropagation.js +0 -5
- package/ui/helpers/useActiveListItemIndex/index.tsx +0 -45
- package/ui/helpers/useScrollSelectorIntoView/index.tsx +0 -14
- package/ui/helpers/useThrottledMeasure/index.js +0 -47
- package/ui/helpers/withSuspense/index.js +0 -37
- package/ui/icons/AddAccount.tsx +0 -5
- package/ui/icons/Billing.tsx +0 -6
- package/ui/icons/Close.tsx +0 -14
- package/ui/icons/Organization.tsx +0 -5
- package/ui/icons/Signout.tsx +0 -5
- package/ui/icons/index.tsx +0 -6
- package/ui/nav/AccountsDropdown/SwitchAccounts.tsx +0 -28
- package/ui/nav/AccountsDropdown/accounts-dropdown.scss +0 -51
- package/ui/nav/AccountsDropdown/index.tsx +0 -90
- package/ui/nav/AccountsToggle/index.tsx +0 -24
- package/ui/nav/ContentView/ContentViewContext.ts +0 -23
- package/ui/nav/ContentView/index.tsx +0 -115
- package/ui/nav/HeaderContainer/header.scss +0 -52
- package/ui/nav/HeaderContainer/index.tsx +0 -23
- package/ui/nav/HeaderContainer/variables.scss +0 -1
- package/ui/nav/MorphingDropdown/MorphingDropdownContext.tsx +0 -151
- package/ui/nav/MorphingDropdown/MorphingDropdownMenu.tsx +0 -38
- package/ui/nav/MorphingDropdown/MorphingDropdownPortal.tsx +0 -166
- package/ui/nav/MorphingDropdown/MorphingDropdownToggle.tsx +0 -34
- package/ui/nav/MorphingDropdown/index.tsx +0 -16
- package/ui/nav/MorphingDropdown/morphing-dropdown.scss +0 -35
- package/ui/nav/NotificationsDropdown/index.tsx +0 -52
- package/ui/nav/NotificationsDropdown/notifications-dropdown.scss +0 -5
- package/ui/nav/NotificationsToggle/NotificationsGlyph.tsx +0 -54
- package/ui/nav/NotificationsToggle/index.tsx +0 -12
- package/ui/nav/NotificationsToggle/notification-animation.json +0 -1
- package/ui/nav/NotificationsToggle/notifications-toggle.scss +0 -26
- package/ui/nav/SidebarContainer/index.tsx +0 -48
- package/ui/nav/SidebarContainer/sidebar-container.scss +0 -21
- package/ui/nav/SlideoutContainer/components/Body.tsx +0 -19
- package/ui/nav/SlideoutContainer/components/Header.tsx +0 -23
- package/ui/nav/SlideoutContainer/components/Wrapper.tsx +0 -46
- package/ui/nav/SlideoutContainer/index.tsx +0 -50
- package/ui/nav/SlideoutContainer/slideout-container.scss +0 -40
- package/ui/nav/index.ts +0 -13
- package/ui/oauth/GitHub.js +0 -38
- package/ui/oauth/getGitHubSigninUrl.js +0 -30
- package/ui/oauth/index.js +0 -9
- package/ui/oauth/oauth.scss +0 -16
- package/ui/sortable-hoc/AutoScroller.js +0 -76
- package/ui/sortable-hoc/DragHandle.js +0 -31
- package/ui/sortable-hoc/Manager.js +0 -54
- package/ui/sortable-hoc/README.md +0 -1
- package/ui/sortable-hoc/SortableContainer/defaultGetHelperDimensions.js +0 -7
- package/ui/sortable-hoc/SortableContainer/defaultShouldCancelStart.js +0 -24
- package/ui/sortable-hoc/SortableContainer/index.js +0 -994
- package/ui/sortable-hoc/SortableContainer/props.js +0 -81
- package/ui/sortable-hoc/SortableElement.js +0 -111
- package/ui/sortable-hoc/SortableHandle.js +0 -45
- package/ui/sortable-hoc/drag-handle.scss +0 -14
- package/ui/sortable-hoc/index.js +0 -9
- package/ui/sortable-hoc/utils.js +0 -292
- package/ui/springs.ts +0 -17
package/rts/getUseQuery/index.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
import {Platform} from "react-native"
|
|
3
|
-
import {
|
|
4
|
-
useCallback,
|
|
5
|
-
useEffect,
|
|
6
|
-
useState,
|
|
7
|
-
useMemo,
|
|
8
|
-
useId,
|
|
9
|
-
useRef,
|
|
10
|
-
} from "react"
|
|
11
|
-
import debug from "debug"
|
|
12
|
-
import _omit from "lodash/omit"
|
|
13
|
-
import LZString from "lz-string"
|
|
14
|
-
|
|
15
|
-
// TODO: remove this when stable
|
|
16
|
-
import isEqual from "fast-deep-equal/react"
|
|
17
|
-
|
|
18
|
-
import isEqualValues from "../../isEqualValues"
|
|
19
|
-
import getUid from "../../auth/getUid"
|
|
20
|
-
|
|
21
|
-
import useData from "./useData"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const log = debug("rb:rts:useQuery")
|
|
25
|
-
|
|
26
|
-
export const getUseQuery =
|
|
27
|
-
(registerQuery) =>
|
|
28
|
-
(model_name, query = {}, options = {}) => {
|
|
29
|
-
const id = useId()
|
|
30
|
-
|
|
31
|
-
// TODO: should the uid be gone here ? it's part of the auth layer, not this here
|
|
32
|
-
// TODO: retrieve this from future AuthContext in client
|
|
33
|
-
const uid = useMemo(() => {
|
|
34
|
-
// TODO: why is there a options.userId here?? (it was for mobile we need to unify this)
|
|
35
|
-
const _uid = Platform.OS === "web" ? getUid() : options.userId
|
|
36
|
-
return _uid
|
|
37
|
-
}, [])
|
|
38
|
-
|
|
39
|
-
// used to track if data was loaded synchronously (no need to show any loader)
|
|
40
|
-
const hasInitiallySetFromStorage = useRef(false)
|
|
41
|
-
const hasFirstReply = useRef(false)
|
|
42
|
-
const hasNetworkReply = useRef(false)
|
|
43
|
-
const lastDocRef = useRef(null)
|
|
44
|
-
// const [page, setPage] = useState(0)
|
|
45
|
-
|
|
46
|
-
const {
|
|
47
|
-
key = "",
|
|
48
|
-
projection = {},
|
|
49
|
-
sort = {},
|
|
50
|
-
useStorage = false,
|
|
51
|
-
} = options
|
|
52
|
-
|
|
53
|
-
const storageKey = useMemo(() => {
|
|
54
|
-
return `${uid}${key ? `.${key}` : ""}.${model_name}.${JSON.stringify(query)}.${JSON.stringify(projection)}.${JSON.stringify(sort)}`
|
|
55
|
-
}, [uid, key, model_name, query, projection, sort])
|
|
56
|
-
|
|
57
|
-
const [source, setSource] = useState()
|
|
58
|
-
|
|
59
|
-
const dataRef = useRef(null)
|
|
60
|
-
const [data, setData] = useData({
|
|
61
|
-
useStorage,
|
|
62
|
-
storageKey,
|
|
63
|
-
hasInitiallySetFromStorage,
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
const [error, setError] = useState()
|
|
67
|
-
|
|
68
|
-
const [loading, setLoading] = useState(() => {
|
|
69
|
-
if (hasInitiallySetFromStorage.current) {
|
|
70
|
-
return false
|
|
71
|
-
}
|
|
72
|
-
return true
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
if (options.debug) {
|
|
77
|
-
console.log("use query", model_name, query, options)
|
|
78
|
-
}
|
|
79
|
-
}, [model_name, query, options])
|
|
80
|
-
|
|
81
|
-
const applyNewData = (newData, context) => {
|
|
82
|
-
setData(newData)
|
|
83
|
-
// set data in a ref so that it doesn't force re-rendering ie: unsubscribe / resubscribe
|
|
84
|
-
dataRef.current = newData
|
|
85
|
-
|
|
86
|
-
// useStorage currently used as a fast local cache, indexedDB
|
|
87
|
-
// we only save network queries
|
|
88
|
-
// TODO: use localstorage in react native and pouchdb everywhere
|
|
89
|
-
if (useStorage && context.source === "network") {
|
|
90
|
-
if (Platform.OS === "web") {
|
|
91
|
-
localStorage.setItem(
|
|
92
|
-
storageKey,
|
|
93
|
-
LZString.compressToUTF16(JSON.stringify(newData)),
|
|
94
|
-
)
|
|
95
|
-
} else {
|
|
96
|
-
// TODO: this is done in pouchDB nOW ?????
|
|
97
|
-
// TODO: RN MMKV
|
|
98
|
-
console.log("mmkv NYI")
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (newData?.length > 0) {
|
|
103
|
-
lastDocRef.current = newData[newData.length - 1]
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const applyContext = (newContext) => {
|
|
108
|
-
if (newContext.source !== source) {
|
|
109
|
-
setSource(newContext.source)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
useEffect(() => {
|
|
114
|
-
const queryKey = key || id
|
|
115
|
-
|
|
116
|
-
if (!model_name) {
|
|
117
|
-
console.warn(
|
|
118
|
-
"attempting to register query with empty collection, skipping",
|
|
119
|
-
)
|
|
120
|
-
return
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (options.debug) {
|
|
124
|
-
console.log("register query", model_name, query, options)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const start = Date.now()
|
|
128
|
-
|
|
129
|
-
log("will register query", model_name, query)
|
|
130
|
-
|
|
131
|
-
const unsubscribe = registerQuery(
|
|
132
|
-
model_name,
|
|
133
|
-
query,
|
|
134
|
-
{...options, key: queryKey, uid},
|
|
135
|
-
(err, queryResult, context) => {
|
|
136
|
-
log("callback answer with context", context, queryResult?.length)
|
|
137
|
-
|
|
138
|
-
// believe it or not, the network can be faster than indexeddb...
|
|
139
|
-
if (context.source === "cache" && hasNetworkReply.current) {
|
|
140
|
-
log("skipping cache arriving later than network")
|
|
141
|
-
return
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// mark if we received from network
|
|
145
|
-
if (context.source === "network" && !hasNetworkReply.current) {
|
|
146
|
-
hasNetworkReply.current = true
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (options.debug) {
|
|
150
|
-
console.log("query took", Date.now() - start, model_name, query)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
setLoading(false)
|
|
154
|
-
if (err) {
|
|
155
|
-
setError(err)
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
log("query callback", model_name, queryKey, JSON.stringify(query))
|
|
160
|
-
|
|
161
|
-
// return if no data (this should be handled already)
|
|
162
|
-
if (!queryResult) return
|
|
163
|
-
|
|
164
|
-
let newData
|
|
165
|
-
if (Array.isArray(queryResult)) {
|
|
166
|
-
newData = queryResult.map((o) => _omit(o, "__txn_id"))
|
|
167
|
-
} else {
|
|
168
|
-
newData = _omit(queryResult, "__txn_id")
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// we return once in any case
|
|
172
|
-
if (!hasFirstReply.current) {
|
|
173
|
-
hasFirstReply.current = true
|
|
174
|
-
|
|
175
|
-
// skip if we already have the data
|
|
176
|
-
if (isEqualValues(data, newData)) {
|
|
177
|
-
applyContext(context)
|
|
178
|
-
return
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
applyContext(context)
|
|
182
|
-
applyNewData(newData, context)
|
|
183
|
-
return
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// TODO: this should be handled by the consumer with the context (cache or network)
|
|
187
|
-
if (context.is_local && options.skipLocal && hasFirstReply.current) {
|
|
188
|
-
log("skipping local update", key)
|
|
189
|
-
return
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (
|
|
193
|
-
__DEV__ &&
|
|
194
|
-
isEqual(data, newData) &&
|
|
195
|
-
!isEqualValues(data, newData)
|
|
196
|
-
) {
|
|
197
|
-
alert("EQUALITY MISMATCH THIS SHOULD NOT HAPPEN!", data, newData)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (!isEqualValues(dataRef.current, newData)) {
|
|
201
|
-
applyContext(context)
|
|
202
|
-
applyNewData(newData, context)
|
|
203
|
-
} else {
|
|
204
|
-
applyContext(context)
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
return () => {
|
|
210
|
-
log && log("useQuery cleanup unsubscribe()")
|
|
211
|
-
typeof unsubscribe === "function" && unsubscribe()
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// WARNING: do not change the hooks dependencies param or you risk creating infinite loops as it unsubscribes on cleanup
|
|
215
|
-
// TODO: this isnt right we need to update on options change too
|
|
216
|
-
}, [JSON.stringify(query), key])
|
|
217
|
-
|
|
218
|
-
const loadNextPage = useCallback(() => {
|
|
219
|
-
console.log("loadNextPage NYI")
|
|
220
|
-
}, [])
|
|
221
|
-
|
|
222
|
-
const result = useMemo(
|
|
223
|
-
() => ({data, source, error, loading, loadNextPage}),
|
|
224
|
-
[data, source, error, loading, loadNextPage],
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
// TODO:
|
|
228
|
-
// if (Array.isArray(result.data) && !result.source) {
|
|
229
|
-
// console.warn("RESULT HAS NO SOURCE", {data, error, loading, source})
|
|
230
|
-
// }
|
|
231
|
-
|
|
232
|
-
return result
|
|
233
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
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
|
package/rts/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import {registerQuery, sendMessage, onMessage} from "./rts"
|
|
2
|
-
import {getUseDocument} from "./getUseDocument"
|
|
3
|
-
import {getUseQuery} from "./getUseQuery"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export const useQuery = getUseQuery(registerQuery)
|
|
7
|
-
|
|
8
|
-
export const useDocument = getUseDocument(registerQuery)
|
|
9
|
-
|
|
10
|
-
export {registerQuery, sendMessage, onMessage}
|
package/rts/rts.js
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
import assert from "assert"
|
|
3
|
-
import {Platform} from "react-native"
|
|
4
|
-
import {io} from "socket.io-client"
|
|
5
|
-
import _get from "lodash/get"
|
|
6
|
-
import _set from "lodash/set"
|
|
7
|
-
import debug from "debug"
|
|
8
|
-
|
|
9
|
-
import getBaseUrl from "../getBaseUrl"
|
|
10
|
-
|
|
11
|
-
import store from "./store"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const log = debug("rb:socket")
|
|
15
|
-
|
|
16
|
-
const TENANT_ID_HEADER = "rb-tenant-id"
|
|
17
|
-
|
|
18
|
-
// how many local transaction ids are we keeping, ?it doesn't really need to be that big
|
|
19
|
-
const MAX_TXN_BUF = 2048
|
|
20
|
-
|
|
21
|
-
let _socket
|
|
22
|
-
const _callbacks = {}
|
|
23
|
-
const _queries_store = {}
|
|
24
|
-
const _local_txn = []
|
|
25
|
-
|
|
26
|
-
// TODO: when server disconnects / crashes and loses all server side stored queries
|
|
27
|
-
// the clients must reconnect and re-register those queries, or the page will need to be hard refreshed
|
|
28
|
-
|
|
29
|
-
// add_local_txn
|
|
30
|
-
// when a request is made to the server, we generate (or send if provided) the txn_id
|
|
31
|
-
// if the array becomes longer than the default buffer length we shift the array
|
|
32
|
-
export const add_local_txn = (txn_id) => {
|
|
33
|
-
assert(txn_id, "add_local_txn trying to add an invalid txn_id")
|
|
34
|
-
_local_txn.push(txn_id)
|
|
35
|
-
if (_local_txn.length > MAX_TXN_BUF) {
|
|
36
|
-
_local_txn.shift()
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// TODO: add compression / decompression
|
|
42
|
-
const dispatchQueryPayload = (payload, uid) => {
|
|
43
|
-
log("dispatchQueryPayload", payload)
|
|
44
|
-
|
|
45
|
-
const {model_name, query_key} = payload
|
|
46
|
-
// const cb = _get(_callbacks, `${model_name}.${query_key}`)
|
|
47
|
-
const callbacks = _callbacks[`${model_name}.${query_key}`]
|
|
48
|
-
|
|
49
|
-
if (!callbacks || !Array.isArray(callbacks)) {
|
|
50
|
-
log("dispatchQueryPayload", "unable to find callback for query payload", payload)
|
|
51
|
-
console.error("dispatchQueryPayload", "unable to find callback for query payload", payload)
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (payload.error) {
|
|
56
|
-
console.warn("rts-client, payload error:", payload.error)
|
|
57
|
-
console.warn("rts-client", "in:", model_name, "query_key:", query_key)
|
|
58
|
-
callbacks.forEach((cb) => cb(payload.error, undefined, {source: "network"}))
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let data
|
|
63
|
-
try {
|
|
64
|
-
// TODO: zstd decompression here
|
|
65
|
-
data = JSON.parse(payload.data_buf)
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.log("Error", err)
|
|
68
|
-
log("dispatchQueryPayload", "unable to parse or send data from payload:", payload.data_buf)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!data) {
|
|
72
|
-
// skipping if data parsing failed
|
|
73
|
-
return
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const context = {
|
|
77
|
-
source: "network",
|
|
78
|
-
is_local: _local_txn.includes(payload.txn_id),
|
|
79
|
-
txn_id: payload.txn_id,
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
callbacks.forEach((cb) => cb(null, data, context))
|
|
83
|
-
|
|
84
|
-
// TODO: pouchdb on react native
|
|
85
|
-
if (Platform.OS === "web") {
|
|
86
|
-
store.update_docs(model_name, data, uid)
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
export const connect = (tenant_id, user_id) => new Promise((resolve) => {
|
|
92
|
-
if (!tenant_id) {
|
|
93
|
-
log("missing tenant_id, skipping")
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
assert(user_id, "missing user_id")
|
|
97
|
-
|
|
98
|
-
log("rts client will connect")
|
|
99
|
-
|
|
100
|
-
_socket = io(getBaseUrl(), {
|
|
101
|
-
forceNew: true,
|
|
102
|
-
transports: ["websocket", "polling"],
|
|
103
|
-
withCredentials: true,
|
|
104
|
-
query: {
|
|
105
|
-
[TENANT_ID_HEADER]: tenant_id,
|
|
106
|
-
},
|
|
107
|
-
// https://socket.io/docs/v4/client-options/#reconnection
|
|
108
|
-
reconnection: true,
|
|
109
|
-
reconnectionAttempts: 128,
|
|
110
|
-
reconnectionDelay: 400, // ms
|
|
111
|
-
reconnectionDelayMax: 10 * 1000, // 10s
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
_socket.on("connect", () => {
|
|
115
|
-
log("socket connected")
|
|
116
|
-
resolve()
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
_socket.io.on("reconnect", (e) => {
|
|
120
|
-
log("socked reconnected", e)
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
_socket.on("error", (err) => {
|
|
124
|
-
log("socket error", err)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
_socket.on("query_payload", (payload) => {
|
|
128
|
-
// console.log("socket:query_payload", payload)
|
|
129
|
-
dispatchQueryPayload(payload, user_id)
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
_socket.on("delete_doc", (payload) => {
|
|
133
|
-
log("document deleted", payload)
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
_socket.on("disconnect", (arg) => {
|
|
137
|
-
log("socket disconnected", arg)
|
|
138
|
-
})
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
export const disconnect = () => {
|
|
143
|
-
if (_socket) {
|
|
144
|
-
try {
|
|
145
|
-
_socket.disconnect()
|
|
146
|
-
} catch (e) {
|
|
147
|
-
// TODO: should we be swallowing this error
|
|
148
|
-
}
|
|
149
|
-
_socket = null
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
export const reconnect = (tenant_id, user_id) => {
|
|
155
|
-
log("socket will force reconnect")
|
|
156
|
-
|
|
157
|
-
// destroy current socket if exists
|
|
158
|
-
disconnect()
|
|
159
|
-
|
|
160
|
-
connect(tenant_id, user_id)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// register a query
|
|
164
|
-
export const registerQuery = (model_name, query, _options, _callback) => {
|
|
165
|
-
// left shift args if _options is undefined
|
|
166
|
-
let options
|
|
167
|
-
let callback
|
|
168
|
-
if (_callback) {
|
|
169
|
-
assert(typeof _callback === "function")
|
|
170
|
-
options = _options
|
|
171
|
-
callback = _callback
|
|
172
|
-
} else {
|
|
173
|
-
options = {}
|
|
174
|
-
callback = _options
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
log("registerQuery", {model_name, query, options, callback})
|
|
178
|
-
|
|
179
|
-
if (!_socket) {
|
|
180
|
-
log("registerQuery: trying to use null socket", {model_name, query})
|
|
181
|
-
return
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const key = options.key || ""
|
|
185
|
-
const query_key = `${key}${JSON.stringify(query)}${options.projection ? JSON.stringify(options.projection) : ""}`
|
|
186
|
-
log("registering query with key", key, model_name, query, query_key)
|
|
187
|
-
|
|
188
|
-
// save callback to update hooks
|
|
189
|
-
const cb_key = `${model_name}.${query_key}`
|
|
190
|
-
if (!_callbacks[cb_key] || !Array.isArray(_callbacks[cb_key])) {
|
|
191
|
-
_callbacks[cb_key] = []
|
|
192
|
-
}
|
|
193
|
-
_callbacks[cb_key].push(callback)
|
|
194
|
-
|
|
195
|
-
// save query for reconnections and retries
|
|
196
|
-
if (!_queries_store[model_name]) {
|
|
197
|
-
_queries_store[model_name] = {}
|
|
198
|
-
}
|
|
199
|
-
_queries_store[model_name][query]
|
|
200
|
-
|
|
201
|
-
// TODO: why both run and register query here ? the run_query should come straight from register ?
|
|
202
|
-
_socket.emit("run_query", {model_name, query, query_key, options})
|
|
203
|
-
_socket.emit("registerQuery", {model_name, query, query_key, options})
|
|
204
|
-
|
|
205
|
-
if (Platform.OS === "web") {
|
|
206
|
-
// run the query from the cache a first time
|
|
207
|
-
store.run_query({model_name, query, options}, callback)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return () => {
|
|
211
|
-
_socket.emit("remove_query", {model_name, query, query_key, options})
|
|
212
|
-
// remove callback
|
|
213
|
-
const cb_index = _callbacks[cb_key].indexOf(callback)
|
|
214
|
-
if (cb_index > -1) {
|
|
215
|
-
_callbacks[cb_key].splice(cb_index, 1)
|
|
216
|
-
} else {
|
|
217
|
-
console.warn("warning, trying to remove a callback that doesn't exist")
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
export const sendMessage = (message, payload) => {
|
|
224
|
-
if (!_socket) {
|
|
225
|
-
console.error("attempting to send message without socket", {message, payload})
|
|
226
|
-
return
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
_socket.emit(message, payload)
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
export const onMessage = (message, callback) => {
|
|
234
|
-
if (!_socket) {
|
|
235
|
-
throw new Error("registering socket message listener without socket")
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
_socket.on(message, callback)
|
|
239
|
-
|
|
240
|
-
return () => {
|
|
241
|
-
_socket.off(message, callback)
|
|
242
|
-
}
|
|
243
|
-
}
|
package/rts/signout.ts
DELETED
package/rts/store/constants.js
DELETED
package/rts/store/debug.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
import debug from "debug"
|
|
3
|
-
import PouchDB from "pouchdb-core"
|
|
4
|
-
|
|
5
|
-
if (debug.enabled("rb:rts:store")) {
|
|
6
|
-
|
|
7
|
-
const log = debug("rb:store:pouch")
|
|
8
|
-
|
|
9
|
-
log("store debug is enabled")
|
|
10
|
-
|
|
11
|
-
const shouldLogAllPouch = debug.enabled("pouch")
|
|
12
|
-
|
|
13
|
-
PouchDB.on("debug", (args) => {
|
|
14
|
-
if (shouldLogAllPouch) {
|
|
15
|
-
log(...args)
|
|
16
|
-
}
|
|
17
|
-
// log find only when not loggin all pouch
|
|
18
|
-
else {
|
|
19
|
-
if (args[0] === "find") {
|
|
20
|
-
log(...args)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
import debug from "debug"
|
|
3
|
-
import PouchDB from "pouchdb-core"
|
|
4
|
-
import IndexedDBAdapter from "pouchdb-adapter-indexeddb"
|
|
5
|
-
import FindPlugin from "pouchdb-find"
|
|
6
|
-
|
|
7
|
-
import {RB_TENANT_ID, RB_APP_NAME} from "env"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const log = debug("rb:rts:store")
|
|
11
|
-
|
|
12
|
-
let prefix = `rb/`
|
|
13
|
-
|
|
14
|
-
if (RB_APP_NAME) prefix += `${RB_APP_NAME}/`
|
|
15
|
-
|
|
16
|
-
prefix += `${RB_TENANT_ID}/`
|
|
17
|
-
|
|
18
|
-
log("prefix:", prefix)
|
|
19
|
-
|
|
20
|
-
PouchDB.prefix = prefix
|
|
21
|
-
|
|
22
|
-
PouchDB.plugin(IndexedDBAdapter)
|
|
23
|
-
PouchDB.plugin(FindPlugin)
|
|
24
|
-
|
|
25
|
-
let _cols_store = Object.create(null)
|
|
26
|
-
|
|
27
|
-
export const get_collection = (col_name, options) => {
|
|
28
|
-
|
|
29
|
-
if (!col_name) {
|
|
30
|
-
console.warn("supplied invalid / empty collection name to rts")
|
|
31
|
-
}
|
|
32
|
-
if (!options.uid) {
|
|
33
|
-
console.warn("rts: get_collection: missing options.uid")
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const col_key = `${options.uid}/${col_name}`
|
|
37
|
-
|
|
38
|
-
if (_cols_store[col_key]) {
|
|
39
|
-
return _cols_store[col_key]
|
|
40
|
-
} else {
|
|
41
|
-
// https://pouchdb.com/api.html#create_database
|
|
42
|
-
const col = new PouchDB(col_key, {adapter: "indexeddb", revs_limit: 1})
|
|
43
|
-
_cols_store[col_key] = col
|
|
44
|
-
|
|
45
|
-
return col
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
export const destroy_all = async() => {
|
|
52
|
-
await Promise.map(Object.values(_cols_store), (db) => db.destroy())
|
|
53
|
-
|
|
54
|
-
_cols_store = Object.create(null)
|
|
55
|
-
}
|