Merge pull request #100 from m1m1sha/perf/ts-type

Perf/ts type
This commit is contained in:
m1m1sha 2024-05-10 15:25:29 +08:00 committed by GitHub
commit bee9565225
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 123 additions and 41 deletions

View File

@ -235,15 +235,13 @@ static INSTANCE_MAP: once_cell::sync::Lazy<DashMap<String, NetworkInstance>> =
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command] #[tauri::command]
fn parse_network_config(cfg: &str) -> Result<String, String> { fn parse_network_config(cfg: NetworkConfig) -> Result<String, String> {
let cfg: NetworkConfig = serde_json::from_str(cfg).map_err(|e| e.to_string())?;
let toml = cfg.gen_config().map_err(|e| e.to_string())?; let toml = cfg.gen_config().map_err(|e| e.to_string())?;
Ok(toml.dump()) Ok(toml.dump())
} }
#[tauri::command] #[tauri::command]
fn run_network_instance(cfg: &str) -> Result<String, String> { fn run_network_instance(cfg: NetworkConfig) -> Result<(), String> {
let cfg: NetworkConfig = serde_json::from_str(cfg).map_err(|e| e.to_string())?;
if INSTANCE_MAP.contains_key(&cfg.instance_id) { if INSTANCE_MAP.contains_key(&cfg.instance_id) {
return Err("instance already exists".to_string()); return Err("instance already exists".to_string());
} }
@ -254,13 +252,11 @@ fn run_network_instance(cfg: &str) -> Result<String, String> {
println!("instance {} started", instance_id); println!("instance {} started", instance_id);
INSTANCE_MAP.insert(instance_id, instance); INSTANCE_MAP.insert(instance_id, instance);
Ok("".to_string()) Ok(())
} }
#[tauri::command] #[tauri::command]
fn retain_network_instance(instance_ids: &str) -> Result<(), String> { fn retain_network_instance(instance_ids: Vec<String>) -> Result<(), String> {
let instance_ids: Vec<String> =
serde_json::from_str(instance_ids).map_err(|e| e.to_string())?;
let _ = INSTANCE_MAP.retain(|k, _| instance_ids.contains(k)); let _ = INSTANCE_MAP.retain(|k, _| instance_ids.contains(k));
println!( println!(
"instance {:?} retained", "instance {:?} retained",
@ -273,14 +269,14 @@ fn retain_network_instance(instance_ids: &str) -> Result<(), String> {
} }
#[tauri::command] #[tauri::command]
fn collect_network_infos() -> Result<String, String> { fn collect_network_infos() -> Result<BTreeMap<String, NetworkInstanceRunningInfo>, String> {
let mut ret = BTreeMap::new(); let mut ret = BTreeMap::new();
for instance in INSTANCE_MAP.iter() { for instance in INSTANCE_MAP.iter() {
if let Some(info) = instance.get_running_info() { if let Some(info) = instance.get_running_info() {
ret.insert(instance.key().clone(), info); ret.insert(instance.key().clone(), info);
} }
} }
Ok(serde_json::to_string(&ret).map_err(|e| e.to_string())?) Ok(ret)
} }
#[tauri::command] #[tauri::command]

View File

@ -1,4 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { NodeInfo } from '~/types/network'
const props = defineProps<{ const props = defineProps<{
instanceId?: string instanceId?: string
}>() }>()
@ -92,7 +94,7 @@ function lossRate(info: any) {
const myNodeInfo = computed(() => { const myNodeInfo = computed(() => {
if (!curNetworkInst.value) if (!curNetworkInst.value)
return {} return {} as NodeInfo
return curNetworkInst.value.detail?.my_node_info return curNetworkInst.value.detail?.my_node_info
}) })
@ -233,7 +235,7 @@ onUnmounted(() => {
}) })
const dialogVisible = ref(false) const dialogVisible = ref(false)
const dialogContent = ref('') const dialogContent = ref<any>('')
function showVpnPortalConfig() { function showVpnPortalConfig() {
const my_node_info = myNodeInfo.value const my_node_info = myNodeInfo.value

View File

@ -1,26 +1,22 @@
import { invoke } from '@tauri-apps/api/tauri' import { invoke } from '@tauri-apps/api/tauri'
import type { NetworkConfig } from '~/types/network' import type { NetworkConfig, NetworkInstanceRunningInfo } from '~/types/network'
export async function parseNetworkConfig(cfg: NetworkConfig): Promise<string> { export async function parseNetworkConfig(cfg: NetworkConfig) {
const ret: string = await invoke('parse_network_config', { cfg: JSON.stringify(cfg) }) return invoke<string>('parse_network_config', { cfg })
return ret
} }
export async function runNetworkInstance(cfg: NetworkConfig) { export async function runNetworkInstance(cfg: NetworkConfig) {
const ret: string = await invoke('run_network_instance', { cfg: JSON.stringify(cfg) }) return invoke('run_network_instance', { cfg })
return ret
} }
export async function retainNetworkInstance(instanceIds: Array<string>) { export async function retainNetworkInstance(instanceIds: string[]) {
const ret: string = await invoke('retain_network_instance', { instanceIds: JSON.stringify(instanceIds) }) return invoke('retain_network_instance', { instanceIds })
return ret
} }
export async function collectNetworkInfos() { export async function collectNetworkInfos() {
const ret: string = await invoke('collect_network_infos', {}) return await invoke<Record<string, NetworkInstanceRunningInfo>>('collect_network_infos')
return JSON.parse(ret)
} }
export async function getOsHostname(): Promise<string> { export async function getOsHostname() {
return await invoke('get_os_hostname') return await invoke<string>('get_os_hostname')
} }

View File

@ -1,4 +1,4 @@
import type { NetworkConfig, NetworkInstance } from '~/types/network' import type { NetworkConfig, NetworkInstance, NetworkInstanceRunningInfo } from '~/types/network'
import { DEFAULT_NETWORK_CONFIG } from '~/types/network' import { DEFAULT_NETWORK_CONFIG } from '~/types/network'
export const useNetworkStore = defineStore('networkStore', { export const useNetworkStore = defineStore('networkStore', {
@ -13,7 +13,7 @@ export const useNetworkStore = defineStore('networkStore', {
// uuid -> instance // uuid -> instance
instances: {} as Record<string, NetworkInstance>, instances: {} as Record<string, NetworkInstance>,
networkInfos: {} as Record<string, any>, networkInfos: {} as Record<string, NetworkInstanceRunningInfo>,
} }
}, },
@ -56,35 +56,36 @@ export const useNetworkStore = defineStore('networkStore', {
instance_id: instanceId, instance_id: instanceId,
running: false, running: false,
error_msg: '', error_msg: '',
detail: {}, detail: {} as NetworkInstanceRunningInfo,
} }
}, },
updateWithNetworkInfos(networkInfos: Record<string, any>) { updateWithNetworkInfos(networkInfos: Record<string, NetworkInstanceRunningInfo>) {
this.networkInfos = networkInfos this.networkInfos = networkInfos
for (const [instanceId, info] of Object.entries(networkInfos)) { for (const [instanceId, info] of Object.entries(networkInfos)) {
if (this.instances[instanceId] === undefined) if (this.instances[instanceId] === undefined)
this.addNetworkInstance(instanceId) this.addNetworkInstance(instanceId)
this.instances[instanceId].running = info.running this.instances[instanceId].running = info.running
this.instances[instanceId].error_msg = info.error_msg this.instances[instanceId].error_msg = info.error_msg || ''
this.instances[instanceId].detail = info this.instances[instanceId].detail = info
} }
}, },
loadFromLocalStorage() { loadFromLocalStorage() {
const networkList = JSON.parse(localStorage.getItem('networkList') || '[]') let networkList: NetworkConfig[]
const result = []
for (const cfg of networkList) { try {
result.push({ networkList = JSON.parse(localStorage.getItem('networkList') || '[]')
...DEFAULT_NETWORK_CONFIG, networkList = networkList.map((cfg) => {
...cfg, return { ...DEFAULT_NETWORK_CONFIG(), ...cfg } as NetworkConfig
}) })
} }
if (result.length === 0) catch {
result.push(DEFAULT_NETWORK_CONFIG) networkList = [DEFAULT_NETWORK_CONFIG()]
}
this.networkList = result this.networkList = networkList
this.curNetwork = this.networkList[0] this.curNetwork = this.networkList[0]
}, },

View File

@ -69,5 +69,92 @@ export interface NetworkInstance {
running: boolean running: boolean
error_msg: string error_msg: string
detail: any detail: NetworkInstanceRunningInfo
}
export interface NetworkInstanceRunningInfo {
my_node_info: NodeInfo
events: Record<string, any>
node_info: NodeInfo
routes: Route[]
peers: PeerInfo[]
peer_route_pairs: PeerRoutePair[]
running: boolean
error_msg?: string
}
export interface NodeInfo {
virtual_ipv4: string
ips: {
public_ipv4: string
interface_ipv4s: string[]
public_ipv6: string
interface_ipv6s: string[]
listeners: {
serialization: string
scheme_end: number
username_end: number
host_start: number
host_end: number
host: any
port?: number
path_start: number
query_start?: number
fragment_start?: number
}[]
}
stun_info: StunInfo
listeners: string[]
vpn_portal_cfg?: string
}
export interface StunInfo {
udp_nat_type: number
tcp_nat_type: number
last_update_time: number
}
export interface Route {
peer_id: number
ipv4_addr: string
next_hop_peer_id: number
cost: number
proxy_cidrs: string[]
hostname: string
stun_info?: StunInfo
inst_id: string
}
export interface PeerInfo {
peer_id: number
conns: PeerConnInfo[]
}
export interface PeerConnInfo {
conn_id: string
my_peer_id: number
peer_id: number
features: string[]
tunnel?: TunnelInfo
stats?: PeerConnStats
loss_rate: number
}
export interface PeerRoutePair {
route: Route
peer?: PeerInfo
}
export interface TunnelInfo {
tunnel_type: string
local_addr: string
remote_addr: string
}
export interface PeerConnStats {
rx_bytes: number
tx_bytes: number
rx_packets: number
tx_packets: number
latency_us: number
} }