feat(phase4): list/set/zset editors, CLI, slow log, DB selector

- ListEditor: pagination, push, edit, remove elements
- SetEditor: filter, add, remove members
- ZsetEditor: filter, add with score, remove members
- CliView: interactive terminal with command history
- SlowLogView: slow log table with time/duration/command
- DbSelector: dropdown to switch Redis databases (0-15)
- StatusBar integrated with DB selector
- MainArea: added CLI and Slow Log tabs
- KeyDetail: dispatch to List/Set/Zset editors
- RedisService: list/set/zset/slowlog/memory operations
- Preload: all new IPC channels typed
This commit is contained in:
2026-07-04 18:07:33 +08:00
parent 272eb6b3af
commit ff09f5dc03
15 changed files with 1197 additions and 2 deletions
+58
View File
@@ -121,4 +121,62 @@ export function registerIpcHandlers(): void {
ipcMain.handle('redis:dbSize', async (_e, id: string) => {
return redisService.dbSize(id)
})
// List
ipcMain.handle('redis:listRange', async (_e, id: string, key: string, start: number, stop: number) => {
return redisService.listRange(id, key, start, stop)
})
ipcMain.handle('redis:listLength', async (_e, id: string, key: string) => {
return redisService.listLength(id, key)
})
ipcMain.handle('redis:listPush', async (_e, id: string, key: string, values: string[]) => {
return redisService.listPush(id, key, ...values)
})
ipcMain.handle('redis:listSet', async (_e, id: string, key: string, index: number, value: string) => {
await redisService.listSet(id, key, index, value)
})
ipcMain.handle('redis:listRemove', async (_e, id: string, key: string, count: number, value: string) => {
return redisService.listRemove(id, key, count, value)
})
// Set
ipcMain.handle('redis:setMembers', async (_e, id: string, key: string) => {
return redisService.setMembers(id, key)
})
ipcMain.handle('redis:setSize', async (_e, id: string, key: string) => {
return redisService.setSize(id, key)
})
ipcMain.handle('redis:setAdd', async (_e, id: string, key: string, members: string[]) => {
return redisService.setAdd(id, key, ...members)
})
ipcMain.handle('redis:setRemove', async (_e, id: string, key: string, members: string[]) => {
return redisService.setRemove(id, key, ...members)
})
// Sorted set
ipcMain.handle('redis:zsetRange', async (_e, id: string, key: string, start: number, stop: number, withScores: boolean) => {
return redisService.zsetRange(id, key, start, stop, withScores)
})
ipcMain.handle('redis:zsetSize', async (_e, id: string, key: string) => {
return redisService.zsetSize(id, key)
})
ipcMain.handle('redis:zsetAdd', async (_e, id: string, key: string, score: number, member: string) => {
return redisService.zsetAdd(id, key, score, member)
})
ipcMain.handle('redis:zsetRemove', async (_e, id: string, key: string, members: string[]) => {
return redisService.zsetRemove(id, key, ...members)
})
// Slow log
ipcMain.handle('redis:slowLogGet', async (_e, id: string, count: number) => {
return redisService.slowLogGet(id, count)
})
ipcMain.handle('redis:slowLogLen', async (_e, id: string) => {
return redisService.slowLogLen(id)
})
// Memory
ipcMain.handle('redis:memoryUsage', async (_e, id: string, key: string) => {
return redisService.memoryUsage(id, key)
})
}
+102
View File
@@ -176,3 +176,105 @@ export async function dbSize(id: string): Promise<number> {
if (!client) throw new Error(`Client ${id} not found`)
return client.dbsize() as Promise<number>
}
// List operations
export async function listRange(id: string, key: string, start: number, stop: number): Promise<string[]> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.lrange(key, start, stop)
}
export async function listLength(id: string, key: string): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.llen(key)
}
export async function listPush(id: string, key: string, ...values: string[]): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.rpush(key, ...values)
}
export async function listSet(id: string, key: string, index: number, value: string): Promise<void> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
await client.lset(key, index, value)
}
export async function listRemove(id: string, key: string, count: number, value: string): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.lrem(key, count, value)
}
// Set operations
export async function setMembers(id: string, key: string): Promise<string[]> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.smembers(key)
}
export async function setSize(id: string, key: string): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.scard(key)
}
export async function setAdd(id: string, key: string, ...members: string[]): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.sadd(key, ...members)
}
export async function setRemove(id: string, key: string, ...members: string[]): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.srem(key, ...members)
}
// Sorted set operations
export async function zsetRange(id: string, key: string, start: number, stop: number, withScores: boolean): Promise<string[]> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
if (withScores) return client.zrange(key, start, stop, 'WITHSCORES')
return client.zrange(key, start, stop)
}
export async function zsetSize(id: string, key: string): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.zcard(key)
}
export async function zsetAdd(id: string, key: string, score: number, member: string): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.zadd(key, score, member)
}
export async function zsetRemove(id: string, key: string, ...members: string[]): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.zrem(key, ...members)
}
// Slow log
export async function slowLogGet(id: string, count: number): Promise<any[]> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.slowlog('GET', count) as Promise<any[]>
}
export async function slowLogLen(id: string): Promise<number> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.slowlog('LEN') as Promise<number>
}
// Memory info
export async function memoryUsage(id: string, key: string): Promise<number | null> {
const client = clients.get(id)
if (!client) throw new Error(`Client ${id} not found`)
return client.memory('USAGE', key) as Promise<number | null>
}