@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.
Files changed (237) hide show
  1. package/package.json +11 -113
  2. package/src/apiClient/getServerApiClient.ts +131 -0
  3. package/src/apiClient/index.ts +86 -0
  4. package/src/index.ts +3 -0
  5. package/src/initClient.ts +32 -0
  6. package/src/types.ts +7 -0
  7. package/AppProvider/AnalyticsContainer.js +0 -56
  8. package/AppProvider/debug.js +0 -4
  9. package/AppProvider/index.tsx +0 -79
  10. package/access-control/ACLForm/components/GrantField/OpSelector.tsx +0 -129
  11. package/access-control/ACLForm/components/GrantField/ResourceSelector.tsx +0 -86
  12. package/access-control/ACLForm/components/GrantField/UsersSelector.tsx +0 -96
  13. package/access-control/ACLForm/components/GrantField/grant-field.scss +0 -26
  14. package/access-control/ACLForm/components/GrantField/icons/CheckMark.tsx +0 -16
  15. package/access-control/ACLForm/components/GrantField/icons/CollapseArrow.tsx +0 -14
  16. package/access-control/ACLForm/components/GrantField/icons/ExpandArrow.tsx +0 -14
  17. package/access-control/ACLForm/components/GrantField/index.tsx +0 -91
  18. package/access-control/ACLForm/components/GrantsList.tsx +0 -48
  19. package/access-control/ACLForm/components/RoleForm.tsx +0 -134
  20. package/access-control/ACLForm/components/RoleView.tsx +0 -115
  21. package/access-control/ACLForm/components/RolesList.tsx +0 -79
  22. package/access-control/ACLForm/components/constants.tsx +0 -1
  23. package/access-control/ACLForm/components/resolver.ts +0 -57
  24. package/access-control/ACLForm/components/role-form.scss +0 -19
  25. package/access-control/ACLForm/index.tsx +0 -48
  26. package/access-control/ACLModal/acl-modal.scss +0 -7
  27. package/access-control/ACLModal/index.tsx +0 -66
  28. package/access-control/PolicyEditor/TargetSelector/QueryBuilder.tsx +0 -48
  29. package/access-control/PolicyEditor/TargetSelector/index.tsx +0 -5
  30. package/access-control/PolicyEditor/TargetSelector/query-builder.scss +0 -9
  31. package/access-control/PolicyEditor/index.tsx +0 -165
  32. package/access-control/index.ts +0 -3
  33. package/apiClient.js +0 -15
  34. package/auth/authProps.js +0 -8
  35. package/auth/components/AccountsList/AccountListItem.js +0 -61
  36. package/auth/components/AccountsList/account-list-item.scss +0 -5
  37. package/auth/components/AccountsList/index.js +0 -17
  38. package/auth/components/Footer/index.js +0 -11
  39. package/auth/components/ForgotPassword/forgot-password.scss +0 -37
  40. package/auth/components/ForgotPassword/index.js +0 -114
  41. package/auth/components/SetNewPassword/index.js +0 -130
  42. package/auth/components/SetNewPassword/set-new-password.scss +0 -47
  43. package/auth/components/SignIn/SignInEmailForm.tsx +0 -115
  44. package/auth/components/SignIn/index.js +0 -69
  45. package/auth/components/SignIn/sign-in.scss +0 -56
  46. package/auth/components/SignOut/index.js +0 -144
  47. package/auth/components/SignOut/sign-out.scss +0 -34
  48. package/auth/components/SignUp/SignUpEmailForm.tsx +0 -98
  49. package/auth/components/SignUp/index.js +0 -66
  50. package/auth/components/SignUp/sign-up.scss +0 -56
  51. package/auth/getTenantId.js +0 -12
  52. package/auth/getUid.js +0 -11
  53. package/auth/helpers/redirectSignIn.native.js +0 -9
  54. package/auth/helpers/redirectSignIn.web.js +0 -7
  55. package/auth/index.js +0 -146
  56. package/auth/signOut.js +0 -20
  57. package/auth/useAuthRouter.js +0 -56
  58. package/env.d.ts +0 -3
  59. package/firebase/index.js +0 -1
  60. package/firebase/sw.js +0 -1
  61. package/form/FileInput/FileUploadContext.tsx +0 -162
  62. package/form/FileInput/FileUploadForm/index.tsx +0 -139
  63. package/form/FileInput/FileUploadForm/usePreventUnload.js +0 -21
  64. package/form/FileInput/UploadButton.tsx +0 -23
  65. package/form/FileInput/constants.ts +0 -16
  66. package/form/FileInput/file-input.scss +0 -1
  67. package/form/FileInput/index.tsx +0 -21
  68. package/form/FileInput/upload-worker/get_file_hash.js +0 -63
  69. package/form/FileInput/upload-worker/index.js +0 -16
  70. package/form/FileInput/upload-worker/no_compress_exts.ts +0 -33
  71. package/form/FileInput/upload-worker/upload_file.js +0 -129
  72. package/form/Form.tsx +0 -23
  73. package/form/Input.tsx +0 -62
  74. package/form/SubmitButton/index.tsx +0 -58
  75. package/form/hook-form.tsx +0 -7
  76. package/form/index.tsx +0 -5
  77. package/getBaseUrl.js +0 -14
  78. package/getObjectId.ts +0 -31
  79. package/hashState.js +0 -158
  80. package/helpers/createBatcher/index.js +0 -36
  81. package/helpers/getInitials.js +0 -39
  82. package/helpers/onReady.js +0 -15
  83. package/helpers/post.js +0 -18
  84. package/helpers/postRPC.js +0 -42
  85. package/helpers/useRPC.js +0 -41
  86. package/helpers/useStoredValue/batchedGetStoredValues.js +0 -30
  87. package/helpers/useStoredValue/index.js +0 -107
  88. package/helpers/useStoredValue/setStoredValues.js +0 -14
  89. package/i18n/en/rb.nav.json +0 -13
  90. package/i18n/en/rb.sign_in.json +0 -11
  91. package/i18n/en/rb.sign_out.json +0 -5
  92. package/i18n/fr/rb.sign_in.json +0 -11
  93. package/i18n/fr/rb.sign_out.json +0 -5
  94. package/i18n/index.js +0 -63
  95. package/index.js +0 -6
  96. package/isEqualValues.js +0 -47
  97. package/jest.config.js +0 -16
  98. package/notifications/Notification/index.js +0 -36
  99. package/notifications/Notification/notification.scss +0 -1
  100. package/notifications/NotificationItem/HeaderStatus.js +0 -93
  101. package/notifications/NotificationItem/index.js +0 -65
  102. package/notifications/NotificationItem/notification-item.scss +0 -25
  103. package/notifications/NotificationsContainer/index.js +0 -37
  104. package/notifications/NotificationsContainer/notifications-container.scss +0 -38
  105. package/notifications/NotificationsContainer/useLLTs.js +0 -28
  106. package/notifications/NotificationsContext/index.js +0 -71
  107. package/notifications/NotificationsContext/useNotificationsList.js +0 -75
  108. package/notifications/NotificationsSettingsModal/SettingsForm.js +0 -52
  109. package/notifications/NotificationsSettingsModal/index.js +0 -48
  110. package/notifications/NotificationsSettingsModal/notifications-settings.scss +0 -1
  111. package/notifications/config.js +0 -1
  112. package/notifications/index.js +0 -4
  113. package/page.js +0 -9
  114. package/publish-output.txt +0 -0
  115. package/rpc.js +0 -32
  116. package/rr-trace/get_fingerprint.js +0 -10
  117. package/rr-trace/get_perf_vitals.js +0 -24
  118. package/rr-trace/get_session_id.js +0 -29
  119. package/rr-trace/index.js +0 -138
  120. package/rr-trace/write_session_data.js +0 -86
  121. package/rts/boot.js +0 -3
  122. package/rts/getUseDocument.js +0 -21
  123. package/rts/getUseQuery/index.js +0 -233
  124. package/rts/getUseQuery/useData.js +0 -55
  125. package/rts/index.js +0 -10
  126. package/rts/rts.js +0 -243
  127. package/rts/signout.ts +0 -8
  128. package/rts/store/constants.js +0 -3
  129. package/rts/store/debug.js +0 -24
  130. package/rts/store/get_collection.js +0 -55
  131. package/rts/store/index.js +0 -100
  132. package/rts/store/replace_query_keys.js +0 -30
  133. package/rts/store/satisfies_projection.js +0 -32
  134. package/rts/store/update_docs.js +0 -47
  135. package/storage/index.jest.js +0 -15
  136. package/storage/index.native.js +0 -38
  137. package/storage/index.web.js +0 -25
  138. package/types.ts +0 -6
  139. package/ui/ActivityIndicator/index.js +0 -113
  140. package/ui/Avatar/index.native.js +0 -31
  141. package/ui/Avatar/index.web.js +0 -37
  142. package/ui/Avatar/styles.js +0 -41
  143. package/ui/ErrorBoundary/index.js +0 -12
  144. package/ui/ExpandableFloatView/exp.scss +0 -15
  145. package/ui/ExpandableFloatView/index.tsx +0 -123
  146. package/ui/ExpandableFloatView/useBackdrop.js +0 -45
  147. package/ui/LottiePlayer/LottiePlayer.js +0 -4
  148. package/ui/LottiePlayer/index.js +0 -8
  149. package/ui/Modal/HashStateModal.js +0 -30
  150. package/ui/Modal/Modal.js +0 -93
  151. package/ui/Modal/ModalForm/AlertBanner.js +0 -82
  152. package/ui/Modal/ModalForm/index.js +0 -188
  153. package/ui/Modal/ModalForm/modal-form.scss +0 -63
  154. package/ui/Modal/index.js +0 -10
  155. package/ui/Modal/modal.scss +0 -101
  156. package/ui/Modal/withHashStateModal.js +0 -24
  157. package/ui/RedboxError/index.js +0 -3
  158. package/ui/Search/SearchHistory/index.js +0 -45
  159. package/ui/Search/SearchHistory/search-history.scss +0 -9
  160. package/ui/Search/SearchHistory/useSearchHistory.tsx +0 -57
  161. package/ui/Search/SearchResults/index.tsx +0 -90
  162. package/ui/Search/index.tsx +0 -298
  163. package/ui/Search/search.scss +0 -0
  164. package/ui/SelectPills/index.tsx +0 -96
  165. package/ui/SelectPills/select-pills.scss +0 -66
  166. package/ui/Tabs/index.tsx +0 -161
  167. package/ui/Tabs/tabs.scss +0 -53
  168. package/ui/Tree/index.js +0 -257
  169. package/ui/Tree/model.js +0 -71
  170. package/ui/Tree/node.js +0 -112
  171. package/ui/Tree/tree.scss +0 -98
  172. package/ui/UserAvatar/default_colors.json +0 -82
  173. package/ui/UserAvatar/index.js +0 -55
  174. package/ui/View/index.tsx +0 -17
  175. package/ui/View/index.web.js +0 -44
  176. package/ui/animations/checkmark.json +0 -1
  177. package/ui/helpers/SizeContext/index.tsx +0 -11
  178. package/ui/helpers/helpers.scss +0 -61
  179. package/ui/helpers/index.ts +0 -6
  180. package/ui/helpers/stopEventPropagation.js +0 -5
  181. package/ui/helpers/useActiveListItemIndex/index.tsx +0 -45
  182. package/ui/helpers/useScrollSelectorIntoView/index.tsx +0 -14
  183. package/ui/helpers/useThrottledMeasure/index.js +0 -47
  184. package/ui/helpers/withSuspense/index.js +0 -37
  185. package/ui/icons/AddAccount.tsx +0 -5
  186. package/ui/icons/Billing.tsx +0 -6
  187. package/ui/icons/Close.tsx +0 -14
  188. package/ui/icons/Organization.tsx +0 -5
  189. package/ui/icons/Signout.tsx +0 -5
  190. package/ui/icons/index.tsx +0 -6
  191. package/ui/nav/AccountsDropdown/SwitchAccounts.tsx +0 -28
  192. package/ui/nav/AccountsDropdown/accounts-dropdown.scss +0 -51
  193. package/ui/nav/AccountsDropdown/index.tsx +0 -90
  194. package/ui/nav/AccountsToggle/index.tsx +0 -24
  195. package/ui/nav/ContentView/ContentViewContext.ts +0 -23
  196. package/ui/nav/ContentView/index.tsx +0 -115
  197. package/ui/nav/HeaderContainer/header.scss +0 -52
  198. package/ui/nav/HeaderContainer/index.tsx +0 -23
  199. package/ui/nav/HeaderContainer/variables.scss +0 -1
  200. package/ui/nav/MorphingDropdown/MorphingDropdownContext.tsx +0 -151
  201. package/ui/nav/MorphingDropdown/MorphingDropdownMenu.tsx +0 -38
  202. package/ui/nav/MorphingDropdown/MorphingDropdownPortal.tsx +0 -166
  203. package/ui/nav/MorphingDropdown/MorphingDropdownToggle.tsx +0 -34
  204. package/ui/nav/MorphingDropdown/index.tsx +0 -16
  205. package/ui/nav/MorphingDropdown/morphing-dropdown.scss +0 -35
  206. package/ui/nav/NotificationsDropdown/index.tsx +0 -52
  207. package/ui/nav/NotificationsDropdown/notifications-dropdown.scss +0 -5
  208. package/ui/nav/NotificationsToggle/NotificationsGlyph.tsx +0 -54
  209. package/ui/nav/NotificationsToggle/index.tsx +0 -12
  210. package/ui/nav/NotificationsToggle/notification-animation.json +0 -1
  211. package/ui/nav/NotificationsToggle/notifications-toggle.scss +0 -26
  212. package/ui/nav/SidebarContainer/index.tsx +0 -48
  213. package/ui/nav/SidebarContainer/sidebar-container.scss +0 -21
  214. package/ui/nav/SlideoutContainer/components/Body.tsx +0 -19
  215. package/ui/nav/SlideoutContainer/components/Header.tsx +0 -23
  216. package/ui/nav/SlideoutContainer/components/Wrapper.tsx +0 -46
  217. package/ui/nav/SlideoutContainer/index.tsx +0 -50
  218. package/ui/nav/SlideoutContainer/slideout-container.scss +0 -40
  219. package/ui/nav/index.ts +0 -13
  220. package/ui/oauth/GitHub.js +0 -38
  221. package/ui/oauth/getGitHubSigninUrl.js +0 -30
  222. package/ui/oauth/index.js +0 -9
  223. package/ui/oauth/oauth.scss +0 -16
  224. package/ui/sortable-hoc/AutoScroller.js +0 -76
  225. package/ui/sortable-hoc/DragHandle.js +0 -31
  226. package/ui/sortable-hoc/Manager.js +0 -54
  227. package/ui/sortable-hoc/README.md +0 -1
  228. package/ui/sortable-hoc/SortableContainer/defaultGetHelperDimensions.js +0 -7
  229. package/ui/sortable-hoc/SortableContainer/defaultShouldCancelStart.js +0 -24
  230. package/ui/sortable-hoc/SortableContainer/index.js +0 -994
  231. package/ui/sortable-hoc/SortableContainer/props.js +0 -81
  232. package/ui/sortable-hoc/SortableElement.js +0 -111
  233. package/ui/sortable-hoc/SortableHandle.js +0 -45
  234. package/ui/sortable-hoc/drag-handle.scss +0 -14
  235. package/ui/sortable-hoc/index.js +0 -9
  236. package/ui/sortable-hoc/utils.js +0 -292
  237. package/ui/springs.ts +0 -17
@@ -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
@@ -1,8 +0,0 @@
1
- import * as get_collection from "./store/get_collection"
2
- import {disconnect} from "./rts"
3
-
4
-
5
- export const signout = async() => {
6
- get_collection.destroy_all()
7
- disconnect()
8
- }
@@ -1,3 +0,0 @@
1
- /* @flow */
2
-
3
- export const UNDERSCORE_PREFIX = "$_"
@@ -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
- }