({ children })
| 91 | * ProxyProvider interacts with local storage to indicate the preferred workspace proxy. |
| 92 | */ |
| 93 | export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => { |
| 94 | // Using a useState so the caller always has the latest user saved |
| 95 | // proxy. |
| 96 | const [userSavedProxy, setUserSavedProxy] = useState(loadUserSelectedProxy()); |
| 97 | |
| 98 | const { permissions } = useAuthenticated(); |
| 99 | const { metadata } = useEmbeddedMetadata(); |
| 100 | |
| 101 | const { |
| 102 | data: proxiesResp, |
| 103 | error: proxiesError, |
| 104 | isLoading: proxiesLoading, |
| 105 | isFetched: proxiesFetched, |
| 106 | } = useQuery( |
| 107 | cachedQuery({ |
| 108 | metadata: metadata.regions, |
| 109 | queryKey: ["get-proxies"], |
| 110 | queryFn: async (): Promise<readonly Region[]> => { |
| 111 | const apiCall = permissions.editWorkspaceProxies |
| 112 | ? API.getWorkspaceProxies |
| 113 | : API.getWorkspaceProxyRegions; |
| 114 | |
| 115 | const resp = await apiCall(); |
| 116 | return resp.regions; |
| 117 | }, |
| 118 | }), |
| 119 | ); |
| 120 | |
| 121 | // Every time we get a new proxiesResponse, update the latency check |
| 122 | // to each workspace proxy. |
| 123 | const { |
| 124 | proxyLatencies, |
| 125 | refetch: refetchProxyLatencies, |
| 126 | loaded: latenciesLoaded, |
| 127 | } = useProxyLatency(proxiesResp); |
| 128 | |
| 129 | const proxy = useMemo( |
| 130 | () => |
| 131 | getPreferredProxy( |
| 132 | proxiesResp ?? [], |
| 133 | userSavedProxy, |
| 134 | proxyLatencies, |
| 135 | // Do not auto select based on latencies, as inconsistent |
| 136 | // latencies can cause this to change on each call. The proxy |
| 137 | // value should be stable to prevent flickering. |
| 138 | false, |
| 139 | ), |
| 140 | [proxiesResp, userSavedProxy, proxyLatencies], |
| 141 | ); |
| 142 | |
| 143 | // This useEffect will auto select the best proxy if the user has not selected one. |
| 144 | // It must wait until all latencies are loaded to select based on latency. This does mean |
| 145 | // the first time a user loads the page, the proxy will "flicker" to the best proxy. |
| 146 | // |
| 147 | // Once the page is loaded, or the user selects a proxy, this will not run again. |
| 148 | useEffect(() => { |
| 149 | if (loadUserSelectedProxy() !== undefined) { |
| 150 | return; // User has selected a proxy, do not auto select. |
nothing calls this directly
no test coverage detected