feat: release OpsXShell 2.1.0 native Tauri edition

This commit is contained in:
Logan.Li committed 2026-07-30 23:32:51 +08:00
1 parent e9a0d21758
commit a3dba0c6ed
311 files changed
+31748 -14897

No files matched your search

+56 -16
View File
@@ -11,6 +11,7 @@ import type {
PoolClientConfig,
} from './types'
import type { CreateConnectionOptions, CreateConnectionResult, PoolStats } from './types'
import { useSettingsStore } from '../settingsStore'
// ============== Pool State ==============
@@ -41,6 +42,10 @@ interface PoolState {
disconnectConnection: (connectionId: string, reason?: string) => Promise<void>
// The native service has already torn this connection down. Do not issue a
// second disconnect command, but release every renderer-side resource.
forgetNativeConnection: (connectionId: string) => void
releaseConnection: (connectionId: string, tabId: string) => Promise<void>
// 连接查询
@@ -133,9 +138,10 @@ export const usePoolStore = create<PoolState>((set, get) => ({
}
// 3. 创建新连接
console.log('>>> Creating new SSH connection via electronAPI...')
console.log('>>> Creating new SSH connection via opsxApi...')
try {
const result = await window.electronAPI?.sshConnect({
const sshSettings = useSettingsStore.getState().settings
const result = await window.opsxApi?.sshConnect({
host: config.host,
port: config.port || 22,
username: config.username,
@@ -143,6 +149,10 @@ export const usePoolStore = create<PoolState>((set, get) => ({
privateKey: config.privateKey,
passphrase: config.passphrase,
proxy: config.proxy,
jumpHost: config.jumpHost,
jumpHosts: config.jumpHosts,
timeoutSeconds: config.timeoutSeconds ?? sshSettings.timeout,
keepAlive: config.keepAlive ?? sshSettings.keepAlive,
})
console.log('>>> sshConnect result:', result)
@@ -158,14 +168,22 @@ export const usePoolStore = create<PoolState>((set, get) => ({
console.log('>>> Connection created, connectionId:', connectionId)
// 设置保活定时器
const keepaliveInterval = window.setInterval(() => {
const conn = get().connections.get(connectionId)
if (conn && (conn.state === 'connected' || conn.state === 'background')) {
window.electronAPI?.sshExec(connectionId, 'echo -n ""').catch(() => {
get().disconnectConnection(connectionId, 'keepalive failed')
})
}
}, poolConfig.keepaliveIntervalMs)
const keepaliveInterval = (config.keepAlive ?? sshSettings.keepAlive)
? window.setInterval(() => {
const conn = get().connections.get(connectionId)
if (conn && (conn.state === 'connected' || conn.state === 'background')) {
void window.opsxApi?.sshKeepalive(connectionId)
.then((result) => {
if (!result.success) {
void get().disconnectConnection(connectionId, result.error || 'keepalive failed')
}
})
.catch(() => {
void get().disconnectConnection(connectionId, 'keepalive failed')
})
}
}, poolConfig.keepaliveIntervalMs)
: undefined
// 4. 创建连接池项
const pooledConnection: PooledConnection = {
@@ -177,6 +195,12 @@ export const usePoolStore = create<PoolState>((set, get) => ({
password: config.password,
privateKey: config.privateKey,
passphrase: config.passphrase,
proxy: config.proxy,
jumpHost: config.jumpHost,
jumpHosts: config.jumpHosts,
timeoutSeconds: config.timeoutSeconds ?? sshSettings.timeout,
keepAlive: config.keepAlive ?? sshSettings.keepAlive,
startupCommand: config.startupCommand,
},
state: 'connected',
refCount: 1,
@@ -220,7 +244,7 @@ export const usePoolStore = create<PoolState>((set, get) => ({
}
try {
const result = await window.electronAPI?.sshConnect(conn.config)
const result = await window.opsxApi?.sshConnect(conn.config)
if (!result?.success) return false
const newConnectionId = result.connectionId
@@ -231,9 +255,11 @@ export const usePoolStore = create<PoolState>((set, get) => ({
newConnections.delete(connectionId)
const now = Date.now()
const keepaliveInterval = window.setInterval(() => {
window.electronAPI?.sshExec(newConnectionId, 'echo -n ""').catch(() => {})
}, state.config.keepaliveIntervalMs)
const keepaliveInterval = conn.config.keepAlive === false
? undefined
: window.setInterval(() => {
void window.opsxApi?.sshKeepalive(newConnectionId).catch(() => {})
}, state.config.keepaliveIntervalMs)
newConnections.set(newConnectionId, {
...conn,
@@ -289,7 +315,7 @@ export const usePoolStore = create<PoolState>((set, get) => ({
}
try {
await window.electronAPI?.sshDisconnect(connectionId)
await window.opsxApi?.sshDisconnect(connectionId)
} catch {
// 忽略断开错误
}
@@ -301,6 +327,20 @@ export const usePoolStore = create<PoolState>((set, get) => ({
})
},
forgetNativeConnection: (connectionId) => {
const conn = get().connections.get(connectionId)
if (!conn) return
if (conn.keepaliveInterval) clearInterval(conn.keepaliveInterval)
if (conn.idleTimeout) clearTimeout(conn.idleTimeout)
set((state) => {
const newConnections = new Map(state.connections)
newConnections.delete(connectionId)
return { connections: newConnections }
})
},
releaseConnection: async (connectionId, tabId) => {
const conn = get().connections.get(connectionId)
if (!conn) return
@@ -391,7 +431,7 @@ export const usePoolStore = create<PoolState>((set, get) => ({
}
promises.push(
window.electronAPI?.sshDisconnect(conn.connectionId)
window.opsxApi?.sshDisconnect(conn.connectionId)
.then(() => {})
.catch(() => {}) as Promise<void>
)