@rpcbase/client 0.50.0 → 0.52.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.
@@ -0,0 +1,8 @@
1
+ /* @flow */
2
+
3
+
4
+ const AppProvider = () => {
5
+
6
+ }
7
+
8
+ export default AppProvider
@@ -6,6 +6,7 @@ import page from "page"
6
6
  import debug from "debug"
7
7
 
8
8
  import post from "../../helpers/post"
9
+ import {reconnect as rts_reconnect} from "../../rts"
9
10
 
10
11
  import {set_is_signed_in, set_uid} from "../index"
11
12
  import Footer from "../Footer"
@@ -53,6 +54,9 @@ const SignIn = ({
53
54
  log("redirect to:", redirect || onSuccessRedirect)
54
55
  set_uid(res.user_id)
55
56
  set_is_signed_in(true)
57
+
58
+ // we must now reconnect on the websocket as we now have a new cookie
59
+ rts_reconnect()
56
60
  onSuccess()
57
61
  if (redirect) {
58
62
  page(redirect)
@@ -7,6 +7,8 @@ import post from "../../helpers/post"
7
7
 
8
8
  import {set_is_signed_in, set_uid} from "../index"
9
9
 
10
+ // TODO: rts_disconnect
11
+ // TODO: clear cache + db
10
12
 
11
13
  const SignOut = ({
12
14
  onSuccess = () => null
@@ -21,6 +23,9 @@ const SignOut = ({
21
23
  set_uid(null)
22
24
  set_is_signed_in(false)
23
25
  localStorage.clear()
26
+
27
+ // TODO: clear DB
28
+
24
29
  setIsSignedOut(true)
25
30
  onSuccess()
26
31
  } else {
@@ -2,6 +2,8 @@
2
2
  import {useState} from "react"
3
3
  import page from "page"
4
4
 
5
+ import {reconnect as rts_reconnect} from "../../rts"
6
+
5
7
  import {set_is_signed_in, set_uid} from "../index"
6
8
  import post from "../../helpers/post"
7
9
  import Footer from "../Footer"
@@ -29,6 +31,9 @@ const SignUp = ({
29
31
  if (res.status === "ok") {
30
32
  set_uid(res.user_id)
31
33
  set_is_signed_in(true)
34
+
35
+ // we must now reconnect on the websocket as we now have a new cookie
36
+ rts_reconnect()
32
37
  onSuccess()
33
38
  page(onSuccessRedirect)
34
39
  } else if (res.status === "error") {
package/base_url.js CHANGED
@@ -6,11 +6,11 @@ import {SERVER_PORT, HOSTNAME} from "env"
6
6
  const protocol = (typeof window !== "undefined" && window?.location?.protocol) || "http:"
7
7
 
8
8
  // there is no SERVER_PORT in production, as we use the default port and we are behind the gateway
9
- let BASE_URL
10
- if (__DEV__) {
11
- BASE_URL = `${protocol}//${HOSTNAME}:${SERVER_PORT}`
12
- } else {
13
- BASE_URL = `https://${HOSTNAME}`
14
- }
9
+ // we assume we specify the port only when localhost or 127.0.0.1
10
+ const is_local = ["localhost", "127.0.0.1"].includes(HOSTNAME)
11
+
12
+ const BASE_URL = is_local ? `${protocol}//${HOSTNAME}:${SERVER_PORT}` : `https://${HOSTNAME}`
13
+
14
+ console.log("HOST", HOSTNAME, BASE_URL)
15
15
 
16
16
  export default BASE_URL
package/hashState.js ADDED
@@ -0,0 +1,141 @@
1
+ /* @flow */
2
+ import {useState, useEffect, createContext, useContext, useCallback} from "react"
3
+ import LZString from "lz-string"
4
+ import _isNil from "lodash/isNil"
5
+ import _omitBy from "lodash/omitBy"
6
+ import isEqual from "fast-deep-equal"
7
+
8
+ import {PAGE_NAVIGATION} from "config/events"
9
+
10
+
11
+ const EMPTY_STATE_TOKEN = "N4XyA" // lz-string encoded empty state ''
12
+
13
+ // WARNING: this assumes hash_str starts with "#"
14
+ const parse_hash_str = (hash_str = window.location.hash) => {
15
+ if (hash_str.length < 1) {
16
+ return {}
17
+ }
18
+ const current_state_str = hash_str.slice(1)
19
+ let parsed
20
+ try {
21
+ const decoded = LZString.decompressFromEncodedURIComponent(current_state_str)
22
+ parsed = JSON.parse(decoded)
23
+ } catch (e) {
24
+ console.error(e)
25
+ }
26
+
27
+ return parsed || {}
28
+ }
29
+
30
+ // On first load, retrieve hashState from URL
31
+ const __initial_state = _omitBy(parse_hash_str(), _isNil)
32
+
33
+ export const encode_payload = (payload) =>
34
+ LZString.compressToEncodedURIComponent(JSON.stringify(payload))
35
+
36
+ // add payload to window hash
37
+ const apply_hash_state = (payload) => {
38
+ const str = encode_payload(payload)
39
+
40
+ if (str === EMPTY_STATE_TOKEN) {
41
+ history.replaceState(null, null, window.location.pathname)
42
+ } else {
43
+ history.replaceState(null, null, `${window.location.pathname}#${encode_payload(payload)}`)
44
+ }
45
+ }
46
+
47
+ export const HashContext = createContext({
48
+ hashState: {},
49
+ serializeHashState: () => null,
50
+ encodeHashLink: () => null,
51
+ })
52
+
53
+ export const useHashState = () => {
54
+ return useContext(HashContext)
55
+ }
56
+
57
+ export const withHashState = (Component) => {
58
+ const WrappedComp = ({children, ...props}) => {
59
+ const hashCtx = useContext(HashContext)
60
+
61
+ return (
62
+ <Component
63
+ {...props}
64
+ hashState={hashCtx.hashState}
65
+ serializeHashState={hashCtx.serializeHashState}
66
+ encodeHashLink={hashCtx.encodeHashLink}
67
+ />
68
+ )
69
+ }
70
+
71
+ WrappedComp.displayName = `withHashState(${Component.displayName})`
72
+
73
+ return WrappedComp
74
+ }
75
+
76
+ export const HashStateProvider = ({children}) => {
77
+ const [hashState, setHashState] = useState(__initial_state)
78
+
79
+ useEffect(() => {
80
+ const onChange = (ev) => {
81
+ const newHashStr = ev.detail.context?.hash
82
+ if (!newHashStr) return
83
+ // WARNING: page.js strips the "#" we add it back
84
+ const parsed = _omitBy(parse_hash_str(`#${newHashStr}`), _isNil)
85
+ const newState = {
86
+ ...hashState,
87
+ ...parsed,
88
+ }
89
+ // apply only if changed
90
+ if (!isEqual(hashState, newState)) {
91
+ setHashState(newState)
92
+ }
93
+ }
94
+ document.body.addEventListener(PAGE_NAVIGATION, onChange)
95
+
96
+ return () => document.body.removeEventListener(PAGE_NAVIGATION, onChange)
97
+ }, [hashState, setHashState])
98
+
99
+ useEffect(() => {
100
+ apply_hash_state(hashState)
101
+ window.__PRIVATE_HASH_STATE_DO_NOT_USE = hashState
102
+ }, [hashState])
103
+
104
+ const serializeHashState = useCallback((payload) => {
105
+ setHashState((current) => {
106
+ // clone and remove nil values
107
+ const newState = _omitBy(
108
+ {
109
+ ...current,
110
+ ...payload,
111
+ },
112
+ _isNil,
113
+ )
114
+ return newState
115
+ })
116
+ }, [])
117
+
118
+ const encodeHashLink = useCallback((payload) => {
119
+ const newState = _omitBy(
120
+ {
121
+ ...hashState,
122
+ ...payload,
123
+ },
124
+ _isNil,
125
+ )
126
+
127
+ return encode_payload(newState)
128
+ }, [])
129
+
130
+ return (
131
+ <HashContext.Provider
132
+ value={{
133
+ hashState,
134
+ serializeHashState,
135
+ encodeHashLink,
136
+ }}
137
+ >
138
+ {children}
139
+ </HashContext.Provider>
140
+ )
141
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpcbase/client",
3
- "version": "0.50.0",
3
+ "version": "0.52.0",
4
4
  "scripts": {
5
5
  "test": "echo \"Error: no test specified\" && exit 0"
6
6
  },