mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 11:44:28 +08:00
refactor(tabs): move Tab and TabsState types to cacheValueTypes
- Moved Tab and TabsState type definitions from cacheSchemas.ts to cacheValueTypes.ts for better organization and clarity. - Updated imports in related components to reflect the new location of these types. - Removed the now redundant tab type definitions from cacheSchemas.ts. These changes enhance the structure of type definitions, promoting a clearer separation of concerns within the codebase.
This commit is contained in:
parent
544e716587
commit
7dc377d467
25
packages/shared/data/cache/cacheSchemas.ts
vendored
25
packages/shared/data/cache/cacheSchemas.ts
vendored
@ -1,4 +1,5 @@
|
||||
import type * as CacheValueTypes from './cacheValueTypes'
|
||||
import type { TabsState } from './cacheValueTypes'
|
||||
|
||||
/**
|
||||
* Cache Schema Definitions
|
||||
@ -97,30 +98,6 @@ export const DefaultUseSharedCache: UseSharedCacheSchema = {
|
||||
'example_scope.example_key': 'example default value'
|
||||
}
|
||||
|
||||
/**
|
||||
* Tab type for browser-like tabs
|
||||
*
|
||||
* - 'route': Internal app routes rendered via MemoryRouter
|
||||
* - 'webview': External web content rendered via Electron webview
|
||||
*/
|
||||
export type TabType = 'route' | 'webview'
|
||||
|
||||
export interface Tab {
|
||||
id: string
|
||||
type: TabType
|
||||
url: string
|
||||
title: string
|
||||
icon?: string
|
||||
metadata?: Record<string, unknown>
|
||||
// TODO: LRU 优化字段,后续添加
|
||||
// lastAccessTime?: number
|
||||
}
|
||||
|
||||
export interface TabsState {
|
||||
tabs: Tab[]
|
||||
activeTabId: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist cache schema defining allowed keys and their value types
|
||||
* This ensures type safety and prevents key conflicts
|
||||
|
||||
24
packages/shared/data/cache/cacheValueTypes.ts
vendored
24
packages/shared/data/cache/cacheValueTypes.ts
vendored
@ -17,3 +17,27 @@ export type CacheActiveSearches = Record<string, WebSearchStatus>
|
||||
// The actual type checking will be done at runtime by the cache system
|
||||
export type CacheMinAppType = MinAppType
|
||||
export type CacheTopic = Topic
|
||||
|
||||
/**
|
||||
* Tab type for browser-like tabs
|
||||
*
|
||||
* - 'route': Internal app routes rendered via MemoryRouter
|
||||
* - 'webview': External web content rendered via Electron webview
|
||||
*/
|
||||
export type TabType = 'route' | 'webview'
|
||||
|
||||
export interface Tab {
|
||||
id: string
|
||||
type: TabType
|
||||
url: string
|
||||
title: string
|
||||
icon?: string
|
||||
metadata?: Record<string, unknown>
|
||||
// TODO: LRU 优化字段,后续添加
|
||||
// lastAccessTime?: number
|
||||
}
|
||||
|
||||
export interface TabsState {
|
||||
tabs: Tab[]
|
||||
activeTabId: string
|
||||
}
|
||||
|
||||
@ -1,100 +0,0 @@
|
||||
import { dbService } from '@data/db/DbService'
|
||||
import { appStateTable } from '@data/db/schemas/appState'
|
||||
import { loggerService } from '@logger'
|
||||
import { eq } from 'drizzle-orm'
|
||||
|
||||
const logger = loggerService.withContext('AppStateService')
|
||||
|
||||
/**
|
||||
* Service for managing application state in the database.
|
||||
* Provides key-value storage for persisting UI state like tabs, window positions, etc.
|
||||
*/
|
||||
export class AppStateService {
|
||||
private static instance: AppStateService
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): AppStateService {
|
||||
if (!AppStateService.instance) {
|
||||
AppStateService.instance = new AppStateService()
|
||||
}
|
||||
return AppStateService.instance
|
||||
}
|
||||
|
||||
/**
|
||||
* Get app state by key
|
||||
* @param key - The state key to retrieve
|
||||
* @returns The stored value or null if not found
|
||||
*/
|
||||
async getState<T = unknown>(key: string): Promise<T | null> {
|
||||
try {
|
||||
const db = dbService.getDb()
|
||||
const result = await db.select().from(appStateTable).where(eq(appStateTable.key, key)).limit(1)
|
||||
|
||||
if (result.length === 0) {
|
||||
logger.debug('App state not found', { key })
|
||||
return null
|
||||
}
|
||||
|
||||
logger.debug('Retrieved app state', { key })
|
||||
return result[0].value as T
|
||||
} catch (error) {
|
||||
logger.error('Failed to get app state', error as Error, { key })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save app state by key (upsert)
|
||||
* @param key - The state key
|
||||
* @param value - The value to store (will be JSON serialized)
|
||||
* @param description - Optional description of what this state stores
|
||||
*/
|
||||
async setState<T = unknown>(key: string, value: T, description?: string): Promise<void> {
|
||||
try {
|
||||
const db = dbService.getDb()
|
||||
|
||||
await db
|
||||
.insert(appStateTable)
|
||||
.values({
|
||||
key,
|
||||
value: value as any,
|
||||
description
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: appStateTable.key,
|
||||
set: {
|
||||
value: value as any,
|
||||
description,
|
||||
updatedAt: Date.now()
|
||||
}
|
||||
})
|
||||
|
||||
logger.debug('Saved app state', { key })
|
||||
} catch (error) {
|
||||
logger.error('Failed to save app state', error as Error, { key })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete app state by key
|
||||
* @param key - The state key to delete
|
||||
* @returns true if deleted, false if not found
|
||||
*/
|
||||
async deleteState(key: string): Promise<boolean> {
|
||||
try {
|
||||
const db = dbService.getDb()
|
||||
const result = await db.delete(appStateTable).where(eq(appStateTable.key, key))
|
||||
|
||||
const deleted = result.rowsAffected > 0
|
||||
logger.debug('Deleted app state', { key, deleted })
|
||||
return deleted
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete app state', error as Error, { key })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const appStateService = AppStateService.getInstance()
|
||||
@ -1,4 +1,4 @@
|
||||
import type { Tab } from '@shared/data/cache/cacheSchemas'
|
||||
import type { Tab } from '@shared/data/cache/cacheValueTypes'
|
||||
import { createMemoryHistory, createRouter, RouterProvider } from '@tanstack/react-router'
|
||||
import { Activity } from 'react'
|
||||
import { useEffect, useMemo } from 'react'
|
||||
|
||||
@ -2,7 +2,6 @@ import type { BodyForPath, QueryParamsForPath, ResponseForPath } from '@shared/d
|
||||
import type { ConcreteApiPaths } from '@shared/data/api/apiSchemas'
|
||||
import type { PaginatedResponse } from '@shared/data/api/apiTypes'
|
||||
import { useState } from 'react'
|
||||
import type { KeyedMutator } from 'swr'
|
||||
import useSWR, { useSWRConfig } from 'swr'
|
||||
import useSWRMutation from 'swr/mutation'
|
||||
|
||||
@ -140,8 +139,6 @@ export function useQuery<TPath extends ConcreteApiPaths>(
|
||||
error?: Error
|
||||
/** Function to manually refetch data */
|
||||
refetch: () => void
|
||||
/** SWR mutate function for optimistic updates */
|
||||
mutate: KeyedMutator<ResponseForPath<TPath, 'GET'>>
|
||||
} {
|
||||
// Internal type conversion for SWR compatibility
|
||||
const key = options?.enabled !== false ? buildSWRKey(path, options?.query as Record<string, any>) : null
|
||||
@ -163,8 +160,7 @@ export function useQuery<TPath extends ConcreteApiPaths>(
|
||||
data,
|
||||
loading: isLoading || isValidating,
|
||||
error: error as Error | undefined,
|
||||
refetch,
|
||||
mutate
|
||||
refetch
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@ import { uuid } from '../utils'
|
||||
import { getDefaultRouteTitle } from '../utils/routeTitle'
|
||||
|
||||
// Re-export types from shared schema
|
||||
export type { Tab, TabsState, TabType } from '@shared/data/cache/cacheSchemas'
|
||||
import type { Tab, TabType } from '@shared/data/cache/cacheSchemas'
|
||||
export type { Tab, TabsState, TabType } from '@shared/data/cache/cacheValueTypes'
|
||||
import type { Tab, TabType } from '@shared/data/cache/cacheValueTypes'
|
||||
|
||||
const DEFAULT_TAB: Tab = {
|
||||
id: 'home',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user