metacubexd/src/signals/proxies.ts

131 lines
3.4 KiB
TypeScript
Raw Normal View History

2023-08-29 20:20:01 +08:00
import { createSignal } from 'solid-js'
import { useRequest } from '~/signals'
import { autoCloseConns, urlForDelayTest } from '~/signals/config'
import type { Proxy, ProxyNode, ProxyProvider } from '~/types'
2023-08-29 20:20:01 +08:00
type ProxyInfo = {
name: string
udp: boolean
type: string
}
2023-08-30 23:02:55 +08:00
// these signals should be global state
const [proxies, setProxies] = createSignal<Proxy[]>([])
const [proxyProviders, setProxyProviders] = createSignal<ProxyProvider[]>([])
const [delayMap, setDelayMap] = createSignal<Record<string, number>>({})
const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
{},
)
2023-08-30 23:54:49 +08:00
2023-08-29 20:20:01 +08:00
export function useProxies() {
const request = useRequest()
const setProxyInfoByProixes = (proxies: Proxy[] | ProxyNode[]) => {
proxies.forEach((proxy) => {
const delay = proxy.history.at(-1)?.delay ?? 0
setProxyNodeMap({
...proxyNodeMap(),
[proxy.name]: {
udp: proxy.udp,
type: proxy.type,
name: proxy.name,
},
})
setDelayMap({
...delayMap(),
[proxy.name]: delay,
})
})
}
2023-08-29 20:20:01 +08:00
const updateProxy = async () => {
const { providers } = await request
.get('providers/proxies')
.json<{ providers: Record<string, ProxyProvider> }>()
Object.values(providers).forEach((provider) => {
setProxyInfoByProixes(provider.proxies)
})
2023-08-29 20:20:01 +08:00
setProxyProviders(
Object.values(providers).filter(
(provider) =>
provider.name !== 'default' && provider.vehicleType !== 'Compatible',
),
)
const { proxies } = await request
.get('proxies')
.json<{ proxies: Record<string, Proxy> }>()
2023-09-01 10:45:38 +08:00
const sortIndex = [...(proxies['GLOBAL'].all ?? []), 'GLOBAL']
2023-08-29 20:20:01 +08:00
setProxyInfoByProixes(Object.values(proxies))
2023-08-29 20:20:01 +08:00
setProxies(
2023-08-30 11:01:19 +08:00
Object.values(proxies)
2023-09-01 11:49:59 +08:00
.filter((proxy) => proxy.all?.length)
2023-08-30 11:01:19 +08:00
.sort(
(pre, next) =>
sortIndex.indexOf(pre.name) - sortIndex.indexOf(next.name),
),
2023-08-29 20:20:01 +08:00
)
}
const setProxyGroupByProxyName = async (proxy: Proxy, proxyName: string) => {
2023-09-02 13:50:24 +08:00
const proxyGroupList = proxies().slice()
const proxyGroup = proxyGroupList.find((i) => i.name === proxy.name)!
if (autoCloseConns()) request.delete('connections')
2023-08-29 20:20:01 +08:00
await request.put(`proxies/${proxy.name}`, {
body: JSON.stringify({
name: proxyName,
}),
})
2023-09-02 13:50:24 +08:00
proxyGroup.now = proxyName
2023-09-02 13:50:24 +08:00
setProxies(proxyGroupList)
queueMicrotask(updateProxy)
2023-08-29 20:20:01 +08:00
}
2023-08-30 11:01:19 +08:00
const delayTestByProxyGroupName = async (proxyGroupName: string) => {
const data: Record<string, number> = await request
2023-09-01 16:30:23 +08:00
.get(`group/${proxyGroupName}/delay`, {
searchParams: {
2023-09-02 15:08:35 +08:00
url: urlForDelayTest(),
2023-09-01 16:30:23 +08:00
timeout: 2000,
},
})
2023-08-30 11:01:19 +08:00
.json()
setDelayMap({
...delayMap(),
...data,
})
2023-08-31 12:02:23 +08:00
}
2023-08-30 11:01:19 +08:00
2023-08-31 12:02:23 +08:00
const updateProviderByProviderName = async (proxyProviderName: string) => {
await request.put(`providers/proxies/${proxyProviderName}`)
await updateProxy()
2023-08-30 11:01:19 +08:00
}
2023-08-31 12:02:23 +08:00
const healthCheckByProviderName = async (providerName: string) => {
await request.get(`providers/proxies/${providerName}/healthcheck`, {
timeout: 30 * 1000, // thie api was a little bit slow sometimes...
})
await updateProxy()
}
2023-08-29 20:20:01 +08:00
return {
proxies,
proxyProviders,
2023-08-30 11:01:19 +08:00
delayTestByProxyGroupName,
delayMap,
2023-08-30 23:54:49 +08:00
proxyNodeMap,
2023-08-29 20:20:01 +08:00
updateProxy,
setProxyGroupByProxyName,
2023-08-31 12:02:23 +08:00
updateProviderByProviderName,
healthCheckByProviderName,
2023-08-29 20:20:01 +08:00
}
}