2023-09-17 03:09:56 +08:00
|
|
|
import { batch, createSignal, untrack } from 'solid-js'
|
2023-09-12 21:33:16 +08:00
|
|
|
import {
|
|
|
|
closeSingleConnectionAPI,
|
|
|
|
fetchProxiesAPI,
|
|
|
|
fetchProxyProvidersAPI,
|
|
|
|
proxyGroupLatencyTestAPI,
|
|
|
|
proxyProviderHealthCheck,
|
|
|
|
selectProxyInGroupAPI,
|
|
|
|
updateProxyProviderAPI,
|
|
|
|
} from '~/apis'
|
2023-09-06 11:17:00 +08:00
|
|
|
import {
|
|
|
|
autoCloseConns,
|
2023-09-17 03:09:56 +08:00
|
|
|
latencyQualityMap,
|
2023-09-06 11:55:12 +08:00
|
|
|
latencyTestTimeoutDuration,
|
2023-09-08 15:22:07 +08:00
|
|
|
latestConnectionMsg,
|
|
|
|
restructRawMsgToConnection,
|
2023-09-12 21:33:16 +08:00
|
|
|
urlForLatencyTest,
|
|
|
|
} from '~/signals'
|
|
|
|
import type { Proxy, ProxyNode, ProxyProvider } from '~/types'
|
2023-08-29 20:20:01 +08:00
|
|
|
|
2023-09-01 12:10:34 +08:00
|
|
|
type ProxyInfo = {
|
|
|
|
name: string
|
|
|
|
udp: boolean
|
2023-09-05 01:30:17 +08:00
|
|
|
now: string
|
|
|
|
xudp: boolean
|
2023-09-01 12:10:34 +08:00
|
|
|
type: string
|
|
|
|
}
|
2023-09-16 02:50:21 +08:00
|
|
|
|
2023-08-30 23:02:55 +08:00
|
|
|
// these signals should be global state
|
|
|
|
const [proxies, setProxies] = createSignal<Proxy[]>([])
|
|
|
|
const [proxyProviders, setProxyProviders] = createSignal<ProxyProvider[]>([])
|
|
|
|
|
2023-09-03 05:35:08 +08:00
|
|
|
const [latencyMap, setLatencyMap] = createSignal<Record<string, number>>({})
|
2023-09-01 12:10:34 +08:00
|
|
|
const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
|
|
|
|
{},
|
|
|
|
)
|
2023-08-30 23:54:49 +08:00
|
|
|
|
2023-09-04 17:57:20 +08:00
|
|
|
const setProxiesInfo = (proxies: (Proxy | ProxyNode)[]) => {
|
|
|
|
const newProxyNodeMap = { ...proxyNodeMap() }
|
|
|
|
const newLatencyMap = { ...latencyMap() }
|
|
|
|
|
|
|
|
proxies.forEach((proxy) => {
|
2023-09-17 03:09:56 +08:00
|
|
|
const latency =
|
|
|
|
proxy.history.at(-1)?.delay || latencyQualityMap().NOT_CONNECTED
|
2023-09-04 17:57:20 +08:00
|
|
|
|
|
|
|
newProxyNodeMap[proxy.name] = {
|
|
|
|
udp: proxy.udp,
|
2023-09-05 01:30:17 +08:00
|
|
|
xudp: proxy.xudp,
|
2023-09-04 17:57:20 +08:00
|
|
|
type: proxy.type,
|
2023-09-05 01:30:17 +08:00
|
|
|
now: proxy.now,
|
2023-09-04 17:57:20 +08:00
|
|
|
name: proxy.name,
|
|
|
|
}
|
|
|
|
newLatencyMap[proxy.name] = latency
|
|
|
|
})
|
|
|
|
|
2023-09-17 03:09:56 +08:00
|
|
|
batch(() => {
|
|
|
|
setProxyNodeMap(newProxyNodeMap)
|
|
|
|
setLatencyMap(newLatencyMap)
|
|
|
|
})
|
2023-09-04 17:57:20 +08:00
|
|
|
}
|
|
|
|
|
2023-09-03 03:26:29 +08:00
|
|
|
export const useProxies = () => {
|
2023-09-19 20:24:13 +08:00
|
|
|
const fetchProxies = async () => {
|
2023-09-04 17:57:20 +08:00
|
|
|
const [{ providers }, { proxies }] = await Promise.all([
|
2023-09-12 21:33:16 +08:00
|
|
|
fetchProxyProvidersAPI(),
|
|
|
|
fetchProxiesAPI(),
|
2023-09-04 17:57:20 +08:00
|
|
|
])
|
2023-08-29 20:20:01 +08:00
|
|
|
|
2023-09-01 10:45:38 +08:00
|
|
|
const sortIndex = [...(proxies['GLOBAL'].all ?? []), 'GLOBAL']
|
2023-09-04 17:57:20 +08:00
|
|
|
const sortedProxies = Object.values(proxies)
|
|
|
|
.filter((proxy) => proxy.all?.length)
|
|
|
|
.sort(
|
|
|
|
(prev, next) =>
|
|
|
|
sortIndex.indexOf(prev.name) - sortIndex.indexOf(next.name),
|
|
|
|
)
|
|
|
|
const sortedProviders = Object.values(providers).filter(
|
|
|
|
(provider) =>
|
|
|
|
provider.name !== 'default' && provider.vehicleType !== 'Compatible',
|
2023-08-29 20:20:01 +08:00
|
|
|
)
|
2023-09-04 17:57:20 +08:00
|
|
|
const allProxies: (Proxy | ProxyNode)[] = [
|
|
|
|
...Object.values(proxies),
|
|
|
|
...sortedProviders.flatMap((provider) => provider.proxies),
|
|
|
|
]
|
|
|
|
|
2023-09-17 03:09:56 +08:00
|
|
|
batch(() => {
|
|
|
|
setProxies(sortedProxies)
|
|
|
|
setProxyProviders(sortedProviders)
|
|
|
|
setProxiesInfo(allProxies)
|
|
|
|
})
|
2023-08-29 20:20:01 +08:00
|
|
|
}
|
|
|
|
|
2023-09-17 14:55:03 +08:00
|
|
|
const selectProxyInGroup = async (proxy: Proxy, proxyName: string) => {
|
2023-09-12 21:33:16 +08:00
|
|
|
await selectProxyInGroupAPI(proxy.name, proxyName)
|
2023-09-19 20:24:13 +08:00
|
|
|
await fetchProxies()
|
2023-09-08 15:09:19 +08:00
|
|
|
|
2023-09-08 11:22:16 +08:00
|
|
|
if (autoCloseConns()) {
|
2023-09-12 21:33:16 +08:00
|
|
|
// we don't use activeConns from useConnection here for better performance,
|
|
|
|
// and we use empty array to restruct msg because they are closed, they won't have speed anyway
|
2023-09-08 15:45:15 +08:00
|
|
|
untrack(() => {
|
|
|
|
const activeConns = restructRawMsgToConnection(
|
|
|
|
latestConnectionMsg()?.connections ?? [],
|
|
|
|
[],
|
|
|
|
)
|
|
|
|
|
|
|
|
if (activeConns.length > 0) {
|
|
|
|
activeConns.forEach(({ id, chains }) => {
|
|
|
|
if (chains.includes(proxy.name)) {
|
2023-09-12 21:33:16 +08:00
|
|
|
closeSingleConnectionAPI(id)
|
2023-09-08 15:45:15 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
2023-09-08 11:22:16 +08:00
|
|
|
}
|
2023-08-29 20:20:01 +08:00
|
|
|
}
|
|
|
|
|
2023-09-03 05:40:39 +08:00
|
|
|
const latencyTestByProxyGroupName = async (proxyGroupName: string) => {
|
2023-09-12 21:33:16 +08:00
|
|
|
const data = await proxyGroupLatencyTestAPI(
|
|
|
|
proxyGroupName,
|
|
|
|
urlForLatencyTest(),
|
|
|
|
latencyTestTimeoutDuration(),
|
|
|
|
)
|
2023-08-30 11:01:19 +08:00
|
|
|
|
2023-09-03 05:35:08 +08:00
|
|
|
setLatencyMap({
|
|
|
|
...latencyMap(),
|
2023-09-02 15:00:13 +08:00
|
|
|
...data,
|
2023-09-01 12:10:34 +08:00
|
|
|
})
|
2023-08-31 12:02:23 +08:00
|
|
|
}
|
2023-08-30 11:01:19 +08:00
|
|
|
|
2023-09-12 21:33:16 +08:00
|
|
|
const updateProviderByProviderName = async (providerName: string) => {
|
2023-09-02 17:55:09 +08:00
|
|
|
try {
|
2023-09-12 21:33:16 +08:00
|
|
|
await updateProxyProviderAPI(providerName)
|
2023-09-02 17:55:09 +08:00
|
|
|
} catch {}
|
2023-09-19 20:24:13 +08:00
|
|
|
await fetchProxies()
|
2023-08-30 11:01:19 +08:00
|
|
|
}
|
|
|
|
|
2023-09-02 17:01:59 +08:00
|
|
|
const updateAllProvider = async () => {
|
2023-09-05 22:38:26 +08:00
|
|
|
await Promise.allSettled(
|
2023-09-12 21:33:16 +08:00
|
|
|
proxyProviders().map((provider) => updateProxyProviderAPI(provider.name)),
|
2023-09-02 17:01:59 +08:00
|
|
|
)
|
2023-09-19 20:24:13 +08:00
|
|
|
await fetchProxies()
|
2023-09-02 17:01:59 +08:00
|
|
|
}
|
|
|
|
|
2023-08-31 12:02:23 +08:00
|
|
|
const healthCheckByProviderName = async (providerName: string) => {
|
2023-09-12 21:33:16 +08:00
|
|
|
await proxyProviderHealthCheck(providerName)
|
2023-09-19 20:24:13 +08:00
|
|
|
await fetchProxies()
|
2023-08-31 10:50:43 +08:00
|
|
|
}
|
|
|
|
|
2023-08-29 20:20:01 +08:00
|
|
|
return {
|
|
|
|
proxies,
|
|
|
|
proxyProviders,
|
2023-09-03 05:40:39 +08:00
|
|
|
latencyTestByProxyGroupName,
|
2023-09-03 05:35:08 +08:00
|
|
|
latencyMap,
|
2023-08-30 23:54:49 +08:00
|
|
|
proxyNodeMap,
|
2023-09-19 20:24:13 +08:00
|
|
|
fetchProxies,
|
2023-09-17 14:55:03 +08:00
|
|
|
selectProxyInGroup,
|
2023-08-31 12:02:23 +08:00
|
|
|
updateProviderByProviderName,
|
2023-09-02 17:01:59 +08:00
|
|
|
updateAllProvider,
|
2023-08-31 12:02:23 +08:00
|
|
|
healthCheckByProviderName,
|
2023-08-29 20:20:01 +08:00
|
|
|
}
|
|
|
|
}
|