RSS Git Download  Clone
Raw Blame History 4kB 135 lines
import { create } from 'zustand'

function computeApiHost(): string {
    const apiUrl = new URL(location.toString())
    if ((globalThis as any).p3xrDevMode === true) {
        const apiPort = (globalThis as any).p3xrApiPort || '7843'
        return `http://${apiUrl.hostname}:${apiPort}`
    }
    return `${apiUrl.protocol}//${apiUrl.host}`
}

type ConnectionState = 'none' | 'connecting' | 'connected'
type CurrentPage = 'connections' | 'database' | 'pulse' | 'profiler' | 'pubsub' | 'analysis' |
    'search' | 'timeseries' | 'info' | 'settings' | 'unknown'

interface RedisState {
    apiHost: string
    connection: any | undefined
    connections: { list: any[] }
    cfg: any | undefined
    version: string | undefined
    currentDatabase: number | undefined
    databaseIndexes: number[]
    keysRaw: string[]
    keysInfo: any
    search: string
    page: number
    info: any
    dbsize: number | undefined
    monitor: boolean
    commands: string[]
    commandsMeta: Record<string, { syntax: string; group: string }>
    modules: any[]
    hasRediSearch: boolean
    hasReJSON: boolean
    hasTimeSeries: boolean
    hasBloom: boolean
    theme: string | undefined
    redisConnections: Record<string, any>
    keysInfoFetchedAt: number
    redisChanged: boolean
    failed: boolean
    reducedFunctions: boolean

    // --- Console drawer + connection-state awareness (Pass 1 of features-smarter) ---
    connectionState: ConnectionState
    currentPage: CurrentPage
    consoleDrawerOpen: boolean

    resetConnections: () => void
    setConnectionState: (s: ConnectionState) => void
    setCurrentPage: (p: CurrentPage) => void
    setConsoleDrawerOpen: (open: boolean) => void
    toggleConsoleDrawer: () => void
}

function getStoredDrawerOpen(): boolean {
    try { return localStorage.getItem('p3xr-console-drawer-open') === 'true' } catch { return false }
}

export const useRedisStateStore = create<RedisState>((set, get) => ({
    apiHost: computeApiHost(),
    connection: undefined,
    connections: { list: [] },
    cfg: undefined,
    version: undefined,
    currentDatabase: undefined,
    databaseIndexes: [],
    keysRaw: [],
    keysInfo: undefined,
    search: '',
    page: 1,
    info: undefined,
    dbsize: undefined,
    monitor: false,
    commands: [],
    commandsMeta: {},
    modules: [],
    hasRediSearch: false,
    hasReJSON: false,
    hasTimeSeries: false,
    hasBloom: false,
    theme: undefined,
    redisConnections: {},
    keysInfoFetchedAt: Date.now(),
    redisChanged: false,
    failed: false,
    reducedFunctions: false,

    connectionState: 'none',
    currentPage: 'unknown',
    consoleDrawerOpen: getStoredDrawerOpen(),

    resetConnections: () => set({ connections: { list: [] } }),
    setConnectionState: (s) => set({ connectionState: s }),
    setCurrentPage: (p) => set({ currentPage: p }),
    setConsoleDrawerOpen: (open) => {
        try { localStorage.setItem('p3xr-console-drawer-open', String(open)) } catch {}
        set({ consoleDrawerOpen: open })
    },
    toggleConsoleDrawer: () => {
        const next = !get().consoleDrawerOpen
        try { localStorage.setItem('p3xr-console-drawer-open', String(next)) } catch {}
        set({ consoleDrawerOpen: next })
    },
}))

// --- Computed helpers (matching Angular computed signals) ---
// Import settings inline to avoid top-level circular dep
import { useSettingsStore } from './settings.store'

export function getFilteredKeys(): string[] {
    const { keysRaw, search } = useRedisStateStore.getState()
    const { searchClientSide, searchStartsWith } = useSettingsStore.getState()
    let keys = keysRaw.slice()
    if (searchClientSide && typeof search === 'string' && search.length > 0) {
        keys = searchStartsWith ? keys.filter((k: string) => k.startsWith(search)) : keys.filter((k: string) => k.includes(search))
    }
    return keys
}

export function getPaginatedKeys(): string[] {
    const { page } = useRedisStateStore.getState()
    const { pageCount } = useSettingsStore.getState()
    const keys = getFilteredKeys()
    if (keys.length <= pageCount) return keys
    const start = (page - 1) * pageCount
    return keys.slice(start, start + pageCount)
}

export function getPages(): number {
    const { pageCount } = useSettingsStore.getState()
    return Math.ceil(getFilteredKeys().length / pageCount)
}