mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
Merge branch 'main' of https://github.com/johndoe6345789/metabuilder
This commit is contained in:
@@ -38,7 +38,7 @@ export class AuthStore {
|
||||
}
|
||||
|
||||
async ensureSessionChecked(): Promise<void> {
|
||||
if (!this.sessionCheckPromise) {
|
||||
if (this.sessionCheckPromise === null) {
|
||||
this.sessionCheckPromise = this.refresh().finally(() => {
|
||||
this.sessionCheckPromise = null
|
||||
})
|
||||
@@ -129,6 +129,7 @@ export class AuthStore {
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
})
|
||||
console.error('Failed to refresh session', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Auto-refresh polling tests
|
||||
*/
|
||||
import { act, renderHook, waitFor } from '@testing-library/react'
|
||||
import { act, renderHook } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useAutoRefresh } from '../useAutoRefresh'
|
||||
|
||||
@@ -34,7 +34,7 @@ export function useAutoRefresh({
|
||||
if (!isAutoRefreshing) return
|
||||
|
||||
const refreshInterval = setInterval(() => {
|
||||
onRefresh()
|
||||
void onRefresh()
|
||||
}, intervalMs)
|
||||
|
||||
const countdownInterval = setInterval(() => {
|
||||
|
||||
@@ -19,8 +19,10 @@ export function useFileTree(initialFiles: FileNode[] = []) {
|
||||
const [files, setFiles] = useState<FileNode[]>(initialFiles)
|
||||
|
||||
const findNodeById = useCallback(
|
||||
(id: string, nodes = files): FileNode | null => {
|
||||
for (const node of nodes) {
|
||||
(id: string, nodes?: FileNode[]): FileNode | null => {
|
||||
const searchNodes = nodes ?? files
|
||||
|
||||
for (const node of searchNodes) {
|
||||
if (node.id === id) return node
|
||||
if (node.children) {
|
||||
const found = findNodeById(id, node.children)
|
||||
@@ -69,32 +71,29 @@ export function useFileTree(initialFiles: FileNode[] = []) {
|
||||
|
||||
const addChild = useCallback(
|
||||
(parentId: string, child: FileNode) => {
|
||||
const parent = findNodeById(parentId)
|
||||
if (!parent || parent.type !== 'folder') return
|
||||
setFiles(currentFiles => {
|
||||
const parent = findNodeById(parentId, currentFiles)
|
||||
if (!parent || parent.type !== 'folder') return currentFiles
|
||||
|
||||
setFiles(files =>
|
||||
files.map(node => {
|
||||
if (node.id === parentId) {
|
||||
return {
|
||||
...node,
|
||||
children: [...(node.children || []), child],
|
||||
const appendChild = (nodes: FileNode[]): FileNode[] =>
|
||||
nodes.map(node => {
|
||||
if (node.id === parentId && node.type === 'folder') {
|
||||
return {
|
||||
...node,
|
||||
children: [...(node.children || []), child],
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.children) {
|
||||
return {
|
||||
...node,
|
||||
children:
|
||||
files.map(n =>
|
||||
n.id === parentId ? { ...n, children: [...(n.children || []), child] } : n
|
||||
)[0]?.children || node.children,
|
||||
if (node.children) {
|
||||
return { ...node, children: appendChild(node.children) }
|
||||
}
|
||||
}
|
||||
return node
|
||||
})
|
||||
)
|
||||
return node
|
||||
})
|
||||
|
||||
return appendChild(currentFiles)
|
||||
})
|
||||
toast.success('Created')
|
||||
},
|
||||
[findNodeById, files]
|
||||
[findNodeById]
|
||||
)
|
||||
|
||||
return {
|
||||
|
||||
@@ -8,18 +8,18 @@ import { useKVStore } from './use-kv-store'
|
||||
* Hook for storing and retrieving cached data with automatic serialization
|
||||
*/
|
||||
export function useCachedData<T>(key: string, tenantId?: string, userId?: string) {
|
||||
const kv = useKVStore(tenantId, userId)
|
||||
const { isReady, get, set, delete: deleteKey } = useKVStore(tenantId, userId)
|
||||
const [data, setData] = useState<T | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
if (!kv.isReady) return
|
||||
if (!isReady) return
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
const cached = await kv.get<T>(key)
|
||||
const cached = await get<T>(key)
|
||||
setData(cached)
|
||||
setError(null)
|
||||
} catch (err) {
|
||||
@@ -30,13 +30,13 @@ export function useCachedData<T>(key: string, tenantId?: string, userId?: string
|
||||
}
|
||||
}
|
||||
|
||||
loadData()
|
||||
}, [key, kv.isReady])
|
||||
void loadData()
|
||||
}, [get, isReady, key])
|
||||
|
||||
const save = useCallback(
|
||||
async (newData: T, ttl?: number) => {
|
||||
try {
|
||||
await kv.set(key, newData, ttl)
|
||||
await set(key, newData, ttl)
|
||||
setData(newData)
|
||||
setError(null)
|
||||
} catch (err) {
|
||||
@@ -45,12 +45,12 @@ export function useCachedData<T>(key: string, tenantId?: string, userId?: string
|
||||
throw err
|
||||
}
|
||||
},
|
||||
[key, kv]
|
||||
[key, set]
|
||||
)
|
||||
|
||||
const clear = useCallback(async () => {
|
||||
try {
|
||||
await kv.delete(key)
|
||||
await deleteKey(key)
|
||||
setData(null)
|
||||
setError(null)
|
||||
} catch (err) {
|
||||
@@ -58,7 +58,7 @@ export function useCachedData<T>(key: string, tenantId?: string, userId?: string
|
||||
setError(errorInfo.message)
|
||||
throw err
|
||||
}
|
||||
}, [key, kv])
|
||||
}, [deleteKey, key])
|
||||
|
||||
return {
|
||||
data,
|
||||
@@ -66,6 +66,6 @@ export function useCachedData<T>(key: string, tenantId?: string, userId?: string
|
||||
error,
|
||||
save,
|
||||
clear,
|
||||
isReady: kv.isReady,
|
||||
isReady,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export function useDBAL() {
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
void init()
|
||||
}, [])
|
||||
|
||||
return { isReady, error }
|
||||
|
||||
@@ -12,7 +12,7 @@ export function useKVStore(tenantId: string = 'default', userId: string = 'syste
|
||||
const { isReady } = useDBAL()
|
||||
|
||||
const set = useCallback(
|
||||
async (key: string, value: any, ttl?: number) => {
|
||||
async (key: string, value: unknown, ttl?: number) => {
|
||||
if (!isReady) {
|
||||
throw new Error('DBAL not ready')
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export function useKVStore(tenantId: string = 'default', userId: string = 'syste
|
||||
)
|
||||
|
||||
const get = useCallback(
|
||||
async <T = any>(key: string): Promise<T | null> => {
|
||||
async <T = unknown>(key: string): Promise<T | null> => {
|
||||
if (!isReady) {
|
||||
throw new Error('DBAL not ready')
|
||||
}
|
||||
@@ -60,7 +60,7 @@ export function useKVStore(tenantId: string = 'default', userId: string = 'syste
|
||||
)
|
||||
|
||||
const listAdd = useCallback(
|
||||
async (key: string, items: any[]) => {
|
||||
async <T = unknown>(key: string, items: T[]) => {
|
||||
if (!isReady) {
|
||||
throw new Error('DBAL not ready')
|
||||
}
|
||||
@@ -76,7 +76,7 @@ export function useKVStore(tenantId: string = 'default', userId: string = 'syste
|
||||
)
|
||||
|
||||
const listGet = useCallback(
|
||||
async (key: string, start?: number, end?: number): Promise<any[]> => {
|
||||
async <T = unknown>(key: string, start?: number, end?: number): Promise<T[]> => {
|
||||
if (!isReady) {
|
||||
throw new Error('DBAL not ready')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user